2

I am currently attempting to undergo lossless compression of RGB24 files using H264 on FFMPEG. However, the color space transformation used in the H264 compression (RGB24 -> YUV444) has proven to be lossy (I'm guessing due to quantisation error). Is there anything else I can use (eg a program) to transform my RGB24 files to YUV losslessly, before compressing them with lossless H264?

The ultimate goal is to compress an RGB24 file then decompress it, with the decompressed file exactly matching the original file. eg RGB24 -> YUV444 -> compressed YUV44 -> decompressed YUV444 -> RGB24.

Is this at all possible?

Armen Michaeli
  • 8,625
  • 8
  • 58
  • 95
Squid
  • 45
  • 1
  • 4

1 Answers1

3

This is a copy/paste from my answer here: RGB-frame encoding - FFmpeg/libav

lets look at the colorspace conversion.

void YUVfromRGB(double& Y, double& U, double& V, const double R, const double G, const double B)
{
    Y =  0.257 * R + 0.504 * G + 0.098 * B +  16;
    U = -0.148 * R - 0.291 * G + 0.439 * B + 128;
    V =  0.439 * R - 0.368 * G - 0.071 * B + 128;
}

And plug in some dummy values:

R = 255, G = 255, B = 255
Y = 235

R = 0, G = 0, B = 0
Y = 16

As you can see, the range 0 -> 255 is squished to 16 -> 235. Thus we have shown that there are some colors in the RGB colorspace that do not exist in the (digital) YUV color space. Hence the conversion is lossy by definition.

Community
  • 1
  • 1
szatmary
  • 29,969
  • 8
  • 44
  • 57
  • I see what you mean, I thought JPEG2000 used the YUV colorspace yet it is completely reversible, hence I thought there might be a way. Thanks for clearing that up. – Squid Mar 19 '14 at 21:50
  • The coefficients I use here are from the ITU-R BT.601 standard. HDTV uses ITU-R BT.709. JPEG uses ITU-R BT.2020 and I THINK that one is lossless (but I have never done all the math to confirm). – szatmary Mar 19 '14 at 22:35
  • You can try to use ITU-R BT.2020 in x264. I'm not sure what would happen. I'm going to have to test that some day :) – szatmary Mar 19 '14 at 22:36
  • Ok thanks for your help! I shall try that one day, but for now someone has suggested just using the libx264rgb encoder which encodes it in the RGB colorspace, making it perfect for me. My next task is working out how to use libx264rgb in C++. – Squid Mar 20 '14 at 00:36
  • x264 does not use bt2020 matrix, it is an encoder, not a scaler! – Валерий Заподовников Dec 31 '21 at 02:09