4

在Android4.1中,实时编码应用程序中经常需要一个关键帧。但是如何使用 MediaCodec 对象呢?目前的Android4.2 SDK好像不支持。

4

3 回答 3

6

可以通过在输入缓冲区排队时指定 MediaCodec.BUFFER_FLAG_SYNC_FRAME 来生成随机关键帧:

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);
  }

}

偶然发现在 Galaxy Nexus 上编码视频时需要插入随机关键帧。在它上面,MediaCodec 没有在视频开始时自动生成关键帧。

于 2013-09-17T12:12:40.843 回答
3

MediaCodec 有一个方法调用setParameters它来救援。在 Kotlin 中,您可以这样做:

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
    }
}

在上面的代码片段中,这videoEncoder是一个配置为编码的 MediaCodec 实例。

于 2017-06-24T04:44:50.593 回答
2

您可以在配置编码器时通过设置 KEY_I_FRAME_INTERVAL 键来请求周期性关键帧。在下面的示例中,我每两秒请求一个。为了清楚起见,我省略了帧速率或颜色格式等其他键,但您仍然希望包含它们。

    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();

但是,我怀疑您真正要问的是如何在编码时请求随机关键帧,例如在过场动画开始时。不幸的是,我还没有看到这个界面。停止和重新启动编码器可能会在重新启动时创建一个新的关键帧。当我有机会尝试时,我会在这里发布结果。

我希望这可以帮到你。

Thad Phetteplace - GLACI, Inc.

于 2013-04-25T17:48:58.190 回答