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"
옵션을 추가하여 다시 컴파일 해야한다.