[FFmpeg-devel] [PATCH v3] ffmpeg_opt: restore documented stream selection behaviour
Gyan Doshi
ffmpeg at gyani.pro
Sat Jul 31 07:02:15 EEST 2021
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);
More information about the ffmpeg-devel
mailing list