Log in

View Full Version : Videogame-footage colour conversions


Reino
2nd March 2014, 21:42
As this topic keeps coming back from time to time, I thought I'd start this thread with the hope an admin would make this a sticky.

This thread is for everyone who does videogame-footage editing/encoding and experiences wrong colour output.
Although the focus is on Fraps, the RGB-part applies to HFYU(bgra), ULRG(rgb24), LAGS(rgb24), or any other RGB-source as well.

Lossless

Fraps(RGB) --> H.264(RGB-lossless):
x264.exe (--preset veryslow) -q 0 --output-csp rgb -o "FPS1(bgr24)_720p30_sample(x264,q0,rgb).mkv" "FPS1(bgr24)_720p30_sample.avi"
ffmpeg.exe -i "FPS1(bgr24)_720p30_sample.avi" (-pix_fmt bgr24) -c:v libx264rgb (-preset veryslow) -qp 0 -an "FPS1(bgr24)_720p30_sample(ffmpeg,qp0,rgb).mkv"Note: parameters between brackets are unnecessary/optional.


Fraps(≤576p,RGBmode)

Fraps(≤576p,RGB) --> H.264(YV12 TV-Range,BT.601) with AviSynth:
AviSynth-script: FFVideoSource("FPS1(bgr24)_540p30_sample.avi").ConvertToYV12()

x264.exe -o "FPS1(bgr24)_540p30_sample(x264(avs,yv12-tv601)).mkv" "FPS1(bgr24)_540p30_sample(avs,yv12-tv601).avs"
ffmpeg.exe -i "FPS1(bgr24)_540p30_sample(avs,yv12-tv601).avs" -c:v libx264 "FPS1(bgr24)_540p30_sample(ffmpeg(avs,yv12-tv601)).mkv"Note: for Fraps(RGB), instead of FFVideoSource() you can always use LWLibavVideoSource() or AviSource() as well.
For Fraps(YUV) I wouldn't recommend AviSource() as it performs an unnecessary colourspace-conversion in this situation.

Fraps(≤576p,RGB) --> H.264(YV12 TV-Range,BT.601):
x264.exe -o "FPS1(bgr24)_540p30_sample(x264,yv12-tv601).mkv" "FPS1(bgr24)_540p30_sample.avi"
ffmpeg.exe -i "FPS1(bgr24)_540p30_sample.avi" -pix_fmt yuv420p -c:v libx264 -an "FPS1(bgr24)_540p30_sample(ffmpeg,yv12-tv601).mkv"

Fraps(≤576p,RGB) --> H.264(YV12 PC-Range,BT.601) with AviSynth:
AviSynth-script: FFVideoSource("FPS1(bgr24)_5420p30_sample.avi").ConvertToYV12(matrix="PC.601")

x264.exe --input-range pc (--range pc) -o "FPS1(bgr24)_540p30_sample(x264(avs,yv12-pc601)).mkv" "FPS1(bgr24)_540p30_sample(avs,yv12-pc601).avs"
ffmpeg.exe -i "FPS1(bgr24)_540p30_sample(avs,yv12-pc601).avs" -c:v libx264 -color_range 2 "FPS1(bgr24)_540p30_sample(ffmpeg(avs,yv12-pc601)).mkv"Note: to specify full-range: -color_range 2, which is the same as -x264-params fullrange=on. It only works with AviSynth-input somehow.

Fraps(≤576p,RGB) --> H.264(YV12 PC-Range,BT.601):
x264.exe --input-range pc (--range pc) -o "FPS1(bgr24)_540p30_sample(x264,yv12-pc601).mkv" "FPS1(bgr24)_540p30_sample.avi"
ffmpeg.exe -i "FPS1(bgr24)_540p30_sample.avi" -pix_fmt yuvj420p -c:v libx264 -an "FPS1(bgr24)_540p30_sample(ffmpeg,yv12-pc601).mkv"Note: to specify full-range: -pix_fmt yuvj420p. -color_range 2 doesn't work here.


Fraps(>576p,RGBmode)

Fraps(>576p,RGB) --> H.264(YV12 TV-Range,BT.709) with AviSynth:
AviSynth-script: FFVideoSource("FPS1(bgr24)_720p30_sample.avi").ConvertToYV12(matrix="Rec709")

x264.exe -o "FPS1(bgr24)_720p30_sample(x264(avs,yv12-tv709)).mkv" "FPS1(bgr24)_720p30_sample(avs,yv12-tv709).avs"
ffmpeg.exe -i "FPS1(bgr24)_720p30_sample(avs,yv12-tv709).avs" -c:v libx264 "FPS1(bgr24)_720p30_sample(ffmpeg(avs,yv12-tv709)).mkv"

Fraps(>576p,RGB) --> H.264(YV12 TV-Range,BT.709) with FFMpeg's videofilter:
ffmpeg.exe -i "FPS1(bgr24)_720p30_sample.avi" -pix_fmt yuv420p -c:v libx264 -vf scale=out_color_matrix=bt709 -an "FPS1(bgr24)_720p30_sample(ffmpeg,vf,yv12-tv709).mkv"Note: x264.exe is excluded here, as it doesn't have the ability to do matrix-conversions.
Note2: instead of -vf scale=out_color_matrix=bt709 you can also use -vf colormatrix=bt601:bt709, though recently there has been discussion about the latter being of lower quality.

Fraps(>576p,RGB) --> H.264(YV12 PC-Range,BT.709) with AviSynth:
AviSynth-script: FFVideoSource("FPS1(bgr24)_720p30_sample.avi").ConvertToYV12(matrix="PC.709")

x264.exe --input-range pc (--range pc) -o "FPS1(bgr24)_720p30_sample(x264(avs,yv12-pc709)).mkv" "FPS1(bgr24)_720p30_sample(avs,yv12-pc709).avs"
ffmpeg.exe -i "FPS1(bgr24)_720p30_sample(avs,yv12-pc709).avs" -c:v libx264 -color_range 2 "FPS1(bgr24)_720p30_sample(ffmpeg(avs,yv12-pc709)).mkv"

Fraps(>576p,RGB) --> H.264(YV12 PC-Range,BT.709) with FFMpeg's videofilter:
ffmpeg.exe -i "FPS1(bgr24)_720p30_sample.avi" -pix_fmt yuvj420p -c:v libx264 -vf scale=out_color_matrix=bt709 -an "FPS1(bgr24)_720p30_sample(ffmpeg,vf,yv12-pc709).mkv"


Fraps(≤576p,YUVmode PC-Range,BT.709)
(Although anything ≤576p assumes BT.601, Fraps (in YUV-mode) defaults to BT.709, no matter the resolution!)

Fraps(≤576p,YV12 PC-Range,BT.709) --> H.264(YV12 TV-Range,BT.601) with AviSynth:
AviSynth-script: FFVideoSource("FPS1(yuvj420p)_540p30_sample.avi").ColorMatrix(clamp=0,inputFR=true)

x264.exe -o "FPS1(yuvj420p)_540p30_sample(x264(avs,yv12-tv601)).mkv" "FPS1(yuvj420p)_540p30_sample(avs,yv12-tv601).avs"
ffmpeg.exe -i "FPS1(yuvj420p)_540p30_sample(avs,yv12-tv601).avs" -c:v libx264 "FPS1(yuvj420p)_540p30_sample(ffmpeg(avs,yv12-tv601)).mkv"Note: By default ColorMatrix's mode is "Rec.709->Rec.601", so no need to specify.

Fraps(≤576p,YV12 PC-Range,BT.709) --> H.264(YV12 TV-Range,BT.601) with FFMpeg's videofilter:
ffmpeg.exe -i "FPS1(yuvj420p)_540p30_sample.avi" -pix_fmt yuv420p -c:v libx264 -vf colormatrix=bt709:bt601 -an "FPS1(yuvj420p)_540p30_sample(ffmpeg,vf,yv12-tv601).mkv"Note: fallback to -vf colormatrix. Somehow -vf scale=out_color_matrix=bt601 doesn't work here.

Fraps(≤576p,YV12 PC-Range,BT.709) --> H.264(YV12 TV-Range,BT.709) with VUI:
x264.exe --range tv --colormatrix bt709 -o "FPS1(yuvj420p)_540p30_sample(x264,vui,yv12-tv709).mkv" "FPS1(yuvj420p)_540p30_sample.avi"
ffmpeg.exe -i "FPS1(yuvj420p)_540p30_sample.avi" -pix_fmt yuv420p -c:v libx264 -colorspace 1 -an "FPS1(yuvj420p)_540p30_sample(ffmpeg,vui,yv12-tv709).mkv"Note: -colorspace 1 same as -x264-params colormatrix=bt709).

Fraps(≤576p,YV12 PC-Range,BT.709) --> H.264(YV12 PC-Range,BT.709) with AviSynth and VUI:
AviSynth-script: FFVideoSource("FPS1(yuvj420p)_540p30_sample.avi")

x264.exe --input-range pc (--range pc) --colormatrix bt709 -o "FPS1(yuvj420p)_540p30_sample(x264(avs,yv12-pc709),vui).mkv" "FPS1(yuvj420p)_540p30_sample(avs,yv12-pc709).avs"
ffmpeg.exe -i "FPS1(yuvj420p)_540p30_sample(avs,yv12-pc709).avs" -c:v libx264 -color_range 2 -colorspace 1 "FPS1(yuvj420p)_540p30_sample(ffmpeg(avs,yv12-pc709),vui).mkv"Note: -color_range 2 -colorspace 1 same as -x264-params fullrange=on:colormatrix=bt709).

Fraps(≤576p,YV12 PC-Range,BT.709) --> H.264(YV12 PC-Range,BT.709) with VUI:
x264.exe --colormatrix bt709 -o "FPS1(yuvj420p)_540p30_sample(x264,vui,yv12-pc709).mkv" "FPS1(yuvj420)_540p30_sample.avi"
ffmpeg.exe -i "FPS1(yuvj420p)_540p30_sample.avi" (-pix_fmt yuvj420p) -c:v libx264 -colorspace 1 -an "FPS1(yuvj420p)_540p30_sample(ffmpeg,vui,yv12-pc709).mkv"


Fraps(>576p,YUVmode PC-Range,BT.709)

Fraps(>576p,YV12 PC-Range,BT.709) --> H.264(YV12 TV-Range,BT.709) with AviSynth:
AviSynth-script: FFVideoSource("FPS1(yuvj420p)_720p30_sample.avi").ColorMatrix(dest=0,clamp=0,inputFR=true)

x264.exe -o "FPS1(yuvj420p)_720p30_sample(x264(avs,yv12-tv709)).mkv" "FPS1(yuvj420p)_720p30_sample(avs,yv12-tv709).avs"
ffmpeg.exe -i "FPS1(yuvj420p)_720p30_sample(avs,yv12-tv709).avs" -c:v libx264 "FPS1(yuvj420p)_720p30_sample(ffmpeg(avs,yv12-tv709)).mkv"Note: ColorMatrix's dest=0 same as mode="Rec.709->Rec.709".

Fraps(>576p,YV12 PC-Range,BT.709) --> H.264(YV12 TV-Range,BT.709):
x264.exe (--input-range pc) --range tv -o "FPS1(yuvj420p)_720p30_sample(x264,yv12-tv709).mkv" "FPS1(yuvj420)_720p30_sample.avi"
ffmpeg.exe -i "FPS1(yuvj420p)_720p30_sample.avi" -pix_fmt yuv420p -c:v libx264 -an "FPS1(yuvj420p)_720p30_sample(ffmpeg,yv12-tv709).mkv"

Fraps(>576p,YV12 PC-Range,BT.709) --> H.264(YV12 PC-Range,BT.709) with AviSynth:
AviSynth-script: FFVideoSource("FPS1(yuvj420p)_720p30_sample.avi")

x264.exe --input-range pc (--range pc) -o "FPS1(yuvj420p)_720p30_sample(x264(avs,yv12-pc709)).mkv" "FPS1(yuvj420p)_720p30_sample(avs,yv12-pc709).avs"
ffmpeg.exe -i "FPS1(yuvj420p)_720p30_sample(avs,yv12-pc709).avs" -c:v libx264 -color_range 2 "FPS1(yuvj420p)_720p30_sample(ffmpeg(avs,yv12-pc709)).mkv"

Fraps(>576p,YV12 PC-Range,BT.709) --> H.264(YV12 PC-Range,BT.709):
x264.exe -o "FPS1(yuvj420p)_720p30_sample(x264,yv12-pc709).mkv" "FPS1(yuvj420)_720p30_sample.avi"
ffmpeg.exe -i "FPS1(yuvj420p)_720p30_sample.avi" (-pix_fmt yuvj420p) -c:v libx264 -an "FPS1(yuvj420p)_720p30_sample(ffmpeg,yv12-pc709).mkv"


Links

- x264 binary (http://download.videolan.org/pub/videolan/x264/binaries/) (official)
- x264 binary (http://komisar.gin.by/) (patched by Komisar)
- FFmpeg binary (http://ffmpeg.zeranoe.com/builds/)
- AviSynth (http://avisynth.nl/index.php/Main_Page)
- FFmpegSource (https://code.google.com/p/ffmpegsource/)
- L-SMASH (https://code.google.com/p/l-smash/)
- L-SMASH-Works AviSynth-plugin (https://drive.google.com/folderview?id=0BwV03nn6LPd9OXJUWVVMMXZmNUU&usp=sharing)
- ColorMatrix (http://bengal.missouri.edu/~kes25c/)

detmek
2nd March 2014, 23:30
I don't understang you examples. FRAPS recording in RGB mode is always full range and does not have matrix (its RGB). So, I don't know what you mean by FRAPS RGB TV range,bt601.
In YUV mode original FRAPS decoder always decodes to full range RGB using 709 matrix. If you have FRAPS installed you can use it within Avisynth with AVISource(""). If you use DirectShowSource("") and LAV Video, I belive it decodes YUV FRAPS video in the same way, to RGB using 709 matrix.

Reino
3rd March 2014, 00:49
I can imagine that's confusing, so I corrected it.
The thought behind it was that during conversion the RGB-source is considered tv601, i.e. a tv601->pc709-conversion.
I wouldn't recommend the use of AviSource() or DirectShowSource().

detmek
3rd March 2014, 10:45
OK. I understand now. Although I wouldn't recommend using DirectShowSource() eather, AviSource is the only way to use original FRAPS decoder and it is frame accurate as it uses VFW interface.

Reino
3rd March 2014, 11:56
If you want to open FPS1(yuvj420p) with AviSource() and want to encode to YV12, I would recommend the use FFVideoSource(), or LWLibavVideoSource() instead, because AviSource() (Fraps' own decoder) performs an unnecessary colourspace-conversion in this situation, as has been discussed in this thread for instance.
For FPS1(bgr24) AviSource(),FFVideoSource() and LWLibavVideoSource() all produce the same output, but make sure you're using the latest Fraps version, because I know v3.4.7.13808 for instance opens FPS1(bgr24) as YUY2 (yuv422,tv601)!

Warperus
4th March 2014, 12:02
Fraps(RGB) --> H.264(YV12 TV-Range,BT.709) with VUI:Were is VUI here? And I believe 709 is a typo here.

Fraps(>576p,YUV PC-Range,BT.709) --> H.264(YV12 TV-Range,BT.709)Why do you think x264 will produce correct colors here? I believe it will go through avisource that will work exactly like for rgb fraps variant (with avisource), that is you'll end up in BT.601.

Reino
4th March 2014, 23:20
With both --colormatrix bt470bg and -colorspace 5 you'll find MediaInfo reporting: "Matrix coefficients: BT.601". With MadVR (a capable renderer) the end result is the same as all other methods; yv12-tv709.
During my research I tested all methods possible and although it's not a straight forward method, it's certainly a possible one. But thinking about it now, it might be better to remove it as it's not a method I would recommend.

I don't think, I actually succesfully tested all methods.
For this method all that is needed is a range-conversion (--range tv and -pix_fmt yuv420p), because if the input is larger than 576p the video renderer will assume BT.709.