2011-01-22 4 views
4

webm 비디오로 전환해야하는 jpg를 생성하는 앱이 있습니다. jpegs에서 rgb 데이터를 vpxenc 샘플로 가져 오려고합니다. 출력 비디오에서 원래 jpg의 기본 모양을 볼 수 있지만 모든 것이 녹색으로 착색됩니다 (검은 색이어야하는 픽셀조차도 중간 정도 녹색 임). 그리고 다른 모든 스캔 라인에는 일부 쓰레기가 있습니다.은 RGB 프레임에서 webm 비디오를 생성해야합니다.

I는 그것을 VPX_IMG_FMT_YV12 I 그래서 같이 구성된다 믿고있어 데이터를 공급하는 것을 시도하고, 각 프레임에 대한

8 비트 Y의 데이터를 각각 2 × V 블록 8 비트 평균 8-

Images

그것은 enti가있다 : U 여기

을 차단 각각 2 × 2의 비트 평균은 나오고 소스 이미지와 비디오의 스크린 샷입니다 RGB-> YV12 변환을 잘못하고있을 가능성이 있습니다. 그러나 8 비트 Y 데이터 만 인코딩하고 U 및 V 블록을 0으로 설정하더라도 비디오는 거의 같습니다. A + B + C + D ...

// (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; 

다음 I 막 (DO, I는 vpxenc로 물품 U 및 V에 대한 2 × 2 필터링 된 값을 생성하기 : I는 기본적으로이 방정식을 통해 내 RGB 데이터를 실행하고있어)/4, 여기서, a, b, c, d는 각 2x2 픽셀 블록의 U 또는 V 값이다.

그래서 궁금하네요 :

  1. 이 좋은 WEBM 비디오를 얻을 수 vpx_codec_encode하는 RGB 데이터를 받아이를 공급하는 (코드) 더 쉬운 방법이 있나요?

  2. 내 RGB-> YV12 변환이 어딘가 잘못 되었습니까?

어떤 도움을 주시면 감사하겠습니다.

+1

업데이트 된 코드를 알려주시겠습니까? Iam 정확히 여기 같은 문제 앞에 서있어 ;-) 감사합니다 –

답변

5

무료 수신자 : 물론입니다. 여기에 코드가 있습니다. YV12 출력을 pFullYPlane/pDownsampledUPlane/pDownsampledVPlane에 넣는 것은 물론 RGB-> YUV를 변환하는 것입니다. 이 코드는이 데이터를 사용하기 위해 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과 함께 일하고있다! –

관련 문제