【问题标题】:Android MediaCodec seems to be ignoring specified KEY_BIT_RATE valueAndroid MediaCodec 似乎忽略了指定的 KEY_BIT_RATE 值
【发布时间】:2017-07-18 13:24:45
【问题描述】:

我需要实现H264编码并配置MediaCodec如下

    MediaCodec codec = MediaCodec.createEncoderByType("video/avc");
    MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", resolution.getWidth(), resolution.getHeight());

    mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
    mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 1000000);
    mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE,30);
    codec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);

比特率设置为 1000000,这是由网络限制定义的要求。当我在三星 Galaxy J7 上进行测试时,我看到 1000 kbps 的输出与预期的一样。但是当我在三星 Galaxy Grand 2 Duos (android 4.4) 或华为 Nexus 6P (android 7.1.2) 等特定设备上测试相同的代码时,我看到编码器每秒产生高达 5 兆字节的输出,这意味着编解码器完全忽略每秒 1000000 位的指定值。它出什么问题了?有没有办法强制编码器使用这个指定的值?

【问题讨论】:

    标签: android video media codec


    【解决方案1】:

    我也遇到过这个问题,它只发生在一个设备上(7 上的 Moto E Plus,虽然 6 上的 Moto E 很好,7 上的其他设备也很好),进一步的测试表明它正在使用分配的比特率作为 Kbps 而不是指定的 bps。
    不幸的是,我发现检测出现此错误的 android 实现的唯一“解决方案”是观察媒体编解码器的输出,如果它看起来输出太多数据,则将其重置为比特率/1000。

    【讨论】:

    • 我认为您还为编码器提供了纳秒时间戳,这是您问题的真正原因。纳秒时间戳将帧速率的测量单位更改为每秒帧数。这意味着您需要将比特率的测量单位更改为每秒千比特,以保持测量的正确性和正确的行为。无论如何,谢谢,你的回答让我有了正确的想法。
    • 我确认我正在处理编解码器微秒,所以我想我们只是在查看两个具有相似症状的不同问题。我不排除我做错了什么——这就是为什么我只是仔细检查了我的时间戳——但现在我将我的问题归咎于 OEM。很高兴您的问题更容易解决。
    • 我遇到了与 moto c plus 相同的问题。我确信 microseconds 而不是 nanoseconds 。我测试过的任何其他设备(大约 15 个)都没有遇到这个问题。
    【解决方案2】:

    这种行为的真正原因在于我在推入帧时传输到编码器的时间戳。在开发阶段,为了简单起见,我使用 System.nanoTime() 值作为时间戳。此时间戳以纳秒表示时间,而编码器需要微秒作为时间戳。

    大多数编解码器实现可能使用自己的计时器来测量实际传入的 fps,因此它们不依赖于实际的时间戳值而只是忽略它们。但是 Nexus 6P 可能有一个聪明的,这个编码器使用时间戳来测量 fps 值。时间戳以纳秒为单位给出,从编解码器的角度来看,时间流慢了 1000 倍,测量的 fps 为每 33 秒 1000/30 ~ 1 帧,因此编解码器试图将所有请求的兆位推送到单个输出帧中。

    【讨论】:

      猜你喜欢
      • 2014-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-28
      • 2016-09-30
      • 2016-03-16
      相关资源
      最近更新 更多