การเข้ารหัสสดด้วย VP9 โดยใช้ FFmpeg

พารามิเตอร์การเข้ารหัส

VP9 มีพารามิเตอร์หลายอย่างเพื่อเพิ่มประสิทธิภาพการเข้ารหัสไลฟ์สด โหมดบิตเรตจะอธิบายหลักการกว้างๆ บางอย่างของโหมดเหล่านี้

ตัวอย่างการเข้ารหัส VP9 ด้วย FFmpeg

ตารางด้านล่างอธิบายพารามิเตอร์ของตัวอย่างการเรียก ffmpeg สำหรับการเข้ารหัส VP9

พารามิเตอร์ คำอธิบาย
-quality realtime realtime เป็นสิ่งจำเป็นสำหรับการไลฟ์สดและความเร็วที่สูงกว่า 5
-speed 6 ควรใช้ความเร็ว 5 ถึง 8 สำหรับการเข้ารหัสแบบสด / เรียลไทม์ ตัวเลขที่ต่ำกว่า (5 หรือ 6) จะมีคุณภาพสูงกว่า แต่ต้องใช้พลัง CPU มากกว่า ตัวเลขที่สูงขึ้น (7 หรือ 8) จะมีคุณภาพต่ำกว่า แต่จัดการได้ง่ายกว่าสำหรับ Use Case ที่มีเวลาในการตอบสนองต่ำ และสำหรับอุปกรณ์ที่มีกำลัง CPU ต่ำกว่า เช่น อุปกรณ์เคลื่อนที่
-tile-columns 4 การแบ่งวิดีโอออกเป็นส่วนๆ จะแบ่งวิดีโอออกเป็นส่วนสี่เหลี่ยม ซึ่งช่วยให้ใช้การทำงานแบบหลายเธรดในการเข้ารหัสและถอดรหัสได้ จำนวนไทล์จะเป็นเลขยกกำลังของ 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 สูงสุด (เปอร์เซ็นต์)
-deadline realtime -quality realtime เวอร์ชันอื่น (เดิม)
-lag-in-frames 0 จำนวนเฟรมสูงสุดที่จะหน่วง
-qmin 4 -qmax 48 ค่าต่ำสุดและสูงสุดสำหรับตัวหาปริมาณ ค่าที่ระบุไว้ที่นี่เป็นเพียงคำแนะนำ และการปรับค่านี้จะช่วยเพิ่ม/ลดคุณภาพวิดีโอโดยแลกกับการลดประสิทธิภาพการบีบอัด
-row-mt 1 เปิดใช้การทำงานแบบมัลติเธรดระดับแถว อนุญาตให้ใช้เธรดสูงสุด 2 เท่าเป็นคอลัมน์ไทล์ 0 = ปิด, 1 = เปิด
-error-resilient 1 เปิดใช้ฟีเจอร์ความยืดหยุ่นต่อข้อผิดพลาด

การเลือกพารามิเตอร์การเข้ารหัส

ข้อมูลด้านล่างใช้การเข้ารหัสอัตราบิตคงที่ (CBR) สำหรับการสตรีมแบบปรับอัตราบิต (ABR) แบบเรียลไทม์ ซึ่งมีการตั้งค่าอัตราเป้าหมายแต่ละรายการอย่างชัดเจนในไฟล์ Manifest ของโปรแกรมแพ็กเกจ ซึ่งจะช่วยให้ "การสลับ" ระหว่างราคาสำหรับลูกค้า ราบรื่นขึ้น การเข้ารหัสอัตราบิตแบบแปรผัน (VBR) และโหมด CQ ก็เป็นอีกตัวเลือกหนึ่งหากอัตราบิตมีความยืดหยุ่นมากขึ้นหรือการเข้ารหัสถูกแบ่งออกเป็นหลายๆ ส่วน โหมด Q จะ มีปัญหาในการเข้ารหัสแบบเรียลไทม์ที่จำเป็นสำหรับวิดีโอสด ดูข้อมูลเพิ่มเติมได้ที่โหมดบิตเรต

ดูรายละเอียดเพิ่มเติมเกี่ยวกับวิธีจัดการ VP9 ได้ในบทความที่เกี่ยวข้องเกี่ยวกับการตั้งค่า VOD โดยคำนึงถึงการมุ่งเน้นที่ CBR

กลเม็ดเคล็ดลับ

โปรดทราบว่าเมื่อไลฟ์สด ทุกอย่างจะถูกจำกัดให้มีความเร็วในการเข้ารหัสแบบเรียลไทม์ขั้นต่ำที่ 1 เท่า (FFmpeg จะรายงานความเร็วในการเข้ารหัสเมื่อดำเนินการ) หากความเร็วในการเข้ารหัสลดลงต่ำกว่า 1 เท่า กระบวนการเข้ารหัสจะไม่ทัน อินพุตของวิดีโอสด ผู้ใช้จะพบปัญหาการบัฟเฟอร์ และการหยุดชะงัก ในการส่งจะทำให้สตรีมใช้งานไม่ได้ในระหว่างการถ่ายทอดสด (แม้ว่าโดยทั่วไปแล้วที่เก็บถาวรจะใช้งานได้)

ตัวอย่างพารามิเตอร์การเข้ารหัสในการทำงาน

ต่อไปนี้แสดงการใช้ CPU ที่ 25 FPS สำหรับขนาดเฟรมต่างๆ บนเดสก์ท็อป quad-core i5 3.6Ghz ที่ใช้ Linux

การแก้ปัญหาเป้าหมาย พารามิเตอร์ VP9 ของ FFmpeg CPU / ความเร็ว (ตัวอย่าง)
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.68 เท่า
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

ตัวอย่าง 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 libvpx-vp9 \
  -b:a 128k -c:a libopus -f webm pipe1

กลเม็ดเคล็ดลับ

  • โปรดทราบว่าที่นี่เราจะส่งเอาต์พุตไปยังไปป์ FIFO ("pipe1") ซึ่งควร สร้างก่อนดำเนินการ ก่อนที่จะเรียกใช้คำสั่ง FFmpeg โดยให้ป้อนคำสั่ง mkfifo pipe1 ในไดเรกทอรีที่ทำงานอยู่ เมื่อใช้ Shaka Packager ระบบจะฟังไปป์นั้นเป็นแหล่งที่มาของอินพุตสำหรับสตรีมที่ระบุ โมเดลการแพ็กเกจอื่นๆ อาจต้องใช้วิธีการที่แตกต่างกัน

  • เพื่อให้ระบบจดจำคำสั่ง -row-mt ได้ ให้ใช้ FFmpeg เวอร์ชันล่าสุดที่เสถียร (ปัจจุบันคือ 3.3.3) จาก https://www.ffmpeg.org/download.html

ตัวอย่างชุดอัตราบิตแบบปรับขนาดได้

ความสามารถของเครื่องที่ใช้เรียกใช้การเข้ารหัส FFmpeg อาจทำให้คุณส่งการเข้ารหัสทั้งหมดต่อไปนี้พร้อมกันได้หรือไม่ได้ ดังนั้นคุณควรเลือกชุดย่อยที่เหมาะกับทรัพยากรที่มีอยู่และกลุ่มเป้าหมายของคุณเองจากรายการ

ชุด ABR แบบเต็มของ FFmpeg

ในสถานการณ์ที่เหมาะสม เราจะรวมตัวอย่างการเข้ารหัสที่ระบุไว้ในส่วนก่อนหน้า เพื่อสร้างคำสั่งเดียวที่สร้างไฟล์ทั้งหมดพร้อมกัน

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

อย่างไรก็ตาม ชุดเต็มด้านบนจะต้องใช้ CPU ที่มีประสิทธิภาพสูงมาก หรืออาจต้อง รองรับการลดภาระงาน GPU ของฮาร์ดแวร์ เช่น ชิปเซ็ตบางรุ่นที่เพิ่มขึ้นเรื่อยๆ Intel Kabylake (และรุ่นที่ใหม่กว่า) มีไปป์ไลน์การเข้ารหัสฮาร์ดแวร์เต็มรูปแบบ (โปรดทราบว่า GPU Kabylake สามารถเข้ารหัส VP9 แบบ 8 บิตได้ แต่เข้ารหัสแบบ 10 บิตไม่ได้)

ตัวอย่างการใช้งานจริงบนเดสก์ท็อปโดยใช้ Shaka Packager

ตัวอย่างที่ใช้งานได้จริงมากกว่าสำหรับเครื่องเดสก์ท็อปทั่วไปอาจใช้ Shaka Packager วิธีง่ายๆ ในการตั้งค่า Shaka คือการติดตั้งภายในคอนเทนเนอร์ Docker โดยใช้ อิมเมจ DockerHub ของ Google ดูวิธีการได้ที่นี่

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 Quad core Intel Core i5-6500 (-MCP-)
แคช: 6144 KB
ความเร็วสัญญาณนาฬิกา: สูงสุด: 3600 MHz 1: 800 MHz 2: 800 MHz 3: 800 MHz 4: 800 MHz
กราฟิกการ์ด กราฟิก Intel Skylake แบบในตัว
หน่วยความจำ RAM 8 GB

ในทางปฏิบัติ เครื่องนี้อาจสร้างช่วง 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 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

โปรดทราบว่า-speedการตั้งค่าค่อนข้างสูง การตั้งค่าเหล่านี้สร้างขึ้น จากการทดลองและจะแตกต่างกันไปในแต่ละเครื่อง

ค่าใช้จ่ายเพิ่มเติมของ Shaka Packager

การแพ็กเกจไม่ใช่กิจกรรมที่ใช้ CPU มากนัก คุณตั้งค่า Shaka Packager ให้รอรับเอาต์พุตทั้งหมดได้ แม้ว่า FFmpeg จะส่งเฉพาะเอาต์พุตบางส่วนก็ตาม การตั้งค่าโปรแกรมสร้างแพ็กเกจที่ทดสอบในเครื่องที่ระบุไว้ข้างต้นมีดังนี้

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