Search code examples
androidandroid-camerayuvargblibyuv

Convert YUV_420 _888 to ARGB using Libyuv


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
);

Solution

  • 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.