Android MediaCodec: how to request a key frame when encoding

在Android 4.1及更高版本中,实时编码应用通常需要请求关键帧。本文介绍了如何使用MediaCodec对象在编码过程中请求关键帧,包括通过设置BUFFER_FLAG_SYNC_FRAME标志和使用setParameters方法指定KEY_I_FRAME_INTERVAL参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://stackoverflow.com/questions/13698893/android-mediacodec-how-to-request-a-key-frame-when-encoding

 

Android MediaCodec: how to request a key frame when encoding

Ask Question

up vote 2 down vote favorite

1

In Android4.1, a key frame is often requested in a real-time encoding application. But how to do it using MediaCodec object? The current Android4.2 SDK seems not support it.

encode android-4.2-jelly-bean

shareimprove this question

edited Dec 7 '12 at 1:48

asked Dec 4 '12 at 8:38

user1874818

1114

add a comment

3 Answers

active oldest votes

up vote 3 down vote

You can produce random keyframe by specifying MediaCodec.BUFFER_FLAG_SYNC_FRAME when queuing input buffers:

MediaCodec codec = MediaCodec.createDecoderByType(type);
codec.configure(format, ...);
codec.start();
ByteBuffer[] inputBuffers = codec.getInputBuffers();
for (;;) {
  int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs);
  if (inputBufferIndex >= 0) {
    // fill inputBuffers[inputBufferIndex] with valid data
    ...
    codec.queueInputBuffer(inputBufferIndex, 0, inputBuffers[inputBufferIndex].limit(), presentationTime,
        isKeyFrame ? MediaCodec.BUFFER_FLAG_SYNC_FRAME : 0);
  }

}

Stumbled upon the need to insert random keyframe when encoding video on Galaxy Nexus. On it, MediaCodec didn't automatically produce keyframe at the start of the video.

shareimprove this answer

answered Sep 17 '13 at 12:12

user2394982

313

add a comment

 

up vote 1 down vote

You can request a periodic key frame by setting the KEY_I_FRAME_INTERVAL key when configuring the encoder. In the example below I am requesting one every two seconds. I've omitted the other keys like frame rate or color format for the sake of clarity, but you will still want to include them.

    encoder = MediaCodec.createByCodecName(codecInfo.getName());
    MediaFormat inputFormat = MediaFormat.createVideoFormat(mimeType, width, height);

    /* ..... set various format options here ..... */
    inputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 2);

    encoder.configure(inputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    encoder.start();

I suspect, however, that what you are really asking is how to request a random key frame while encoding, like at the start of a cut scene. Unfortunately I haven't seen an interface for that. It is possible that stopping and restarting the encoder would have the effect of creating a new key frame at the restart. When I have the opportunity to try that, I'll post the result here.

I hope this was helpful.

Thad Phetteplace - GLACI, Inc.

shareimprove this answer

edited Apr 25 '13 at 17:55

answered Apr 25 '13 at 17:48

user2320957

112

add a comment

up vote 0 down vote

MediaCodec has a method called setParameters which comes to the rescue. In Kotlin you can do it like:

fun yieldKeyFrame(): Boolean {
    val param = Bundle()
    param.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 0)
    try {
        videoEncoder.setParameters(param)
        return true
    } catch (e: IllegalStateException) {
        return false
    }
}

in above snippet, the videoEncoder is an instance of MediaCodec configured to encode.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值