자세히 알아보기: VideoNG

Dale Curtis
Dale Curtis

저는 Chromium의 미디어 재생 엔지니어링 책임자인 데이얼 커티스입니다. 저희 팀은 MSEWebCodecs와 같은 동영상 재생을 위한 웹용 API와 오디오 및 동영상의 디뮤싱, 디코딩, 렌더링과 관련된 플랫폼별 내부 기능을 담당합니다.

이 도움말에서는 Chromium의 동영상 렌더링 아키텍처를 설명합니다. 확장성과 관련된 일부 세부정보는 Chromium에만 해당할 수 있지만 여기에서 다루는 대부분의 개념과 설계는 다른 렌더링 엔진과 네이티브 재생 앱에도 적용됩니다.

Chromium의 재생 아키텍처는 지난 몇 년 동안 크게 변경되었습니다. 이 시리즈의 첫 번째 게시물에 설명된 성공의 피라미드 개념으로 시작하지 않았지만, 안정성, 성능, 확장성이라는 유사한 단계를 따랐습니다.

초기에는 동영상 렌더링이 매우 간단했습니다. 단지 for 루프를 사용하여 컴포저이터로 전송할 동영상 프레임을 디코딩하는 소프트웨어를 선택하면 되었습니다. 수년 동안 이 방법은 충분히 안정적이었지만 웹의 복잡성이 증가함에 따라 성능과 효율성을 높이기 위한 필요성이 제기되어 아키텍처가 변경되었습니다. 많은 개선사항에는 OS별 프리미티브가 필요했습니다. 따라서 모든 Chromium 플랫폼에 도달할 수 있도록 아키텍처도 더 확장 가능해야 했습니다.

다양한 Chromium 플랫폼으로의 렌더링 흐름 다이어그램

동영상 렌더링은 전송할 항목을 선택하고 해당 정보를 효율적으로 전송하는 두 단계로 나눌 수 있습니다. 가독성을 높이기 위해 Chromium에서 전송할 항목을 선택하는 방법을 살펴보기 전에 효율적인 전송을 다룹니다.

일부 용어 및 레이아웃

이 도움말에서는 렌더링에 중점을 두므로 파이프라인의 디뮤싱 및 디코딩 측면만 간단히 살펴봅니다.

들어오는 바이트와 나가는 구조화된 패킷

오늘날 보안을 중시하는 세상에서 디코딩과 디뮤싱을 하려면 상당히 주의를 기울여야 합니다. 바이너리 파서는 풍부한 타겟 환경이며 미디어 재생은 바이너리 파싱으로 가득 차 있습니다. 따라서 미디어 파서에서 보안 문제가 발생하는 것은 매우 흔한 일입니다.

Chromium은 사용자에게 보안 문제가 발생할 위험을 줄이기 위해 심층 방어를 실행합니다. 실제로는 디뮤싱과 소프트웨어 디코딩이 항상 권한이 낮은 프로세스에서 발생하는 반면 하드웨어 디코딩은 시스템의 GPU와 통신하기에 충분한 권한만 있는 프로세스에서 발생합니다.

렌더러, GPU, 오디오 프로세스의 Chromium 샌드박스

Chromium의 교차 프로세스 통신 메커니즘을 Mojo라고 합니다. 이 도움말에서는 Mojo에 관해 자세히 다루지 않지만 프로세스 간의 추상화 레이어로서 Mojo는 Chromium의 확장 가능한 미디어 파이프라인의 초석입니다. 재생 파이프라인을 살펴볼 때 이를 염두에 두는 것이 중요합니다. 미디어를 수신, 디뮤싱, 디코딩, 표시하기 위해 상호작용하는 교차 프로세스 구성요소의 복잡한 조정을 알려주기 때문입니다.

너무 많은 비트

오늘날의 동영상 렌더링 파이프라인을 이해하려면 동영상이 특별한 이유인 대역폭에 대한 지식이 필요합니다. 초당 60프레임으로 3840x2160 (4K) 해상도를 재생하면 9~12기가비트/초의 메모리 대역폭이 사용됩니다. 최신 시스템의 최대 대역폭은 초당 수백 기가비트일 수 있지만 동영상 재생은 여전히 상당한 부분을 차지합니다. 주의하지 않으면 GPU와 CPU 메모리 간의 복사나 이동으로 인해 총 대역폭이 쉽게 증가할 수 있습니다.

효율성을 염두에 둔 최신 동영상 재생 엔진의 목표는 디코더와 최종 렌더링 단계 간의 대역폭을 최소화하는 것입니다. 이 때문에 동영상 렌더링은 Chromium의 기본 렌더링 파이프라인과 거의 분리됩니다. 특히 기본 렌더링 파이프라인의 관점에서 동영상은 불투명도가 있는 고정 크기의 구멍일 뿐입니다. Chromium은 노출 영역이라는 개념을 사용하여 이를 실행합니다. 여기서 각 동영상은 Viz와 직접 통신합니다.

구멍과 '동영상을 여기에 넣으세요'라는 화살표가 있는 웹페이지

모바일 컴퓨팅의 인기로 인해 전원과 효율성이 현재 세대의 중요한 관심사가 되었습니다. 그 결과 디코딩과 렌더링이 하드웨어 수준에서 그 어느 때보다도 밀접하게 결합되어 동영상이 OS 자체에조차 불투명한 구멍처럼 보입니다. 플랫폼 수준 디코더는 종종 Chromium이 오버레이 형태로 플랫폼 수준 컴포지션 시스템에 전달하는 불투명 버퍼만 제공합니다.

운영체제를 나타내는 상자로 래핑된 구멍과 '동영상을 여기에 넣으세요'라는 화살표가 있는 웹페이지

모든 플랫폼에는 플랫폼 디코딩 API와 함께 작동하는 자체 오버레이 형식이 있습니다. Windows에는 직접 컴포지션미디어 재단 변환이, macOS에는 CoreAnimation 레이어VideoToolbox가, Android에는 SurfaceViewMediaCodec이, Linux에는 VASurfacesVA-API가 있습니다. 이러한 개념에 대한 Chromium의 추상화는 각각 OverlayProcessormojo::VideoDecoder 인터페이스에서 처리합니다.

경우에 따라 이러한 버퍼를 시스템 메모리에 매핑할 수 있으므로 불투명할 필요도 없고 액세스할 때까지 대역폭을 소비하지 않습니다. Chromium에서는 이러한 버퍼를 GpuMemoryBuffers라고 합니다. Windows에서는 DXGI 버퍼, macOS에서는 IOSurfaces, Android에서는 AHardwareBuffers, Linux에서는 DMA 버퍼로 지원됩니다. 일반적으로 동영상 재생에는 이러한 액세스가 필요하지 않지만 이러한 버퍼는 캡처 장치와 최종 인코더 간에 최소한의 대역폭을 보장하기 위해 동영상 캡처에 중요합니다.

앞의 텍스트에 언급된 버퍼의 다이어그램

GPU는 디코딩과 표시를 모두 담당하는 경우가 많으므로 이러한 불투명 버퍼를 사용하면 대역폭이 큰 동영상 데이터가 GPU를 실제로 벗어나지 않습니다. 앞서 설명한 대로 GPU에 데이터를 유지하는 것은 특히 높은 해상도와 프레임 속도에서 효율성을 높이는 데 매우 중요합니다.

오버레이 및 GPU 버퍼와 같은 OS 프리미티브를 더 많이 활용할수록 동영상 바이트를 불필요하게 셔플하는 데 낭비되는 대역폭이 줄어듭니다. 디코딩에서 렌더링에 이르기까지 모든 것을 한곳에서 유지하면 전력 효율성이 크게 향상될 수 있습니다. 예를 들어 Chromium이 macOS에서 오버레이를 사용 설정하면 전체 화면 동영상 재생 중 전원 소모량이 절반으로 줄었습니다. Windows, Android, ChromeOS와 같은 다른 플랫폼에서는 전체 화면이 아닌 경우에도 오버레이를 사용할 수 있으므로 거의 모든 곳에서 최대 50% 까지 절약할 수 있습니다.

렌더링

최적의 전송 메커니즘을 살펴봤으므로 이제 Chromium에서 전송할 항목을 선택하는 방법을 논의할 수 있습니다. Chromium의 재생 스택은 '가져오기' 기반 아키텍처를 사용합니다. 즉, 스택의 각 구성요소는 계층적 순서대로 아래에 있는 구성요소에서 입력을 요청합니다. 스택의 맨 위에는 오디오 및 동영상 프레임 렌더링이 있고 그 아래에는 디코딩, 디뮤싱, I/O가 있습니다. 렌더링된 각 오디오 프레임은 클럭을 전진시킵니다. 이 클럭은 프레젠테이션 간격과 결합될 때 렌더링할 동영상 프레임을 선택하는 데 사용됩니다.

각 프레젠테이션 간격 (디스플레이의 각 새로고침)에서 동영상 렌더러는 앞에서 언급한 SurfaceLayer에 연결된 CompositorFrameSink에 의해 동영상 프레임을 제공하도록 요청받습니다. 디스플레이 속도보다 프레임 속도가 느린 콘텐츠의 경우 동일한 프레임을 두 번 이상 표시하는 반면, 프레임 속도가 디스플레이 속도보다 빠르면 일부 프레임이 표시되지 않습니다.

시청자에게 즐거움을 주는 방식으로 오디오와 동영상을 동기화하는 방법에는 더 많은 것이 있습니다. Chromium에서 최적의 동영상 원활성을 달성하는 방법에 관한 자세한 내용은 Project Butter를 참고하세요. 동영상 렌더링을 각 프레임이 표시되어야 하는 횟수를 나타내는 이상적인 시퀀스로 분할하는 방법을 설명합니다. 예를 들어 '디스플레이 간격마다 1프레임( [1], 60Hz에서 60fps)', '2개 간격마다 1프레임( [2], 60Hz에서 30fps)' 또는 여러 개의 고유한 프레임과 디스플레이 간격을 포함하는 더 복잡한 패턴(예: [2:3:2:3:2](60Hz에서 25fps))을 사용할 수 있습니다. 동영상 렌더러가 이 이상적인 패턴에 가까울수록 사용자가 재생을 원활하게 인식할 가능성이 높습니다.

디뮤싱, 디코딩, 렌더링의 순서입니다.

대부분의 Chromium 플랫폼은 프레임별로 렌더링하지만 그렇지 않은 플랫폼도 있습니다. 확장 가능한 아키텍처를 사용하면 일괄 렌더링도 가능합니다. 일괄 렌더링은 OS 수준 컴포저가 여러 프레임에 관해 미리 알리고 애플리케이션에서 제공한 타이밍 일정에 따라 프레임의 출시를 처리하는 효율성 기술입니다.

미래가 이미 도래했나요?

Chromium이 OS 프리미티브를 활용하여 최고의 재생 환경을 제공하는 방법에 중점을 두었습니다. 하지만 기본 동영상 재생을 넘어서려는 웹사이트는 어떻게 해야 하나요? Chromium 자체에서 차세대 웹 콘텐츠를 도입하는 데 사용하는 것과 동일한 강력한 프리미티브를 제공할 수 있을까요?

답은 '예'입니다. 확장성은 오늘날 웹 플랫폼을 생각하는 방식의 핵심입니다. Google은 웹 개발자가 OS와 통신할 때 Chromium에서 사용하는 것과 동일한 프리미티브를 사용할 수 있도록 WebGPUWebCodecs와 같은 새로운 기술을 만들기 위해 다른 브라우저 및 개발자와 협력하고 있습니다. WebGPU는 GPU 버퍼 지원을 제공하고 WebCodecs는 앞서 언급한 오버레이 및 GPU 버퍼 시스템과 호환되는 플랫폼 디코딩 및 인코딩 프리미티브를 제공합니다.

WebCodecs와 WebGPU의 관계

스트림 종료

읽어 주셔서 감사합니다. 최신 재생 시스템과 Chromium이 매일 수억 시간의 시청 시간을 지원하는 방식을 더 잘 이해하는 데 도움이 되었기를 바랍니다. 코덱 및 최신 웹 동영상에 관해 자세히 알아보려면 Sid Bala의 H.264 is magic, Erica Beaves의 How Modern Video Players Work, Cyril Concolato의 Packaging award-winning shows with award-winning technology를 참고하세요.

우나 크라베츠의 예쁜 그림 1개