我在我的项目中使用 MediaCodec 对来自相机的视频进行编码。由于某些原因,我需要将 KEY_I_FRAME_INTERVAL 设置为 0,这意味着录制的 mp4 视频中的每一帧都将是关键帧(关键帧包含整个图像,而不仅仅是与前一帧的增量差异)。
在这里我遇到了问题:在Nexus 10、Nexus 7、小米红米2、华硕Zenphone 5、Galaxy A5上一切正常。但 lenovo vivi s1 仅以关键帧间隔等于 1 秒进行录制。无论在 mediaFormat 中设置什么值,我在 mediaCodec.configure() 中使用什么值。我尝试设置 0, 1, 5, 10,但视频中的关键帧总是每 30 帧。
有什么想法可以解决这个问题吗?
有关更多信息,这是我的 mediaCodec 编码器的设置:
videoCodec = MediaCodec.createEncoderByType(MIME_VIDEO_CODEC_H264);
MediaFormat videoFormat = MediaFormat.createVideoFormat(MIME_VIDEO_CODEC_H264, 1280, 720);
videoFormat.setInteger(MediaFormat.KEY_BIT_RATE, 3800000);
videoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
videoFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
videoFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 0);
videoCodec.configure(videoFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
//using input surface to get input data from camera
inputSurface = new CodecInputSurface(videoCodec.createInputSurface());
videoCodec.start();
这个答案迟到了并且基于意见,但可能会有所帮助。
对于 Android 中的许多其他事情,我认为这
KEY_I_FRAME_INTERVAL
对于编码器来说是一种“善意的推荐”,而不是严格的设置。此 API 背后可能有数百种硬件编码器实现,而一些更“严格”且可能较旧的编码器可能无法使用此设置,这可能是您遇到问题的设备的情况。但这纯粹是猜测。
如果您的问题是增加编码流中的 I 帧频率,您可以考虑定期向 MediaCodec 实例提交
PARAMETER_KEY_REQUEST_SYNC_FRAME
设置。如果编码器能够采用其他中间模式,而不仅仅是 I 帧之间的“零秒”和“一秒”间隔,则这可能是实现更频繁的 I 帧的一种方法(尽管不一定是它们的精确频率)。
还值得注意的是,从 Android 7.1 开始
KEY_I_FRAME_INTERVAL
接受浮点值。
我遇到了同样的问题,看来您还必须为 MediaFormat.KEY_CAPTURE_RATE 设置一个值,然后 MediaFormat.KEY_I_FRAME_INTERVAL 才会受到尊重。
您应该在将每一帧渲染到编解码器之前使用请求同步。