자세히 알아보기: VideoNG

Dale Curtis
Dale Curtis

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

이 도움말에서는 Chromium의 동영상 렌더링 아키텍처를 안내합니다. 확장성에 관한 일부 세부정보는 Chromium에만 있을 수 있지만 여기서 설명하는 대부분의 개념과 디자인은 다른 렌더링 엔진과 네이티브 재생 앱에도 적용됩니다.

Chromium의 재생 아키텍처는 수년에 걸쳐 크게 변경되었습니다. 이 시리즈의 첫 번째 게시물에서 설명한 대로 성공의 피라미드라는 아이디어로 시작하지는 않았지만 최종적으로 안정성, 성능, 확장성이라는 유사한 단계를 따랐습니다.

초기에는 동영상 렌더링이 매우 단순했습니다. 단순한 for 루프로, 어떤 소프트웨어가 동영상 프레임을 컴포지터로 전송할지 선택할 수 있었습니다. 지난 몇 년 동안은 신뢰할 수 있었지만 웹의 복잡성이 증가함에 따라 더 많은 성능과 효율성에 대한 필요성으로 인해 아키텍처도 변경되었습니다. 여러 개선사항을 위해서는 OS별 프리미티브가 필요했습니다. 따라서 Chromium의 모든 플랫폼에 도달할 수 있도록 아키텍처의 확장성을 더 높여야 했습니다.

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

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

일부 용어 및 레이아웃

이 문서에서는 렌더링에 중점을 두므로 파이프라인의 디덕싱 및 디코딩에 관해서만 간략히 언급하겠습니다.

흘러 들어가는 바이트와 흘러 나가는 구조화된 패킷입니다.

보안 의식이 높은 현대 사회에서 디코딩과 역다중화에는 상당한 주의가 필요합니다. 바이너리 파서는 리치 대상 환경이고 미디어 재생은 바이너리 파싱으로 가득합니다. 따라서 미디어 파서의 보안 문제는 매우 흔하게 발생합니다.

Chromium은 사용자에게 보안 문제가 발생할 위험을 줄이기 위해 심층 방어를 시행합니다. 실질적으로 이는 역다중화 및 소프트웨어 디코딩은 항상 낮은 권한의 프로세스에서 발생하는 반면, 하드웨어 디코딩은 시스템의 GPU와 통신할 수 있는 권한만 있는 프로세스에서 발생한다는 것을 의미합니다.

렌더기, GPU, 오디오 프로세스를 위한 Chromium 샌드박스입니다.

Chromium의 프로세스 간 통신 메커니즘을 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 프리미티브를 더 많이 활용할수록 불필요하게 동영상 바이트를 셔플하는 데 사용되는 대역폭이 줄어듭니다. 디코딩부터 렌더링까지 모든 것을 한곳에 보관하면 놀라운 전력 효율을 달성할 수 있습니다. 예를 들어 macOS에서 Chromium 오버레이를 사용 설정하면 전체 화면 동영상 재생 중 전력 소모량이 절반으로 감소했습니다. 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 플랫폼은 프레임별로 렌더링하지만 모든 플랫폼은 렌더링되지 않습니다. Google의 확장 가능한 아키텍처는 일괄 렌더링도 허용합니다. 일괄 렌더링은 OS 수준 컴포지터에 여러 프레임에 관해 미리 알려주고 애플리케이션에서 제공하는 타이밍 일정에 따라 해제를 처리하는 효율성 기법입니다.

미래는 지금이야?

Google은 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, 수상 경력에 빛나는 기술로 수상 경력에 빛나는 프로그램 패키징(시릴 콘콜라토)을 추천합니다.

Una Kravets의 삽화는 예쁜 그림입니다.