[FFmpeg-devel] avformat/utils: fix stream ordering for program ID stream specifiers

Submitted by Marton Balint on May 18, 2019, 11:33 p.m.

Details

Message ID 20190518233346.28142-1-cus@passwd.hu
State New
Headers show

Commit Message

Marton Balint May 18, 2019, 11:33 p.m.
Fixes a regression introduced in dbfd042983eed8586d4048795c00af820f5b6b1f.

Signed-off-by: Marton Balint <cus@passwd.hu>
---
 doc/fftools-common-opts.texi |  5 ++++-
 libavformat/utils.c          | 16 +++++++++++-----
 2 files changed, 15 insertions(+), 6 deletions(-)

Comments

Marton Balint May 23, 2019, 7:29 p.m.
On Sun, 19 May 2019, Marton Balint wrote:

> Fixes a regression introduced in dbfd042983eed8586d4048795c00af820f5b6b1f.

Will apply soon.

Thanks,
Marton

>
> Signed-off-by: Marton Balint <cus@passwd.hu>
> ---
> 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..4359526f19 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
> +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;
> -- 
> 2.16.4
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Marton Balint May 24, 2019, 8:44 p.m.
On Thu, 23 May 2019, Marton Balint wrote:

>
>
> On Sun, 19 May 2019, Marton Balint wrote:
>
>> Fixes a regression introduced in dbfd042983eed8586d4048795c00af820f5b6b1f.
>
> Will apply soon.

Applied.

Regards,
Marton

Patch hide | download patch | download mbox

diff --git a/doc/fftools-common-opts.texi b/doc/fftools-common-opts.texi
index e75bec4354..4359526f19 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
+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;