30分帶你從認識FFmpeg到玩轉FFmpeg

一、ffmpeg介紹

文章最後有福利

FFmpeg是一套可以用來記錄、轉換數字音頻、視頻,並能將其轉化為流的開源計算機程序。採用LGPL或GPL許可證。它提供了錄製、轉換以及流化音視頻的完整解決方案。它包含了非常先進的音頻/視頻編解碼庫libavcodec,為了保證高可移植性和編解碼質量,libavcodec裡很多code都是從頭開發的。

框圖如圖所示:

30分帶你從認識FFmpeg到玩轉FFmpeg

二、編解碼基礎知識

(1)封裝格式

所謂封裝格式是指音視頻的組合格式,例如最常見的封裝格式有mp4、mp3、flv等。簡單來說,我們平時接觸到的帶有後綴的音視頻文件都是一種封裝格式。

(2)編碼格式

以mp4為例,通常應該包含有視頻和音頻。視頻的編碼格式為YUV420P,音頻的編碼格式為PCM。再以YUV420編碼格式為例。我們知道通常圖像的顯示為RGB(紅綠藍三原色),在視頻壓縮的時候會首先將代表每一幀畫面的RGB壓縮為YUV,再按照關鍵幀(I幀),過渡幀(P幀或B幀)進行運算和編碼。解碼的過程正好相反,解碼器會讀到I幀,並根據I幀運算和解碼P幀以及B幀。並最終根據視頻文件預設的FPS還原每一幀畫面的RGB數據。最後推送給顯卡。所以通常我們說的編碼過程就包括:畫面採集、轉碼、編碼再封裝。

(3)視頻解碼和音頻解碼有什麼區別

FPS是圖像領域中的定義,是指畫面每秒傳輸幀數,通俗來講就是指動畫或視頻的畫面數。FPS太低畫面會感覺閃爍不夠連貫,FPS越高需要顯卡性能越好。一些高速攝像機的採集速度能夠達到11000幀/秒,那麼在播放這類影片的時候我們是否也需要以11000幀/秒播放呢?當然不是,通常我們會按照25幀/秒或者60幀/秒設定圖像的FPS值。但是由於視頻存在關鍵幀和過渡幀的區別,關鍵幀保存了完整的畫面而過渡幀只是保存了與前一幀畫面的變化部分,需要通過關鍵幀計算獲得。因此我們需要對每一幀都進行解碼,即獲取畫面的YUV數據。同時只對我們真正需要顯示的畫面進行轉碼,即將YUV數據轉換成RGB數據,包括計算畫面的寬高等。

三、代碼實現

(1)註冊FFmpeg組件

//註冊和初始化FFmpeg封裝器和網絡設備

(2)打開文件和創建輸入設備

AVFormatContext 表示一個封裝器,

在讀取多媒體文件的時候,它負責保存與封裝和編解碼有關的上下文信息。

(3)遍歷流並初始化解碼器

封裝器中保存了各種流媒體的通道,通常視頻通道為0,音頻通道為1。

除此以外可能還包含字幕流通道等。

第2步和第3步基本就是打開多媒體文件的主要步驟,

解碼和轉碼的所有參數都可以在這裡獲取。

接下來我們就需要循環進行讀取、解碼、轉碼直到播放完成。

(4)讀取壓縮數據

/*之所以稱為壓縮數據主要是為了區分AVPacket和AVFrame兩個結構體。

AVPacket表示一幅經過了關鍵幀或過渡幀編碼後的畫面,

AVFrame表示一個AVPacket經過解碼後的完整YUV畫面*/

(5)解碼

(6)視頻轉碼

// 720p輸出標準

/*

這裡需要解釋一下outWidth * outHeight * 4計算理由:

720p標準的視頻畫面包含720 * 480個像素點,

每一個像素點包含了RGBA4類數據,每一類數據分別由1個byte即8個bit表示。

因此一幅完整畫面所佔的大小為outWidth * outHeight * 4。

(7)音頻轉碼

四、代碼地址

基於qt的FFmpeg客戶端(Linux版本):

服務端可採用LIVE555服務器 ,參考博文:

零 背景知識

本章主要介紹一下FFMPEG都用在了哪裡(在這裡僅列幾個我所知的,其實遠比這個多)。說白了就是為了說明:FFMPEG是非常重要的。

使用FFMPEG作為內核視頻播放器:

30分帶你從認識FFmpeg到玩轉FFmpeg

使用FFMPEG作為內核的Directshow Filter:

30分帶你從認識FFmpeg到玩轉FFmpeg

使用FFMPEG作為內核的轉碼工具:

30分帶你從認識FFmpeg到玩轉FFmpeg

事實上,FFMPEG的視音頻編解碼功能確實太強大了,幾乎囊括了現存所有的視音頻編碼標準,因此只要做視音頻開發,幾乎離不開它。

1.1ffmpeg程序的使用

FFmpeg項目由以下幾部分組成:

  • FFmpeg視頻文件轉換命令行工具,也支持經過實時電視卡抓取和編碼成視頻文件;
  • ffserver基於HTTP、RTSP用於實時廣播的多媒體服務器.也支持時間平移;
  • ffplay用 SDL和FFmpeg庫開發的一個簡單的媒體播放器;
  • libavcodec一個包含了所有FFmpeg音視頻編解碼器的庫。為了保證最優性能和高可複用性,大多數編解碼器從頭開發的;
  • libavformat一個包含了所有的普通音視格式的解析器和產生器的庫。

1.2 誰在使用ffmpeg

  • 使用FFMPEG作為內核視頻播放器:Mplayer,ffplay,射手播放器,暴風影音,KMPlayer,QQ影音...
  • 使用FFMPEG作為內核的Directshow Filter:ffdshow,lav filters...
  • 使用FFMPEG作為內核的轉碼工具:ffmpeg,格式工廠...

2.如何安裝

30分帶你從認識FFmpeg到玩轉FFmpeg

FFmpeg可以在Windows、Linux還有Mac OS等多種操作系統中進行安裝和使用。

FFmpeg分為3個版本:Static、 Shared、 Dev

  • 前兩個版本可以直接在命令行中使用。包含了三個exe:ffmpeg.exe,ffplay.exe,ffprobe.exe
  • Static版本中的exe體積較大,那是因為相關的Dll都已經編譯進exe裡面去了。
  • Shared版本中exe的體積相對小很多,是因為它們運行的時候還需要到相關的dll中調用相應的功能
  • Dev版本用於開發,裡面包含了庫文件xxx.lib以及頭文件xxx.h

3.怎麼使用

3.1 命令行工具的使用

3.11 ffmpeg.exe

用於轉碼的應用程序:

30分帶你從認識FFmpeg到玩轉FFmpeg

ffmpeg -i input.avi -b:v 640k output.ts

具體用法參考: ffmpeg參數中文詳細解釋

詳細的使用說明(英文):http://ffmpeg.org/ffmpeg.html

3.12 ffplay.exe

主要用於播放的應用程序

播放test.avi


ffplay test.avi

具體的使用方法可以參考:ffplay的快捷鍵以及選項

3.13 ffprobe.exe

ffprobe是用於查看文件格式的應用程序。

30分帶你從認識FFmpeg到玩轉FFmpeg

3.2 使用ffmpeg庫進行開發

To Be Continue...

FFMPEG高級篇

FFmpeg基本環境搭建及編譯

FFmpeg的解封裝基本處理

FFmpeg用於硬件設備解碼的關鍵擴展數據處理

FFmpeg用於硬件的track mode基本控制

虛擬機安裝

由於是在自己家裡,不是工作環境,電腦還是裝的windows7系統,於是開始安裝虛擬機,我平時一直都喜歡用VMWare這個虛擬機,上次買了新電腦後一直都沒有安裝,這次必須先安裝上。先是安裝了最新的VMWare Workstation 11 + Ubuntu14.04,發現跑起來巨慢無比,難道是我的電腦落伍了?沒有辦法,也不想去折騰這個事情,還是老老實實換了一個VMWare Workstation 10.0.1 build-1379776 + Ubuntu-12.04.4-alternate-i386,最好跑起來還湊合。具體虛擬機和Ubuntu的安裝過程就不詳述了,網上文章一大堆。

配置並編譯

下載最新版本的ffmpeg,目前穩定版本是ffmpeg-2.6.1。進入虛擬機解壓:

30分帶你從認識FFmpeg到玩轉FFmpeg

配置

30分帶你從認識FFmpeg到玩轉FFmpeg

然後進行make編譯,最後出現錯誤:

30分帶你從認識FFmpeg到玩轉FFmpeg

原來忽略了直接在windows的共享目錄中,解壓到Linux目錄中便不會出現這個問題了。當然如果我們編譯的不是共享庫,而是靜態庫,也不會出現這個問題,因為沒有Linux的鏈接文件。

在Linux目錄下,編譯成功,生成我們的動態庫:

30分帶你從認識FFmpeg到玩轉FFmpeg

這樣我們生產了我們需要的動態庫和頭文件。

大家可能糊塗了,我現在是在pc上編譯的,不能用於嵌入式設備上。這個我知道,我也沒有辦法,現在我已經沒有以前的那些ARM的編譯環境。大家如果是在實際的交叉環境下,配置ffmpeg的configure時指定交叉編譯參數,估計大概如下面的配置:

./configure --prefix=./install --disable-static --enable-shared --enable-gpl --enable-pthreads --cross-prefix=arm-none-linux-gnueabi- --enable-cross-compile --target-os=linux --extra-cflags="-mcpu=arm9 -W -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -O2 -Wall" --arch=armv4l --cpu=arm9

當然這些既是根據具體的環境修改了。這裡就不多說,本文只有在PC上來講解。

30分帶你從認識FFmpeg到玩轉FFmpeg

FFmpeg總結

視頻大小

ntsc:408P,對應分辨率為720*480,建議碼率為1800Kbps

snits:對應分辨率640*480

hd720:720P,對應分辨率為1280*720,建議碼率為3500Kbps

hd1080:1080P,對應分辨率為1920*1080,建議碼率為8500Kbps

可變碼率(VBR):動態比特率編碼,指編碼器的輸出碼率可以根據編碼器輸入源信號的複雜度自適應調整,目前是達到輸出質量保持不變。VBR適於存儲,不適合流式傳輸,它能有效利用有限空間。

固定碼率(CBR):指編碼器輸出碼率固定,不適合存儲,CBR對於複雜內容可能沒有足夠碼率進行編碼,

幀數:每秒鐘播放的圖片數(fps)。高的幀率可以得到更流暢、更逼真的畫面。但是幀率很大會浪費圖形處理的能力,因為顯示器不能以更快的速度更新,則超過刷新率的幀率就浪費掉。同一視頻,統一碼率情況下,幀數越多,畫質越不好。因為每張畫面會分擔每秒有限的文件體積,如果畫面越多,那麼每張畫面所能表現的內容越有限。一般30fps就基本流暢,50fps就有行雲流水感覺,很難區分60fps與100fps區別。

分辨率:畫面大小,單位是像素。和編碼率的關係:越高的分辨率,需要越高的編碼率。因為圖像細節多,需要文件體積大。同一碼率,畫面越大,圖像馬賽克程度越明顯。

採樣率:每秒鐘對音頻信號的採樣次數,採樣率越高聲音還原度越高,聲音越自然,單位Hz。一般音頻文件採樣率44100Hz,即1秒鐘採樣44100次。低於這個值,聲音會有明顯損失,高於這個值,人耳難以分辨,同時會增加音頻文件所佔用的空間。

30分帶你從認識FFmpeg到玩轉FFmpeg

參考資料 :私信‘資料'可MF領取相關資料,C++、linux,

  • FFMPEG視音頻編解碼零基礎學習方法
  • FFmpeg使用小記
  • FFmpeg官方文檔
  • 如何在Windows上安裝FFmpeg程序
  • ffmpeg教程 (一) 基本安裝

第一時間獲得博客更新提醒,以及更多技術信息分享,歡迎關注私信我,

1.直接幫你解答ffmpeg相關疑問c++。linux,TCP。

2.第一時間獲得業內十多個領域技術文章

3.針對文章內疑點提出問題,第一時間回覆你,幫你耐心解答

4.讓你和原創作者成為很好的朋友,拓展自己的人脈資源


分享到:


相關文章: