我检查了两台 Android 设备上 MediaExtractor 的输出,在相同的情况下,它似乎在它们上生成略有不同的样本 视频文件。
对于一个设备,非 VCL NAL 单元会连接到下一个 VCL 单元以 产生一个 sample 。在另一台设备上,每个非 VCL 单元构成一个完整的样本。
另一个区别:在一个设备上,样本具有前导 0 字节和起始代码前缀 (001);另一方面,这些字节被省略。
如果我尝试在其他设备上使用第一个设备的 NAL 单元格式,则视频无法播放。
如果我正在生成自己的 NAL 单元(不使用 MediaExtractor),是否有原则性的方法来了解 MediaCodec H264 解码器期望的格式?
最佳答案
官方方法是提供起始码前缀(这是在一个数据包中包含多个 NAL 单元所必需的) - 这是所有 OpenMAX IL(MediaCodec 下面内部使用的标准)解码器所期望的(即使有些解码器也可能会这样做)支持其他格式)。无论您将 SPS/PPS 放在单独的缓冲区中(设置了 BUFFER_FLAG_CODEC_CONFIG 标志),还是将其添加到带有 VCL NAL 单元的缓冲区中,都无关紧要 - 我认为解码器应该能够处理这两种情况。我认为您不会找到任何单独的文档来澄清 Android 的这一点,除了从设备实际执行的操作中隐式推导出来之外。
您能否指出哪些设备(以及哪些平台版本)输出这些比特流变体的哪些组合,以及哪些组合在哪个设备上失败?据我所知,存在起始码的流应该在任何地方都可以工作,但当然也可能有异常(exception)。从 Android 4.3 开始,这些东西应该比 4.1 和 4.2 上表现得更好。
一些供应商似乎确实在 MediaExtractor 中做了一些非标准的事情 - 我已经在 https://code.google.com/p/android/issues/detail?id=74356 上写了一份关于此的错误报告。 。在这种情况下,三星特定的非标准行为将通过 MediaFormat 中的 isDMCMMExtractor=1
键来表示。我真的同意 MediaExtractor 应该被更严格地指定,因为现在它主要只能用于将数据输入 MediaCodec(假设它被理解,至少对于供应商特定的硬件编解码器),但很难说它实际上做了什么,如果应用程序想要对 MediaExtractor 输出执行其他操作(例如使用第三方 bundle 解码器进行解码,或通过网络发送提取的数据等)。
如果某些设备无法解码事实上的标准比特流格式(但只有在按照平台的 MediaExtractor 的方式进行破坏时才能成功),听起来好像需要进行另一个 CTS 兼容性测试,通过测试原始硬编码的解码数据包(这样 MediaExtractor 就无法介入并转换事物)。 EncodeDecodeTest(请参阅 http://bigflake.com/mediacodec/)等 CTS 测试在此设备上是否正常工作?如果确实如此,但如果解码标准数据包格式失败,则意味着设备的编码器也会输出非标准的内容。
关于android - MediaExtractor 如何确定要放入 H264 NAL 单元中的内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28773016/