ffmpeg源码编译(最新版本4.1、android平台)

一、ffmpeg介绍:

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。
FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括Windows、Mac OS X等。这个项目最早由Fabrice Bellard发起,2004年至2015年间由Michael Niedermayer主要负责维护。许多FFmpeg的开发人员都来自MPlayer项目,而且当前FFmpeg也是放在MPlayer项目组的服务器上。项目的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward"。
多媒体视频处理工具FFmpeg有非常强大的功能包括视频采集功能、视频格式转换、视频抓图、给视频加水印等。
以上介绍摘自百度。

二、源码下载:

官网:https://ffmpeg.org/
github:https://github.com/FFmpeg/FFmpeg

三、环境配置:

这里主要指NDK配置,编译android平台需要NDK支持,步骤如下:

  1. vim ~/.bashrc
  2. 在文件最后面添加:
export NDKROOT=/home/ceshi/ceshi/android-ndk-r17cexport PATH=$NDKROOT:$PATH
  1. source ~/.bashrc

四、配置文件修改:

打开FFmpeg目录下的configure文件,找到下面几行:

SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'

替换为:

SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'

目的:修改生成的.so的文件名,可以能够让android项目识别

五、脚本编写:

新建一个脚本文件android_build.sh,添加如下内容:

  #!/bin/bash
  # 清空上次的编译
  make clean
  #你自己的NDK路径。
  export NDK = / home / ceshi / ceshi / android - ndk - r17c
  # 设置你的android平台编译器的版本 这里采用Android21
  export SYSROOT = $NDK / platforms / android - 21 / arch - arm /
  #编译使用的toolchain
  export TOOLCHAIN = $NDK / toolchains / arm - linux - androideabi - 4.9 / prebuilt / linux - x86_64
  export CPU = arm
  # 这个是输出的路径
  export PREFIX = $(pwd) / android / $CPU
  export ADDI_CFLAGS = "-marm"
  . / configure --target - os = linux \
  --prefix = $PREFIX --arch = arm \
  --disable - doc \
  --enable - shared \
  --disable - static \
  --disable - x86asm \
  --disable - symver \
  --enable - gpl \
  --disable - ffmpeg \
  --disable - ffplay \
  --disable - ffprobe \
  --disable - doc \
  --disable - symver \
  --cross - prefix = $TOOLCHAIN / bin / arm - linux - androideabi - \
  --enable - cross - compile \
  --sysroot = $SYSROOT \
  --extra - cflags = "-I$NDK/sysroot/usr/include/arm-linux-androideabi -Os -fpic $ADDI_CFLAGS -isysroot $NDK/sysroot" \
  --extra - ldflags = "$ADDI_LDFLAGS" \
  $ADDITIONAL_CONFIGURE_FLAG
  # make clean
  make
  make install

六、编译:

为上一步的脚本添加可执行权限,执行。

七、踩过的坑

error 1:

/home/cece/cece/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-nm: /lib64/libc.so.6: version `GLIBC_2.18’ not found (required by /home/cece/cece/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/…/bin/…/lib/bfd-plugins/…/lib64/libc++.so.1)
https://www.jianshu.com/p/feab970fd74c

扫描二维码关注公众号,回复: 9391087 查看本文章

解决方案:
不影响编译,不要轻易升级。升级可能会导致系统瘫痪,我升级了一次,果然系统挂了。。。
如需要升级,可参考:https://blog.csdn.net/qq_39295044/article/details/86685789

error 2:

_64/lib/gcc/arm-linux-androideabi/4.9.x/include/stdint.h:9:26: fatal error: stdint.h: No such file or directory

解决方案:
需在–extra-cflags中添加 “-isysroot $NDK/sysroot”
还有有关汇编的头文件也进行了分离.
需要根据目标平台进行指定“-I$NDK/sysroot/usr/include/arm-linux-androideabi”,将“arm-linux-androideabi” 改为需要的平台就可以

error 3:

 libavcodec / aaccoder.c : In function 'search_for_ms' :
  libavcodec / aaccoder.c : 803 : 25 : error : expected identifier or '(' before numeric constant
  int B0 = 0, B1 = 0;
      ^
  libavcodec / aaccoder.c:865 : 28 : error : lvalue required as left operand of assignment
  B0 += b1 + b2;
  ^
  libavcodec / aaccoder.c:866 : 25 : error : 'B1' undeclared(first use in this function)
  B1 += b3 + b4;
  ^

解决方案:
最新版本命名冲突,修改libavcodec/aaccoder.c 文件 B0改成b0。

error 4:

 libavcodec / hevc_mvs.c : In function 'derive_spatial_merge_candidates' :
  libavcodec / hevc_mvs.c : 208 : 15 : error : 'y0000000' undeclared(first use in this function)
  ((y ## v) >> s->ps.sps->log2_min_pu_size))
    ^

解决方案:
同上,修改变量名,避免冲突即可。

error 5:

 libavcodec / opus_pvq.c : In function 'quant_band_template' :
  libavcodec / opus_pvq.c : 498 : 9 : error : expected identifier or '(' before numeric constant
  int B0 = blocks;

解决方案:
同上,修改变量名,避免冲突即可。

八、补充

不同的NDK版本,编译时需要的错误不一样,我这里使用的是android - ndk - r17c,需要注意。

参考链接:
https://blog.csdn.net/qq_34902522/article/details/87879145
https://www.jianshu.com/p/feab970fd74c

发布了59 篇原创文章 · 获赞 22 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/Martin_chen2/article/details/97619950