Android Media Codec:解码和显示一个视频帧需要多长时间

时间:2016-12-30 17:10:32

标签: java android encoding decoding mediacodec

我找不到有关此主题的任何信息。也许有人可能会帮忙。 我正在使用Android MediaCodec来解码H264帧。 MediaCodec用于同步模式。我想测量从排队一帧到解码器的时间到屏幕上实际可见的时间。

所以在我的代码的某些时候我打电话给

codec.getInputBuffer(inIndex);

之后:

int outIndex = codec.dequeueOutputBuffer(bufferInfo, BUFFER_TIMEOUT);

if(outIndex >= 0)
    codec.releaseOutputBuffer(outIndex, true);
    if(PMVR.calculateLatency && validIteration) {
        PMVR.calculateLatency = false;
        PMVR.pingEnded = System.nanoTime();
}

问题一:我可以假设先前排队到输入缓冲区的帧是我在调用dequeuOutputBuffers()时解码的帧(注意:同步模式)吗?我找不到实际设置图片ID的选项......

问题二:我用releaseOutputBuffer()致电render=true。显示解码帧需要多长时间?

感谢您的帮助,

了Christoph

1 个答案:

答案 0 :(得分:1)

首先,请记住解码器以异步方式工作。无论您是以同步模式还是异步模式使用MediaCodec API,都不会改变它;只会改变您是否需要轮询解码器的输入/输出,或者是否通过回调获得它们。

一般情况下,如果你只传入一个数据包进行解码并等待解码后的帧,那么你就不会接近解码器的全部性能。在许多情况下,如果你以这种方式做事,你甚至无法实时解码视频。有些解码器甚至不会返回单帧输出,直到您输入了一些数据包(或信号流的结尾)。

您无法可靠地假设您获得的帧是与您传入的用于解码的数据包相对应的帧。如果流使用帧重新排序(如在具有B帧的H264中),则输出帧将不会与它们输入的顺序相同。如果数据包已损坏,解码器可能会跳过返回某些帧。

要通过解码器识别各个帧,您可以使用presentationTimeUs参数queueInputBuffer,该参数将传递到MediaCodec.BufferInfo中的相同字段。只要此值在所有输入数据包中都是唯一的,您就应该能够使用它来将输入数据包跟踪到输出帧中。

当您使用releaseOutputBuffer致电render=true时,框架将尽快显示;我不认为它在任何地方确定了多久,但是在一两个屏幕内刷新可能是你可以假设的。从API级别21开始,您也可以传递参数long renderTimestampNs,这样您就可以更准确地指定何时显示它。