在我的安卓应用程序中,我想录制一个延时的视频。我有一个InputSurface -> MediaCodec (编码器) -> MediaMuxer。
但是如果我想要加速视频(例如: x3),我得到的结果视频的帧率非常高。例如:在正常速度下,我可以获得30fps的视频。如果我加速(x3),我得到的视频是90fps。
由于视频的帧率很高,我手机的视频播放器无法正常播放视频(电脑的视频播放器播放得很好,没有任何问题)。因此,我认为我必须删除一些帧,以保持低于60fps的帧率。
但我不知道怎么丢弃这些框架。因为在AVC流中,我们有I,B,P帧,它们可能依赖于其他帧,所以我们不能随意丢弃它们。有人能帮我吗?
发布于 2015-06-23 00:00:44
您必须对流进行解码和重新编码,并在进行过程中丢弃帧。只需将60fps视频的时间戳减半,就可以得到120fps的视频。
请记住,原始H.264视频流中没有嵌入任何时间戳。由MediaExtractor解析并由MediaMuxer添加的.mp4包装器保存计时信息。MediaCodec接口似乎接受并生成表示时间戳,但它主要只是传递时间戳,以帮助您保留与正确帧相关联的时间戳--编码器可以对帧进行重新排序。(一些编码器确实会查看时间戳以尝试满足比特率目标,因此您不能传递伪值。)
您可以执行类似于DecodeEditEncode example的操作。当解码器调用releaseOutputBuffer()时,您只需在每隔一帧上为渲染参数传递"false“即可。
如果您正在接受来自其他来源的视频帧,例如用于屏幕录制的虚拟显示器,则不能将编码器的Surface直接提供给显示器。您必须创建一个SurfaceTexture、create a Surface,然后在帧到达时对其进行处理。DecodeEditEncode示例正是这样做的,它在执行此操作时使用GLES着色器修改每个帧。
不过,屏幕录制确实带来了额外的困难。来自虚拟显示器的帧在产生时到达,而不是以固定的帧速率到达,从而产生可变帧速率的视频。例如,您可能有如下的帧序列:
[1] [2] <10 seconds pass> [3] [4] [5] ...虽然大多数帧的到达间隔为16.7ms (60fps),但当显示不更新时,会出现间隙。如果你的录音每隔一帧抓取一次,你会得到:
[1] <10+ seconds pass> [3] [5] ...你最终在错误的帧上暂停了10秒,如果1和2之间有大量的移动,这可能会很明显。要正确地工作,需要在丢帧过程中使用一些智能,例如,根据需要重复前一帧,以产生恒定帧率30fps的视频。
https://stackoverflow.com/questions/30972081
复制相似问题