開始
之前一直做直播方面的開發,不過一直沒機會接觸一些推流和播放器的技術,所以業餘時間自己去寫了一下推流器模組的Demo。
自己也總結了一些常用的知識:
過程
模組構成
我將推流器看成五塊知識點,分別是:採集、處理、編碼、封包、推流。
採集模組
採集是將機器獲得的圖片和視訊轉成一幀幀影象資料返回到開發者手中。
以下是採集模組一些知識點
yuv、rgb、ycbcr的顏色空間模型知識點:
硬知識點,請參考: blog.csdn.net/u010186001/…
iOS採集知識點
iOS下通過硬體採集到的影象資料會用CMSampleBufferRef來儲存回撥到使用者手中。 CMSampleBufferRef結構如下:(音訊:結構體內的CVPixelBuffer替換成CMBlockBuffer),CVPixelBuffer就是RGB/YUV/YCBCR的資料。
GPUImage知識點
GPUImage是IOS上基於opengl的影象、視訊處理開源框架,裡面帶有大量的濾鏡,同時也很方便在原有基礎上加入自己的濾鏡Filter,所有濾鏡是基於opengl shader實現的,所以濾鏡效果影象處理是在GPU上實現的,處理效率比較高。
GPUImage基本架構是chain式結構,主要由一個GPUImageOutput interface和一個GPUImageInput protocol串聯起來,GPUImageOutput輸出Texture,GPUImageInput輸入Texture,整個鏈式影象資料傳遞由Texture負責。camera,stillimage等影象、視訊sources繼承自GPUImageOutput,濾鏡Filters繼承自GPUImageOutput並實現GPUImageInput,View,FileWriter等Outputs實現GPUImageInput。
處理模組
OpenGL ES 地址:www.khronos.org/opengles/
Metal 地址:developer.apple.com/documentati…
Metal 是一個和 OpenGL ES類似的面向底層的圖形程式設計介面,通過使用相關的 api 可以直接操作 GPU ,最早在 2014 年的 WWDC 的時候釋出,並於今年釋出了 Metal 2,是蘋果的一個親兒子。
Metal框架支援GPU硬體加速、高階3D圖形渲染以及大資料並行運算。且提供了先進而精簡的API來確保框架的細粒度(fine-grain),並且在組織架構、程式處理、圖形呈現、運算指令以及指令相關資料資源的管理上都支援底層控制。其核心目的是儘可能的減少CPU開銷,而將執行時產生的大部分負載交由GPU承擔。
(以後需要繼續研究Metal)
GPUImageFilter
可以參考:www.jianshu.com/p/468788069…
編碼知識點
最廣泛最常用的格式 H264
I幀
幀內編碼幀 ,I幀表示關鍵幀,你可以理解為這一幀畫面的完整保留;解碼時只需要本幀資料就可以完成(因為包含完整畫面)
幀內編碼用來縮減影象的空間冗餘。為了提高H.264幀內編碼的效率,在給定幀中充分利用相鄰巨集塊的空間相關性,相鄰的巨集塊通常含有相似的屬性。因此,在對一給定巨集塊編碼時,首先可以根據周圍的巨集塊預測(典型的是根據左上角巨集塊、左邊巨集塊和上面巨集塊,因為此巨集塊已經被編碼處理),然後對預測值與實際值的差值進行編碼,這樣,相對於直接對該幀編碼而言,可以大大減小位元速率。
H.264提供9種模式進行4×4畫素巨集塊預測,包括1種直流預測和8種方向預測。在圖中,相鄰塊的A到I共9個畫素均已經被編碼,可以被用以預測,如果我們選擇模式4,那麼,a、b、c、d4個畫素被預測為與E相等的值,e、f、g、h4個畫素被預測為與F相等的值,對於影象中含有很少空間資訊的平坦區,H.264也支援16×16的幀內編碼。
I幀特點:
- 它是一個全幀壓縮編碼幀。它將全幀影象資訊進行JPEG壓縮編碼及傳輸;
- 解碼時僅用I幀的資料就可重構完整影象;
- I幀描述了影象背景和運動主體的詳情;
- I幀不需要參考其他畫面而生成;
- I幀是P幀和B幀的參考幀(其質量直接影響到同組中以後各幀的質量);
- I幀是幀組GOP的基礎幀(第一幀),在一組中只有一個I幀;
- I幀不需要考慮運動向量;
- I幀所佔資料的資訊量比較大。
P幀
前向預測編碼幀。P幀表示的是這一幀跟之前的一個關鍵幀(或P幀)的差別,解碼時需要用之前快取的畫面疊加上本幀定義的差別,生成最終畫面。(也就是差別幀,P幀沒有完整畫面資料,只有與前一幀的畫面差別的資料) P幀的預測與重構:P幀是以I幀為參考幀,在I幀中找出P幀“某點”的預測值和運動向量,取預測差值和運動向量一起傳送。在接收端根據運動向量從I幀中找出P幀“某點”的預測值並與差值相加以得到P幀“某點”樣值,從而可得到完整的P幀。
P幀特點:
- P幀是I幀後面相隔1~2幀的編碼幀;
- P幀採用運動補償的方法傳送它與前面的I或P幀的差值及運動向量(預測誤差);
- 解碼時必須將I幀中的預測值與預測誤差求和後才能重構完整的P幀影象;
- P幀屬於前向預測的幀間編碼。它只參考前面最靠近它的I幀或P幀;
- P幀可以是其後面P幀的參考幀,也可以是其前後的B幀的參考幀;
- 由於P幀是參考幀,它可能造成解碼錯誤的擴散;
- 由於是差值傳送,P幀的壓縮比較高。
B幀
雙向預測內插編碼幀。B幀是雙向差別幀,也就是B幀記錄的是本幀與前後幀的差別(具體比較複雜,有4種情況,但我這樣說簡單些),換言之,要解碼B幀,不僅要取得之前的快取畫面,還要解碼之後的畫面,通過前後畫面的與本幀資料的疊加取得最終的畫面。B幀壓縮率高,但是解碼時CPU會比較累。所以移動端一般不解壓B幀。
B幀的預測與重構 B幀以前面的I或P幀和後面的P幀為參考幀,“找出”B幀“某點”的預測值和兩個運動向量,並取預測差值和運動向量傳送。接收端根據運動向量在兩個參考幀中“找出(算出)”預測值並與差值求和,得到B幀“某點”樣值,從而可得到完整的B幀。
B幀特點
- B幀是由前面的I或P幀和後面的P幀來進行預測的;
- B幀傳送的是它與前面的I或P幀和後面的P幀之間的預測誤差及運動向量;
- B幀是雙向預測編碼幀;
- B幀壓縮比最高,因為它只反映丙參考幀間運動主體的變化情況,預測比較準確;
- B幀不是參考幀,不會造成解碼錯誤的擴散。
VideoToolBox
iOS8以上才支援,硬編碼庫。
VideoToolBox:developer.apple.com/documentati…
FFmpeg
iOS暫時支援軟編碼,不過軟編碼適配比較多格式和機型。
推流知識點
Rtmp協議
是Adobe的一個沒有完全公開的基於TCP上的協議。
優點:延遲低,正常來說3s左右。而且支援加密。 缺點:iOS、安卓來說需要另外支援的播放器來播放,H5也沒辦法直接播放Rtmp協議的,所以很多H5也會用HLS來播放。還有一點是Rtmp基於TCP協議,所以RTMP會累積延時,所以當累積到一段時候需要清除延時。
HLS協議和HTTP協議
優點:協議簡單,效能高。 缺點:延時比較高,而且HLS延時是根據分塊大小決定。
Demo
github:github.com/KoonChaoSo/…