在CSDN上的這一段日子,接觸到了很多同行業的人,尤其是使用進行視音頻編解碼的人,有的已經是有多年經驗的“大神”,有的是剛開始學習的初學者。在和大家探討的過程中,我忽然發現了一個問題:在“大神”和初學者之間好像有一個不可逾越的鴻溝。“大神”們水平高超,探討著深奧的問題;而初學者們還停留在入門階段。究竟是什么原因造成的這種“兩極分化”呢?最后,我發現了問題的關鍵:難度比較大,卻沒有一個循序漸進,由簡單到復雜的教程。現在網上的有關的教程多半難度比較大,不太適合剛接觸的人學習;而且很多的例子程序編譯通不過,極大地打消了學習的積極性。我自己在剛開始學習的時候也遇到了很大的困難。為了幫助更多的人快速成為“大神”,我想總結一個學習的方法,方便大家循序漸進的學習。
PS:有不少人不清楚“”應該怎么讀。它讀作“ef ef em peg”
0. 背景知識
本章主要介紹一下都用在了哪里(在這里僅列幾個我所知的,其實遠比這個多)。說白了就是為了說明:是非常重要的。
使用作為內核視頻播放器:
,,射手播放器,暴風影音,,QQ影音…
使用作為內核的 :
,lav …
使用作為內核的轉碼工具:
,格式工廠…
事實上,的視音頻編解碼功能確實太強大了格式工廠能轉exe視頻嗎,幾乎囊括了現存所有的視音頻編碼標準,因此只要做視音頻開發,幾乎離不開它。
對于完全沒有視音頻技術背景的人來說,在學習之前最好先了解一下幾種最基本的視音頻數據的格式,可以參考下面的文章:
[總結]視音頻編解碼技術零基礎學習方法
視音頻數據處理入門:RGB、YUV像素數據處理
視音頻數據處理入門:PCM音頻采樣數據處理
視音頻數據處理入門:H.264視頻碼流解析
視音頻數據處理入門:AAC音頻碼流解析
視音頻數據處理入門:FLV封裝格式解析
視音頻數據處理入門:UDP-RTP協議解析
1. 程序的使用(.exe,.exe,.exe)
【視頻資源】
本文中第1,2章是編程最基礎的內容。這部分的內容我在給大二同學代課的時候錄制成了視頻,有時間的話可以看一下《基于 + SDL 的視頻播放器的制作》課程的視頻。
本章主要介紹一下工程包含的三個exe的使用方法。
的官方網站是:
編譯好的可用版本的下載地址(官網中可以連接到這個網站,和官方網站保持同步):
該網站中的分為3個版本:,,Dev。
前兩個版本可以直接在命令行中使用格式工廠能轉exe視頻嗎,他們的區別在于:里面只有3個應用程序:.exe,.exe,.exe,每個exe的體積都很大,相關的Dll已經被編譯到exe里面去了。里面除了3個應用程序:.exe,.exe,.exe之外,還有一些Dll,比如說-54.dll之類的。里面的exe體積很小,他們在運行的時候,到相應的Dll中調用功能。
Dev版本是用于開發的,里面包含了庫文件xxx.lib以及頭文件xxx.h,這個版本不包含exe文件。
打開系統命令行接面,切換到所在的目錄,就可以使用這3個應用程序了。
1.1 .exe
是用于轉碼的應用程序。
一個簡單的轉碼命令可以這樣寫:
將input.avi轉碼成.ts,并設置視頻的碼率為
[plain]
-.avi-b:.ts
ffmpeg -i input.avi -b:v 640k output.ts
具體的使用方法可以參考: 參數中文詳細解釋
詳細的使用說明(英文):
1.2 .exe
是用于播放的應用程序。
一個簡單的播放命令可以這樣寫:
播放test.avi
[plain]
.avi
ffplay test.avi
具體的使用方法可以參考: 的快捷鍵以及選項
詳細的使用說明(英文):
1.3 .exe
是用于查看文件格式的應用程序。
這個就不多介紹了。
詳細的使用說明(英文):
2. 庫的使用:視頻播放器
本章開始介紹使用的庫進行開發。
2.1 庫的配置
從網站上
1.下載Dev版本,里面包含了的xxx.h頭文件以及xxx.lib庫文件。
2.下載版本,里面包含了的dll文件。
3.將這兩部分文件拷貝到VC工程下面就可以了
注:可能會出現問題,參見: 庫移植到 VC 需要的步驟
如果不想自己手動配置,可以下載已經配置好的工程:最簡單的基于+SDL的視頻播放器
2.2 最簡單的視頻播放器
學習文章《100行代碼實現最簡單的基于+SDL的視頻播放器》中的代碼,這是做視頻播放器最簡單的代碼了,是我自己精簡出來的,已經不能再簡化了,每一行都很重要。
原版是基于SDL1.2的視頻播放器,后來更新了基于SDL2.0的最簡單的視頻播放器:最簡單的基于+SDL的視頻播放器 ver2 (采用SDL2.0)
上述播放器使用和兩個類庫完成了視頻的解碼工作。實際上解碼工作只需要就可以了。因此更新了一個“純凈”的解碼器。該解碼器只使用完成解碼工作:最簡單的基于的解碼器-純凈版(不包含)
的函數介紹:函數介紹
注1:播放視頻或音頻數據的時候會用到SDL。有關SDL可以參考:SDL介紹
SDL參考文檔:SDL GUIDE 中文譯本
注2:如果想查看解碼后的數據,需要用到 YUV播放器:YUV播放器源代碼或YUV 都可以
2.3 相關結構體的研究
的結構體之間的關系參考文章:中最關鍵的結構體之間的關系
結構體中每個變量的分析,參考文章:
結構體分析:
結構體分析:
結構體分析:
結構體分析:
結構體分析:
結構體分析:
結構體分析:
3. 庫的使用:音頻播放器 3.1 最簡單的音頻播放器
學習文章《最簡單的基于+SDL的音頻播放器》 中的代碼,和最簡單的視頻播放器一樣,這是最簡單的音頻播放器,每一行代碼都很重要。
原版是基于SDL1.2的音頻播放器,后來更新了一個基于SDL2.0的最簡單的音頻播放器:最簡單的基于+SDL的音頻播放器 ver2 (采用SDL2.0)
注:如果想要查看解碼后的數據(PCM數據),需要用到。
4. 庫的使用:一個真正的播放器—— 4.1 真正的播放器
流程圖如文章《源代碼分析:整體流程圖》 所示。代碼比較復雜,但是其核心代碼和《100行代碼實現最簡單的基于+SDL的視頻播放器》 是一樣的。可以兩個工程結合著學習。
代碼簡介資料:如何用編寫一個簡單播放器
使用說明:的快捷鍵以及選項
已經移植到VC下的工程:(別人做的,質量很不錯)
移植到MFC下的工程,包含了簡單的圖形界面和一些控制按鈕:播放器移植VC的工程: for MFC
上述軟件的代碼簡介: for mfc 代碼備忘
.c函數結構簡單分析:.c函數結構簡單分析(畫圖)
5. 庫的使用:編碼
5.1 編碼
編碼我自己研究的不是很多,可以參考文章:使用類庫實現YUV視頻序列編碼為視頻
上面那篇文章是用的類庫比較舊,新版類庫的的使用可以參考下面幾篇文章。
圖像的編碼可以參考:最簡單的基于的圖像編碼器(YUV編碼為JPEG)
音頻的編碼可以參考:最簡單的基于的音頻編碼器(PCM編碼為AAC)
視頻的編碼可以參考:最簡單的基于的視頻編碼器(YUV編碼為H.264)
HEVC(H.265)視頻編碼可以參考:最簡單的基于的視頻編碼器-更新版(YUV編碼為HEVC(H.265))
上述編碼器使用和兩個類庫完成了視頻的編碼工作。實際上編碼工作只需要就可以了。因此更新了一個“純凈”的編碼器。該編碼器只使用完成編碼工作:最簡單的基于的編碼器-純凈版(不包含)
5.2 轉碼
轉碼實際上是先解碼然后編碼。
不進行轉碼,只進行封裝格式轉換的程序可參考:最簡單的基于的封裝格式轉換器(無編解碼)
轉碼程序可參考:最簡單的基于的轉碼程序
比較復雜的轉碼程序可以參考.c,它移植到MFC下的工程:轉碼器移植VC的工程: for MFC
.c函數結構簡單分析:.c函數結構簡單分析(畫圖)
6. 源代碼分析
通曉了庫的使用以后,可以看一下的源代碼。注意的源代碼只有在linux下才能編譯,在下可以使用MinGW進行編譯。推薦使用查看的源代碼。
有一個很完整的源代碼的分析文檔:ffdoc
的庫函數源代碼分析文章列表如下:
【架構圖】
源代碼結構圖 - 解碼
源代碼結構圖 - 編碼
【通用】
源代碼簡單分析:()
源代碼簡單分析:()
源代碼簡單分析:內存的分配和釋放(()、()等)
源代碼簡單分析:常見結構體的初始化和銷毀(,等)
源代碼簡單分析:()
源代碼簡單分析:()和()
源代碼簡單分析:()
源代碼簡單分析:()
【解碼】
圖解打開媒體的函數
源代碼簡單分析:()
源代碼簡單分析:_info()
源代碼簡單分析:()
源代碼簡單分析:2()
源代碼簡單分析:()
【編碼】
源代碼簡單分析:()
源代碼簡單分析:r()
源代碼簡單分析:()
源代碼簡單分析:()
源代碼簡單分析:()
【其它】
源代碼簡單分析:日志輸出系統(()等)
源代碼簡單分析:結構體成員管理系統-
源代碼簡單分析:結構體成員管理系統-
源代碼簡單分析:的()
源代碼簡單分析:的()
源代碼簡單分析:的l()
源代碼簡單分析:的
【腳本】
源代碼簡單分析:
源代碼簡單分析:
偏底層的的源代碼分析文章列表如下:
【解碼- H.264 解碼器】
的H.264解碼器源代碼簡單分析:概述
的H.264解碼器源代碼簡單分析:解析器()部分
的H.264解碼器源代碼簡單分析:解碼器主干部分
的H.264解碼器源代碼簡單分析:熵解碼()部分
的H.264解碼器源代碼簡單分析:宏塊解碼()部分-幀內宏塊(Intra)
的H.264解碼器源代碼簡單分析:宏塊解碼()部分-幀間宏塊(Inter)
的H.264解碼器源代碼簡單分析:環路濾波()部分
【解碼- HEVC 解碼器】
的HEVC解碼器源代碼簡單分析:概述
的HEVC解碼器源代碼簡單分析:解析器()部分
的HEVC解碼器源代碼簡單分析:解碼器主干部分
的HEVC解碼器源代碼簡單分析:CTU解碼()部分-PU
的HEVC解碼器源代碼簡單分析:CTU解碼(CTU )部分-TU
的HEVC解碼器源代碼簡單分析:環路濾波()
7.其它幾個類庫的使用 7.1.(加特效)
可以給視音頻添加各種濾鏡效果。有兩個例子,一個是給視頻添加水印:
最簡單的基于的例子(水印疊加)
另一個是給YUV數據加特效:
最簡單的基于的的例子-純凈版
7.2.(讀設備)
可以讀取電腦的多媒體設備的數據,或者輸出數據到指定的多媒體設備上。
直接使用.exe命令行工具的文章:獲取設備數據(攝像頭,錄屏)
編程方面做了2個有關的例子:
讀取攝像頭:最簡單的基于的例子(讀取攝像頭)
屏幕錄制:最簡單的基于的例子(屏幕錄制)
7.3.(圖像拉伸,像素格式轉換)
類庫可以轉換像素數據的格式,同時可以拉伸圖像的大小。
的使用示例:最簡單的基于的的示例(YUV轉RGB)
此外,這個示例還附帶了一個程序,用于生成測試圖片: 最簡單的基于的的示例附件:測試圖片生成工具8.封裝格式的處理使用進行封裝格式的處理,主要是通過完成。有關封裝格式的處理,做了3個例子:
封裝格式轉換器:最簡單的基于的封裝格式轉換器(無編解碼)
視音頻分離器簡化版(-):最簡單的基于的封裝格式處理:視音頻分離器簡化版(-)
視音頻分離器():最簡單的基于的封裝格式處理:視音頻分離器()
視音頻復用器(muxer):最簡單的基于的封裝格式處理:視音頻復用器(muxer)
9.流媒體方面的應用使用進行流媒體方面的應用,主要是流媒體的發送和接收。
直接使用.exe命令行工具的文章:
發送流媒體的命令(UDP,RTP,RTMP)
編程方面做了一個例子:
基于的推流器:最簡單的基于的推流器(以推送RTMP為例)
10.的其他雜項使用讀寫內存(而非文件)的例子:
內存播放器:最簡單的基于的內存讀寫的例子:內存播放器
內存轉碼器:最簡單的基于的內存讀寫的例子:內存轉碼器
11. 在其它平臺下的應用
把應用于、IOS、 Phone的示例程序可以參考:
最簡單的基于的移動端例子:
最簡單的基于的移動端例子: 視頻解碼器
最簡單的基于的移動端例子: 視頻解碼器-單個庫版
最簡單的基于的移動端例子: 推流器
最簡單的基于的移動端例子: 視頻轉碼器
最簡單的基于的移動端例子附件: 自帶播放器
最簡單的基于的移動端例子附件:SDL
最簡單的基于的移動端例子:IOS
最簡單的基于的移動端例子:IOS 視頻解碼器
最簡單的基于的移動端例子:IOS 推流器
最簡單的基于的移動端例子:IOS 視頻轉碼器
最簡單的基于的移動端例子附件:IOS自帶播放器
最簡單的基于的移動端例子:
12. 相關工程的學習
學習完成,還可以了解一下基于的相關的多媒體開源工程,在這里推薦以下幾個:
12.1
是基于的解碼器類庫的 。廣泛安裝在PC上。
有關的源代碼分析文章(更新中):
源代碼分析1 : 整體結構
源代碼分析 2: 位圖覆蓋濾鏡(對話框部分)
源代碼分析 3: 位圖覆蓋濾鏡(設置部分)
源代碼分析 4: 位圖覆蓋濾鏡(濾鏡部分)
源代碼分析 5: 位圖覆蓋濾鏡(總結)
源代碼分析 6: 對解碼器的dll的封裝()
源代碼分析 7: 視頻解碼器類(c)
源代碼分析 8: 視頻解碼器類()
源代碼分析 9: 編解碼器有關類的總結
12.2 LAV
LAV 是基于的解碼器類庫,以及解封裝器類庫的 。廣泛安裝在PC上。
有關LAV 的源代碼分析文章:
LAV 源代碼分析 1: 總體結構
LAV 源代碼分析 2: LAV
LAV 源代碼分析 3: LAV Video (1)
LAV 源代碼分析 4: LAV Video (2)
12.3
是Linux下使用最廣泛的播放器,也有版本的。其中使用了。
有關的源代碼分析文章:
源代碼分析
12.4 Media - HC
現在廣為使用很多播放器都是構建于Media - HC的基礎之上的。
有關Media - HC的源代碼分析文章:
Media - HC 源代碼分析 1:整體結構
Media - HC 源代碼分析 2:核心類 ()(1)
Media - HC 源代碼分析 3:核心類 ()(2)
Media - HC 源代碼分析 4:核心類 ()(3)
Media - HC 源代碼分析 5:關于對話框 ()
Media - HC 源代碼分析 6:選項卡 ()
Media - HC 源代碼分析 7:詳細信息選項卡(s)
12.5 XBMC
XBMC是一個優秀的自由和開源的(GPL)媒體中心軟件。
有關XBMC源代碼分析文章:
XBMC源代碼分析 1:整體結構以及編譯方法
XBMC源代碼分析 2:(皮膚Skin)
XBMC源代碼分析 3:核心部分(core)-綜述
XBMC源代碼分析 4:視頻播放器()-解碼器(以為例)
XBMC源代碼簡析 5:視頻播放器()-解復用器(以為例)
XBMC源代碼分析 6:視頻播放器()-文件頭(以為例)
XBMC源代碼分析 7:視頻播放器()-輸入流(以為例)