2017-01-25 3 views
0

私はこのgithubの例を実行しています。 WebRTC着信I420FrameオブジェクトはyuvPlanesの3つの配列を持っているようですAndroidのorg.webrtc.VideoRenderer.I420Frame配列の画像

典型的なAndroidカメラアプリケーションは、PreviewCallback.onPreviewFrame byte []を単一のバイト配列として取得します。 私の仕事は、定期的にI420として画像をストリーミングすることです。 誰かがJPEG/PNGファイルのように1バイト[]配列からI420Frames yuvPlanesを生成する方法を教えてもらえますか?

非常に重要です。すべての回答が高く評価されました。

答えて

1

PreviewCallback.onPreviewFrame()は、JPEGまたはPNGストリームを返しません。カメラgetSupportedPreviewFormats()リストを確認してください(フロントとリアのカメラで異なる場合があります)。あなたはNV21がこのリストに掲載されていることが保証されています。運がよければ、APIレベル12 からYV12を選択することができます(Amazon Fire HD(2012)などの一部のデバイスではこのことがあり、実際にはYV12ストリーム)を配信できないことに注意してください。

それはYV12バイト配列からI420Frameを構築するのは簡単です:あなたはUとVのプレーンを割り当てる必要があり、NV21については

private VideoRenderer.I420Frame mFrame; 
void onPreviewFrame(byte[] yv12_data, Camera camera) { 
    if (mFrame == null) { 
     Camera.Parameters params = camera.getParameters(); // this is an expensive call, don't repeat it on every frame! 
     assert(params.getPreviewFormat() == ImageFormat.YV12); 
     int width = params.getPreviewSize().width; 
     int stride_y = 16 + ((width-1)/16)*16; 
     int stride_uv = 16 + ((stride_y/2-1)/16)*16; 
     int height = params.getPreviewSize().height; 
     mFrame = new VideoRenderer.I420Frame(width, height, 0, new int[]{stride_y, stride_uv, stride_uv}, new ByteBuffer[3], 0); 
    } 

    mFrame.yuvPlanes[0] = ByteBuffer.wrap(yv12_data, 0, mFrame.yuvStrides[0]*mFrame.height) // Y 
    mFrame.yuvPlanes[1] = ByteBuffer.wrap(yv12_data, mFrame.yuvStrides[0]*mFrame.height+mFrame.yuvStrides[2]*mFrame.height/2, mFrame.yuvStrides[1]*mFrame.height/2) // U 
    mFrame.yuvPlanes[2] = ByteBuffer.wrap(yv12_data, mFrame.yuvStrides[0]*mFrame.height, mFrame.yuvStrides[2]*mFrame.height/4) // V 

    ... do something with the frame 
} 

private VideoRenderer.I420Frame mFrame; 
void onPreviewFrame(byte[] nv21_data, Camera camera) { 
    if (mFrame == null) { 
     Camera.Parameters params = camera.getParameters(); // this is an expensive call, don't repeat it on every frame! 
     assert(params.getPreviewFormat() == ImageFormat.NV21); 
     int width = params.getPreviewSize().width; 
     int height = params.getPreviewSize().height; 
     mFrame = new VideoRenderer.I420Frame(width, height, 0, new int[]{width, width/2, width/2}, new ByteBuffer[3], 0); 
     mFrame.yuvPlanes[1] = ByteBuffer.wrap(new byte[width*height/4]); 
     mFrame.yuvPlanes[2] = ByteBuffer.wrap(new byte[width*height/4]); 
    } 

    mFrame.yuvPlanes[0] = ByteBuffer.wrap(nv21_data, 0, mFrame.width*mFrame.height) // Y 
    for (int top=0, from=mFrame.width*mFrame.height; from < mFrame.width*mFrame.height*3/2; to++, from+=2) { 
     mframe.yuvPlanes[1][to] = nv21_data[from+1]; // U 
     mframe.yuvPlanes[2][to] = nv21_data[from]; // V 
    } 

    ... do something with the frame 
} 
+0

は卿を返信いただきありがとうございます。 YUVイメージからバイト配列を取得し、I420Frameを作成しています。今私はこのエラーを取得していますJava.Lang.ArrayIndexOutOfBoundsException:length = 1179648; regionStart = 0; mFrame.yuvPlanes [0]の場合はregionLength = 2073600です。どのように私はそれをストリームすることができる必要があります画像のサイズに関係なく確認することができますか? – user2801184

+0

詳細を入力してください。この例外のスタックトレース。どのプレビューフォーマットを使用しますか?プレビューサイズ?? –

0
I420Frame onPreviewFrame(byte[] yv12_data) 
     { 
      if (mFrame == null) 
      { 
       //Camera.Parameters params = camera.getParameters(); // this is an expensive call, don't repeat it on every frame! 
       //assert(params.getPreviewFormat() == ImageFormat.YV12); 
       int width = 640; 
       int stride_y = 16 + ((width - 1)/16) * 16; 
       int stride_uv = 16 + ((stride_y/2 - 1)/16) * 16; 
       int height = 480; 
       mFrame = new VideoRenderer.I420Frame(width, height, new int[] { stride_y, stride_uv, stride_uv }, new ByteBuffer[3]); 
      }     

      mFrame.YuvPlanes[0] = ByteBuffer.Wrap(yv12_data, 0, mFrame.YuvStrides[0] * mFrame.Height); // Y 
      mFrame.YuvPlanes[1] = ByteBuffer.Wrap(yv12_data, (mFrame.YuvStrides[0] * mFrame.Height) , mFrame.YuvStrides[1] * mFrame.Height);// U 
      mFrame.YuvPlanes[2] = ByteBuffer.Wrap(yv12_data, (mFrame.YuvStrides[0] * mFrame.Height)+ (mFrame.YuvStrides[1] * mFrame.Height), mFrame.YuvStrides[2] * mFrame.Height); // V 
      return mFrame; 
      // ... do something with the frame 
     } 
関連する問題