10비트 HDR 영상을 8비트 SDR 영상으로 변환하기 위해서는 픽셀 포맷 변경(8비트로의 다운샘플링)과 함께 원본의 풍부한 색감을 최대한 보존하기 위해 반드시 적절한 톤매핑 과정이 필요합니다. FFmpeg와 AviSynth+는 이를 조금씩 다른 방법으로 처리할 수 있는데요, 샤나인코더 4.9.0.6 이상 버전들은 FFmpeg의 복잡한 톤매핑 과정(zscale, tonemap 필터 체인 적용)을 빠른 설정 메뉴인 "HDR을 SDR로 톤 매핑(shanatonemap)"으로 간소화했습니다.
이에 반해 필터 처리 언어라고도 할 수 있는 AviSynth+에서는 약간 복잡하지만 두 가지 다른 방법으로 SDR 변환을 할 수 있는데요, FFmpeg와 상당히 유사한 DGTonemap 필터와, 일종의 간략화 버전인 DGHDRtoSDR 필터가 그것입니다.
<StaxRip에서 AviSynth+의 DGTonemap(DGHable 알고리듬) 필터를 적용한 모습>
<StaxRip에서 AviSynth+의 DGHDRtoSDR 필터를 적용한 모습>
이 세 가지 다른 변환 방법이 성능과 결과에서 어떤 차이를 보일까 궁금해서 테스트했습니다.
■ 시스템 환경
- 샤나인코더 : 5.0.0.4
- AviSynth+ : 3.5.1 (2020-04-03)
- StaxRip : 2.1.0.2 Beta
- x264(StaxRip) : 159-r2991M built with GCC 10.0.1 by Patman
- Windows : Windows 10 Home 2004
- CPU : Intel(R) Core(TM) i5-7300HQ CPU @ 2.50GHz
■ 원본
LG: New York HDR의 UHD HDR인 ts 파일을 StaxRip으로 작업하기 쉽도록 mkv 파일로 리먹싱
ffmpeg -hide_banner -analyzeduration 100M -probesize 50M -i "LG New York HDR UHD 4K Demo.ts" -map 0 -c copy -bsf:a aac_adtstoasc -y "LG New York HDR UHD 4K Demo.mkv"
■ 필터 처리 방법
- 샤나인코더: 해상도 변경은 scale, 톤매핑은 shanatonemap
- AviSynth+(StaxRip): 해상도 변경은 Spline64Resize, 톤매핑은 DGTonemap(DGHable 알고리듬) vs DGHDRtoSDR
■ 인코더
- 비디오: 세 방법 모두 동일한 x264 옵션으로 설정
--crf 23 --profile high --aq-mode 3 --me umh --direct auto --merange 24 --b-adapt 2 --colorprim bt709 --colormatrix bt709 --transfer bt709 --aud --deblock -1:-1
- 오디오: 스트림 복사
■ 인코딩 성능 결과
- 샤나인코더: 소요시간 5분 31초, 파일 크기 64.20 MiB
- DGTonemap: 소요시간 2분 54초, 파일 크기 64.51 MiB
- DGHDRtoSDR: 소요시간 2분 31초, 파일 크기 62.85 MiB
AviSynth+가 가장 최신 버전(2020년 4월 3일자 3.5.1)이라는 것과 StaxRip에서 사용된 x264 역시 가장 최근 버전을 가장 최근의 GCC 10.0.1로 컴파일한 것이라는 것을 고려해야 합니다만, 그런 사항들을 고려하더라도 AviSynth+의 필터들과 샤나인코더(FFmpeg) 필터들의 성능이 상당히 차이가 나는 것을 알 수 있는데, 이는 FFmpeg의 tonemap 필터가 아직 최적화되지 않았기 때문으로 판단됩니다.
■ 결과 동영상들
- 샤나인코더
- DGTonemap
- DGHDRtoSDR
색감이 조금씩 다른 것을 아실 수 있을 겁니다.
■ 추가 자료들
○ AviSynth+ 스크립트 소스들
- DGTonemap(DGHable):
======================================================================================
LoadPlugin("D:\Utilities\StaxRip\Apps\Plugins\AVS\AvsResize\avsresize.dll")
LoadPlugin("D:\Utilities\StaxRip\Apps\Plugins\AVS\DGTonemap\DGTonemap.dll")
LoadPlugin("D:\Utilities\StaxRip\Apps\Plugins\Dual\ffms2\ffms2.dll")
FFVideoSource("D:\Work\tmp\LG New York HDR UHD 4K Demo.mkv", cachefile = "D:\Work\tmp\LG New York HDR UHD 4K Demo_temp\LG New York HDR UHD 4K Demo.ffindex")
#AssumeFPS(25)
Spline64Resize(1920, 1080)
z_ConvertFormat(pixel_type="RGBPS",colorspace_op="2020ncl:st2084:2020:l=>RGB:Linear:2020:l", dither_type="None")
DGHable()
z_ConvertFormat(pixel_type="YV12",colorspace_op="RGB:Linear:2020:l=>709:709:709:l", dither_type="ordered")
======================================================================================
- DGHDRtoSDR:
======================================================================================
LoadPlugin("D:\Utilities\StaxRip\Apps\Plugins\Dual\DGHDRtoSDR\DGHDRtoSDR.dll")
LoadPlugin("D:\Utilities\StaxRip\Apps\Plugins\Dual\ffms2\ffms2.dll")
FFVideoSource("D:\Work\tmp\LG New York HDR UHD 4K Demo.mkv", cachefile = "D:\Work\tmp\LG New York HDR UHD 4K Demo_temp\LG New York HDR UHD 4K Demo.ffindex")
#AssumeFPS(25)
Spline64Resize(1920, 1080)
ConvertBits(16)
DGHDRtoSDR(mode="pq",white=2500)
======================================================================================
변환한 동영상들 원본과 로그 파일들을 구글 드라이브로 공유합니다. 관심 있는 분들은 사본 받아서 살펴보시기 바랍니다.