如何将解码器的输出表面传递给编码器的输入表面?

时间:2016-02-25 05:38:45

标签: android mediacodec surface

我试图了解表面到表面的方法如何与MediaCodec一起使用。在仅ByteBuffer方法中,解码数据放在OutputBuffers中。可以手动处理此非编码数据,然后传递给编码器的InputBuffers。

如果我们看一下Android MediaCodec CTS中使用表面到表面方法在解码器和编码器之间传递数据的示例,我们将解码器配置为将解码数据输出到名为outputSurface的Surface上,并且我们将编码器配置为在Surface上接收名为inputSurface的数据。

在文档中,createInputSurface以及Encoder配置中此表面的用法如下所述:

  

createInputSurface():请求Surface用作编码器的输入,代替输入缓冲区。

换句话说,这在ByteBuffers声明的CTS示例中是可见的:编码器没有InputBuffers。你有:

  • DecoderInputBuffers(从MediaExtractor接收视频轨道样本)
  • DecoderOutputBuffers(输出以拉出解码的yuv帧)
  • 无。 (嗯......输入Surface。)
  • EncoderOutputBuffers(输出拉动重新编码的东西以传递给多路复用器)

您可以使用以下代码行代替在Encoder InputBuffers中对数据进行排队:

outputSurface.awaitNewImage();
outputSurface.drawImage();
inputSurface.setPresentationTime(videoDecoderOutputBufferInfo.presentationTimeUs * 1000);
inputSurface.swapBuffers();

如何将解码器的ouputSurface内容传递给编码器的inputSurface?幕后具体发生了什么?

1 个答案:

答案 0 :(得分:2)

解码器/编码器的输出/输入Surface分别是特别配置的物理上连续的保留等)内存中的专用硬件(例如,GPUs,硬件(加速)编解码器)或软件模块可以以最适合性能需求的方式使用(通过使用硬件加速,DMA等功能)。

更具体地说,在当前的上下文中,解码器的输出Surface由SurfaceTexture支持,因此它可以在OpenGL environment中用作外部用于任何类型处理的纹理,然后在Surface上呈现,编码器可以从中读取和编码以创建最终的视频帧。

不巧的是,OpenGL只能渲染到Surface

因此解码器充当原始视频帧的提供商曲面(纹理) 运营商 OpenGL medium 将其呈现给编码器的输入 Surface ,这是目的地用于(待编码)视频帧。

为了进一步满足您的好奇心,请查看Editing frames and encoding with MediaCodec了解详情。

[编辑]

您可以检查grafika Continuous CameraShow + capture camera中的子项目,这些子项目当前会将相机帧(馈送到SurfaceTexture)呈现为视频(和显示)。基本上,唯一的变化是MediaCodec向SurfaceTexture提供帧而不是Camera。

Google CTS DecodeEditEncodeTest完全相同,可用作参考,以使学习曲线更顺畅。

从非常基础开始,正如fadden指出的那样使用Android graphics tutorials