Kodowanie VP9 z użyciem FFmpeg

Parametry kodowania

VP9 udostępnia wiele parametrów do optymalizacji kodowania na żywo. Kilka ogólnych zasad znajdziesz w trybie szybkości transmisji bitów.

Przykład kodowania FFmpeg VP9

Tabela poniżej zawiera opis parametrów wywołania ffmpeg w kodowaniu VP9.

Parametr Opis
-quality realtime realtime to klucz do transmitowania na żywo i szybkości powyżej 5.
-speed 6 Do kodowania transmisji na żywo lub w czasie rzeczywistym należy używać szybkości od 5 do 8. Niższe liczby (5 lub 6) są wyższej jakości, ale wymagają większej mocy procesora. Wyższe liczby (7 lub 8) będą mieć niższą jakość, ale będą łatwiejsze do zarządzania w przypadkach o mniejszym czasie oczekiwania, a także w przypadku mniejszych procesorów, takich jak urządzenia mobilne.
-tile-columns 4 Tile dzieli film na prostokątne regiony, co umożliwia wielowątkowość w kodowaniu i dekodowaniu. Liczba kafelków jest zawsze 2. 0 = 1 kafelek, 1 = 2, 2 = 4, 3 = 8, 4 = 16, 5 = 32.
-frame-parallel 1 Włącza równoległe funkcje decydowania.
-threads 8 Maksymalna liczba wątków do użycia.
-static-thresh 0 Próg wykrywania ruchu.
-max-intra-rate 300 Maksymalna szybkość transmisji i-Frame (pct)
-deadline realtime Alternatywna (starsza wersja) -quality realtime
-lag-in-frames 0 Maksymalna liczba klatek do opóźnienia
-qmin 4 -qmax 48 Minimalne i maksymalne wartości kwantyzatora. Przedstawione tu wartości to tylko sugestia, a to poprawienie lub obniżenie jakości wideo kosztem kosztu kompresji.
-row-mt 1 Włącz wielowierszowy wątek. Zezwala na używanie maksymalnie 2 wątków jako kolumn kafelkowych. 0 = wyłączone, 1 = włączone.
-error-resilient 1 Włącz funkcje odporności błędów.

Wybór parametrów kodowania

W przypadku poniższych informacji używane jest stałe kodowanie szybkości transmisji bitów (CBR) w przypadku strumieniowego przesyłania na żywo z adaptacyjną szybkością transmisji (ABR), gdzie każda wartość docelowa jest wyraźnie określona w pliku manifestu pakietu. W efekcie klient uzyska lepszą stawkę. Możesz też użyć kodowania VBR i QQ, jeśli szybkość transmisji bitów jest bardziej elastyczna lub kodowanie jest podzielone na fragmenty. Tryb Q ma problemy z kodowaniem w czasie rzeczywistym, które jest wymagane w przypadku transmisji na żywo. Więcej informacji znajdziesz w sekcji Tryby szybkości transmisji bitów.

Więcej informacji o tym, jak manipulować kodem VP9, znajdziesz też w odpowiednim artykule w sekcji o ustawieniach VOD. Pamiętaj jednak, że jego głównym tematem jest CBR.

Porady i wskazówki

Pamiętaj, że w przypadku transmisji na żywo wszystko jest ograniczone do minimalnej szybkości kodowania 1x w czasie rzeczywistym (FFmpeg zgłasza szybkość kodowania w miarę jej postępów). Jeśli szybkość kodowania spadnie poniżej 1x, oznacza to, że proces kodowania nie nadąża za przesyłaniem wideo na żywo, a w trakcie transmisji wystąpi buforowanie, a przerwy w transmisji staną się bezużyteczne podczas transmisji na żywo.

Przykłady parametrów kodowania w działaniu

Poniżej znajdziesz informacje o wykorzystaniu procesora przez 25 klatek na sekundę przy różnych rozmiarach klatek w procesorze czterordzeniowym i5 3,6 GHz na komputerze z Linuksem:

Rozwiązanie docelowe FFmpeg – parametry VP9 CPU / Szybkość (przykład)
3840x2160 (2160p) -r 30 -g 90 -s 3840x2160 -jakość w czasie rzeczywistym -speed 5 -wątki 16 -wiersz-mt 1 -kolumny-kolumny 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 7800k ~88% 0,39x
2560x1440 (1440p) -r 30 -g 90 -s 2560x1440 -jakość w czasie rzeczywistym -prędkość 5 -wątki 16 -wiersz-mt 1 -kolumny-kolumny 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 6000k ~86% 0,68x
1920x1080 (1080p) -r 30 -g 90 -s 1920 x 1080 -jakość w czasie rzeczywistym -speed 5 -wątki 8 -row-mt 1 -til-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 4500k ~82% 1,04x
1280x720 (720p) -r 30 -g 90 -s 1280x720 -jakość w czasie rzeczywistym -speed 5 -wątków 8 -row-mt 1 -til-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 3000k ~78% 1,77x
854x480 (480p) -r 30 -g 90 -s 854x480 -jakość w czasie rzeczywistym -speed 6 -threads 4 -row-mt 1 -table-columns 1 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 1800k ok.64% 3,51x
640x360 (360p) -r 30 -g 90 -s 640x360 -jakość w czasie rzeczywistym -speed 7 -threads 4 -row-mt 1 -table-columns 1 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 730k ok.62% 5,27x
426x240 (240p) -r 30 -g 90 -s 426x240 -jakość w czasie rzeczywistym -speed 8 -wątków 2 -row-mt 1 -table-columns 0 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 365k ok.66% 8,27x

Przykładowy plik FFmpeg może wyglądać tak:

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

Porady i wskazówki

  • W tym przypadku zapisujemy dane w potoku FIFO ("pipe1"), które należy utworzyć przed uruchomieniem polecenia FFmpeg. Aby to zrobić, wpisz polecenie mkfifo pipe1 w katalogu roboczym. Jeżeli korzystasz z narzędzia Shaka Packager, zostanie ono użyte jako źródło wejściowe dla określonego strumienia. Inne modele opakowań mogą wymagać innej metody.

  • Aby mieć pewność, że polecenia -row-mt będą rozpoznawane, użyj najnowszej stabilnej wersji FFmpeg (obecnie 3.3.3) dostępnej na https://www.ffmpeg.org/download.html

Przykładowy ustawiony zestaw adaptacyjnych szybkości transmisji bitów

W zależności od mocy maszyny, na której działa kodowanie FFmpeg, może być lub nie być możliwe dostarczanie wszystkich poniższych kodowań naraz, dlatego podzbiór zgodny z własnymi zasobami dostępnymi i grupami odbiorców powinien być wybrany z listy.

Pełny zestaw ABR FFmpeg

W idealnym przypadku łączymy przykłady kodowania opisane w poprzedniej sekcji, aby utworzyć jedno polecenie, które generuje wszystkie wartości w tym samym czasie:

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

Powyższy zestaw będzie jednak wymagać bardzo wydajnego procesora lub obsługi sprzętowej przeładowania GPU, np. niektórych chipsetów. Intel Kabylake (i nowsze) ma pełny procesor kodowania. Pamiętaj, że GPU Kabylake obsługuje 8-bitowe kodowanie VP9, ale nie 10-bitowe.

Praktyczny przykład aplikacji Shaka Packager

Bardziej praktycznym przykładem na typowe komputery jest użycie Shaka Packager. Prostym sposobem skonfigurowania Shaki jest zainstalowanie go w kontenerze Dockera za pomocą obrazu Google Dockera. Instrukcje znajdziesz tutaj:

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

W tym przykładzie użyliśmy komputera z tą konfiguracją:

System Host: obserw jądra: 4.4.0-91-lowlatency x86_64 (64-bitowy)
Komputer Xfce 4.12.3 Distro: OS: https://ubuntustudio.org/2016/10/ubuntu-studio-16-10-released/
CPU Czterordzeniowy Intel Core i5-6500 (-MCP-)
cache: 6144 KB
Zegary: maks. 3600 MHz 1: 800 MHz 2: 800 MHz 3: 800 MHz 4: 800 MHz
Karta graficzna Zintegrowana grafika Intel Skylake
Pamięć 8GB RAM

W praktyce maszyna może optymalnie wykorzystać ten zakres kodów ABR, przy czym system FFmpeg regularnie zgłasza szybkość kodowania 1x:

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

Ustawienia elementu -speed są dość wysokie. Te ustawienia zostały ustalone eksperymentalnie i różnią się w zależności od komputera.

Narzut Shaka Packager

Opakowanie nie jest szczególnie obciążające procesor. Program Shaka Packager może wychwycić wszystkie dane wyjściowe, nawet jeśli tylko podzbiór jest dostarczany przez FFmpeg. Te ustawienia pakowania są testowane na komputerze opisanym powyżej:

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