4

I am processing Android camera2 preview frames which are encoded in YUV_420 _888, by calling the method I420ToARGB from the Libyuv library but I get images in wrong colors.

 libyuv::I420ToARGB(
    ysrc, //const uint8* src_y,
    ystride, //int src_stride_y,
    usrc, //const uint8* src_u,
    ustride, ///int src_stride_u,
    vsrc, //const uint8* src_v,
    vstride, //int src_stride_v,
    argb, //uint8* dst_argb,
    w*4, //int dst_stride_argb,
    w, //int width,
    h //int height
);
Weber
  • 425
  • 5
  • 9

1 Answers1

3

If red objects appear blue, and vice versa, you have the U and V color planes backwards. Per the Android developer documentation, the planes are:

http://developer.android.com/reference/android/graphics/ImageFormat.html#YUV_420_888

The order of planes in the array returned by Image#getPlanes() is guaranteed such that plane #0 is always Y, plane #1 is always U (Cb), and plane #2 is always V (Cr).

Also, it seems that this libyuv method doesn't support pixel stride, which may be larger than 1 for YUY_420_888 images. In that case, you need to preprocess the planes to be contiguous, or use a method that accepts semi-planar 420 from libyuv if one exists, when the pixel stride is larger than 1.

Eddy Talvala
  • 15,449
  • 2
  • 37
  • 42
  • **libyuv** does support pixel stride of `2`, see [Android420ToARGBMatrix()](https://chromium.googlesource.com/libyuv/libyuv/+/master/source/convert_argb.cc#2985). Unfortunately, it's not exactly what one needs to process camera frames, because it uses the [BT.610](https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion) color space. – Alex Cohn Sep 17 '20 at 11:08