From patchwork Tue Sep 10 13:18:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Niklas Haas X-Patchwork-Id: 51492 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:612c:41b1:b0:48e:c0f8:d0de with SMTP id le49csp403217vqb; Tue, 10 Sep 2024 06:18:32 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWZOYBi5Ftsod73QPIHJGNQQNSB4nIsMH5VNCthh/nSO3cU8X0dueloQHga5rjyogRdxisV186SSVOkfgBd+qSu@gmail.com X-Google-Smtp-Source: AGHT+IGftKqCIp3ThdD8hrUxnnGbYqrNj9PaaLSOFzOXCNkc0g+jMYGEeOEa1wcQVMyHF5sEOT2w X-Received: by 2002:a5d:6d84:0:b0:374:ca15:e7b1 with SMTP id ffacd0b85a97d-3788973f712mr4933101f8f.10.1725974312101; Tue, 10 Sep 2024 06:18:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1725974312; cv=none; d=google.com; s=arc-20240605; b=LkLRQVJ25RTvxximRjkoX438hNNfLfSAq4XAuSsh3SRRPl1Guwl4bxQugT8te12ger 0IvkFp0EHDRxMZiBUZAj2l8F6Y7I9BEStk6HrIjr59GnUUuDXpz+AXd76E9U+a+lW2/u umMvcuSRyNyLCYNgtogb8Op+QimUdxI6FlC+PDGU9aPDM99p8aBLBgNoYfY9IdTsP9AB Iib5pwDEjFlWjqB7oTBJaI88KT6TQNoUhDyMabeHSBBT5BcQU0soEq9qo1SYI4y/u6lq WRDfEOGhFX8UfVIw1dIZS62dLGLPGrHdULvqg46NcZYi77S8M9Bo/qph9+pm9FwipiCE iYzg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; 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:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=A7VG0fTjJkYd6hBoh8LI3lfSW3k1UVYB/NnM5XM77wY=; fh=xmAeKtysnShNOmkhiJmYkS30uw4Fu2hvBJ7qlIwukxQ=; b=iTd5pfQANl+pupqhfXu419oa20OdEIsd6ZOKJTBhQVA9XD55/1xWKhq0GlRBXWRkUb ka2tKoxYFCZER/7dwspBDIm+gMBQAQ9kiF7fsiYbVmAnXhJvbiauhtD+wXU7SfSJRvsb RucvibfBnmgcWqeo15i0QM+d3duTK0p2F7ItNz7W5EwD0ZTDdDP376lcK73orO2HhywP cOJNiKAmmtkIXE4rLKCsWCpBVEfU8L0KAaPbocXBs2rpAbuxWBIXZu+4l1VFT0d9Z0Aj dSjY27IwwngS9cNpm0PKSg0Wnn0oqjALz+9NlxJCwtRLIRlYl9e20O/lDIHvuLgIocoG VZyA==; 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=b3LElJTy; 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 4fb4d7f45d1cf-5c3ebdb6c16si5624243a12.643.2024.09.10.06.18.30; Tue, 10 Sep 2024 06:18:32 -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=b3LElJTy; 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 4BF7868E117; Tue, 10 Sep 2024 16:18:27 +0300 (EEST) 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 2AC3D68DCC3 for ; Tue, 10 Sep 2024 16:18:21 +0300 (EEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=haasn.xyz; s=mail; t=1725974300; bh=Q8r7WZGHWQ4OuK/nUGOX7aETHJJek8zKja2NfGDYJL4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=b3LElJTyWXUuSookMZQvgWDYMEf9CeaA0YWAMKSgeCJpnuj6+/NF2T0wsBw4bSC/I IivWUJX5Rbc1de4UDvOCKiEwUkSaqnvmE/1/nNe2yq6eJAfMv+ziKfIFcdJxTcMKFW amHaNKoU693lNEmiMKp0ye4uqt1PAW+KtIaba7DY= Received: from haasn.dev (unknown [10.30.0.2]) by haasn.dev (Postfix) with ESMTP id CA35D40D6F; Tue, 10 Sep 2024 15:18:20 +0200 (CEST) From: Niklas Haas To: ffmpeg-devel@ffmpeg.org Date: Tue, 10 Sep 2024 15:18:16 +0200 Message-ID: <20240910131816.1482534-2-ffmpeg@haasn.xyz> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240910131816.1482534-1-ffmpeg@haasn.xyz> References: <20240910131816.1482534-1-ffmpeg@haasn.xyz> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v3 2/2] 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: qUl36A+qeXgW 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/video.h | 5 +++++ 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 3946f04b53..38077ff701 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -656,19 +656,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; } } @@ -744,14 +747,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 a3113f5c13..b5682006f0 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -461,12 +461,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/video.h b/libavfilter/video.h index 77f27fdf7c..f44d3445dc 100644 --- a/libavfilter/video.h +++ b/libavfilter/video.h @@ -51,4 +51,9 @@ AVFrame *ff_get_video_buffer(AVFilterLink *link, int w, int h); */ 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); + #endif /* AVFILTER_VIDEO_H */