FFmpeg Makefile to CMakeLists.txt
2021年5月23日 · 1034 字 · 3 分钟
想了解学习下 FFmpeg 的源码,并希望可以自己编译调试。
- 阅读:源码,github 上也有公开的仓库
- 编译:FFmpeg Compilation Guide 介绍如何编译构建。
- 调试:Setup Eclipse IDE for FFmpeg (Linux)
官网介绍的开发环境中 IDE 是 Eclipse, 本人不熟悉。自己常用的是 CLion/CMake。但是 FFmpeg 是基于 Makefile 文件构建的, CLion 好像不支持,(已经支持了,我也是写这篇日志的时候才知道,详见官网说明,感觉还没开始就已经结束了,汗~)。
CLion 虽支持 Makefile,你只是调试 ffmpeg, ffplay, ffprobe 等自带的 application 应该没有多大问题。如果你想自己写一个新的 application,那你就得修改 configure 脚本或者 Makefile 文件了。
那我还是选择用 CMake
吧。
编译说明
- 编译环境:Docker 镜像,Ubuntu:18.04
- 编译目标:FFmpeg(含 Nasm、libx264)
- 参考文档:
编译脚本
#/bin/bash
#
# 下载,编译 nasm, libx264, libav*, ffmpeg
# 将 ffmpeg 目录下 Makefile “翻译” 成 CMakeLists.txt
# 使用 cmake, clang/clang++ 编译 ffmpeg
function mkdir_env () {
CUR_DIR=`pwd`
mkdir -p ffmpeg && cd ffmpeg && mkdir -p sources bin build
cd sources && SOURCES=`pwd`
cd ../bin && BIN=`pwd`
cd ../build && BUILD=`pwd`
echo $SOURCES $BIN $BUILD $CUR_DIR
# PATH="$BIN:$PATH"
}
function dl_dep () {
apt-get update -qq && apt-get -y install \
autoconf \
automake \
build-essential \
cmake \
git-core \
libass-dev \
libfreetype6-dev \
libgnutls28-dev \
libtool \
libvorbis-dev \
meson \
ninja-build \
pkg-config \
texinfo \
wget \
yasm \
zlib1g-dev
}
function build_nasm () {
cd $SOURCES && \
wget https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.bz2 && \
tar xjvf nasm-2.15.05.tar.bz2 && \
cd nasm-2.15.05 && \
./autogen.sh && \
PATH="$BIN:$PATH" ./configure --prefix="$BUILD" --bindir="$BIN" && \
make -j 8 && \
make install
}
function build_libx264 () {
cd $SOURCES && \
git -C x264 pull 2> /dev/null || git clone --depth 1 https://code.videolan.org/videolan/x264.git && \
cd x264 && \
PATH="$BIN:$PATH" PKG_CONFIG_PATH="$BUILD/lib/pkgconfig" ./configure --prefix="$BUILD" --bindir="$BIN" --enable-static --enable-pic && \
PATH="$BIN:$PATH" make -j8 && \
make install
}
function build_ffmpeg () {
cd $SOURCES && \
wget -O ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 && \
tar xjvf ffmpeg-snapshot.tar.bz2
cd $SOURCES/ffmpeg && \
PATH="$BIN:$PATH" PKG_CONFIG_PATH="$BUILD/lib/pkgconfig" ./configure \
--prefix="$BUILD" \
--pkg-config-flags="--static" \
--extra-cflags="-I$BUILD/include" \
--extra-ldflags="-L$BUILD/lib" \
--extra-libs="-lpthread -lm" \
--ld="g++" \
--bindir="$BIN" \
--disable-all \
--disable-autodetect \
--disable-w32threads \
--disable-os2threads \
--disable-alsa \
--disable-appkit \
--disable-avfoundation \
--disable-bzlib \
--disable-coreimage \
--disable-iconv \
--disable-libxcb \
--disable-libxcb-shm \
--disable-libxcb-xfixes \
--disable-libxcb-shape \
--disable-lzma \
--disable-sndio \
--disable-schannel \
--disable-sdl2 \
--disable-securetransport \
--disable-xlib \
--disable-zlib \
--disable-amf \
--disable-audiotoolbox \
--disable-cuda-llvm \
--disable-cuvid \
--disable-d3d11va \
--disable-dxva2 \
--disable-ffnvcodec \
--disable-nvdec \
--disable-nvenc \
--disable-v4l2-m2m \
--disable-vaapi \
--disable-vdpau \
--disable-videotoolbox \
--enable-ffmpeg \
--enable-small \
--enable-avcodec \
--enable-avformat \
--enable-avfilter \
--enable-swresample \
--enable-swscale \
--enable-decoder=h264 \
--enable-encoder=rawvideo,libx264 \
--enable-parser=h264 \
--enable-protocol=file \
--enable-demuxer=mov \
--enable-muxer=rawvideo,mp4 \
--enable-filter=scale \
--enable-nonfree \
--enable-gpl \
--enable-libx264
make --just-print > make.log && \
PATH="$BIN:$PATH" make -j 8 && \
make install
}
function test_ffmpeg () {
ls -lh $BIN
wget https://file-examples-com.github.io/uploads/2017/04/file_example_MP4_1280_10MG.mp4 -O $BIN/in.mp4
$BIN/ffmpeg -i $BIN/in.mp4 -vf scale=iw*.5:ih*.5 -vcodec h264 -acodec copy $BIN/out.mp4 -y
}
function get_cmakelists () {
cp $CUR_DIR/CMakeLists.txt $SOURCES/ffmpeg/
cd $SOURCES/ffmpeg
arr=(libavfilter libavformat libavcodec libswresample libswscale libavutil fftools)
for tag in "${arr[@]}"; do
echo "=======================================> $tag"
temp=`cat make.log | grep "printf \"CC\|printf \"X86" \
| grep -o "\-c \-o.*.c\|\" .*; nasm" \
| grep -o "\.o.*\|\" .*; nasm" \
| grep -o "\ .*" \
| grep -o ".*\.c\|.*\.o" \
| grep $tag \
| tr '\n' ' '`
echo $temp
sed -i "s|<$tag>|$temp|g" CMakeLists.txt
done
}
function build_c_ffmpeg () {
apt install -y clang # 用 clang 编译链接
mkdir -p $SOURCES/ffmpeg/build && cd $SOURCES/ffmpeg/build
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=/usr/bin/clang ..
make -j 8
}
function test_c_ffmpeg () {
$SOURCES/ffmpeg/build/ffmpeg -i $BIN/in.mp4 -vf scale=iw*.5:ih*.5 -vcodec h264 -acodec copy $SOURCES/ffmpeg/build/out.mp4 -y
}
mkdir_env
dl_dep
build_nasm
build_libx264
build_ffmpeg
test_ffmpeg
get_cmakelists
build_c_ffmpeg
test_c_ffmpeg
上述脚本中涉及的 CMakeLists.txt 内容如下
cmake_minimum_required(VERSION 3.10)
project(ffmpeg)
set(CMAKE_CXX_STANDARD 14)
add_definitions(-D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_POSIX_C_SOURCE=200112
-D_XOPEN_SOURCE=600 -DPIC -DHAVE_AV_CONFIG_H -DBUILDING_avfilter -DBUILDING_avformat)
set(CMAKE_C_FLAGS "-std=c11 -fomit-frame-pointer -fPIC -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 -Wno-unused-const-variable -Wno-char-subscripts \
-O0 -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 -fdiagnostics-color=auto")
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--fatal-warnings -fPIC \
-Wl,-z,noexecstack \
-Wl,-z,now \
-Wl,-z,relro \
-Wl,-z,defs \
-Wl, -rdynamic")
include_directories(
${CMAKE_SOURCE_DIR} # for ./config.h
${CMAKE_SOURCE_DIR}/../../build/include # for libx264
)
add_library(avfilter STATIC <libavfilter>)
add_library(avformat STATIC <libavformat>)
add_library(avcodec STATIC <libavcodec>)
add_library(swresample STATIC <libswresample>)
add_library(swscale STATIC <libswscale>)
add_library(avutil STATIC <libavutil>)
add_executable(ffmpeg <fftools>)
target_link_libraries(ffmpeg dl pthread dl m
${CMAKE_SOURCE_DIR}/../../build/lib/libx264.a
avfilter
avformat
avcodec
swresample
swscale
avutil
pthread m dl m m m pthread m)
编译步骤
# 启动 docker 容器, 进入 bash
docker run -it --name temp ubuntu:18.04 /bin/bash
# 从宿主机复制文件到容器
docker cp build.sh temp:/
docker cp CMakeLists.txt temp:/
# 容器中执行
bash build.sh