一、音視頻封裝格式原理:
??????????我們播放的視頻文件一般都是用一種封裝格式封裝起來的,封裝格式的作用是什么呢?一般視頻文件里不光有視頻,還有音頻,封裝格式的作用就是把視頻和音頻打包起來。 所以我們先要解封裝格式,看有哪些視頻流和哪些音頻流,此時的音頻流和視頻流都還是壓縮數據,不能直接用于顯示的,這就需要解碼。
????????
? ? ? ? 如FFmpeg 視頻文件就是一個容器 (視頻流(H264) 音頻流(aac))。
? ? ? 1、視頻文件封裝格式:
??????????封裝格式(也叫容器),就是將已經編碼壓縮好的視頻軌和音頻軌按照一定的格式放到一個文件中,也就是說僅僅是一個外殼,或者大家把它當成一個放視頻軌和音頻軌的文件夾也可以。
? ? ? 2、音視頻編碼方式:
- 視頻編碼方式:將視頻像素數據(RGB,YUV?等)壓縮成視頻碼流,從而降低視頻的數據量。包含有HEVC(H265)、H264、MPEG4、MPEG2、VP9等;
- 音頻編碼方式:將音頻采樣數據(PCM?等)壓縮成音頻碼流,從而降低音頻的數據量。包含有AAC、MP3、WMV、AC-3。
? ? ? ?3、編解碼方式和封裝格式的關系:
????????????????「視頻封裝格式」= 視頻 + 音頻 +視頻編解碼方式 等信息的容器。
? ? ? ?4、RGB/YUV概念:
????????通常我們采用RGB模型
來表示顏色
,RGB模型中,每種顏色需要3個數字分別表示R、G、B
,每個數字占用1個bit字節
,這樣總共需要24bits
。
? ? ? ? YUV能更高效顏色模型用更少的bit來表示顏色,Y——表示亮度,也就是灰階值,U和V表示色度分量。
- ?YCbCr顏色模型基本原理:
????????假設我們定義一個?「亮度(Luminance)」?的概念來表示顏色的亮度,那它就可以用含 R、G、B 的表達式表示為:
Y = kr*R + kg*G + kb*B
????????Y 即「亮度」,kr、kg、kb 即 R、G、B 的權重值。
????????可以定義一個?「色度(Chrominance)」?的概念來表示顏色的差異
Cr = R – YCg = G – YCb = B – Y
????????Cr、Cg、Cb 分別表示在 R、G、B 上的色度分量.。
- YUV:關鍵是在于它的
亮度信號 Y
?和色度信號 U、V
?是分離
的,那就是說即使只有 Y 信號分量而沒有 U、V 分量,我們仍然可以表示出圖像,只不過圖像是黑白灰度
圖像。在YCbCr 中 Y 是指亮度分量,Cb 指藍色色度分量,而 Cr 指紅色色度分量。 - YCbCr 與 RGB 相互轉換的公式:
Y = 0.299R + 0.587G + 0.114BCb = 0.564(B - Y)Cr = 0.713(R - Y)R = Y + 1.402CrG = Y - 0.344Cb - 0.714CrB = Y + 1.772Cb
????????
二、H264編碼框架:
?????????視頻編碼方式就是指通過特定的壓縮技術,將某個視頻格式的文件轉換成另一種視頻格式的文件的方式。H.264和H265編碼是目前視頻格式中用得最廣泛的編碼方式,H.264創造了多參考幀、多塊類型、整數變換、幀內預測等新的壓縮技術,使用了更精細的分像素運動矢量(1/4、1/8)和新一代的環路濾波器,使得壓縮性能大大提高,系統更加完善。H.265是ITUTVCEG繼H.264之后所制定的新的視頻編碼標準。H.265標準圍繞著現有的視頻編碼標準H.264,保留原來的某些技術,同時對一些相關技術加以改進。H.265旨在在有限的帶寬下傳輸更高質量的網絡視頻,僅需要原先的一半帶寬即可播放相同質量的視頻。
? ? ? ? 1、H264碼流文件分層:
- VCL(Video Coding Layer,視頻編碼層):負責高效的視頻內容表示,VCL數據即編碼處理的輸出,它表示被壓縮編碼后的視頻數據序列。
- NAL(Network AbstractionLayer,網絡提取層):負責以網絡所要求的恰當的方式對數據進行打包和傳送,是傳輸層。不管是在本地播放還是在網絡上播放,都要通過這一層來傳輸。
? ? ? ? 2、H264編碼原理:
- ?H.264/AVC并未明確表述一個編解碼器如何實現,而是規定了一個編碼的視頻比特流的句法和該比特流的解碼方法,因此在實現上有較大的靈活性。H264和以前的H261、H.263、MPEG-1、MPEG-4 等的編解碼器功能模塊的組成類似,不同的部分是其內部各功能模塊的細節部分,H.264編解碼器的功能組成如下:
????????
- ?H.264/AVC 編解碼器的工作原理。H.264編碼器采用變換和預測混合編碼方式。編碼時,首先輸入的幀或場Fn以宏塊為單位被編碼器處理。宏塊有幀內和幀間兩種模式。幀內模式使用當前幀內已編碼的宏塊進行預測。幀間模式使用以往一個或多個幀作為參考進行運動預測。然后,對預測值和原始值的差值進行變換、量化、重新排序和編碼,對量化系統X進行逆量化、逆變換后,與預測系統相加,得到未經濾波的uF*幀,對uF*幀進行塊間濾波,得到當前重構幀 Fn*。而解碼過程相對比較簡單,對于編碼器的各部分進行逆向操作,結果經逆量化、逆變換后通過濾波器得到重構輸出圖像。H.264編解碼器工作原理如圖:
????????
?????????3、H264碼流分析:
? ? ? ? H264碼流的結構中包含 :H264視頻序列——圖像——片組——片——NALU——宏塊 ——像素。從大到小排序?? ? ??????????
- H264編碼格式:在 VCL數據傳輸或存儲之前,這些編碼的VCL數據先被映射或封裝進NAL單元中。每個NAL單元包括一個原始字節序列負載(RBSP,RawByteSequencePayload)和一組對應于視頻編碼的 NAL 頭信息。RBSP的基本結構:在原始編碼數據的后面添加了結尾標記,一個比特“1”和若干比特“0”,以便字節對齊。H.264碼流NAL單元序列如圖? ? ? ??
- ?NAL Header:NAL頭由一個字節組成,禁止位(1位)、重要性指示位(2位)、NALU類型(5位)。? ? ? ? ?
????????
- ?RBSP:包括一系列的NAL單元,每個NAL單元包含一個RBSP。典型的RBSP單元序列。每個單元都按獨立的NAL單元傳送。NAL單元的信息頭(1字節)定義了RBSP單元的類型,NAL單元的其余部分為RBSP數據。????????
? ? ?
- SODB ,String Of Data Bits 原始數據比特流:因為它是流的形式,所以長度不一定是8倍數,它是由 VLC 層產生的。由于我們計算機是以8倍數去處理數據所以計算機在處理H264時,就需要 RBSP。
- RBSP,SODB + tailing bits (原始字節序列載荷):由于它是一個壓縮流,SODB 不知道是在何處結束,所以算法在SODB最后一位補一個1,沒有按字節對齊的則補 0。
- EBSP (擴展字節序列載荷):在生成壓縮流之后,在每一幀的開頭加一個起始位,這個起始位一般是 00 00 00 01 或者是 00 00 01。所以在h264碼流中規定每有兩個連續的00 00,就增加一個0x03。
- EBSP 和 RBSP的區別:NALU的組成部分為(NALU = NALU Header + RBSP),嚴格來說NALU的組成部分為(NALU = NALU Header + EBSP);
- ?NALU單元中的參數集:SPS(序列參數集)作用于一系列連續的編碼圖像;PSS(圖像參數集)作用于編碼視頻序列中一個或多個獨立的圖像。參數集是一個獨立的數據單位,不依賴于參數集外的其他句法元素。一個參數集不對應某個特定的圖像或序列,同一序列參數集可以被一個或者多個圖像參數集引用。同理,同一個圖像參數集也可以被一個或者多個圖像引用只在編碼器認為需要更新參數集的內容時,才會發出新的參數集。?????????
- ?NALU中的視頻幀:生成的H264視頻幀是由多個切片組成的。一個H264的幀至少由一個切片組成,不能沒有切片,可以是一個到多個不能沒有。在網絡傳輸的時候一個H264幀可能需要切開去傳,一個一次傳不完,這就按照切片來切。每一個切片組成一個NAL Unit。
- 切片與宏塊的關系:在切片數據中,包含若干個宏塊。在一個宏塊中,又包含了宏塊類型、宏塊預測、殘差數據。
? ? ? ? 4、H264碼流結構圖:????????
? ? ? ? ?5、H264碼流NAL單元解碼流程:
????????首先從NAL單元中提取出RBSP語法結構,然后按照下圖所示的流程處理RBSP語法結構。輸入的是NAL單元,輸出結果是經過解碼的當前圖像的樣值點。 NAL單元中分別包含了序列參數集和圖像參數集。圖像參數集和序列參數集在其他NAL單元傳輸過程中作為參考使用,在這些數據NAL單元的片頭中,通過語法元素pic_parameter_set_id設置它們所使用的圖像參數集編號;而相應的每個圖像參數集中,通過語法元素seq_paramter_set_id設置他們使用的序列參數集編號。????????
?????????6、H264解碼詳解:
?????????H264是新一代的編碼標準,以高壓縮高質量和支持多種網絡的流媒體傳輸著稱,在編碼方面,我理解的他的理論依據是:參照一段時間內圖像的統計結果表明,在相鄰幾幅圖像畫面中,一般有差別的像素只有10%以內的點,亮度差值變化不超過2%,而色度差值的變化只有1%以內。所以對于一段變化不大圖像畫面,我們可以先編碼出一個完整的圖像幀A,隨后的B幀就不編碼全部圖像,只寫入與A幀的差別,這樣B幀的大小就只有完整幀的1/10或更小!B幀之后的C幀如果變化不大,我們可以繼續以參考B的方式編碼C幀,這樣循環下去。這段圖像我們稱為一個序列(序列就是有相同特點的一段數據),當某個圖像與之前的圖像變化很大,無法參考前面的幀來生成,那我們就結束上一個序列,開始下一段序列,也就是對這個圖像生成一個完整幀A1,隨后的圖像就參考A1生成,只寫入與A1的差別內容。
- GOP:在H264中圖像以序列為單位進行組織,一個序列是一段圖像編碼后的數據流,以I幀開始,到下一個I幀結束。?
- GOP序列說明:在 H.264協議里定義了3種幀,完整編碼的幀叫I幀,參考之前的I幀生成的只對差異部分進行編碼的幀叫P幀,還有一種參考前后的幀進行編碼的幀叫B幀。在H264中圖像以序列為單位進行組織,一個序列是一段圖像編碼后的數據流,以幀開始,到下一個I幀結束,中間部分也被稱為一個GOP。一個序列的第一個圖像叫作IDR圖像(立即刷新圖像),IDR圖像都是I幀圖像。H.264引入IDR圖像是為了解碼的重新同步,當解碼器解碼到IDR圖像時,立即將參考幀隊列清空,將已解碼的數據全部輸出或拋棄,重新查找下一個參數集,開始解碼一個新的序列。這樣,如果前一個序列出現重大錯誤,在這里可以獲得重新同步的機會。IDR圖像之后的圖像永遠不會使用IDR之前的圖像的數據來解碼。一個序列就是一段內容差異不太大的圖像編碼后生成的一串數據流。當運動變化比較少時,一個序列可以很長,因為運動變化少就代表圖像畫面的內容變動很小,所以就可以是一個Ⅰ幀,然后一直是P幀、B幀。當運動變化多時,一個序列可能會比較短,比如只包含一個I和幾個P、B幀。
- ?I幀:指幀內編碼幀,I幀表示關鍵幀,你可以理解為這一幀畫面的完整保留;解碼時只需要本幀數據就可以完成(因為包含完整畫面)。特點如下:
- 它是一個全幀壓縮編碼幀。它將全幀圖像信息進行JPEG壓縮編碼及傳輸;
- 解碼時僅用I幀的數據就可以重構完整圖像;
- I幀描述了圖像背景和運動主體的詳情;
- I幀不需要參考其他畫面生成;
- I幀是P幀和B幀的參考幀(其質量直接影響到同組中以后各的質量);
- I幀是幀組GOP的基礎幀(第1幀),在一組中只有一個I幀;
- I幀不需要考慮運動矢量;
- I幀所占數據的信息量比較大。
- 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幀是參考幀,它可能造成解碼錯誤的擴散; 7.由于是差值傳送,P幀的壓縮比較高。
- B幀:雙向預測內插編碼幀。B幀是雙向差別幀,也就是B幀記錄的是本幀與前后幀的差別(具體比較復雜,有4種情況,但我這樣說簡單些),換言之,要解碼B幀,不僅要取得之前的緩存畫面,還要解碼之后的畫面,通過前后畫面的與本幀數據的疊加取得最終的畫面。B幀壓縮率高,但是解碼時CPU會比較累。
?
?
?
?