【從零衝擊音視頻開發】音視頻開發必備知識基礎

前言

以前已經出過了FFmpeg環境搭建的文章了,固然那是專門針對iOS的開發而言的,以後會從新補過對Android Studio的開發環境該怎麼搭建。主要緣由是由於,我想要專攻的方向仍是安卓,以前找到了教程都是關於XCode的安裝,因此仍是須要重構過的。html

文章內容參考書目《音視頻開發進階指南 -- 基於 Android 與 iOS 平臺的實踐》bash

那些必須懂得的基礎知識點

其實咱們應該從兩個角度來理解這個事情,音視頻開發其實能夠拆解爲兩部分,一是音頻,一是視頻。網絡

音頻

聲音是怎樣產生的? 在初中的書本也應該有這樣的定義,物體振動產生聲音。就像人若是沒有聲帶,就會變成啞吧,可能仍是會有咿咿呀呀的聲音,可是失去了這個基礎,終究說不成話。post

到了高中,你會接觸到波的概念,而聲波也就是咱們平常生活中最常接觸到的波之一。咱們評價一我的的聲音如何,是否是會用洪亮,尖銳、渾厚這樣的詞彙來進行形容呢。其餘他就是咱們聲波的三個要素:頻率、振幅、波形學習

人的聽力一樣也是有一個接收頻率存在的,就像是你聽不到蝙蝠的超聲波同樣,科學家給出的數據以下:20Hz~20kHz,具體範圍因人而異。編碼

數字音頻

上面講述的是咱們在平常生活的體驗,可是計算機呢,它所保存的數據通常都是離散型的。那他如何識別咱們的聲音,並進行一個記錄呢,如何將咱們的話翻譯成只包含01的二進制文件,有將他翻譯回來成爲咱們的聲音的呢?spa

音頻處理須要通過3大步驟:採樣 -> 量化 -> 編碼操作系統

採樣

首先就是採樣的過程,通常咱們採用的頻率是44.1kHz。也就是1秒的採樣次數爲44100次。.net

固然可能會有讀者問,爲何要是44.1kHz呢,我大點小點不能夠嗎?其實能夠,可是別人用44.1kHz,總有他的道理,因此就找了一個比較好的答案給大家。跳轉連接翻譯

量化

這就是離散化的做用了,想一想咱們的圓面積在之前是如何來進行運算的,的出現是一個怎樣的過程?

n邊形來進行一個替換,那這個時候n越大,求得的數值越接近圓真正的值,而的值,咱們求得的也更爲接近。這其實也就是離散化的音頻恢復的作法。

離散數據 恢復數據

編碼

一般咱們所說的音頻的裸數據格式就是 脈衝編碼調製(PCM) 數據,而他的組成分別有量化格式、採樣率、聲道數

  1. 量化格式:
位數 最小值 最大值
8 0 255
16 -32768 32767
32 -2147483648 2147483647

若是位數越大,那麼對一個音的描述越明確,那麼還原度就越高

  1. 採樣率: 在上文咱們已經說起過了
  2. 聲道數: 單聲道、雙聲道、立體聲道(2或4個聲道)

》》例題《《

若是一個量化格式爲16位,採樣率爲44.1kHz,聲道數爲2,那麼他的比特率是多少?若是存儲一分鐘,產生的數據量是多少?

比特率能夠理解爲存儲時長爲1s時數據的產生量。

即,比特率 = 量化格式 * 採樣率 * 聲道數

一分鐘產生的數據量 = 比特率 * 存儲時間 = 44100 * 16 * 2 * 60 = 84672000 Bit

音頻編碼

這一部分的內容涉及的是一個數據壓縮的問題,由於一個數據量過大的文件,實際上是不適合在網絡中進行傳輸的,壓縮就成爲他們的必需要進行處理的事件,固然分爲形式有兩種:有損壓縮、無損壓縮

常見的壓縮方式其實有不少,最多見的有:(1)WAV編碼 (2)MP3編碼 (3)AAC編碼 (4)Ogg編碼

AAC編碼

使用場景: 128Kbit/s如下的音頻編碼,多用於視頻中音頻軌的編碼。

AAC的音頻文件格式有ADIF & ADTS:

  • ADIF:Audio Data Interchange Format 音頻數據交換格式。這種格式的特徵是能夠肯定的找到這個音頻數據的開始,不需進行在音頻數據流中間開始的解碼,即它的解碼必須在明肯定義的開始處進行。故這種格式經常使用在磁盤文件中。

  • ADTS:Audio Data Transport Stream 音頻數據傳輸流。這種格式的特徵是它是一個有同步字的比特流,解碼能夠在這個流中任何位置開始。它的特徵相似於mp3數據流格式。

對AAC編碼格式的詳細介紹詳見於AAC 文件解析及解碼流程

Ogg編碼

使用場景: 語音聊天的音頻消息場景。

特色: 實現比MP3編碼的碼率更小,可是音質更優。不支持流媒體

視頻

在介紹視頻以前,咱們須要知道視頻是怎麼呈現的。

做爲一個要傳輸的數據,天然也是須要進行量化和編碼的過程的。

圖像數值表示

RGB表示方式

兩種表現方式:

  1. 浮點表示: 取值範圍0.0 ~ 1.0OpenGL ES中採用的表示方式。
  2. 整數表示: 取值範圍0 ~ 25500 ~ FF8位一個子像素,32位一個像素。存在一些平臺的圖片格式爲RGBA_8888,而Android平臺上是RGB_565表示方式,也就是R用5位表示,G用6位表示,B用5位表示,也就是16位來表示一個像素。

那麼咱們就須要對單張的圖像進行一次計算了。以一張1280 * 720RGB_565的圖像做爲例子來計算。

存儲空間 = 1280 * 720 * 16 = 1.758MB
複製代碼

這只是單張圖片的計算結果,咱們對於視頻的傳輸是幾張圖片嘛?

爲了讓人的視頻感受出「 視頻 」真的是視頻,那必然要有必定的刷新率,刷新率爲24fps36fps,甚至更高時,這樣海量的數據,1個小時的電影下載都不知道要廢去多少時間。

YUV表示方式

相較於RGB表示方式的優點在於RGB要求三個獨立的視頻信號同時傳輸。

對於YUV的定義:

  • Y:描述明亮度,也稱灰度值;是將RGB信號的特定部分疊加。
  • U / Cb:藍色通道和明亮度的差別值。
  • V / Cr:紅色通道和明亮度的差別值。

YUV採樣的常見格式爲YUV420,這並非說的Y:Cb:Cr = 4:2:0,表明實際上是對每行掃描線來講,一種色度份量是以2:1的抽樣率來存儲的。

你能夠看出的UV是交替出現和Y進行比較的。

RGB表示方法同樣,來進行一次計算

存儲空間 = 1280 * 720 * 8 + 1280 * 720 * 4 = 1.318MB
複製代碼

可能讀者沒明白爲何是84,其實從上面的圖中已經說明YUV應該成組出現,那麼聯合的時候一個完整YUV就應該是12Bit,你也能夠選擇改寫成12

顯然他的存儲空間更小了,並且實際應用上更爲方便。

YUV和RGB的換算

Y = 0.299R + 0.587G + 0.114B 
U = -0.147R - 0.289G + 0.436B
V = 0.615R - 0.515G - 0.100B
-----  再推算回RGB-----
R = Y + 1.14V
G = Y - 0.39U - 0.58V
B = Y + 2.03U
複製代碼

視頻編碼

由於如今主要流行的編碼標準爲H.264,由於他創造了多參考幀、多塊類型、整數變換、幀內預測等新型壓縮技術。

H.264中,三種類型的幀數據分別爲:

  • I幀: 幀內編碼幀,用於去除空間冗餘信息。
  • P幀: 前向預測編碼幀,參考前面的一個I幀或P幀生成。
  • B幀: 雙向預測內插編碼幀,參考前面的一個I幀或P幀,和後面的一個P幀圖像幀編碼生成。

P幀B幀簡化去的是視頻幀在時間維度上的冗餘信息。

關於IDR幀

這是一個特殊的I幀,由於會存在這樣的狀況。

多幀預測中,P幀參考前面的是前面的一個I幀P幀生成的,P幀是一個不斷向前參考的幀,也就是說前一個I幀並不必定是關鍵幀,因此就算找到了I幀也不能說可以成爲參考條件。而IDR幀就是爲了解決這樣的問題,一旦找打了IDR幀,也就不會再向前探索參考了,直接成爲參考幀。

DTS與PTS

DTS: 標示讀入內存中數據流在何時開始送入解碼器中進行解碼。也就是解碼順序的時間戳。

PTS: 用於標示解碼後的視頻幀何時被顯示出來。

在沒有B幀的狀況下,二者一致;反之則不一樣了。

GOP

GOP: 指的是兩個I幀之間造成的一組圖片。必要設置的參數爲gop_size,也就是兩個I幀之間的幀的數量,如此經過改變gop_size的大小,來控制視頻的質量。

以上就是個人學習成果,若是有什麼我沒有思考到的地方或是文章內存在錯誤,歡迎與我分享。


相關文章推薦:

答應我,收好這份釘釘和抖音的面經,真的很重要!!!

操做系統中的三大經典同步問題,你如何復現?

Android自定義View,你摸的透透的了?

相關文章
相關標籤/搜索