FFmpeg와 Vulkan Compute: CPU와 ASIC의 한계를 넘는 GPU 비디오 파이프라인
일반적인 유저들에게 비디오 인코딩과 디코딩은 이미 ‘해결된 문제’처럼 보인다. 스마트폰이나 랩탑에 탑재된 전용 하드웨어 가속기(ASIC)가 H.264, HEVC, 심지어 AV1까지 조용하고 효율적으로 처리해주기 때문이다. 하지만 엔터프라이즈 레벨이나 프로덕션 환경으로 넘어가면 이야기가 완전히 달라진다.
수일 치의 원본 카메라 푸티지를 스크러빙하는 편집자, 8K 16-bit 마스터링을 다루는 컬러리스트, 32-bit 부동소수점 ACEScg 비디오를 렌더링하는 VFX 아티스트들에게 성능의 벽은 여전히 높다. 이들은 값비싼 독점 솔루션을 구매하거나 100코어 CPU와 수백 기가바이트의 RAM을 갖춘 수랭식 워크스테이션에 의존해야 했다.
최근 Khronos 그룹 블로그에 올라온 FFmpeg의 Vulkan Compute Shader 도입에 관한 글은, 이 오래된 병목을 일반 소비자용 GPU로 어떻게 박살 낼 수 있는지 보여주는 훌륭한 엔지니어링 사례다. 15년 넘게 백엔드와 미디어 파이프라인을 다뤄온 엔지니어로서, 이 접근 방식은 굉장히 우아하면서도 실용적이다.
하이브리드 디코딩의 실패와 PCIe Latency의 저주
코덱을 GPU로 가속하려는 시도는 예전부터 있었다. 비디오 압축 알고리즘은 본질적으로 직렬(Serial)과 병렬(Parallel) 작업이 혼재되어 있다. JPEG를 예로 들면, 양자화(Quantization)는 완벽히 병렬화가 가능하지만, 허프만 코딩이나 DC 값 예측은 철저하게 직렬적이다.
과거 업계의 상식적인 접근은 ‘하이브리드 디코딩’이었다. 복잡한 직렬 작업은 CPU가 처리하고, 중간 결과물을 GPU로 넘겨 병렬 처리를 맡기는 식이다. 하지만 현업에서 이 방식을 테스트해 본 엔지니어라면 누구나 알 것이다. PCIe 대역폭을 통한 메모리 복사 Latency가 연산에서 얻는 이득을 모조리 깎아먹는다.
실제로 dav1d 디코더나 x264의 OpenCL 지원 시도가 이 문제로 인해 실패하거나 방치되었다. 내가 항상 팀원들에게 강조하는 시스템 아키텍처의 불문율이 있다. “GPU로 데이터를 보냈으면, 처리가 끝날 때까지 절대 CPU로 다시 가져오지 마라.” FFmpeg 팀은 이 교훈을 정확히 이해하고, CPU의 개입 없이 코덱 전체를 100% GPU에 상주시키는 Compute Shader 구현을 택했다.
해상도의 폭발이 가져온 뜻밖의 병렬성
흥미로운 점은 비디오 해상도가 미친 듯이 커지면서 오히려 GPU Compute에 유리한 환경이 조성되었다는 것이다. 대부분의 코덱은 블록이나 슬라이스 단위로 작업을 분할한다. 과거 저해상도 시절에는 이 단위가 프레임에서 차지하는 비중이 커서 병렬화의 한계가 명확했다.
하지만 4K, 8K 시대가 되면서 하나의 프레임 안에 수많은 블록이 존재하게 되었고, 이는 최신 GPU의 수천 개 코어를 꽉 채울 수 있는 엄청난 양의 병렬 워크로드를 의미한다.
FFv1과 ProRes RAW의 혁신
아카이빙 커뮤니티의 표준인 FFv1은 압축률은 좋지만 Range Coder의 병목 때문에 고해상도 처리가 끔찍하게 느렸다. FFmpeg는 Workgroup 크기를 32로 고정하고, 각 로컬 인스턴스가 병렬로 룩업과 어댑테이션을 수행하게 만들어 이 문제를 해결했다.
또한, 업계 표준인 ProRes RAW의 경우 DCT와 계수 코더를 사용하는데, 타일 수에 제한이 없어 GPU의 병렬성을 극대화하기 완벽한 구조다. FFmpeg는 2-Pass Shader 접근법을 통해 첫 번째 셰이더가 타일을 디코딩하고, 두 번째 셰이더가 행/열 단위로 블록을 변환하는 방식을 취했다.
Hacker News 커뮤니티의 반응과 오해
이 소식이 Hacker News에 올라왔을 때, 스레드에서는 꽤 흥미로운 논쟁이 벌어졌다. 많은 개발자들이 이 기술의 목적을 ‘웹 스트리밍’으로 오해하고 있었다.
- 일반적인 오해: “왜 굳이 GPU Compute를 쓰지? Intel QSV나 NVENC 같은 전용 하드웨어(ASIC)를 쓰면 전력도 적게 먹고 빠른데?”
- 실제 타겟: 이 기술은 H.264로 트위치 방송을 하려는 사람을 위한 것이 아니다. ASIC이 지원하지 않는 전문가용 Mezzanine 포맷(ProRes, FFv1, DPX)을 다루는 프로덕션을 위한 것이다.
HN의 한 유저가 정확히 지적했듯, 기존에는 4K 16-bit FFv1 영상을 편집하려면 어마어마한 스토리지 대역폭과 워크스테이션이 필요했거나, 화질 열화를 감수하고 Proxy 파일을 만들어야 했다. 하지만 이 기술을 사용하면 일반적인 RTX 4080 같은 소비자용 GPU에서도 초당 수백 프레임으로 무손실 비디오를 스크러빙할 수 있다. VFX 파이프라인에서 Proxy 생성이라는 번거로운 단계를 완전히 제거할 수 있다는 뜻이다.
왜 CUDA가 아니라 Vulkan인가?
개인적으로 가장 마음에 드는 부분은 이들이 특정 벤더의 API(CUDA, Metal)에 종속되지 않고 Vulkan Compute를 선택했다는 점이다.
과거에는 Vulkan을 단순한 그래픽 API로 치부했지만, 지금의 Vulkan은 포인터, Subgroup 연산, 공유 메모리 앨리어싱, 64-bit 어드레싱 등을 지원하며 전용 Compute API에 필적하는 수준으로 진화했다. 특히 FFmpeg처럼 수십 년간 유지보수되어야 하는 오픈소스 프로젝트 입장에서, 특정 벤더의 구형 GCC 버전에 묶이거나 라이선스 문제에 시달리는 것보다 순수한 SPIR-V 셰이더를 작성하는 것이 훨씬 안정적이고 영속적인 선택이다.
결론: 하드웨어 가속의 패러다임 전환
FFmpeg 8.1 릴리즈와 함께 도입된 이 기술은 단순한 ‘성능 최적화’ 수준이 아니다. 인디 VFX 스튜디오나 아카이빙 전문가들이 수천 달러짜리 장비 없이도 하이엔드 작업을 할 수 있게 만들어주는 게임 체인저다.
물론 JPEG2000처럼 구조적으로 구제 불능인 코덱도 여전히 존재하지만, Vulkan Compute를 통해 소프트웨어 디코딩의 유연성과 하드웨어 가속의 성능을 결합한 FFmpeg의 아키텍처는 현대 미디어 파이프라인이 나아가야 할 올바른 방향을 제시하고 있다. 당장 이번 주말에 FFmpeg 8.1을 빌드해서 로컬 GPU로 ProRes RAW 파일을 돌려봐야겠다.
- Reference: Video Encoding and Decoding with Vulkan Compute Shaders in FFmpeg
- HN Thread: Hacker News Discussion