1. 程式人生 > >ffmpeg學習---8.ubuntu14.04原始碼編譯ffmpeg-2.1

ffmpeg學習---8.ubuntu14.04原始碼編譯ffmpeg-2.1

一. 編譯
1. 下載
http://www.ffmpeg.org/ 下載ffmpeg的原始碼,我這兒下載的是ffmpeg-2.1.7.tar.bz2
2. 簡單編譯
解壓後,進入ffmpeg的原始碼目錄
  1. [email protected]:/work/ffmpeg-2.1.7$ sudo apt-get install yasm    //這兒需要先安裝yasm,否則configure會報錯
  2. [email protected]:/work/ffmpeg-2.1.7$ mkdir install                //建立一個Install目錄,存放編譯好之後的東東
  3. [email protected]
    :/work/ffmpeg-2.1.7$ ./configure --prefix=./install //安裝到install目錄
  4. Creating config.mak, config.h, and doc/config.texi...     //這兒說明configure成功,可以編譯了
  5. [email protected]:/work/ffmpeg-2.1.7$ make -j16
3. 生成ffplay
   之所以預設編譯沒有生成ffplay的原因是系統中沒有安裝SDL, ffplay是依賴SDL顯示的
  1. [email protected]:/work/ffmpeg-2.1.7$ sudo apt-
    get install libsdl1.2-dev   
   安裝完SDL庫之後,重新按照步驟2編譯一遍就可以生成ffplay了
4.生成動態庫
按照上述2編譯出來的是靜態庫,要想生成動態庫,需要在configure時加入--enable-shared 
  1. [email protected]:/work/ffmpeg-2.1.7$ sudo apt-get install yasm    //這兒需要先安裝yasm,否則configure會報錯
  2. [email protected]:/work/ffmpeg-2.1.7$ mkdir install                //建立一個Install目錄,存放編譯好之後的東東
  3. [email protected]:/work/ffmpeg-2.1.7$ ./configure --enable-shared --prefix=./install //安裝到install目錄
  4. Creating config.mak, config.h, and doc/config.texi...     //這兒說明configure成功,可以編譯了
  5. [email protected]:/work/ffmpeg-2.1.7$ make -j16
4.1 如果出現如下錯誤
  1. /usr/bin/ld: libavcodec/mqc.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
  2. libavcodec/mqc.o: error adding symbols: Bad value
  3. collect2: error: ld returned 1 exit status
解決方法是:

  1. config.mak L75加入 -fPIC,然後重新編譯
  2. HOSTCFLAGS=-O3 --std=c99 -Wall -fPIC
4.2 編譯ffmpeg自帶的Demo
  1. a. 要想編譯example下的程式
  2. [email protected]:/work/ffmpeg/ffmpeg-2.7.2$ make examples           //編譯example
  3. [email protected]:/work/ffmpeg/ffmpeg-2.7.2$ make examplesclean      //清除example
  4. b. 要想編譯libavutils下的程式
  5. [email protected]:/work/ffmpeg/ffmpeg-2.7.2$ make testprogs          //不僅只有libavutils下的
  6. 清除的話,直接touch吧,這些檔案都是和ffmpeg共用的清了中間檔案還得重新編譯
4.2.1 在example中加入自己的程式
在ffmpeg-3.0.1中上述Demo己轉到doc目錄下
a. 在doc/Makefile 中新增 DOC_EXAMPLES-yes       += mytest
b. 在doc/examples/Makefile中新增   EXAMPLES     += mytest
c. 在doc/examples/mytest.c中新增 mytest.c檔案
d. 在ffmpeg的原始碼目錄下編譯 make examples即可
4.3 不編譯ffmpeg ffprobe ffserver
  1. configuration: --prefix=./install --disable-ffmpeg --disable-ffprobe --disable-ffserver
二.開發
1. 在ffmpeg庫中加入列印
在libavutil/avutil.h或者libavutil/log.h中加入
  1. 在./libavutil/log.h中
  2. #define dbmsg(fmt, args ...) printf("cong:%s:%s[%d]: "fmt"\n",__FILE__, __FUNCTION__, __LINE__,##args)
2. demo
fftest.c
  1. #include <stdio.h>
  2. #include <libavformat/avformat.h>
  3. #include <libswscale/swscale.h>
  4. #define dbmsgc(fmt, args ...) printf("cong:%s[%d]: "fmt"\n", __FUNCTION__, __LINE__,##args)
  5. //#define dbmsg(fmt, args ...) printf("cong:%s:%s[%d]: "fmt"\n",__FILE__, __FUNCTION__, __LINE__,##args)
  6. int main(int argc, char **argv)
  7. {
  8.     int i=0;
  9.     AVFormatContext *pFormatCtx = NULL;
  10.     avcodec_register_all();
  11. #if CONFIG_AVDEVICE
  12.     avdevice_register_all();
  13. #endif
  14.     avfilter_register_all();
  15.     av_register_all();
  16.     if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0)
  17.         return -1; // Couldn't open file
  18.     if(avformat_find_stream_info(pFormatCtx, NULL)<0)
  19.         return -1; // Couldn't find stream inform
  20.     av_dump_format(pFormatCtx,0, 0, 0);
  21.     return 0;
  22. }
Makefile
  1. FFMPEG=/work/ffmpeg-2.1.7/install
  2. CC=gcc
  3. CFLAGS=--I$(FFMPEG)/include
  4. LDFLAGS = -L$(FFMPEG)/lib/ -lswscale -lswresample -lavformat -lavdevice -lavcodec -lavutil -lavfilter -lm 
  5. TARGETS=fftest
  6. all: $(TARGETS)
  7. fftest:fftest.c
  8.     $(CC) $(CFLAGS) -o [email protected] $^ $(LDFLAGS)
  9. clean:
  10.     rm -rf $(TARGETS)
  11. run:
  12.     export LD_LIBRARY_PATH=/work//ffmpeg-2.1.7/install/lib/ \
  13.     && ./fftest ~/Downloads/testapk/nvren.dts
這樣用make run 就可以運行了

fftest.rar (下載後改名為fftest.tar.gz)
三.除錯
3.1 加入dump_stack函式
  1. ./libavutil/log.h
  2. #include <execinfo.h>
  3. void dump_stack(void);
  4. ./libavutil/log.c
  5. void dump_stack()
  6. {
  7.     int i;
  8.     int size = 64; 
  9.     void * array[64];
  10.     int stack_num = backtrace(array, size);
  11.     char ** stacktrace = backtrace_symbols(array, stack_num);
  12.     for (= 0; i < stack_num; ++i)
  13.     { 
  14.         printf("%s\n", stacktrace[i]);
  15.     } 
  16.     free(stacktrace);
  17. }
  18. 在./configure檔案中
  19. 將3071行 LD_LIB='-L'改為
  20. 3071 LD_LIB='-l% -rdynamic'
3.2 不strip
在libray.mak中
L32 -$(if $(ASMSTRIPFLAGS), $(STRIP) $(ASMSTRIPFLAGS) [email protected]) 注掉
附1.git管理
  1. [email protected]:/work/ffmpeg/ffmpeg-3.0.1$ vi .gitignore 
  2. [email protected]:/work/ffmpeg/ffmpeg-3.0.1$ cat .gitignore 
  3. *.o
  4. install
  5. .gitignore
  6. *.a
  7. *.d
  8. *.html
  9. *.3
  10. *.1
  11. *.pod
  12. *.texi
  13. *.pc
  14. .config
  15. .version
  16. config.asm
  17. config.fate
  18. config.h
  19. config.log
  20. config.mak
  21. doc/config.texi
  22. libavutil/avconfig.h
  23. libavutil/ffversion.h
  24. doc/fate.txt
  25. doc/print_options
  26. ffmpeg
  27. ffmpeg_g
  28. ffplay
  29. ffplay_g
  30. ffprobe
  31. ffprobe_g
  32. ffserver
  33. ffserver_g
  34. [email protected]:/work/ffmpeg/ffmpeg-3.0.1$ git init
  35. [email protected]:/work/ffmpeg/ffmpeg-3.0.1$ git add ./
  36. [email protected]:/work/ffmpeg/ffmpeg-3.0.1$ git commit -'ffmpeg3.0.1 project init
然後再configure   make