View Full Version : RGB to YV12 video encoding - colors are off...


orion44
12th June 2019, 04:39
I recorded a game with MAME's native recorder. The output video (sf2.avi) is in the following format:

Video
ID : 0
Format : RGB
Codec ID : 0x00000000
Codec ID/Info : Basic Windows bitmap format. 1, 4 and 8 bpp versions are palettised. 16, 24 and 32bpp contain raw RGB samples
Duration : 26 min 43 s
Bit rate : 118 Mb/s
Width : 384 pixels
Height : 224 pixels
Display aspect ratio : 1.714
Frame rate : 59.610 FPS
Bit depth : 8 bits
Bits/(Pixel*Frame) : 23.039
Stream size : 22.1 GiB (95%)

I then used avisynth:

AVISource("D:\Project\sf2.avi", audio=false)
PointResize(960,720)

to encode with x264:

x264 --profile high --level 3.2 --preset slow --pass 1 --stats D:\Project\stats.log --bitrate 1000 -I 600 -i 60 -o D:\Project\1stPass.mkv "D:\Project\AviSynth Scripts\AVISource.avs"
x264 --profile high --level 3.2 --preset slow --pass 2 --stats D:\Project\stats.log --bitrate 1000 -I 600 -i 60 -o D:\Project\2ndPass.mkv "D:\Project\AviSynth Scripts\AVISource.avs"
pause

During the encoding, I got the following warning:

resize [warning]: converting from bgr24 to yuv420p

The x264 encoded video has colors which are slightly off.

Example:

Screenshot taken directly from game. Looks good:

http://u.cubeupload.com/ClearSky/2mame201906102241334.png

Screenshot taken from AviSynth script above. Looks a bit lower quality, but colors are the same.

http://u.cubeupload.com/ClearSky/3FromVideo.png

Screenshot taken from final x264 encode. Red color is slightly off:

http://u.cubeupload.com/ClearSky/3fu.png

Is this color conversion normal, the way it should be, or is there a way to fix this?

Thanks.

Cary Knoop
12th June 2019, 04:50
The lower quality is mostly chroma subsampling.
The color difference looks like a Rec.601/Rec709 interpretation issue.

FranceBB
12th June 2019, 12:21
Try with:

#Indexing
OpenDMLSource("D:\Project\sf2.avi")

#From BGR24 to 4:2:0 planar
Converttoyv12(interlaced=false)

#Resize
Spline36Resize(960, 720)

Please note that PointResize is a pretty basic resizing kernel, so I would suggest you either Lanczos or Spline.
Since you recorded in RGB, when you are gonna convert it to yv12 you are gonna lose something, while by converting it to yv24 you are gonna preserve chroma. Are you sure you wanna encode in H.264 4:2:0 planar?
As to the color matrix, I don't know whether it has been recorded in BT601 or BT709, but in case it was recorded in BT601 and you wanna convert it to BT709, just use:

#Indexing
OpenDMLSource("D:\Project\sf2.avi")

#From BGR24 to 4:2:0 planar
Converttoyv12(interlaced=false)

#From BT601 to BT709
ColorMatrix(mode="Rec.601->Rec.709", clamp=true, interlaced=false, threads=0, thrdmthd=0, opt=3)

#Resize
Spline36Resize(960, 720)

By the way, in your case, your content is a videogame, so it doesn't really matter, but in case one day you'll have to encode a real live footage, you may wanna do a color matrix conversion with 16bit precision. In case you wanna do it in 16bit interleaved: Matrix(from=601, to=709, rg=1.0, gg=1.0, bg=1.0, a=16, b=235, ao=16, bo=235, bitdepth=16)

wonkey_monkey
12th June 2019, 15:36
Converttoyv12(interlaced=false)

#From BT601 to BT709
ColorMatrix(mode="Rec.601->Rec.709", clamp=true, interlaced=false, threads=0, thrdmthd=0, opt=3)

Would it not be one less conversion just to do:

converttoyv12(interlaced = false, matrix = "rec709")