使用 VideoToolbox 探索低延迟视频编码 | WWDC 演讲实录
本文根據 Peikang 在 WWDC 2021 分享翻譯,演講者 Peikang,來自 Video Coding 和 Processing 團隊。譯者陶金亮,網易云信資深音視頻開發工程師,擁有多年端側音視頻工作經驗。
支持低延遲編碼已成為視頻應用程序開發過程的一個重要方面,在低延遲直播和 RTC 領域有著廣泛的應用。本分享主要分享了 VideoToolbox(一個低級框架,提供對硬件編碼器和解碼器的直接訪問, 它提供視頻壓縮和解壓縮服務,以及存儲在 CoreVideo 像素緩沖區中的光柵圖像格式之間的轉換)是如何支持低延遲 H.264 硬件編碼,以最大限度地減少端到端延遲并實現新的性能水平,最終實現最佳實時通信和高質量視頻播放。
分享實錄視頻:https://developer.apple.com/videos/play/wwdc2021/10158
低延遲編碼對于許多視頻應用非常重要,尤其是實時視頻通信應用。在本次演講中,我將在 VideoToolbox 中介紹一種新的編碼模式,以實現低延遲編碼。這種新模式的目標是針對是實時視頻通信應用優化現有的編碼器流水線。那么實時視頻通信應用需要什么?我們需要最大限度地減少通信中的端到端延遲。
我們期望通過讓視頻應用程序與更多設備進行通信來增強互操作性。例如:當呼叫中有多個接收者時,編碼器管道也應該是高效的,并且,該應用程序需要以最佳視覺質量來呈現視頻。那么,我們需要一種可靠的機制來從網絡丟失引入的錯誤中恢復通信。
我今天要講的低延遲視頻編碼將在這些方面進行優化。使用低延遲編碼模式,我們的實時應用程序可以達到新的性能水平。在本次演講中,我將首先概述低延遲視頻編碼。我們可以對如何在管道中實現低延遲有基本的了解。然后我將展示如何使用 VTCompressionSession API 來構建管道并使用低延遲模式進行編碼。最后,我將討論我們在低延遲模式下引入的多個功能。
低延遲視頻編碼
首先讓我概述一下低延遲視頻編碼。這是 Apple 平臺上視頻編碼器管道的簡圖。 VideoToolbox 將 CVImagebuffer 作為輸入圖像,它要求視頻編碼器執行 H.264 等壓縮算法以減少原始數據的大小。輸出的壓縮數據封裝在 CMSampleBuffer 中,可以通過網絡傳輸進行視頻通信。從上圖中我們可以注意到,端到端延遲可能受兩個因素影響:處理時間和網絡傳輸時間。
為了最大限度地減少處理時間,低延遲模式消除了幀重新排序,遵循一進一出的編碼模式。此外,該低延遲編碼模式下的速率控制器對網絡變化的適應速度也更快,因此也可以最大限度減少網絡擁塞造成的延遲。通過這兩個優化,我們已經可以看到與默認模式相比,已經有了明顯的性能提升。對于 720p 30fps 的視頻,低延遲編碼可以減少高達 100 毫秒的延遲。這種節省對于視頻會議至關重要。
通過這樣的操作實現了減少延遲,我們可以為視頻會議和直播等實時通信實現更高效的編碼管道。
此外,低延遲模式始終使用硬件加速視頻編碼器以節省電量。請注意,此模式支持的視頻編解碼器類型為 H.264,我們將在 iOS 和 macOS 上引入此功能。
在 VideoToolbox 中使用低延遲模式
接下來,我想談談如何在 VideoToolbox 中使用低延遲模式。我將首先回顧 VTCompressionSession 的使用,然后向您展示啟用低延遲編碼所需的步驟。
VTCompressionSession 的使用
當我們使用 VTCompressionSession 時,首先要使用 VTCompressionSessionCreate API 創建會話。并通過 VTSessionSetProperty API 配置會話,例如目標比特率。如果未提供配置,編碼器將以默認行為運行。
創建會話并正確配置后,我們可以通過調用 VTCompressionSessionEncodeFrame 將 CVImageBuffer 傳遞給會話,同時可以從會話創建期間提供的輸出處理程序中檢索編碼結果。
在壓縮會話中啟用低延遲編碼很容易,我們唯一需要做的就是在會話創建過程中進行修改,如下文的代碼:
-
首先,我們需要一個用于編碼器規范的 CFMutableDictionary,編碼器規范用于指定會話必須使用的特定視頻編碼器。
-
然后我們需要在 encoderSpecification 中設置 EnableLowLatencyRateControl 標志。
-
最后,我們將此 encoderSpecification 賦予 VTCompressionSessionCreate,壓縮會話就將在低延遲模式下運行。
配置步驟和往常一樣。例如,我們可以使用 AverageBitRate 屬性設置目標比特率。
好的,我們已經介紹了 Video Toolbox 低延遲模式的基礎知識。下面,我想繼續介紹此模式中的新功能,它們可以進一步幫助我們開發實時視頻應用程序。
VideoToolbox 低延遲模式新功能
到目前為止,我們已經討論了使用低延遲模式的延遲優勢,其余的好處可以通過我將要介紹的功能來實現。
第一個功能是新的 Profiles,我們通過向管道添加兩個新 Profiles來增強互操作性。也會聊聊時域分層SVC,此功能在視頻會議中非常有用。也可以使用最大幀量化參數(Max QP)對圖像質量進行細粒度控制。最后,我們希望通過添加長期參考(LTR)的支持來提高錯誤恢復能力。
新的 Profiles 支持
讓我們談談新的 Profiles 支持。 Profile 定義了一組解碼器能夠支持的編碼算法,Profile 用于確定視頻編碼過程中幀間壓縮使用的算法(例如是否包含 B 幀、CABAC 支持、顏色空間支持等),Profile 越高,就說明采用了越高級的壓縮特性,對應的對編解碼硬件的要求也越高。為了與接收方通信,編碼比特流應符合解碼器支持的特定配置文件。
在 VideoToolbox 中,我們支持一系列profiles,例如Baseline Profile、Main Profile和High Profile。今天,我們為該系列添加了兩個新profiles:Constrained Baseline Profile (CBP) 和 Constrained High Profile (CHP) 。
CBP 主要用于低成本應用,而 CHP 則具有更先進的算法以獲得更好的壓縮比。我們可以先檢查解碼器功能以判斷應該使用哪個 Profile。
想要使用 CBP,只需將 ProfileLevel 會話屬性設置為 ContrainedBaseLine_AutoLevel。同樣,我們可以將Profile級別設置為 ContrainedHigh_AutoLevel 以使用 CHP。
時域分層SVC
現在讓我們談談時域分層 SVC。我們可以使用時域分層來提高多方視頻通話的效率。
例如:一個簡單的三方視頻會議場景。在此模型中,接收器 A 的帶寬較低,為 600kbps,而接收器 B 的帶寬較高,為 1,000kbps。通常,發送端需要對兩組碼流進行編碼,以滿足每個接收端的下行帶寬。這種做法可能不是最佳的。
該模型可以通過時域分層 SVC 來更加高效的實現,其中發送方只需要編碼一個比特流,但最后可以比特流輸出可以分為兩層。
我們來看看這個過程是如何工作的。這是一個編碼視頻幀序列,其中每一幀都使用前一幀作為預測參考。
我們可以將一半的幀拉入另一層,我們可以更改參考,以便只有原始層中的幀用于預測。原始層稱為基礎層,新構建的層稱為增強層。增強層可以作為基礎層的補充,以提高幀率。
對于接收器 A,我們可以發送基礎層幀,因為基礎層本身已經是可解碼的。更重要的是,由于基礎層只包含一半的幀,所以傳輸的數據速率會很低。
另一方面,接收器 B 可以享受更流暢的視頻,因為它有足夠的帶寬來接收基本層幀和增強層幀。
我們來看看使用時域分層 SVC 編碼的視頻。我將播放兩個視頻,一個來自基礎層,另一個來自基礎層和增強層。基礎層本身可以正常播放,但同時我們可能會注意到視頻不太流暢。如果我們播放第二個視頻,我們可以立即看到差異。與左側視頻相比,右側視頻具有更高的幀速率,因為它同時包含基礎層和增強層。
(視頻)
左側視頻具有 50% 的輸入幀率,并使用 60% 的目標比特率。這兩個視頻只需要編碼器一次編碼一個比特流。當我們進行多方視頻會議時,這將更加節能。
時域分層的另一個好處是錯誤恢復能力。我們可以看到,增強層中的幀不用于預測,因此對這些幀沒有依賴性。這意味著如果在網絡傳輸過程中丟失了一個或多個增強層幀,其他幀不會受到影響。這使得整個會話更加健壯。
啟用時域分層的方法非常簡單。我們在低延遲模式下創建了一個名為 BaseLayerFrameRateFraction 的新會話屬性,只需將此屬性設置為 0.5,這意味著一半的輸入幀分配給基礎層,其余分配給增強層。
我們可以從示例緩沖區附件中檢查圖層信息。對于基礎層幀,CMSampleAttachmentKey_ IsDependedOnByOthers 將為真,否則為假。
我們還可以選擇為每一層設置目標比特率。請記住,我們使用會話屬性 AverageBitRate 來配置目標比特率。目標比特率配置完成后,我們可以設置新的 BaseLayerBitRateFraction 屬性來控制基礎層所需的目標比特率百分比。如果未設置此屬性,則將使用默認值 0.6。我們建議基礎層比特率分數應在 0.6 到 0.8 的范圍內。
最大幀 QP
現在,讓我們看看最大幀量化參數或者說是最大幀 QP。幀 QP 用于調節圖像質量和數據速率。
我們可以使用低幀 QP 來生成高質量的圖像。但在這種情況下,圖像尺寸會很大。
另一方面,我們可以使用高幀 QP 來生成低質量但尺寸較小的圖像。
在低延遲模式下,編碼器使用圖像復雜度、輸入幀速率、視頻運動等因素調整幀 QP,以在當前目標比特率約束下產生最佳視覺質量。所以我們鼓勵依靠編碼器的默認行為來調整幀 QP。
但是在某些客戶端對視頻質量有特定要求的情況下,我們可以控制編碼器使用最大幀 QP。使用最大幀 QP 時,編碼器將始終選擇小于此限制的幀 QP,因此客戶端可以對圖像質量進行細粒度的控制。
值得一提的是,即使指定了最大幀 QP,常規速率控制仍然有效。如果編碼器達到最大幀 QP 上限但比特率預算用完,它將開始丟棄幀以保持目標比特率。
使用此功能的一個示例是通過較差的網絡傳輸屏幕內容視頻。我們可以通過犧牲幀速率來進行權衡,以發送清晰的屏幕內容圖像,通過設置最大幀 QP 可以滿足此要求。
我們可以使用新的會話屬性 MaxAllowedFrameQP 傳遞最大幀 QP。根據標準最大幀 QP 的值必須介于 1 到 51 之間。
長期參考幀 (LTR)
說一下我們在低延遲模式下開發的最后一個功能,長期參考幀。長期參考幀即 LTR 可用于錯誤恢復。讓我們看一下這張圖,其中顯示了管道中的編碼器、發送方客戶端和接收方客戶端。
假設視頻通信通過一個連接不良的網絡,由于傳輸錯誤,可能會發生幀丟失。當接收方客戶端檢測到幀丟失時,它可以請求刷新幀以重置會話。如果編碼器收到請求,通常它會編碼一個關鍵幀以用于刷新目的,但關鍵幀通常相當大。大的關鍵幀需要更長的時間才能到達接收器。由于網絡條件已經很差,大幀可能會加劇網絡擁塞問題。那么,我們可以使用預測幀而不是關鍵幀進行刷新嗎?答案是肯定的,如果我們有幀確認。讓我們來看看它是如何工作的。
首先,我們需要決定確認的幀。我們稱這些幀為長期參考幀或 LTR,這是編碼器的決定。當發送方客戶端傳輸 LTR 幀時,還需要向接收方客戶端請求確認。如果成功接收到 LTR 幀,則需要返回確認。一旦發送方客戶端獲得確認并將該信息傳遞給編碼器,編碼器就知道對方收到了哪些 LTR 幀。
再來看看網絡不好的情況:當編碼器收到刷新請求時,因為這次,編碼器有一堆已確認的 LTR,它能夠對從這些已確認的 LTR 中的一個預測的幀進行編碼,以這種方式編碼的幀稱為 LTR-P。與關鍵幀相比,LTR-P 的編碼幀大小通常要小得多,因此更容易傳輸。
現在,讓我們談談 LTR 的 API。請注意,幀確認需要由應用層處理,它可以通過 RTP 控制協議中的 RPSI 消息等機制來完成。這里我們只關注編碼器和發送方客戶端在這個過程中是如何通信的。啟用低延遲編碼后,我們可以通過設置 EnableLTR 會話屬性來啟用此功能。
當 LTR 幀被編碼時,編碼器將在示例附件 RequireLTRAcknowledgementToken 中用信號發送一個唯一的幀令牌。
發送方客戶端負責通過 AcknowledgedLTRTokens 幀屬性將確認的 LTR 幀報告給編碼器。由于一次可以收到多個確認,我們需要使用一個數組來存儲這些幀標記。
我們可以隨時通過 ForceLTRRefresh 框架屬性請求刷新框架。一旦編碼器收到這個請求,一個 LTR-P 將被編碼。如果沒有已確認的 LTR 可用,在這種情況下,編碼器將生成一個關鍵幀。
總結
以上就是本次 Peikang 在 WWDC 2021 大會上分享的全部內容譯文,若有翻譯不合理處,歡迎指正交流。
目前網易云信在客戶端層面實現了軟件編碼的 SVC 和長期參考幀方案,同時服務器在轉發上面也實現了 SVC 方案。SVC 提供了服務器一個額外的手段控制視頻流的轉發碼率,再結合大小流和碼率壓制, 以及客戶端下行的網絡帶寬探測和擁塞控制等手段,網易云信為了追求極致的觀看體驗,不斷的打磨產品,本次分享的內容,我相信不久就可以在云信的產品中得到很好的運用。
總結
以上是生活随笔為你收集整理的使用 VideoToolbox 探索低延迟视频编码 | WWDC 演讲实录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用高级视频质量工具 AVQT 评估视频
- 下一篇: 云游戏打破硬件限制,传输体验或成发展掣肘