2011-01-22 19 views
4

私はwebmビデオにする必要があるjpgの束を生成するアプリケーションを持っています。私はjpegsからvpxencサンプルに自分のrgbデータを取得しようとしています。出力ビデオのオリジナルのjpgから基本的な形を見ることができますが、すべてが緑色に塗りつぶされています(黒でなければならないピクセルも緑の半分程度です)。は、RGBフレームからwebmビデオを作成する必要があります

私はそれをVPX_IMG_FMT_YV12私は同様に構成されていると仮定していたデータは、供給しようとしている:フレーム毎に

8ビットのYデータの各2×2のVブロックの 8ビット平均を 8-ここで、各2×2のビット平均値Uが

ブロックは、ソース画像と出ている映像のスクリーンショットである。

Images

それはentiです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; 

...そして私はvpxencに書き込むUとVのための2x2のフィルタリングされた値を生成するために、私は(A + B + C + Dを行います)/ 4であり、ここで、a、b、c、dは各2×2画素ブロックのUまたはV値である。

だから私は思ったんだけど:

  1. がいいWEBMのビデオを取得するためにvpx_codec_encodeするRGBデータを取得し、それを養うために(コードで)もっと簡単な方法はありますか?

  2. RGB-> YV12変換がどこか間違っていますか?

ご協力いただければ幸いです。

+1

最新のコードを教えていただけますか?ここにまったく同じ問題の前に立っている私は012- ありがとう –

答えて

5

freefallr:はい。ここにコードがあります。 RGB-> YUVを変換し、YV12出力をpFullYPlane/pDownsampledUPlane/pDownsampledVPlaneに入れていることに注意してください。このコードは、このデータを使用するためにvpxencサンプルを修正したときに見栄えの良いWebMビデオを生成しました。

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; 
     } 
    } 
} 
+0

あなたが入力バッファはどうあるべきか、長い見当がつかない場合、私はまた、この http://en.wikipedia.org/wiki/YUV#Y.27UV420p_.28and_Y.27V12_or_YV12.29_to_RGB888_conversion を読んでお勧めします。 –

0

気にしないでください。私が使用していたスキームは正しいものでしたが、U/Vダウンサンプリングコードにバグがありました。

+0

RGB - > YUV変換コードを投稿できますか? –

+0

私もWebMで働いています! –

関連する問題