трябва да създадете webm видео от RGB рамки

Имам приложение, което генерира куп jpgs, които трябва да превърна в webm видео. Опитвам се да вкарам моите rgb данни от jpegs във vpxenc извадката. Мога да видя основните форми от оригиналните jpg файлове в изходното видео, но всичко е оцветено в зелено (дори пикселите, които трябва да са черни, са около половината зелени) и във всяка друга линия за сканиране има някакъв боклук.

Опитвам се да му подам VPX_IMG_FMT_YV12 данни, които предполагам са структурирани така:

за всеки кадър 8-битови Y данни 8-битови средни стойности на всеки 2x2 V блок 8-битови средни стойности на всеки 2x2 U блок

Ето изходно изображение и екранна снимка на видеоклипа, който излиза:

Изображения

Напълно възможно е да правя преобразуването RGB->YV12 неправилно, но дори ако кодирам само 8-битовите Y данни и задам U и V блоковете на 0, видеото изглежда почти същото. По принцип пускам моите RGB данни чрез това уравнение:

// (R, G, and B are 0-255)
float y = 0.299f*R + 0.587f*G + 0.114f*B;
float v = (R-y)*0.713f;
float u = (B-v)*0.565f;

.. и след това, за да създам 2x2 филтрираните стойности за U и V, които записвам във vpxenc, просто правя (a + b + c + d) / 4, където a,b,c,d са U или V стойностите на всеки 2x2 пикселен блок.

Така че се чудя:

  1. Има ли по-лесен начин (в код) да вземете RGB данни и да ги подадете към vpx_codec_encode, за да получите хубаво webm видео?

  2. Грешно ли е преобразуването ми RGB->YV12 някъде?

Всяка помощ ще бъде високо оценена.


person Mike    schedule 22.01.2011    source източник
comment
Можете ли да ми кажете, че сте актуализирали кода? Стоя пред абсолютно същия проблем тук ;-) благодаря   -  person    schedule 25.01.2011


Отговори (2)


freefallr: Разбира се. Ето кода. Обърнете внимание, че преобразува RGB->YUV на място, както и поставя YV12 изхода в pFullYPlane/pDownsampledUPlane/pDownsampledVPlane. Този код създаде добре изглеждащи WebM видеоклипове, когато промених техния vpxenc образец, за да използва тези данни.

void RGB_To_YV12( unsigned char *pRGBData, int nFrameWidth, int nFrameHeight, void *pFullYPlane, void *pDownsampledUPlane, void *pDownsampledVPlane )
{
    int nRGBBytes = nFrameWidth * nFrameHeight * 3;

    // Convert RGB -> YV12. We do this in-place to avoid allocating any more memory.
    unsigned char *pYPlaneOut = (unsigned char*)pFullYPlane;
    int nYPlaneOut = 0;

    for ( int i=0; i < nRGBBytes; i += 3 )
    {
        unsigned char B = pRGBData[i+0];
        unsigned char G = pRGBData[i+1];
        unsigned char R = pRGBData[i+2];

        float y = (float)( R*66 + G*129 + B*25 + 128 ) / 256 + 16;
        float u = (float)( R*-38 + G*-74 + B*112 + 128 ) / 256 + 128;
        float v = (float)( R*112 + G*-94 + B*-18 + 128 ) / 256 + 128;

        // NOTE: We're converting pRGBData to YUV in-place here as well as writing out YUV to pFullYPlane/pDownsampledUPlane/pDownsampledVPlane.
        pRGBData[i+0] = (unsigned char)y;
        pRGBData[i+1] = (unsigned char)u;
        pRGBData[i+2] = (unsigned char)v;

        // Write out the Y plane directly here rather than in another loop.
        pYPlaneOut[nYPlaneOut++] = pRGBData[i+0];
    }

    // Downsample to U and V.
    int halfHeight = nFrameHeight >> 1;
    int halfWidth = nFrameWidth >> 1;

    unsigned char *pVPlaneOut = (unsigned char*)pDownsampledVPlane;
    unsigned char *pUPlaneOut = (unsigned char*)pDownsampledUPlane;

    for ( int yPixel=0; yPixel < halfHeight; yPixel++ )
    {
        int iBaseSrc = ( (yPixel*2) * nFrameWidth * 3 );

        for ( int xPixel=0; xPixel < halfWidth; xPixel++ )
        {
            pVPlaneOut[yPixel * halfWidth + xPixel] = pRGBData[iBaseSrc + 2];
            pUPlaneOut[yPixel * halfWidth + xPixel] = pRGBData[iBaseSrc + 1];

            iBaseSrc += 6;
        }
    }
}
person Mike    schedule 29.03.2011
comment
Бих предложил също да прочетете това en.wikipedia.org/wiki/ ако нямате представа колко дълги трябва да са входните буфери. - person Evren Bingøl; 03.10.2013

Няма значение. Схемата, която използвах, беше правилна, но имах грешка в U/V кода за намаляване на дискретизацията.

person Mike    schedule 24.01.2011
comment
Можете ли да публикувате своя код за преобразуване RGB -› YUV, бих искал да погледна! - person ; 22.03.2011