MediaCodec: MediaFormat setting KEY_I_FRAME_INTERVAL value is ignored
Asked Answered
R

3

6

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();
Reamy answered 1/2, 2016 at 15:29 Comment(5)
According to the web, that device uses a Mediatek MT6752 chipset. I've seen some complaints recently about MediaTek video encoding issues (stackoverflow.com/questions/34891420, stackoverflow.com/questions/35030050).Broeder
@Broeder This all looks like it's easier to avoid MT chipsets. I tried lenovo a536, it's althougth runed on MT chipset, and it have the same issue plus i'm not able to convert 720p to 720*480. Don't know why yet.Reamy
I'm not sure about MediaCodec, but usually 0 is auto and 1 is every frame an I frame. Ignore this comment if I'm wrong.Raceme
@Raceme in world of android's mediacodec 0 means that every frame will be a key frame. It works with Qualcom, Intel, Exynos chipsets. 1 means that key frame will appear every second (every 30 frame if 30 fps is set)Reamy
Also on motog6 the value is ignored and no key frames are written unless force. Tested using WEBM output format only.Welldressed
F
1

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.

Feverfew answered 15/5, 2021 at 10:2 Comment(0)
C
0

I encountered the same problem, it seems that you must also set a value for MediaFormat.KEY_CAPTURE_RATE and then MediaFormat.KEY_I_FRAME_INTERVAL will be respected.

Convergence answered 20/9, 2023 at 6:58 Comment(0)
G
-2

You should use request sync for every frame before rendering it to the codec.

Gereron answered 10/5, 2017 at 11:5 Comment(1)
KEY_I_FRAME_INTERVAL is the number of seconds. It is not related to KEY_FRAME_RATE.Scenario

© 2022 - 2025 — McMap. All rights reserved.