使用带有MediaCodec的getInputImage进行编码

Har*_*ryS 3 encoding android mediacodec

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

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

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

从MediaCodec中取出输入缓冲区后

int inputBufferId = encoder.dequeueInputBuffer (5000);
Run Code Online (Sandbox Code Playgroud)

我可以访问返回的正确图像

encoder.getInputImage (inputBufferId);
Run Code Online (Sandbox Code Playgroud)

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

encoder.queueInputBuffer (inputBufferId, position, size, presentationUs, 0);
Run Code Online (Sandbox Code Playgroud)

方法可用,但没有任何匹配图像.可以使用检索呼叫所需的大小

ByteBuffer  byteBuffer = encoder.getInputBuffer (inputBufferId);
Run Code Online (Sandbox Code Playgroud)

byteBuffer.remaining ();
Run Code Online (Sandbox Code Playgroud)

但是除了getInputImage()之外,这似乎会在调用时搞砸编码器.

另一个缺少的文档或者我错了什么?

mst*_*sjo 5

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

第二种选择是在getInputBuffer你展示时使用,但有一点需要注意.第一次打电话getInputBufferByteBuffer接听remaining()它.(或者也许capacity()效果更好?)只有在此之后,才打电话getInputImage.细节是,在调用时getInputImage,ByteBuffer返回的是getInputBuffer无效的,反之亦然.(文档说"在调用此方法之后,任何先前为同一输入索引返回的ByteBuffer或Image对象必须不再使用." MediaCodec.getInputBuffer(int).)