summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/fftools-common-opts.texi10
-rw-r--r--libavformat/utils.c65
2 files changed, 67 insertions, 8 deletions
diff --git a/doc/fftools-common-opts.texi b/doc/fftools-common-opts.texi
index 7787e11cda..79feb39ca7 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 3e482a3bbc..cc35998336 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -5070,11 +5070,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++)