android – 解码mp4 / h.264使用没有MediaExtractor的MediaCodec,预期的访问单元格式

前端之家收集整理的这篇文章主要介绍了android – 解码mp4 / h.264使用没有MediaExtractor的MediaCodec,预期的访问单元格式前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图使用MediaCodec API进行解码,而不使用MediaExtractor API.相反,我使用mp4parser从mp4文件获取样本.目前,我只使用h.264 / avc编码的视频内容.

MediaCodec API的官方文件指出:

buffers do not start and end on arbitrary byte boundaries,this is not a stream of bytes,it’s a stream of access units.

意思是,我必须将访问单元提供给解码器.但是,我想念这些信息中的一些细节:

对于h.264,在mp4样本中,可以有多个NAL单元,每个单元前面有4个(默认)字节,指定NAL单元长度.

现在我的问题:

>可以有mp4样本,其中编解码器配置NAL单元(sps,pps)与包含编码(部分)帧的NAL单元混合.在这种情况下,我应该在调用queueInputBuffers()时传递标志BUFFER_FLAG_CODEC_CONFIG吗?
> mp4样本中还可以有其他(附加)NAL单元,如SEI或访问单元分隔符NAL单元.那些呢?没问题?

我尝试了不同的可能性,但我从Android获得的所有反馈都是dequeueOutputBuffer()的调用超时(或者如果我将-1作为超时参数传递则不返回).因此,我似乎无法解决此问题.

任何建议做什么或在哪里看也是非常受欢迎的.

解决方法

指定NAL单元长度的NAL长度前缀需要在传递给MediaCodec进行解码之前转换为Annex-B起始码(字节0x00,0x00,0x01). (有些解码器可能会立即接受MP4格式,但这并不常见.)

存储在文件中avcC原子中的SPS / PPS也需要转换为使用Annex-B启动码.请注意,avcC atom包含一些您不需要传递给解码器的其他字段.您可以在发送任何实际帧之前将SPS和PPS打包在一个缓冲区中(在每个缓冲区之前使用启动码)并设置BUFFER_FLAG_CODEC_CONFIG标志,或者在用于配置解码器的MediaFormat中传递它们(使用Annex-B启动码) (在一个ByteBuffer中使用键“csd-0”,或在两个单独的键中作为“csd-0”和“csd-1”).

如果你的文件在每个帧中有更多的SPS / PPS,你应该只能将它们作为帧的一部分传递,并且大多数解码器应该能够应对它(特别是如果它与之前的SPS / PPS相同而不是配置改变).

因此:将属于一个样本的所有NAL单元传递到一个缓冲区中,但将所有NAL单元长度标头重写为起始码.并且要处理在流本身内没有碰巧有SPS / PPS的MP4文件,解析avcC原子(我不知道mp4parser以哪种格式返回)并将带有启动码的SPS和PPS传递给解码器(通过MediaFormat作为“csd-0”或作为第一个缓冲区,设置BUFFER_FLAG_CODEC_CONFIG).

原文链接:https://www.f2er.com/android/309674.html

猜你在找的Android相关文章