From: Niklas Haas <ffmpeg@haasn.xyz> To: ffmpeg-devel@ffmpeg.org Cc: Niklas Haas <git@haasn.dev> Subject: [FFmpeg-devel] [PATCH] avfilter: properly reduce YUV colorspace format lists Date: Mon, 25 Mar 2024 16:10:20 +0100 Message-ID: <20240325151020.82220-1-ffmpeg@haasn.xyz> (raw) From: Niklas Haas <git@haasn.dev> Doing this with REDUCE_FORMATS() instead of swap_color_*() is not only shorter, but more importantly comes with the benefit of being done inside a loop, allowing us to correctly propagate complex graphs involving multiple conversion filters (e.g. -vf scale,zscale). The latter family of swapping functions is only used to settle the best *remaining* entry if no exact match was found, and as such was never the correct solution to YUV colorspaces, which only care about exact matches. --- libavfilter/avfiltergraph.c | 84 ++----------------------------------- 1 file changed, 4 insertions(+), 80 deletions(-) diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index bb5399c55e8..12ff7d6ffb9 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -794,6 +794,10 @@ static int reduce_formats_on_filter(AVFilterContext *filter) nb_formats, ff_add_format); REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats, nb_formats, ff_add_format); + REDUCE_FORMATS(int, AVFilterFormats, color_spaces, formats, + nb_formats, ff_add_format); + REDUCE_FORMATS(int, AVFilterFormats, color_ranges, formats, + nb_formats, ff_add_format); /* reduce channel layouts */ for (i = 0; i < filter->nb_inputs; i++) { @@ -906,82 +910,6 @@ static void swap_samplerates(AVFilterGraph *graph) swap_samplerates_on_filter(graph->filters[i]); } -static void swap_color_spaces_on_filter(AVFilterContext *filter) -{ - AVFilterLink *link = NULL; - enum AVColorSpace csp; - int i; - - for (i = 0; i < filter->nb_inputs; i++) { - link = filter->inputs[i]; - if (link->type == AVMEDIA_TYPE_VIDEO && - link->outcfg.color_spaces->nb_formats == 1) - break; - } - if (i == filter->nb_inputs) - return; - - csp = link->outcfg.color_spaces->formats[0]; - - for (i = 0; i < filter->nb_outputs; i++) { - AVFilterLink *outlink = filter->outputs[i]; - if (outlink->type != AVMEDIA_TYPE_VIDEO) - continue; - /* there is no meaningful 'score' between different yuv matrices, - * so just prioritize an exact match if it exists */ - for (int j = 0; j < outlink->incfg.color_spaces->nb_formats; j++) { - if (csp == outlink->incfg.color_spaces->formats[j]) { - FFSWAP(int, outlink->incfg.color_spaces->formats[0], - outlink->incfg.color_spaces->formats[j]); - break; - } - } - } -} - -static void swap_color_spaces(AVFilterGraph *graph) -{ - for (int i = 0; i < graph->nb_filters; i++) - swap_color_spaces_on_filter(graph->filters[i]); -} - -static void swap_color_ranges_on_filter(AVFilterContext *filter) -{ - AVFilterLink *link = NULL; - enum AVColorRange range; - int i; - - for (i = 0; i < filter->nb_inputs; i++) { - link = filter->inputs[i]; - if (link->type == AVMEDIA_TYPE_VIDEO && - link->outcfg.color_ranges->nb_formats == 1) - break; - } - if (i == filter->nb_inputs) - return; - - range = link->outcfg.color_ranges->formats[0]; - - for (i = 0; i < filter->nb_outputs; i++) { - AVFilterLink *outlink = filter->outputs[i]; - if (outlink->type != AVMEDIA_TYPE_VIDEO) - continue; - for (int j = 0; j < outlink->incfg.color_ranges->nb_formats; j++) { - if (range == outlink->incfg.color_ranges->formats[j]) { - FFSWAP(int, outlink->incfg.color_ranges->formats[0], - outlink->incfg.color_ranges->formats[j]); - break; - } - } - } -} - -static void swap_color_ranges(AVFilterGraph *graph) -{ - for (int i = 0; i < graph->nb_filters; i++) - swap_color_ranges_on_filter(graph->filters[i]); -} - #define CH_CENTER_PAIR (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER) #define CH_FRONT_PAIR (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT) #define CH_STEREO_PAIR (AV_CH_STEREO_LEFT | AV_CH_STEREO_RIGHT) @@ -1258,10 +1186,6 @@ static int graph_config_formats(AVFilterGraph *graph, void *log_ctx) if ((ret = reduce_formats(graph)) < 0) return ret; - /* for video filters, ensure that the best colorspace metadata is selected */ - swap_color_spaces(graph); - swap_color_ranges(graph); - /* for audio filters, ensure the best format, sample rate and channel layout * is selected */ swap_sample_fmts(graph); -- 2.44.0 _______________________________________________ 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".
next reply other threads:[~2024-03-25 15:10 UTC|newest] Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top 2024-03-25 15:10 Niklas Haas [this message] 2024-03-27 14:13 ` Damiano Galassi
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20240325151020.82220-1-ffmpeg@haasn.xyz \ --to=ffmpeg@haasn.xyz \ --cc=ffmpeg-devel@ffmpeg.org \ --cc=git@haasn.dev \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git