【问题标题】:mediacodec decode h264 stream limitationmediacodec 解码 h264 流限制
【发布时间】:2016-06-15 06:05:37
【问题描述】:

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

我也尝试使用 mediaextractor 播放 mp4 文件,它工作正常,但媒体编解码器的缓冲区不是以“0001”开头。

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

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

【问题讨论】:

标签: android samsung-mobile android-mediacodec mediaextractor


【解决方案1】:

某些特定的解码器也可能能够以“mp4”格式(使用不同类型的起始码)解码 H264 NAL 单元,但这并不保证适用于所有设备。

如果三星的 MediaExtractor 版本知道他们自己的解码器可以处理它,可能会以这种格式返回它。至少有更早的先例,三星使用他们的 MediaExtractor 版本对时间戳做了同样的、非标准的事情,参见例如https://code.google.com/p/android/issues/detail?id=74356.

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

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

【讨论】:

    【解决方案2】:

    一般来说,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 进行视频解码,请记住这一点。它适用于一切,但任何稍微更自定义或低级的东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-17
      • 2015-12-26
      • 1970-01-01
      • 1970-01-01
      • 2014-02-06
      • 2013-04-25
      • 1970-01-01
      • 2021-08-30
      相关资源
      最近更新 更多