[總結]FFMPEG視音訊編解碼零基礎學習方法
在CSDN上的這一段日子,接觸到了很多同行業的人,尤其是使用FFMPEG進行視音訊編解碼的人,有的已經是有多年經驗的“大神”,有的是剛開始學習的初學者。在和大家探討的過程中,我忽然發現了一個問題:在“大神”和初學者之間好像有一個不可逾越的鴻溝。“大神”們水平高超,探討著深奧的問題;而初學者們還停留在入門階段。究竟是什麼原因造成的這種“兩極分化”呢?最後,我發現了問題的關鍵:FFMPEG難度比較大,卻沒有一個循序漸進,由簡單到複雜的教程。現在網上的有關FFMPEG的教程多半難度比較大,不太適合剛接觸FFMPEG的人學習;而且很多的例子程式編譯通不過,極大地打消了學習的積極性。我自己在剛開始學習FFMPEG的時候也遇到了很大的困難。為了幫助更多的人快速成為“大神”,我想總結一個學習FFMPEG的方法,方便大家循序漸進的學習FFMPEG。
PS:有不少人不清楚“FFmpeg”應該怎麼讀。它讀作“ef ef em peg”
0. 背景知識
本章主要介紹一下FFMPEG都用在了哪裡(在這裡僅列幾個我所知的,其實遠比這個多)。說白了就是為了說明:FFMPEG是非常重要的。
使用FFMPEG作為核心視訊播放器:
Mplayer,ffplay,射手播放器,暴風影音,KMPlayer,QQ影音...
使用FFMPEG作為核心的Directshow Filter:
ffdshow,lav filters...
使用FFMPEG作為核心的轉碼工具:
ffmpeg,格式工廠...
事實上,FFMPEG的視音訊編解碼功能確實太強大了,幾乎囊括了現存所有的視音訊編碼標準,因此只要做視音訊開發,幾乎離不開它。
對於完全沒有視音訊技術背景的人來說,在學習FFmpeg之前最好先了解一下幾種最基本的視音訊資料的格式,可以參考下面的文章:
1. ffmpeg程式的使用(ffmpeg.exe,ffplay.exe,ffprobe.exe)
【視訊資源】
本文中第1,2章是FFmpeg程式設計最基礎的內容。這部分的內容我在給大二同學代課的時候錄製成了視訊,有時間的話可以看一下《基於 FFmpeg + SDL 的視訊播放器的製作》課程的視訊。
本章主要介紹一下ffmpeg工程包含的三個exe的使用方法。
ffmpeg的官方網站是:http://ffmpeg.org/
編譯好的windows可用版本的下載地址(官網中可以連線到這個網站,和官方網站保持同步): http://ffmpeg.zeranoe.com/builds/
該網站中的FFMPEG分為3個版本:Static,Shared,Dev。
前兩個版本可以直接在命令列中使用,他們的區別在於:Static裡面只有3個應用程式:ffmpeg.exe,ffplay.exe,ffprobe.exe,每個exe的體積都很大,相關的Dll已經被編譯到exe裡面去了。Shared裡面除了3個應用程式:ffmpeg.exe,ffplay.exe,ffprobe.exe之外,還有一些Dll,比如說avcodec-54.dll之類的。Shared裡面的exe體積很小,他們在執行的時候,到相應的Dll中呼叫功能。
Dev版本是用於開發的,裡面包含了庫檔案xxx.lib以及標頭檔案xxx.h,這個版本不包含exe檔案。
開啟系統命令列接面,切換到ffmpeg所在的目錄,就可以使用這3個應用程式了。
1.1 ffmpeg.exe
ffmpeg是用於轉碼的應用程式。
一個簡單的轉碼命令可以這樣寫:
將input.avi轉碼成output.ts,並設定視訊的位元速率為640kbps
ffmpeg -i input.avi -b:v 640k output.ts
具體的使用方法可以參考: ffmpeg引數中文詳細解釋詳細的使用說明(英文):http://ffmpeg.org/ffmpeg.html
1.2 ffplay.exe
ffplay是用於播放的應用程式。
一個簡單的播放命令可以這樣寫:
播放test.avi
ffplay test.avi
具體的使用方法可以參考:ffplay的快捷鍵以及選項詳細的使用說明(英文):http://ffmpeg.org/ffplay.html
1.3 ffprobe.exe
ffprobe是用於檢視檔案格式的應用程式。
這個就不多介紹了。
詳細的使用說明(英文):http://ffmpeg.org/ffprobe.html
2. ffmpeg庫的使用:視訊播放器
本章開始介紹使用ffmpeg的庫進行開發。
2.1 ffmpeg庫的配置
從http://ffmpeg.zeranoe.com/builds/網站上
1.下載Dev版本,裡面包含了ffmpeg的xxx.h標頭檔案以及xxx.lib庫檔案。
2.下載Shared版本,裡面包含了ffmpeg的dll檔案。
3.將這兩部分檔案拷貝到VC工程下面就可以了
注:可能會出現問題,參見:FFMPEG 庫移植到 VC 需要的步驟
如果不想自己手動配置,可以下載已經配置好的工程:最簡單的基於FFMPEG+SDL的視訊播放器
2.2 最簡單的視訊播放器
學習文章《100行程式碼實現最簡單的基於FFMPEG+SDL的視訊播放器》中的程式碼,這是ffmpeg做視訊播放器最簡單的程式碼了,是我自己精簡出來的,已經不能再簡化了,每一行都很重要。
原版是基於SDL1.2的視訊播放器,後來更新了基於SDL2.0的最簡單的視訊播放器:最簡單的基於FFMPEG+SDL的視訊播放器 ver2 (採用SDL2.0)
上述播放器使用libavformat和libavcodec兩個類庫完成了視訊的解碼工作。實際上解碼工作只需要libavcodec就可以了。因此更新了一個“純淨”的解碼器。該解碼器只使用libavcodec完成解碼工作: 最簡單的基於FFmpeg的解碼器-純淨版(不包含libavformat)
ffmpeg的函式介紹:ffmpeg函式介紹
注1:播放視訊或音訊資料的時候會用到SDL。有關SDL可以參考:SDL介紹
SDL參考文件:SDL GUIDE 中文譯本
注2:如果想檢視解碼後的資料,需要用到 YUV播放器:YUV播放器原始碼或YUV Player Deluxe都可以
2.3 相關結構體的研究
ffmpeg的結構體之間的關係參考文章:FFMPEG中最關鍵的結構體之間的關係
結構體中每個變數的分析,參考文章:
FFMPEG結構體分析:AVFormatContextFFMPEG結構體分析:AVCodecContext
FFMPEG結構體分析:AVIOContext
FFMPEG結構體分析:AVCodec
FFMPEG結構體分析:AVStream
FFMPEG結構體分析:AVPacket
3. ffmpeg庫的使用:音訊播放器
3.1 最簡單的音訊播放器
學習文章《最簡單的基於FFMPEG+SDL的音訊播放器》 中的程式碼,和最簡單的視訊播放器一樣,這是最簡單的音訊播放器,每一行程式碼都很重要。
原版是基於SDL1.2的音訊播放器,後來更新了一個基於SDL2.0的最簡單的音訊播放器:最簡單的基於FFMPEG+SDL的音訊播放器 ver2 (採用SDL2.0)
注:如果想要檢視解碼後的資料(PCM資料),需要用到Audition。
4. ffmpeg庫的使用:一個真正的播放器——ffplay
4.1 真正的播放器
ffplay流程圖如文章《FFplay原始碼分析:整體流程圖》 所示。ffplay程式碼比較複雜,但是其核心程式碼和《100行程式碼實現最簡單的基於FFMPEG+SDL的視訊播放器》 是一樣的。可以兩個工程結合著學習。
ffplay程式碼簡介資料:如何用FFmpeg編寫一個簡單播放器
ffplay使用說明:ffplay的快捷鍵以及選項
ffplay已經移植到VC下的工程:ffplay_vc2005(別人做的,質量很不錯)
ffplay移植到MFC下的工程,包含了簡單的圖形介面和一些控制按鈕:ffplay播放器移植VC的工程:ffplay for MFC
上述軟體的程式碼簡介:ffplay for mfc 程式碼備忘
ffplay.c函式結構簡單分析:ffplay.c函式結構簡單分析(畫圖)
5. ffmpeg庫的使用:編碼
5.1 編碼
ffmpeg編碼我自己研究的不是很多,可以參考文章 :使用FFmpeg類庫實現YUV視訊序列編碼為視訊
上面那篇文章是用的類庫比較舊,新版類庫的的使用可以參考下面幾篇文章。
影象的編碼可以參考:最簡單的基於FFMPEG的影象編碼器(YUV編碼為JPEG)
音訊的編碼可以參考:最簡單的基於FFMPEG的音訊編碼器(PCM編碼為AAC)
視訊的編碼可以參考:最簡單的基於FFMPEG的視訊編碼器(YUV編碼為H.264)
HEVC(H.265)視訊編碼可以參考:最簡單的基於FFmpeg的視訊編碼器-更新版(YUV編碼為HEVC(H.265))
上述編碼器使用libavformat和libavcodec兩個類庫完成了視訊的編碼工作。實際上編碼工作只需要libavcodec就可以了。因此更新了一個“純淨”的編碼器。該編碼器只使用libavcodec完成編碼工作: 最簡單的基於FFmpeg的編碼器-純淨版(不包含libavformat)
5.2 轉碼
轉碼實際上是先解碼然後編碼。
不進行轉碼,只進行封裝格式轉換的程式可參考:最簡單的基於FFMPEG的封裝格式轉換器(無編解碼)
轉碼程式可參考:最簡單的基於FFMPEG的轉碼程式
比較複雜的轉碼程式可以參考ffmpeg.c,它移植到MFC下的工程:ffmpeg轉碼器移植VC的工程:ffmpeg for MFC
ffmpeg.c函式結構簡單分析:ffmpeg.c函式結構簡單分析(畫圖)
6. ffmpeg原始碼分析
通曉了ffmpeg庫的使用以後,可以看一下ffmpeg的原始碼。注意ffmpeg的原始碼只有在linux下才能編譯,在windows下可以使用MinGW進行編譯。推薦使用Eclipse檢視ffmpeg的原始碼。
有一個很完整的ffmpeg原始碼的分析文件:ffdoc
FFmpeg的庫函式原始碼分析文章列表如下:
【架構圖】
【通用】
FFmpeg 原始碼簡單分析:av_register_all()
FFmpeg 原始碼簡單分析:avcodec_register_all()
FFmpeg 原始碼簡單分析:記憶體的分配和釋放(av_malloc()、av_free()等)
FFmpeg 原始碼簡單分析:常見結構體的初始化和銷燬(AVFormatContext,AVFrame等)
FFmpeg 原始碼簡單分析:av_find_decoder()和av_find_encoder()
FFmpeg 原始碼簡單分析:avcodec_open2()
FFmpeg 原始碼簡單分析:avcodec_close()
【解碼】
圖解FFMPEG開啟媒體的函式avformat_open_input
FFmpeg 原始碼簡單分析:avformat_open_input()
FFmpeg 原始碼簡單分析:avformat_find_stream_info()
FFmpeg 原始碼簡單分析:av_read_frame()
FFmpeg 原始碼簡單分析:avcodec_decode_video2()
FFmpeg 原始碼簡單分析:avformat_close_input()
【編碼】
FFmpeg 原始碼簡單分析:avformat_alloc_output_context2()
FFmpeg 原始碼簡單分析:avformat_write_header()
FFmpeg 原始碼簡單分析:avcodec_encode_video()
FFmpeg 原始碼簡單分析:av_write_frame()
FFmpeg 原始碼簡單分析:av_write_trailer()
【其它】
FFmpeg原始碼簡單分析:日誌輸出系統(av_log()等)
FFmpeg原始碼簡單分析:結構體成員管理系統-AVClass
FFmpeg原始碼簡單分析:結構體成員管理系統-AVOption
FFmpeg原始碼簡單分析:libswscale的sws_getContext()
FFmpeg原始碼簡單分析:libswscale的sws_scale()
FFmpeg原始碼簡單分析:libavdevice的avdevice_register_all()
FFmpeg原始碼簡單分析:libavdevice的gdigrab
【指令碼】
偏底層的libavcodec的原始碼分析文章列表如下:
【解碼- libavcodec H.264 解碼器】
FFmpeg的H.264解碼器原始碼簡單分析:解析器(Parser)部分
FFmpeg的H.264解碼器原始碼簡單分析:解碼器主幹部分
FFmpeg的H.264解碼器原始碼簡單分析:熵解碼(EntropyDecoding)部分
FFmpeg的H.264解碼器原始碼簡單分析:巨集塊解碼(Decode)部分-幀內巨集塊(Intra)
FFmpeg的H.264解碼器原始碼簡單分析:巨集塊解碼(Decode)部分-幀間巨集塊(Inter)
FFmpeg的H.264解碼器原始碼簡單分析:環路濾波(LoopFilter)部分
【解碼-libavcodec HEVC 解碼器】
FFmpeg的HEVC解碼器原始碼簡單分析:解析器(Parser)部分
FFmpeg的HEVC解碼器原始碼簡單分析:CTU解碼(CTUDecode)部分-PU
FFmpeg的HEVC解碼器原始碼簡單分析:CTU解碼(CTU Decode)部分-TU
FFmpeg的HEVC解碼器原始碼簡單分析:環路濾波(LoopFilter)
7.FFmpeg其它幾個類庫的使用
7.1.libavfilter(加特效)
AVFilter可以給視音訊新增各種濾鏡效果。有兩個例子,一個是給視訊新增水印:
另一個是給YUV資料加特效:
7.2.libavdevice(讀裝置)
AVDevice可以讀取電腦的多媒體裝置的資料,或者輸出資料到指定的多媒體裝置上。
直接使用ffmpeg.exe命令列工具的文章:FFmpeg獲取DirectShow裝置資料(攝像頭,錄屏)
程式設計方面做了2個有關的例子:
讀取攝像頭:最簡單的基於FFmpeg的AVDevice例子(讀取攝像頭)
螢幕錄製:最簡單的基於FFmpeg的AVDevice例子(螢幕錄製)
7.3.libswscale(影象拉伸,畫素格式轉換)
Swscale類庫可以轉換畫素資料的格式,同時可以拉伸影象的大小。
libswscale的使用示例: 最簡單的基於FFmpeg的libswscale的示例(YUV轉RGB)
此外,這個示例還附帶了一個程式,用於生成測試圖片: 最簡單的基於FFmpeg的libswscale的示例附件:測試圖片生成工具8.FFmpeg封裝格式的處理
使用FFmpeg進行封裝格式的處理,主要是通過AVFormat完成。有關封裝格式的處理,做了3個例子:封裝格式轉換器:最簡單的基於FFMPEG的封裝格式轉換器(無編解碼)
視音訊分離器簡化版(demuxer-simple):最簡單的基於FFmpeg的封裝格式處理:視音訊分離器簡化版(demuxer-simple)
視音訊分離器(demuxer):最簡單的基於FFmpeg的封裝格式處理:視音訊分離器(demuxer)
視音訊複用器(muxer):最簡單的基於FFmpeg的封裝格式處理:視音訊複用器(muxer)
9.FFmpeg流媒體方面的應用
使用FFmpeg進行流媒體方面的應用,主要是流媒體的傳送和接收。直接使用ffmpeg.exe命令列工具的文章:
程式設計方面做了一個例子:
基於FFmpeg的推流器:最簡單的基於FFmpeg的推流器(以推送RTMP為例)
10.FFmpeg的其他雜項
使用FFmpeg讀寫記憶體(而非檔案)的例子:記憶體播放器:最簡單的基於FFmpeg的記憶體讀寫的例子:記憶體播放器
記憶體轉碼器:最簡單的基於FFmpeg的記憶體讀寫的例子:記憶體轉碼器
11. ffmpeg在其它平臺下的應用
把FFmpeg應用於Android、IOS、Windows Phone的示例程式可以參考:
最簡單的基於FFmpeg的移動端例子:Android HelloWorld
最簡單的基於FFmpeg的移動端例子:Android 視訊解碼器
最簡單的基於FFmpeg的移動端例子:Android 視訊解碼器-單個庫版
最簡單的基於FFmpeg的移動端例子:Android 推流器
最簡單的基於FFmpeg的移動端例子:Android 視訊轉碼器
最簡單的基於FFmpeg的移動端例子附件:Android 自帶播放器
最簡單的基於FFmpeg的移動端例子附件:SDL Android HelloWorld
最簡單的基於FFmpeg的移動端例子:IOS HelloWorld
最簡單的基於FFmpeg的移動端例子:Windows PhoneHelloWorld
12. ffmpeg相關工程的學習
學習完成ffmpeg,還可以瞭解一下基於ffmpeg的相關的多媒體開源工程,在這裡推薦以下幾個:
12.1 ffdshow
ffdshow是基於ffmpeg的解碼器類庫libavcodec的DirectShow Filter。廣泛安裝在PC上。
有關ffdshow的原始碼分析文章(更新中):
ffdshow 原始碼分析1 : 整體結構
ffdshow 原始碼分析 2: 點陣圖覆蓋濾鏡(對話方塊部分Dialog)
ffdshow 原始碼分析 4: 點陣圖覆蓋濾鏡(濾鏡部分Filter)
ffdshow 原始碼分析 5: 點陣圖覆蓋濾鏡(總結)
ffdshow 原始碼分析 6: 對解碼器的dll的封裝(libavcodec)
ffdshow 原始碼分析 7: libavcodec視訊解碼器類(TvideoCodecLibavcodec)
ffdshow 原始碼分析 8: 視訊解碼器類(TvideoCodecDec)
ffdshow 原始碼分析 9: 編解碼器有關類的總結
12.2 LAV filters
LAV Filter是基於ffmpeg的解碼器類庫libavcodec,以及解封裝器類庫libavformat的DirectShow Filter。廣泛安裝在PC上。
有關LAV Filter的原始碼分析文章:
LAV Filter 原始碼分析 2: LAV Splitter
LAV Filter 原始碼分析 3: LAV Video (1)
LAV Filter 原始碼分析 4: LAV Video (2)
12.3 Mplayer
Mplayer是Linux下使用最廣泛的播放器,也有Windows版本的。其中使用了ffmpeg。
有關Mplayer的原始碼分析文章:
12.4 Media Player Classic - HC
現在廣為使用很多播放器都是構建於Media Player Classic - HC的基礎之上的。
有關Media Player Classic - HC的原始碼分析文章:
Media Player Classic - HC 原始碼分析 1:整體結構
Media Player Classic - HC 原始碼分析 2:核心類 (CMainFrame)(1)
Media Player Classic - HC 原始碼分析 3:核心類 (CMainFrame)(2)
Media Player Classic - HC 原始碼分析 4:核心類 (CMainFrame)(3)
Media Player Classic - HC 原始碼分析 5:關於對話方塊 (CAboutDlg)
Media Player Classic - HC 原始碼分析 6:MediaInfo選項卡 (CPPageFileMediaInfo)
Media Player Classic - HC 原始碼分析 7:詳細資訊選項卡(CPPageFileInfoDetails)
12.5 XBMC
XBMC是一個優秀的自由和開源的(GPL)媒體中心軟體。
有關XBMC原始碼分析文章:
XBMC原始碼分析 4:視訊播放器(dvdplayer)-解碼器(以ffmpeg為例)
XBMC原始碼簡析 5:視訊播放器(dvdplayer)-解複用器(以ffmpeg為例)
XBMC原始碼分析 6:視訊播放器(dvdplayer)-檔案頭(以ffmpeg為例)
XBMC原始碼分析 7:視訊播放器(dvdplayer)-輸入流(以libRTMP為例)
相關文章
- FFMPEG視音訊編解碼學習(1)音訊
- 一、視音訊編解碼技術零基礎(理論總結)音訊
- 各種音視訊編解碼學習詳解
- FFmpeg音訊解碼音訊
- ffmpeg解碼音訊流音訊
- 各種音訊視訊編碼方法音訊
- FFmpeg音視訊編譯配置選項編譯
- 視訊編解碼學習之一:理論基礎
- ffmpeg實戰-音視訊基礎概念
- FFmpeg學習總結
- Android 音視訊 - MediaCodec 編解碼音視訊Android
- 音訊編碼基礎詳解音訊
- 音視訊學習之 - H264編碼
- FFmpeg音視訊同步
- ffmpeg音訊編碼之pcm轉碼aac音訊
- Android 音視訊開發 視訊編碼,音訊編碼格式Android音訊
- FFmpeg iOS 音訊開發的小總結iOS音訊
- FFmpeg學習之一(FFmpeg原始碼編譯)原始碼編譯
- 音視訊開發-全網最全常用音視訊編碼和格式彙總
- FFmpeg開發筆記(八):ffmpeg解碼音訊並使用SDL同步音訊播放筆記音訊
- 使用FFmpeg處理音視訊
- NDK開發——FFmpeg視訊解碼
- 全套日語視訊教程(教你如何零基礎學習日語)
- ffmpeg實戰-音視訊合成案例
- ffmpeg命令錄製windows音視訊Windows
- 音訊編解碼-speex庫的使用方法音訊
- 音視訊學習(一)-- 基礎知識準備
- 音訊編碼基礎知識音訊
- FFmpeg打造Android萬能音訊播放器總結Android音訊播放器
- FFmpeg命令影片音訊轉碼引數詳解音訊
- 音視訊學習路線
- Android音視訊(四)MediaCodec編解碼AACAndroid
- 零基礎學習Java,全方位知識點總結!Java
- 音訊編解碼標準音訊
- C#程式呼叫FFmpeg操作音視訊C#
- [FFmpeg + OpenGL + OpenSL ES]音視訊同步- 8
- 音訊解碼基礎講解音訊
- 音視訊學習筆記(一)筆記