FFMPEG (libx264)“高度不能被2整除”;

我试图从一组帧使用FFMPEG使用libx264编解码器编码。mp4视频。

这是我正在运行的命令:

/usr/local/bin/ffmpeg -r 24 -i frame_%05d.jpg -vcodec libx264 -y -an video.mp4

我有时会得到以下错误:

[libx264 @ 0xa3b85a0] height not divisible by 2 (520x369)

在搜索了一下之后,似乎这个问题与缩放算法有关,可以通过添加-vf参数来修复。

然而,在我的例子中,我不想做任何缩放。理想情况下,我希望保持尺寸与框架完全相同。任何建议吗?是否存在h264强制的某种纵横比?

138042 次浏览

最初的问题的答案应该缩放视频,而不是修复height not divisible by 2错误。这可以通过使用这个过滤器来实现:

-vf "pad=ceil(iw/2)*2:ceil(ih/2)*2"

完整的命令:

ffmpeg -i frame_%05d.jpg -vcodec libx264 \
-vf "pad=ceil(iw/2)*2:ceil(ih/2)*2" -r 24 \
-y -an video.mp4

基本上,.h264需要偶数尺寸,所以这个过滤器将:

  1. 将原来的高度和宽度除以2
  2. 四舍五入到最近的像素
  3. 再乘以2,使它成为偶数
  4. 添加黑色填充像素到这个数字

你可以通过添加过滤器参数:color=white来改变填充的颜色。看到pad文档

这可能是因为H264视频在应用压缩之前通常以4:2:0的格式从RGB空间转换到YUV空间(尽管格式转换本身是一种有损压缩算法,可节省50%的空间)。

YUV-420从RGB(红绿蓝)图片开始,并将其转换为YUV(基本上是一个强度通道和两个“色调”通道)。然后,通过为该色调的每个2X2平方创建一个色调样本,对色调通道进行下采样。

如果水平或垂直的RGB像素数为奇数,则YUV帧的下采样色相空间中的最后一个像素列或行将获得不完整的数据。

如果你想设置一些输出宽度,并使输出与原始的比例相同

scale=720:-1

为了避免这个问题,你可以用

scale="720:trunc(ow/a/2)*2"

(仅供搜索如何缩放的人使用)

对于width 而且 height

使用作物过滤器使width 而且 height能被2整除:

ffmpeg -i input.mp4 -vf "crop=trunc(iw/2)*2:trunc(ih/2)*2" output.mp4

如果你想要规模而不是裁剪,将crop改为scale

对于width height

使用规模过滤器。这将使宽度为1280。高度将自动计算以保留纵横比,而且宽度将被2整除:

ffmpeg -i input.mp4 -vf scale=1280:-2 output.mp4

类似于上面,但使高度720和自动计算宽度:

ffmpeg -i input.mp4 -vf scale=-2:720 output.mp4

你不能同时对宽度而且高度使用-2,但如果你已经指定了一个维度,那么使用-2是一个简单的解决方案。

颈须大人有正确答案,非常快

-vf scale=1280:-2

对于android,不要忘记添加

"-preset ultrafast" and|or "-threads n"

你也可以使用bitand函数来代替trunc:

bitand (x, 65534)

将做与trunc(x/2)*2相同的事情,在我看来它更透明 (考虑65534在这里是一个神奇的数字;))


我的任务是将自动大量的视频文件缩放到一半的分辨率

scale=-2,ih/2导致轻微的模糊的图像

原因:

  • 输入视频的显示长宽比(DAR)设置
  • scale缩放真实的帧尺寸
  • 在预览期间,新视频的大小必须使用DAR进行校正,在相当低分辨率视频的情况下,(360x288, DAR 16:9)可能会导致模糊

解决方案:

-vf "scale='bitand(oh*dar, 65534)':'bitand(ih/2, 65534)', setsar=1"

解释:

  • Output_height = input_height / 2
  • Output_width = output_height * original_display_aspect_ratio
  • output_widthoutput_height现在都四舍五入到最接近的能被2整除的小数字
  • setsar=1意味着output_dimensions现在是最终的,不应该应用宽高比校正

有人可能会觉得这很有用。

这里scale解决方案的问题是,他们扭曲源图像/视频,这几乎从来都不是你想要的。

相反,我发现最好的解决方案是在奇数维度上添加一个1像素的pad。(默认情况下,填充是黑色的,很难被注意到。)

其他pad解决方案的问题是,它们不能泛化任意维度,因为它们总是填充。

这个解决方案只在高度和/或宽度奇数的情况下添加一个1像素的pad:

-vf pad="width=ceil(iw/2)*2:height=ceil(ih/2)*2"

这是理想的,因为它总是做正确的事情,即使没有填充是必要的。