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).

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...