FFMPEG (libx264)“높이를 2로 나눌 수 없음”


188

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가 적용하는 일종의 종횡비가 있습니까?


@AleksandrDubinsky 그러나 LordNeckbeard의 대답은 원래 너비와 높이를 유지하지 않습니다. 여기서 너비 또는 높이를 수동으로 지정해야합니다 .w가 -vf scale = -2 : ih 또는 -vf scale = iw : -2를 사용하는 경우에는 그렇지 않습니다 높이와 너비 모두 uneven..Please 그 대답은 더 최적 인 방법을 설명입니다 일 경우 .. 감사?
varmashrivastava

1
@varmashrivastava 글쎄, SO가 작동하는 방식은 원래 하나의 질문이 있었을 수 있으며 Google은 다른 질문을 가진 사람들을 통해 페이지를 도용합니다. 그것은 그것이 무엇인지, 싸우지 않도록 노력하십시오. 원래 질문 -vf pad="width=ceil(iw/2)*2:height=ceil(ih/2)*2"에 대한 정답은입니다.이 답변 중 하나도 아닙니다. 다른 사람의 질문에 대한 정답은 LordNeckbeard의 것입니다.
Aleksandr Dubinsky

@varmashrivastava 저는 첫 번째 답을 고쳤습니다. 잘만되면 그것은 개조에 의해 파괴되지 않습니다.
알렉산드르 Dubinsky

@AleksandrDubinsky thanks .. 사용자는 컬러 패딩 픽셀을 원하지 않는다면 "scale="대신 사용할 수 "pad="있습니까?
varmashrivastava

답변:


269

받는 사람 대답 원래의 질문에 않습니다 하지 비디오 크기를 조정할이다 :

-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. 이 숫자까지 검은 색 패딩 픽셀 추가

필터 매개 변수를 추가하여 패딩의 색상을 변경할 수 있습니다 :color=white. pad 문서를 참조하십시오 .


3
버그가 아닙니다. 출력이 입력의 프레임 크기를 상속하므로 스케일링을 수행하지 않아도됩니다.
llogan

5
기록을 위해, 나는 이미지에서 비디오를 만든 곳에서 무언가를하고 있었고 yuvj444p를 픽셀 형식으로 사용했습니다. 비디오 크기에는 신경 쓰지 않았습니다. 그런 다음 yuv420p로 변환해야했고 비디오 크기가 중요했습니다. 위키 백과에서 yuv420p를 찾았습니다. 이미지가 특정 크기가되어야하는 다중 픽셀 색상 형식이라고 생각합니다. 압축이 중요한 이유를 모르겠습니다.
lahwran

7
검은 색 행 / 열을 추가하려면 스케일 대신 패드를 사용하는 것이 좋습니다. 이미지를 1 픽셀 씩 확대하면 이미지가 흐려집니다.
Glenn Maynard,

5
@NickeManarin에서이 필터는 비디오가 왼쪽 상단에 위치하도록 세로 크기에 1 픽셀의 흰색 패딩을 추가하는 데 사용됩니다 -vf pad="width=iw:height=ih+1:x=0:y=0:color=white". ffmpeg pad 문서는 다음과 같습니다 . ffmpeg.org/ffmpeg-filters.html#pad-1
Mark Berry

4
다음은 홀수 인 치수에 패딩 픽셀 만 추가하는 솔루션입니다 -vf pad="width=ceil(iw/2)*2:height=ceil(ih/2)*2".
danneu

250

그냥 사용 -2

로부터 스케일 필터 문서 :

값 중 하나가 -nwith n > 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것이 간단한 해결책입니다.


14
티크는 "트릭"이 없기 때문에 정답으로 표시되어야한다고 생각합니다. 한 번 이상 공표 할 것
LucaM

1
왜 작동 -vf scale=-2:-2하지 않습니까? 필자의 경우 가능한 한 원본 파일 크기를 유지하고 싶습니다. 나를 위해 일한 것은 -vf scale=-2:ih. 그러나 두 하드웨어가 모두 고르지 않으면 작동하지 않습니다.
파스칼

2
@tuner 결과 값은 -2다른 차원의 선언 된 값에 따라 다릅니다.
llogan

3
제 경우에는 다음과 같은 오류가 발생했습니다. Size values less than -1 are not acceptable.그러나 @Zbyszek의 답변은 완벽하게 작동했습니다.
Julien

1
@Julien 아닙니다ffmpeg . 정적 빌드를 다운로드 할 수 있습니다 .
llogan 18

64

출력 너비를 설정하고 원본과 동일한 비율로 출력하려는 ​​경우

scale=720:-1 

이 문제에 빠지지 않으면 사용할 수 있습니다.

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

(스케일링으로 방법을 찾는 사람들에게만 해당)


16
고정 높이의 경우scale="trunc(oh*a/2)*2:720"
Tom

20

scale솔루션 의 문제점 은 소스 이미지 / 비디오가 왜곡되어 사용자가 원하는 것이 거의 없다는 것입니다.

대신, 가장 좋은 해결책은 홀수 치수에 1 픽셀 패드를 추가하는 것입니다. 기본적으로 패딩은 검은 색이며 알아 채기가 어렵습니다.

다른 pad솔루션 의 문제점 은 항상 패딩하기 때문에 임의의 크기를 일반화하지 않는다는 것입니다.

이 솔루션은 홀수 인 경우 높이 및 / 또는 너비에 1 픽셀 패드 만 추가합니다.

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

패딩이 필요없는 경우에도 항상 올바른 작업을 수행하기 때문에 이상적입니다.


스케일 솔루션은 픽셀 수를 최대 1만큼 변경합니다. 그것은 그림을 거의 왜곡시키지 않습니다. 필터링 속도가 걱정된다면을 사용하십시오 scale=iw+mod(iw,2):ih+mod(ih,2):flags=neighbor. 필요한 경우 각 차원을 1 씩만 늘릴 수 있으며 마지막 행 / 열이 복제됩니다.
Gyan

@Gyan이 문제가 해결 된 지 너무 오래되었습니다 (오래 전에 작성한 의견에서 내 대답이 추출되었습니다). 단일 픽셀로 스케일링하면 일부 조건에서 눈에 띄는 시각적 인 인공물 도입 되어 귀찮은 이유가 있음을 기억합니다 처음에. 단일 픽셀 변경으로 인해 불균형 양이 흐려지는 것을 정확히 기억하지 못합니까? 일부 vid / image 형식에서만 가능합니까? 내가 말할 수있는 것은이 수정으로 수천 개의 vids를 처리했으며 유리한 변형이었습니다.
danneu

19

압축을 적용하기 전에 H264 비디오가 일반적으로 RGB에서 YUV 공간으로 4 : 2 : 0으로 변환된다는 사실 때문일 수 있습니다 (형식 변환 자체는 손실 압축 알고리즘이지만 공간 절약은 50 %입니다).

YUV-420은 RGB (Red Green Blue) 영상으로 시작하여 YUV (기본적으로 1 개의 강도 채널과 2 개의 "hue"채널)로 변환합니다. 그런 다음 해당 색조의 2X2 사각형마다 하나의 색조 샘플을 생성하여 색조 채널을 서브 샘플링합니다.

가로 또는 세로로 홀수의 RGB 픽셀이있는 경우 YUV 프레임의 서브 샘플링 된 색조 공간에서 마지막 픽셀 열 또는 행에 대한 데이터가 불완전합니다.


2
또 다른 흥미로운 사실은 Microsoft Media Foundation으로 디코딩 할 때 H264에 16의 배수를 사용해야합니다. 따라서 1080P 비디오는 실제로 1088 높은 버퍼로 디코딩합니다 (마지막 8 줄은 무시하더라도).
Adisak

2

LordNeckbeard는 정답이 매우 빠릅니다.

-vf scale=1280:-2

안드로이드의 경우 추가를 잊지 마십시오

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

쓰레드를 선언 할 필요는 없습니다 : 그것은 자동적으로 처리됩니다. H.264로 인코딩 할 때 Andriod 속도 저하 --disable-asmx264 빌드 스크립트 에서 사용되는 "WritingMinds / ffmpeg-android"라는 인기있는 사람들이 사용했기 때문이라고 생각합니다 . 이로 인해 불필요하고 상당한 속도 저하가 발생합니다 (ffmpeg 로그를 확인할 수 있고 표시되는 경우에는 using cpu capabilties: none!좋지 않습니다). 왜 그것들을 추가했는지 모르겠지만 Android 개발자는 아닙니다.
llogan

1

다음 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"

설명:

  • output_height = 입력 _ 높이 / 2
  • output_width = output_height * 원본 _ 디스플레이 _aspect_ratio
  • 모두 output_widthoutput_height는 지금 2 가까운 작은 숫자 나눌로 반올림됩니다
  • setsar=1output_dimensions 가 최종 임을 의미하며 , 가로 세로 비율 수정이 적용되지 않아야 함

누군가 도움이 될 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.