Android 本机 Window 时间戳

Android Native Window timestamp

我有一个简单的 NDK Android 代码来解码和播放简单的视频文件。我注意到 Android 有 native_window_set_buffers_timestamp(ANativeWindow, int64_t); 方法。

我读到它为添加到队列中的帧提供了时间戳。是否有可能使用这些标记在我计划的时间段内导致出列和渲染帧? 我有类似于描述的代码:in this example 我在示例中设置演示时间戳(我确信我有正确的值,我以纳秒为单位设置它们),但视频呈现的速度与解码的速度一样快(太快了)。设置时间戳没有任何效果。有人解决这个问题吗?

该字段作为一种通过系统传递时间戳的方式而存在。它可能会也可能不会影响框架的处理方式。

IIRC,该字段最初用于相机捕获的视频帧。通过包含捕获帧时的时间戳,生成编码视频的应用程序可以输出准确的时间戳。如果应用程序使用应用程序接收帧的时间,则时间值会发生显着变化。

旧版本的 Android 在显示帧时忽略时间戳。在 Android 4.4 ("KitKat") 中,SurfaceFlinger 合成器添加了一项功能,允许它根据时间戳保持或丢弃帧。这样做的目的是使 A/V 同步更容易。 Grafika's "scheduled swap" activity, notably those above the doFrame() 方法中的评论对此进行了详细讨论。

简而言之,该功能的目标是让视频播放器稍微提早提交每一帧,以便在音频播放到达适当时间时准备好并在合成队列中等待。当系统繁忙时,尝试在应用程序本身中进行细粒度同步是有问题的。 (SurfaceFlinger 以更高的优先级运行。)

当应用程序向整个视频文件发送垃圾邮件时提供适当节奏的播放不是我们的目标。为了与向嵌入式 PTS 提供框架的应用程序向后兼容,并且如果应用程序提交的时间戳是未来几年的时间,为了避免长时间停顿,SurfaceFlinger 会忽略不在当前时间一秒左右的时间戳。所以你仍然需要用勺子喂帧,但时间戳可以帮助避免停顿和掉落。

所以...如果您想管理自己的视频播放,则必须自己调整输出速度。您可以在 Grafika 的 SpeedControlCallback class.

中查看示例