1

So I have a raw video in yuv420p format - input.yuv, and I know its frame size. I execute 2 commands:

ffmpeg -pix_fmt yuv420p -s 352x288 -i input.yuv -pix_fmt yuv422p input_yuv422p.yuv

and then

ffmpeg -pix_fmt yuv422p -s 352x288 -i input_yuv422p.yuv -pix_fmt yuv420p input_decoded.yuv

The problem is that files input.yuv and input_decoded.yuv differ. My understanding is that when we convert to yuv422p from yuv420p - we should essentially copy existing U and V components to produce more samples to fill in; then, when converting back - we should simply drop these samples, and receive the original file back, but that's not what I see. Am I doing something wrong here, and is it possible to receive original yuv420p back?

IvanIvanovich
  • 21
  • 1
  • 4
  • 1
    Rounding errors, I guess? Can you quantify the differences in luma/chroma? – slhck Feb 05 '19 at 09:41
  • Hm, if we simply copy bytes when doing `420p` to `422p` and drop bytes when converting back - there should be no possible source for rounding errors. Maybe my assumption about how the conversion `420p` to `422p` is performed is wrong, and `ffmpeg` does some kind of interpolation indeed. Will check differences now, thanks. – IvanIvanovich Feb 05 '19 at 10:10
  • So I get this PSNR between original and converted back: `PSNR y:inf u:51.837944 v:51.936866` so only chroma differs. Is it possible to somehow instruct `ffmpeg` to use the simple copying/dropping bytes when converting between `yuv420p` and `yuv422p` forward/backward? – IvanIvanovich Feb 05 '19 at 10:20
  • No, don't think so. In principle copying the bytes is what would be needed, but the image is decoded and encoded back to the new format, hence possible interpolation errors. You could check a hex dump of a small example (or use http://rawpixels.net/) to see where the error comes from — or how big it is. – slhck Feb 05 '19 at 13:42
  • Yeah, I guess ffmpeg performs some interpolation when upsampling from 420 to 422 and antialiasing when downsampling back from 422 to 420 - at least that's the default behavior of similar Matlab library: https://www.mathworks.com/help/vision/ref/chromaresampling.html. And it looks like this library actually has the options to achieve the behavior I wanted, which would result in no difference between the original yuv420p and "converted back", in case anyone also needs this. How do I close this question as answered?) – IvanIvanovich Feb 07 '19 at 14:15
  • You can post your own answer below using the button. – slhck Feb 07 '19 at 16:18

1 Answers1

1

It seems that ffmpeg performs some interpolation when upsampling from 420 to 422 and antialiasing when downsampling back from 422 to 420 - at least that's the default behavior of similar Matlab library: mathworks.com/help/vision/ref/chromaresampling.html. And it looks like this library actually has the options to achieve the behavior of simply copying/dropping chrominance values which would result in no difference between the original yuv420p and "converted back", in case anyone also needs this.

IvanIvanovich
  • 21
  • 1
  • 4