使用 MediaCodec API JNI 解码 H.264 流
Decode H.264 stream using MediaCodec API JNI
我正在使用 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 函数来解码输入流,但这些都是挑战 -
- 此 resource 指出 -
...you can't do anything with the decoded video frame but render them
to surface
此处已通过 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
或 configure()
?
我发现您提出的函数定义存在两个基本问题。
首先,MediaCodec 在访问单元(H.264 的 NAL 单元)上运行,而不是流中的任意数据块,因此您需要一次传入一个 NAL 单元。一旦接收到块,编解码器可能希望在生成任何输出之前等待其他帧到达。你一般不能传入一帧输入然后等待接收一帧输出。
其次,正如您所指出的,ByteBuffer 输出是采用多种颜色格式之一进行 YUV 编码的。格式因设备而异;高通设备特别使用他们自己的专有格式。 (不过,它已经过逆向工程,所以如果你四处搜索,你可以找到一些代码来解开它。)
常见的解决方法是将视频帧发送到 SurfaceTexture,后者将它们转换为 GLES "external" 纹理。这些可以通过多种方式进行操作,或者呈现到 pbuffer 并使用 glReadPixels()
.
提取
我正在使用 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 函数来解码输入流,但这些都是挑战 -
- 此 resource 指出 -
...you can't do anything with the decoded video frame but render them to surface
此处已通过 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
或 configure()
?
我发现您提出的函数定义存在两个基本问题。
首先,MediaCodec 在访问单元(H.264 的 NAL 单元)上运行,而不是流中的任意数据块,因此您需要一次传入一个 NAL 单元。一旦接收到块,编解码器可能希望在生成任何输出之前等待其他帧到达。你一般不能传入一帧输入然后等待接收一帧输出。
其次,正如您所指出的,ByteBuffer 输出是采用多种颜色格式之一进行 YUV 编码的。格式因设备而异;高通设备特别使用他们自己的专有格式。 (不过,它已经过逆向工程,所以如果你四处搜索,你可以找到一些代码来解开它。)
常见的解决方法是将视频帧发送到 SurfaceTexture,后者将它们转换为 GLES "external" 纹理。这些可以通过多种方式进行操作,或者呈现到 pbuffer 并使用 glReadPixels()
.