2017-07-18 27 views
0

我需要实现H264编码和配置MediaCodec如下的Android MediaCodec似乎被忽略指定KEY_BIT_RATE值

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

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

回答

0

这种行为的真正原因是在我推送帧时转入编码器的时间戳。在简化的开发阶段,我使用System.nanoTime()值作为时间戳。此时间戳以纳秒为单位表示时间,而编码器需要以微秒作为时间戳。

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

0

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

+0

我想你也给纳秒时间戳的编码器,这是你的问题的真正原因。纳秒时间戳将帧率的度量单位更改为每秒帧数。这意味着您需要将比特率的度量单位更改为每秒千比特以保持测量的正确性和正确的行为。无论如何,谢谢你的回答,让我有正确的想法。 –

+1

我确认我正在交付编解码器微秒,所以我想我们只是看着两个类似症状的不同问题。我不排除我做错了 - 这就是为什么我只是加倍检查我的时间戳 - 但现在我在为我的问题指责OEM。很高兴你的问题更容易理清。 –

+0

我遇到了与moto c plus相同的问题。我相信微秒会进入而不是纳秒。没有面对与我测试过的任何其他设备(15件东西)的这个问题。 –