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