使用ffmpeg
分割文件时,如果我不想重新编码,我目前只能在关键帧边界上拼接。如果我想将时间控制到特定帧,则会出现问题。据我所知,如果您正在执行流副本,则只能从关键帧开始。如果你想从任意帧开始,你必须重新编码。
但是,对于ffmpeg
理解的编解码器(如H.264),似乎在技术上可以用新创建的关键帧替换所需的第一帧,而无需重新编码视频的其余部分。这将代表一种“智能复制”的行为。例如,假设我的视频包含以下帧和类型:
Frame number: 0 1 2 3
0123456789012345678901234567890123
Frame type: IppbppbppbppbIppbppbppbppbIppbppbp
Keyframes: ^ ^ ^
(I
帧是关键帧,p
和b
帧不是)
目前,如果我想删除前几帧并从正好在第20帧开始,我必须重新编码从该输入帧开始的整个流。这将导致不希望的质量下降。相反,如果我执行副本,ffmpeg
将从最近的关键帧开始:
Frame number: 0 1 2 3
0123456789012345678901234567890123
Frame type: IppbppbppbppbIppbppbppbppbIppbppbp
Desired start: ^
Actual start: ^
为什么ffmpeg
不能寻找第13帧(切割点之前的最后一个完整关键帧),完全计算第20帧,并将第20帧重新创建为I帧?然后它将像以前一样复制剩余的帧。像这样:
Frame number: 0 1 2 3
0123456789012345678901234567890123
Input type: IppbppbppbppbIppbppbppbppbIppbppbp
Output type: IpbppbIppbppbp
对于拼接视频而言,这似乎是一个非常有用的功能,而不会降低质量。是否有任何技术障碍(例如H.264规范或任何其他常见的编解码器)阻止这种方法?
答案 0 :(得分:3)
它不仅必须以关键帧(IDR)开头,还必须关闭GOP。在h.264中,P / B帧最多可以引用16个其他帧。因此,如果替换第一帧,则还必须替换在新帧之前引用帧的所有后续帧。在实践中,这几乎是所有帧。此外,这个过程实际上会与去块滤波器混在一起,因为它会尝试修复可能已被修改的伪像。