diff mbox series

[FFmpeg-devel,v3] ffmpeg_opt: restore documented stream selection behaviour

Message ID 20210729044420.2282-1-ffmpeg@gyani.pro
State Accepted
Commit c50f5460d2f059e5be393eac90e4eac55a6034c6
Headers show
Series [FFmpeg-devel,v3] ffmpeg_opt: restore documented stream selection behaviour | expand

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Gyan Doshi July 29, 2021, 4:44 a.m. UTC
11d3b03fcb added consideration of default stream disposition for audio
and video when choosing the 'best' stream among all the inputs. This can
lead to video streams with lower resolution or audio streams with fewer
channels being selected.

Stream disposition, however, only sets a priority for a stream
among all other streams in the *same input*. It cannot set a priority
for a stream across all inputs.

This patch sets a middle-way and selects the best stream from each file
with default disposition considered. Then it discards disposition weight
and selects best stream as per the original criteria of highest
resolution for video and most channels for audio.
---
 fftools/ffmpeg_opt.c | 77 ++++++++++++++++++++++++++++----------------
 1 file changed, 50 insertions(+), 27 deletions(-)

Comments

Gyan Doshi July 31, 2021, 4:02 a.m. UTC | #1
Plan to push tomorrow.

On 2021-07-29 10:14, Gyan Doshi wrote:
> 11d3b03fcb added consideration of default stream disposition for audio
> and video when choosing the 'best' stream among all the inputs. This can
> lead to video streams with lower resolution or audio streams with fewer
> channels being selected.
>
> Stream disposition, however, only sets a priority for a stream
> among all other streams in the *same input*. It cannot set a priority
> for a stream across all inputs.
>
> This patch sets a middle-way and selects the best stream from each file
> with default disposition considered. Then it discards disposition weight
> and selects best stream as per the original criteria of highest
> resolution for video and most channels for audio.
> ---
>   fftools/ffmpeg_opt.c | 77 ++++++++++++++++++++++++++++----------------
>   1 file changed, 50 insertions(+), 27 deletions(-)
>
> diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
> index 1b43bab9fc..34cc6c4fd3 100644
> --- a/fftools/ffmpeg_opt.c
> +++ b/fftools/ffmpeg_opt.c
> @@ -2260,23 +2260,35 @@ static int open_output_file(OptionsContext *o, const char *filename)
>           if (!o->video_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE) {
>               int best_score = 0, idx = -1;
>               int qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0);
> -            for (i = 0; i < nb_input_streams; i++) {
> -                int score;
> -                ist = input_streams[i];
> -                score = ist->st->codecpar->width * ist->st->codecpar->height
> -                           + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
> -                           + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
> -                if (ist->user_set_discard == AVDISCARD_ALL)
> -                    continue;
> -                if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
> -                    score = 1;
> -                if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
> -                    score > best_score) {
> -                    if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
> +            for (j = 0; j < nb_input_files; j++) {
> +                InputFile *ifile = input_files[j];
> +                int file_best_score = 0, file_best_idx = -1;
> +                for (i = 0; i < ifile->nb_streams; i++) {
> +                    int score;
> +                    ist = input_streams[ifile->ist_index + i];
> +                    score = ist->st->codecpar->width * ist->st->codecpar->height
> +                               + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
> +                               + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
> +                    if (ist->user_set_discard == AVDISCARD_ALL)
>                           continue;
> -                    best_score = score;
> -                    idx = i;
> +                    if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
> +                        score = 1;
> +                    if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
> +                        score > file_best_score) {
> +                        if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
> +                            continue;
> +                        file_best_score = score;
> +                        file_best_idx = ifile->ist_index + i;
> +                    }
>                   }
> +                if (file_best_idx >= 0) {
> +                    if((qcr == MKTAG('A', 'P', 'I', 'C')) || !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
> +                        file_best_score -= 5000000*!!(input_streams[file_best_idx]->st->disposition & AV_DISPOSITION_DEFAULT);
> +                    if (file_best_score > best_score) {
> +                        best_score = file_best_score;
> +                        idx = file_best_idx;
> +                    }
> +               }
>               }
>               if (idx >= 0)
>                   new_video_stream(o, oc, idx);
> @@ -2285,19 +2297,30 @@ static int open_output_file(OptionsContext *o, const char *filename)
>           /* audio: most channels */
>           if (!o->audio_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_AUDIO) != AV_CODEC_ID_NONE) {
>               int best_score = 0, idx = -1;
> -            for (i = 0; i < nb_input_streams; i++) {
> -                int score;
> -                ist = input_streams[i];
> -                score = ist->st->codecpar->channels
> -                        + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
> -                        + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
> -                if (ist->user_set_discard == AVDISCARD_ALL)
> -                    continue;
> -                if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
> -                    score > best_score) {
> -                    best_score = score;
> -                    idx = i;
> +            for (j = 0; j < nb_input_files; j++) {
> +                InputFile *ifile = input_files[j];
> +                int file_best_score = 0, file_best_idx = -1;
> +                for (i = 0; i < ifile->nb_streams; i++) {
> +                    int score;
> +                    ist = input_streams[ifile->ist_index + i];
> +                    score = ist->st->codecpar->channels
> +                            + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
> +                            + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
> +                    if (ist->user_set_discard == AVDISCARD_ALL)
> +                        continue;
> +                    if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
> +                        score > file_best_score) {
> +                        file_best_score = score;
> +                        file_best_idx = ifile->ist_index + i;
> +                    }
>                   }
> +                if (file_best_idx >= 0) {
> +                    file_best_score -= 5000000*!!(input_streams[file_best_idx]->st->disposition & AV_DISPOSITION_DEFAULT);
> +                    if (file_best_score > best_score) {
> +                        best_score = file_best_score;
> +                        idx = file_best_idx;
> +                    }
> +               }
>               }
>               if (idx >= 0)
>                   new_audio_stream(o, oc, idx);
Gyan Doshi Aug. 1, 2021, 4:22 a.m. UTC | #2
Pushed as c50f5460d2f059e5be393eac90e4eac55a6034c6

On 2021-07-31 09:32, Gyan Doshi wrote:
> Plan to push tomorrow.
>
> On 2021-07-29 10:14, Gyan Doshi wrote:
>> 11d3b03fcb added consideration of default stream disposition for audio
>> and video when choosing the 'best' stream among all the inputs. This can
>> lead to video streams with lower resolution or audio streams with fewer
>> channels being selected.
>>
>> Stream disposition, however, only sets a priority for a stream
>> among all other streams in the *same input*. It cannot set a priority
>> for a stream across all inputs.
>>
>> This patch sets a middle-way and selects the best stream from each file
>> with default disposition considered. Then it discards disposition weight
>> and selects best stream as per the original criteria of highest
>> resolution for video and most channels for audio.
>> ---
>>   fftools/ffmpeg_opt.c | 77 ++++++++++++++++++++++++++++----------------
>>   1 file changed, 50 insertions(+), 27 deletions(-)
>>
>> diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
>> index 1b43bab9fc..34cc6c4fd3 100644
>> --- a/fftools/ffmpeg_opt.c
>> +++ b/fftools/ffmpeg_opt.c
>> @@ -2260,23 +2260,35 @@ static int open_output_file(OptionsContext 
>> *o, const char *filename)
>>           if (!o->video_disable && av_guess_codec(oc->oformat, NULL, 
>> filename, NULL, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE) {
>>               int best_score = 0, idx = -1;
>>               int qcr = avformat_query_codec(oc->oformat, 
>> oc->oformat->video_codec, 0);
>> -            for (i = 0; i < nb_input_streams; i++) {
>> -                int score;
>> -                ist = input_streams[i];
>> -                score = ist->st->codecpar->width * 
>> ist->st->codecpar->height
>> -                           + 100000000 * !!(ist->st->event_flags & 
>> AVSTREAM_EVENT_FLAG_NEW_PACKETS)
>> -                           + 5000000*!!(ist->st->disposition & 
>> AV_DISPOSITION_DEFAULT);
>> -                if (ist->user_set_discard == AVDISCARD_ALL)
>> -                    continue;
>> -                if((qcr!=MKTAG('A', 'P', 'I', 'C')) && 
>> (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
>> -                    score = 1;
>> -                if (ist->st->codecpar->codec_type == 
>> AVMEDIA_TYPE_VIDEO &&
>> -                    score > best_score) {
>> -                    if((qcr==MKTAG('A', 'P', 'I', 'C')) && 
>> !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
>> +            for (j = 0; j < nb_input_files; j++) {
>> +                InputFile *ifile = input_files[j];
>> +                int file_best_score = 0, file_best_idx = -1;
>> +                for (i = 0; i < ifile->nb_streams; i++) {
>> +                    int score;
>> +                    ist = input_streams[ifile->ist_index + i];
>> +                    score = ist->st->codecpar->width * 
>> ist->st->codecpar->height
>> +                               + 100000000 * !!(ist->st->event_flags 
>> & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
>> +                               + 5000000*!!(ist->st->disposition & 
>> AV_DISPOSITION_DEFAULT);
>> +                    if (ist->user_set_discard == AVDISCARD_ALL)
>>                           continue;
>> -                    best_score = score;
>> -                    idx = i;
>> +                    if((qcr!=MKTAG('A', 'P', 'I', 'C')) && 
>> (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
>> +                        score = 1;
>> +                    if (ist->st->codecpar->codec_type == 
>> AVMEDIA_TYPE_VIDEO &&
>> +                        score > file_best_score) {
>> +                        if((qcr==MKTAG('A', 'P', 'I', 'C')) && 
>> !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
>> +                            continue;
>> +                        file_best_score = score;
>> +                        file_best_idx = ifile->ist_index + i;
>> +                    }
>>                   }
>> +                if (file_best_idx >= 0) {
>> +                    if((qcr == MKTAG('A', 'P', 'I', 'C')) || 
>> !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
>> +                        file_best_score -= 
>> 5000000*!!(input_streams[file_best_idx]->st->disposition & 
>> AV_DISPOSITION_DEFAULT);
>> +                    if (file_best_score > best_score) {
>> +                        best_score = file_best_score;
>> +                        idx = file_best_idx;
>> +                    }
>> +               }
>>               }
>>               if (idx >= 0)
>>                   new_video_stream(o, oc, idx);
>> @@ -2285,19 +2297,30 @@ static int open_output_file(OptionsContext 
>> *o, const char *filename)
>>           /* audio: most channels */
>>           if (!o->audio_disable && av_guess_codec(oc->oformat, NULL, 
>> filename, NULL, AVMEDIA_TYPE_AUDIO) != AV_CODEC_ID_NONE) {
>>               int best_score = 0, idx = -1;
>> -            for (i = 0; i < nb_input_streams; i++) {
>> -                int score;
>> -                ist = input_streams[i];
>> -                score = ist->st->codecpar->channels
>> -                        + 100000000 * !!(ist->st->event_flags & 
>> AVSTREAM_EVENT_FLAG_NEW_PACKETS)
>> -                        + 5000000*!!(ist->st->disposition & 
>> AV_DISPOSITION_DEFAULT);
>> -                if (ist->user_set_discard == AVDISCARD_ALL)
>> -                    continue;
>> -                if (ist->st->codecpar->codec_type == 
>> AVMEDIA_TYPE_AUDIO &&
>> -                    score > best_score) {
>> -                    best_score = score;
>> -                    idx = i;
>> +            for (j = 0; j < nb_input_files; j++) {
>> +                InputFile *ifile = input_files[j];
>> +                int file_best_score = 0, file_best_idx = -1;
>> +                for (i = 0; i < ifile->nb_streams; i++) {
>> +                    int score;
>> +                    ist = input_streams[ifile->ist_index + i];
>> +                    score = ist->st->codecpar->channels
>> +                            + 100000000 * !!(ist->st->event_flags & 
>> AVSTREAM_EVENT_FLAG_NEW_PACKETS)
>> +                            + 5000000*!!(ist->st->disposition & 
>> AV_DISPOSITION_DEFAULT);
>> +                    if (ist->user_set_discard == AVDISCARD_ALL)
>> +                        continue;
>> +                    if (ist->st->codecpar->codec_type == 
>> AVMEDIA_TYPE_AUDIO &&
>> +                        score > file_best_score) {
>> +                        file_best_score = score;
>> +                        file_best_idx = ifile->ist_index + i;
>> +                    }
>>                   }
>> +                if (file_best_idx >= 0) {
>> +                    file_best_score -= 
>> 5000000*!!(input_streams[file_best_idx]->st->disposition & 
>> AV_DISPOSITION_DEFAULT);
>> +                    if (file_best_score > best_score) {
>> +                        best_score = file_best_score;
>> +                        idx = file_best_idx;
>> +                    }
>> +               }
>>               }
>>               if (idx >= 0)
>>                   new_audio_stream(o, oc, idx);
>
> _______________________________________________
> 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".
diff mbox series

Patch

diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index 1b43bab9fc..34cc6c4fd3 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -2260,23 +2260,35 @@  static int open_output_file(OptionsContext *o, const char *filename)
         if (!o->video_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE) {
             int best_score = 0, idx = -1;
             int qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0);
-            for (i = 0; i < nb_input_streams; i++) {
-                int score;
-                ist = input_streams[i];
-                score = ist->st->codecpar->width * ist->st->codecpar->height
-                           + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
-                           + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
-                if (ist->user_set_discard == AVDISCARD_ALL)
-                    continue;
-                if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
-                    score = 1;
-                if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
-                    score > best_score) {
-                    if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+            for (j = 0; j < nb_input_files; j++) {
+                InputFile *ifile = input_files[j];
+                int file_best_score = 0, file_best_idx = -1;
+                for (i = 0; i < ifile->nb_streams; i++) {
+                    int score;
+                    ist = input_streams[ifile->ist_index + i];
+                    score = ist->st->codecpar->width * ist->st->codecpar->height
+                               + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
+                               + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
+                    if (ist->user_set_discard == AVDISCARD_ALL)
                         continue;
-                    best_score = score;
-                    idx = i;
+                    if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+                        score = 1;
+                    if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
+                        score > file_best_score) {
+                        if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+                            continue;
+                        file_best_score = score;
+                        file_best_idx = ifile->ist_index + i;
+                    }
                 }
+                if (file_best_idx >= 0) {
+                    if((qcr == MKTAG('A', 'P', 'I', 'C')) || !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+                        file_best_score -= 5000000*!!(input_streams[file_best_idx]->st->disposition & AV_DISPOSITION_DEFAULT);
+                    if (file_best_score > best_score) {
+                        best_score = file_best_score;
+                        idx = file_best_idx;
+                    }
+               }
             }
             if (idx >= 0)
                 new_video_stream(o, oc, idx);
@@ -2285,19 +2297,30 @@  static int open_output_file(OptionsContext *o, const char *filename)
         /* audio: most channels */
         if (!o->audio_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_AUDIO) != AV_CODEC_ID_NONE) {
             int best_score = 0, idx = -1;
-            for (i = 0; i < nb_input_streams; i++) {
-                int score;
-                ist = input_streams[i];
-                score = ist->st->codecpar->channels
-                        + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
-                        + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
-                if (ist->user_set_discard == AVDISCARD_ALL)
-                    continue;
-                if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
-                    score > best_score) {
-                    best_score = score;
-                    idx = i;
+            for (j = 0; j < nb_input_files; j++) {
+                InputFile *ifile = input_files[j];
+                int file_best_score = 0, file_best_idx = -1;
+                for (i = 0; i < ifile->nb_streams; i++) {
+                    int score;
+                    ist = input_streams[ifile->ist_index + i];
+                    score = ist->st->codecpar->channels
+                            + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
+                            + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
+                    if (ist->user_set_discard == AVDISCARD_ALL)
+                        continue;
+                    if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
+                        score > file_best_score) {
+                        file_best_score = score;
+                        file_best_idx = ifile->ist_index + i;
+                    }
                 }
+                if (file_best_idx >= 0) {
+                    file_best_score -= 5000000*!!(input_streams[file_best_idx]->st->disposition & AV_DISPOSITION_DEFAULT);
+                    if (file_best_score > best_score) {
+                        best_score = file_best_score;
+                        idx = file_best_idx;
+                    }
+               }
             }
             if (idx >= 0)
                 new_audio_stream(o, oc, idx);