繁体   English   中英

媒体编解码器解码h264流限制

[英]mediacodec decode h264 stream limitation

我正在使用mediacodec在三星S6,Android 5.1.1上解码h264流,发现mediacodec的输入缓冲区必须以“ 0001”开头(并且不需要设置pps,sps),否则ACodec将报告错误。

我还尝试使用mediaextractor播放mp4文件,但工作正常,但mediacodec的缓冲区不是以“ 0001”开头。

我不知道为什么h264流的解码器有这样的限制,目前我需要分析套接字中的流,并将数据切成小包(每个包以0001开头),然后将它们提供给mediacodec,但这效率低下。

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

一些特定的解码器也可能能够解码“ mp4”格式的H264 NAL单元(具有不同类型的起始码),但这不能保证在所有设备上都能实现。

如果三星的MediaExtractor版本知道自己的解码器可以处理它,则可能是这种格式的返回。 至少在更早的先例中,三星使用其MediaExtractor版本对时间戳进行了相同的非标准操作,请参见例如https://code.google.com/p/android/issues/detail?id=74356

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

正如fadden所写,MediaCodec可以在完整的NAL单元上运行,因此您需要以这种格式提供数据(即使您认为效率很低)。 如果您通过套接字接收的数据格式不易获得此信息(关于帧边界),那么这就是协议格式的问题(例如,实现RTP接收并不容易!),而不是MediaCodec本身-这是一个非常普遍的限制,需要在解码之前具有完整帧,而不是在整个帧之前都无法提供随机块。 除非您自己的实现效率低下,否则它应该不会效率低下。

一般来说,Android会期望每个输入的最终单位。 对于某些设备,我发现将h264的媒体格式上的csd-0 / 1设置为不一致。 但是,如果您将每个参数集作为输入缓冲区,则媒体编解码器会将其作为格式更改。

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最终单位手动解析分辨率。

//注意,我在这里使用Xamarin。 但是电话和事情几乎相同。 我相当确定iOS VideoToolbox Xamarin Wrapper中存在错误,是的。如果您考虑使用Xamarin进行视频解码,请记住这一点。 它适用于所有事物,但更定制或低级的任何事物。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM