imagedecodelibvpx

libVPX convert VPX_IMG_FMT_I420 -> RGB


How I can convert VPX_IMG_FMT_I420 vpx_image_t to RGB?

Example code:

int DecodeFrame()
{
  vpx_video_reader_read_frame(reader);
  vpx_codec_iter_t iter = NULL;
  vpx_image_t *img = NULL;
  size_t frame_size = 0;
  const unsigned char *frame = vpx_video_reader_get_frame(reader, &frame_size);
  if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0)) return 0;

  img = vpx_codec_get_frame(&codec, &iter);

// here I need to convert img to RGB array

  return 1;
};

Solution

  • Code from uTox:

    void yuv420tobgr(uint16_t width, uint16_t height, 
                     const uint8_t *y, const uint8_t *u, const uint8_t *v,
                     unsigned int ystride, 
                     unsigned int ustride, 
                     unsigned int vstride, 
                     uint8_t *out)
    {
        unsigned long int i, j;
        for (i = 0; i < height; ++i) {
            for (j = 0; j < width; ++j) {
                uint8_t *point = out + 4 * ((i * width) + j);
                int t_y = y[((i * ystride) + j)];
                int t_u = u[(((i / 2) * ustride) + (j / 2))];
                int t_v = v[(((i / 2) * vstride) + (j / 2))];
                t_y = t_y < 16 ? 16 : t_y;
    
                int r = (298 * (t_y - 16) + 409 * (t_v - 128) + 128) >> 8;
                int g = (298 * (t_y - 16) - 100 * (t_u - 128) - 208 * (t_v - 128) + 128) >> 8;
                int b = (298 * (t_y - 16) + 516 * (t_u - 128) + 128) >> 8;
    
                point[2] = r>255? 255 : r<0 ? 0 : r;
                point[1] = g>255? 255 : g<0 ? 0 : g;
                point[0] = b>255? 255 : b<0 ? 0 : b;
                point[3] = ~0;
            }
        }
    }