-
-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Greenish tint in the output #240
Comments
The phenomenon appears to be hardware agnostic, the same effect occurs when the Vulkan filter device is AMD Hawk Point instead of Intel DG2.
|
Does it happen for e.g. |
Need to verify it using other samples however, it does not seem to affect 420P or even the 420P10 as long as it is SDR content (bt. 709). |
After testing on a different source, there is definitely a difference with 420P input as well. Placebo (Crop): https://www.nle-chipcraft.com/Git/CobraPLC.png LAV (Crop): |
can you show me where the ycbcr -> RGB conversation code is there are already 3 colorspace i found and none had them in them AFAIK. mpdn had a similar issue and i want to check a number. |
Sorry, I'm still trying to get around to this; I should have the time later this week. You can find the colormatrix generation code here: https://github.com/haasn/libplacebo/blob/master/src/colorspace.c#L1412 With test cases here: https://github.com/haasn/libplacebo/blob/master/src/tests/colorspace.c Probably the simplest place to start would be to add more unit tests with hard-coded reference matrices, e.g. https://github.com/haasn/libplacebo/blob/master/src/tests/colorspace.c#L201 But, I highly suspect that the actual color matrices are correct, and the issue comes from someplace else. |
It would be easier also if you could reproduce the problem on a static test pattern with known YCbCr values, such as |
https://forum.doom9.org/showthread.php?p=1713449#post1713449 i grab a ire test pattern later. the one i created on the fast has a general tint. |
So for 8-bit we have:
Edit: Nvm, I see; the issue is about 128 vs 127.5? But that is clearly not the case here, as we use 128, not 127.5. |
Furthermore, |
don't waste your time to explain yourself to me. i just remember someone very competent had a similar issue. |
My own testing: Generation
Exact bit values
So, zscale and libplacebo are a near match here (the difference is about 2^-12, which is below the human perceptibility threshold), and swscale is significantly different from both. Reference computationUsing the exact numbers taken from the BT.601 specification, courtesy of https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion, and plugging in the actual 8-bit source YCbCr value ( y = 162
cb = 44
cr = 142
(rd, gd, bd) = (yrgb + crr, yrgb - 0.114/0.587 * cbb - 0.299/0.587 * crr, yrgb + cbb)
where yrgb = 255/219 * (y - 16)
crr = 255/224 * 1.402 * (cr - 128)
cbb = 255/224 * 1.772 * (cb - 128)
EvaluationThis is the MSE of each approach, versus the reference computation:
So we can see that swscale is the least accurate here. Intuitively, this is what we should expect - swscale uses exclusively 16-bit integer math, libplacebo uses 32-bit floating point math, and zscale probably uses a mix of 64-bit float math (for matrices) and 16-bit lookup tables. ConclusionI could find no bug in libplacebo when comparing the output of |
I tried repeating the same test with
Same pattern - swscale differs (in this case by about 2^-8, a noticeable amount), zscale and libplacebo match. |
Edit: My invocation was correct, I forgot to specify
This gives us an MSE of:
|
@Chipcraft can you share more details about the original input file? Maybe a log with |
Debug log on the input
|
@Chipcraft's file is not dovi |
I you look closely, the green channel is also very slightly off, but in the opposite direction. Considering the green channel is usually the luma channel minus the red and blue offsets (times some small-ish scaling factor), this makes perfect sense. So wait, could you clarify, @Chipcraft, is this a DV profile 5 source file? |
The movie itself has P7 FEL however, libplacebo is only used on the base level bitstream (no EL or RPU). The EL is on a separate file at this point, not even in the same container. Also, "apply_dolbyvision" 0/1 obviously makes no difference here, I've checked that as well. |
Here is another sample. The source is 8K yuv420p10le(tv, bt2020nc/bt2020/smpte2084) AV1. From here: https://www.youtube.com/watch?v=OdYsO1FAFQk Here is one frame extracted (copy) from it (I frame at 00:02:55); https://nle-chipcraft.com/Git/Georgia/Georgia_1F.obu An encode, with crop done by lavfilters: https://nle-chipcraft.com/Git/Georgia/Georgia_LAV.mkv
Debug logffmpeg version N-113620-g3be80ce299 Copyright (c) 2000-2024 the FFmpeg developers An encode, with crop done by libplacebo: https://nle-chipcraft.com/Git/Georgia/Georgia_PLC.mkv
Debug logffmpeg version N-113620-g3be80ce299 Copyright (c) 2000-2024 the FFmpeg developers |
btw, since when is there a free version of DaVinci Resolve? |
I knew it was a fool's errand however, decided to test anyways.
|
Would it be correct to assume that using "libplacebo=format=yuv420p10le" on an input, that is already in yuv420p10le format would result in either a bit-exact output, or at the very least something with a difference below the limit of the human perception? Even in this case, the output from libplacebo features the same exact issue, as the previous test cases.
Debug log
Debug log
|
i found something that will not explain a colroshift but is oddly different. the ire 10 03-10% Gray.mp4 is a mix of 24 and 25 on madVR or with color dithering a 25 24 25, 24 25 24, and very rare others so time for video-output-levels=limited madVR limited so either the file is bad and has a static 37 and madVR is magickly making it 37.1 or there is something going on here. only screengrabs have been used not screenshot functions. no scaling only chroma no filter just nothing. edit: more accurate measurement using only the 250x250 cantered pixels and infranview: 2.19x10+16 = 37.9 mpv: my best guess is it doesn't dither with limited range output creating this massive error and the file is Y 37. |
Passing either RGBA or BGRA pixel formats through libplacebo's "format" results in a bit-exact output however, that is not the case with either YUV420P or YUV420P10 (and potentially others).
Meanwhile, for YUV420P or YUV420P10 inputs, the "-vf libplacebo=format=yuv420p" or "-vf libplacebo=format=yuv420p10" introduces the green tint in the output. Also, introduced a third filter for testing purposes: VPP_QSV. The output from VPP_QSV (Crop) results in a bit-exact output with LAV. LAV (Crop):
libplacebo (Crop):
VPP_QSV (Crop):
|
No, libplacebo uses a fully RGB internal pipeline, so both input/output to yuv420p will require conversion (upscaling, downscaling, YCbCr<->RGB).. |
an error in chroma scaling could create such an error couldn't it? |
Indeed. Maybe something you can try is comparing:
To see which of these combinations are affected |
|
that leaves rgb conversation but that looked good on paper. does libplacebo do RGB full/limited directly or always one and then level correct them? meaning it's so unlikely but the level conversation? it's maybe done twice in this yuv420p -> yuv420p workflow or not at all. |
The issue appears to be related to the height of the input frame. The RGB to YUV output is in line with LAV as long as the frame height is < 577 pixels. RGB 55AAFFh to YUV420P Input height 576 pixels: LAV libplacebo Y = 94/95h Input height >= 577 pixels: LAV libplacebo EDIT: I suppose this is not the issue here. |
if no meta data is provided it may guess bt 601 instead of bt 709 |
Output from the RGB-to-YUV conversion is identical regardless of the flagged colorspace, primaries, transfer and range in FFMpeg. It only changes depending on the resolution (i.e., <= 576 height and >= 577).
They both produce an identical output. |
On latest FFmpeg master, YUV space and range are auto-negotiated, but color primaries and TRC are not yet. I'm working on that (tm). So your command does nothing, because vf_libplacebo does not know about what tags you're setting "downstream". |
but what does libplacebo guess differently between pal resolution and bigger than pal resolution? so we may get closer to the reason of this problem? |
Found the issue. LAV
"LAV_Reference.yuv" and "LAV_Decompress.yuv" are a bit-exact match. libplacebo
Not only neither the "PLC_Decompress.yuv" or the "PLC_Decompress-2.yuv" are a bit-exact match with the "PLC_Reference.yuv", but also the "PLC_Decompress.yuv" and "PLC_Decompress-2.yuv" differ between each other. The encoded output between the "PLC_Packed.yuv" and "PLC_Decompress.yuv" are a bit-exact match. Meanwhile, the output from "PLC_Decompress-2.yuv" source still illustrates the issue, however the difference is smaller than with "PLC_Packed.yuv" / "PLC_Decompress.yuv". Encode parameters
Outputs Source ( LAV ( libplacebo ( libplacebo ( libplacebo ( |
Libplacebo filtering causes the output image to feature a greenish tint. In this case, libplacebo was used for cropping.
Otherwise the same workflow, using lavfilter crop-filter instead of libplacebo does not illustrate this behavior.
Input: Stream #0:0: Video: hevc (Main 10), yuv420p10le(tv, bt2020nc/bt2020/smpte2084), 3840x2160 [SAR 1:1 DAR 16:9] // HDR10 BL
libplacebo (master) - 34e019b
ffmpeg (master) - FFmpeg/FFmpeg@34a47b9
Command w/ libplacebo:
ffmpeg -init_hw_device vulkan -i Input_BL.h265 -bsf:v hevc_metadata=chroma_sample_loc_type=2 -vf libplacebo=crop_w=3840:crop_h=1600:w=3840:h=1600 -c:v hevc_qsv -preset veryslow -scenario archive -profile:v main10 -level:v 51 -tier high -global_quality 14 -flags +cgop -g 120 -pix_fmt p010le -loglevel verbose Placebo_Out.h265
Command w/ lavfilter:
ffmpeg -init_hw_device vulkan -i Input_BL.h265 -bsf:v hevc_metadata=chroma_sample_loc_type=2 -vf crop=3840:1600:0:280 -c:v hevc_qsv -preset veryslow -scenario archive -profile:v main10 -level:v 51 -tier high -global_quality 14 -flags +cgop -g 120 -pix_fmt p010le -loglevel verbose Lavfilter_Out.h265
The text was updated successfully, but these errors were encountered: