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

时间:2013-12-30 21:13:11

标签: ffmpeg h.264 libx264

我正在尝试使用libx264编解码器使用FFMPEG从一组帧中编码.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强制执行的宽高比?

7 个答案:

答案 0 :(得分:220)

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

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

命令:

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

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

  1. 将原始高度和宽度除以2
  2. 将其四舍五入到最近的像素
  3. 再次将它乘以2,从而使其成为偶数
  4. 将黑色填充像素添加到此数字
  5. 您可以通过添加过滤器参数:color=white来更改填充的颜色。请参阅the documentation of pad

答案 1 :(得分:191)

只需使用-2

即可

来自scale filter documentation

  

如果其中一个值为-nn > 1,则缩放过滤器也将使用   计算的维持输入图像宽高比的值   来自其他指定的维度。然而,在那之后它将会成功   确保计算出的维度可以被n整除并调整   必要时的价值。

实施例

将宽度设置为1280,将自动计算高度以保持纵横比,高度可以被2整除:

-vf scale=1280:-2

与上述相同,但具有声明的高度;留下宽度由过滤器处理:

-vf scale=-2:720

“可被2整除”

根据x264的要求,YUV 4:2:0色度二次采样输出需要“宽度和高度可被2整除”。 4:2:2需要“宽2整除”,4:4:4没有这些限制。但是,大多数基于非FFmpeg的播放器只能正确解码4:2:0,这就是为什么在输出H.264视频时经常会看到带有ffmpeg选项的-pix_fmt yuv420p命令。

买者

很遗憾,您无法将-2用于宽度高度,但如果您已经指定了一个维度,那么使用-2是一个简单的解决方案。

答案 2 :(得分:62)

如果要设置一些输出宽度并使输出具有与原始

相同的比率
scale=720:-1 

并且不会遇到这个问题,那么你可以使用

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

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

答案 3 :(得分:18)

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

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

如果您在水平或垂直方向上有奇数个RGB像素,则YUV帧的二次采样色调空间中的最后一个像素列或行将包含不完整的数据。

答案 4 :(得分:11)

这里的protected override void OnPaint(PaintEventArgs e) { if(myGenericStream != null) { using(MemoryStream ms = new MemoryStream()) { int pos = myGenericStream.Position; myGenericStream.CopyTo(ms); myGenericStream.Seek(pos, SeekOrigin.Begin); //I have also tried myGenericStream.Position = pos ms.Seek(0, SeekOrigin.Begin); // Paint work using the new MemoryStream... } } } 解决方案存在的问题是,它们扭曲了源图像/视频,而这几乎永远都不是您想要的。

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

其他scale解决方案的问题在于,它们不能始终覆盖任意尺寸,因为它们总是填充。

此解决方案仅在高度和/或宽度为奇数时添加一个1像素的填充块:

pad

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

答案 5 :(得分:2)

LordNeckbeard有正确答案,非常快

-vf scale=1280:-2

对于android,不要忘记添加

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

答案 6 :(得分:1)

您也可以使用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_width output_height 现在四舍五入到可被2整除的最接近的较小数字
  • setsar=1表示 output_dimensions 现在是最终版,不应应用宽高比修正

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