2017-08-16 16 views
0

私はYUYV rawファイルをC++のYUV420 rawファイルに変換しようとしています。書式はYUV Formats Pageのように文書化されています。私の出力ファイルは変換後に緑がかって見えます。私はExperts Exchangeのソースコードを採用して、UYVYではなくYUYVから変換しました。ここで私のソースコードは次のとおりV4L2_PIX_FMT_YUYV(YUV 4:2:2)をV4L2_PIX_FMT_YVU420(YUV 4:2:0)に変換してください

一般に
void conv422to420(uint8_t* src, uint8_t* dst) 
{ 
    uint8_t* pyFrame = dst; 
    uint8_t* puFrame = pyFrame + width_*height_; // Cb 
    uint8_t* pvFrame = puFrame + width_*height_/4; // Cr 

    int uvOffset = width_ * 2 * sizeof(uint8_t); 

    int i,j; 

    for(i=0; i<height_-1; i++) 
    { 
    for(j=0; j<width_; j+=2) 
    { 
     auto evenRow = ((i&1) == 0); 
     *pyFrame++ = *src++; 
     ++src; 
     uint16_t calc; 
     if (evenRow) 
     { 
      calc = *src; 
      calc += *(src + uvOffset); 
      calc /= 2; 
      *pvFrame++ = (uint8_t) calc; 
     } 
     *pyFrame++ = *src++; 
     ++src; 
     if (evenRow) 
     { 
      calc = *src; 
      calc += *(src + uvOffset); 
      calc /= 2; 
      *puFrame++ = (uint8_t) calc; 
     } 
    } 
    } 
} 

IがYUV420の値であることがYUYVに隣接する2つの列に2つのUと2つのV値の平均を取りました。私は "平均化"がこれを行う正しい方法であるかどうか分かりません。私は25.0 -f rawvideo -s 1280 -pix_fmt yuyv422 -i yuyv422.yuv -pix_fmt YUV420P -f -r rawvideo 25.0 -s 1280×720 -vデバッグyuv420p.yuv

-r

のffmpegの-yを使用しているので

は、YUV420 rawファイルを正常に生成し、自分の出力ファイルのdiffは、UチャネルとYチャネルで生成されたffmpegと大きく異なります。

私の質問は、そのような変換のためのオープンソースのソリューションはありますか?私のソリューションには何が間違っていますか?

答えて

0

デバッグのいくつかの試行後、小さな問題が判明しました.UV値を割り当てた後にsrcポインタをインクリメントしてください。コードは次のとおりです。

uint8_t* pyFrame = dst; 
uint8_t* puFrame = pyFrame + width_*height_* sizeof(uint8_t); // Cb 
uint8_t* pvFrame = puFrame + width_*height_* sizeof(uint8_t)/4; // Cr 

int uvOffset = width_ * 2 * sizeof(uint8_t); 

int i,j; 

for(i=0; i<height_-1; i++) 
{ 
    for(j=0; j<width_; j+=2) 
    { 
     auto evenRow = ((i&1) == 0); 
     *pyFrame++ = *src++; 
     if (evenRow) 
     { 
      uint16_t calc = *src; 
      calc += *(src + uvOffset); 
      calc /= 2; 
      *puFrame++ = *src; 
     } 
     ++src; 
     *pyFrame++ = *src++; 
     if (evenRow) 
     { 
      uint16_t calc = *src; 
      calc += *(src + uvOffset); 
      calc /= 2; 
      *pvFrame++ = (uint8_t) calc; 
     } 
     ++src; 
    } 
} 

画像が正しく変換されていることがわかりました。それを平均化するのがベストプラクティスなのかまだ分かりません。誰かが "ベストプラクティス"を持っているなら、私に知らせてください。

関連する問題