Skip to content

FFmpeg:Compile

FFmpeg 컴파일 방법에 대한 설명.

GCC 빌드 옵션 확인 방법

configuration을 사용한 빌드를 사용할 경우 GCC 옵션이 별도로 출력되지 않는다. 옵션을 확인하고 싶을 경우 common.makCOMPILE함수를 아래와 같이 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

$ sudo apt-get install libavcodec-extra

Windows build

FFMPEG 소스를 원도우에서 빌드하는 방법은 아래와 같다. SVN 을 통하여 ffmpeg소스를 다운 받는다 (이미 포팅된 소스임)

만약 libavformat.vcproj 프로젝트를 로드할 수 없습니다. 라고 에러나 나면 아래 사항을 추가로 적용하면 됨. C:\Program Files (x86)\M icrosoft Visual Studio 9.0\VC\VCProjectDefaults폴더에 yasm.rules 파일만 있으면된다.

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 (&apos;symbol&apos; or &apos;symbol = value&apos;) "
                    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 &quot;[value]&quot;"
                    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 &quot;[value]&quot;"
                    DefaultValue="&quot;$(IntDir)\$(InputName).obj&quot;"
                />
                <StringProperty
                    Name="ListFileName"
                    DisplayName="List File Name"
                    Category="Output"
                    Description="Select an output listing by setting its file name"
                    Switch="-l &quot;[value]&quot;"
                />
                <StringProperty
                    Name="PreIncludeFile"
                    DisplayName="Pre Include File"
                    Category="Configuration"
                    Description="Select a pre-included file by setting its name"
                    Switch="-P &quot;[value]&quot;"
                />
                <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 (&apos;nasm&apos; or &apos;raw&apos;)"
                    >
                    <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 (&apos;nasm&apos;) or AT&amp;T ( &apos;gas&apos;) syntax"
                    >
                    <Values>
                        <EnumValue
                            Value="0"
                            Switch="-pnasm"
                            DisplayName="Nasm"
                        />
                        <EnumValue
                            Value="1"
                            Switch="-pgas"
                            DisplayName="Gas"
                        />
                    </Values>
                </EnumProperty>
            </Properties>
        </CustomBuildRule>
    </Rules>
</VisualStudioToolFile>

Debug mode

./configuration --disable-stripping --enable-debug=3 --extra-cflags=-g

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>

내용을 축약 하면 아래와 같다.

## --extra-cflags와 --extra-ldflags도 생략한다.
./configure --enable-libopenh264

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

See also

Favorite site

FFmpeg Compilation Guide