Message ID | 20231028144430.60538-8-ffmpeg@haasn.xyz |
---|---|
State | New |
Headers | show |
Series | YUVJ removal preliminary cleanup | expand |
Context | Check | Description |
---|---|---|
yinshiyou/make_loongarch64 | success | Make finished |
yinshiyou/make_fate_loongarch64 | success | Make fate finished |
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
On Sat, Oct 28, 2023 at 04:41:14PM +0200, Niklas Haas wrote: > From: Niklas Haas <git@haasn.dev> > > YUV->YUV conversions should preserve input range, if the output range is > unspecified. Ensures full-range YUV input comes out as full-range YUV > output by default, even through YUV->YUV pixel format conversions. > --- > libavfilter/vf_scale.c | 23 +++++++++++++++++++++++ > 1 file changed, 23 insertions(+) this seems to change the output of the following: ffmpeg -i 4493/AVCI100.mov -vframes 3 -bitexact file.nut did not investigate if this is a bug or bugfix files are here: https://samples.ffmpeg.org/ffmpeg-bugs/trac/ticket524/ [...]
On Tue, 31 Oct 2023 00:42:47 +0100 Michael Niedermayer <michael@niedermayer.cc> wrote: > On Sat, Oct 28, 2023 at 04:41:14PM +0200, Niklas Haas wrote: > > From: Niklas Haas <git@haasn.dev> > > > > YUV->YUV conversions should preserve input range, if the output range is > > unspecified. Ensures full-range YUV input comes out as full-range YUV > > output by default, even through YUV->YUV pixel format conversions. > > --- > > libavfilter/vf_scale.c | 23 +++++++++++++++++++++++ > > 1 file changed, 23 insertions(+) > > this seems to change the output of the following: > ffmpeg -i 4493/AVCI100.mov -vframes 3 -bitexact file.nut > did not investigate if this is a bug or bugfix > > files are here: https://samples.ffmpeg.org/ffmpeg-bugs/trac/ticket524/ Seems like it's a regression. mpeg4 does not support full range YUV, so giving it full range YUV causes wrong levels to be saved. I will drop this commit from this series and include it as part of the filter negotiation series, since that one has the necessary infrastructure to handle this more gracefully.
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 3d58de0494..cde6f52169 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -687,6 +687,27 @@ static int scale_field(ScaleContext *scale, AVFrame *dst, AVFrame *src, return 0; } +static int is_regular_yuv(enum AVPixelFormat fmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); + if (desc->flags & (AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PAL)) + return 0; + if (desc->name && av_strstart(desc->name, "xyz", NULL)) + return 0; + if (desc->nb_components < 3) + return 0; /* grayscale is forced full range inside libswscale */ + 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; + } +} + static int scale_frame(AVFilterLink *link, AVFrame *in, AVFrame **frame_out) { AVFilterContext *ctx = link->dst; @@ -794,6 +815,8 @@ scale: in_full = in->color_range == AVCOL_RANGE_JPEG; if (scale->out_range != AVCOL_RANGE_UNSPECIFIED) out_full = scale->out_range == AVCOL_RANGE_JPEG; + else if (is_regular_yuv(in->format) && is_regular_yuv(outlink->format)) + out_full = in_full; /* preserve pixel range by default */ if (in->width == outlink->w && in->height == outlink->h &&
From: Niklas Haas <git@haasn.dev> YUV->YUV conversions should preserve input range, if the output range is unspecified. Ensures full-range YUV input comes out as full-range YUV output by default, even through YUV->YUV pixel format conversions. --- libavfilter/vf_scale.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)