קידוד בזמן אמת באמצעות 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