解码器的输出表面如何传递到编码器的输入表面?
How does an output surface of a Decoder is passed to an input surface of an Encoder?
我正在尝试了解表面对表面方法如何与 MediaCodec 配合使用。在仅使用 ByteBuffer 的方法中,解码后的数据放在 OutputBuffers 中。可以手动处理此非编码数据,然后将其传递给编码器的 InputBuffers。
如果我们看一下来自 Android MediaCodec CTS 的示例,使用表面到表面的方法在解码器和编码器之间传递数据,我们将解码器配置为将解码数据输出到一个名为 outputSurface 的 Surface,我们配置 Encoder 以接收名为 inputSurface 的 Surface 上的数据。
在文档中,createInputSurface 和这个表面在编码器配置中的用法是这样描述的:
createInputSurface(): Requests a Surface to use as the input to an encoder, in place of input buffers.
换句话说,这在 ByteBuffers 声明的 CTS 示例中可见:编码器没有 InputBuffers。你有:
- DecoderInputBuffers(从 MediaExtractor 接收视频轨道样本)
- DecoderOutputBuffers(输出以拉取已解码的 yuv 帧)
- 没有。 (嗯……输入Surface。)
- EncoderOutputBuffers(输出以拉取重新编码的内容以传递给多路复用器)
您没有在编码器输入缓冲区中排队数据,而是使用了以下代码行:
outputSurface.awaitNewImage();
outputSurface.drawImage();
inputSurface.setPresentationTime(videoDecoderOutputBufferInfo.presentationTimeUs * 1000);
inputSurface.swapBuffers();
Decoder的ouputSurface内容是如何传递给Encoder的inputSurface的?幕后具体发生了什么?
解码器's/encoder的output/inputSurface
分别是特殊配置(要么物理连续 或 reserved 等)专用硬件(例如,GPUs
、硬件(加速)编解码器)或软件模块可以以最适合的方式使用的内存满足性能需求(通过使用硬件加速、DMA 等功能)。
更具体地说,例如,在当前上下文中,解码器的输出 Surface 由 SurfaceTexture
支持,因此它可以在 OpenGL environment
中用作 ]external 纹理在表面上渲染之前进行任何类型的处理,编码器可以从表面读取和编码以创建最终视频帧。
并非巧合,OpenGL 只能渲染到 Surface
。
因此解码器充当原始视频帧的提供者,表面(纹理) carrier, OpenGL medium 将其渲染到编码器的 输入 Surface 是(要编码的)视频帧的 目的地。
为了进一步满足您的好奇心,请查看 了解更多详情。
[编辑]
您可以查看 grafika
Continuous Camera or Show + capture camera 中的子项目,该子项目当前将相机帧(馈送到 SurfaceTexture)渲染到视频(并显示)。所以本质上,唯一的变化是 MediaCodec 将帧馈送到 SurfaceTexture 而不是 Camera。
Google CTS DecodeEditEncodeTest 完全一样,可以作为参考,让学习曲线更平滑
从最基础的开始,正如 fadden 指出的那样,使用 Android graphics tutorials
我正在尝试了解表面对表面方法如何与 MediaCodec 配合使用。在仅使用 ByteBuffer 的方法中,解码后的数据放在 OutputBuffers 中。可以手动处理此非编码数据,然后将其传递给编码器的 InputBuffers。
如果我们看一下来自 Android MediaCodec CTS 的示例,使用表面到表面的方法在解码器和编码器之间传递数据,我们将解码器配置为将解码数据输出到一个名为 outputSurface 的 Surface,我们配置 Encoder 以接收名为 inputSurface 的 Surface 上的数据。
在文档中,createInputSurface 和这个表面在编码器配置中的用法是这样描述的:
createInputSurface(): Requests a Surface to use as the input to an encoder, in place of input buffers.
换句话说,这在 ByteBuffers 声明的 CTS 示例中可见:编码器没有 InputBuffers。你有:
- DecoderInputBuffers(从 MediaExtractor 接收视频轨道样本)
- DecoderOutputBuffers(输出以拉取已解码的 yuv 帧)
- 没有。 (嗯……输入Surface。)
- EncoderOutputBuffers(输出以拉取重新编码的内容以传递给多路复用器)
您没有在编码器输入缓冲区中排队数据,而是使用了以下代码行:
outputSurface.awaitNewImage();
outputSurface.drawImage();
inputSurface.setPresentationTime(videoDecoderOutputBufferInfo.presentationTimeUs * 1000);
inputSurface.swapBuffers();
Decoder的ouputSurface内容是如何传递给Encoder的inputSurface的?幕后具体发生了什么?
解码器's/encoder的output/inputSurface
分别是特殊配置(要么物理连续 或 reserved 等)专用硬件(例如,GPUs
、硬件(加速)编解码器)或软件模块可以以最适合的方式使用的内存满足性能需求(通过使用硬件加速、DMA 等功能)。
更具体地说,例如,在当前上下文中,解码器的输出 Surface 由 SurfaceTexture
支持,因此它可以在 OpenGL environment
中用作 ]external 纹理在表面上渲染之前进行任何类型的处理,编码器可以从表面读取和编码以创建最终视频帧。
并非巧合,OpenGL 只能渲染到 Surface
。
因此解码器充当原始视频帧的提供者,表面(纹理) carrier, OpenGL medium 将其渲染到编码器的 输入 Surface 是(要编码的)视频帧的 目的地。
为了进一步满足您的好奇心,请查看
[编辑]
您可以查看 grafika
Continuous Camera or Show + capture camera 中的子项目,该子项目当前将相机帧(馈送到 SurfaceTexture)渲染到视频(并显示)。所以本质上,唯一的变化是 MediaCodec 将帧馈送到 SurfaceTexture 而不是 Camera。
Google CTS DecodeEditEncodeTest 完全一样,可以作为参考,让学习曲线更平滑
从最基础的开始,正如 fadden 指出的那样,使用 Android graphics tutorials