קידוד בזמן אמת באמצעות VP9 באמצעות FFmpeg

פרמטרים של קידוד

ב-VP9 יש מגוון פרמטרים לאופטימיזציה של קידוד בזמן אמת. חלק מהעקרונות הרחבים האלה מתוארים במצבי קצב העברת נתונים.

דוגמה לקידוד FFmpeg VP9

בטבלה הבאה מפורטים הפרמטרים של קריאה ל-ffmpeg לדוגמה לקידוד VP9.

פרמטר תיאור
-quality realtime realtime הוא חיוני לשידור חי ולמהירויות שגבוהות מ-5.
-speed 6 יש להשתמש במהירות 5 עד 8 לקידוד בזמן אמת / בזמן אמת. מספרים נמוכים יותר (5 או 6) איכותיים יותר, אבל הם דורשים יותר מעבד (CPU). מספרים גבוהים יותר (7 או 8) יהיו באיכות נמוכה יותר, אך יהיה קל יותר לנהל אותם במקרים של זמן אחזור קצר יותר, וגם עבור מכשירי חשמל נמוכים יותר, כמו מכשירים ניידים.
-tile-columns 4 המשבצות מפצלות את הסרטון לאזורים מלבניים, כך שאפשר להשתמש בו במגוון שרשורים לקידוד ולפענוח. מספר המשבצות הוא תמיד כלי חשמל של שניים. 0 = אריח אחד, 1 = 2, 2 = 4, 3 = 8, 4 = 16, 5 = 32.
-frame-parallel 1 הפעלת תכונות של פענוח מקבילות.
-threads 8 מספר השרשורים המקסימלי לשימוש.
-static-thresh 0 סף לזיהוי תנועה.
-max-intra-rate 300 קצב העברת נתונים מקסימלי ל-i-Frame (PCt)
-deadline realtime גרסה חלופית (דורית) של -quality realtime
-lag-in-frames 0 מספר המסגרות המרבי לעיכוב
-qmin 4 -qmax 48 הערכים המינימליים והמקסימום לכמת. הערכים כאן הם רק הצעה, ושינוי זה יעזור להגדיל או להקטין את איכות הווידאו על חשבון יעילות הדחיסה.
-row-mt 1 הפעלת ריבוי שורות עם שרשור. מאפשר שימוש בשרשור של עד פי 2 כעמודות משבצות. 0 = כבוי, 1 = מופעל.
-error-resilient 1 הפעלת תכונות גמישות של שגיאות.

בחירת פרמטרים של קידוד

במידע שבהמשך נעשה שימוש בקידוד קצב העברת נתונים קבוע (CBR) עבור סטרימינג בשידור חי בקצב העברת נתונים (ABR), שבו כל שיעור יעד מוגדר באופן מפורש במניפסט של החבילה. התוצאה תהיה ניקיון של &מירכאות;מעבר בין&ציטוטים בין תעריפים ללקוחות. אפשרויות של קידוד קצב העברת נתונים (VBR) משתנה ומצב CQ הן גם אפשרויות אם קצב העברת הנתונים יכול להיות גמיש יותר או שהקידוד נחתך. מצב Q יקשה על קידוד בזמן אמת הנדרש עבור וידאו בשידור חי. מידע נוסף זמין בקטע מצבי ביטים.

לפרטים נוספים על אופן הפעולה של VP9 כדאי לעיין גם במאמר הנלווה בנוגע להגדרות VOD, אבל יש לשים לב להתמקדות ב- CBR.

טיפים וטריקים

חשוב לזכור שכשמפעילים סטרימינג בשידור חי, כל התוכן מוגבל לקצב קידוד מינימלי של 1 פעמים בזמן אמת (FFmpeg מדווח על מהירות הקידוד תוך כדי התקדמות). אם מהירות הקידוד יורדת מתחת ל-1x, תהליך הקידוד לא יתעדכן בקלט של וידאו בשידור חי, והמשתמשים יבחינו באחסון במאגר נתונים זמני, וההפסקות בשידור יגרמו לכך שהשידור לא יהיה שמיש במהלך השידור החי (עם זאת, בדרך כלל ניתן להשתמש בארכיון).

דוגמאות לפרמטרים של קידוד בפעולה

כשמשתמשים במעבד עם מערכת הפעלה i5 3.6Ghz ו-Linux, בקישור

רזולוציית יעד פרמטרים של FFmpeg VP9 מעבד / מהירות (דוגמה)
3840x2160 (2160p) -r 30 -g 90 -s 3840x2160 -איכות בזמן אמת -מהירות 5 -שרשורים 16 -row-mt 1 -tile-columns 3 -frame-Parallel 1 -qmin 4 -qmax 48 -b:v 7800k ~88% 0.39x
2,560x1,440 (1440p) -r 30 -g 90 -s 2560x1440 -איכות בזמן אמת -מהירות 5 -שרשורים 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 -איכות בזמן אמת -מהירות 5 -שורות ~82% 1.04x
1280x720 (720p) -r 30 -g 90 -s 1280x720 -איכות בזמן אמת -מהירות 5 -שרשורים 8 -row-mt 1 -tile-columns 2 -frame-Parallel 1 -qmin 4 -qmax 48 -b:v 3000k כ-78% x.17
854x480 (480p) -r 30 -g 90 -s 854x480 -איכות בזמן אמת -מהירות 6 -שרשורים 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 -איכות בזמן אמת -מהירות 7 -שרשורים 4 -שורה-mt 1 -אריחים-עמודות 1 -מסגרת מקבילה 0 -qmin 4 -qmax 48 -b:v 730k כ-62% 5.27x
426x240 (240p) -r 30 -g 90 -s 426x240 -איכות בזמן אמת -מהירות 8 -שורות כ-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 vp9 \
  -b:a 128k -c:a libopus -f webm pipe1

טיפים וטריקים

  • לתשומת ליבכם: כאן אנחנו מפיקים צינור FIFO ("pipe1"), שצריך ליצור לפני ההפעלה של פקודת FFmpeg. כדי לעשות זאת, יש לספק את הפקודה mkfifo pipe1 בספריית העבודה שלך. כשמשתמשים ב-Shake 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

עם זאת, לקבוצה המלאה שלמעלה יהיה צורך במעבד משמעותי מאוד, או שיש לו תמיכה בטעינה של GPU בחומרה, כמו למשל בערכות שבבים מסוימות שהולכת וגדלה. ל- Intel Kabylake (ועוד) יש צינור עיבוד נתונים מלא לחומרה. (שימו לב: ה-GPU ב-Kabylake יכול לבצע קידוד VP-8 סיביות, אך לא 10 סיביות).

דוגמה מעשית לשולחן העבודה באמצעות Shaka Packager

דוגמה מעשית יותר למחשבים שולחניים נפוצים עשויה להשתמש ב-Shake Packager. דרך פשוטה להגדיר את Shaka היא להתקין אותה בתוך מאגר Docker, באמצעות תמונת DockerHub של Google. ניתן למצוא הוראות כאן:

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

לצורך הדוגמה הזו, השתמשנו במכונה עם ההגדרות הבאות:

מערכת מארח: obs Kernel: 4.4.0-91-lowlatency x86_64 (64-bit)
מחשב Xfce 4.12.3 הפצה: OS: https://ubuntustudio.org/2016/10/ubuntu-studio-16-10-released/
מעבד (CPU) Intel Core i5-6500 (-MCP-)
cache: 6,144KB
מהירויות שעון: 3600 MHz 1: 800 MHz 2: 800 MHz 3: 800 MHz 4: 800 MHz
כרטיס גרפי גרפיקה משולבת של Intel Skylake
זיכרון זיכרון RAM של 8GB

בפועל, המכונה הזו יכולה להפיק באופן אופטימלי את הטווח הבא של קידודי 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 להאזנה לכל סוגי הפלט, גם אם רק קבוצת משנה מועברת על ידי 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