您必须对流进行解码和重新编码,同时丢帧。只需将 60fps 视频中的时间戳减半即可获得 120fps 视频。
请记住,原始 H.264 视频流中没有嵌入任何时间戳。由 MediaExtractor 解析并由 MediaMuxer 添加的 .mp4 包装器保存了计时信息。MediaCodec 接口似乎接受并产生表示时间戳,但它主要只是传递它以帮助您保持与正确帧相关联的时间戳——帧可以由编码器重新排序。(一些编码器确实会查看时间戳以尝试满足比特率目标,因此您不能传递虚假值。)
您可以执行类似DecodeEditEncode 示例的操作。当解码器调用releaseOutputBuffer()
时,您只需为每隔一帧的 render 参数传递“false”。
如果您正在接受来自其他来源的视频帧,例如用于屏幕录制的虚拟显示器,您不能将编码器的 Surface 直接交给显示器。您必须创建一个 SurfaceTexture,从中创建一个 Surface,然后在帧到达时对其进行处理。DecodeEditEncode 示例正是这样做的,它使用 GLES 着色器修改每一帧。
不过,屏幕录制确实存在额外的困难。来自虚拟显示器的帧在生成时到达,而不是以固定的帧速率,产生可变帧速率的视频。例如,您可能有一个这样的帧序列:
[1] [2] <10 seconds pass> [3] [4] [5] ...
虽然大多数帧以 16.7 毫秒 (60fps) 的间隔到达,但在显示未更新时存在间隙。如果您的录制每隔一帧抓取一次,您将获得:
[1] <10+ seconds pass> [3] [5] ...
你最终在错误的帧上暂停了 10 秒,如果1和2之间有很多移动,这可能会很明显。使这项工作正常工作需要一些智能丢帧,例如根据需要重复前一帧以产生恒定帧率 30fps 视频。