【发布时间】:2012-11-21 20:12:42
【问题描述】:
在 Android4.1 中,实时编码应用程序中经常需要一个关键帧。但是如何使用 MediaCodec 对象呢?目前的Android4.2 SDK好像不支持。
【问题讨论】:
标签: encode android-4.2-jelly-bean
在 Android4.1 中,实时编码应用程序中经常需要一个关键帧。但是如何使用 MediaCodec 对象呢?目前的Android4.2 SDK好像不支持。
【问题讨论】:
标签: encode android-4.2-jelly-bean
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
}
}
在上面的 sn-p 中,videoEncoder 是配置为进行编码的 MediaCodec 的一个实例。
【讨论】:
您可以在输入缓冲区排队时通过指定 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 不会在视频开始时自动生成关键帧。
【讨论】:
您可以在配置编码器时通过设置 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.
【讨论】: