From patchwork Mon Mar 25 13:40:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Niklas Haas X-Patchwork-Id: 47425 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:c889:b0:1a3:b6bb:3029 with SMTP id hb9csp1195503pzb; Mon, 25 Mar 2024 06:40:57 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVZbXR29AF4asXMxgBw5eZPAm+NOZG8PvlvwIM5f9S6WFW4LQRRkEPal7Ioq4qS34c+8KPlioSBjIk7KDuOdnTq7C4IFzGuAHHz0A== X-Google-Smtp-Source: AGHT+IE7/Bej5nZddZecWLjmtH19tFKI3CoHz0J4uKwApWB9rU3lKJeRZXoxjBzOhQKUxZi88qg2 X-Received: by 2002:a17:906:c047:b0:a46:9e27:c250 with SMTP id bm7-20020a170906c04700b00a469e27c250mr4268254ejb.6.1711374056865; Mon, 25 Mar 2024 06:40:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1711374056; cv=none; d=google.com; s=arc-20160816; b=qMWAzC2px/xjUvI3S9IgG7i0Ee1A4jOBnIrc5EXoStWGB56AinyBHMCUlTCVe0Tv97 TxRM1t72NUpVm2HAl8O51IZiepKUxochZFiDBoXftfEnpShWYch1re9h+E3fQpPyaGcl /m1bMUdDhWY4HJG2QbeAy5e4tcZndV740wKQ+F/OFM4xClmS6VbecfsEIZaaArRM513C MEtjMDcwdwRylaIbxH63gf62Bv+dR87n6DME474QAH9fXZKm4kQaOq5O0KRPrmS2QLmv K1kMJuQDQNVuDUrNGJCuYQkz/ieqx3iAeuKCIqpchajKedXg0b1grGyDVmdbWpL/sptj YKWA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=Z1XweVbjpVUsmpdQA9K/LgDyTaUvyqSpw4M81ge2TZs=; fh=xmAeKtysnShNOmkhiJmYkS30uw4Fu2hvBJ7qlIwukxQ=; b=0alyaNODrnNbqOgxt7JTqOj2LwqPFh8uURKfuA8yJtyN6xfIW0PYSyq6YIZPOlgZYR x64lCQyJ5KS/mNrkjjOyuqYAFjDPZdZlklR3ok1xGVILAnh9gzd7sk92+PU9s2IrGLqK CoCb9/grQqtlFF2Y0y5FBWk5A2f55cWQA7kzmOmJgp5b3cm1mmpgdrZBjpC+tdihpWrV pEK0s9wUD81M61R61+IGacUkBFVrs1jvNr+BEKE0PCtkaogN/+6E8w0OdsFGVjT8daIH NXWd5dXQsAl3bxNAzWjCDcGt7m1xprptZe2pwKPTwBYeguqJjtOIw8fxzhfTWSkSKBzU UkVA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@haasn.xyz header.s=mail header.b=uOb6imXV; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id u18-20020a170906125200b00a46a922ddebsi2441055eja.642.2024.03.25.06.40.56; Mon, 25 Mar 2024 06:40:56 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@haasn.xyz header.s=mail header.b=uOb6imXV; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D796C68D51E; Mon, 25 Mar 2024 15:40:53 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: k8czYZzNi0nU 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 */ /**