FFmpeg height not divisible by 2 오류 원인과 해결

yuv420p 인코딩에 홀수 높이(또는 너비)가 들어갔다는 오류입니다. -2로 스케일하거나 trunc(ih/2)*2로 내림해 두 변을 짝수로 만드세요. Sume가 크기를 맞추는 방식도 다룹니다.

읽는 시간 5분Sume
전체 글

"Height not divisible by 2"는 yuv420p로 인코딩하는 영상의 높이가 홀수라는 뜻입니다. 너비가 홀수면 같은 내용의 너비 오류가 납니다. yuv420p는 색 정보를 그림 너비의 절반, 높이의 절반 크기로 저장하므로 두 변이 모두 짝수여야 합니다. 크기를 짝수로 만드세요. scale 필터에서 계산되는 변을 -2로 지정하거나(scale=1280:-2), scale=trunc(iw/2)*2:trunc(ih/2)*2로 홀수 프레임을 짝수로 내림하면 됩니다.

FFmpeg 관련 내용은 FFmpeg의 필터, ffmpeg, 유틸리티 문서와 pixfmt.h 레퍼런스에서, Sume 관련 내용은 영상 필터, 영상 트림, Timeline 1.0 문서와 Sume API 레퍼런스에서 가져왔으며, 모두 2026-09-28에 확인했습니다. 현재 동작이라고 설명한 내용은 Sume의 코드에서 확인한 것입니다.

yuv420p는 왜 짝수 크기가 필요한가요?

yuv420p 같은 4:2:0 형식에서는 2×2 픽셀 블록마다 색 샘플 한 세트를 공유하므로, 색 평면의 너비와 높이가 그림의 절반입니다. FFmpeg는 이 배율을 크로마 서브샘플 값인 hsub와 vsub라고 부릅니다. FFmpeg의 scale 예시 중 하나는 크기를 이 값의 배수로 맞추고, 다른 하나는 해상도를 짝수로 만드는데, 문서는 이것이 일부 코덱에 필요하다고 설명합니다. 변이 홀수면 인코더가 받지 않는 반쪽 블록이 남습니다.

홀수는 크기를 정한 무언가에서 생깁니다. 한 변을 계산한 scale, crop, 또는 처음부터 홀수였던 소스입니다. 크기를 정하는 그 단계에서 고치세요.

scale 필터로 어떻게 고치나요?

크기를 정하는 방식에 맞는 형태를 고르세요. 각 형태의 동작은 FFmpeg의 scale 필터 문서를 따릅니다.

FFmpeg 필터 문서의 scale 필터 기준, 2026-09-28 확인.
scale 값동작
scale=1280:-2너비를 정하고 높이를 화면 비율로 계산한 뒤 2로 나누어떨어지게 함. -n은 계산된 변을 n으로 나누어떨어지게 하며, 직접 정한 변은 적은 값 그대로이므로 그 변도 짝수로 지정.
scale=1280:-1화면 비율은 유지하지만 -1은 변을 1로 나누어떨어지게 할 뿐이라 홀수가 나올 수 있음.
scale=trunc(iw/2)*2:trunc(ih/2)*2프레임 크기를 유지하고 홀수 너비나 높이를 짝수로 내림. iw와 ih는 입력 너비와 높이.
scale=400:300:force_original_aspect_ratio=decrease:force_divisible_by=2화면 비율을 유지하며 영상을 짝수 크기로 400×300 안에 맞춤.
# Width 1280, height from the aspect ratio, rounded to even
ffmpeg -i input.mp4 -vf scale=1280:-2 -c:v libx264 -pix_fmt yuv420p -c:a copy output.mp4

# Keep the size, but round an odd width or height down to even
ffmpeg -i input.mp4 -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" -c:v libx264 -pix_fmt yuv420p -c:a copy output.mp4

crop 필터는 어떤가요?

FFmpeg의 crop 필터는 기본적으로 값을 알아서 맞춰 주지만, 서브샘플링된 영상에서만 그렇습니다. exact 옵션의 기본값은 0이며, 이 옵션이 꺼져 있으면 서브샘플링된 영상의 crop 너비, 높이, 위치는 주어진 값 그대로 쓰이지 않고 가장 가까운 더 작은 값으로 내림됩니다. yuv444p처럼 크로마 서브샘플링이 없는 소스에는 이런 내림이 없으므로, 거기서 홀수로 crop하면 홀수인 채로 yuv420p 인코딩에 도달합니다. 이 경우와 exact=1을 지정한 경우에는 언제나, 예를 들어 trunc(iw/2)*2 형태의 식으로 숫자를 직접 짝수로 유지하세요.

Sume는 홀수 크기를 어떻게 처리하나요?

Sume의 트림, 필터, Timeline 도구는 이전 Sume Job의 출력처럼 워크스페이스에 있는 media.sume.com 파일을 읽습니다. 문서에 따르면 exact 트림은 yuv420p의 H.264로 쓰고, 현재 코드에서는 영상 필터와 Timeline도 마찬가지이므로 이 도구들의 출력 크기도 짝수여야 합니다. 도구별 처리 방식은 다음과 같습니다.

  • 영상 필터의 crop op는 사각형을 소스 프레임에 대한 비율로 받으며, 컴파일러가 yuv420p에 맞게 짝수로 반올림합니다. 이 op는 화질 손실 없이 영상을 크롭하는 방법에서 보여 줍니다.
  • 영상 트림의 output은 256에서 2160까지의 너비와 높이를 받습니다. 현재 코드에서는 각 값을 짝수로 내림하며, 한 변만 지정하면 다른 변은 화면 비율을 유지하도록 -2로 계산합니다. output이 없으면 exact 트림은 소스 크기를 그대로 유지하므로, 소스 자체가 홀수라면 output을 보내세요.
  • Timeline 1.0의 output.width와 output.height는 256에서 2160까지의 짝수 정수여야 하며, 현재 코드에서는 타임라인 합성의 출력 크기도 짝수여야 합니다. 둘 다 영상의 프레임 레이트나 해상도 바꾸기에서 다룹니다.
  • 영상 필터에 filtergraph를 그대로 넘길 때는 크기를 직접 짝수로 맞춰야 합니다. scale은 필터 허용 목록에 있고, 무료 POST /v1/video-filter/check는 인코더를 건드리지 않고 스키마와 허용 목록 검사를 실행하므로, 이 검사를 통과한 프로그램도 실제로 실행할 때는 실패할 수 있습니다. 계산하는 크기에는 모두 -2나 trunc(iw/2)*2를 쓰세요.

출처

관련 글

개발자 카테고리의 다른 글

개발자 글 전체 보기

작성자 Sume