編碼原理
為什麼巨大的原始視訊可以編碼成很小的視訊呢?這其中的技術是什麼呢?核心思想就是去除備援資訊:
1)空間備援:圖像相鄰像素之間有較強的相關性
2)時間備援:視訊序列的相鄰圖像之間内容相似
3)編碼備援:不同像素值出現的機率不同
4)視覺備援:人的視覺系統對某些細節不敏感
5)知識備援:規律性的結構可由先驗知識和背景知識得到
直播秒開優化
-
DNS 解析慢
為了有效降低 DNS 解析對首開的影響,我們可以提前完成播放域名->IP 位址的解析,
并緩存起來,播放的時候,直接傳入帶 IP 位址的播放位址,進而省去了 DNS 解析的耗時。
如果要支援用 IP 位址播放,是需要修改底層 ffmpeg 源碼的。
-
播放政策
很多側重點播的播放器,為了減少卡頓,會有一些緩沖政策,當緩沖足夠多的資料之後 ,再送入解碼播放。
而為了加快首開效果,需要對播放的緩沖政策做一些調整,如果第一幀還沒有渲染出來的情況下,
不要做任何緩沖,直接送入解碼器解碼播放,這樣就可以保證沒有任何因為「主動」緩沖帶來的首開延時。
-
播放參數設定
所有基于 ffmpeg 的播放器,都會遇到
avformat_find_stream_info
這個函數耗時比較久,
進而增大了首開時間,該函數主要作用是通過讀取一定位元組的碼流資料,
來分析碼流的基本資訊,如編碼資訊、時長、碼率、幀率等等,它由兩個參數來控制其讀取的資料量大小和時長,
一個是 probesize,一個是 analyzeduration。
減少 probesize 和 analyzeduration 可以有效地減少
avformat_find_stream_info
的函數耗時,
進而加快首開,但是需要注意的是,設定地太小可能會導緻讀取的資料量不足,進而無法解析出碼流資訊,導緻播放失敗,
或者出現隻有音頻沒有視訊,隻有視訊沒有音頻的問題。
- 服務端優化
伺服器關鍵幀緩沖
CDN最近政策
直播弱網
-
首先如何判斷是弱網
不一定要進行網絡檢測,可以檢測兩次發包的時間間隔,通過發包的狀态與時間的長度判斷網絡狀态。
-
根據上行帶寬的狀況來動态調整碼率、FPS、分辨率
一般情況下視訊軌碼率預設設定為600Kbps,音頻軌碼率預設設定為64Kbps。
-
編碼優化
對于視訊編碼器确定編碼器開啟了最低延遲,對于x264尤其明顯。
盡量使用 ACC-LC Codec 來編碼音頻,HE-ACC 或者 HE-ACC 2 雖然編碼效率高,但是編碼所需時間更長,而産生更大體積的音頻,造成包可能過大。
不要使用視訊 MJPEG 的視訊壓縮格式,至少使用不帶 B 幀的 MPEG4 視訊壓縮格式(Simple profile),甚至最好使用 H.264 baseline profile(X264 還有一個「-tune zerolatency」的優化開關)。
這樣一個簡單的優化可以降低延遲,因為它能夠以更低的碼率編碼全幀率視訊。
固定碼率編碼 CBR 可以一定程度上消除網絡抖動影響,如果能夠使用可變碼率編碼 VBR 可以節省一些不必要的網絡帶寬,降低一定的延遲。是以建議盡量使用 VBR 進行編碼。
- 傳輸協定優化
-
在服務端節點和節點之間盡量使用 RTMP 而非基于 HTTP 的 HLS 協定進行傳輸,這樣可以降低整體的傳輸延遲。
這個主要針對終端使用者使用 HLS 進行播放的情況。
- 如果終端使用者使用 RTMP 來播放,盡量在靠近推流端的收流節點進行轉碼,這樣傳輸的視訊流比原始視訊流更小。
-
如果有必要,可以使用定制的 UDP 協定來替換 TCP 協定,省去弱網環節下的丢包重傳可以降低延遲。
它的主要缺點在于,基于 UDP 協定進行定制的協定的視訊流的傳輸和分發不夠通用,CDN 廠商支援的是标準的傳輸協定。
另一個缺點在于可能出現丢包導緻的花屏或者模糊(缺少關鍵幀的解碼參考),這就要求協定定制方在 UDP 基礎之上做好丢包控制。
4、丢幀處理
弱網環境下的丢幀政策。一般情況我們會有兩種隊列,分别是編碼之前的原始資料隊列和編碼之後的編碼隊列。
弱網丢幀政策常見的實作有兩種:一種是丢棄原始資料隊列中未編碼的資料幀,另外一種是丢棄編碼隊列中的資料幀。
這兩種實作各有優缺點,無論采用哪種實作方式都以“不影響音視訊的對齊”為第一準則。
丢掉了一定時間的視訊幀同時也需要丢掉同等時間的音頻幀。
-
播放優化
動态碼率播放政策。除了動态調整 buffer 大小的政策之外,也可以利用實時監測的網絡資訊來動态調整播放過程中的碼率,
在網絡帶寬不足的情況下降低碼率進行播放,減少延遲。
視訊拼接處理步驟(細節處理,比如分辨率大小不一,時間處理等等)
解封裝、解碼、決定分辨率大小、編碼、時間處理、封裝。
NV21如何轉換成I420
首先需要明白為什麼需要将NV21轉換成I420,這是因為x264隻支援編碼I420的資料。
實際上就是YUV420p與YUV420sp之間的轉換。
YUV420p與YUV420sp的相關知識請參考:《音視訊基礎知識-YUV圖像》
具體轉換參考:https://blog.csdn.net/yuanjinsong123/article/details/83895464
寫死與軟編碼如何選擇
https://github.com/interviewandroid/AndroidInterView/blob/master/android/mediacodec.md
x264編碼調優
參考:https://blog.csdn.net/liuchen1206/article/details/79351137
DTS與PTS
PTS就是Presentation Time Stamp也就說這個幀什麼時候會放在顯示器上;
DTS就是Decode Time Stamp,就是說這個幀什麼時候被放在編碼器去解。
在沒有B幀的情況下,DTS和PTS的輸出順序是一樣的。
比特率
比特率表示經過編碼(壓縮)後的音、視訊資料每秒鐘需要用多少個比特來表示。
比特率也叫做碼率
也就是指每秒傳送的比特(bit)數。
比如音頻的比特率:比特率 =采樣率 x 采用位數 x聲道數。
影響視訊清晰度的名額
幀率
碼率
分辨率
量化參數(壓縮比)
影響視訊流暢度的名額
碼率
幀率
什麼是GOP
GOP ( Group of Pictures ) 是一組連續的畫面,由一張 I 幀和數張 B / P 幀組成,是視訊圖像編碼器和解碼器存取的基本機關。
也就是說GOP組是指一個關鍵幀I幀所在的組的長度,每個 GOP 組隻有 1 個 I 幀。
GOP 組的長度格式也決定了碼流的大小。
GOP越大,中間的P幀和B幀的數量就越多,是以解碼出來的視訊品質就越高,但是會影響編碼效率。
例如720P的視訊,需要選擇多大的碼率才合适
檔案大小 = (音頻碼率 + 視訊碼率)/ 8 * 影片時長(機關為秒s)
什麼是SPS,什麼是PPS
SPS又稱作序列參數集。SPS中儲存了一組編碼視訊序列的全局參數。包含了profile、level、寬高和顔色空間等資訊。
所謂的編碼視訊序列即原始視訊的一幀一幀的像素資料經過編碼之後的結構組成的序列。
PPS是圖像參數集。每一幀的編碼後資料所依賴的參數儲存于圖像參數集中。
SurfaceView/TextureView的差別
- SurfaceView是一個有自己Surface的View。界面渲染可以放在單獨線程而不是主線程中。它更像是一個Window,自身不能做變形和動畫。
- TextureView同樣也有自己的Surface。但是它隻能在擁有硬體加速層層的Window中繪制,它更像是一個普通View,可以做變形和動畫。
Camera和Camera2如何選擇
參考官方的CameraView:https://github.com/google/cameraview
JNI線程互動
native 環境中建立的線程,如果需要通路 JNI,必須要調用 AttachCurrentThread 關聯,并使用 DetachCurrentThread 解除連結。
技術交流,歡迎加我微信:ezglumes ,拉你入技術交流群。
掃碼關注公衆号【音視訊開發進階】,一起學習多媒體音視訊開發~~~
喜歡就點個 「在看」 吧 ▽