在linux下聯合編譯ffmpeg和SDL源碼之二

        在上一章,我們用最簡單的tutorial01.c來編譯了ffmpeg源碼,並且可以用gdb追蹤,這一章,我們先形成一個簡單的Makefile, 以利用ffmpeg編好的本地庫,而不是安裝到系統的系統庫,這樣我們每次修改完ffmpeg的時候,只要make一下就可以了,不需要install。

        我們先看一下原來的編譯命令:


gcc -g -o tu ./src/tutorial01.c -lavutil -lavformat -lavcodec -lz -lavutil -lpthread -lswscale -lm -I../ffmpeg

       STEP 1. 我們先寫一個比較簡單的Makefile

.PHONY:all
all:tu

tu:obj/tutorial01.o
    gcc -Wall -I../ffmpeg tutorial01.o -o tu -lavutil -lavformat -lavcodec -lz -lavutil -lpthread -lswscale -lm

obj/tutorial01.o: src/tutorial01.c
    gcc -g -c src/tutorial01.c -o obj/tutorial01.o -I../ffmpeg/

       STEP 2. 把gcc, include頭文件的目錄,庫等編譯參數用參數來替換,添加僞目標clean, Makefile如下:

##libs
LIBS := -lavutil -lavformat -lavcodec -lz -lavutil -lpthread -lswscale -lm
#
##include
INCLUDE_PATH := -I../ffmpeg
#
#compile para
CC = gcc
CFLAGS = -Wall -g -c
LINK = gcc

.PHONY:all
all:tu 

tu:obj/tutorial01.o
    $(LINK) tutorial01.o -o tu $(INCLUDE_PATH) $(LIBS) 

obj/tutorial01.o: src/tutorial01.c
    $(CC) $(CFLAGS) -c src/tutorial01.c -o obj/tutorial01.o $(INCLUDE_PATH)

.PHONY:clean
clean:
    rm -rf obj/*.o
    rm tu

     

        STEP 3. 爲了能之後自動檢測src裏所有.c的文件,我們增加了自動尋找src裏.c的功能和自動通過匹配文件名生成對應的.o並放在obj目錄先,然後通過鏈接這些.o來生成最終可執行的文件。Makefile修改及註釋如下:

#find all .c file in src
SRC_DIR := src 
SRC_FILE_TYPE = c
FIND_SRC_FILES = $(shell find $(SRC_DIR) -name "*.$(SRC_FILE_TYPE)")
SRC_FILES = $(notdir $(FIND_SRC_FILES) )       //選找所有src/*.c文件

#obj
OBJ_FILES = $(SRC_FILES:.$(SRC_FILE_TYPE)=.o)            //這裏爲 tutorial01.o
OBJ_DIR := obj 
OBJS = $(addprefix $(OBJ_DIR)/,$(OBJ_FILES))             //這裏爲obj/tutorial01.o

##libs
SYS_LIBS := -lavformat -lavcodec -lavutil -lz -lpthread -lswscale -lm 

#include
INCLUDE_PATH := -I../ffmpeg

#compile para
CC = gcc 
CFLAGS = -Wall -g -c
LINK = gcc 
LINK_FLAGS = -g -o

target = tu

.PHONY:all
all:tu 

$(target):$(OBJS)                      //link所有的obj
    $(LINK) $(LINK_FLAGS) $@ $(OBJS)  $(SYS_LIBS) $(INCLUDE_PATH) 

#compile source files into object files
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.$(SRC_FILE_TYPE)       //根據.c的名字自動生成.o文件
    $(CC) $(CFLAGS) $(INCLUDE_PATH) -c $< -o $@

.PHONY:clean
clean:
    rm -rf obj/*.o
    rm tu

.PHONY:debug                                           //調試用
debug:
    @echo OBJ_FILES:$(OBJ_FILES)
    @echo OBJS:$(OBJS)

        上面的debug,是在寫Makefile的過程中用於調試一些變量的,例如這裏 make debug 就可以打印出OBJS的變量是不是我們需要的。

        STEP 4. 因爲我們後續有可能會修改ffmpeg和SDL的源碼,例如添加一些打印信息等,這樣我們如果用的是ffmpeg編出來的本地庫,那麼重編ffmpeg的時候就不用make install了,只要make就可以了,這樣也可以不會影響到我們原來系統中的ffmpeg。所以,我們把ffmpeg相關的系統庫(avformat, avcodec, avutil等)都改爲本地庫,修改Makefile相關的部分如下:

##libs
LIB_DIR := ../ffmpeg
LOCAL_LIBS :=   -L$(LIB_DIR)/libavformat -lavformat \
                -L$(LIB_DIR)/libavcodec -lavcodec \
                -L$(LIB_DIR)/libavutil -lavutil \
                -L$(LIB_DIR)/libswscale -lswscale
SYS_LIBS := -lz -lpthread -lm
#
##include
INCLUDE_PATH := -I../ffmpeg
#
#compile para
CC = gcc 
CFLAGS = -Wall -g -c
LINK = gcc 
LINK_FLAGS = -g -o

target = tu

.PHONY:all
all:tu 

$(target):$(OBJS)
    $(LINK) $(LINK_FLAGS) $@ $(OBJS)  $(LOCAL_LIBS) $(SYS_LIBS) $(INCLUDE_PATH) 
           我們試着把系統裏的庫(/usr/local/lib/libav*.a)換個位置, 編譯通過,把ffmpeg下對應的.a換個地方,編譯不通過,證明用的是ffmpeg下的lib.

        STEP 5. 我們用gdb進行調試,如下:

$ gdb --args ./tu test_stream/ShaoNvShiDai_720P.avi 
GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/liaowm/workspace/iPlayer/jni/simulation/tu...done.
(gdb) b main
Breakpoint 1 at 0x433d76: file src/tutorial01.c, line 77.
(gdb) r
Starting program: /home/liaowm/workspace/iPlayer/jni/simulation/tu test_stream/ShaoNvShiDai_720P.avi
[Thread debugging using libthread_db enabled]

Breakpoint 1, main (argc=2, argv=0x7fffffffe438) at src/tutorial01.c:77
77	  AVFormatContext *pFormatCtx = NULL;
(gdb) n
88	  if(argc < 2) {
(gdb) 
93	  av_register_all();
(gdb) 
97	  if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0)
(gdb) s
avformat_open_input (ps=0x7fffffffe310, filename=0x7fffffffe75f "test_stream/ShaoNvShiDai_720P.avi", fmt=0x0, options=0x0) at libavformat/utils.c:588
588	{
(gdb) n
589	    AVFormatContext *s = *ps;
(gdb) 
        可以得知可以進入avformat_open_input等ffmpeg的內部函數進行調試,目前的需求完成。到此,我們完成了ffmpeg的Makefile,爲我們添加SDL的庫提供了方便。下面,我們下載tutorial02.c,來進行ffmpeg和SDL的源碼聯合編譯。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章