FFmpeg:Compile
FFmpeg 컴파일 방법에 대한 설명.
GCC 빌드 옵션 확인 방법
configuration을 사용한 빌드를 사용할 경우 GCC 옵션이 별도로 출력되지 않는다. 옵션을 확인하고 싶을 경우 common.mak의 COMPILE함수를 아래와 같이 echo를 추가하면 된다.
define COMPILE
$(call $(1)DEP,$(1))
echo $($(1)) $($(1)FLAGS) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $<
$($(1)) $($(1)FLAGS) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $<
endef
FFmpeg관련 라이브러리를 사용할 경우 가급적 pkg-config를 사용하도록 하자.
참고로 더 정확한 방법은 아래와 같다.
$(foreach VAR,$(BRIEF), \
$(eval override $(VAR) = @$$(call ECHO,$(VAR),$$(MSG)); $($(VAR))))
$(foreach VAR,$(SILENT),$(eval override $(VAR) = @$($(VAR))))
약 26번째 줄에 있는 위 구문에서 $$(call ECHO,$(VAR),$$(MSG)); $($(VAR))))앞에 있는 @를 제거하면 된다.
FFplay Options
ffplay의 컴파일 옵션은 아래와 같다.
echo @printf "CC\t%s\n" ffplay.o; gcc -I. -I./ -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U__STRICT_ANSI__
-D__USE_MINGW_ANSI_STDIO=1 -D__printf__=__gnu_printf__ -DPIC -DZLIB_CONST -std=c99 -fomit-frame-pointer -D_GNU_SOURCE=1
-Dmain=SDL_main -Id:/local/tcm-gcc481-x64/include/SDL -g -Wdeclaration-after-statement -Wall -Wdisabled-optimization
-Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -Wmissing-prototypes -Wno-pointer-to-int-cast
-Wstrict-prototypes -Wempty-body -Wno-parentheses -Wno-switch -Wno-format-zero-length -Wno-pointer-sign -O3 -fno-math-errno
-fno-signed-zeros -fno-tree-vectorize -Werror=format-security -Werror=implicit-function-declaration -Werror=missing-prototypes
-Werror=return-type -Werror=vla -Wformat -Wno-maybe-uninitialized -D_GNU_SOURCE=1 -Dmain=SDL_main
-Id:/local/tcm-gcc481-x64/include/SDL -MMD -MF ffplay.d -MT ffplay.o -c -o ffplay.o ffplay.c
그리고 Link시 출력되는 내용은 아래와 같다.
echo @printf "LD\t%s\n" ffplay_g.exe; gcc -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavresample -Llibavutil
-Llibpostproc -Llibswscale -Llibswresample -Wl,--nxcompat -Wl,--dynamicbase -Wl,--as-needed -Wl,--warn-common
-Wl,-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample
-o ffplay_g.exe cmdutils.o ffplay.o -lavdevice -lavfilter -lavformat -lavcodec -lswresample -lswscale -lavutil -lavicap32
-lgdi32 -lpsapi -lole32 -lstrmiids -luuid -lws2_32 -liconv
-Ld:/local/tcm-gcc481-x64/lib -lmingw32 -lSDLmain -lSDL -mwindows -lm -lz -lpsapi -ladvapi32 -lshell32
-Ld:/local/tcm-gcc481-x64/lib -lmingw32 -lSDLmain -lSDL -mwindows
FFserver Options
ffserver의 컴파일 옵션은 아래와 같다.
printf "CC\t%s\n" ffserver.o; gcc -I. -I./ -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -DZLIB_CONST -std=c99 -fomit-frame-pointer -pthread
-g -Wdeclaration-after-statement -Wall -Wdisabled-optimization -Wpointer-arith -Wredundant-decls
-Wwrite-strings -Wtype-limits -Wundef -Wmissing-prototypes -Wno-pointer-to-int-cast -Wstrict-prototypes
-Wempty-body -Wno-parentheses -Wno-switch -Wno-format-zero-length -Wno-pointer-sign -O3 -fno-math-errno
-fno-signed-zeros -fno-tree-vectorize -Werror=format-security -Werror=implicit-function-declaration
-Werror=missing-prototypes -Werror=return-type -Werror=vla -Wformat -Wno-maybe-uninitialized
-MMD -MF ffserver.d -MT ffserver.o -c -o ffserver.o ffserver.c
CC ffserver.o
printf "LD\t%s\n" ffserver_g; gcc -Llibavcodec -Llibavdevice -Llibavfilter -Llibavformat -Llibavresample
-Llibavutil -Llibpostproc -Llibswscale -Llibswresample -Wl,--as-needed -Wl,-z,noexecstack -Wl,--warn-common
-Wl,-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample
-o ffserver_g cmdutils.o ffserver_config.o ffserver.o
-lavdevice -lavfilter -lavformat -lavcodec -lswresample -lswscale -lavutil -lxcb -lxcb-shm -lxcb
-lxcb-xfixes -lxcb-render -lxcb-shape -lxcb -lxcb-shape -lxcb -lX11 -lm -lbz2 -lz -pthread -lrt
LD ffserver_g
printf "CP\t%s\n" ffserver; cp -p ffserver_g ffserver
CP ffserver
printf "STRIP\t%s\n" ffserver; strip ffserver
STRIP ffserver
CentOS install
$ yum -y install http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm
$ yum install ffmpeg
Ubuntu install
Windows build
FFMPEG 소스를 원도우에서 빌드하는 방법은 아래와 같다. SVN 을 통하여 ffmpeg소스를 다운 받는다 (이미 포팅된 소스임)
- SVN URL: http://ffmpeg-msvc.googlecode.com/svn/trunk
- vcproj 디렉터리 아래에 있는
*.sln파일을 사용하여Visual Studio 9.0에서 로드한다.
만약 libavformat.vcproj 프로젝트를 로드할 수 없습니다. 라고 에러나 나면 아래 사항을 추가로 적용하면 됨. C:\Program Files (x86)\M icrosoft Visual Studio 9.0\VC\VCProjectDefaults폴더에 yasm.rules 파일만 있으면된다.
-
yasm.rules파일 얻는방법:http://www.koders.com/noncode/fid7BD4B41310CC0BF225F0FEBC46B082B9B59EC6A3.aspx(링크가 깨졌다)
yasm.rules 샘플
<?xml version="1.0" encoding="utf-8"?>
<VisualStudioToolFile
Name="Yasm"
Version="8.00"
>
<Rules>
<CustomBuildRule
Name="YASM"
DisplayName="Yasm Assembler"
CommandLine="yasm -Xvc -f $(PlatformName) [AllOptions] [AdditionalOptions] [Inputs]"
Outputs="[$ObjectFileName]"
FileExtensions="*.asm"
ExecutionDescription="Assembling $(InputFileName)"
ShowOnlyRuleProperties="false"
>
<Properties>
<StringProperty
Name="Defines"
DisplayName="Definitions"
Category="Pre-Defined Symbols"
Description="Specify pre-defined symbols ('symbol' or 'symbol = value') "
Switch="-D [value]"
Delimited="true"
Inheritable="true"
/>
<StringProperty
Name="IncludePaths"
DisplayName="Include Paths"
Category="Configuration"
Description="Set the paths for any additional include files"
Switch="-i "[value]""
Delimited="true"
Inheritable="true"
/>
<StringProperty
Name="UnDefines"
DisplayName="Remove Definitions"
Category="Pre-Defined Symbols"
Description="Remove pre-defined symbols "
Switch="-u [value]"
Delimited="true"
Inheritable="true"
/>
<StringProperty
Name="ObjectFileName"
DisplayName="Object File Name"
Category="Output"
Description="Select the output file name"
Switch="-o "[value]""
DefaultValue=""$(IntDir)\$(InputName).obj""
/>
<StringProperty
Name="ListFileName"
DisplayName="List File Name"
Category="Output"
Description="Select an output listing by setting its file name"
Switch="-l "[value]""
/>
<StringProperty
Name="PreIncludeFile"
DisplayName="Pre Include File"
Category="Configuration"
Description="Select a pre-included file by setting its name"
Switch="-P "[value]""
/>
<BooleanProperty
Name="Debug"
DisplayName="Debug Information"
Category="Output"
Description="Generate debugging information"
Switch="-g cv8"
/>
<EnumProperty
Name="PreProc"
DisplayName="Pre-Processor"
Category="Configuration"
Description="Select the pre-processor ('nasm' or 'raw')"
>
<Values>
<EnumValue
Value="0"
Switch="-rnasm"
DisplayName="Nasm "
/>
<EnumValue
Value="1"
Switch="-rraw"
DisplayName="Raw"
/>
</Values>
</EnumProperty>
<EnumProperty
Name="Parser"
DisplayName="Parser"
Category="Configuration"
Description="Select the parser for Intel ('nasm') or AT&T ( 'gas') syntax"
>
<Values>
<EnumValue
Value="0"
Switch="-pnasm"
DisplayName="Nasm"
/>
<EnumValue
Value="1"
Switch="-pgas"
DisplayName="Gas"
/>
</Values>
</EnumProperty>
</Properties>
</CustomBuildRule>
</Rules>
</VisualStudioToolFile>
Debug mode
FFmpeg with OpenH264
pkg-config 설정 파일(openh264.pc)이 설치된 디렉토리를 PKG_CONFIG_PATH환경변수에 등록한 후 아래와 같이 진행하면 된다. <del>
./configure --extra-ldflags=-static-libgcc --enable-shared --enable-cross-compile --arch=x86 \
--cross-prefix=i686-w64-mingw32- --target-os=mingw32 --enable-runtime-cpudetect \
--enable-pic --disable-doc --enable-memalign-hack --disable-everything \
--enable-decoder='h264,mpeg4,mjpeg' --enable-libopenh264 --enable-encoder=libopenh264 \
--extra-cflags=-I빌드한 openh264/include --extra-ldflags=-L빌드한 openh264/lib \
--enable-filter=yadif --prefix=`pwd`/../ffmpeg_w32_dist
</del>
내용을 축약 하면 아래와 같다.
Troubleshooting
recompile with -fPIC
FFmpeg를 사용하는 다른 라이브러리(e.g. OpenCV)에서 아래와 같은 현상이 발생될 수 있다.
/usr/bin/ld: /usr/local/lib/libavcodec.a(avpacket.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/libavcodec.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
이 경우 configure단계에서 --extra-cflags="-fPIC" 옵션을 추가하여 다시 컴파일 해야한다.