You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Native C++无法为MediaCodec Image对象设置时间戳

问题原因及解决方案

核心问题:MediaCodec通过getInputImage(index)获取的InputImage,其setTimestamp()方法是无效的。这类Image的时间戳与对应的InputBuffer绑定,由MediaCodec在queueInputBuffer时统一设置,直接调用Image的setTimestamp()不会修改底层缓冲区的时间戳,因此后续调用getTimestamp()会返回初始值0。

为什么代码无报错但不生效?

Android的Image类确实存在setTimestamp(long)方法,但对于MediaCodec提供的InputImage实例来说,该方法属于空实现(仅修改Java层临时变量,未同步到底层Native缓冲区),因此不会抛出异常,但也不会产生实际效果。

正确实现步骤

  1. 移除JNI中调用Image.setTimestamp的代码,这部分操作完全无效。
  2. 在Kotlin/Java层调用MediaCodec.queueInputBuffer时传入时间戳:
    当你从MediaCodec获取InputImage并完成像素复制后,需要在提交缓冲区时,将YUV420对象的timestampUs作为参数传给queueInputBuffer。

示例代码(Kotlin层):

val index = codec.dequeueInputBuffer(timeoutUs)
if (index >= 0) {
    val image = codec.getInputImage(index)
    // 调用JNI方法完成像素复制
    YuvUtils.copyToImage2(image)
    image.close() // 必须关闭Image释放资源
    // 关键:在此传入时间戳(单位为微秒)
    codec.queueInputBuffer(
        index,
        0, // offset,Image模式下填0即可
        0, // size,Image模式下填0即可
        yuvFrame.timestampUs, // 传入你的YUV帧时间戳
        0 // flags
    )
}

额外注意事项

  • 确保YUV420的timestampUs单位为微秒,与MediaCodec的queueInputBuffer要求的时间戳单位一致。
  • 必须在使用完InputImage后调用image.close(),否则会导致MediaCodec的InputBuffer泄漏,后续无法获取新的缓冲区。

内容的提问来源于stack exchange,提问作者Avaneesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 19:06:03