diff mbox

[FFmpeg-devel] avformat/utils: Stream specifier enhancement

Message ID 0b533ebc-731a-137c-1884-b5b6667c2b1e@vivanet.hu
State Accepted
Commit 37d0213968a2b58499f52dfe09c8d7a27d4c5a86
Headers show

Commit Message

Bodecs Bela April 1, 2018, 9:42 p.m. UTC
Dear All,

currently when specifying the program id you can only decide to select
all stream of the specified program (e.g. p:103 will select all streams
of program 103) or narrow the selection to a specific stream sub index
(e.g. p:145:1 will select 2nd stream of program 145.) But you can not
specify like all audio streams of program 145 or 3rd video stream of
program 311.
In some case, mainly working with multiprogram mpeg-ts containers as
input, this feature would be handy.
This patch makes it possible to narrow the stream selection among
streams of the specified program by stream type and optionally its
index. Handled types: a, v, s, d.
Examples: p:601:a  will select all audio streams of program 601,
p:603:a:1 will select 2nd audio streams of program 603,
p:604:v:0 will select first video stream of program 604.
This syntax enhancement does not interfere in any way with
current/exiting syntax or working command lines

please review this patch.

thank you in advance,

best,

Bela
From ac3fb61a574e5d945389bf4e725408f3f28835b9 Mon Sep 17 00:00:00 2001
From: Bela Bodecs <bodecsb@vivanet.hu>
Date: Sun, 1 Apr 2018 23:29:14 +0200
Subject: [PATCH] avformat/utils: Stream specifier enhancement

Currently when specifying the program id you can only decide to select
all stream of the specified program (e.g. p:103 will select all streams
of program 103) or narrow the selection to a specific stream sub index
(e.g. p:145:1 will select 2nd stream of program 145.) But you can not
specify like all audio streams of program 145 or 3rd video stream of
program 311.
In some case, mainly working with multiprogram mpeg-ts containers as
input, this feature would be handy.
This patch makes it possible to narrow the stream selection among
streams of the specified program by stream type and optionally its
index. Handled types: a, v, s, d.
Examples: p:601:a  will select all audio streams of program 601,
p:603:a:1 will select 2nd audio streams of program 603,
p:604:v:0 will select first video stream of program 604.

Signed-off-by: Bela Bodecs <bodecsb@vivanet.hu>
---
 doc/fftools-common-opts.texi | 10 +++++--
 libavformat/utils.c          | 65 ++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 67 insertions(+), 8 deletions(-)

Comments

Michael Niedermayer April 4, 2018, 12:37 a.m. UTC | #1
On Sun, Apr 01, 2018 at 11:42:34PM +0200, Bodecs Bela wrote:
> Dear All,
> 
> currently when specifying the program id you can only decide to select
> all stream of the specified program (e.g. p:103 will select all streams
> of program 103) or narrow the selection to a specific stream sub index
> (e.g. p:145:1 will select 2nd stream of program 145.) But you can not
> specify like all audio streams of program 145 or 3rd video stream of
> program 311.
> In some case, mainly working with multiprogram mpeg-ts containers as
> input, this feature would be handy.
> This patch makes it possible to narrow the stream selection among
> streams of the specified program by stream type and optionally its
> index. Handled types: a, v, s, d.
> Examples: p:601:a  will select all audio streams of program 601,
> p:603:a:1 will select 2nd audio streams of program 603,
> p:604:v:0 will select first video stream of program 604.
> This syntax enhancement does not interfere in any way with
> current/exiting syntax or working command lines

I think this is a good idea.
Can you also add fate test(s) for this ? (can be in a seperate patch
later of course)

thx

[...]
Bodecs Bela April 4, 2018, 8:39 a.m. UTC | #2
2018.04.04. 2:37 keltezéssel, Michael Niedermayer írta:
> On Sun, Apr 01, 2018 at 11:42:34PM +0200, Bodecs Bela wrote:
>> Dear All,
>>
>> currently when specifying the program id you can only decide to select
>> all stream of the specified program (e.g. p:103 will select all streams
>> of program 103) or narrow the selection to a specific stream sub index
>> (e.g. p:145:1 will select 2nd stream of program 145.) But you can not
>> specify like all audio streams of program 145 or 3rd video stream of
>> program 311.
>> In some case, mainly working with multiprogram mpeg-ts containers as
>> input, this feature would be handy.
>> This patch makes it possible to narrow the stream selection among
>> streams of the specified program by stream type and optionally its
>> index. Handled types: a, v, s, d.
>> Examples: p:601:a  will select all audio streams of program 601,
>> p:603:a:1 will select 2nd audio streams of program 603,
>> p:604:v:0 will select first video stream of program 604.
>> This syntax enhancement does not interfere in any way with
>> current/exiting syntax or working command lines
> I think this is a good idea.
> Can you also add fate test(s) for this ? (can be in a seperate patch
> later of course)
>
ok, I will try.

bb

> thx
>
> [...]
>
>
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
diff mbox

Patch

diff --git a/doc/fftools-common-opts.texi b/doc/fftools-common-opts.texi
index 185ec21..71ad428 100644
--- a/doc/fftools-common-opts.texi
+++ b/doc/fftools-common-opts.texi
@@ -42,10 +42,14 @@  streams, 'V' only matches video streams which are not attached pictures, video
 thumbnails or cover arts.  If @var{stream_index} is given, then it matches
 stream number @var{stream_index} of this type. Otherwise, it matches all
 streams of this type.
-@item p:@var{program_id}[:@var{stream_index}]
-If @var{stream_index} is given, then it matches the stream with number @var{stream_index}
+@item p:@var{program_id}[:@var{stream_index}] or p:@var{program_id}[:@var{stream_type}[:@var{stream_index}]]
+In first version, if @var{stream_index} is given, then it matches the stream with number @var{stream_index}
 in the program with the id @var{program_id}. Otherwise, it matches all streams in the
-program.
+program. In the latter version, @var{stream_type} is one of following: 'v' for video, 'a' for audio, 's'
+for subtitle, 'd' for data. If @var{stream_index} is also given, then it matches
+stream number @var{stream_index} of this type in the program with the id @var{program_id}.
+Otherwise, if only @var{stream_type} is given, it matches all
+streams of this type in the program with the id @var{program_id}.
 @item #@var{stream_id} or i:@var{stream_id}
 Match the stream by stream id (e.g. PID in MPEG-TS container).
 @item m:@var{key}[:@var{value}]
diff --git a/libavformat/utils.c b/libavformat/utils.c
index f13c820..7d68677 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -5062,11 +5062,66 @@  FF_ENABLE_DEPRECATION_WARNINGS
             if (s->programs[i]->id != prog_id)
                 continue;
 
-            if (*endptr++ == ':') {
-                int stream_idx = strtol(endptr, NULL, 0);
-                return stream_idx >= 0 &&
-                    stream_idx < s->programs[i]->nb_stream_indexes &&
-                    st->index == s->programs[i]->stream_index[stream_idx];
+            if (*endptr++ == ':') {  // p:<id>:....
+                if ( *endptr == 'a' || *endptr == 'v' ||
+                     *endptr == 's' || *endptr == 'd') {  // p:<id>:<st_type>[:<index>]
+                    enum AVMediaType type;
+
+                    switch (*endptr++) {
+                    case 'v': type = AVMEDIA_TYPE_VIDEO;      break;
+                    case 'a': type = AVMEDIA_TYPE_AUDIO;      break;
+                    case 's': type = AVMEDIA_TYPE_SUBTITLE;   break;
+                    case 'd': type = AVMEDIA_TYPE_DATA;       break;
+                    default:  av_assert0(0);
+                    }
+                    if (*endptr++ == ':') {  // p:<id>:<st_type>:<index>
+                        int stream_idx = strtol(endptr, NULL, 0), type_counter = 0;
+                        for (j = 0; j < s->programs[i]->nb_stream_indexes; j++) {
+                            int stream_index = s->programs[i]->stream_index[j];
+                            if (st->index == s->programs[i]->stream_index[j]) {
+#if FF_API_LAVF_AVCTX
+FF_DISABLE_DEPRECATION_WARNINGS
+                                return type_counter == stream_idx &&
+                                       (type == st->codecpar->codec_type ||
+                                        type == st->codec->codec_type);
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+                                return type_counter == stream_idx &&
+                                       type == st->codecpar->codec_type;
+#endif
+                             }
+#if FF_API_LAVF_AVCTX
+FF_DISABLE_DEPRECATION_WARNINGS
+                            if (type == s->streams[stream_index]->codecpar->codec_type ||
+                                type == s->streams[stream_index]->codec->codec_type)
+                                type_counter++;
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+                            if (type == s->streams[stream_index]->codecpar->codec_type)
+                                type_counter++;
+#endif
+                        }
+                        return 0;
+                    } else {  // p:<id>:<st_type>
+                        for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
+                            if (st->index == s->programs[i]->stream_index[j]) {
+#if FF_API_LAVF_AVCTX
+FF_DISABLE_DEPRECATION_WARNINGS
+                                 return type == st->codecpar->codec_type ||
+                                        type == st->codec->codec_type;
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+                                 return type == st->codecpar->codec_type;
+#endif
+                            }
+                        return 0;
+                    }
+                } else {  // p:<id>:<index>
+                    int stream_idx = strtol(endptr, NULL, 0);
+                    return stream_idx >= 0 &&
+                           stream_idx < s->programs[i]->nb_stream_indexes &&
+                           st->index == s->programs[i]->stream_index[stream_idx];
+                }
             }
 
             for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)