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

FFMPEG(libx264)";高度不能被2整除;,ffmpeg,h.264,libx264,Ffmpeg,H.264,Libx264,我正在尝试使用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参数来解决 然而,在我的例

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

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

-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需要均匀的尺寸,因此此过滤器将:

  • 将原始高度和宽度除以2
  • 将其四舍五入到最近的像素
  • 再把它乘以2,使之成为偶数
  • 将黑色填充像素添加到此数字

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

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

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


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

    如果要设置一些输出宽度,并以与原始图像相同的比率进行输出

    scale=720:-1 
    
    为了避免这个问题,你可以使用

    scale="720:trunc(ow/a/2)*2"
    
    (仅适用于搜索如何缩放的用户)

    用于宽度和高度 使用过滤器使宽度和高度可被2整除:

    如果您想代替裁剪,请将
    裁剪
    改为
    缩放

    宽度或高度 使用过滤器。这将使宽度为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

    比特和(x,65534) 将执行与trunc(x/2)*2相同的操作,并且在我看来更透明。
    (这里65534是一个神奇的数字;)


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

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

    原因:

    • 输入视频的显示纵横比(DAR)已设置
    • 缩放
      缩放实际帧尺寸
    • 在预览过程中,必须使用DAR校正新视频的大小,如果视频资源非常低(360x288,DAR 16:9),可能会导致模糊

    解决方案:

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

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

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

    这里的
    缩放解决方案的问题是,它们会扭曲源图像/视频,而这几乎从来都不是您想要的

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

    其他
    pad
    解决方案的问题在于,它们不能在任意维上推广,因为它们总是pad

    此解决方案仅在高度和/或宽度为奇数时添加1像素焊盘:

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

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

    这不是一个bug。不执行缩放并不重要,因为输出将继承输入的帧大小;它不在乎视频大小。然后我需要将其转换为yuv420p,然后它关心视频大小。我在维基百科上查到yuv420p,我认为它是一种多像素的颜色格式,需要图像具有特定的大小。不过,我不知道这有什么关系。最好使用pad而不是scale来添加一个黑色的行/列。将图像放大一个像素将使其模糊。@NickeManarin,此过滤器应能将1个像素的白色填充添加到垂直维度,视频位于左上角:
    -vf pad=“width=iw:height=ih+1:x=0:y=0:color=white”
    。ffmpeg pad文档在这里:。这里有一个解决方案,只在奇数尺寸上添加一个填充像素:
    -vf pad=“width=ceil(iw/2)*2:height=ceil(ih/2)*2”
    。另一个有趣的事实。。。当你用微软媒体基金会的东西解码时,你需要为H264使用16倍的倍数。所以1080P视频实际上解码到一个1088高的缓冲区(尽管你忽略了最后8行)。对于一个固定的高度,它是
    scale=“trunc(oh*a/2)*2:720”
    我认为这应该被标记为正确答案,因为不涉及“技巧”。为什么
    -vf scale=-2:-2
    不起作用?就我而言,我
    -vf pad="width=ceil(iw/2)*2:height=ceil(ih/2)*2"