使用MediaCodec API JNI解码H.264流

时间:2015-09-08 10:46:51

标签: android c++ mediacodec

我正在使用MediaCodec API开发H.264解码器。我试图在一个函数中调用JNI层中的MediaCodec java API:

void Decompress(const unsigned char *encodedInputdata, unsigned int inputLength, unsigned char **outputDecodedData, int &width, int &height) {
    // encodedInputdata is encoded H.264 remote stream
    // .....
    // outputDecodedData = call JNI function of MediaCodec Java API to decode
    // .....
}

稍后我会将outputDecodedData发送到我现有的视频渲染管道并在Surface上渲染。

我希望我能够编写一个Java函数来解码输入流,但这些都是挑战 -

  1. resource表示 -
  2.   

    ...您无法对已解码的视频帧执行任何操作,但会对其进行渲染   表面

    此处Surface已通过decoder.configure(format, surface, null, 0)呈现表面上的输出ByteBuffer并声明We can't use this buffer but render it due to the API limit

    那么,我是否可以将输出ByteBuffer发送到本机图层以转换为unsigned char*并传递到我的渲染管道而不是传递Surface ot configure()

1 个答案:

答案 0 :(得分:1)

我看到你提出的函数定义存在两个基本问题。

首先,MediaCodec对访问单元(H.264的NAL单元)进行操作,而不是来自流的任意数据块,因此您需要一次传入一个NAL单元。一旦接收到块,编解码器可能希望在产生任何输出之前等待其他帧到达。您通常不能传入一帧输入并等待接收一帧输出。

其次,如您所述,ByteBuffer输出采用多种颜色格式之一进行YUV编码。格式因设备而异; Qualcomm设备特别使用他们自己的专有格式。 (虽然它已被反向设计,所以如果你四处搜索,你可以找到一些代码来解开它。)

常见的解决方法是将视频帧发送到SurfaceTexture,将其转换为GLES“外部”纹理。这些可以通过各种方式进行操作,或者渲染为pbuffer并使用glReadPixels()进行提取。