avformat/utils: fix stream ordering for program ID stream specifiers

Fixes a regression introduced in dbfd042983.

Signed-off-by: Marton Balint <cus@passwd.hu>
pull/315/head
Marton Balint 6 years ago
parent 50789e356d
commit f9271d0158
  1. 5
      doc/fftools-common-opts.texi
  2. 16
      libavformat/utils.c

@ -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 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 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 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}] @item @var{stream_type}[:@var{additional_stream_specifier}]
@var{stream_type} is one of following: 'v' or 'V' for video, 'a' for audio, 's' @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 for subtitle, 'd' for data, and 't' for attachments. 'v' matches all video

@ -5107,7 +5107,7 @@ AVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *f
* >0 if st is a matching stream * >0 if st is a matching stream
*/ */
static int match_stream_specifier(AVFormatContext *s, AVStream *st, 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. */ int match = 1; /* Stores if the specifier matches so far. */
while (*spec) { while (*spec) {
@ -5162,6 +5162,8 @@ FF_DISABLE_DEPRECATION_WARNINGS
for (j = 0; j < s->programs[i]->nb_stream_indexes; j++) { for (j = 0; j < s->programs[i]->nb_stream_indexes; j++) {
if (st->index == s->programs[i]->stream_index[j]) { if (st->index == s->programs[i]->stream_index[j]) {
found = 1; found = 1;
if (p)
*p = s->programs[i];
i = s->nb_programs; i = s->nb_programs;
break; break;
} }
@ -5264,8 +5266,10 @@ int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
int ret, index; int ret, index;
char *endptr; char *endptr;
const char *indexptr = NULL; 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) if (ret < 0)
goto error; goto error;
@ -5283,11 +5287,13 @@ int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
return (index == st->index); return (index == st->index);
/* If we requested a matching stream index, we have to ensure st is that. */ /* 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++) { nb_streams = p ? p->nb_stream_indexes : s->nb_streams;
ret = match_stream_specifier(s, s->streams[i], spec, NULL); 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) if (ret < 0)
goto error; goto error;
if (ret > 0 && index-- == 0 && st == s->streams[i]) if (ret > 0 && index-- == 0 && st == candidate)
return 1; return 1;
} }
return 0; return 0;

Loading…
Cancel
Save