From: Niklas Haas <ffmpeg@haasn.xyz>
To: ffmpeg-devel@ffmpeg.org
Cc: Niklas Haas <git@haasn.dev>
Subject: [FFmpeg-devel] [PATCH] avfilter: fix YUV colorspace negotiation for YUVJ
Date: Mon, 25 Mar 2024 14:40:44 +0100
Message-ID: <20240325134044.17030-1-ffmpeg@haasn.xyz> (raw)
From: Niklas Haas <git@haasn.dev>
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".
next reply other threads:[~2024-03-25 13:40 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-25 13:40 Niklas Haas [this message]
2024-03-25 15:10 ` Niklas Haas
2024-03-28 12:55 ` Niklas Haas
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=20240325134044.17030-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