Декодирование из VP8 видеокадра в RGB

голоса
1

В моем приложении, мы должны отображать видеокадр на экране. Я использую libvpx для декодирования видео с WebM, но кадр декодируется в формат YUV (VPX_IMG_FMT_I420 в соответствии с документацией). Мне нужно выходной формат RGB и документация говорит изображение поддерживается формат RGB (VPX_IMG_FMT_RGB24). У меня есть формула для перевода YUV-> RGB:
R = Y + 1,13983 * (V - 128);
G = Y - 0,39465 * (U - 128) - 0,58060 * (V - 128);
В = У + 2,03211 * (U - 128);
Но я думаю , что это слишком много переходов VP8-> YUV-> RGB. Есть ли способ установить выходной формат кадра для функции преобразования?

Задан 13/06/2013 в 14:19
источник пользователем
На других языках...                            


1 ответов

голоса
1

Если вы можете позволить себе с помощью корпорации Intel IPP библиотеки, вот некоторые CPU дружественного куска кода , который вы можете попробовать и применить в вашем проекте:

unsigned char*  mpRGBBuffer;

void VPXImageToRGB24(vpx_image_t* pImage, bool isUsingBGR)
{
   const unsigned int rgbBufferSize = pImage->d_w * pImage->d_h * 3;

   mpRGBBuffer - allocate your raw RGB buffer...

    const IppiSize  sz          = { pImage->d_w, pImage->d_h };
    const Ipp8u*    src[3]      = { pImage->planes[PLANE_Y],     pImage->planes[PLANE_U],     pImage->planes[PLANE_V]       };
    int             srcStep[3]  = { pImage->stride[VPX_PLANE_Y], pImage->stride[VPX_PLANE_U], pImage->stride[VPX_PLANE_V]   };

    if (isUsingBGR) ippiYCbCr420ToBGR_8u_P3C3R(src, srcStep, pDest, pImage->d_w * 3, sz);
    else            ippiYCbCr420ToRGB_8u_P3C3R(src, srcStep, pDest, pImage->d_w * 3, sz);
}

Если вы не хотите использовать IPP, вот ссылка на какой - то рабочий мир ядро , которое может быть действительно полезным. Испытано это, работает на 100% , но не уверен , что стоимость процессора.

Вот код по ссылке выше (в случае, если ссылка не может ...)

inline int clamp8(int v)
{
    return std::min(std::max(v, 0), 255);
} 

Image VP8Decoder::convertYV12toRGB(const vpx_image_t* img)
{
    Image rgbImg(img->d_w, img->d_h);
    std::vector<uint8_t>& data = rgbImg.data;

    uint8_t *yPlane = img->planes[VPX_PLANE_Y];
    uint8_t *uPlane = img->planes[VPX_PLANE_U];
    uint8_t *vPlane = img->planes[VPX_PLANE_V];

    int i = 0;
    for (unsigned int imgY = 0; imgY < img->d_h; imgY++) {
        for (unsigned int imgX = 0; imgX < img->d_w; imgX++) {
            int y = yPlane[imgY * img->stride[VPX_PLANE_Y] + imgX];
            int u = uPlane[(imgY / 2) * img->stride[VPX_PLANE_U] + (imgX / 2)];
            int v = vPlane[(imgY / 2) * img->stride[VPX_PLANE_V] + (imgX / 2)];

            int c = y - 16;
            int d = (u - 128);
            int e = (v - 128);

            // TODO: adjust colors ?

            int r = clamp8((298 * c           + 409 * e + 128) >> 8);
            int g = clamp8((298 * c - 100 * d - 208 * e + 128) >> 8);
            int b = clamp8((298 * c + 516 * d           + 128) >> 8);

            // TODO: cast instead of clamp8

            data[i + 0] = static_cast<uint8_t>(r);
            data[i + 1] = static_cast<uint8_t>(g);
            data[i + 2] = static_cast<uint8_t>(b);

            i += 3;
        }
    }
    return rgbImg;
}
Ответил 15/11/2013 в 17:56
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more