一個最簡單的視頻播放器的過程(不包括視頻加密等等過程): ios
這是一個視頻播放的最基本的原理流程圖,從這個圖能夠很總體得看到視頻處理的一些主要步驟:算法
解協議的做用,就是將流媒體協議的數據,解析爲標準的相應的封裝格式數據。視音頻在網絡上傳播的時候,經常採用各類流媒體協議,例如HTTP,RTMP,或是MMS等等。這些協議在傳輸視音頻數據的同時,也會傳輸一些信令數據。這些信令數據包括對播放的控制(播放,暫停,中止),或者對網絡狀態的描述等。解協議的過程當中會去除掉信令數據而只保留視音頻數據。例如,採用RTMP協議傳輸的數據,通過解協議操做後,輸出FLV格式的數據。編程
解封裝的做用,就是將輸入的封裝格式的數據,分離成爲音頻流壓縮編碼數據和視頻流壓縮編碼數據。封裝格式種類不少,例如MP4,MKV,RMVB,TS,FLV,AVI等等,它的做用就是將已經壓縮編碼的視頻數據和音頻數據按照必定的格式放到一塊兒。例如,FLV格式的數據,通過解封裝操做後,輸出H.264編碼的視頻碼流和AAC編碼的音頻碼流。windows
解碼的做用,就是將視頻/音頻壓縮編碼數據,解碼成爲非壓縮的視頻/音頻原始數據。音頻的壓縮編碼標準包含AAC,MP3,AC-3等等,視頻的壓縮編碼標準則包含H.264,MPEG2,VC-1等等。解碼是整個系統中最重要也是最複雜的一個環節。經過解碼,壓縮編碼的視頻數據輸出成爲非壓縮的顏色數據,例如YUV420P,RGB等等;壓縮編碼的音頻 數據輸出成爲非壓縮的音頻抽樣數據,例如PCM數據。瀏覽器
視音頻同步的做用,就是根據解封裝模塊處理過程當中獲取到的參數信息,同步解碼出來的視頻和音頻數據,並將視頻音頻數據送至系統的顯卡和聲卡播放出來。bash
咱們常見的封裝視頻的格式有:flv(音視頻分開)、mp四、avi等等。後面咱們會詳細說明。網絡
由於攝像頭採集到的畫面、以及麥克風採集到的音頻數據是通過壓縮的處理,否則視頻文件就會很大。數據結構
也就是說:函數
錄像、錄音,實質是一個壓縮採集的圖像或者聲音的過程。這個過程就是視頻編碼壓縮的過程。工具
播放視頻、音頻文件實質上就是解壓縮的過程,這個過程又稱爲解碼。
封裝格式的做用是:視頻碼流和音頻碼流按照必定的格式存儲在一個文件中。
封裝格式分析工具:Elecard Format Analyzer
爲何要音視頻分開存儲呢?由於音視頻的編碼格式各類各樣,同時編碼必然會形成混亂。
常見的視頻封裝格式有:
以兩個格式爲例子,介紹一下原理:
MPEG2-TS格式是由一個一個數據大小固定的TS-Packet組成,所以能夠支持快進。
FLY格式由FLV HEADER以及一個一個大小不固定的Tag組成。由於FLV格式直接可以用flash(瀏覽器)播放,所以經常使用於視頻直播鄰域。咱們在作RTMP推流的時候,一開始就須要發送頭信息。由於數據單元大小不固定,所以原生的視頻播放器不支持FLV視頻的快進(有些播放器進行了處理能夠快進)。
視頻的壓縮算法不少,所以編碼格式就會有不少種,下面介紹一些常見的編解碼格式:
以H264爲例,H264是由大小不固定的NALU構成。(NALU實質是一種數據結構)。H264裏面有不少子壓縮算法,原理比較複雜,包括了熵編碼,環路濾波,幀內檢測,幀間檢測等知識。H264編碼原理比較複雜,所以H264的壓縮效率是幾百到幾千倍。
YUV,分爲三個份量,Y:表示明亮度(Luminance或Luma),也就是灰度值;而 U 和 V :表示的則是色度(Chrominance或Chroma),做用是描述影像色彩及飽和度,用於指定像素的顏色。 YUV碼流的存儲格式其實與其採樣的方式密切相關,主流的採樣方式有三種,YUV4:4:4,YUV4:2:2,YUV4:2:0
######YUV格式採樣方式4:2由來:
在最近十年中,視頻工程師發現人眼對色度的敏感程度要低於對亮度的敏感程度。在生理學中,有一條規律,那就是人類視網膜上的視網膜杆細胞要多於視網膜錐細胞,說得通俗一些,視網膜杆細胞的做用就是識別亮度,而視網膜錐細胞的做用就是識別色度。因此,你的眼睛對於亮和暗的分辨要比對顏色的分辨精細一些。正是由於這個,在咱們的視頻存儲中,沒有必要存儲所有顏色信號。既然眼睛看不見,那爲何要浪費存儲空間(或者說是金錢)來存儲它們呢?
音頻採樣數據PCM:保存了音頻中每一個採樣點的值,音頻採樣數據體積很大,通常須要進過壓縮,咱們日常說的「無損」實質上是沒有損失的壓縮的意思。
YUV:YUV Player
PCM:Adobe Audition
查看視頻信息:MediaInfo
視頻編碼數據:Elecard Format Analyzer
視頻編碼分析工具:Elecard Stream Eye
FFmpeg是開源的C/C++音視頻處理的類庫,這個庫十分優秀,以致於不少大公司都在用。主流的視頻播放器幾乎都使用了FFmpeg。
以下圖所示:
爲了方便編寫和調試,編寫過程通常在Windows(VS)、Linux(Gcc)平臺中進行。編寫調試無誤後再再放在Android編譯器上調試。爲了方便,我這裏就在vs下進行項目配置。
先進入ffmpeg的官網:點擊打開連接,不要直接點擊頁面上最大的那個「download」,而是點擊左側標籤中的Download,再點擊「Get the packages」中的windows圖標,此時在圖標下面會出現「Windows Builds」字樣,點擊進入以後會看到有三種包能夠下載,分別是Static,Shared,Dev,咱們在這裏使用的是後兩種,其中Shared中有dll文件,Dev中有頭文件和lib文件。
選擇對應的系統,這裏咱們先介紹Windows版本的,點擊下面的Windows Builds,跳轉到下面的界面:
下面並解壓的資源以下:
####2.將下載好的include文件、lib文件和dll文件複製到工程目錄中。 將上一步下載好的包解壓,取Shared中的dll文件直接複製到工程目錄下(dll文件在bin文件夾中),取Dev中的include文件夾和lib文件夾直接複製到工程目錄下。
####3.在編譯器中進行配置(我這裏使用的是VS2013,Win64)。 這一步共須要配置三個部分: #####⑴配置屬性->C/C++->常規->附加包含目錄:設置爲include或include路徑。
#####⑵配置屬性->連接器->常規->附加庫目錄:設置爲lib或lib路徑
avcodec.lib
avdevice.lib
avfilter.lib
avformat.lib
avutil.lib
postproc.lib
swresample.lib
swscale.lib
複製代碼
####4.通過以上三步後ffmpeg的配置就已經完成了。咱們可使用一段代碼來測試是否配置成功。測試代碼以下:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
//C/C++混編,指示編譯器按照C語言進行編譯
extern "C" {
#include "libavcodec\avcodec.h"
}
void main() {
//輸出FFmpeg的配置信息,檢查是否配置好
cout << avcodec_configuration() << endl;
system("pause");
}
複製代碼
若是輸入以下結果則說明配置成功。