android - MediaExtractor 如何确定要放入 H264 NAL 单元中的内容?

标签 android h.264 android-mediacodec mediaextractor

我检查了两台 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/

相关文章:

android - 一个 Surface 上的多个视频

android - 在终止的应用程序中设置警报管理器的 nullPointerException

php - 服务器端 PHP session 在 android 中不起作用

Android MediaCodec 似乎可以缓冲 H264 帧

c++ - 使用 ffmpeg 库将 .264 转换为 .ts

c++ - Live555截断FFMpeg的编码数据

android - Android MediaCodec NDK 未使用 SPS/PPS VUI

java - Edittext 和 ProgressDialog 均不出现

android - 如何重置所有 Activity 并启动新 Activity ?

ffmpeg - 升级现有Level-4.1的h.264解决方案以支持4K(Level-5.2)