Opened 3 years ago

Closed 2 years ago

Last modified 2 years ago

#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)

test.tar.bz2 (726.6 KB ) - added by razvan 3 years ago.
mkv and resulting mp4

Download all attachments as: .zip

Change History (13)

by razvan, 3 years ago

Attachment: test.tar.bz2 added

mkv and resulting mp4

comment:1 by razvan, 3 years ago

Component: undeterminedffmpeg

comment:2 by Balling, 3 years ago

Component: ffmpegundetermined
Resolution: duplicate
Status: newclosed

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 (see #8404). 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 -c:v libx264rgb -crf 0 -preset ultrafast -color_range 2 rec.mkv

I will also recommend to immediately use mp4, not mkv.

Use this: ffmpeg -i rec.mkv -vf scale=src_range=1:out_color_matrix=bt709:flags=accurate_rnd -c:v libx264 -crf 10 -color_primaries 1 -color_trc 1 -colorspace 1 TESTCASE-yuv.mp4

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 -vf scale=src_range=1:out_color_matrix=bt709:flags=accurate_rnd -c:v libx264 -crf 10 -color_primaries 1 -color_trc iec61966_2_1 -colorspace 1 TESTCASE-yuv.mkv

but that may be not supported in many cases, since -color_trc just tags the video not doing any conversions :)

Last edited 2 years ago by Balling (previous) (diff)

comment:3 by jeeb, 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 Elon Musk, 3 years ago

Resolution: duplicate
Status: closedreopened

comment:5 by Balling, 3 years ago

Resolution: duplicate
Status: reopenedclosed

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 Elon Musk, 3 years ago

Resolution: duplicate
Status: closedreopened

comment:7 by Balling, 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:8 by razvan, 3 years ago

Thank you for the workaround

in reply to:  8 comment:9 by Balling, 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 razvan, 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 Balling, 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 Balling, 2 years ago

Resolution: duplicate
Status: reopenedclosed

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.

Last edited 2 years ago by Balling (previous) (diff)
Note: See TracTickets for help on using tickets.