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

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

VP9 มีพารามิเตอร์ที่หลากหลายเพื่อเพิ่มประสิทธิภาพการเข้ารหัสแบบสด หลักการสําคัญบางประการจะกล่าวถึงในโหมดอัตราบิต

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

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

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

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

ข้อมูลด้านล่างใช้การเข้ารหัสอัตราบิตคงที่ (CBR) สําหรับสตรีมมิงอัตราบิตแบบปรับขนาดได้ (ABR) ที่มีการตั้งค่าอัตราเป้าหมายแต่ละค่าอย่างชัดแจ้งในไฟล์ Manifest ของ Package&#39 ซึ่งจะส่งผลให้ราคาดูสะอาดตาขึ้นและสลับราคาระหว่างราคาสําหรับลูกค้า การเข้ารหัสอัตราบิตแปรผัน (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 -คุณภาพแบบเรียลไทม์ -ความเร็ว 5 -ชุดข้อความ 16 -row-mt 1 -การ์ด-คอลัมน์ 3 -เฟรม-ขนาน 1 -qmin 4 -qmax 48 -b:v 7800k ~88% 0.39 เท่า
2560x1440 (1440p) -r 30 -g 90 -s 2560x1440 -แบบเรียลไทม์ -ความเร็ว 5 -ชุดข้อความ 16 -row-mt 1 -การ์ด-คอลัมน์ 3 -เฟรม-ขนาน 1 -qmin 4 -qmax 48 -b:v 6000k ~66% 0.68 เท่า
1920x1080 (1080p) -r 30 -g 90 -s 1920x1080 -คุณภาพแบบเรียลไทม์ -ความเร็ว 5 -ชุดข้อความ 8 -row-mt 1 -ไทล์-คอลัมน์ 2 -เฟรมแบบขนาน 1 -qmin 4 -qmax 48 -b:v 4500k ราว 82% 1.04 เท่า
1280x720 (720p) -r 30 -g 90 -s 1280x720 -คุณภาพแบบเรียลไทม์ -ความเร็ว 5 -ชุดข้อความ 8 -row-mt 1 -การ์ด-คอลัมน์ 2 -เฟรม-ขนาน 1 -qmin 4 -qmax 48 -b:v 3000k ราว 78% 1.77 เท่า
854x480 (480p) -r 30 -g 90 -s 854x480 -คุณภาพแบบเรียลไทม์ -ความเร็ว 6 -ชุดข้อความ 4 -แถว-mt 1 -การ์ด-คอลัมน์ 1 -เฟรมขนาน 1 -qmin 4 -qmax 48 -b:v 1800k 34.31 เท่า
640x360 (360p) -r 30 -g 90 -s 640x360 -คุณภาพแบบเรียลไทม์ -ความเร็ว 7 -ชุดข้อความ 4 -แถว-mt 1 -การ์ด-คอลัมน์ 1 -เฟรมแบบขนาน 0 -qmin 4 -qmax 48 -b:v 730k ประมาณ 62% 5.27 เท่า
426x240 (240p) -r 30 -g 90 -s 426x240 -คุณภาพแบบเรียลไทม์ -ความเร็ว 8 -ชุดข้อความ 2 -แถว-mt 1 -การ์ด-คอลัมน์ 0 -เฟรม-ขนาน 0 -qmin 4 -qmax 48 -b:v 365k ประมาณ 66% 8.27 เท่า

ตัวอย่าง 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

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

  • โปรดทราบว่าที่นี่เรากําลังเอาต์พุตไปยังท่อ 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 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 (และรุ่นที่ใหม่กว่า) มีไปป์ไลน์การเข้ารหัสฮาร์ดแวร์เต็มรูปแบบ (โปรดทราบว่า GPU ของ Kabylake สามารถเข้ารหัส VP9 แบบ 8 บิตได้ แต่ทําไม่ได้ 10 บิต)

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

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

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

สําหรับตัวอย่างนี้ เราใช้เครื่องที่กําหนดค่าไว้ดังนี้

ระบบ โฮสต์: ob Kernel: 4.4.0-91-lowlatency x86_64 (64 บิต)
เดสก์ท็อป Xfce 4.12.3 Distro: ระบบปฏิบัติการ: https://ubuntustudio.org/2016/10/ubuntu-studio-16-10-released/
CPU Intel Core i5-6500 (-MCP-)
cache: 6144 KB
ความเร็วของนาฬิกา: สูงสุด: 3600 MHz 1: 800 MHz 2: 800 MHz 3: 800 MHz 4: 800 MHz
การ์ดกราฟิก กราฟิก Intel Intellake ในตัว
หน่วยความจำ 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 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 เป็นหลัก คุณสามารถตั้งค่าให้ Shaka Packager ฟังเอาต์พุตทั้งหมด แม้ว่า FFmpeg จะนําส่งเฉพาะชุดย่อยก็ตาม การตั้งค่า 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