MediaCodec解码H264流限制



我正在使用mediacodec在三星S6上解码H264流,Android 5.1.1,发现输入缓冲区到MediaCodec必须以" 0001"开头(并且不需要设置PPS,SPS)或ACODEC将报告错误。

我还尝试使用MediaExtractor播放MP4文件,它可以正常运行,但是MediaCodec的缓冲区并非以" 0001"开头。

我不知道为什么Decodec A H264流具有这样的限制,目前我需要分析来自插座的流,并将数据切成小包装(每个软件包以0001开头),然后将它们交给MediaCodec,但是它是效率低下。

MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 1024, 1024);

某些特定的解码器也可能能够以" mp4"格式(使用不同类型的启动码)中解码H264 NAL单位,但是在所有设备上都不能保证。

>

,如果三星的MediaExtractor版本以这种格式返回,如果他们知道自己的解码器可以处理它。至少较早的先例是,三星与时间戳有关MediaStractor的时间戳做了同样的,非标准的事情,例如,请参见例如https://code.google.com/p/android/issues/detail?id=74356。

(让MediaExtractor返回数据只有当前设备的解码器才能处理的数据是错误的IMO,因为一个人可能想使用MediaExtractor读取文件,但是将压缩数据通过网络发送到另一个设备进行解码,在这些设备中案例,以非标准格式返回数据是错误的。)

正如Fadden所写,MediaCodec在整个NAL单元上运行,因此您需要以这种格式提供数据(即使您认为感觉效率低下)。如果您通过套接字收到该信息(关于帧边界)不容易可用的格式的数据,那么这是您的协议格式的问题(例如,实现RTP接收并不容易!),而不是MediaCodec本身 - 在解码之前需要具有完整框架的一个非常普遍的限制,而不是能够喂养随机块,直到您拥有完整的框架为止。除非您自己的实施效率低下,否则这不应降低。

一般而言,Android期望每个输入的NAL单位。对于某些设备,我发现在媒体格式上设置CSD-0/1以使H264无法持续工作。但是,如果您将每个参数设置为输入缓冲器,则媒体codec将其作为格式变化。

int outputBufferIndex = NativeDecoder.DequeueOutputBuffer (info, 1000);
if (outputBufferIndex == (int)MediaCodec.InfoOutputFormatChanged) {
    Console.WriteLine ("Format changed: {0}", NativeDecoder.OutputFormat);
} else if (outputBufferIndex >= 0) {
    CodecOutputBufferAvailable (NativeDecoder, outputBufferIndex, info);
}

还指出,Nexus和其他一些三星设备必须设置它是必须的:

formatDescription.SetInteger(MediaFormat.KeyWidth, SelectedPalette.Value.Width);
formatDescription.SetInteger(MediaFormat.KeyHeight, SelectedPalette.Value.Height);
formatDescription.SetInteger(MediaFormat.KeyMaxInputSize, SelectedPalette.Value.Width * SelectedPalette.Value.Height);

我很幸运,我可以询问这些决议。但是您可以从SPS和PPS NAL单位手动解析该分辨率。

//注意我在这里使用Xamarin。但是电话和事物几乎是一样的。我可以肯定的是,iOS videotoolbox xamarin包装器中有错误,是的。如果您考虑使用Xamarin进行视频解码,请记住这一点。它非常适合所有事物,但所有内容都更加自定义或低级。

最新更新