Encoding live dengan VP9 menggunakan FFmpeg

Parameter encoding

VP9 menyediakan berbagai parameter untuk mengoptimalkan encoding live. Beberapa prinsip umum ini dibahas dalam Mode Bitrate.

Contoh encoding VP9 FFmpeg

Tabel di bawah menjelaskan parameter contoh panggilan ffmpeg untuk encoding VP9.

Parameter Deskripsi
-quality realtime realtime sangat penting untuk live streaming dan untuk kecepatan di atas 5.
-speed 6 Kecepatan 5 hingga 8 harus digunakan untuk encoding live / real-time. Angka yang lebih rendah (5 atau 6) memiliki kualitas lebih tinggi, tetapi memerlukan daya CPU yang lebih besar. Angka yang lebih tinggi (7 atau 8) akan memiliki kualitas yang lebih rendah, tetapi lebih mudah dikelola untuk kasus penggunaan latensi yang lebih rendah dan juga untuk perangkat dengan daya CPU yang lebih rendah seperti perangkat seluler.
-tile-columns 4 Pengubinan membagi video menjadi beberapa wilayah persegi panjang, yang memungkinkan multi-threading untuk encoding dan decoding. Jumlah petak selalu merupakan pangkat dua. 0 = 1 petak, 1 = 2, 2 = 4, 3 = 8, 4 = 16, 5 = 32.
-frame-parallel 1 Aktifkan fitur kemampuan dekode paralel.
-threads 8 Jumlah maksimum thread yang akan digunakan.
-static-thresh 0 Batas deteksi gerakan.
-max-intra-rate 300 Kecepatan bit i-Frame maksimum (pct)
-deadline realtime Versi alternatif (lama) -quality realtime
-lag-in-frames 0 Jumlah maksimum frame yang tertinggal
-qmin 4 -qmax 48 Nilai minimum dan maksimum untuk penguantisasi. Nilai di sini hanyalah saran dan penyesuaian ini akan membantu meningkatkan/menurunkan kualitas video dengan mengorbankan efisiensi kompresi.
-row-mt 1 Aktifkan multithreading baris. Memungkinkan penggunaan hingga 2x thread sebagai kolom petak. 0 = nonaktif, 1 = aktif.
-error-resilient 1 Aktifkan fitur ketahanan error.

Memilih parameter encoding

Informasi di bawah menggunakan encoding kecepatan bit konstan (CBR) untuk streaming kecepatan bit adaptif (ABR) live, dengan setiap kecepatan target ditetapkan secara eksplisit dalam manifes packager. Hal ini akan menghasilkan "pengalihan" tarif yang lebih bersih untuk klien. Encoding kecepatan bit variabel (VBR) dan mode CQ juga merupakan opsi jika kecepatan bit dapat lebih fleksibel atau encoding sedang di-chunk. Mode Q akan bermasalah dengan encoding real-time yang diperlukan untuk video live. Lihat Mode Bitrate untuk mengetahui informasi selengkapnya.

Untuk mengetahui detail lebih lanjut tentang cara memanipulasi VP9, sebaiknya baca juga artikel terkait tentang setelan VOD, tetapi dengan mempertimbangkan fokus pada CBR.

Tips dan trik

Ingatlah bahwa saat melakukan live streaming, semuanya dibatasi pada kecepatan encoding real-time minimum 1x (FFmpeg melaporkan kecepatan encoding saat berlangsung). Jika kecepatan encoding Anda turun di bawah 1x, proses encoding tidak akan dapat mengimbangi input video live, dan pengguna akan mengalami buffering, serta gangguan dalam transmisi akan membuat streaming tidak dapat digunakan selama siaran live (meskipun arsipnya umumnya dapat digunakan).

Contoh parameter encoding yang sedang digunakan

Berikut menunjukkan pemakaian CPU pada 25 fps untuk berbagai ukuran frame di desktop quad-core i5 3,6 GHz yang menjalankan Linux:

Resolusi Target Parameter VP9 FFmpeg CPU / Kecepatan (contoh)
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
2560x1440 (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
1920x1080 (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
1280x720 (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
854x480 (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
640x360 (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
426x240 (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

Contoh FFmpeg mungkin terlihat seperti ini:

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

Tips dan trik

  • Perhatikan bahwa di sini kita melakukan output ke saluran FIFO ("pipe1"), yang harus dibuat sebelum eksekusi, sebelum menjalankan perintah FFmpeg. Untuk melakukannya, berikan perintah mkfifo pipe1 di direktori kerja Anda. Saat menggunakan Shaka Packager, aplikasi ini akan memproses pipe tersebut sebagai sumber input untuk streaming yang diberikan. Model kemasan lain mungkin memerlukan metode yang berbeda.

  • Untuk memastikan perintah -row-mt dikenali, gunakan rilis stabil FFmpeg terbaru (saat ini 3.3.3) dari https://www.ffmpeg.org/download.html

Contoh set kecepatan bit adaptif

Bergantung pada kemampuan mesin yang menjalankan encoding FFmpeg, semua encoding berikut mungkin dapat atau tidak dapat dikirimkan secara bersamaan, jadi subset yang sesuai dengan target audiens dan sumber daya yang tersedia harus dipilih dari daftar.

Set ABR lengkap FFmpeg

Dalam skenario ideal, kita menggabungkan contoh encoding yang diuraikan di bagian sebelumnya untuk membuat satu perintah yang menghasilkan semuanya secara bersamaan:

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

Namun, set lengkap di atas akan memerlukan CPU yang sangat canggih, atau mungkin dukungan dari pelepasan GPU hardware seperti yang semakin banyak disediakan oleh beberapa chipset. Intel Kabylake (dan yang lebih baru) memiliki pipeline encoding hardware penuh. (Perhatikan bahwa GPU Kabylake dapat melakukan encoding VP9 8-bit, tetapi tidak 10-bit).

Contoh desktop praktis menggunakan Shaka Packager

Contoh yang lebih praktis untuk mesin desktop umum mungkin menggunakan Shaka Packager. Cara sederhana untuk menyiapkan Shaka adalah dengan menginstalnya dalam container Docker, menggunakan image DockerHub Google. Petunjuknya dapat ditemukan di sini:

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

Untuk contoh ini, kami menggunakan mesin dengan konfigurasi berikut:

Sistem Host: obs Kernel: 4.4.0-91-lowlatency x86_64 (64 bit)
Desktop Xfce 4.12.3 Distro: OS: https://ubuntustudio.org/2016/10/ubuntu-studio-16-10-released/
CPU Cache Intel Core i5-6500 (-MCP-) quad core: 6144 KB kecepatan clock: maks: 3600 MHz 1: 800 MHz 2: 800 MHz 3: 800 MHz 4: 800 MHz

Kartu Grafis Grafis terintegrasi Intel Skylake
Memori RAM 8 GB

Pada praktiknya, mesin ini dapat menghasilkan rentang encoding ABR yang dapat digunakan berikut secara optimal, dengan FFmpeg secara konsisten melaporkan kecepatan encoding 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

Perhatikan bahwa setelan -speed cukup tinggi. Setelan ini ditetapkan secara eksperimental dan akan bervariasi dari satu mesin ke mesin lainnya.

Overhead Shaka Packager

Pengemasan bukanlah aktivitas yang terlalu banyak menggunakan CPU. Shaka Packager dapat disetel untuk memproses semua output, meskipun hanya sebagian kecil yang dikirimkan oleh FFmpeg. Berikut adalah setelan pengemasan yang diuji pada mesin yang diuraikan di atas:

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