我正在使用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函数来解码输入流,但这些都是挑战 -
...您无法对已解码的视频帧执行任何操作,但会对其进行渲染 表面
此处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()
?
答案 0 :(得分:1)
我看到你提出的函数定义存在两个基本问题。
首先,MediaCodec对访问单元(H.264的NAL单元)进行操作,而不是来自流的任意数据块,因此您需要一次传入一个NAL单元。一旦接收到块,编解码器可能希望在产生任何输出之前等待其他帧到达。您通常不能传入一帧输入并等待接收一帧输出。
其次,如您所述,ByteBuffer输出采用多种颜色格式之一进行YUV编码。格式因设备而异; Qualcomm设备特别使用他们自己的专有格式。 (虽然它已被反向设计,所以如果你四处搜索,你可以找到一些代码来解开它。)
常见的解决方法是将视频帧发送到SurfaceTexture,将其转换为GLES“外部”纹理。这些可以通过各种方式进行操作,或者渲染为pbuffer并使用glReadPixels()
进行提取。