Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MediaCodec: MediaFormat setting KEY_I_FRAME_INTERVAL value is ignored

I'm using MediaCodec in my project to encode videos from camera. For some reasons i need to set KEY_I_FRAME_INTERVAL to 0, which means that every frame in recorded mp4 video will be a key frame (key frame contains the whole image, not just the incremental difference with previous frame).

And here i meet the problem: on nexus 10, nexus 7, xiaomi redmi 2, asus zenphone 5, galaxy a5 everything is ok. But lenovo vibe s1 is recording ONLY with key frame interval equal to 1 second. No matter what value is set in mediaFormat what i'm using in mediaCodec.configure(). I tried to set 0, 1, 5, 10, but key frame in video is allways every 30 frame.

Any ideas how to solve this issue?

For more information, here's my mediaCodec encoder's setup:

    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();
like image 560
Niakros Avatar asked Nov 26 '22 14:11

Niakros


1 Answers

This answer is late and opinion-based, but may be helpful.

As for many other things in Android, I consider this KEY_I_FRAME_INTERVAL being rather a sort of a "kind recommendation" to the encoder than a strict setting. There are maybe hundreds of hardware encoder implementations behind this API, and some more "rigid" and likely old ones may not be able to make use of this setting, which is possibly the case for the device you faced the problem on. This is a pure speculation though.

If your problem is to increase the I-frame frequency in the encoded stream, you may consider PARAMETER_KEY_REQUEST_SYNC_FRAME setting being submitted to the MediaCodec instance periodically. If the encoder is capable of other intermediate modes than just "zero second" and "one second" interval between I-frames, this may a way to achieve more frequent I-frames (not necessarily their precise frequency though).

It is also worth noticing that since Android 7.1 KEY_I_FRAME_INTERVAL accepts floating-point values.

like image 131
lnstadrum Avatar answered Jan 13 '23 19:01

lnstadrum