258

我正在尝试使用 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 强制执行的纵横比?

4

7 回答 7

350

不想缩放视频的原始问题答案是:

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

命令:

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

基本上, .h264 需要均匀的尺寸,因此此过滤器将:

  1. 将原始高度和宽度除以 2
  2. 四舍五入到最近的像素
  3. 再次将其乘以 2,从而使其成为偶数
  4. 将黑色填充像素添加到此数字

您可以通过添加过滤器参数来更改填充的颜色:color=white。请参阅pad 的文档

于 2013-12-30T21:56:05.763 回答
333

对于宽度高度

使用裁剪过滤器使宽度高度可被 2 整除:

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

如果要缩放而不是裁剪更改cropscale.

对于宽度高度

使用比例过滤器。这将使宽度为 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是一个简单的解决方案。

于 2015-04-11T19:48:21.207 回答
74

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

scale=720:-1 

而不是遇到这个问题,那么你可以使用

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

(仅适用于搜索如何通过缩放来做到这一点的人)

于 2014-06-17T09:49:49.650 回答
30

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

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

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

如果它们是奇数,则此解决方案仅在高度和/或宽度上添加 1 像素填充:

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

这是理想的,因为即使不需要填充,它也总是做正确的事情。

于 2018-10-27T18:19:47.177 回答
20

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

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

如果水平或垂直有奇数个 RGB 像素,则 YUV 帧的子采样色调空间中的最后一个像素列或行的数据不完整。

于 2014-05-12T16:51:34.567 回答
3

您也可以使用bitand函数代替trunc

比特和(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"

解释:

  • 输出高度 = 输入高度 / 2
  • output_width = output_height * original_display_aspect_ratio
  • output_width和output_height现在都四舍五入到可被 2 整除的最接近的较小数字
  • setsar=1表示output_dimensions现在是最终的,不应应用纵横比校正

有人可能会觉得这很有帮助。

于 2018-04-20T18:51:57.367 回答
2

LordNeckbeard 有正确的答案,非常快

-vf scale=1280:-2

对于android,不要忘记添加

"-preset ultrafast" and|or "-threads n"
于 2017-11-30T19:19:39.117 回答