※ 이 글의 이해를 위해서는 다음 게시글을 반드시 먼저 읽어야 합니다.
샤나인코더는 FFmpeg를 기반으로 하기 때문에 FFmpeg의 명령어 구성과 거의 대부분 호환이 됩니다. 따라서 FFmpeg에 대한 이해도가 높을수록 샤나인코더를 보다 더 잘 활용할 수 있다는 장점이 있습니다.
이 글에서는 샤나인코더에서 'H264'라고 명명돼 있는 x264 인코딩 설정을 살펴보고, 그것이 FFmpeg에서의 x264 인코딩 설정을 어떻게 사용자가 쉽게 구성할 수 있도록 GUI 환경으로 구성한 것인지 알아봅니다. 그리고 더 나아가 샤나인코더에서의 인코딩 설정이 FFmpeg 명령어로는 어떻게 구성될 수 있는지도 살펴보도록 하겠습니다.
본문에서 구성한 H264 명령어는 하드웨어 제약이 없는 재생 환경에서 어느 정도 화질을 우선 순위에 둔 옵션 설정법을 적용하였는데, 옵션 중 기본값(FFmpeg에서 x264는 medium 프리셋이 기본값)과는 다른 설정 부분은 붉은색으로, 나름 빈번히 다뤄지는 다른 옵션들은 녹색으로 표시하였습니다. 일종의 가이드라인일 뿐 절대적인 원칙은 아니며, 원본에 대한 부분은 고려하지 않았으므로 실제 인코딩에 적용할 때는 반드시 원본 특성(인터레이스 여부, 프레임 레이트 변경이 필요한지 여부, 필터를 이용한 보정이 필요한지 여부 등)을 반영해야 한다는 점을 꼭 유념하시기 바랍니다.
1. 빠른 설정(F6)
좋은 화질의 결과물을 얻고 싶다면 '퀄리티' 모드를 선택합니다. 퀀타이저 모드는 비트레이트 변동이 심하므로 특별한 경우 말고는 선택하지 마십시오. 퀄리티 모드 자체가 퀀타이저 모드를 화질을 위한 최적화 알고리듬으로 보정한 것입니다.
화질은 일반적으로 (동일 비트레이트일 경우) 퀄리티 모드(crf) = 비트레이트 모드 2패스(2pass) > 비트레이트 모드 1패스(abr)입니다. 비트레이트 컨트롤과 관련된 부분은 좀더 자세하게 설명돼 있는 이 게시글을 참조하시기 바랍니다.
x264의 crf(constant rate factor, 일종의 비디오 퀄리티 결정 지수) 기본값은 23입니다. 값이 낮을수록 고화질입니다.
원본의 일부분을 잘라(오른쪽 클릭 ⇒ 구간 설정) 인코딩하면서 화질 대비 최대 효율을 얻을 수 있는 crf 값을 찾는 방법이 가장 압축률이 높은 방법이지만, 최적의 crf를 찾는 시간이 많이 소요되는 방식이므로 대개 18~22 정도의 crf 값으로 인코딩을 많이 합니다. 16 이하의 crf 값은 화질 대비 소요시간이 너무 크므로 비추입니다.
프레임 레이트 변경은 기존 프레임을 복사(duplicate)하거나 생략(drop)하는 방식으로 프레임 레이트를 조정하므로, 이 옵션으로 프레임을 늘려주는 프레임 더블링 방식은 움직임을 부드럽게 하는 플루이드 모션(AMD)이나 필터 처리로 움직임을 부드럽게 하는 프레임 더블링 방식과는 다릅니다. 진정한 프레임 더블링 방식이 아니므로 이 방법으로 프레임 레이트를 늘리는 것은 별로 추천하지 않습니다.
하지만 의미없는 60 프레임 영상(부드러운 움직임도 없는데 쓸데없이 프레임을 반복해 프레임 레이트만 늘려놓은 영상. 일부 릴들이 이에 해당)을 30 프레임으로 프레임 다운하는 것은 권장합니다.
CFR(constant frame rate, 고정 프레임 레이트)은 원본과 상관없이 고정 프레임 레이트 영상으로 만들기 위한 옵션으로, 가변 프레임 레이트를 인식하지 못하는 대부분의 영상 편집 프로그램에서 편집하기 위한 영상을 인코딩하는 경우에 이용할 것을 권장합니다. 이 옵션을 선택하지 않으면 비디오 코덱과 파일 형식에 따라 고정, 가변 여부를 인코더가 알아서 결정합니다.
샤나인코더에서 원본이 가변 프레임 레이트인 경우 프레임 레이트 변경을 선택하고 파일 형식을 mp4로 인코딩하면 (코덱에 따라 다르지만, 많은 경우에) 가변 프레임 레이트로 인코딩됩니다. (FFmpeg에서는 이 경우 고정 프레임 레이트로 인코딩됨.)
프레임 레이트 변동으로 인해 오디오 싱크가 틀어지는 일은 실질적으로 발생하지 않습니다.
키 프레임 변경은 키 프레임 간격을 초 단위로 설정합니다. (매개변수 옵션 -shanakeyframe 이 적용됩니다.) 다만, 코덱과 설정에 따라 오차가 발생할 수 있습니다. 설정을 하지 않아도 상관없습니다. 하지만 GOP 크기를 줄이고 싶다면 낮은 값으로 설정하시기 바랍니다. 효율(압축률)은 떨어지는 대신 재생시 탐색(seeking, 건너뛰기)에서 좀 더 유리한 영상을 얻을 수 있습니다.
OpenCL 가속은 소프트웨어 코덱인 x264가 OpenCL 방식으로 그래픽 카드를 이용한 하드웨어 가속 기능을 일부 이용하도록 한 옵션이지만 실용성이 거의 없으므로 선택하지 마십시오. (경우에 따라 인코딩 오류의 원인 중 하나)
HD 이상의 해상도를 가진 영상은 재생기기에서 프로파일 제한이 있지 않은 한 High 프로파일을 선택하시기 바랍니다. High는 고해상도 영상을 위해 Main에 8x8dct(압축 효율을 증대시키는 8x8 매크로블럭의 adaptive DCT 변환)을 더하여 압축률을 높인 프로파일이므로, "Main은 HD 이하, High는 HD 이상"이라고 생각하시면 됩니다. (샤나인코더와 달리 FFmpeg 명령줄의 경우 특별한 목적 말고는 굳이 프로파일을 선택할 필요가 없습니다.)
그러나 가끔 FHD 영상인데도 Main이나 Baseline 프로파일로 인코딩된 영상을 볼 수 있는데, 이는 단순히 잘못 설정한 것일 수도 있고, x264로 실시간 녹화시 가뜩이나 혹사당하는 CPU의 부담을 줄이기 위해 부하를 많이 주는 특성을 뺀 프로파일을 선택한 결과일 수도 있습니다. 어쨌든 화질을 고려한다면 반드시 High를 선택하실 것을 권장합니다.
레벨은 auto를 선택하십시오. 레벨은 최대 대역폭과 관련이 있기 때문에 재생기기 레벨 제한 등 특별한 이유가 있지 않은 한 auto를 선택하시는 게 속편한 방법입니다. (역시 FFmpeg 명령줄의 경우 굳이 레벨 제한을 해야 할 경우를 제외하고는 설정할 필요 없음.)
프리셋은 '목표 압축률 수준에 맞춰 미리 설정된 고유 옵션 설정값들의 모음'입니다. 높은 압축률(효율)을 목표로 할수록 낮은 속도가 나오기 때문에 속도로 표시한 것입니다. FFmpeg에서는 x264, x265 코덱 모두 medium이 기본값이며, 대개 medium, slow, slower 정도가 적당합니다. veryslow나 placebo는 화질 대비 시간이 과도하게 소요되므로 실용성이 없습니다.
튜닝(tune)은 원본에 맞춰 원하는 튜닝을 위해 몇몇 고유 옵션을 적절하게 설정한 값들의 모음입니다. 프리셋에 우선하지만 사용자 고유 옵션 설정값에는 우선 순위가 떨어집니다. 원본에 따라 film, animation, grain(옛날 영화처럼 화면에 노이즈가 낀 영상), stillimage 등을 선택할 수 있습니다. psnr과 ssim은 화질 관련 해당 지표값을 최대화하는 설정값들입니다. 대개 film이나 animation, grain 정도만 쓰이고 나머지는 쓸 일 없으실 듯...
Fast Decode와 Zero Latency는 설정 안 하시는 게 낫습니다. (Zero latency는 레이턴시 제약이 높은 상황에서 재생하기 위한 용도로 인코딩할 때 쓰는 옵션)
2. 고급 설정 (=FFmpeg의 고유 옵션 설정)
대부분 빠른 설정 부분에서 프리셋 설정만으로도 만족스러운 결과가 나옵니다. 하지만 원본에 따라 좀더 세밀한 옵션을 주거나 화질을 좀더 높이고 싶은 설정을 하고 싶다면 고급 설정을 클릭하여 다음과 같이 사용자화할 수 있습니다.
한 가지 유념할 점은, 샤나인코더의 H264 고급 설정 부분은 모든 고유 옵션에 대해 설정할 것을 전제로 하기 때문에 과도하게 많은 부분에 대해 신경써야 하는 단점이 있습니다. 실제 FFmpeg 명령줄을 구성할 때는 기본값인 medium 프리셋에서 달라지는 고유 옵션들만 -x264-params 옵션 뒤에 명시하면 되므로 오히려 더 간편하게 적용할 수 있습니다.
(참고로 샤나인코더에서는 아직 x265의 고급 설정 메뉴를 제공하고 있지 않습니다. x265에서 고유 옵션들을 설정하려면 F8을 눌러 매개변수 창에서 -x265-params로 시작하는 옵션값을 인코딩 설정 부분에 직접 삽입해야 합니다.)
[Frame-Type]
Deblocking은 H264의 중요한 특성 중 하나인 in-loop deblocking을 의미합니다. 일종의 깍두기 제거를 위해 흐림 효과를 주는 것이라고 생각하면 됩니다. 반드시 선택해야 제대로 된 화질이 나옵니다. (참고: H.264/AVC 표준의 In-Loop Deblocking Filter)
첫 번째 값은 화면 전체에 블러링을 주는 강도고, 두 번째 값은 경계 부분에 블러링을 주는 강도입니다. 대개 기본값인 0 또는 -2에서 2 사이의 값을 줍니다. 디테일이 좀더 살아있는 영상을 위해서는 낮은 값을, 약간의 블러링을 감수하고 깨끗한 영상을 원한다면 높은 값을 주는 것이 좋습니다. (애니메이션의 경우 경계 부분의 디테일을 살리기 위해 두 번째 옵션(Beta)에 낮은 값을 주는 것이 좋음.)
CABAC은 퀀타이저로 조정된 데이터를 무손실 압축하는 엔트로피 코딩의 알고리듬을 의미하는데, 기존의 다른 방식보다 압축 효율이 높아 High 프로파일 이상에서는 반드시 선택합니다.
GOP size는 GOP 크기값의 최소값과 최대값을 결정하는데, 최소값은 키프레임들 간의 최소 간격, 최대값은 키프레임들 간의 최대 간격을 말합니다. 이 값들이 작을수록 화질은 개선되지만 I 프레임의 증가로 데이터 용량이 증가하여 압축률이 떨어지며 인코딩 시 시간이 더 소요됩니다. 웬만하면 수정하지 않을 것을 권장합니다.
Open GOP는 GOP 내 P와 B 프레임들이 GOP 밖의 프레임을 참조할 수 있는 GOP를 말합니다. H264는 모든 GOP가 닫혀(closed) 있는 것이 기본값입니다. GOP가 열려(open) 있으면 P/B 프레임에 할당하는 데이터를 보다 절약할 수 있으므로 압축 효율은 올라가지만 재생시 필요한 레이턴시는 증가합니다. (HEVC은 open이 기본값. HEVC 재생이 H264 재생보다 고사양의 하드웨어를 요구하는 이유 중 하나임.)
Slice는 인코딩시 프레임을 자르는 값인데, 손대지 말 것을 권장합니다.
B-frames는 연속되는 B 프레임의 최대 갯수입니다. (기본값은 3) 값이 높을수록 효율은 증가(압축률이 높아 용량이 절약되거나 화질에서 이득)하나 인코딩 시간이 더 소요됩니다.
Adaptive B-Frames(b-adapt)는 B 프레임 결정 방법을 어떤 식으로 adaptive하게 적용할 것인지 하는 것입니다. 기본값은 'Fast'이지만 'Optimal'을 적용해서 효율을 증가시킵니다. (대신 B 프레임 최대 갯수가 늘어날수록 인코딩 속도는 저하)
Reference Frames는 P 프레임이 참조할 수 있는 선행 프레임 수입니다. (B 프레임의 참조 수는 P 프레임의 참조수보다 1~2 더 적음.) 이 값이 클수록 압축률은 증가하나 인코딩과 디코딩시 레이턴시가 늘어납니다. (쉽게 말해 높은 버퍼가 필요하다는 의미.) 기본값은 3.
Adaptive I-Frames Decision(scenecut)은 얼마나 적극적으로 I 프레임을 만들 것인지 지시하는 값입니다. 값이 높을수록 I 프레임들이 (즉, GOP들이) 많이 생성됩니다.
다른 부분은 굳이 건드릴 필요 없는 설정입니다.
[Rate Control]
프레임/매크로블럭 간의 비트레이트 분배와 관련된 설정입니다.
VBV Maximum Bitrate와 VBV Buffer Size는 전체 비트레이트 제한을 위한 설정으로, 버퍼사이즈가 하드웨어적으로 제한된 재생기기를 위한 인코딩 시 설정하는 부분입니다. (참고: x264의 VBV 옵션) 그외의 경우 설정할 필요가 없습니다.
Number of Frames for Lookahead(rc-lookahead)는 프레임 종류 결정을 위해 선행적으로 들여다보는 프레임 수입니다. 40이 기본값이며 크기가 클수록 효율은 증가하지만 인코딩/디코딩 시 레이턴시가 증가합니다.
MB-Tree는 MB(macroblock, 하나의 프레임 또는 필드를 가로 세로 일정한 크기의 정사각형으로 자른 것)의 프레임 간 비트레이트 배분을 좀더 효율적으로 하여 압축률을 향상시킵니다.
AQ(adaptive quantization)는 화면상에서 무시되기 쉬운 flat area와 어두운 부분에 비트를 좀더 할당하여 디테일을 좀더 살리는 옵션입니다. Variance나 Auto-Variance를 추천합니다. Strength는 1~2 정도의 값에서 적당히 결정하는 게 좋습니다.
[Analysis]
프레임/매크로블럭 간의 움직임 차이 분석과 관련된 설정입니다.
Motion Estimation은 가장 중요한 부분 중 하나입니다. hex가 기본값인데, umh로 변경하여 프레임 간 움직임 예측 알고리듬을 좀더 개선할 것을 권장합니다. 범위(Range)는 기본값 16에서 24 사이, Subpixel M.E.(subme)는 높은 숫자일수록 화질이 개선되지만 속도가 저하되므로 기본값인 7 정도가 적당.
MV Prediction Mode(direct)는 direct motion vector의 예측 모드입니다. 기본값은 spatial(공간)이지만 auto로 설정.
다른 부분은 웬만하면 기본값대로 하실 것을 권합니다.
3. 매개변수 설정 창으로 본 옵션 설정의 결과
위와 같이 설정한 후 F8을 눌러 매개변수 창을 열어보면 다음과 같이 기록돼 있을 겁니다.
필터 매개변수 부분은 샤나인코더에서 FFmpeg의 비디오 필터(첫째 칸)와 오디오 필터(둘째 칸) 설정을 보여주는 부분입니다.
샤나인코더에서는 빠른 설정에서 설정한 오디오의 샘플 레이트를 aresample 필터로 처리하여 오디오 필터(af) 부분에 반영합니다. (샤나인코더 예전 버전에서는 빠른 설정에서 오디오 쪽은 반드시 샘플 레이트 변경을 선택해 aresample 필터가 적용되도록 했는데, 이는 코덱에 따라서 샘플 레이트를 변경하지 않으면 인코딩이 진행되지 않고 오류가 발생하는 코덱이 있어서 이를 방지하기 위함이었습니다. 5.0.0.3 버전부터는 GSM, AMRNB, AMRWB 오디오 코덱만 샘플 레이트를 필수로 사용하도록 변경하였습니다.)
인코딩 설정 부분은 빠른 설정에서 설정한 내용을 FFmpeg 명령어로 보여주는 부분인데, FFmpeg의 명령어 중 input과 비디오/오디오 필터를 제외한 나머지 부분을 보여줍니다. (Input은 파일 목록의 파일 이름이 들어가고, 필터는 바로 위의 '필터 매개변수' 부분에 표시)
내용을 보면 샤나인코더가 빠른 설정의 설정 내용을 FFmpeg 명령어로 어떻게 치환했는지를 알 수 있습니다. 고급 설정에서 설정한 값들은 읽기 전용으로 편집이 불가능하게 되어 있어 빠른 설정을 이용해야 하지만, 추가 명령 옵션이나 추가 메타데이터 입력 등은 자신이 직접 삽입하거나 수정할 수 있게 되어 있어 FFmpeg 명령어들을 안다면 샤나인코더가 어떤 식으로 작업을 처리하는지 알 수 있고 필요한 부분은 직접 추가하거나 수정하면서 샤나인코더를 최대한 활용할 수 있습니다.
4. FFmpeg에서 x264 설정에 적용하기
위와 같이 샤나인코더에서 설정한 x264 인코딩 명령어를 FFmpeg에서 실행하기 적당하게 FFmpeg 명령줄로 변환하면 다음과 같습니다. (대문자는 실제 실행할 때 적절하게 수정할 부분)
ffmpeg -i INPUT -c:v libx264 -preset medium -crf 23.0 -x264-params deblock=-1,-1:b-adapt=2:aq-mode=2:merange=24:me=umh:direct=auto -c:a aac -b:a 128k -ac 2 -sn -map_metadata -1 -map_chapters -1 OUTPUT.mp4
이때 유의할 점은 다음과 같습니다.
- 비디오 프로파일, 튠, 레벨 설정 생략
- 고유 옵션 설정 부분은 기본값에서 달라지는 부분만 적용
- 오디오 코덱은 FDK-AAC가 아닌 FFmpeg 내장 aac 적용 (FFmpeg 라이센스 문제)
- 기타 샤나인코더만의 커스텀 옵션이 있다면 이를 FFmpeg에 맞게 변경
기존에 배포되고 있는 FFmpeg 바이너리(대표적으로는 BtbN의 FFmpeg 빌드)들은 FFmpeg 기본 라이센스인 GPL을 준수하기 위해서 오디오 코덱에 FDK-AAC가 포함되지 않습니다. 이와는 달리 샤나인코더에서는 FDK-AAC가 기본 AAC 인코더로 설정돼 있으니 샤나인코더 ⇒ FFmpeg 명령줄 변환에 이 사항을 반드시 고려해야 합니다. (샤나인코더에서 어떻게 FDK-AAC를 포함시킬 수 있는지는 이 게시글에 개발자인 리나님이 남기신 댓글을 참조하시기 바랍니다.)
최대한 원본화질과 동급이나 초고화질로만 소장하면서 용량때문에 일일이 인코딩하는데
저는 화질우선시 하는편이라 위에 설명해놓으신 빠른설정에 설명과 이미지대로만 설정해놓고
인코딩하면 최대한 화질보존하면서 인코딩 되는건가요?