From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id C38EA49974 for ; Mon, 25 Mar 2024 13:40:54 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9D09C68D517; Mon, 25 Mar 2024 15:40:53 +0200 (EET) Received: from haasn.dev (haasn.dev [78.46.187.166]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2129E68D507 for ; Mon, 25 Mar 2024 15:40:47 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=haasn.xyz; s=mail; t=1711374046; bh=BC9IlcZJ1riAnNUX0k7qligyqD1qSRVoCQxVIz/845I=; h=From:To:Cc:Subject:Date:From; b=uOb6imXVDrhqD+mFsxDfKzu/SEylira8L9ilMemDxZIE92kwMQLEXiP5ddaxraxgn Q65Vi0qugerHsfbXpuyWUulaMTfpQLfrCAz81q68dVLA6GJYz0IvcD1MmuhSrfYtsH XDuO15yDB3e6xtpk4Vnt+DFFuB2LxsY3/mU+O/X0= Received: from haasn.dev (unknown [10.30.0.2]) by haasn.dev (Postfix) with ESMTP id DE42E41128; Mon, 25 Mar 2024 14:40:46 +0100 (CET) From: Niklas Haas To: ffmpeg-devel@ffmpeg.org Date: Mon, 25 Mar 2024 14:40:44 +0100 Message-ID: <20240325134044.17030-1-ffmpeg@haasn.xyz> X-Mailer: git-send-email 2.44.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avfilter: fix YUV colorspace negotiation for YUVJ X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Niklas Haas Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: From: Niklas Haas Ironically, despite being introduced to make YUVJ unnecessary, the new YUV negotiation logic failed to actually negotiate YUVJ formats themselves correctly, leading to errors when passing YUVJ frames into a filter graph. (They were effectively treated like RGB or Grayscale formats, rather than as forced-full-range YUV, and hence did not have their colorspace matrix correctly negotiated) Fix this by splitting off the YUVJ check from ff_fmt_is_regular_yuv(). Obviously, we can trivially undo this change again once YUVJ is actually deleted from the codebase. --- libavfilter/avfiltergraph.c | 31 +++++++++++++++++++------------ libavfilter/buffersrc.c | 15 ++++++++++----- libavfilter/internal.h | 5 +++++ 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index bb5399c55e8..bc63cb88f32 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -610,19 +610,22 @@ int ff_fmt_is_regular_yuv(enum AVPixelFormat fmt) if (desc->nb_components < 3) return 0; /* Grayscale is explicitly full-range in swscale */ av_assert1(!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)); - if (desc->flags & (AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PAL | - AV_PIX_FMT_FLAG_XYZ | AV_PIX_FMT_FLAG_FLOAT)) - return 0; + return !(desc->flags & (AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PAL | + AV_PIX_FMT_FLAG_XYZ | AV_PIX_FMT_FLAG_FLOAT)); +} + +int ff_fmt_is_forced_full_range(enum AVPixelFormat fmt) +{ switch (fmt) { case AV_PIX_FMT_YUVJ420P: case AV_PIX_FMT_YUVJ422P: case AV_PIX_FMT_YUVJ444P: case AV_PIX_FMT_YUVJ440P: case AV_PIX_FMT_YUVJ411P: - return 0; - default: return 1; + default: + return 0; } } @@ -698,14 +701,18 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) link->incfg.color_spaces->nb_formats = 1; link->colorspace = link->incfg.color_spaces->formats[0]; - if (!link->incfg.color_ranges->nb_formats) { - av_log(link->src, AV_LOG_ERROR, "Cannot select color range for" - " the link between filters %s and %s.\n", link->src->name, - link->dst->name); - return AVERROR(EINVAL); + if (ff_fmt_is_forced_full_range(swfmt)) { + link->color_range = AVCOL_RANGE_JPEG; + } else { + if (!link->incfg.color_ranges->nb_formats) { + av_log(link->src, AV_LOG_ERROR, "Cannot select color range for" + " the link between filters %s and %s.\n", link->src->name, + link->dst->name); + return AVERROR(EINVAL); + } + link->incfg.color_ranges->nb_formats = 1; + link->color_range = link->incfg.color_ranges->formats[0]; } - link->incfg.color_ranges->nb_formats = 1; - link->color_range = link->incfg.color_ranges->formats[0]; } } else if (link->type == AVMEDIA_TYPE_AUDIO) { int ret; diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index ddcd4037859..4082a93dfd9 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -459,12 +459,17 @@ static int query_formats(AVFilterContext *ctx) if ((ret = ff_add_format(&color_spaces, c->color_space)) < 0 || (ret = ff_set_common_color_spaces(ctx, color_spaces)) < 0) return ret; - if ((ret = ff_add_format(&color_ranges, c->color_range)) < 0) - return ret; - if (c->color_range == AVCOL_RANGE_UNSPECIFIED) { - /* allow implicitly promoting unspecified to mpeg */ - if ((ret = ff_add_format(&color_ranges, AVCOL_RANGE_MPEG)) < 0) + if (ff_fmt_is_forced_full_range(swfmt)) { + if ((ret = ff_add_format(&color_ranges, AVCOL_RANGE_JPEG)) < 0) + return ret; + } else { + if ((ret = ff_add_format(&color_ranges, c->color_range)) < 0) return ret; + if (c->color_range == AVCOL_RANGE_UNSPECIFIED) { + /* allow implicitly promoting unspecified to mpeg */ + if ((ret = ff_add_format(&color_ranges, AVCOL_RANGE_MPEG)) < 0) + return ret; + } } if ((ret = ff_set_common_color_ranges(ctx, color_ranges)) < 0) return ret; diff --git a/libavfilter/internal.h b/libavfilter/internal.h index 000f94cb164..294e54d1410 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -199,6 +199,11 @@ int ff_fmt_is_in(int fmt, const int *fmts); */ int ff_fmt_is_regular_yuv(enum AVPixelFormat fmt); +/** + * Returns true if a YUV pixel format is forced full range. (i.e. YUVJ). + */ +int ff_fmt_is_forced_full_range(enum AVPixelFormat fmt); + /* Functions to parse audio format arguments */ /** -- 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".