1. 程式人生 > >直播推流方案及過程分解

直播推流方案及過程分解

直播過程

1.相機預覽及資料採集Camera — 取資料(onPreviewFrame(Byte[] rawFrameData, Camera camera))
2.原始幀處理(Rotate旋轉/Scale縮放:使用Libyuv/FFmpeg等工具庫)
3.編碼器編碼得到相應的h24資料(openh264庫編碼)
4.傳送給流媒體伺服器 (librtmp庫推流)
5.伺服器接受及轉發

一、資料採集及預覽

1.Surfaceview+Camera
2.GLSurfaceView +SurfaceTexture (openglees 做濾鏡美顏功能)

二、原始幀處理

onPreviewFrame 預設得到的是NV21格式的資料,需要轉換程I420
2.1轉換I420(YUV420P)

為什麼要使用轉I420
1.Camera預覽格式:NV21、YV12 ,預設是NV21 格式
2.H264編碼必須要用 I420格式的YUV420

YUV420的幾種格式

NV12,NV21,YV12,I420都屬於YUV420,但是YUV420 又分為YUV420P,YUV420SP,P與SP區別就是,前者YUV420P UV順序儲存,而YUV420SP則是UV交錯儲存,這是最大的區別,具體的yuv排序就是這樣的:
I420: YYYYYYYY UU VV ->YUV420P
YV12: YYYYYYYY VV UU ->YUV420P
NV12: YYYYYYYY UVUV ->YUV420SP
NV21: YYYYYYYY VUVU ->YUV420SP

Libyuv庫是一個專門對YUV資料進行轉換縮放旋轉的庫

YUV是Google已經開源了專門用於YUV資料的處理的庫。它擁有如下特性
1、libYUV是一個開源的實現各種YUV,RGB色彩之間的轉換、旋轉、縮放
2、支援windows、linux系統,支援x86、arm架構
3、支援SSE、AVX、NEON加速,在編譯時會根據硬體平臺旋轉使用的實現方式
原始碼地址:
https://chromium.googlesource.com/libyuv/libyuv/

三、視訊編碼

3.1.MediaCodec
NV21 格式並不是所有機器的 MediaCodec 都支援這種格式作為編碼器的輸入格式。 因此,在初始化 MediaCodec 的時候,我們需要通過 codecInfo.getCapabilitiesForType 來查詢機器上的 MediaCodec 實現具體支援哪些 YUV 格式作為輸入格式。一般來說,起碼在 4.4+ 的系統上,這兩種格式在大部分機器上都有支援:
MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar
MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar
兩種格式分別是 YUV420P 和 NV21,如果機器上只支援 YUV420P 格式,則需要先將攝像頭輸出的 NV21 格式先轉換成 YUV420P,才能送入編碼器進行編碼,否則最終出來的視訊就會花屏,或者顏色出現錯亂。

3.2.FFMpeg+x264/openh264
H264編碼必須要用 I420格式

3.3軟硬編對比
從上面的分析來看,硬編的好處主要在於速度快,而且系統自帶,不需要引入外部的庫,但是特性支援有限,而且硬編的壓縮率一般偏低。對於軟編碼來說,雖然速度較慢,但是壓縮率比較高,而且支援的 H264 特性也會比硬編碼多很多,相對來說比較可控。就可用性而言,在 4.4+的系統上,MediaCodec 的可用性是能夠基本保證的,但是不同等級機器的編碼器能力會有不少差別,建議可以根據機器的配置,選擇不同的編碼器配置。

四、rtmp推流

使用librtmp庫推流

五、伺服器搭建

nginx-rtmp-module搭建rtmp流媒體伺服器