#9374 closed defect (duplicate)
mkv to mp4 has a color tint
Reported by: | razvan | Owned by: | |
---|---|---|---|
Priority: | normal | Component: | undetermined |
Version: | git-master | Keywords: | mp4 tint color |
Cc: | Blocked By: | ||
Blocking: | Reproduced by developer: | no | |
Analyzed by developer: | no |
Description
ubuntu 21.04
I have the same results on ubuntu and windows.
I am recording the screen in a lossless format to have small CPU load.
Here I use latest git version from johnvansickle.com
ffmpeg -video_size 1920x1200 -framerate 25 -f x11grab -i :0.0 -vcodec libx264rgb -crf 0 -preset ultrafast rec.mkv
Input #0, matroska,webm, from 'vid.mkv':
Metadata:
ENCODER : Lavf58.64.100
Duration: 00:00:29.67, start: 0.000000, bitrate: 2829 kb/s
Stream #0:0: Video: h264 (High 4:4:4 Predictive), gbrp(pc, gbr/unknown/unknown, progressive), 1920x1200, 30 fps, 30 tbr, 1k tbn, 60 tbc (default)
Metadata:
ENCODER : Lavc58.112.103 libx264rgb
DURATION : 00:00:29.666000000
then I convert/compress it in mp4
using latest git version from johnvansickle.com
ffmpeg -i rec.mkv -vcodec libx264 rec-git.mp4
ffprobe rec.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'rec.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf59.4.101
Duration: 00:00:02.16, start: 0.000000, bitrate: 719 kb/s
Stream #0:0(und): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), gbrp(tv, gbr/unknown/unknown), 1920x1200, 714 kb/s, 25 fps, 25 tbr, 12800 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
but the resulting mp4 is tinted by green and pink color (white areas are tinted green and dark areas are tinted pink)
I have the same result using ffmpeg 4.4 for mkv to mp4, mp4 is tinted in green and pink.
But if I use ffmpeg 4.3.1 for mkv to mp4 conversion the result is not tinted anymore
fprobe rec-4.3.1.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'rec-4.3.1.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.45.100
Duration: 00:00:02.16, start: 0.000000, bitrate: 716 kb/s
Stream #0:0(und): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv444p, 1920x1200, 711 kb/s, 25 fps, 25 tbr, 12800 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
Attachments (1)
Change History (13)
by , 3 years ago
Attachment: | test.tar.bz2 added |
---|
comment:1 by , 3 years ago
Component: | undetermined → ffmpeg |
---|
comment:2 by , 3 years ago
Component: | ffmpeg → undetermined |
---|---|
Resolution: | → duplicate |
Status: | new → closed |
This is a duplicate of #9132.
Now, I will help you. First of all you are tagging video in limited range RGB. I mean, that is BS, since it is actually full range. That can be checked with ffplay rec.mkv -vf extractplanes=r (see black FFmpeg logo, in limited range RGB black 0 is reserved and cannot be used, other colors are also good like 247, 247, 240). Use ffmpeg -video_size 1920x1200 -framerate 25 -f x11grab -i :0.0 -vcodec libx264rgb -crf 0 -preset ultrafast rec.mkv -color_range 2 I will also recommend to immediately use mp4, not mkv.
Use this: ffmpeg -i rec.mkv -pix_fmt yuv420p -vf scale=src_range=1:out_color_matrix=bt709:flags=accurate_rnd -c:v libx264 -crf 10 TESTCASE-yuv.mp4 -color_primaries 1 -color_trc 1 -colorspace 1
That will not be perfect since the sRGB does use -color_primaries 1 (which is BT.709) but not -color_trc 1. That is unfortunate and you can use
ffmpeg -i rec.mkv -pix_fmt yuv420p -vf scale=src_range=1:out_color_matrix=bt709:flags=accurate_rnd -c:v libx264 -crf 10 TESTCASE-yuv.mkv -color_primaries 1 -color_trc iec61966_2_1 -colorspace 1
but that may be not supported in many cases, since -color_trc just tags the video not doing any conversions :)
comment:3 by , 3 years ago
This is actually two bugs, one of which you are correct about (RGB matrix not being reset in the scale filter leading to 4:4:4 YCbCr being mistakenly flagged as RGB).
The other one (captured bgr0 getting flagged as limited range - no scale filter involved at all) is a result of a piece of old logic which was correct when x264 only supported YCbCr, but was not changed as RGB support was added to the wrapper. If the range flag was set to unspecified, it would only set the full range flag for the YUVJ pixel formats and set it to off otherwise.
I noticed this same logic was also copied over to the libx265 wrapper.
I have posted a patch set to fix this issue in the libx264 and libx265 wrappers for now: https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=4613
Of course, the logic generating the AVFrame should probably set the range flag, but that is not something for tonight.
comment:4 by , 3 years ago
Resolution: | duplicate |
---|---|
Status: | closed → reopened |
comment:5 by , 3 years ago
Resolution: | → duplicate |
---|---|
Status: | reopened → closed |
x11grub x264rgb mistagging as limited range was fixed in 7ca71b79f2b3256a0eef1a099b857ac9e4017e36 due to my report here on github: https://github.com/FFmpeg/FFmpeg/commit/7ea4bcff7b038774b404bad2b9c7112a7855a088#commitcomment-54917435
But that has nothing to do with this issue since swscale does not support limited RGB anyway and fallbacks to full, so there was no need to reopen this, the bug is indeed (as said by Jan) a duplicate of #9132 with a workaround available.
comment:6 by , 3 years ago
Resolution: | duplicate |
---|---|
Status: | closed → reopened |
comment:7 by , 3 years ago
Do you think other encoders (nvidia's) are affected? I tested x264rgb on linux it is fixed. There is no way to specify source range automatically, see https://trac.ffmpeg.org/ticket/8941#comment:3
comment:9 by , 3 years ago
Replying to razvan:
Thank you for the workaround
There is an actual fix available for this. https://patchwork.ffmpeg.org/project/ffmpeg/patch/20210822205542.16631-1-jeebjp@gmail.com/
comment:10 by , 3 years ago
I compiled ffmpeg from latest git snapshot together with x264,
did a screen grab and mkv to mp4 conversion with this binary without any workaround
and the colors are all ok now (no tint anymore).
Thank you all,
Razvan
comment:11 by , 3 years ago
Yeah, but that is not enough. After the patch the bitstream is being flagged as unspecified matrix, which is not enough for YCbCr, though it does not recognise it as RGB anymore (since that uses identity matrix). You still need to use -colorspace 1 for bt.709.
comment:12 by , 3 years ago
Resolution: | → duplicate |
---|---|
Status: | reopened → closed |
This was partly a duplicate of #8404.
The other one (captured bgr0 getting flagged as limited range - no scale filter involved at all) is a result of a piece of old logic which was correct when x264 only supported YCbCr
And partly duplicate of #9167.
logic generating the AVFrame should probably set the range flag, but that is not something for tonight.
Yes, it should. I mean it does work for libopenh264. Why does not it work for libx264[rgb]? LOL. Again, #9167.
mkv and resulting mp4