我打算在Android平台上将YUV数据编码为H264格式。我已经实现了所有实现但是有一个小问题在这里询问有关使用dequeOutputBuffer()调用返回的DSI数据。
目前,对于第一次调用dequeOutputBuffer(),我得到了DSI数据。因此,对于ViceoEncoder的第一个YUV帧输入,我两次调用dequeOutputBuffer()来获取编码流。对于剩余的帧,我只调用dequeOutputBuffer()一次以获得相应的编码数据。这种方法适用于在ARM arch上运行的设备,但在x86 arch上运行的设备上,它在dequeOutputBuffer()期间挂起,同时编码第一个YUV帧。
所以,我的问题是:
希望问题很明确。
答案 0 :(得分:1)
视频编码器在产生任何输出之前将接受N帧。在某些情况下,N将为1,您将在提供单个输入帧后立即看到输出帧。其他编解码器需要在开始产生输出之前收集相当多的视频数据。看起来你已经设法通过加倍帧并丢弃一半的输出来解决当前的情况,但你应该知道不同的设备和不同的编解码器将表现不同(假设可移植性是一个问题)。
CSD数据在设置了BUFFER_FLAG_CODEC_CONFIG
标志的缓冲区中提供。 MediaCodec
中没有记录的行为是否或何时出现此类缓冲区。 (事实上,如果你使用的是VP8,it doesn't appear at all。)对于AVC,它会到达第一个缓冲区。如果您对CSD数据不感兴趣,只需忽略设置了该标志的任何数据包。
由于缓冲区信息标志适用于整个数据缓冲区,因此API不提供返回单个缓冲区的方法,该缓冲区中包含CSD和编码帧数据。
另请注意,编码器可以重新排序输出,因此您可以提交帧0,1,2并接收0,2,1的编码数据。跟踪的最简单方法是为每个唯一标识它的帧提供一个演示时间戳。一些编解码器将使用PTS值来调整编码质量以尝试满足比特率目标,因此您需要使用合理的“实际”值,而不是一个简单的整数计数器。