קידוד בשידור חי באמצעות VP9 באמצעות FFmpeg
פרמטרים של קידוד
ב-VP9 יש מגוון פרמטרים שאפשר להשתמש בהם כדי לבצע אופטימיזציה של קידוד בשידור חי. חלק מהעקרונות הכלליים האלה מוסברים במאמר בנושא מצבי קצב העברת נתונים.
דוגמה לקידוד VP9 ב-FFmpeg
בטבלה הבאה מתוארים הפרמטרים של קריאה לדוגמה ל-ffmpeg
לקידוד VP9.
פרמטר | תיאור |
---|---|
-quality realtime |
realtime הוא חיוני לסטרימינג בשידור חי ולמהירויות מעל 5 . |
-speed 6 |
המהירות 5 עד 8 מתאימה לקידוד של שידורים חיים או בזמן אמת. מספרים נמוכים יותר (5 או 6 ) מייצגים איכות גבוהה יותר, אבל דורשים יותר כוח עיבוד. מספרים גבוהים יותר (7 או 8 ) יצביעו על איכות נמוכה יותר, אבל יהיה קל יותר לנהל אותם במקרים של שימוש בזמן אחזור נמוך וגם במכשירים עם עוצמת מעבד נמוכה יותר, כמו מכשירים ניידים. |
-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 |
קצב העברת נתונים מקסימלי של פריימים מלאים (באחוזים) |
-deadline realtime |
גרסה חלופית (קודמת) של -quality realtime |
-lag-in-frames 0 |
מספר המסגרות המקסימלי של השהיה |
-qmin 4 -qmax 48 |
הערכים המינימליים והמקסימליים של הכמת. הערכים שמוצגים כאן הם רק הצעה, והתאמה שלהם תעזור לכם להגדיל או להקטין את איכות הסרטון על חשבון יעילות הדחיסה. |
-row-mt 1 |
הפעלת ריבוי-הליכי משנה בשורות. מאפשר שימוש בעד 2x שרשורים כעמודות של משבצות. 0 = כבוי, 1 = מופעל. |
-error-resilient 1 |
הפעלת תכונות עמידות לשגיאות. |
בחירת פרמטרים של קידוד
המידע שבהמשך מתייחס לקידוד בקצב העברת נתונים קבוע (CBR) לשידור חי בקצב העברת נתונים דינמי (ABR), שבו כל קצב יעד מוגדר באופן מפורש במניפסט של כלי האריזה. כך מתקבל מעבר חלק יותר בין תעריפים ללקוחות. אפשרות נוספת היא קידוד עם קצב העברת נתונים משתנה (VBR) ומצב CQ אם קצב העברת הנתונים יכול להיות גמיש יותר או אם הקידוד מתבצע במנות. מצב Q יתקשה בקידוד בזמן אמת שנדרש לשידור חי של וידאו. מידע נוסף זמין במאמר מצבי קצב העברת נתונים.
כדאי לעיין גם במאמר הנלווה בנושא הגדרות VOD כדי לקבל פרטים נוספים על שינוי הגדרות VP9, אבל צריך לזכור שההתמקדות היא ב-CBR.
טיפים וטריקים
חשוב לזכור שבמהלך סטרימינג בשידור חי, הכול מוגבל למהירות קידוד מינימלית בזמן אמת של x1 (FFmpeg מדווח על מהירות הקידוד במהלך ההתקדמות). אם מהירות הקידוד יורדת מתחת ל-1x, תהליך הקידוד לא יתאים לקצב ההזנה של הווידאו בשידור חי, והמשתמשים יחוו שמירה במאגר נתונים זמני (באפרינג) ושיבושים בשידור. השידור לא יהיה שמיש במהלך השידור החי (אבל בדרך כלל אפשר יהיה להשתמש בארכיון).
דוגמאות לקידוד פרמטרים בפעולה
הטבלה הבאה מציגה את ניצול המעבד ב-25 פריימים לשנייה עבור גדלי פריימים שונים במחשב שולחני עם מעבד i5 מרובע ליבה במהירות 3.6GHz שמריץ Linux:
מועד אחרון לפתרון | פרמטרים של FFmpeg VP9 | מעבד (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.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 |
דוגמה לשימוש ב-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
דוגמה להגדרת קצב העברת נתונים (bitrate) דינמי
בהתאם ליכולות של המחשב שמריץ את הקידוד של FFmpeg, יכול להיות שלא תהיה אפשרות לספק את כל הקידודים הבאים בו-זמנית, ולכן צריך לבחור מתוך הרשימה קבוצת משנה שמתאימה למשאבים הזמינים ולקהלי היעד שלכם.
FFmpeg full ABR set
בתרחיש אידיאלי, אנחנו משלבים את דוגמאות הקידוד שמתוארות בקטע הקודם כדי ליצור פקודה אחת שמפיקה את כולן בו-זמנית:
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 | ארבע ליבות Intel Core i5-6500 (-MCP-) מטמון: 6144 KB מהירויות שעון: מקסימום: 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 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