Kodowanie na żywo w VP9 za pomocą FFmpeg
Parametry kodowania
VP9 udostępnia szereg parametrów do optymalizacji kodowania na żywo. Niektóre ogólne zasady dotyczące tych trybów są omówione w sekcji Tryby szybkości transmisji.
Przykład kodowania w FFmpeg w formacie VP9
W tabeli poniżej opisano parametry przykładowego wywołania ffmpeg
w przypadku kodowania VP9.
Parametr | Opis |
---|---|
-quality realtime |
realtime jest niezbędne w przypadku transmisji na żywo i prędkości powyżej 5 . |
-speed 6 |
Szybkość 5 do 8 powinna być używana w przypadku kodowania na żywo lub w czasie rzeczywistym. Niższe liczby (5 lub 6 ) oznaczają wyższą jakość, ale wymagają większej mocy procesora. Wyższe wartości (7 lub 8 ) będą oznaczać niższą jakość, ale będą łatwiejsze w obsłudze w przypadku zastosowań wymagających mniejszego opóźnienia, a także w przypadku urządzeń o mniejszej mocy procesora, takich jak urządzenia mobilne. |
-tile-columns 4 |
Dzielenie na kafelki dzieli film na prostokątne regiony, co umożliwia wielowątkowość podczas kodowania i dekodowania. Liczba kafelków jest zawsze potęgą liczby 2. 0 = 1 kafelek, 1 = 2, 2 = 4, 3 = 8, 4 = 16, 5 = 32. |
-frame-parallel 1 |
Włącz funkcje dekodowania równoległego. |
-threads 8 |
Maksymalna liczba wątków do użycia. |
-static-thresh 0 |
Próg wykrywania ruchu. |
-max-intra-rate 300 |
Maksymalna szybkość transmisji bitów klatki I (w procentach) |
-deadline realtime |
Wersja alternatywna (starsza) -quality realtime |
-lag-in-frames 0 |
Maksymalna liczba opóźnionych klatek |
-qmin 4 -qmax 48 |
Wartości minimalne i maksymalne kwantyzatora. Wartości te są jedynie sugestią, a ich dostosowanie pomoże zwiększyć lub zmniejszyć jakość filmu kosztem wydajności kompresji. |
-row-mt 1 |
Włącz wielowątkowość wierszy. Umożliwia używanie maksymalnie 2 wątków jako kolumn kafelków. 0 = wyłączone, 1 = włączone. |
-error-resilient 1 |
Włącz funkcje odporności na błędy. |
Wybieranie parametrów kodowania
Poniższe informacje dotyczą kodowania ze stałą szybkością transmisji bitów (CBR) w przypadku adaptacyjnej transmisji strumieniowej ze zmienną szybkością transmisji bitów (ABR), gdzie każda docelowa szybkość transmisji jest jawnie ustawiona w pliku manifestu pakietu. Umożliwi to klientom płynniejsze przełączanie się między stawkami. Kodowanie ze zmienną szybkością transmisji bitów (VBR) i tryb CQ są również opcjami, jeśli szybkość transmisji bitów może być bardziej elastyczna lub kodowanie jest dzielone na części. Tryb Q będzie mieć problemy z kodowaniem w czasie rzeczywistym, które jest wymagane w przypadku filmów na żywo. Więcej informacji znajdziesz w sekcji Tryby szybkości transmisji.
Więcej informacji o manipulowaniu VP9 znajdziesz w artykule o ustawieniach VOD, ale pamiętaj, że skupiamy się na CBR.
Porady i wskazówki
Pamiętaj, że podczas transmisji na żywo wszystko jest ograniczone do minimalnej prędkości kodowania w czasie rzeczywistym wynoszącej 1x (FFmpeg raportuje prędkość kodowania w miarę postępów). Jeśli szybkość kodowania spadnie poniżej 1x, proces kodowania nie będzie nadążać za wejściem wideo na żywo, a użytkownicy będą doświadczać buforowania i przerw w transmisji, co sprawi, że strumień będzie bezużyteczny podczas transmisji na żywo (chociaż archiwum będzie ogólnie użyteczne).
Przykłady działania parametrów kodowania
Poniżej przedstawiono wykorzystanie procesora przy 25 kl./s w przypadku różnych rozmiarów klatek na komputerze stacjonarnym z 4-rdzeniowym procesorem i5 3,6 GHz z systemem Linux:
Rozdzielczość docelowa | Parametry FFmpeg VP9 | Procesor / szybkość (przykład) |
---|---|---|
3840x2160 (2160p) | -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 | ~88% 0,39x |
2560 x 1440 (1440p) | -r 30 -g 90 -s 2560x1440 -quality realtime -speed 5 -threads 16 -row-mt 1 -tile-columns 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 6000k | ~86% 0,68x |
1920 x 1080 (1080p) | -r 30 -g 90 -s 1920x1080 -quality realtime -speed 5 -threads 8 -row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 4500k | ~82% 1,04x |
1280 x 720 (720p) | -r 30 -g 90 -s 1280x720 -quality realtime -speed 5 -threads 8 -row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 3000k | ~78% 1,77x |
854 x 480 (480p) | -r 30 -g 90 -s 854x480 -quality realtime -speed 6 -threads 4 -row-mt 1 -tile-columns 1 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 1800k | ~64% 3,51x |
640 x 360 (360p) | -r 30 -g 90 -s 640x360 -quality realtime -speed 7 -threads 4 -row-mt 1 -tile-columns 1 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 730k | ~62% 5.27x |
426 x 240 (240p) | -r 30 -g 90 -s 426x240 -quality realtime -speed 8 -threads 2 -row-mt 1 -tile-columns 0 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 365k | ~66% 8,27x |
Przykładowe polecenie 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 libvpx-vp9 \
-b:a 128k -c:a libopus -f webm pipe1
Porady i wskazówki
Pamiętaj, że w tym przypadku dane wyjściowe są kierowane do potoku FIFO („pipe1”), który należy utworzyć przed wykonaniem polecenia FFmpeg. Aby to zrobić, w katalogu roboczym wpisz polecenie
mkfifo pipe1
. Jeśli używasz Shaka Packagera, będzie on nasłuchiwać tego potoku jako źródła wejściowego dla danego strumienia. Inne modele pakowania mogą wymagać innej metody.Aby polecenia
-row-mt
były rozpoznawane, używaj najnowszej stabilnej wersji FFmpeg (obecnie 3.3.3) dostępnej na stronie https://www.ffmpeg.org/download.html.
Przykładowy zestaw adaptacyjnej szybkości transmisji bitów
W zależności od mocy urządzenia, na którym działa kodowanie FFmpeg, może być możliwe lub niemożliwe dostarczenie wszystkich poniższych kodowań w tym samym czasie, dlatego z listy należy wybrać podzbiór odpowiedni dla dostępnych zasobów i odbiorców docelowych.
Pełny zestaw ABR FFmpeg
W idealnym scenariuszu połączymy przykłady kodowania opisane w poprzedniej sekcji, aby utworzyć jedno polecenie, które wygeneruje je wszystkie jednocześnie:
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 libvpx-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 libvpx-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 libvpx-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 libvpx-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 libvpx-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 libvpx-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 libvpx-vp9 -b:a 64k -c:a libopus -f webm pipe7
Powyższy pełny zestaw będzie jednak wymagał bardzo wydajnego procesora lub ewentualnie obsługi sprzętowego odciążania GPU, które jest coraz częściej dostępne w niektórych chipsetach. Procesory Intel Kabylake (i nowsze) mają pełną ścieżkę kodowania sprzętowego. (Pamiętaj, że układ GPU Kabylake może kodować 8-bitowy format VP9, ale nie 10-bitowy).
Praktyczny przykład na komputerze z użyciem Shaka Packager
Bardziej praktyczny przykład dla typowych komputerów stacjonarnych może wykorzystywać Shaka Packager. Prostym sposobem na skonfigurowanie Shaki jest zainstalowanie jej w kontenerze Dockera przy użyciu obrazu Google DockerHub. Instrukcje znajdziesz tutaj:
https://github.com/google/shaka-packager#using-docker-for-testing--development
W tym przykładzie użyliśmy urządzenia o tej konfiguracji:
System | Host: obs Kernel: 4.4.0-91-lowlatency x86_64 (64 bit) |
Komputer | Xfce 4.12.3 Distro: OS: https://ubuntustudio.org/2016/10/ubuntu-studio-16-10-released/ |
CPU | 4-rdzeniowy procesor Intel Core i5-6500 (-MCP-) pamięć podręczna: 6144 KB taktowanie: maks. 3600 MHz 1: 800 MHz 2: 800 MHz 3: 800 MHz 4: 800 MHz |
Karta graficzna | Zintegrowana karta graficzna Intel Skylake |
Pamięć | 8 GB pamięci RAM |
W praktyce ta maszyna może optymalnie generować ten zakres kodowań ABR, a FFmpeg będzie stale 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 libvpx-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 libvpx-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 libvpx-vp9 -b:a 128k -c:a libopus -f webm pipe3
Pamiętaj, że ustawienia -speed
są dość wysokie. Te ustawienia zostały ustalone eksperymentalnie i będą się różnić w zależności od urządzenia.
Narzut Shaka Packager
Pakowanie nie jest szczególnie wymagające pod względem mocy obliczeniowej procesora. Shaka Packager może nasłuchiwać wszystkich danych wyjściowych, nawet jeśli FFmpeg dostarcza tylko ich podzbiór. Oto ustawienia pakietu testowane na opisanym powyżej urządzeniu:
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