主頁 >  其他 > 音視頻小白入門

音視頻小白入門

2021-03-05 10:23:30 其他

音視頻小白入門

  • 1 一些說明
  • 2 音頻介紹
    • 2-1 音視頻處理流程
    • 2-2 聲音是如何被聽到的
    • 2-3 聲音的三要素
    • 2-4 模數轉換
    • 2-5 PCM與WAV
  • 3 音頻的編碼技術
    • 3-1 音頻有損壓縮技術
    • 3-2 音頻無損壓縮技術
    • 3-3 幾種常見編解碼器的比較
    • 3-4 AAC編碼器介紹
    • 3-5 ADTS格式
    • 3-6 通過ffmpeg生成AAC資料
  • 4 音頻操作
    • 4-1 什么是音頻重采樣
  • 5 影像的基本知識、YUV
    • 5-1 影像的基本概念
    • 5-2 螢屏顯示幕
    • 5-3 碼流的計算
    • 5-4 影像的顯示
    • 5-5-1 什么是YUV
      • 簡介
      • YUV采樣格式
      • 什么是掃描線(scan line)
      • 宏像素 (macropixels)
      • YUV4:4:4
      • YUV4:2:2
      • YUV4:2:0
      • YUV存盤格式
      • 4:4:4,24位像素深度
      • 4:2:2,16位像素深度
        • YUY2
        • UYVY
      • 4:2:0,12位像素深度
        • IMC2
        • IMC4
        • YV12&I420
        • NV12
      • 劇終
    • 5-5-2YUV
    • 5-6 YUV的常見格式
    • 5-7 YUV的存盤格式
    • 5-8 YUV操作
  • 6 H264技術介紹
    • 6-1 H264壓縮碼率與GOP
    • 6-2 H264中的I幀P幀和B幀
    • 6-3 H264中的宏塊
    • 6-4 幀內壓縮技術
    • 6-5 幀間壓縮技術
    • 6-6 H264無損壓縮及編解碼處理流程
    • 6-7 H264碼流結構
  • 7 H264中的引數
    • 7-1 H264中的profile和level
    • 7-2 H264SPS中的重要引數
    • 7-3 H264PPS與Slice-Header
    • 7-4 H264分析工具1
  • 8 RTMP和FLV
    • 8-1 RTMP連接的建立
    • 8-2 創建RTMP流
    • 8-3 RTMP訊息
    • 8-4 RTMP抓包分析
    • 8-5 FLV協議
    • 8-6 FLV協議分析器
    • 8-7 推流程式的骨架

1 一些說明

音視頻技術,本身紛繁復雜,對于初學者來說可不那么容易,網上沒有一門系統講解音視頻技術知識與實戰的課程,更可怕的是,網上的內容和講解的水平參差不齊,漏洞百出,那基本上全是坑,有很多人就是掉到坑里,爬不出來了,
對音視頻基礎知識的系統掌握程度實際決定著你今后能夠走多遠走多高,俗話說得好 基礎不牢地動山搖,那對于音視頻開發來說就尤其如此,一個小的知識點掌握得不好,就有可能卡你好幾天,
把基礎的音視頻知識學習好,才能學習其他更高階的東西,這樣對于作業才能游刃有余,

并且音視頻基礎知識都是音視頻面試環節中必不可少的面試點,比如說gop是什么,為什么會產生花屏和卡頓,關鍵幀的時間間隔是多長等等這些呢,都是我們面試中,經常被問到的問題,所以你掌握了音視頻的作業原理之后,才能應對面試官提出的原理性問題,

那么了解了原理之后,采集編碼,可以開始學習流媒體服務器,那在流媒體服務器這一塊呢,我們首先可以學習Nginx來搭建一個最初級的自己環境內部的流媒體服務器,那么通過這個服務器呢我們就可以進行推流和拉流了,那么之后,可以看看SRS,SRS是一個比較成熟的這個商業方案,如果你的公司具有一定的資源能夠拿到很多的硬體資源的話,那你完全可以通過srs搭建一套可以商用化的流媒體服務集群,那你說我自己的公司或者是我自己的這個掌握資源也沒有這么多,那這個時候呢如果你還想打造這種商業的媒體服務器,其實還有一種辦法就是通過CDN網路,那么有很多的cdn廠商了,包括阿里對吧騰訊等等等等,

相對來說呢,音視頻的知識比較龐雜枯燥,有很多很小很瑣碎的知識點,這也是為什么在網上很難找到比較系統的介紹音視頻知識的資源,

本文為學習筆記,所以里面會有很多亂七八糟重疊或是參考一些大佬的見解,冒犯之處,見諒,

2 音頻介紹

2-1 音視頻處理流程

在講解音頻之前呢,我們首先來了解一下音頻的整個處理流程,對于這個處理流程的了解,對于我們后邊學習音頻有個至關重要的作用,

整個在音頻處理的程序中它需要經歷幾個步驟,對于每一個不同的步驟你都應該做哪些事情,你需要清楚整個的這個音頻流轉的大的這個方向是什么,

在這里插入圖片描述

首先對于音頻的處理流程,實際是包括了兩個層面的,(基于這個娛樂直播系統作為這個背景)
第一個層面,是直播客戶端的處理流程,
第二個層面呢,是這個音頻資料的流轉,也就是說當我采集后,那采集的是什么資料,在我編碼之后編碼出的是什么格式,

在這里插入圖片描述

下面呢,我們就來看一下直播客戶端的這個處理流程,我們在進行這個直播客戶端撰寫的程序中啊,要分成幾個模塊,那對于不同的模塊,你要做不同的事情,那么對于音頻來講呢,首先你要做的事情就是音頻的采集,對音頻的采集實際我們只要調一些相關的api就可以了,并不是特別的復雜,但是對于不同的平臺,這些api其實是完全不一樣的,比如說我們在這個安卓端他有audio_record還有media_records,那我們什么時候應該使用audio recording,什么時候應該用media record,那在這個ios端的也有很多的錄制音頻的方法,比如其實大家最常用的可能是…這是非常底層的一層api,在它的上層呢,其實還有av foundation這一層的api,那我們又該如何選擇呢 ,那這些呢,其實都是我們必須要知道的,對于我們后邊深入的學習音視頻必須要知道的,但是在知道這一切之前,我們應該知道對于音頻來說,你第一步要做的事情就應該是從你的麥克風上,你的音頻設備上將這些資料抓取到,這是我們這個直播客戶端要做的第一件事,就就是音頻的采集,那當你采集完音頻之后,那你要想傳輸實際再說并不能直接進行傳輸,為什么呢,因為這時候采集的資料它的資料量是非常大的,當你要直接放入到網上給他傳入到對端的時候,那就很有可能由于你的資料量比較大,從而將整個的這個網路線路給打死,讓大家想到的辦法就是將這個非常大的音頻也好,視頻也好,進行一個編碼,編碼后的資料就是非常小的資料了,它對于編碼這塊的具體的分為有損編碼跟無損編碼,對吧,什么時候應該用有損,什么應該無損,那么有損是去掉了哪些資料,這些呢下面會說明,
那這就是我們的這個客戶端的一個共享端,客戶端應該是有共享端和觀看端兩個端,要共享端做的就是這個音視頻的采集,采集完編碼,編碼完傳輸到對端,那對端就是觀看端,那首先他要將接收到的所有的資料先進行解碼,揚聲器讓他去播放那個聲音,但它是沒法播放的,他必須要將原來壓縮后的資料,解碼后,還原回原始的資料,那么拿到原始資料之后呢才能交給這個播放器,如果是視頻的話應該是交給渲染器進行渲染,如果音頻的話交給揚聲器直接播放出來,由driver再驅動硬體模塊將聲音播放出來,

當我們通過 audio record 、media records或者是這個audio unit類似的這些api去做這件事的時候去采集資料的時候,那么現在我們 只要知道我們采集的資料就是PCM,他是一個數字信號,我們自然中說話的這種聲音,各種聲音它是一種模擬信號,將模擬信號轉成數字信號,這個數字信號的就是PCM資料,那拿到這個PCM資料之后經過編碼器(那就有很多的編碼器了,我們知道的比較熟悉的有AAC編碼器,mp3編碼器對吧),經過這個編碼器之后呢就編譯出相應的編碼格式,拿到壓縮(編碼)后的資料之后我們可以在它外層,給它套一個套,相當于給她穿了一件馬甲,那么給它套了一層這個格式之后,就產生了這樣一種格式的多媒體檔案,
對于我們的直播系統來說呢,采集的時候你采集出PCM,編碼后的編碼成具體的這個壓縮后的資料直接進行傳輸了,而沒有生成多媒體檔案,但是有些情況下呢,你可能需要生成多媒體檔案,

2-2 聲音是如何被聽到的

在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述

2-3 聲音的三要素

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

2-4 模數轉換

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

2-5 PCM與WAV

對于音頻來說,有一個位深或者需要采樣大小的一個概念,這個采樣大小是什么意思呢,就是說你能夠表述的這個數值的最大范圍值是多少,一般情況下呢,是使用八位或者是16位,八位呢它是表述的范圍就是負128到正128,無符號數就是0到255,如果是16位就是負32768到正32768,這樣一個范圍,他們表現的這個值呢,是非常大的,

在這里插入圖片描述

對于音頻的原始資料來說,它包括這三個重要的概念, 但在介紹這個之前呢,我們首先要知道我們要存盤音頻的原始資料的格式是什么,那實際上最常用的有兩種格式了,PCM和wav,這個PCM資料就是純的音頻資料,他沒有任何的格式,對于PCM資料來說,里邊的每一個資料,它是有一定的含義的,如果你把它封裝成一個多媒體檔案的話,就有了一個檔案格式的概念,就是wav,WAV呢,你既可以存盤原始資料就是PCM資料,也可以存盤這個壓縮資料,但是大多數情況下,99%我們都用wav來存盤原始資料,也就是PCM資料,那什么意思呢,其實WAV他就是在pcm這個原始資料之上, 套了一個頭,這個頭呢包含了一些最基本的資訊,現在我們只要知道對于音頻的原始資料來說,一種是PCM資料,它是純的音頻資料,另外 一種是在PCM上加了一個頭的wav,

在這里插入圖片描述

那么我們再來看看 這個量化的基本概念啊,現在我們來一一看一下,第一個就是采用大小或者說是有的地方叫做位深,就是說你的這個位深 越大,它描述的這個峰值就越大, 描述的峰值越大,那么這個對于我們一段聲音的波形來說,他的這個聲音的強度其實是更真實的,

他第二個呢是采樣率,就是說對于一段音頻波形來說,我們進行這個模數轉換的時候,那我是按照什么樣的這個頻率采樣了,這都是我們常見的采樣率,采樣率越高,與模擬信號之間的模仿呢就越接近,對吧,它的誤差就越小,那么你采樣率越低,那么有一些很敏感的資訊他就忽略掉了,對于我們通常打電話來說一般都是8k的采樣率,

那么第三個呢 就是聲道數,那分為單聲道雙聲道和多聲道或者我們稱為立體聲,三個以上的就稱為立體聲了 ,有的認為是兩個是立體聲,這個沒關系,我們只要知道這個聲道數其實是在我們這個聽聲音的時候是非常關鍵的一個要素就好了,但實際就是對于我們正常人來說分為左耳和右耳,實際它就是雙聲道,左耳聽到一個聲音,右耳聽到一個聲音,當然,這個雙聲道的時候,可能兩個聲道的聲音可以是一模一樣的 ,也可以兩個聲音是有不同的,對于多聲道,我們可以想像在我們的一個電腦上我可以擺六個喇叭,那每一個喇叭呢就是一個聲道,這樣呢 如果他把你環抱起來的話,實際就是形成了一個立體聲,就在前后左右上下很多的方向你都可以放一個喇叭這樣你的感受的音響的效果就會更好,比如說我們在電影院啊你聽到那個聲音就非常震撼,但是如果同樣的影片你拿到電腦上去我們的普通耳機去聽的話那就效果就會差很多,對就是這個道理,

所以我們進行這個量化的時候有三個概念,PCM資料就是你的采樣大小乘以你的采樣率,乘以你的聲道數,就是一個采樣,就一秒鐘的采樣了多少,這資料是多少,

正常網路,比如我們是十兆的光纖,上行和下行其實它是有一個比例的,下行是10M,但是上行可能只有2M,4M,你光傳一個音頻就是被壓縮的音頻就非常的這個困難,可以這么大的碼流顯然是無法在我們的網上傳輸的,所以我們要進行這個資料的壓縮壓縮后的資料就非常小了

在這里插入圖片描述

在這里插入圖片描述

3 音頻的編碼技術

3-1 音頻有損壓縮技術

在這里插入圖片描述

圖片

那所謂的音頻編碼呢,實際就是音頻的壓縮技術,

對于音頻壓縮技術來說,他實際是追求兩個極端,第一個極端是將資料量壓縮得越來越小對越小越好,對吧,第二個極端是壓縮的速度越快越好,當然這兩個極端來說,它是有一些這個悖論的,很難達到既壓縮得最小,又能壓縮的最快,一般情況下呢,要尋求一個平衡點,就是說我壓縮的點已經適合于網路傳輸了,那么同時呢他速度又特別快,這個編解碼技術,是最適合我們的實時通訊傳輸的,這是我們最喜歡的一種編碼技術ok,

對于我們這個音頻的壓縮來說,那所謂的消除冗余資訊,我們應該有一些了解,比如說我們所講的人的聽覺范圍是在哪呢,是在20赫茲以上到兩萬赫茲以下,這段其實是我對于我們人來說是最敏感的,對吧那根據這個原則,20一下以及兩萬赫茲以上的這個資料,其實我們采集到了但也是沒有任何意義的資料,對吧所以這些資訊呢都屬于冗余資訊,對于這部分資訊我們都應該將它踢除掉對而且這些資訊t除掉之后,它就沒法再恢復回和原來一模一樣了,對吧所以這也稱為什么呢稱為有損壓縮,這所謂有損壓縮技術就是說當我們把資料進行壓縮之后就無法再還原回和原來一模一樣的資訊吧,

那第二種呢就是無損壓縮,剩下的就是我們人比較敏感的一些具體資訊,但對于這些資訊呢我們在進行一下無損壓縮,讓他這個資料量變得更小,那這樣就達到了一個非常好的壓縮效果對吧,像無損壓縮技術比如說我們傳統7z…等等,

圖片

圖片

3-2 音頻無損壓縮技術

熵編碼是一系列技術的統稱,

圖片

圖片

在這里插入圖片描述

3-3 幾種常見編解碼器的比較

OPUS它有什么特點呢第一個是延遲小第二個是壓縮率高,做實時通訊的相關應用的,基本上都使用的是OPUS,

AAC呢可以說是目前應用最廣泛的一款編解碼器,

OGG由于它是這個收費的,所以應用的不如前面這兩款呢應用的廣泛.

那在他們之前呢其實speek是應用的相對比較廣泛的一款編解碼器,它有一個非常好的一個功能,就是它包括了這個回音消除,這個功能那在之前的這種實時通訊的領域中呢那回音消除可以說是一個非常難以解決的問題.

G.711是屬于窄帶音頻,也就是說它編碼后的這個資料呢非常小,適合于在非常窄的這個網路上進行傳輸,但是它有一個非常不好的一點就是它的這個聲音損耗特別嚴重,像我們正常的通話他都有失真的這種情況,如果你要是播放一些音樂檔案,樂器的一個聲音,其實聽起來要保真性要特別好才行,他就不適合

由于webrtc,所以OPUS在未來大概率會把AAC淘汰掉

圖片

圖片

圖片

3-4 AAC編碼器介紹

那么在這么多的編解碼器中呢,其實目前常用的編解碼器就兩種OPUS,AAC,

aac呢可以說是最成熟而且是應用最廣泛的一種編解碼器,那么對于每一種編解碼器來說其實他都有各自的特點,你要想使用某一種編解碼器的,你需要對它做一個深入的研究,而這里,我們使用的編解碼器主要是aac,所以讓我們對aac作一下重點的這個講解,首先呢我們要知道AAC是由何而來的對吧它.

他的目的呢就是取代這個mp3,因為mp3相對來說他的存盤的這個檔案壓縮比,還是比較低啊,壓縮后的檔案比較大…

AAC兩個優點,壓縮率高,保真性好,

AAC LC、AAC HE V2比較常用,AAC HE V1用的比較少,基本被V2取代,

圖片

圖片

圖片

在這里插入圖片描述

3-5 ADTS格式

圖片

圖片

圖片

圖片

3-6 通過ffmpeg生成AAC資料

-i : input

-vn : video none

-c:a :codec audio

libfdk_aac應該算是AAC編解碼器中性能最好的一款編解碼器

-ar :audio sample_rate

-channel 雙聲道

在這里插入圖片描述

圖片

4 音頻操作

4-1 什么是音頻重采樣

在這里插入圖片描述

三元組中任意一組值發生改變,都叫重采樣,

采樣大小(比如16位),有的地方叫位深,

圖片

那么另外一個呢就是便于方便運算,比如說我們在處理音頻的時候有一個非常有名的一個問題,就是回音消除問題對吧,在一般的回音消除的時候,我們都會將這個音頻的聲道呢變成單聲道,為什么呢,因為在處理回音消除的時候,只有一個聲道的時候,這個資料是最單純的,是最好處理的,如果你是多聲道的時候,兩個聲道很有可能他那個聲音是不一樣,對吧,我們在聽一個比較高音質的音頻的時候,你會發現左聲道和右聲道他們是有一些差別的,有的是低音重一些,有的是這個高音重一些對吧,反正就是總是有一些不一樣,他會達到一個非常好的一個效果,讓他們兩個聲道保持一些差別,讓你聽出來的聲音呢更有立體感,那這樣就給這個回音消除造成了很大的這個困難,你左邊的聲道是這樣,右邊聲道是這樣,我應該怎么消除呢,它很難計算,所以這個時候呢,一般我們會把雙聲道變成這個單聲道呢,那這樣呢就為了便于我們的運算,

圖片

FFMPEG是跨平臺的,所以它上面都有大部分平臺的設備引數

圖片

圖片

5 影像的基本知識、YUV

5-1 影像的基本概念

圖片

就是它是由一組影像組成,為了傳輸或者是占用更小的空間而被壓縮的,一般情況下呢,在顯示設備上進行顯示的資料,叫做視頻,一般情況下我們所說的這個視頻呢都是經過壓縮的,主要是為了占用更小的空間或者是在傳輸的程序中呢,它這個傳輸的資料量比較小,所以要進行一個壓縮,否則的話它就占用的空間特別大,那他最終在哪顯示呢,就是在這個顯示設備上,那通過這個簡單的定義呢我們就知道這個關鍵點了,圖象、壓縮和顯示設備,那下面呢我們就對這幾個關鍵詞呢一一做一下講解,

圖片

影像呢,它是由像素組成的,大家都非常清楚,在這里呢我們可以看一下這個這張小圖,這張小圖 呢是有很多的小格子組成的,當然,這里面呢這個清楚的表達我這個含義呢,在每個小格子這個邊上呢都有一個線,那真實的在顯示設備上去看的時候,它不可能出現這個線路,所以那通過這些小格子的拼裝呢,我們就能拼裝成一張圖是吧,這是像素,而像素都是RGB組成的,每一個像素它的顏色都是通過rgb來展示出來的,再有一個重要的概念呢,就是解析度,那這么多的小格子這么多的像素,它就有一個解析度,所謂的解析度呢,其實就是你這個橫向x軸有多少個像素,縱向有多少個像素,他的這個乘積,也就是說整個這張圖是有多少個像素點描述出來的,

在這里插入圖片描述

上面的圖呢,就是像素,可在這一個像素中實際在顯示幕上呢,就是由三個發光二極管然后組成的,一個是紅色一個是綠色一個藍色,

在這里插入圖片描述

圖片

對于RGB來說呢,就是每一個像素是由三個發光二極管不同的顏色組成的,對吧.那當每個發光二極管顯示的亮度不一樣的時候,它們就組成了各種不一樣的顏色,

在這里插入圖片描述

那對于每一個像素來說呢,它還是有一定的位深的,所謂位深就是我們用多少個位,來表示一個像素,我們來看一下那最常見的呢,是RGB888,就是每一個元素呢,是占一個位元組,是占用八位,所以一個RGB呢,它是由24位組成的,這是我們通常情況下的這個資料,

它還有一種呢,是RGBA,它是占32位,它的含義呢,就是透明度,也就是說你這個顏色他的這個透明度是什么樣子的,那有的呢,是完全不透明的還有是半透明的,那通過什么來控制的呢,實際上就是通過這個A, RGBA這種方式呢他就是在用32位,最后一位用來控制A的,也就是它的這個透明度是多少,

5-2 螢屏顯示幕

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-VU1KNMLr-1610356447473)(https://uploader.shimo.im/f/CUmnUBKMdBNcPkZH.png!thumbnail?fileGuid=Xk3wQdKCdtV3twqC)]

先來看一下像素,其實像素的概念最原始的就是從顯示幕來的,因為你要顯示 嗎,才會有像素,那將每一個點都點亮,每一個點都有不同的顏色,最終將它拼成一幅圖,這才是真正像素,它的由來對吧,而對于我們影像來說呢,為了能夠讓我們的顯示幕,讓哪個像素點亮,哪個不亮,每個像素點顯示不同的顏色,對吧,所以我們這個影像也就是說它的資料也要對應有像素的概念,所以一談到像素,就是有兩個方面的,一個是我們的顯示幕是有像素的,另一方面呢是我們的影像資料是有像素的,

圖片

那么如果我們用顯微鏡去看一下我們螢屏的話,其實我們的螢屏就是這個樣子,每一個點其實都是由三個發光二極管組成的,就是紅綠藍對吧,我們這么看,從右往左看,紅綠藍每個都是紅綠藍、紅綠藍、RGB,對吧,那有無數的這些發光二極管,最終呢,組成了我們整個的螢屏,而 每三個發光二極管紅綠藍就組成了一個像素,根據我們影像的資料,它是什么顏色的,然后去控制這個發光二極管的強弱,光的強度跟弱度,從而最終形成我們不同的顏色,最終拼在一起呢,就形成了我們真正看到的影像,對吧,ok這就是螢屏,

圖片

好,那影像與螢屏的關系通過我們剛才的這個介紹啊,你應該已經基本清楚了,那影像呢它是資料對吧,最侄訓通過資料來驅動整個螢屏,去顯示,ok這就是影像與螢屏的關系,

圖片

好了解了這個之后呢,后邊我們在展示的時候那你就非常容易理解了,另外一個我們需要知道的就是rgb的顏色問題,實際上實際生活中,我們RGB影像,在很多情況下,并不是RGB,它是BGR,有同學就會發現就有一些影像你在展示的時候,它的顏色實際上是不對的,就是因為它本身資料不是RGB而是BGR,也是三原色, 但是它們排列的順序不一樣了,這樣就導致了你最終送給這個顯示幕顯示的時候,是你送的是BGR資料,這個對于顯示幕的驅動來說,他并不知道你送的是BGR啊,它還按著RGB的資料去解釋,螢屏上去渲染,這樣造成什么問題呢,就造成你的色彩與真實的色彩是不一樣的,所以我們要做的時候,怎么做呢?其實對于這種BGR資料,把它轉換成RGB資料,轉換完了之后你再去渲染的時候這個問題就迎刃而解了對吧,知道原理之后,你才能知道問題的根源是在哪,他有很多同學,在這個底下就會問我,說為什么我這個圖片展示的時候以真實的那個圖片展示不一樣,或者說我自己編的程式展示出來了這個顏色不對,而別人用別的圖片瀏覽器去看的時候呢,顏色是對的,什么原因呢,其實就是這個原因,非常簡單,你只要知道這個原理就特別容易去解決這個問題對吧,

那什么資料使用的是BGR這個格式呢?就是bmp這種格式,所以我們在播放bmp這個影像的時候,一定要想著先進行一次轉換,再進行展示就ok了,那一般的情況下我們用什么庫或者說是怎么寫這個函式去將轉成RGB呢,一種方法呢,是你了解他整個的結構之后,你自己去寫一個程式就轉換,對吧這其實非常好寫,只不過順序做一下變化,你讀出每一個像素點的值給他做一下轉換,再重新存進去就ok了 這是一種方式,那還有一種方式呢,就是我們用別人寫好,現成的庫去做這件事,比如所FFMPEG庫,它里邊有一個LIB_SW_square,那就是專門做這個事了,也不是專門做這個事的,算是是其中的一個小的功能對吧,你調一下這個api就可以完成轉化了,這是RGB的一個色彩問題,

圖片

好,另外呢,我們還要了解一下這個螢屏的指標,那經常我們會看到一些指標它是什么含義對吧,第一個呢是ppi,就是每英寸的這個像素數,比如說我們手機上經常會看到這個PPI,其實它跟解析度呢是很類似的,但是他這個指標呢,就是你這個螢屏,比如說橫向的,在這個一寸長的距離內,一共放了多少個像素點,當然你放的像素點越多,說明你的密度越大,他的這個顯示效果就更細膩,就會更好對吧, 那我們就能知道如果你像素密度特別多的話,那你這個螢屏一定是一塊比較好的螢屏,因為你這個空間很小嘛,空間很小,你能放那么多的二極管 ,那說明那個技術非常厲害了對吧,

第二個呢是DPI,是指的每英寸的點數,實際這個ppi和dpi基本就是相同的,是一對一的關系,但是對于有些螢屏來說呢,這個dpi是每英寸的點數,對于每一個點來說,他有可能包括的不只是一個像素,可能是多個像素,對于這種螢屏呢其實是比較少見的,基本上是ppi就等于dpi,這個稍作了解就OK.

那有一個指標啊,PPI>300,再一寸這么大的一個距離里呢,如果你能放300個以上的像素,那就達到了視網膜的級別,所謂的 視網膜級別,就是我們人眼已經區分不出來它里邊兒是由像素組成的,對吧,就認為它就是一塊的東西,我們就認為他們是一體的,并不能看出里邊兒每一個小的點對吧,這也就是螢屏的指標,

5-3 碼流的計算

圖片

我們來介紹一下,碼流的計算,對于碼流的計算呢,我們首先要知道兩個簡單而且非常重要的概念,第一個是解析度,第二個 呢是幀率,

x軸乘以y軸的像素個數,那當然我們一般的時候就是通過這個x來表達,他并不需要真正計算出他到底等于多少,其實我們想知道的就是它寬是多大高是多大,常見的寬高比呢,16:9或者是四比三,對于四比三來說大家可能見得比較少了,比如說像我們以前看的電視機,都是四比三的,還有包括我們以前非常老的這種顯示幕,像九幾年的時候,我們那個顯示幕呢就是方方正正的那種,基本上都是四比三的這個顯示幕,看隨著這個技術的發展呢現在基本上都是16比九的,對于視頻來說那幾乎都是16比九,那這兩個呢其實都是我們的一個常規的格式,那如果你的這個視頻呢,這個寬高不是這種16比九或者四比三的,那它屬于一個非標準的這個視頻的解析度,那對于這種解析度呢其實我們要做一次轉換,要把它轉換成四比三或者16比九,有很多時候呢我們在做這種這個渲染的時候啊,不是這兩種情況下,那你在渲染的時候呢,就會容易出錯,渲染出這個結果呢,與你想達到的結果并不符合你的預期,所以我們在拿到這個非標準化的時候一定要想著先把它轉成這個16比九或四比三,之后呢我們再去渲染這樣,才是一個標準的流程,其實這些最基本的概念其實是非常重要的對吧,很多的問題都是由于你概念的不清楚,才導致了這個你最終費了九牛二虎之力,可能是為了解決一個問題花了一周或者兩周的時間還解決不好,最根本的原因就在于你對這個原理不了解,如果你對這個原理清楚的話,也就是分分鐘的時間,那第三個呢就是我們常見的這種解析度啊,有這個360p,720p,1K,2K,那360p呢其實就是640乘以360,720p呢,這個就是高清了,就是1280乘以720,大家自己去這個看一下就ok了對吧,那等于四比三呢我們常見的是640乘以480,

圖片

所謂幀率就是每秒鐘采集或者播放影像的個數,對于播放器來說,每秒放多少幀,就是幀率,對于我們采集的設備來說我們要從設備上采集 影像,就是每秒鐘我們能采集多少幀,那就是它的幀率,實際上就是每秒鐘影像的個數,那對于普通的影片來說,像我們以前的影片片都是25幀每秒,但實際上呢在我們真正的這個遠程通訊或者是這個看電影的時候,他們的幀率都是不一樣的,比如對于我們實時通訊來說,一般情況下,我們為了調低碼流大小,我們會把它設成這個15幀,與你的帶寬是有密切關系的,如果你帶寬足夠的話,當然是越高越好,但是為了保證實時性,防止資料量太大,把你的帶寬打死,那么這個時候呢,我們可能會調低你的這個幀率,那最低的情況下呢,一般我們就保持每秒15幀,其實就可以基本滿足我們實時通訊的這個要求了,除非說,你的這個通訊時,對這個視頻質量要求特別高,比如說我們是遠程的教學中的這個繪圖對吧,這個時候呢你的這個要求的清晰度跟這個幀率呢,可能會高一些,但對于一般呢,我們只是顯示一個頭像的話,其實你15幀每秒其實沒有任何問題的,

比如錄制視頻,這種情況下呢,一般我們都是30幀每秒,就滿足了我們日常的這個需求了,60幀每秒呢比如我們的這個電影兒對吧,電影在這個拍攝的時候基本上都是在60幀以上的這種幀,那這樣呢,可以保證一個非常平滑的一個效果就是每一個細節你都看得非常清楚,尤其是人的面部表情,要求的這個平滑度越高,那對你的這個幀率啊,就要求越高,那對于你顯示的清晰程度實際是與解析度密切相關的,是吧,那你想讓這幅圖非常的清晰你就解析度特別高,那你想讓那個視頻特別平滑那你就幀特別高,ok,

在這里插入圖片描述

那介紹完這兩個概念之后呢,我們現在就來看一下,未編碼的這個RGB的碼流如何計算,比如說 一個720p的就是1280乘720乘以3乘以25,可最后我們約等于多少呢約等于69兆對吧,但這個是不是這個我們通常所說的碼率呢,并不是,我們通常所說的碼流是按位來計算的,所以應該是69M再乘以一個8,500多M,

圖片

5-4 影像的顯示

圖片

看今天呢我們就來說一說影像的展示,那所謂的影像呢其實之前的課程中呢我們已經向你介紹過了,它就是用于螢屏顯示的資料,在影像與顯示幕之間呢他有很多概念是相通的,他們中的這個像素呢都是由rgb,這是我們第一個,要知道的那第二個呢他有解析度的概念對吧,

因為顯示幕的大小很有可能是不一樣的,在不同的場景下我們的這個影像呢應該如何去展示,這里舉得這個例子就是影像大小等于顯示區域大小,當我們真正去顯示的時候并不是說將整個螢屏都是占用了,對吧,我們會寫一個這個app,在app里呢有一個顯示空間,那這個顯示空間呢它也有一個大小,比如說我們默認的720P,那我們影像呢如果也是720p的,那說明這個影像大小等于顯示區域大小,那就是1比1的關系,直接將影像放進去之后進行展示就ok了,那還有什么呢,還有這個影像小于顯示區域的,可這個時候呢我們就要有兩種選擇了,一種呢是將圖片進行一個拉伸,可拉伸之后呢,符合我們整個顯示區域大小之后,然后進行展示,那拉伸之后,影像有可能會發生一些變化,比如變形,那還有一種可能呢,就是說我們這個影像雖然很小,但是它四周有留白,就不用管你的這個顯示區域是多大我的影像就這么大,

還有一種case呢,就是影像大于顯示區域,那如果你的影像視屏顯示區域大的,那也有兩種辦法那第一種辦法呢就是將影像進行縮小,另外我的顯示區域就這么大,那你圖片很大沒關系呀然后我就給你上下左右切掉,

圖片

圖片

圖片

圖片

一般情況下我們會左右留白,很少有上下留白的,那這里我舉了一個特殊的例子,可能就是這個影像哪兒都比較小,所以要進行四周的留白,當然對于這種情況呢,其實我們做下拉伸之后呢,然后盡量讓他兩頭不留白,左右留白,這是我們一般的做法,當然你所有的影像啊其實都要符合一個原則,你要符合一個16比九或者是四比三的這個比例,那才更好的處理,如果你這個比例不能達到的話,

圖片

5-5-1 什么是YUV

簡介

YUV是視頻、圖片、相機等應用中使用的一類影像格式,實際上是所有“YUV”像素格式共有的顏色空間的名稱, 與RGB格式(紅 - 綠 - 藍)不同,YUV是用一個稱為Y(相當于灰度)的“亮度”分量和兩個“色度”分量表示,分別稱為U(藍色投影)和V(紅色投影),由此得名,

YUV也可以稱為YCbCr,雖然這些術語意味著略有不同,但它們往往會混淆并可互換使用,

Y表示亮度分量:如果只顯示Y的話,影像看起來會是一張黑白照,
U(Cb)表示色度分量:是照片藍色部分去掉亮度(Y),
V(Cr)表示色度分量:是照片紅色部分去掉亮度(Y),

要說清楚YUV,得分別說清楚以下兩點:

  • YUV的采樣格式:即我們在采集圖片、視頻幀時,是如何獲取每個像素的Y、U、V三個分量的,
  • YUV的存盤格式:即Y、U、V三個分量的值,是以什么方式存盤在記憶體或者檔案中的,

為了理解這兩點,破費功夫,只因沒有在網上找到比較讓人滿意的解讀,最后找到了兩篇檔案:
VLC提供的wiki和微軟家提供的Video Rendering with 8-Bit YUV Formats

YUV采樣格式

什么是掃描線(scan line)

為了說明采樣格式,先說明一下待會兒會用的的概念:掃描線

什么是掃描線?這是關于電視顯示的術語,用來描述電視是如何顯示畫面的,wiki中是這么解釋的:

電視螢幕由電子槍射出的電子,經由磁場偏向后打在螢屏上而發光,因此每一個圖框都由電子槍的掃描線畫出來,

大概意思如下圖:圖片來源

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-jBtWKQjm-1610356447499)(https://uploader.shimo.im/f/MfVtBnMIUxNUfF0a.png!thumbnail?fileGuid=Xk3wQdKCdtV3twqC)]

電子槍的掃描線從左上角像素點到右下角像素點順序移動,噴射電子顯像,

我猜,這種像素的顯示方式也對像素的采樣方式產生了影響,YUV采樣格式中就大量提到了掃描線,至于這中間是否有什么歷史"恩怨",大家如果知道,不妨留言分享,

宏像素 (macropixels)

像素是視頻顯示的基本單位,因為它代表了螢屏上一個"點"的色彩,通常也會被形象地稱為"像素點",通常RGB格式像素點,會有Red、Green、Blue三個基本像素分量組成,也就是說,只要確定了紅、綠、藍三個像素分量就能確定這個像素將要顯示什么,

同理,YUV格式也可以分為三個分量,即Y、U、V一一對應,

但和RGB不一樣的是,利用人體眼睛對亮度分量(Y)敏感,而對色度分量(U和V)不敏感的原理,視頻可以通過降低色度分量的采樣資料,達到降低視頻資料量而人眼很難分辨的目的,所以,目前流行的YUV采樣,基本都是降低色度分量的采集,

也就是說,一個視頻幀中,亮度分量Y的采樣數不會被改變,但色度分量U和V會被降低采樣數(downsampling),如此一來,Y、U、V三個分量將無法達到和RGB一樣一一對應的效果,

好在YUV所有的格式中,U、V分量的采樣數是相等的,只是不同的Y分量之間,需要共享數量不足的UV分量,為了讓這個共享更好的表達,YUV出現了宏像素的概念,即:當前格式下,至少需要x個像素點的采樣資料,才能將這x個像素點完整表達,這幾個像素點組成了一個宏像素,每個像素點稱為宏像素點,所謂的完整表達,也就是讓所有的Y分量都有對應的UV分量可以使用,

如果看到這里,還不是很懂,你可以先跳過這節,這對后文的閱讀影響不是很大,

宏像素的概念,是從微軟家的那個檔案看到的,但他家沒做任何解釋,網上也沒有,這一節的內容,實際上是本人自己琢磨了好久才總結出來的,受限知識水平,請大家謹慎參考,如果有大神發現有誤,請留言幫幫小弟,一拜……再拜……

YUV4:4:4

YUV格式,采用A:B:C表示法用于描述UV色度分量相對于Y分量的采樣率,這怎么理解呢,以YUV4:4:4為例,

YUV4:4:4的采樣方式表示:各采樣分量在掃面每個像素點時,都不會降低采樣率,

圖片

如圖,一個方格表示一個像素點,方格中的YUV分別表示有在該像素點采YUV分量,之所以用四個方格顯示,是因為YUV格式中,UV分量最小時需要四個像素共享一個UV分量對,同時,共享一個UV分量對的像素點,在平面上和UV分量都有臨近的關系,所以這四個像素點不會是同一條掃面線上的點,而是分布在兩條掃描線上,

所以,一個宏像素最多容納四個宏像素點,而在YUV4:X:X的表示法中,的4表達的也是這個意思,

從圖可以看出,YUV4:4:4的采樣方式,是對每個像素點進行Y、U、V分量的全采樣,

關于記憶體占用,因為YUV模式的每個分量都是存盤在一個位元組(8bit)中的,

所以,對于四個像素,YUV4:4:4格式需要48 + 48 + 4*8 = 96位,因此,每個像素深度為24位

YUV4:2:2

YUV4:2:2的采樣方式表示:水平方向Y分量與UV分量2:1采樣,垂直方向不降低采樣率,也就是這樣:

圖片

水平方向上的兩個像素點組成了一個宏像素,兩個像素點共享一對UV像素分量,

至于U和V分量是從水平方向第一個像素采集,還是分開到兩個像素采集,如果是分開采集,是先采U分量還是先采集V分量,這個可能需要更專業的解釋了,根據我搜索到的資料,最準確的說法只是,在掃描線上,水平方向上的UV分量是Y分量的一半,

對于四個像素,YUV4:2:2格式需要48 + 28 + 2*8 = 64位,每個像素深度為16位

YUV4:2:0

YUV4:2:2的采樣方式表示:水平和垂直方向上Y分量和UV分量對的采樣比都是2:1,

目前YUV4:2:0有兩種變體,一種用于MPEG-1標準如下圖:

圖片

另一個常用語MPEG-2標準,我們經常見到的4:2:0通常都是這種,如下圖:

圖片

對于四個像素,YUV4:2:0格式需要4*8 + 8 + 8 = 48位,每個像素深度為12位

YUV存盤格式

YUV的存盤格式分為打包格式(packet formats)和平面格式(planar formats),

在打包格式中,Y,U和V組件存盤在單個陣列中,YUV三個分量是順序交錯存盤, 像素被組織成宏像素組,其布局取決于采樣格式,

在平面格式中,Y,U和V分量存盤在三個不同的平面(陣列)中,YUV三個分量被分開存盤在三個不同的陣列中,

4:4:4,24位像素深度

YUV4:4:4實際上表達的是:采樣模式位4:4:4的打包存盤的資料,它的存盤方式如圖:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-xyHUmEoM-1610356447505)(https://uploader.shimo.im/f/u0A71T3JmhGAfulv.png!thumbnail?fileGuid=Xk3wQdKCdtV3twqC)]

一個小方格代表一個位元組,一組連續的小方格代表一個像素,

4:2:2,16位像素深度

4:2:2的采樣格式共有兩種存盤方式

  • YUY2
  • UYVY

它們的存盤方式都是打包格式,其中每個宏像素是兩個像素,編碼為四個連續位元組,

YUY2

在YUY2格式中,中第一個位元組包含第一個Y樣本,第二個位元組包含第一個U(Cb)樣本,第三個位元組包含第二個Y樣本,以及 第四個位元組包含第一個V(Cr)樣本,如圖所示:

圖片

UYVY

這種格式與YUY2相同,只是位元組順序顛倒了 - 也就是說,色度和亮度位元組被翻轉,如圖:

圖片

4:2:0,12位像素深度

下面要介紹的4:2:0格式都采用了平面存盤模式,共有四種:

  • IMC2
  • IMC4
  • YV12
  • NV12

所有的4:2:0模式,色度分量無論是在水平還是垂直方向上,采樣數都是亮度分量的1/4,

IMC2

IMC2格式的存盤方式如圖:

圖片

每個分量以一個位元組存盤,平面存盤格式的意思就是,先存盤視頻幀中所有的Y分量,Y分量存盤完之后,才開始存盤色度分量,在IMC2格式中,YUV三分量的存盤關系是:先存所有的Y分量、再存所有的V分量,最后存盤U分量,

為了便于處理和表達,通常在代碼中會以三個陣列來分別裝著三個分量,

另外需要提一嘴,在IMC2格式中,存盤UV分量的記憶體空間步長分別是存盤Y分量的一半,另外因為色度分量的采樣書是Y分量的1/4,所以,及時色度分量占用空間是亮度分量的一半,也會有一些空閑的記憶體,

IMC4

圖片

和IMC2格式類似,只是U、V兩個色度分量的存盤順序對調了一下,

YV12&I420

圖片

YV12格式的存盤方式又有變化,存盤色度分量的記憶體步幅是亮度分量的一半,首先Y分量資料以unsigned char陣列的形式存盤,緊跟著后面存V分量,最后存U分量,

I420和YV12的存盤方式差不多,區別的地方在于,I420的Y分量后,存盤的是U分量,最后存V分量,色度分量的存盤順序替換了一下,另外I420也被稱為YUV420P,

YV12、I420、YUV420p這三個名詞在多媒體開發中,是出現頻率比較高的是那個了,大家不妨記憶一下

NV12

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Gof2elbc-1610356447514)(https://uploader.shimo.im/f/PuSEXCkloHipEtiF.png!thumbnail?fileGuid=Xk3wQdKCdtV3twqC)]

NV12格式首先存盤Y分量平面,作為具有偶數行的無符號字符值陣列, Y平面后面緊跟著一個無符號字符值陣列,其中包含打包的U(Cb)和V(Cr)樣本,

劇終

本文以理解為主,部分講述并不代表事實,在生產場景這已經夠用了,

5-5-2YUV

圖片

在這里插入圖片描述

圖片

*加粗樣式在這里插入圖片描述

圖片

圖片

圖片

5-6 YUV的常見格式

YUV420:

第一行:只有Y和Cb分量

第二行:只有Y和Cr分量

第三行:只有Y和Cb分量

第四行:只有Y和Cr分量

第五行:只有Y和Cb分量

第六行:只有Y和Cr分量

圖片

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

圖片

我們這里關于上圖的計算方式,只講YUV420,

5-7 YUV的存盤格式

我們來介紹一下yuv的存盤,主要指的是 yuv420的存盤格式,那對于yuv444,yuv422都是類似的,

圖片

那對于這個YUV420的存盤格式,有幾個點我們需要掌握,第一個點呢就是,它是按照分層來存盤的,那我們可以看到啊,在這個示意圖中呢,前面的這半部分,都是Y相關的資訊,之后才是U和V的資訊,他是一層一層這樣存盤的,那這樣的一個存盤格式就特別適合于這個黑白電視機相兼容對吧 ,彩色電視與黑白電視相兼容,因為如果你是一個黑白電視的話,我們只要讀取前面的Y相關的資料,就可以了,對于U和V,它可以舍棄掉,如果你想展示一個彩色,就要涉及到U和V,那么對于我們YUV420這種格式呢,他是怎么去使得Y和UV對應的呢,實際就是與他這個名字是相關的,四,就每一個y的前四個,對應一個U和V,你看圖中箭頭淺藍色的色塊,

我們知道如上存盤的時候,你在決議的時候,比如說我們進行這個視頻的渲染,那你讀取的每一個Y對應的UV,它是一個固定的關系了,通過這個,我們就可以知道他們的關系, 第一層的第一行取出兩個與第二行取出兩個對應的呢就是,U中的第一個和V中的第一個,一行一行的這個掃描那么我們就可以,將整個的視頻進行一個彩色的展示,這個就是YUV420的存盤格式,

圖片

那其實這張圖呢就是我們這節課所要講的一個核心內容,那么接下來呢,我們看看這個常見的存盤格式,那剛才我們講了這個呢,是最普通的,最廣泛使用的這種,那對于我們常見的呢,實際還分為平面存盤和打包存盤,對于平面存盤來說,又分為I420和YV12這兩種模式,I420就是我們剛才所介紹的,前面是y,后邊是跟著U,再跟著V,而YV12呢,它存盤的前面是y,后邊變成了先存V后存U,這是他們一些細微的差別,那么我們只要知道,這兩種模式最主要的區別是在于先存V還是先存U,

對于打包模式來說,就是先存Y,再存UV、UV

在這里插入圖片描述

那對于我們這種平面存盤和打包存盤啊,實際在我們日常作業中經常用到,比如說像ios她應該都是YV12了,而對于安卓系統來說一般都是NV21,所以這兩種模式我們必須都要掌握,因為你在作業中呢,隨時都有可能遇到,對于我們這門課來說呢,在底層的這個YUV呢,可能我們就不是特別的詳細的去做了,但是在我們的日常作業中,你是做移動端開發的,很有可能你會使用這個硬體的加速,對吧,還有這個通過硬體的攝像頭采集,采集出的資料都是跟這個YUV密切相關的,那么我們在編碼的時候,你也要告訴這個編碼器那你使用的YUV是什么格式,這樣才能正常的編碼,否則的話編碼之后,然后你再播放出來的資料就完全錯亂了,對吧,它顯示不出來,

在這里插入圖片描述

那接下來呢我們再來看,這個yuv的未編碼的YUV的碼流是多少,在之前呢,我已經向你介紹過RGB的碼流,他是怎么計算的,

我們在網路傳輸的時候是以位為單位的,比如說你是一兆的帶寬,實際是一兆的位元位,而不是一兆的位元組數,對吧這個我們要清楚,

在這里插入圖片描述

5-8 YUV操作

圖片

在這里插入圖片描述

圖片

圖片

讓我們首先來看一下如何生成yuv,那生成yuv有很多的方式,那一種呢是我們通過這個硬體設備,攝像頭采集到YUV的資料,那么另外一種方式呢,是我們可以通過多媒體檔案,然后從多媒體檔案中呢抽取出YUV,但由于我們還沒有學到如何從設備上采集視頻資料,對吧,那今天呢我們就使用多媒體檔案來生成yuv,那這個命令呢,就是通過FFMPEG從多媒體檔案中獲取到YUV資料,那我們來一一看一下它的引數,那第一個引數呢就是他的輸入檔案,對吧,那這里呢你可以寫任何一個多媒體檔案,只要這個多媒體檔案中含有視頻就ok,第二個引數呢,an,a代表是audion呢代表是none,那就是沒有音頻,所以如果你的這個多媒體檔案中呢是帶音頻的,那通過這個-an就可以把音頻給過濾掉,第三個引數呢是cv代表的是視頻的解碼器編碼器,那后邊兒帶著這個rawvideo表示的是說,我們對于這個多媒體檔案中的視頻做rawvideo處理,經過他處理之后,我們就可以獲取到YUV資料了,ok那最后一個引數是指定輸出的YUV資料的格式,那您既可以指定YUV420p,也可以指定其他的型別,

我們來解釋一下這兩個引數第一個引數呢是指明你要播放的這個YUV的它的格式是什么,如果是YUV420P話實際這個引數呢,是可以省略掉的,因為ffplay默認的就是YUV420p,第二個呢是最關鍵的一個引數,就是你要告訴他你的播放的解析度是多少.

大家一個新的這個引數-vf,簡單濾波,

圖片

圖片

6 H264技術介紹

6-1 H264壓縮碼率與GOP

我舉了一個例子,假設我們有一個一秒鐘的視頻,解析度呢是640乘以480,幀率是15幀,格式是YUV420P,碼流多大?

結果應該是55M

圖片

圖片

對于h264他建議的碼流大小是多少呢?是500kbps,通過這兩個值我們就可以得出,它的壓縮比是1:100,那對于我們一個完整的視頻像一個電影,那這個資料量其實對于我們普通的磁盤空間而言,就是存不了幾部電影,ok所以呢這個也是我們面試的時候經常被問到的一個問題,很多人都說 ,我學過音視頻知道h264編碼原理等等等等,那人家問你說這個h264的這個壓縮比是多少,那你要知道他是1%,對吧,這才能知道你真的學過,幀率對于碼流來說起到一個作用,幀率越高,占用空間越大,那如果我們用h264進行壓縮的話,幀率呢相對來說,起到的作用就會小很多,隨著我們后邊課程的介紹那你會了解到,解析度和幀率到底哪個對碼流的影響更大,

實際我們在拍電影的時候,看到那個電影院播放的視頻都是120幀每秒,這樣你才能看到這個,電影非常的平滑,那對于像我這個錄課一般都是30幀以上的視頻,15幀是用在實時通訊,大家一起開會的時候,對吧,像視頻會議啊,還有在線教育一般都會用到15幀每秒的幀率,

那例子中他的建議碼流是500kbps,那這個數值是從哪兒來的呢,實際上我們在網上去搜索的時候可以看到很多的這種數值,但這個數值呢一般不是說通過嚴謹的科學計算出來的,而是各個廠家經過大量的實踐,它是一個經驗值,經驗總結出來的,實際我們可以通過一個網址找到,就是聲網給的值,它在整個音視頻領域其實還是蠻權威的對吧,我們去做的時候也是按這個直接作為參考的,打開網址,打開這個檔案中心之后,我們點擊視頻通話,點進階功能,點視頻管理,點設定視頻屬性,

看你在做這個視頻相關的開發的時候,你要設定這個碼流其實就可以參考這里邊兒的,如果是直播碼流,就是娛樂直播這種通過ramp進行資料傳輸的,為什么設這么高的碼流呢?就是為了它的流暢度,因為對于娛樂直播來說主播在講的時候,觀眾有一些延遲比如說有幾秒甚至是十幾秒的延遲是關系不大,因為當你看的時候他只要是連續的一直在播,你就認為這個節目其實是非常好的對吧,清晰度也夠,流暢度也夠,因為你與主播沒有互動所以你感受不到這種延遲性,但是對于實時通訊來說,這種互動就不能產生太大的延遲,所以對于實時通訊來說,碼流設定小一點,保證網路的通暢性,

圖片

圖片

我們再來介紹一個非常關鍵的知識點,就是GOP也是我們在面試,面試開發崗的時候呢,面試官經常問道的一個問題,

對于這么多的幀,實際我們在壓縮的時候就比較困難,科學家們就想到一個非常好的辦法,就是將這些幀進行一下分組,怎么進行分組呢,就是按照他們的相關性進行分組,比如我這里舉個例子,對于這樣一個視頻呢,我分成兩組,那怎么分的呢,小人一樣,只是他們角度的不一樣,我們把它分成一組,所以呢每一個group其實都是描述的一個影像目標的細微的差別,在同一個組中的這個視頻幀這樣他是強相關的,不同組之間的相關性特別小,這樣我們就可以把這個視頻劃分成許多的組,每一組呢都是強相關的視頻幀,組成了這一組GOP,英文全稱就是group of picture,

圖片

GOP的幀與幀之間的差別特別小,所以對于這樣一組真來說他們進行編碼的時候,非常容易壓縮了,這個資料量會很容易地下降下去,為什么呢,我們來看一下啊,那么因為我們所有的圖片都是這個小人兒的吧,差別就是轉換的角度不一樣或者這個小人兒的姿勢不一樣對吧,對于整個背景來說,背景圖完全是一樣的,所以當我們進行計算的時候,完全可以把所有的這個背景用一張圖表示,對于差值我們進行一下存盤,這個GOP的這一組幀進行壓縮的時候,它會壓縮的非常小,只需要存很少的資料就可以將原來的一組幀,還原回來,對吧,那這個呢,就是GOP的意義,那實際上呢,這GOP也是我們后續學習H264編解碼技術的一個核心的知識點,它是一把鑰匙,只有我們掌握了什么是GOP,那你才能學習后面所有的知識,否則就跟看天書一樣,

6-2 H264中的I幀P幀和B幀

圖片

IPB幀,這些幀呢,其實都是H264中非常關鍵基本的一些概念,那對于這些知識的了解呢,對于你后面的學習有著非常大的好處,而且呢這些知識也是我們面試官經常問的一些問題.

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Epg10ve8-1610356447562)(https://uploader.shimo.im/f/LFW8Cec6IQpeudau.png!thumbnail?fileGuid=Xk3wQdKCdtV3twqC)]

P幀約占I的一半,這樣就大大減少了這個資料量,

雖然B幀的壓縮率是最高的,但是他同時帶來一個非常大的壞處,就是它占用cpu以及耗時是非常多的,那如果你B幀的幀數越多,你的延遲性就會越大,對于實時通訊來說呢,一定是快速的讓對方看到,那你這個資料傳輸過去之后呢應該立即就解碼,然后讓展示了出來,這樣才是一個最好的方式,所以在大部分的這個實時通訊的場景中,只使用I和P幀,不使用B幀,

在音視頻轉碼的服務中呢,他會大量的使用B幀,就為了減少存盤空間,我們如果去這個云服務廠商去買一定的空間的話,你會發現你買的空間越大,那你的這個花費就成指數增長對吧,我剛開始的時候可能就是一個最基本的比如說500兆,可能就是一個相當于免費一樣,但是你用500個g、500個t那就完全不一樣了,

在這里插入圖片描述

圖上B幀和B幀之間是沒有參考的,

在這里插入圖片描述

實際在h264中呢,還有兩個特殊的幀,就是sps跟pps,那就不能稱為幀了,這應該稱為這個引數資料,那他其實也屬于I幀的一部分,也就是說在每個IDR前面都會有一個sps跟pps這兩個幀,這兩個幀一般是同時出現的,不會單獨出現那么,這兩個幀的作用是什么呢?我們來看一下,sps就是序列引數集,對幀組的一個引數設定是吧,就是GOP的一個引數設定,我們看看它包括哪些內容,看圖,sps相關的就是修飾或者是約束GOP的一些引數,

第二個呢是pps,對于GOP中,這一組中的每一幅影像的一個引數約束,

重點呢,就是你要知道這兩個東西是成對出現的,是在IDR幀之前,

6-3 H264中的宏塊

今天呢我們來介紹一下h264的壓縮技術,實際上H264的壓縮技術啊,它是由一系列的技術所組成的一個系列集合,不是簡簡單單的一個技術,

第一個技術就是幀內壓縮技術解決的就是空域資料冗余問題,什么是空域呢?我們來想象一下一張圖片對吧,它占用一定的空間,那么 所謂的幀內壓縮技術就是解決這張圖片內的這個資料壓縮問題,比如你是一個天藍色的背景,背景的前面有一個物體,那整個這個天藍色的背景你實際上可以用非常小的一個資料量進行一個存盤,后面在進行解壓縮的時候,可以通過這很少的資料量就能完全還原回去,對于前面這個物體呢實際也有相應的這個演算法對吧,對于幀內壓縮技術來說呢解決的就是這些問題,

幀間壓縮技術,就是幀與幀之間的進行一個壓縮對吧,那他解決了呢是時域的資料問題,所謂時域,就是隨著時間的推移,每一個時間段你都會有一幀資料對吧,那這一幀一幀的資料,他們之間可以做參考的,那我第一幀是一個I幀,它的壓縮比會低一些,但是第二幀呢,我就可以根據第一幀的資料進行一個壓縮,進行一個殘差值,那我用第二幀的資料減去第一幀的資料它的變化量進行一個壓縮,那就使得這個資料量非常小了,這里說的比較簡單,實際的真正處理程序呢還是蠻復雜的,

第三,做DCT,那做完余弦變換之后這個資料會呈現一個什么模型呢,他就會將真正有資料的這個地方啊,進行一個濾波,濾波完成之后呢,就是把所有的資料集中到一塊兒,另外一塊就全部變成0了,這樣就大大的減少了我們后邊處理資料的這種復雜度,通過這樣一個濾波處理之后呢,后邊我們在對 都給它聚集了這一塊資料 然后再進行一個壓縮,這樣呢,這個資料量就會變得更小,所謂的DCT,就是把資料進行一個調整,更有利于我們后邊做無損壓縮,

最后一個就是CABAC壓縮,就是根據背景關系進行一個資料的壓縮,那對于這兩塊呢,資料余弦變換和CADAC,它都屬于無損壓縮技術,而對于這個幀間壓縮跟這個幀內壓縮呢,都屬于有損壓縮技術,尤其是幀內壓縮,其實就是將這個不必要的資料全部去掉,比如說我們人眼啊,對于圖片來說它對亮度更關注是吧,對色度就弱一些,那這個時候呢我們就可以把很多與色度相關的這些資料呢給他減少掉,從而減少整個資料量,而幀間呢,是我們根據前一幀的這個資料,因為前一幀已經是有損的了,所以呢我們后一幀是根據前一幀做參考的,那也是有損的,

所以我們可以大體上分為 就是前兩項是有損壓縮后兩項是無損壓縮,

CABAC目前來說也是一個比較老的無損壓縮技術,那么現在最新的就有更高效的這個無損壓縮技術,其實對于我們現在來說,我們不是搞這個數學的也不是搞演算法的,我們只要知道他有這些技術就ok了,具體怎么做,那我們就可以留給那些專門做數學的或者是做演算法的一些工程師去處理就ok了,那這是整個H264壓縮技術的一個概況,

在這里插入圖片描述

宏塊呢,是我們上面所講的這些知識中啊最為關鍵的一個基礎點,我們之前說,GOP,他是打開我們學習H264編解碼的一把鑰匙,而宏塊呢,則是我們就進行H264編解碼最基礎的一個知識點,所以我們這節課的重點是要把這個宏塊給弄清楚,

宏塊就是視頻壓縮操作的一個基本單元是吧,那無論是幀間壓碩訓是幀內壓縮都是以宏塊為計數單位了,

圖片

圖片

那我們要把它切換成一個個宏塊那他是什么樣子呢,這個宏塊是按像素來的,8*8的一個像素,它就稱為一個宏塊,看右邊這張圖呢就是宏塊的一個具體的表現,最開始的時候每個宏塊的每個像素,都有一定的值,有一定的顏色對吧,那后邊呢我們就會按照這個宏塊去給他進行壓縮,

圖片

那我們將底下這張圖啊,全部用宏塊劃分完成之后他變成什么樣子呢,就變成上面這張圖的樣子,看起來整體的這個圖形呢跟下邊兒是一樣的,但是它的色彩啊,它的這種平滑度啊,都不如下面這張好看,通過這樣一個劃分呢,就更有利于我們后邊進行這個視頻的編碼和解碼,

那對于宏塊來說,我們還可以劃成很多的子塊,比如在這里,這是h264的一個子塊兒的劃分,對吧,那整個這個大的塊兒是16乘16的,等一會兒我們會介紹到這個h264它宏塊劃分的這個尺寸大小,那有很多尺寸,那么整個這個大塊兒呢是16乘16,那么我們中間給他進行一個平均分配,每一塊是88,在88里又可以劃分,…經過這樣一個劃分之后,每一個宏塊就非常小了,宏塊的大與小,其實對于我們編碼有著非常重要的這個關系,如果你宏塊非常小,那我們進行壓縮的時候控制力就更強對吧,如果你宏塊特別大那控制力就弱一些,但是有一點,一個非常平滑的一個背景,就一個天藍色的背景對吧,宏塊劃得大,它的處理速度就快,整個背景來說,沒有太多的細節的,我們只要劃分一個非常大的一個16乘16的,我們很快就能將整個背景進行處理掉,而對于很多細節紋理特別強的這些圖,有很多小細節比如一個眉毛都很清楚的這些細節那你就畫成很小的這種宏塊,處理起來呢,它的壓縮比就更高,

在這里插入圖片描述

對于右邊這張圖就是典型的例子,對于MPEG2,就是將一個這個16乘16的劃分成四等份每個是8乘8,處理時候呢,每一塊的資料量就非常多,而H264呢,他就對這個宏塊劃分做了非常大的這個靈活性,那么將宏塊劃分成小的之后呢我們能看到,解壓縮的時候你可以看到每一塊都非常小對吧,整個的這個背景呢幾乎你都不用存什么資料,只要存一些特定的這個紋理的資料就ok了,

所以宏塊劃分的越仔細,對于我們后面的編解碼就很重要,

圖片

那對于宏塊都有哪些尺寸呢,對于h264有很多尺寸,那么最常見的我們以前默認的就是16乘16,經過圖上個劃分之后呢我們這個壓縮率啊就大大提高了,我們H264相對于MPEG啊其實是有一個質的飛躍的對吧,

6-4 幀內壓縮技術

今天呢我們來介紹一下幀內壓縮技術,那我們要進行幀內壓縮就要有一個幀內壓縮的一個理論,對吧,那對于幀內壓縮他的理論包括哪些呢,我們來看一下,

圖片

那第一個呢,非常關鍵的就是相鄰像素之間的差別不是很大,所以可以通過宏塊進行預測,那什么意思呢就是我們的所有像素,像素量你單獨拿出來之后,您可以看到每個像素點之間的差別其實非常小的,而我們上節課就向你介紹了整個h264他進行這個編解碼的時候,都是以什么為單位呢,都是宏塊為單位的對吧,一個一個的像素進行處理這個效率太低了,那最少你也得是一個4乘4的一個小塊,所以在H264,在幀內進行壓縮的時候呢,它是以這個宏塊為基礎的,對他并不是只是我這兩個像素相鄰,我就對這個像素進行一個處理,而是說把這個4乘4的一個像素按著一塊一塊碼好之后呢,讓兩個宏塊之間進行比較那么這兩個宏塊之間由于是鄰近在一起,所以他們之間的這個差別也不是很大,那有的人可能會覺得那個顏色不一樣,對吧,有的很明顯,那下面呢,我們就來解決這個問題,人對亮度的敏感度超過了色度,像我們黑白電視只要你能看到影像對吧我們就知道他講的是什么故事,它是一個怎么樣一個程序不影響我們正常的視覺,那你加了顏色之后呢,他感覺更好,但是呢,你把這個顏色稍微做一些偏差其實也是無所謂的,對吧,這是我們大家都能感覺到的,而對于我們要處理的這個資料啊,實際大家都已經知道了,我們要進行壓縮的資料是什么資料呢,是YUV資料,YUV資料,它有一個天然的好處就是可以將亮度和色度進行這個區分, 那亮度就是Y資料,那色度呢就是UV資料,所以我們在處理的時候呢,可以直接對Y資料進行處理,然后UV資料呢做另外的處理,這樣我們z再進行幀內壓縮的時候就可以實作我們這個預測的方法進行壓縮了,那所謂的預測就是說當我們不知道下一個宏塊,也就是下一個4乘4,16個像素是多少的時候,我們可以根據他之前的或者已經已知的這個像素,來推斷出下一個16個像素它具體是什么樣子的,ok啊這就是我們整個幀內壓縮的一個理論基礎,

在這里插入圖片描述

圖片

圖片

好,那我們了解了這個理論基礎之后呢我們再往下看,那對于幀內預測來說呢,h264提供了九種這個模式,從零到九,那我們現在只要知道有這幾種模式就ok了,那么在這九種模式在使用的時候呢,實際會做一個預判,也就是說,我從某一個點、某一個宏塊為基礎,那么在這個 宏塊下邊的一個宏塊或者是它右邊的一個宏塊,那應該是什么,進行推算的時候呢實際有九種模式進行推算,那至于選擇哪一種模式,在H264中呢,有一種演算法就是可以快速的定位我應該使用哪一種模式,他的一個基本原則是什么呢,就是這九種模式中哪種模式最接近于原來的這個4乘4的這個宏塊,那就選擇那種模式,這個有很多的論文,大家有興趣的話去可以看一下這個具體的論文怎么去選擇具體使用哪種模式,對于每一個宏塊的預測,都是不一樣的,它都是可以根據一個快速的一個方法去定位下一個宏塊去采用哪種模式,那么通過這樣呢,我們就可以把所有的這個宏塊啊,進行一個處理,處理之后呢,我們就可以看到那這個宏塊呢,都變成了數字,364354,他這是什么意思呢,就是我這個宏塊使用的預測模式是第幾個模式,那這個三呢,就代表模式三,六呢代表模式六,他是這樣一個這個處理,那我們后邊兒再處理的時候那你只要知道它選用的模式是什么,我們就可以知道這個宏塊,他應該是什么資料了,對吧,因為它可以通過模式預測出來啊,

那具體的九種模式是什么呢,就是我這里畫的這九種模式,第一個圖,代表每一列的值都相等,比如第一列就都是A,第二列都是B…第二個圖同理,橫向都相等,第三個圖就是平均值,每個像素都是一樣的值,

我們就簡單列舉了三個那對于其他不同模式有興趣的同學呢可以繼續去看一些論文,好那這就是不同模式的預測結果,

圖片

圖片

在這里我們再來舉一個具體例子啊, 像我這張圖片對吧就是一幅圖,視頻中的一幅圖那么我們要對這一小塊兒進行一個預測,我們現在通過這個大圖可以看到啊它這是一個帽檐兒對吧,上邊是一些磚的顏色,然后這邊呢還是帽檐兒的這個白色帽子的白色,在這邊呢就是帽子里邊對一些顏色讓我們來看一下,那這張圖呢就是我們從那個小的方塊中抽取出來了,左邊是原始資料,右邊呢是按照4乘4的這個亮度塊進行預測,我們一定要記住啊,亮度塊與色度塊是單獨進行預測的,要知道這一點,那預測出的結果呢,它實際是通過上邊的這個資料和左邊的這個資料那推測出來的,我們可以看到這兩個資料幾乎是一樣的對吧,有一些細微的差別,但是差別呢不是太大,所以通過這種預測我們就可以將這個資料量大大地減少,那你通過這個整張圖,我們可以看到那上邊兒這是一個帽檐兒對吧,能看到一個大體的結果呢,那所以通過這樣一個預測我們基本上可以獲取到原始圖幾乎是一模一樣的,但還是有一些細微差別,

在這里插入圖片描述

圖片

圖片

那么對于這些細微差別呢其實還需要進行一個處理,但如果是一整張圖我們就預測下來之后可以看到啊,你可以看到整體上都是差不多的但是呢,可以看到這個清晰度會差很多,對吧為什么差很多呢,就因為這些預測的時候呢,有一些塊他分不清了,對那這個時候會怎么辦呢實際還有一個殘殺值的計算,當我們將所有的這個資料預測出來之后,那么還要通過原始圖與這個預測的圖進行一個差值計算,計算出的結果就是這張灰色的小圖,

他們對端進行解碼的時候就可以根據這個模式先把原來的這個影像預測出來,預測出來之后呢再加上我們的這個殘殺值就能完全的還原成,這個資料與原始資料還是有一些差別的,比如說一些色度上的一個差別,那肯定是有一些損失的對吧,因為這是有損壓縮,

當然你可以做到完全的這個無損壓縮,那這樣的話其實這個整個處理的這個程序也非常長,所以呢,在我們真實的這個使用程序中,很少有完全的一點都不存在損失的這樣壓縮,

圖片

6-5 幀間壓縮技術

圖片

在這里插入圖片描述

圖片

最主要的我們要知道所謂的幀間壓縮一定是在同一個GOP之內的,不同的GOP之間兩個幀進行幀間壓縮這是不可能做到的,因為兩個不同的GOP他們幀之間的這個差距太大了,也沒有什么相關性,這樣呢你就沒法兒進行了一個壓縮,而在同一個GOP之間呢,他們的幀是強相關的,

后邊的幀要參考前面的幀進行壓縮,

圖片

那第三個呢就是運動估計,運動估計的是我們幀間壓縮的一個最為重要的一個壓縮技術,那它是通過宏塊匹配的方式,找到這個運動矢量,那所謂的運動矢量就是它是有方向的吧,一個宏塊從一個坐標到另外一個坐標,而且是有方向的,這叫做矢量,運動矢量就是它有一個運動的軌跡,所以呢所謂的運動估計,就是通過宏塊匹配的方法,最終找到運動的矢量,所以你在看相關的資料的時候,會看到運動估計,那你一定要知道,它指的是一個程序,

在這里插入圖片描述

那最后一個呢是運動補償,這也是我們經常看資料會看到的,找到殘差值,最后呢我們在解碼的時候,他把這個殘差值給他補上去,

圖片

臺球滾動,也就宏塊的這個距離以及他的這個方向,我們就給他記錄下來這就是運動食量,

圖片

對于宏塊的查找的演算法呢其實有很多了我這里列舉了幾個,那你感興趣的同學呢可以去對這幾個搜索去做一下這個深入的研究,但你可以直接在網上去搜索相應的名字,就可以找到具體的演算法那具體他是怎么作業的你就可以一目了然了,ok那這里呢我就不再展開講了,

好那我們實際上邊兒通過這個宏塊的查找這個整個的程序其實就是運動估計

了解了上面的中間壓縮技術之后呢,我們看幾個實際的這個例子啊,

圖片

在這里插入圖片描述

6-6 H264無損壓縮及編解碼處理流程

那么經過無損壓縮之后,它的資料量會進一步變小這樣呢,將整個的一個碼流降到更低的,對吧,ok

圖片

圖片

但對于無損壓縮他有幾個步驟,來一看一下,他第一步呢,就是我們要經過一個DCT變換,這個DCT變換它的作用是什么呢,就是我們經過有損壓縮之后,這個資料呢是分散在我們的這個就是二維圖表中的各個節點上的,對吧各個點上的,那么這個資料比較分散的時候呢,我們進行壓縮就比較困難,通過DCT變換之后,形成了一個濾波,經過這個濾波處理之后,所有的就是分散的資料就被集中到了一塊兒,集中到了某一個角,對吧要不是左上角要不是右下角,將所有資料集中到一塊兒之后,我們再進行無損壓縮的時候呢,就會非常的方便,那整個DCT變換其實就是起到了一個資料從分散的變成集中的這樣一個程序,就是他的這個物理含義,DCT如何實作這一點的呢?這需要你有很好的一個數學背景當然,也不是很困難, 對吧,它無非就是一些二維陣列的一個轉換而已,通程序式,非常的方便,

圖片

常見的無損壓縮方法一種是VLC,這屬于MFPEG2使用到這個技術,另外一種呢是CBAC,它的壓縮率會更高,

首先呢,VLC就是可變長的編碼,舉了一個例子,比如26個字母a到z,如果a的使用率是最高的,頻率最高,所以呢給他一個短碼,z的使用率非常低,就給他一個長碼,高頻字符越多,壓縮率越好,那這里的a呢就是一個代替,這里是a的字符那你可以把它換成任何一個資料塊啊,對吧,對一個不常用的資料塊,我們用一個長碼進行表示,那我們就可以進行這個無損壓縮了,這就是VLC的一個基本的概念,

圖片

那第二種呢是CABAC,就是背景關系適配的(binary)二進制的算術編碼,這張圖呢就是VLC與CABAC的一個對比圖,VLC,這屬于MFPEG2,CABAC屬于H264,通過這張圖我們可以看到啊,這左邊呢是很多的圖片對吧經過壓縮之后,她變得非常小了,通過VLC,而通過CABAC呢,前邊兒他都是類似的,都是很大的塊,隨著時間的推移,后面的資料,他因為有背景關系,對吧,所以呢后邊兒的塊呢非常小,就是它的壓縮率會非常高,

圖片

介紹完我們上邊的這個無損壓縮之后呢,這張圖呢就是整個h264編碼的一個流程圖,

左上角是當前幀Fn,然后我們選擇幀內預測模式,

幀間編碼,就要看Fn-1

圖片

解碼就是反向的程序,

圖片

那這里呢我還有兩個參考資料大家可以去網上查一下,那第一個呢就是H264整個編解碼程序,是在白皮書里有詳細的介紹,那么另外一個呢,這個網址呢實際是介紹了整個h264它不同的編碼級別,它的區別是什么,以及我們現有的一些H264的具體實作,那哪個功能更強,都有一個特別好的介紹.

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-MjF0umnc-1610356447614)(https://uploader.shimo.im/f/mc09NTjNt86taRZg.png!thumbnail?fileGuid=Xk3wQdKCdtV3twqC)]

從第二個網站中,我們可以看到,H264的BP(baseline profile),是沒有B幀的,而在我們實時通訊中呢,一般使用的都是BP,他之所以不使用B幀,就是為了減少這個延遲,對吧,那如果我們是一個非常這個要求壓縮率非常高的時候呢,我們最好選擇這個Hi444P profile,這個時候呢,他的這個B幀都是支持的,它還支持什么CABAC.這個可以作為我們的一個參考,另外一個呢就是我們實際意義比較大的就是我們不同的具體實作,比如這里有很多實作,那在這些具體實作里面,大家為什么選擇x264作為h264的編碼器呢,就是因為它這個功能實作的特別全,性能特別優越,在這里通過這張圖表呢我們可以發現幾乎所有的功能它都支持,

圖片

6-7 H264碼流結構

之前講述了整個H264它的編碼的一個處理流程,結束之后他輸出的結果是什么呢,實際上就是我們今天所要講的是h264碼流對吧,拿到這個碼流之后呢,我們既可以把它保存成這個多媒體檔案,也可以把這個碼流呢,直接通過網路進行一個傳輸,在傳輸給對方之后呢,組包解碼最終呢還原回原始的資料,進行一個播放,是吧這就是他整個的一個處理程序,

在這里插入圖片描述

ok,這個輸出的碼流,它的格式是什么樣的,那首先我們要知道,H264碼流它是按分層存盤的,那到底他是怎么分層呢,我們就來看一看,在整個分層的程序中啊,他的第一層稱為NAL層,那什么是NAL層呢,實際就是網路抽象層對吧,這一層的作用是什么呢?方便我們在網路上傳輸視頻流,因為我們在網上傳輸的時候,經常會發現有這個丟包啊延遲啊亂序啊,那如果我們沒有NAL層的話,只是傳輸二進制的資料,無論你是音頻也好,視頻也好,那么在這里我們當然主要講的就是視頻了,如果你傳這些二進制的視頻資料,如果出現亂序重傳丟包,我們怎么解決?實際上我們沒法解決,沒有一個糾錯的能力,怎么才能有糾錯能力呢?這個H264碼流增加NAL層的最主要的一個原因,那么有了這個NAL層之后,你就可以在網上順暢地進行傳輸了,當然他也會丟包也會亂序,也會有重復的包,但是由于你有了NAL層,那在接收端接收到這個資料的時候,他就能區分出這些資料到底有沒有丟失,有沒有亂序,有沒有重傳,當它檢測完之后呢,他就可以根據各種的情況進行相應的處理,比如說你發生丟包了,我知道的是丟了哪個包,我就可以告訴對方說這個包兒丟了你再從新給我傳一下,如果是亂序了那他可以根據NAL層的序號,然后重新進行一個重排,當然這個序號并不保存在NAL層,對吧,他是跟RTP層有一個緊密的關系,但是在NAL層,他是知道這個包的起始和結束的,再配合RTP資料包的,這個 sequence number,也就是順序號,那就知道你這個資料是在前面還是后面,

NAL層,就是H264碼流中用于網路傳輸的協議層,那如果沒有這層的話,我們在網路上傳輸就會遇到很多問題,而且是無法解決的,

在這里插入圖片描述

還有第二層就是VLC層,就是視頻編碼層,實際就是我們前面所講的幀內、幀間、熵編碼啊,所有的這些東西都打包成一塊,輸出的資料呢,就是VCL層,所以呢對于H264碼流來說,它分成了兩層碼流,那第一層呢是主要用于網路傳輸的,那么第二層呢是vcl層是視頻編碼層,

那么我們知道了這個H264,這個碼流分層之后呢,我們再看看VCL邏輯關系,各個結構之間的邏輯關系是什么樣子的,上半部分呢,它表述的是編碼后的一幀一幀的視頻幀,對吧,他們是一個從左到右的一個順序關系,一個視頻有很多的視頻幀,其中的每一個被壓縮后的視頻幀是由什么組成的呢,是由slice組成的,會有很多的slice組合成一個壓縮的影像,對吧,那當然了如果你對這個H264碼流熟悉,或者說你經常分析H264碼流的話,你會發現實際一般情況下,一個slice就對應的整個影像,但是在H264的官方檔案上,那么它的一個影像中呢,是可以分很多的slice的,那這個slice是起到一個什么作用呢,其實他是想通過這個編解碼器將它分成很多的小塊兒,更方便于我們網上傳輸,這樣處理的時候呢,他的靈活度更高,但實際情況呢,一般呢都是一張圖片對應一個slice,除非你強制說我把它拆成很多的slice,這就涉及到很多的編碼原理上的一個東西了,對吧,如果你想對這塊更深入的研究,去看看官方檔案就行,實際無論怎樣,我們現在只要知道一個影像無論你是由一個slice組成,兩個slice組成的,他都是應該可以包含多個slice的,對吧,ok

好,再下來呢,就是每一個slice呢,它是由很多的小塊組成的,這些小塊是什么呢,實際就是宏塊對吧,

圖片

再下來呢,我們要介紹幾個碼流的基本概念,那我們在網上去看h264相關的概念的時候呢,其實經常會遇到這個概念,如果你對這幾個概念不清楚的話,對于你理解H264碼流會有很多的困難,那首先我們要知道一個最基本的,SODB,二進制資料串,那什么是二進制資料串呢一會兒我們在來介紹,那么第二個,RBSP,原始位元組的順序payload,這payload其實也就是負載資料了,對吧,就是按位元組存盤的原始資料,

第三個呢,是MALU單元,那這三個概念是非常關鍵的三個概念,

這三個概念它分別代表了什么含義,所謂的SODB實際就是原始資料位元流,我們也叫它二進制資料串,那這個二進制資料串是由誰產生的呢?就是VCL層,也就是我們前面所介紹的幀間、幀內、熵編碼出來之后的,沒有做任何處理的一個二進制資料串,對吧這個資料串都是以位碼在一起的,每一位都可能代表著某種含義對吧,這樣壓縮率高,按位碼的時候,就會出現問題,就是它的長度有可能不是八的整數倍,為什么要用八的整數倍,因為一個位元組是8位,我們計算機最底層的,盡量是以位元組為單位,這樣呢,才好處理,對吧,如果你都是位來計算的話,計算機也很麻煩,所以為了壓縮的關系,使用位元組,但是為了后面我們便于處理呢,最好讓所有的資料呢,都是按照八的整數倍來處理,我們用這個VCL層所產生的這個資料呢,就是SODB,它不一定是8的整數倍,所以需要補齊,所以就產生了一個叫做RBSP,它有一個基本的演算法,比如說我們后邊差三位,那么我們先補一個一,后邊補兩個零,就是這樣一個補位的方式,差五位,就是補一個1,4個零,這樣我們就能理解了,對吧,所以SODB和RBSP他們之間的關系你就非常清楚了,

圖片

最后我們再來看NAL單元,實際是由一個nal_header還得加上RBSP,跟我們前面所介紹的這個分層又對應起來了,對吧,那我們整個H264碼流是分成兩層的一個是NAL層,一個是VCL層,實際上NAL層呢,就是這一個位元組的header,加上我們用h264編碼器編出的這個RBSP,這樣就形成了NALU,

圖片

通過H264的這個分析工具你就可以看到整個的邏輯關系就非常清楚了,

圖片

MB:宏塊 mb_type宏塊的型別 mb_pred宏塊的預測值 coded residual殘差值

第一種呢就是說我們,在檔案中保存的它一般是什么情況呢,就是每一個單元前面都加一個start_code,就是00000001或者是000001,RTP傳輸不需要start code.

圖片

7 H264中的引數

7-1 H264中的profile和level

那我們主要介紹一下sps中呢,第一個呢是h264_profile,第二個呢是h264_level,這兩個引數它的含義是什么呢來里面看一下,

在這里插入圖片描述

圖片

圖片

在這里插入圖片描述

圖片

7-2 H264SPS中的重要引數

在這里插入圖片描述

圖片

在這里插入圖片描述

7-3 H264PPS與Slice-Header

圖片

圖片

7-4 H264分析工具1

圖片

圖片

8 RTMP和FLV

8-1 RTMP連接的建立

圖片

對于RTMP協議來說呢,我相信很多同學都對他有一定的了解,對吧,它主要應用在娛樂直播這個傳輸協議,或者是說點播的這種傳輸上,那與之對應的呢實際上還有另外一個協議稱為hls協議,那它是由蘋果公司推出的,它推出的主要目的是什么呢,就是為了替代RTMP協議,那雖然這個蘋果公司啊他的想法是很好,并且adobe公司也因為蘋果公司推出的HLS協議宣布今后不再對RTMP支持,但實際的應用場景中,尤其是在國內,讓大家主要應用的還是RTMP,分析其中的原因呢,我認為有兩個主要的原因第一個原因呢就是RTMP協議在傳輸的這種效率以及實時性上呢,要比HLS要高很多,有興趣的同學呢,可以進一步去了解一下這兩種傳輸協議的具體實作,那這樣你就能分析出這樣一個結果了,那么第二點呢是因為rtmp協議啊它存活的時間比較長了,那個廠商呢,尤其是云廠商在之前呢都是花了大量的這個財力物力人力,時間去把它進行一個推廣應用,這個技術呢其實非常的成熟嗯,這時候你有了一個HLS對吧,你要替換RTMP協議,對于很多廠商來說呢,他又要花很多的人力物力時間去做這件事,但實際對于任何一家公司來說,他主要還是為了這個盈利為目的,的對吧,那你替換這樣一個傳輸協議的話,對他來說成本是非常高的,所以呢,這主要基于這兩種原因,那目前來說RTMP協議的是很難被替換掉的,更可能的一種情況是兩者并存,

ok那我們再往后設想啊,就是說在若干年之后那有沒有可能就是說hls替換rtmp呢,但我認為實際上這兩種協議啊都有可能被替換掉,那會被什么替換掉呢,會被一種新的這種傳輸協議,那這種傳輸協議呢就不是依賴于tcp的傳輸協議了而是依賴于udp的,那現在我們可以看到整個這個傳輸界,那越來越多的人,已經這個認識了或者是在推進這個tcp可以替換掉的這一個程序,對吧,用什么替換呢就用udp來替換掉,對因為tc p他效率太低了,而且是太冗余了,在整個的連接程序中它會花費很長的時間,一旦說網路出現問題的時候,這種策略太復雜,還不如什么好呢,就是udp,可以用UDP重新做一個這種類似于tcp的一個更薄的,這種可靠的傳輸協議,這樣來代替這個tcp,從而達到更高效的一種傳輸,這是未來的一種趨勢了,我們就不再繼續深入的討論了,回到我們的這個課程中來,也就是說在未來的幾年呢,rtmp還是有它這很大的優勢,對吧相對于hls來說,所以呢我們必須要對這個協議有一些深刻的理解

RTMP是在TCP連接之上的,

綠色的線稱為TCP,

圖片

圖片

所以我們看檔案與真實的情況還是有很大差別的,實際最早Adobe公司推出FMS(flash_communication)就是通訊的服務器是吧,很多人,抓起包然后分析它這個服務器相應的回應,最終總結出來一個真正的、它的具體實作是怎么做的,很多人就是根據這個他里邊兒的實作,然后自己又實作了一遍,就是沒有完全按照檔案去實作,而且他文章寫得特別羅嗦,有很多表述不清的地方,大家以后看這個檔案的時候呢一定要注意,ok這是真實的握手,非常簡單對吧

在這里插入圖片描述

檔案中:

在這里插入圖片描述

實際上:

圖片

8-2 創建RTMP流

今天呢我們來介紹一下如何通過RTMP創建流,首先來看一下協議中RTMP流的創建,那在這里呢其實非常的簡單對吧,那對于客戶端來說來說呢,向服務端發送一個create the stream轉一個命令訊息,服務端收到訊息然后回傳結果也就是create the stream response,然后客戶端收到訊息之后,整個流就算創建成功了,

在這里插入圖片描述

在這里插入圖片描述

實際的情況,遠非如此,通過我們抓包工具抓包呢,你就可以看到,在客戶端與服務端創建流之前,其實他做了好幾個這個訊息的發送,對吧,第一步實際他應該呼叫一個release_stream,告訴服務端,如果你有這個流的話,你要先釋放掉,第二步fc_publish_stream,那至于這個訊息他起的具體作用是什么呢,實際上就是大家都不太清楚,但是還是一定要有這個訊息,FC他如何去理解呢,實際就是這個flash_communication的一個縮寫 后邊是publish_stream,那具體這個訊息從哪兒來的呢,這個就是大家通過抓包工具抓取的adobe公司官方發布的這個f ms這個服務器上他的一個訊息,所以這個fc呢說明的就是在真實的實作程序中,然后具有的一個訊息,實際有沒有這個訊息,從服務端的這個業務邏輯上來看,沒有什么太大的作用,對吧,但是呢為了與這個官方的兼容,所以大家呢還是發這個訊息,所以第一步你要花release_stream,第二步呢 要發 fc_publish_stream,那第三部呢才真正的是create_stream,服務端在收到這三個訊息之后,回傳一個status,在實際這個status呢就是create the stream的一個response,收到這個status之后,整個流就算創建成功了,

說所以我們可以看到這個協議檔案,跟真實的實作,還是有很大差別的,也就是說對于Adobe公司來說,他的那份檔案呢,并沒有根據后來的具體實作,做變更,沒有進行更新對吧,所以很多東西啊,你光看那個檔案,還不足以滿足你的這個真正去使用它去開發rtmp客戶端或者是服務端

ok好那下一個呢,流創建成功之后呢,作為客戶端、作為主播端,他就要推流,所謂推流就是把自己的音頻和視頻發送出去,那他是怎樣一個程序呢,那這里我們就不看協議了,直接看我們真實的情況,

這個meta data里邊存放的是什么資料呢,就是我們后邊要發送的音頻或者是視頻的一些基本資訊,比如說對于視頻來說就包括了解析度和幀率對吧寬多少高多少每秒鐘多少幀,一些基本的資訊, 要發送過去,對于音頻來說呢就是采樣大小采樣率通道數啊,

圖片

拉流:set_buffer_size,也就是設定緩沖區的大小,這個緩沖區呢就可以讓你播放的更平滑,不會出現卡頓,那你buffer設定越大,這個平滑性越好,

8-3 RTMP訊息

圖片

第2部分,虛線部分的Message Header和Extended Timestamp是可有可無的,實線部分的Basic Header是必須要有的,

第三部分: 如果fmt,csid號是2到63,則占一個位元組(一般推流,64個id足夠用了,云服務可能用下面的大的)

如果fmt,csid號是0,2的8次方+64開始,范圍是2的8次方

如果fmt,csid號是1,2的24次方+2的8次方+64,范圍是2的24次方

csid(chunk stream id)

第五部分,主要看fmt,如果fmt為01,則3個位元組,其他看圖,

第六部分:當Timestamp為全F,則需要拓展時間戳,

在這里插入圖片描述

8-4 RTMP抓包分析

8-5 FLV協議

那為什么要介紹flv協議呢?其實主要的原因就是flv協議呢與RTMP協議有著密切的關系,實際上你基本上就可以把RTMP認為是FLV,最大的區別,就是在于所有的RTMP的資料,在FLV中要加一個頭,我們稱為Tag,

FLV檔案格式如圖

圖片

8-6 FLV協議分析器

雷神的(雷霄驊),FLV格式分析器

github上有很多,

C、C++的庫都有

8-7 推流程式的骨架

圖片

圖片

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/266302.html

標籤:其他

上一篇:在TensorFlow2.x中執行TensorFlow1.x代碼的靜態圖執行模式

下一篇:Linux下執行緒的同步與互斥

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more