最近在做流媒體開發這一塊,在伺服器端,所用的live555不支援mp4,avi等視頻容器格式,所以打算運用ffmpeg來進行擴充。將MP4檔案先運用ffmpeg進行解析,解析成live555所支援的基本視頻流格式(如H.264等)和音頻流格式,再運用live555中對基本音視頻流的處理方式處理後,發送到用戶端進行解碼播放,這其中運用到了ffmpeg庫,為了便於調試,開發環境初步選擇了在windows下進行,所以需要在windows下編譯ffmpeg。然後再擴充live555原始碼。所用的版本為ffmpeg0.8.5.本文主要介紹如何編譯ffmpeg,以及被vc6.0調用。
一,編譯環境的搭建:1,作業系統:windows xp sp32, VC6.03, MinGW+msys 到http://sourceforge.net/projects/mingw/files/去下載線上安裝包,這個檔案一般只有幾百K位元組,下完以後雙擊運行,按提示安裝,在需要選擇的時候把和C、C++、msys相關的都選上,繼續自動安裝,然後需要等待一些時間……MinGW+msys系統便已經安裝好了,我安裝的路徑是C:\MinGW,
msys的目錄是C:\MinGW\msys\1.04, ffmpeg 0.8.5(源碼可以在官網上找到)5,ffmpeg編譯裡面的彙編代碼需要yasm.exe,去yasm官網(http://yasm.tortall.net/Download.html)下一個windows合適的最新版本,弄好改名成yasm.exe放到C:\WINDOWS\system32下去(主要是省得加環境變數)或者放到C:\MinGW\msys\1.0\bin檔案夾下。最好nasm也弄一個,經常某些庫編譯用的上。不放也無所謂,就是產生的東西不支援彙編,所以速度會很受影響。
二、編譯過程
1、編輯C:\MinGW\msys\1.0\msys.bat檔案,在最前面加入一行
call "C:\Program Files\Microsoft Visual Studio \VC98\bin\vcvars32.bat"
後面路徑是機器上安裝的vc的對應路徑,加入這行編譯ffmpeg時會多出windows下調用dll對應的lib,方便vc調用。(網上看到的)
2、雙擊C:\MinGW\msys\1.0\msys.bat運行,進入ffmpeg源碼目錄D:\ffmpeg0.8.5,這個視窗的命令和shell相似,和cmd運行有些區別,右斜杠需要換成左斜杠,然後盤符D:也要改成/d,輸入cd /d/ffmpeg/ffmpeg0.8.5,進入ffmpeg主目錄。
3、開始編譯ffmpeg,繼續輸入:
"./configure --enable-shared --disable--static --enable-memalign-hack" 配置
4,等待一段時間後,輸入:make (忽略警告)
5,等待較長的時間後,輸入make install
此時編譯過程結束,需要的結果在C:\MinGW\msys\1.0\local目錄下,有對應的標頭檔(include中),dll以及lib等庫檔案(bin中),還有ffmpeg.exe等運行程式。
在自己編譯的時候,曾經先編譯了ffmpeg1.0,但因為版本的問題,在擴充的代碼中老是報記憶體不能為讀的錯誤,懷疑是ffmpeg版本的問題,所以想要降到0.8的試一下。但是在後來編譯0.8的時候不論哪種版本,配置configure完後,make的時候都找不到相應的檔案,無法make,這個問題困擾了自己很長時間,曾經一度想放棄,改在linux下操作。後來在網上找到點蛛絲馬跡。乾脆把MinGW卸載了,重新安裝的,然後配置,make就可以了。具體原因沒有深究。
補充說明:make指令後實際上在ffmpeg目錄裡已經有產生的dll和lib了,但是make install指令還是建議要執行
因為它會為你整理好需要的標頭檔(太體貼了,自己全拷覺得太多,自己選擇又太麻煩,而且不會正確),然後dll檔案大小會減小一些(自動檔案瘦身)。
最後用VC6.0調用產生的庫。在VC6.0的include路徑中加入在上文產生local中includ路徑。在link路徑中加入local中bin的路徑,然後在自己所建的工程link中加入產生的靜態庫avformat.lib avutil.lib avcodec.lib
這樣就可以調用ffmpeg庫了。
附:編譯時間遇到的一些問題:
1,Cannot open include file: 'inttypes.h': No such file or director解決辦法
1、找到include目錄中的ffmpeg\common.h
2、在“#define COMMON_H”之後加入如下代碼,同時刪除“#include <inttypes.h>” 然後儲存:
#if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
# define CONFIG_WIN32
#endif
#if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(EMULATE_INTTYPES)
# define EMULATE_INTTYPES
#endif
#ifndef EMULATE_INTTYPES
# include <inttypes.h>
#else
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
# ifdef CONFIG_WIN32
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
# else
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
# endif
#endif
2,error C3861: 'UINT64_C': identifier not found
找到include目錄中的ffmpeg\common.h
在函數頭部加入宏定義:
//自己所加的定義,處理UINT64_C未定義的錯誤
#ifndef INT64_C
#define INT64_C(c) (c ## L)
#define UINT64_C(c) (c ## UL)
#endif
3,處理相關宏定義格式錯誤,將括弧中的…改為n
#if AV_GCC_VERSION_AT_LEAST(4,3)
#define av_alloc_size(n) __attribute__((alloc_size(__VA_ARGS__)))
#else
#define av_alloc_size(n)
#endif
4,出現Cannot open include file: 'stdint.h': No such file or directory
在出現 #include <stdint.h>的地方注掉即可
5,處理template類錯誤的方法,在extern前檢查宏定義
#undef __cplusplus
extern "C" {
#include "libavutil/avutil.h"
#include "libavformat/avformat.h"
}
#define __cplusplus