使用带有MediaCodec的getInputImage进行编码

时间:2016-02-14 17:41:38

标签: android encoding mediacodec

背景:我进行视频文件解复用,解码视频轨道,对接收到的帧应用一些更改,再次解码和复用它们。

在Android中执行此操作的已知问题是供应商指定编码器/解码器颜色格式的数量。 Android 4.3引入了表面以使设备独立,但我发现很难使用它们,因为我的框架更改例程需要Canvas写入。

自Android 5.0以来,使用灵活的YUV420色彩格式很有前途。与用于解码的getOutputImage和用于编码的getInputImage一起,Image对象可以用作从解码MediaCodec检索的格式。我使用getOutputImage进行解码工作,并可以在RGB转换后可视化结果。为了编码YUV图像并将其排队到MediaCodec(编码器),似乎缺少一个链接:

从MediaCodec

出列输入缓冲区后
int inputBufferId = encoder.dequeueInputBuffer (5000);

我可以访问由

返回的正确图像
encoder.getInputImage (inputBufferId);

我填写了图像缓冲区 - 这也是有效的,但是我没有看到将输入缓冲区排队回编解码器进行编码的方法......只有一个

encoder.queueInputBuffer (inputBufferId, position, size, presentationUs, 0);

方法可用,但没有任何匹配图像。可以使用

检索呼叫所需的大小
ByteBuffer  byteBuffer = encoder.getInputBuffer (inputBufferId);

byteBuffer.remaining ();

但是除了getInputImage()之外,这似乎搞砸了编码器。

另一篇缺少的文档还是我错了?

1 个答案:

答案 0 :(得分:5)

这确实有点问题 - 最简单的方法可能是计算Image中任何平面的起始指针与任何平面的最后一个字节之间的最大距离,但是你需要本机代码来做这(为了获得直接字节缓冲区的实际指针值)。

第二种方法是在显示时使用getInputBuffer,但有一点需要注意。首先致电getInputBuffer以获取ByteBuffer并致电remaining()。 (或者capacity()可能效果更好?)。只有在此之后,请致电getInputImage。详细信息是,在调用getInputImage时,ByteBuffer返回的getInputBuffer会失效,反之亦然。 (文档说“在调用此方法之后,任何先前为同一输入索引返回的ByteBuffer或Image对象必须不再使用。”​​MediaCodec.getInputBuffer(int)中。)