本文為「Dev for Dev 專欄」系列內容,作者為聲網資深影片演算法負責人 戴偉。
01 影片編解碼標準的歷史和現在
1990 年左右 H.261 標準的制定,開啟了影片編解碼標準化的歷程。經過 30 多年的努力,影片的編碼效率得到了極大幅度的提升。在下圖中,我們大致列舉了一下所有的影片編碼標準的制定組織和釋出時間。
我們可以發現,到目前為止,影片編碼領域主要還有三大組織在制定標準。他們分別是制定 H.26x 系列的編解碼標準的 ITU-T 和 MPEG 聯合的組織,制定 Avx 系列的編解碼標準的以 Google 為首的 AOM 聯盟以及制定 AVSx 系列的編解碼標準的中國專家組。
在這些標準中,目前世界上應用最為廣泛的標準,是 ITU-T 和 MPEG 聯合制定的 H.264、H.265 以及 Google 制定的 VP9 和他們後面的 AV1 這四個編解碼標準。其中 H.264 已經有將近 20 年的歷史,其編碼效率已遠遠低於最新制定的 H.266 等編解碼標準,但是由於支援他的裝置極其廣泛,所以它目前仍然是支援度最高的一個編解碼標準。
下圖是 Bitmovin 連續 4 年的一個編解碼器使用調查問卷,我們可以發現,除了 H.264 之外, H.265 也是一個支援度相對較高的編解碼標準,而 VP9 和 AV1 也有一定的增長勢頭。總體來說,H.26x 系列的編碼標準,由於其廣泛的公司參與和支援,會更加容易得到硬體晶片的實現。但是從 H.265 以來,其專利費的不清晰也成為了他們推廣的一大阻力。反之,AV1 從制定初期就定下了免專利費的目標,發展過程中也得到了越來越多的公司支援和加入,我們相信 AVx 系列的支援度也會以一個較為驚人的速度不斷髮展。
影片編解碼標準的首要目標是在保證畫質的前提下儘可能的壓縮影片檔案大小,節省儲存和傳輸成本。這個目標也很好的切合了影片初期的使用範圍,即一開始的 VCD,DVD 以及後期網際網路興起之後的影片點播網站等。但是,隨著 RTE 的不斷髮展,影片領域湧現出了不少新的需求,而這些新的需求,又會反過來促進編解碼的進一步發展。那麼,RTE 的時代下,又湧現出了哪些新的需求呢?
02 RTE 時代下對編解碼標準提出新的需求
RTE 裡的影片應用場景和普通應用場景最明顯的區別,在於對影片的端到端延時要求。普通的影片點播因為沒有互動的需求,所以基本不關注延時的問題。而在 RTE 場景中通常會涉及到大量的互動與互動,因此對延時有著極高的要求,一般要求至少是在 300ms 以內。並且因為超低延時的限制,導致編碼的輸出位元速率對網路頻寬的變化要更為靈敏。
另外,因為 RTE 是實時的應用場景,所有產生的影片可以認為是即編即用的,這也是和普通影片場景的一個極大區別。因為在普通的影片場景中,影片的播放次數遠遠大於影片的壓縮次數,這也是所有編解碼標準中盡力控制解碼器複雜度的原因。而在 RTE 的領域,如果不考慮特殊的錄製等需求,所有的影片都是編碼一次,播放有限次的。
在這兩個大前提下,影片的編碼和傳輸在 RTE 的領域裡就催生了幾個很重要的問題:
1、在位元速率波動的情況下如何保證畫質的穩定
在傳統的影片編碼的場景中,一般是先給定一個固定的位元速率,然後整個影片以這個不變的位元速率作為目標進行編碼。在這種場景下,編碼器可以相對容易的控制整個影片畫質的穩定。然而在一個實時傳輸的系統中,網路頻寬是實時變化的,可能前一秒還是一個通暢的網路狀況,下一秒就由於網路擁塞而導致目標位元速率突降。
例如我們現在正在以 1.2Mbps 的位元速率編碼一個 720P 15fps 的影片,突然由於網路的原因,當前可用的頻寬下降到了 300kbps,此時,如果編碼器依然還以 720P 15fps 的方式去編碼這個碼流,會體驗到非常嚴重的主觀畫質下降的問題。
另外,在頻寬波動的狀態下,如何保證畫質的平穩過度,也是一個非常重要的問題,當頻寬從 1.2Mbps 突降到 300kbps,然後又慢慢爬升回 1.2Mbps 的時候,如何保證這期間畫質的穩定,也是對使用者體驗的一大考驗。
2、如何在丟包的情況下保證影片的流暢度
在傳統的網際網路點播場景中,一般都會有 2 – 3 秒的播放快取時間。如果遇到網路丟包的情況時,延時可能會到5秒以上。這些延時在真正的觀看體驗中除了延遲變大的那一刻,其他時候基本是無感知的。然而,在 RTE 的場景中,因為有著實時互動的要求,對端到端的延時有著極高的要求,過高的延時會直接導致使用體驗的惡化。
在低延時的前提下,解碼器並沒有太多的時間來等待傳輸過程中丟失的包。所以在丟包率較高的場景下,很容易出現有幾幀,甚至連續幾幀無法在接收端完整收到的情況。如果沒有一個很好的抗丟包的策略,那麼很可能後續的影片幀都會由於找不到對應的參考幀而無法解碼。
為了讓影片能夠重新解碼,一般需要編碼器重新發一個 IDR 幀。而 IDR 幀因為可以獨立解碼,不依賴前面的幀是否可解,導致他的幀大小是一般的 P 幀的 2 – 3倍以上。這麼大的幀在丟包率較高的網路條件下,會有更高的機率無法被完整的收到,進一步加劇影片的卡頓率,導致較差的使用者體驗。
3、如何提升低位元速率下的影片質量
RTE 場景中挑戰性最大的就是如何在弱網場景下依然保證不錯的使用者體驗。在傳統的編解碼標準中,當給定位元速率很低的時候,只能透過使用一個很大的量化步長來儘可能的丟棄影像資訊來達到低位元速率的目的。然而這種做法會引入很嚴重的塊效應,極大的影響了我們的主觀體驗。
在 RTE 的場景中,我們可以透過一系列的方法來提升主觀的畫質。在傳送端可以有包括降幀率、降解析度等方法,其中降幀率並不需要重啟編碼器,而降解析度則一般需要重啟整個編碼器,丟棄掉之前的所有編碼資訊。在接收端則可以透過超分等方法進行畫質的影像提升等。
但是這些方法在位元速率特別低,QP 特別大的時候,都無法很好的將損失的畫質給彌補回來,反而可能會引入額外的主觀畫質問題。例如超分的畫面如果有這很嚴重的塊效應,那麼超分出來的畫面會在很大程度上依然保留這些塊效應的邊界,甚至可能會在在這些邊界上引入更嚴重的 artifacts。
03 新編解碼標準的技術展望
在說了這麼多 RTE 場景下對影片編解碼的新需求之後,我們再來談一談這些新需求會促生影片編解碼的一些什麼新的技術展望。
1、動態解析度適配
在傳統的編解碼標準中,一旦編碼開啟,整個過程中的解析度是不能變化的。如果想變化解析度,有幾種方法可以選擇:
①使用多條流編碼不同解析度,並且在對應位置進行流切換的方式來達到解析度變化的目的。
②使用 SVC 技術來進行動態解析度的切換。
兩種方法比較起來,我們可以看到方法①的架構比方法②要簡單很多,整體的業務邏輯也會相對簡單清晰。
但是因為方法①的多條流之間是互相獨立的,所以在上行傳送的時候,這些流會佔據較多的上行位元速率;方法②裡因為流是互相依賴的,所以它的上行位元速率比方法①起來會少一點。但是,對於接收端來說,如果接收端觀看的都是小解析度的影片,那麼兩個方案對於接收端來說沒有區別。但是如果接收端觀看的是大解析度的影片,那麼方法②的總體碼流因為流之間的資訊冗餘,會比方法①的單流要高出 10%左右的位元速率。
所以上述兩種方法,都有各自的優缺點。而我們所說的動態解析度適配技術,即在編碼過程中動態變化編碼的解析度,然後再解碼的時候透過上取樣的技術全部都取樣到相同的解析度,很好的吸收了前兩種方法的優點。 我們可以發現,在 AV1 中已經提出了一種編碼過程中超解析度的方法。即在編碼 1280x720P 的時候,如果遇到頻寬等問題需要降低解析度進行編碼,它會以 640x720P 的解析度來編碼當前幀,然後再解碼的時候再透過一個確定的方式將畫面超分回 1280x720P。
AV1 的這個設計,當時是考慮到硬體快取的限制,所以只在水平方向進行縮放,垂直方向並沒有進行縮放。
然而,僅僅水平方向的二分之一的縮放,對降低位元速率並不能起到非常大的作用,將來的編碼器應該可以支援更多方向,更大比例的縮放,來達到動態降低位元速率的目標。
2、可配置的 in-loop filtering
傳統的編解碼標準裡只規定了解碼的整個流程,包括流程中用到的各種係數,都用一個文件規定的十分明白。這麼做的主要目的,是在於確保無論什麼時候,什麼裝置編碼出來的碼流,只要符合這個標準,都可以隨時隨地被按照這個標準設計的解碼器正確解碼出來。本質上,它還是為了編碼一次解碼無數次的目的而設計的。這種設計方法有一個比較明顯的問題,即他們的 in-loop filtering 的可調引數太少了,不能在所有的場景下得到最優的效果。
在 RTE 的場景下,我們其實並不需要考慮太多一個小時後別人想看的話怎麼辦這種問題,我們更需要關注的是在互動的過程中如何得到最佳的使用者體驗。那麼我們就可以將這些濾波的係數都改成可配置的。例如在戶外場景我們可以使用一套專門為了戶外訓練的模型,在室內場景我們可以使用一套專門為了室內訓練的模型,螢幕共享的時候使用一套專門為了字型最佳化過的模型。甚至在以後遇到新場景時,再訓練一套這個新場景下的模型。
更進一步說,我們可以將和編解碼相關的後處理,作為一個新的 in-loop filtering 模組,做到編解碼的流程中去。這樣就可以進一步提升參考幀的質量,提升壓縮的效率。
這樣的話,我們就可以在各種各樣的場景下,得到更佳的使用者體驗。
3、更適應網路的丟包容錯機制
在傳統的影片編解碼標準的制定過程中,並沒有考慮過太多的各種網路丟包時如何進行錯誤恢復的方式,也並沒有規定進行錯誤恢復的方式和方法,而是把這個能力交給了每一個開發者來定義。這個在某種程度上為開發者提供了非常大的錯誤恢復方案的靈活性,但是這麼做的代價,就是所有的錯誤恢復都是隻能在解碼之後才能進行操作。從另外一個角度來說,也限制了編碼器獲得更高編碼效率的空間。所以在 RTE 的場景中,我們需要一套 in-loop error concealment 的方法,來最大化的提升編碼效率。
此外,在 syntax 的層級,傳統的影片編解碼演算法也並沒有什麼特殊處理的方法,我們還需要再 syntax 的層次對網路的丟包場景進行進一步的適配,充分考慮各種丟包的情況進行處理,達到最高的編碼效率。
04 總結
在 RTE 的應用越來越廣泛的今天,由於 RTE 的場景有其特殊的要求,傳統的編解碼標準不能夠很好的適應 RTE 的場景的要求。我們相信隨著 RTE 的應用越來越廣泛,那麼新的編解碼標準在制定的時候,就不可避免的需要考慮 RTE 的新需求,創造出一個新的 RTE 的影片編解碼標準。
(正文完)
關於 Dev for Dev
Dev for Dev 專欄全稱為 Developer for Developer,該專欄是聲網與 RTC 開發者社群共同發起的開發者互動創新實踐活動。
透過工程師視角的技術分享、交流碰撞、專案共建等多種形式,匯聚開發者的力量,挖掘和傳遞最具價值的技術內容和專案,全面釋放技術的創造力。