4

In my Android application, I am encoding some media in webm (vp8) format using MediaCodec. The encoding is working as expected. However, I need to ensure that I create a sync frame once in a while. Here is what I do:

encoder.queueInputBuffer(..., MediaCodec.BUFFER_FLAG_SYNC_FRAME);

Later in the code, I check for sync frame:

encoder.dequeueOutputBuffer(bufferInfo, 0);
boolean isSyncFrame = (bufferInfo.flags & MediaCodec.BUFFER_FLAG_SYNC_FRAME);

The problem is that isSyncFrame never gets a true value.

I am wondering if I am making a mistake in my encoding configuration. May be there is a better way to tell the encoder to create a sync frame once in a while.

I hope it is not a bug in MediaCodec. Thank you in advance for your help.

Zong
  • 6,160
  • 5
  • 32
  • 46
Peter
  • 11,260
  • 14
  • 78
  • 155

2 Answers2

5

There is no (current as of Android 4.3) way to request an on-demand sync frame using MediaCodec encoders. This is partly due to OMX, the underlying codec implementation in Android, that does not provide a way to specify which input frame should be encoded as a sync frame; although it has a way to trigger a sync frame "in the near future".

feisal's answer is the only currently supported way to control sync frames, but you have to do it at configuration time.

==edit re: jesup

You can trigger a sync frame in the near future using MediaCodec.setParameter:

Bundle params = new Bundle();
params.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 0);

mCodec.setParameters(syncFrame);

Unfortunately, there is no (reliable) way to tell in MediaCodec if an encoded buffer is a sync frame other than doing it on your own by inspecting the byte-codes.

Lajos Molnar
  • 791
  • 6
  • 9
  • 2
    "OMX [] does not provide a way to specify which input frame should be encoded as a sync frame" - this is insane.... And so how to I generate an iframe/keyframe in response to an RTCP PLI (packet loss)? – jesup Apr 16 '14 at 01:21
  • @LajosMolnar Could please help to answer the question ? http://stackoverflow.com/questions/31823231/how-to-update-mediacodec-encoding-bitrate-dynamically-while-streaming-in-android – Jerikc XIONG Aug 07 '15 at 02:02
1

you can set the rate of I-frames in the MediaFormat object of your encoder by setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, int secs_between_iframes );

feisal
  • 585
  • 1
  • 8
  • 20