是否可以合并使用不同参数编码的 H.264 流?

是否可以合并使用不同参数编码的 H.264 流?

以下命令生成两个 H.264 视频剪辑,每个剪辑 10 秒,具有不同的预设参数(veryslowvs veryfast),并将它们合并到一个 MP4 容器中。

$ ffmpeg -loglevel quiet -f rawvideo -pix_fmt rgba -s 1920x1080 -r 30 -i /dev/zero -pix_fmt yuv420p -c:v libx264 -preset:v veryslow -t 10 part1.mp4
$ ffmpeg -loglevel quiet -f rawvideo -pix_fmt rgba -s 1920x1080 -r 30 -i /dev/zero -pix_fmt yuv420p -c:v libx264 -preset:v veryfast -t 10 part2.mp4
$ cat list
file part1.mp4
file part2.mp4
$ ffmpeg -f concat -i list -c copy join.mp4

到目前为止一切顺利。但如果我尝试使用播放该文件ffplay,我会收到很多错误,例如“decode_slice_header 错误”、“illegal reordering_of_pic_nums_idc”。

如果两个剪辑都使用相同的预设进行编码,则没有问题。

这是否意味着如果两个 H.264 流具有不同的编码参数,即使它们的大小、帧速率和像素格式都相同,我也无法合并它们?

答案1

一般来说,你不能。

预设不会导致视频不同,除非您的限制是带宽,否则较慢的预设将为您提供更好的效率。但它会影响解码器需要初始化的一些参数,这就是为什么它可能无法处理混合不同的比特流的原因。

可能仍有可能在解码域中连接文件(例如通过使用 concat 过滤器),但绝对不是在原始比特流级别。这意味着您必须在连接后重新编码。

您可以尝试做的是连接原始字节流:

ffmpeg -i part1.mp4 -c:v copy -an -f h264 part1.264
ffmpeg -i part2.mp4 -c:v copy -an -f h264 part2.264
cat part1.264 part2.s264 concat.264
ffmpeg -i concat.264 -c:v copy output.mp4

但我现在无法尝试,所以你的里程可能会有所不同。

答案2

虽然 H.264 规范和 ISOBMFF 具有允许在流期间更改 VPS/SPS/PPS 的语法,但很可能其中一个或两个

  • ffmpeg 没有预料到这一点,因此无法正确构建 mp4 文件
  • 播放软件无法解码包含多个 SPS/PPS 集的 mp4 文件。

如果您能够使用 MPEG TS 而不是 MP4,那么看看您是否可以将各部分混合到 mpegts,然后连接两个传输流以形成最终的 ( cat part1.ts part2.ts > join.ts)。MPEG TS 解码器更有可能包含解析 SPS/PPS 更改的逻辑。

相关内容