가끔 인코딩을 하다보면 정전 등 여러가지 이유로 인코딩 중간에 종료되는 경우가 있습니다.

인코딩이 거의 다 완료된 시점에서 이런 일이 발생하면 난감하죠..

아무튼 이런 경우에 오류가 발생한 지점부터 다시 이어서 인코딩하는 간단한 팁입니다.


먼저 x264의 출력(--output)을 .mp4나 .mkv 같은 컨테이너가 아니라 .264 즉, Elementary Stream(ES)으로 지정해야 합니다.

ES는 Raw Stream이라고도 하는데 컨테이너에 담기지 않은 순수한 x264 압축 스트림을 말합니다.

이렇게 ES로 출력물을 설정하면 중간에 인코딩이 종료되어도 그때까지 인코딩된 스트림은 살릴 수가 있습니다.

예를 들어 아래와 같이 인코딩 중간에 불완전 종료된 경우 마지막 GOP만 버리면 나머지 앞부분의 스트림은 아무런 문제가 없습니다.

(컨테이너에 담아서 출력하는 경우에는 스트림 전체를 못 쓰게 됩니다. 따라서 VFR 같은 특별한 경우가 아니라면 .264로 출력하는 것이 좋겠죠.)

I    B    B    P    B    P    B    B    P    I    B    P    B    P    I    B    B    P    B    P    I    B    B    P    불완전 종료


즉 다음과 같이 파란색의 앞부분은 살리고, 빨간색의 마지막 GOP만 버리는 것입니다.

I    B    B    P    B    P    B    B    P    I    B    P    B    P    I    B    B    P    B    P    I    B    B    P    불완전 종료


방법은 간단합니다. MKVmergeGUI로 해당 .264 파일을 열어서 Split 메뉴를 사용해 파란색 부분만 잘라냅니다.

예를 들어 불완전 종료된 .264 파일의 용량이 700 MB 였다면 여유있게 695 MB 정도에서 나눠주면 됩니다.

(불완전한 마지막 GOP의 크기는 아주 작기 때문에 마지막 GOP만 정확히 잘라내기는 힘듭니다.)


다음으로 인코딩이 진행되지 않은 나머지 뒷부분을 인코딩 해야겠죠.

만약 앞서 잘라놓은 695 MB 의 .mkv 파일이 원본 소스의 50000 프레임 지점까지라면 50001 프레임부터 인코딩을 시작하면 됩니다.

x264의 --seek 옵션을 사용하면 소스의 중간부터 인코딩이 가능한데 이 경우에는 --seek 50001 을 사용하면 되겠죠.

(CRF인 경우에는 --seek 옵션을 사용하지 않고 avs 스크립트에서 직접 앞부분을 잘라내도 상관없습니다.)

하지만 이렇게 칼같이 50001 프레임부터 시작하는 것보다는 여유있게 49500 프레임 정도에서 시작하는 것이 비트 배분에 약간 유리합니다.

처음 500 프레임은 다시 MKVmergeGUI로 잘라내면 되니까 여유있게 하시는 편이 좋습니다. (--keyint 의 두 배 정도 여유를 두는 것입니다.)

똑같은 x264 옵션을 사용하기 때문에 695 MB 의 .mkv 파일이 50000 프레임에서 잘렸다면

나머지 뒷부분의 인코딩 결과물도 정확히 500 프레임에서 잘리게 됩니다. (원본 소스로 치면 50000 프레임에서 잘리는 것이죠.)


이런식으로 앞부분에서 잘라낸 .mkv 파일과 뒷부분에서 잘라낸 .mkv 파일을 다시 하나로 합쳐주면

처음부터 인코딩을 다시 하지 않아도 동일한 결과물을 얻을 수 있습니다.

다만 한 가지 조건이 더 있는데 인코딩 모드가 CRF인 경우에만 가능합니다.

저는 주로 CRF를 사용하기 때문에 2패스 인코딩에서는 이 방법을 사용해 본 적이 없었는데..짧은 영상으로 테스트해 본 결과,

2패스 인코딩의 경우 --seek 옵션을 사용해도 .stats 파일까지 함께 이동되는 것은 아닌 것 같습니다.

인코딩이 불가능한 것은 아니지만 결국 그렇게 인코딩을 한다고 해도 악영향만 끼치는 결과가 되겠죠. (엉뚱한 .stats 파일을 사용하게 되니까요.)

그나마 --zones 옵션으로 앞부분의 인코딩 옵션을 낮추는 것은 가능하기 때문에 

빠르게 전체 프레임을 다시 인코딩한 다음 뒷부분만 잘라서 불완전하게 종료된 앞부분과 합치면 될 것 같습니다.

하지만 이런식으로 2패스 인코딩을 두 개로 나눠서 하는 경우 입력 비트레이트를 정확하게 맞추지 못 할 수도 있습니다.

(두 번째 인코딩은 입력 비트레이트를 정확히 맞추겠지만 그 뒷부분만 잘라서 따로 합치는 것이기 때문입니다.)

사소한 거지만 이것도 CRF의 장점이라고 할 수 있겠네요.




Posted by 김코덱