FFmpeg를 사용한 VP9 실시간 인코딩

인코딩 매개변수

VP9은 다양한 매개변수를 제공하여 실시간 인코딩을 최적화합니다. 이와 관련된 몇 가지 광범위한 원칙은 비트 모드에서 설명합니다.

FFmpeg VP9 인코딩 예

아래 표는 VP9 인코딩의 ffmpeg 호출 예의 매개변수를 설명합니다.

매개변수 설명
-quality realtime realtime은 실시간 스트리밍과 5 이상의 속도에 필수적입니다.
-speed 6 실시간/실시간 인코딩에 5~8의 속도를 사용해야 합니다. 숫자가 작을수록 (5 또는 6) 품질이 높아지지만 CPU 전력이 더 많이 필요합니다. 번호(7 또는 8)가 클수록 품질이 낮지만 지연 시간이 짧은 사용 사례와 모바일과 같은 CPU 전력 기기가 낮은 경우에도 더 쉽게 관리할 수 있습니다.
-tile-columns 4 Tail을 사용하면 동영상을 직사각형 영역으로 분할하여 인코딩과 디코딩을 멀티스레딩할 수 있습니다. 타일 수는 항상 2의 제곱입니다. 0 = 1 타일, 1 = 2, 2 = 4, 3 = 8, 4 = 16, 5 = 32입니다.
-frame-parallel 1 병렬 디코딩 기능을 사용 설정합니다.
-threads 8 사용할 최대 스레드 수입니다.
-static-thresh 0 움직임 감지 임계값.
-max-intra-rate 300 최대 i-Frame 비트 전송률 (pct)
-deadline realtime -quality realtime의 대체 (기존) 버전
-lag-in-frames 0 지연 가능한 최대 프레임 수
-qmin 4 -qmax 48 양자화의 최솟값 및 최댓값 여기에 표시된 값은 단순한 제안사항이며, 이렇게 하면 동영상 품질을 높이거나 낮출 수 있으며 압축 효율성이 저하됩니다.
-row-mt 1 행 멀티스레딩을 사용 설정합니다. 최대 2배의 대화목록을 타일 열로 사용할 수 있습니다. 0 = 사용 중지, 1 = 사용
-error-resilient 1 오류 탄력성 기능을 사용 설정합니다.

인코딩 매개변수 선택

아래 정보는 실시간 적응형 비트 전송률 스트리밍 (ABR)에 상수 비트 전송률 (CBR) 인코딩을 사용하며, 각 타겟 속도는 패키지 패키지에 명시적으로 설정됩니다. 이렇게 하면 클라이언트의 요금이 더 깔끔해지고 깔끔해집니다. 비트 전송률이 더 유연하거나 인코딩이 청크 단위의 단위인 경우, 가변 비트 전송률 (VBR) 인코딩과 CQ 모드 옵션도 가능합니다. Q 모드는 실시간 동영상에 필요한 실시간 인코딩에 어려움을 겪습니다. 자세한 내용은 비트 전송률 모드를 참고하세요.

VP9을 조작하는 방법에 관한 자세한 내용은 VOD 설정과 함께 제공되는 도움말을 참조하면서 CBR에 초점을 맞추는 것이 좋습니다.

도움말 및 유용한 정보

실시간 스트리밍 시 모든 항목은 최소 실시간 인코딩 속도 1x로 제한됩니다 (FFmpeg는 진행 속도를 인코딩합니다). 인코딩 속도가 1x 미만이면 인코딩 프로세스에서 실시간 동영상 입력을 따라갈 수 없으며 사용자가 버퍼링을 경험하고 실시간 스트리밍 중에 전송을 중단하면 실시간 스트림을 사용할 수 없게 됩니다(일반적으로 보관 파일을 사용할 수 있음).

작동 중인 인코딩 매개변수의 예

다음은 쿼드 코어 i5 3.6Ghz 데스크톱의 다양한 프레임 크기에서 25fps의 CPU 사용률을 보여줍니다.

목표 해상도 FFmpeg VP9 매개변수 CPU / 속도 (예)
3840x2160 (2160p) -r 30 -g 90 -s 3840x2160 -quality 실시간 -speed 5 -threads 16 -row-mt 1 -tile-columns 3 -frame- parallel 1 -qmin 4 -qmax 48 -b:v 7800k ~88% 0.39x
2560x1440 (1440p) -r 30 -g 90 -s 2560x1440 -quality 실시간 -speed 5 -threads 16 -row-mt 1 -tile-columns 3 -frame- parallel 1 -qmin 4 -qmax 48 -b:v 6000k ~86% 0.68x
1920x1080 (1080p) -r 30 -g 90 -s 1920x1080 -quality 실시간 -speed 5 -threads 8 -row-mt 1 -tile-columns 2 -frame- parallel 1 -qmin 4 -qmax 48 -b:v 4500k ~82% 1.04x
1280x720 (720p) -r 30 -g 90 -s 1280x720 -quality 실시간 -speed 5 -threads 8 -row-mt 1 -tile-columns 2 -frame- parallel 1 -qmin 4 -qmax 48 -b:v 3000k ~78% 1.77x
854x480 (480p) -r 30 -g 90 -s 854x480 -quality 실시간 -speed 6 -threads 4 -row-mt 1 -tile-columns 1 -frame- parallel 1 -qmin 4 -qmax 48 -b:v 1800k ~44% 3.51x
640x360 (360p) -r 30 -g 90 -s 640x360 -quality 실시간 -speed 7 -threads 4 -row-mt 1 -tile-columns 1 -frame- parallel 0 -qmin 4 -qmax 48 -b:v 730k ~62% 5.27x
426x240 (240p) -r 30 -g 90 -s 426x240 -quality 실시간 -speed 8 -threads 2 -row-mt 1 -tile-columns 0 -frame- parallel 0 -qmin 4 -qmax 48 -b:v 365k ~66% 8.27x

FFmpeg 예는 다음과 같습니다.

ffmpeg -stream_loop 100 -i /home/id3as/Videos/120s_tears_of_steel_1080p.webm \
  -r 30 -g 90 -s 3840x2160 -quality realtime -speed 5 -threads 16 -row-mt 1 \
  -tile-columns 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 7800k -c:v vp9 \
  -b:a 128k -c:a libopus -f webm pipe1

도움말 및 유용한 정보

  • 여기서는 FFmpeg 명령어를 실행하기 전에 실행하기 전에 만들어야 하는 FIFO 파이프 ("pipe1")가 출력됩니다. 이렇게 하려면 작업 디렉터리에 mkfifo pipe1 명령어를 제공합니다. Shaka Packager를 사용하면 파이프가 지정된 스트림의 입력 소스로 수신 대기합니다. 다른 포장 모델의 경우 다른 방법이 필요할 수 있습니다.

  • -row-mt 명령어가 인식되도록 하려면 https://www.ffmpeg.org/download.html의 최신 안정화 버전인 FFmpeg (3.3.3)를 사용하세요.

적응형 비트 전송률 세트 예

FFmpeg 인코딩을 실행하는 시스템의 성능에 따라 다음과 같은 인코딩을 모두 제공하는 것이 가능할 수도 있고 가능하지 않을 수도 있으므로 자체 사용 가능한 리소스와 공유 대상 그룹에 적합한 하위 집합을 목록에서 선택해야 합니다.

FFmpeg 전체 ABR 세트

이상적인 시나리오에서는 이전 섹션에서 설명한 인코딩 예제를 결합하여 모든 명령어를 동시에 생성하는 단일 명령어를 만듭니다.

ffmpeg -stream_loop 100 -i lakes1080p.mp4 \
  -y -r 25 -g 75 -s 3840x2160 -quality realtime -speed 5 -threads 8 \
  -tile-columns 2 -frame-parallel 1 \
  -b:v 7800k -c:v vp9 -b:a 196k -c:a libopus -f webm pipe1 \
  -y -r 25 -g 75 -s 2560x1440 -quality realtime -speed 5 -threads 8 \
  -tile-columns 2 -frame-parallel 1 \
  -b:v 6000k -c:v vp9 -b:a 196k -c:a libopus -f webm pipe2 \
  -y -r 25 -g 75 -s 1920x1080 -quality realtime -speed 5 -threads 4 \
  -tile-columns 2 -frame-parallel 1 \
  -b:v 4500k -c:v vp9 -b:a 196k -c:a libopus -f webm pipe3 \
  -y -r 25 -g 75 -s 1280x720 -quality realtime -speed 5 -threads 4 \
  -tile-columns 2 -frame-parallel 1 \
  -b:v 3000k -c:v vp9 -b:a 196k -c:a libopus -f webm pipe4 \
  -y -r 25 -g 75 -s 854x480 -quality realtime -speed 6 -threads 4 \
  -tile-columns 2 -frame-parallel 1 \
  -b:v 2000k -c:v vp9 -b:a 196k -c:a libopus -f webm pipe5 \
  -y -r 25 -g 75 -s 640x360 -quality realtime -speed 7 -threads 2 \
  -tile-columns 1 -frame-parallel 0 \
  -b:v 730k -c:v vp9 -b:a 128k -c:a libopus -f webm pipe6 \
  -y -r 25 -g 75 -s 426x240 -quality realtime -speed 8 -threads 2 \
  -tile-columns 1 -frame-parallel 0 \
  -b:v 365k -c:v vp9 -b:a 64k -c:a libopus -f webm pipe7

그러나 위의 전체 세트에는 매우 강력한 CPU가 필요하거나 일부 칩셋이 점점 더 많이 제공되는 등의 하드웨어 GPU 오프로드 지원이 필요할 수도 있습니다. Intel Kabylake 이상은 완전한 하드웨어 인코딩 파이프라인을 갖추고 있습니다. Kabylake GPU는 8비트 VP9 인코딩을 수행할 수 있지만 10비트는 수행할 수 없습니다.

Shaka Packager를 사용한 실제 데스크톱의 예

일반적인 데스크톱 머신의 실제 예로는 Shaka Packager가 사용될 수 있습니다. Shaka를 설정하는 간단한 방법은 Google의 DockerHub 이미지를 사용하여 Docker 컨테이너 내에 설치하는 것입니다. 안내는 다음 페이지에서 확인하세요.

https://github.com/google/shaka-packager#using-docker-for-testing--development

이 예에서는 다음과 같은 구성이 있는 머신을 사용했습니다.

시스템 호스트: obs 커널: 4.4.0-91-lowlatency x86_64 (64비트)
데스크톱 Xfce 4.12.3 Distro: OS: https://ubuntustudio.org/2016/10/ubuntu-studio-16-10-released/
CPU 쿼드 코어 Intel Core i5-6500 (-MCP-)
캐시: 6144KB
클록 속도: 3,600MHz 1: 800MHz 2: 800MHz 3: 800MHz 4: 800MHz
그래픽 카드 Intel Skylake 통합 그래픽
메모리 8GB RAM

실제로 이 머신은 사용 가능한 ABR 인코딩 범위를 최적으로 생성할 수 있으며, FFmpeg는 지속적으로 1배의 인코딩 속도를 보고합니다.

ffmpeg -stream_loop 100 -i 120s_tears_of_steel_1080p.webm \
  -y -r 30 -g 90 -s 1920x1080 -quality realtime -speed 7 -threads 8 \
  -row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 \
  -b:v 4500k -c:v vp9 -b:a 128k -c:a libopus -f webm pipe1 \
  -y -r 30 -g 90 -s 1280x720 -quality realtime -speed 8 -threads 6 \
  -row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 \
  -b:v 3000k -c:v vp9 -b:a 128k -c:a libopus -f webm pipe2 \
  -y -r 30 -g 90 -s 640x360 -quality realtime -speed 8 -threads 2 \
  -row-mt 1 -tile-columns 1 -frame-parallel 1 -qmin 4 -qmax 48 \
  -b:v 730k -c:v vp9 -b:a 128k -c:a libopus -f webm pipe3

-speed 설정이 매우 높다는 점에 유의하세요. 이 설정은 실험용으로 설정되었으며 머신마다 다릅니다.

Shaka Packager 오버헤드

패키징은 특히 CPU를 많이 사용하는 활동이 아닙니다. 일부 하위 집합만 FFmpeg에서 전달하더라도 Shaka Packager가 모든 출력을 수신 대기하도록 설정할 수 있습니다. 다음은 위에서 설명한 시스템에서 테스트되는 패키지 프로그램 설정입니다.

packager \
  in=pipe1,stream=audio,init_segment=livehd-audio-1080.webm,segment_template=livehd-audio-1080-\$Number\$.webm \
  in=pipe1,stream=video,init_segment=livehd-video-1080.webm,template=livehd-video-1080-\$Number\$.webm \
  in=pipe2,stream=audio,init_segment=livehd-audio-720.webm,segment_template=livehd-audio-720-\$Number\$.webm \
  in=pipe2,stream=video,init_segment=livehd-video-720.webm,template=livehd-video-720-\$Number\$.webm \
  in=pipe3,stream=audio,init_segment=livehd-audio-360.webm,segment_template=livehd-audio-360-\$Number\$.webm \
  in=pipe3,stream=video,init_segment=livehd-video-360.webm,template=livehd-video-360-\$Number\$.webm \
  --mpd_output livehd.mpd --dump_stream_info --min_buffer_time=10 --time_shift_buffer_depth=300 \
  --segment_duration=3 --io_block_size 65536