使用MediaCodec,如何生成间隔小于1秒的关键i帧?

时间:2016-08-25 23:27:02

标签: android mediacodec video-encoding keyframe

MediaFormat.KEY_I_FRAME_INTERVAL只取整数值,我认为这是控制编码器生成I帧的频率的原因吗?那么这是否意味着如果我使用MediaCodec,我不可能更频繁地生成I帧?

4 个答案:

答案 0 :(得分:2)

您可以通过缩放时间戳来解决此问题。如果你是将时间戳输入编码器时,将时间戳乘以2,然后在编码器输出缓冲区的时间戳上除以2,您应该能够获得半秒的I帧间隔。然后你还需要将比特率(和帧速率)减半以使其匹配。当然,这不是理想的,但应该让你获得正确的效果。

答案 1 :(得分:0)

我终于找到了解决这个问题的方法!

在需要关键帧之前插入以下代码,然后它将在下一个可用帧上生成关键帧。

stdout

答案 2 :(得分:0)

文档说:

  

A zero value means a stream containing all key frames is requested.

所以你需要的只是:

MediaFormat format = MediaFormat.createVideoFormat(...);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 0);

适用于某些设备,但对于某些设备(例如Nexus 6p),它会产生异常:

E/ACodec: [OMX.qcom.video.encoder.avc] configureCodec returning error -1010
E/ACodec: signalError(omxError 0x80001001, internalError -1010) 
E/MediaCodec: Codec reported err 0xfffffc0e, actionCode 0, while in state 3
E/MediaCodec: configure failed with err 0xfffffc0e, resetting...

答案 3 :(得分:0)

从Android 7.1开始,

KEY_I_FRAME_INTERVAL也可以接收浮动信息。

因此现在可以执行以下操作:

val mediaFormat: MediaFormat = MediaFormat.createVideoFormat(VIDEO_MIME_TYPE, 480, 640)
// 30 Frames per second
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30) 
// 1 second between key frames!
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1) 
// 0.3 seconds between key frame!
mediaFormat.setFloat(MediaFormat.KEY_I_FRAME_INTERVAL, 0.3F)