From f9271d0158122c9e043b7d83f691884b65ec1ba5 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sun, 19 May 2019 00:43:29 +0200 Subject: [PATCH] avformat/utils: fix stream ordering for program ID stream specifiers Fixes a regression introduced in dbfd042983eed8586d4048795c00af820f5b6b1f. Signed-off-by: Marton Balint --- doc/fftools-common-opts.texi | 5 ++++- libavformat/utils.c | 16 +++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/doc/fftools-common-opts.texi b/doc/fftools-common-opts.texi index e75bec4354..4c821bad07 100644 --- a/doc/fftools-common-opts.texi +++ b/doc/fftools-common-opts.texi @@ -36,7 +36,10 @@ Possible forms of stream specifiers are: Matches the stream with this index. E.g. @code{-threads:1 4} would set the thread count for the second stream to 4. If @var{stream_index} is used as an additional stream specifier (see below), then it selects stream number -@var{stream_index} from the matching streams. +@var{stream_index} from the matching streams. Stream numbering is based on the +order of the streams as detected by libavformat except when a program ID is +also specified. In this case it is based on the ordering of the streams in the +program. @item @var{stream_type}[:@var{additional_stream_specifier}] @var{stream_type} is one of following: 'v' or 'V' for video, 'a' for audio, 's' for subtitle, 'd' for data, and 't' for attachments. 'v' matches all video diff --git a/libavformat/utils.c b/libavformat/utils.c index 6ef94239a4..3d764c18d6 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -5107,7 +5107,7 @@ AVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *f * >0 if st is a matching stream */ static int match_stream_specifier(AVFormatContext *s, AVStream *st, - const char *spec, const char **indexptr) + const char *spec, const char **indexptr, AVProgram **p) { int match = 1; /* Stores if the specifier matches so far. */ while (*spec) { @@ -5162,6 +5162,8 @@ FF_DISABLE_DEPRECATION_WARNINGS for (j = 0; j < s->programs[i]->nb_stream_indexes; j++) { if (st->index == s->programs[i]->stream_index[j]) { found = 1; + if (p) + *p = s->programs[i]; i = s->nb_programs; break; } @@ -5264,8 +5266,10 @@ int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st, int ret, index; char *endptr; const char *indexptr = NULL; + AVProgram *p = NULL; + int nb_streams; - ret = match_stream_specifier(s, st, spec, &indexptr); + ret = match_stream_specifier(s, st, spec, &indexptr, &p); if (ret < 0) goto error; @@ -5283,11 +5287,13 @@ int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st, return (index == st->index); /* If we requested a matching stream index, we have to ensure st is that. */ - for (int i = 0; i < s->nb_streams && index >= 0; i++) { - ret = match_stream_specifier(s, s->streams[i], spec, NULL); + nb_streams = p ? p->nb_stream_indexes : s->nb_streams; + for (int i = 0; i < nb_streams && index >= 0; i++) { + AVStream *candidate = p ? s->streams[p->stream_index[i]] : s->streams[i]; + ret = match_stream_specifier(s, candidate, spec, NULL, NULL); if (ret < 0) goto error; - if (ret > 0 && index-- == 0 && st == s->streams[i]) + if (ret > 0 && index-- == 0 && st == candidate) return 1; } return 0;