2016-08-10 2 views
0

私はYUV420pイメージをC++でRGB24に変換し、C#でバイト配列からビットマップを作成しようとしています。ffmpeg YUV420からRGB24は1つの行のみを変換します

私の画像サイズは1920 w * 1020 hで、ffmpegデコーダはlinesizes = {1920、960、960}のデータに対して3つのプレーナーを与えます。しかし、sws_scaleの後、私はlinesize = 5760の1つのプレーンだけでRGB画像を取得しています。 それは正しいようには見えません。データの1行だけでなく、5760 * hを取得する必要があります。私は間違っているの? AVFramelinesizeフィールドは、データの総量であることを

//c++ part 
    if (avcodec_receive_frame(m_decoderContext, pFrame) == 0) 
    { 
     //RGB 
     sws_ctx = sws_getContext(m_decoderContext->width, 
      m_decoderContext->height, 
      m_decoderContext->pix_fmt, 
      m_decoderContext->width, 
      m_decoderContext->height, 
      AV_PIX_FMT_RGB24, 
      SWS_BILINEAR, 
      NULL, 
      NULL, 
      NULL 
     ); 

     sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data, pFrame->linesize, 
      0, pFrame->height, 
      pFrameRGB->data, pFrameRGB->linesize); 


//c# part (im reading data from pipe and its equal to c++ part)------------------------------------------------------------------ 
     byte[] rgbch = new byte[frameLen]; 
     for (int i=0; i<frameLen; i++) 
     { 
      rgbch[i] = Convert.ToByte(pipe.ReadByte()); 
     } 

     if (rgbch.Length > 0) 
     { 
      var arrayHandle = System.Runtime.InteropServices.GCHandle.Alloc(rgbch, 
    System.Runtime.InteropServices.GCHandleType.Pinned); 

      var bmp = new Bitmap(1920, 1080, 
       3, 
       System.Drawing.Imaging.PixelFormat.Format24bppRgb, 
       arrayHandle.AddrOfPinnedObject() 
      ); 

      pictureBox1.Image = bmp; 
     } 
+0

なぜあなたはそれが正しくないと思いますか?平面のピクセルデータを与え、各行が3 * 1920のサイズを持ち、合計メモリ領域が3 * 1920 *の高さであるインターリーブピクセルデータを取得します。 –

+0

さて、私は3 * 1920 *高さのメモリ領域がどこにあるのか分かりません。 'pFrameRGB-> data'には3 * 1920の行が1つしかありません...フルイメージの場合、他の行はすべて必要ですか?.. – Aleksey

+0

' sws_scale'の戻り値は何ですか?出力バッファの行数 - 'pFrameRGB-> data'でなければなりません。それが1でなければ、あなたの仮定は間違っています。それが本当に1なら、何かが間違っている。 –

答えて

1

あなたの仮定が正しくありません。変数名には1行の長さが入りますが、戻り値はsws_scaleで、行数がわかります。したがって、出力ビットマップの合計メモリ範囲サイズはlinesizeに戻り値を乗じたものになります。

関連する問題