<android编译ffmpeg+x264+faac> <Android/NDK环境下FFmpeg及AAC,MP3,X264的编译>


android编译ffmpeg+x264+faac

http://blog.csdn.net/vblittleboy/article/details/24316303

1. 在x264的源码目录下创建b1.sh,内容如下:

点击(此处)折叠或打开

  1. export NDK=/opt/google/android/android-ndk-r8e
  2. export VERSION=4.4.3
  3. export PREBUILT=$NDK/toolchains/arm-linux-androideabi-$VERSION/prebuilt
  4. export PLATFORM=$NDK/platforms/android-8/arch-arm
  5. ./configure --enable-static \
  6. --enable-shared \
  7. --enable-pic \
  8. --disable-asm \
  9. --disable-cli \
  10. --host=arm-linux \
  11. --cross-prefix=$PREBUILT/linux-x86_64/bin/arm-linux-androideabi- \
  12. --sysroot=$PLATFORM
2. 在ffmepg的父目录下创建b1.sh,内容如下:并创建目录elib,并 把上面生成的lib264.a 拷贝到该目录下

点击(此处)折叠或打开

  1. #!/bin/bash
  2. export VERSION=4.4.3
  3. export NDK=/opt/google/android/android-ndk-r8e
  4. export PREBUILT=$NDK/toolchains/arm-linux-androideabi-$VERSION/prebuilt/linux-x86_64
  5. export PLATFORM=$NDK/platforms/android-9/arch-arm
  6. export FFMPEG_ROOT=/home/test/code/ffmpeg-1.1.5 
  7. export X264_ROOT=/home/test/code/x264_and #上面的x264的源码目录
  8. export ELIB="$FFMPEG_ROOT/elib"
  9. function build_one
  10. {
  11. $FFMPEG_ROOT/configure --target-os=linux \
  12. --enable-cross-compile \
  13. --enable-runtime-cpudetect \
  14. --disable-asm \
  15. --arch=arm \
  16. --cc=$PREBUILT/bin/arm-linux-androideabi-gcc \
  17. --cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \
  18. --disable-stripping \
  19. --nm=$PREBUILT/bin/arm-linux-androideabi-nm \
  20. --sysroot=$PLATFORM \
  21. --enable-nonfree \
  22. --enable-version3 \
  23. --disable-everything \
  24. --enable-gpl \
  25. --disable-doc \
  26. --enable-avresample \
  27. --enable-demuxer=rtsp \
  28. --enable-muxer=rtsp \
  29. --disable-ffplay \
  30. --disable-ffserver \
  31. --enable-ffmpeg \
  32. --disable-ffprobe \
  33. --enable-libx264 \
  34. --enable-encoder=libx264 \
  35. --enable-decoder=h264 \
  36. --enable-protocol=rtp \
  37. --enable-hwaccels \
  38. --enable-zlib \
  39. --disable-devices \
  40. --disable-avdevice \
  41. --extra-cflags="-I$X264_ROOT -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=armv7-a" \
  42. --extra-ldflags="-L$ELIB"
  43. make -j4
  44. }
  45. build_one
  46. $PREBUILT/bin/arm-linux-androideabi-ar d libavcodec/libavcodec.a inverse.o
  47. $PREBUILT/bin/arm-linux-androideabi-ld -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -L$ELIB -soname libffmpeg.so -shared -nostdlib -z noexecstack -Bsymbolic --whole-archive --no-undefined -o libffmpeg.so libavcodec/libavcodec.a libavfilter/libavfilter.a libavresample/libavresample.a libavformat/libavformat.a libavutil/libavutil.a libswscale/libswscale.a -lc -lm -lz -ldl -llog -lx264 --warn-once --dynamic-linker=/system/bin/linker $PREBUILT/lib/gcc/arm-linux-androideabi/$VERSION/libgcc.a
到此为止so文件已经编译完毕:
下面编译jni的so文件;

点击(此处)折叠或打开

  1. LOCAL_PATH := $(call my-dir)

  2. include $(CLEAR_VARS)
  3. MY_PATH := /home/wanjm/code/binary #上面的so文件的目录
  4. LOCAL_MODULE := ffmpeg
  5. LOCAL_SRC_FILES := $(MY_PATH)/libffmpeg.so #仅支持一个文件;
  6. include $(PREBUILT_SHARED_LIBRARY)


  7. include $(CLEAR_VARS)
  8. LOCAL_MODULE := myffmp
  9. LOCAL_SRC_FILES := VideoEncoder.c #jni的c文件;
  10. LOCAL_C_INCLUDES := /home/wanjm/code/ffmpeg-1.2.4 
  11. LOCAL_LDLIBS := -llog -lm -lc -ldl -lz -lstdc++
  12. LOCAL_STATIC_LIBRARIES := libffmpeg #引用5处生成的so文件;
  13. include $(BUILD_SHARED_LIBRARY)
上面so方式弄出来的,还是两个文件,在实际的java中,要限价在libffmpeg.so,然后在加载myffmp; 反序后会报告少依赖包, 但是按照该顺序还是加载失败;

然后按照下面的写法,可以生成单个so文件,且可以调试;

点击(此处)折叠或打开

  1. LOCAL_PATH := $(call my-dir)
  2. MY_PATH :=/home/wanjm/code/binary/elib

  3. include $(CLEAR_VARS)
  4. #MY_PATH := /home/wanjm/code/binary
  5. #LOCAL_MODULE := ffmpeg
  6. #LOCAL_SRC_FILES := $(MY_PATH)/libffmpeg.so
  7. #include $(PREBUILT_SHARED_LIBRARY)

  8. include $(CLEAR_VARS)
  9. LOCAL_MODULE := avcodec
  10. LOCAL_SRC_FILES := $(MY_PATH)/libavcodec.a
  11. include $(PREBUILT_STATIC_LIBRARY)

  12. include $(CLEAR_VARS)
  13. LOCAL_MODULE := avformat
  14. LOCAL_SRC_FILES := $(MY_PATH)/libavformat.a
  15. include $(PREBUILT_STATIC_LIBRARY)

  16. include $(CLEAR_VARS)
  17. LOCAL_MODULE := avutil
  18. LOCAL_SRC_FILES := $(MY_PATH)/libavutil.a
  19. include $(PREBUILT_STATIC_LIBRARY)

  20. include $(CLEAR_VARS)
  21. LOCAL_MODULE := x264
  22. LOCAL_SRC_FILES := $(MY_PATH)/libx264.a
  23. include $(PREBUILT_STATIC_LIBRARY)

  24. include $(CLEAR_VARS)
  25. LOCAL_MODULE := swscale
  26. LOCAL_SRC_FILES := $(MY_PATH)/libswscale.a
  27. include $(PREBUILT_STATIC_LIBRARY)


  28. include $(CLEAR_VARS)
  29. LOCAL_MODULE := myffmp
  30. LOCAL_SRC_FILES := VideoEncoder.c
  31. LOCAL_C_INCLUDES := /home/wanjm/code/ffmpeg-1.2.4
  32. LOCAL_LDLIBS := -llog -lm -lc -ldl -lz -lstdc++
  33. LOCAL_STATIC_LIBRARIES := libavformat libavutil libavcodec libswscale libavutil libx264
  34. include $(BUILD_SHARED_LIBRARY)




makefile 脚本: 注意-lgcc 应该放在最后,否则找到__aeabi_idiv等方法;

点击(此处)折叠或打开

  1. VERSION=4.8
  2. NDK_ROOT=/opt/google/android-ndk-r9b
  3. TOOLCHAINS_ROOT=$(NDK_ROOT)/toolchains/arm-linux-androideabi-$(VERSION)/prebuilt/linux-x86_64
  4. TOOLCHAINS_PREFIX=$(TOOLCHAINS_ROOT)/bin/arm-linux-androideabi
  5. TOOLCHAINS_INCLUDE=$(TOOLCHAINS_ROOT)/lib/gcc/arm-linux-androideabi/$(VERSION)/include-fixed
  6. SYSROOT=$(NDK_ROOT)/platforms/android-9/arch-arm
  7. PLATFORM_INCLUDE=$(SYSROOT)/usr/include
  8. PLATFORM_LIB=$(SYSROOT)/usr/lib
  9. FLAGS= -fpic -DANDROID
  10. #如果没有-lc,实际运行时会找不到gettimeofday;
  11. LDFLAGS=-shared -L$(PLATFORM_LIB) --no-undefined -lc -llog -lm -lc -ldl -lz #-nostdlib -ldl -lm -Bdynamic -lc -lstdc++
  12. #FLAGS="-I$(TOOLCHAINS_INCLUDE) -I$(PLATFORM_INCLUDE) " #-L$(PLATFORM_LIB) -nostdlib -lgcc -Bdynamic -lc"
  13. CC=$(TOOLCHAINS_PREFIX)-gcc --sysroot=$(SYSROOT)
  14. LD=$(TOOLCHAINS_PREFIX)-ld
  15. libtime.so: main.o
  16. $(LD) $(LDFLAGS) main.o -o libtime.so -L/home/wanjm/code/binary/elib -lavformat -lavutil -lavcodec -lswscale -lavutil -lx264 -L$(TOOLCHAINS_ROOT)/lib/gcc/arm-linux-androideabi/$(VERSION) -lgcc
  17. cp libtime.so ../libs/armeabi
  18. main.o: VideoEncoder.c
  19. $(CC) -c VideoEncoder.c -o main.o -I/home/wanjm/code/ffmpeg-1.2.4
  20. clean:
  21. rm -rf libtime.so
  22. rm main.o

一步到位的ffmpeg+x264 for android 的编译;
1. 建立目录android,其下放置解压的ffmpeg和x264源码目录;建立install 目录,和make目录;
2. 在make中创建build.sh; 注意此处用的是相对目录,所以只能在make目录下运行;

点击(此处)折叠或打开

  1. #!/bin/bash
  2. export VERSION=4.6
  3. export NDK=/opt/google/android-ndk-r9b
  4. export PREBUILT=$NDK/toolchains/arm-linux-androideabi-$VERSION/prebuilt/linux-x86_64
  5. export PLATFORM=$NDK/platforms/android-9/arch-arm
  6. export FFMPEG_ROOT=../ffmpeg-1.2.4
  7. export X264_ROOT=../x264 #上面的x264的源码目录
  8. export PREFIX=../install
  9. export ELIB="$PREFIX/lib"
  10. export FAAC_ROOT=../faac-1.28
  11. function build_x264
  12. {
  13. cd $X264_ROOT
  14. pwd
  15. ./configure --enable-static \
  16. --prefix=$PREFIX \
  17. --enable-shared \
  18. --enable-pic \
  19. --disable-asm \
  20. --disable-cli \
  21. --host=arm-linux \
  22. --cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \
  23. --sysroot=$PLATFORM
  24. make
  25. cp libx264.a $ELIB
  26. cd -
  27. }
  28. function build_faac
  29. {
  30. cd $FAAC_ROOT
  31. pwd
  32. CFLAGS="-fpic -DANDROID -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -DANDROID -Wa,--noexecstack -MMD -MP "
  33. #FLAGS="--host=arm-androideabi-linux --enable-static --disable-shared --prefix=$HOME --enable-armv5e "
  34. CROSS_COMPILE=$PREBUILT/bin/arm-linux-androideabi-
  35. export CPPFLAGS="$CFLAGS"
  36. export CFLAGS="$CFLAGS"
  37. export CXXFLAGS="$CFLAGS"
  38. export CXX="${CROSS_COMPILE}g++ --sysroot=${PLATFORM}"
  39. export LDFLAGS="$LDFLAGS"
  40. export CC="${CROSS_COMPILE}gcc --sysroot=${PLATFORM}"
  41. export NM="${CROSS_COMPILE}nm"
  42. export STRIP="${CROSS_COMPILE}strip"
  43. export RANLIB="${CROSS_COMPILE}ranlib"
  44. export AR="${CROSS_COMPILE}ar"
  45. ./configure --program-prefix=$PREFIX \
  46. --host=arm-linux
  47. make
  48. cp ./libfaac/.libs/libfaac.a $ELIB
  49. cd -
  50. }
  51. function build_one
  52. {
  53. $FFMPEG_ROOT/configure --target-os=linux \
  54. --prefix=$PREFIX \
  55. --enable-cross-compile \
  56. --enable-runtime-cpudetect \
  57. --disable-asm \
  58. --arch=arm \
  59. --cc=$PREBUILT/bin/arm-linux-androideabi-gcc \
  60. --cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \
  61. --disable-stripping \
  62. --nm=$PREBUILT/bin/arm-linux-androideabi-nm \
  63. --sysroot=$PLATFORM \
  64. --enable-nonfree \
  65. --enable-version3 \
  66. --enable-gpl \
  67. --disable-doc \
  68. --enable-avresample \
  69. --enable-demuxer=rtsp \
  70. --enable-muxer=rtsp \
  71. --disable-ffplay \
  72. --disable-ffserver \
  73. --enable-ffmpeg \
  74. --disable-ffprobe \
  75. --enable-libx264 \
  76. --enable-libfaac --enable-nonfree \
  77. --enable-encoder=libx264 \
  78. --enable-decoder=h264 \
  79. --enable-protocol=rtp \
  80. --enable-encoder=libfaac \
  81. --enable-decoder=aac \
  82. --enable-hwaccels \
  83. --enable-zlib \
  84. --disable-devices \
  85. --disable-avdevice \
  86. --extra-cflags="-I$X264_ROOT -I$FAAC_ROOT/include -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=armv7-a" \
  87. --extra-ldflags="-L$ELIB"
  88. make -j4
  89. make install
  90. }
  91. mkdir -p $ELIB
  92. build_faac
  93. build_x264
  94. build_one













http://blog.csdn.net/iamshaofa/article/details/44116743

本篇介绍在Android/Ndk环境下FFmpeg的编译及使用, FFmpeg自带了H264、AAC、MP3的解码器,但却没有(或没有好的)相应的编码器。相应的编码器需要使用第三方库。推荐使用的第三方库为x264(H264编码) 、FDK_AAC(AAC编码),lame(MP3编码)。

在顺序上,应该先编译好第三方库,最后再编译FFmpeg库。

【本书说明:本文作者:邵发,本文选自《FFmpeg视音频编程指南》。有关本书的详细信息请访问官网:http://www.afanihao.cn 】

【权利声明:作者保留本文的全部权利。作者授权任何人都可以自由转载本文,但转载时必须遵守以下限制:①转载时必须全文转载,不得有任何修改,包括“权利声明”和“本书说明”部分 ② 仅限于网络转载,即最终结果公布于网络上。凡是不遵守以上两条的转载行为视为侵权行为。除非本人允许,任何人不得将本文内容用于任何的其他用途。】

1.1        NDK环境的准备

本篇的演示示例使用的是android-ndk-r8e版本,但理论上也适用于更新的NDK版本。为了让你的编译过程极其顺利,应该对NDK作以下改动:

进入目录 platforms/android-14/arch-arm/usr/lib

应该可以看到一些文件,例如 crtbegin_dynamic.o ,crtbegin_static.o  crtend_so.o , crtbegin_so.o ,crtend_android.o,等等。

 

把这个目录下的所有文件拷贝到

\toolchains\arm-linux-androideabi-4.6\prebuilt\linux-x86\lib\gcc\arm-linux-androideabi\4.6

 

否则在链接的时候ld会提示“找不到crtbegin_so.o和crtend_so.o”的错误。

 

应该把NDK的相关工具都把加PATH环境变量中,例如,

#!/bin/sh

export PATH=$PATH:/opt/ndk/android-ndk-r8e/

export PATH=$PATH: /opt/ndk/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/

 

1.2        FDK_AAC库的编译

如果你不打算使用AAC编码的功能,则可以略过本节。目前(2015年3月),fdk_aac的官方发布地址是在source_forge上,也许以后会变,作者可以自行搜索。目前地址为:

http://sourceforge.net/projects/opencore-amr/files/fdk-aac/

本文使用的版本是fdk-aac-0.1.3,为减少不必要的麻烦,读者也请下载这个包。

 

1.2.1         修改configure脚本

修改脚本的目的是去除目标库的版本号,以适应Android/NDK的对库的加载要求。简单地讲,这是因为在Android/NDK项目的java代码中,使用System.loadLibrary()函数来加载so文件时,动态库是不能加版本号的。

在fdk_aac的configure脚本里找到如下的行:

# This must be glibc/ELF.

linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)

  version_type=linux # correct to gnu/linux during the next big refactor

  need_lib_prefix=no

  need_version=no

  library_names_spec='${libname}${shared_ext}   ${libname}${shared_ext}   $libname${shared_ext}'

  soname_spec='${libname}${shared_ext}'

  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'

  shlibpath_var=LD_LIBRARY_PATH

  shlibpath_overrides_runpath=no

 

把粗体字部分替换为:

library_names_spec='$libname${shared_ext} $libname.a'

 

1.2.2         新建配置脚本

在源码的根目录下建议一个myconfig.sh脚本。这是一个SHELL脚本,要求读者自己稍微了解一些SHELL脚本的写法。在这里只强调一点:SHELL脚本是以\n结尾的,如果你是在windows下面编辑的,那么应该用dos2unix来把文本的换行符转成unix格式。

为了避免不必要的麻烦,把NDK解压缩在/opt/ndk/android-ndk-r8e目录,并将FDK的输出目录--prefix设置在/opt/ndk/openlib目录下。读者第一遍操作时,不要擅自修改目录,必须在熟练掌握之后再自行修改目录。

myconfig.sh里面内容为:

#!/bin/sh

 

export CC=arm-linux-androideabi-gcc

export CXX=arm-linux-androideabi-g++

export AR=arm-linux-androideabi-ar

export LD=arm-linux-androideabi-ld

export AS=arm-linux-androideabi-gcc

 

export CFLAGS=" --sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 "

export CXXFLAGS=" --sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 "

 

export LDFLAGS=" -L/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm/usr/lib  -march=armv7-a -Wl,--fix-cortex-a8 "

 

./configure --enable-static --prefix=/opt/ndk/openlib --host=arm-linux

 

1.2.3         编译

如果你严格按照以上的操作进行,那么编译过程会非常简单。Linux下的开源软件一般都是分为三步编译 configure , make,make install,而fdk_aac也不例外。

1)   ./myconfig.sh

执行上述配置脚本,开始配置

2)  make

3)  make  install

一切正常,将在/opt/ndk/openlib下存放输出库及头文件,注意这个库是去掉版本号的libfdk-aac。显然,Android/NDK的程序员会更喜欢不带版本号的库。

 

1.3        LAME-MP3的编译

如果你不打算在项目中使用mp3编码,则略过本节。

本节介绍lame的编译,但遗憾的是,其动态库没有办法去掉版本号。所以本方法生成的目标动态库是带版本号的。

1.3.1         新建配置脚本

新建配置文件myconfig.sh,内容如下,

#!/bin/sh

 

export CC=arm-linux-androideabi-gcc

export CXX=arm-linux-androideabi-g++

export AR=arm-linux-androideabi-ar

export LD=arm-linux-androideabi-ld

export CFLAGS=" --sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm "

export LDFLAGS=" -L/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm/usr/lib  "

./configure --enable-static --prefix=/opt/ndk/openlib --host=arm-linux

 

1.3.2         编译

1)   ./myconfig.sh

执行上述配置脚本,开始配置

2)  make

3)  make  install

一切正常,将在/opt/ndk/openlib下存放输出库及头文件。

 

1.4        x264的编译

x264属于VLC的一部分,当前的源码位置为:

ftp://ftp.videolan.org/pub/videolan/x264/snapshots/

本篇使用的源码版本为x264-snapshot-20140723-2245-stable.tar.bz2

1.4.1         修改configure脚本

这一步的目的是使输出的库文件不带版本号。如果你坚持认为版本号不影响你的开发,则忽略本小节。

找到这一位置:

    else

        echo "SOSUFFIX=so" >> config.mak

        echo "SONAME=libx264.so.$API" >> config.mak

        echo "SOFLAGS=-shared -Wl,-soname,\$(SONAME) $SOFLAGS" >> config.mak

    fi

 

将粗体字修改为:(即去掉$API后缀)

echo "SONAME=libx264.so" >> config.mak

 

1.4.2         新建配置脚本

新建myconfig.sh配置脚本,

#!/bin/sh

export CC=arm-linux-androideabi-gcc

export CXX=arm-linux-androideabi-g++

export AR=arm-linux-androideabi-ar

export LD=arm-linux-androideabi-ld

export AS=arm-linux-androideabi-gcc

export CFLAGS=" --sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"

export LDFLAGS=" -L/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm/usr/lib -march=armv7-a -Wl,--fix-cortex-a8 "

./configure --enable-static --enable-shared --prefix=/opt/ndk/openlib --host=arm-linux 

 

1.4.3         编译

1)   ./myconfig.sh

执行上述配置脚本,开始配置

2)  make

3)  make  install

 

1.5        FFmpeg的编译

本示例使用的是FFmpeg2.1.3版本,可以从其官网ffmpeg.org上下载。如果不需要x264/aac/lame,可以直接进行本节的编译。

1.5.1         修改configure脚本

本节的目的是让输出的库不含有版本号。

先找到configure的如下位置:

SHFLAGS='-shared -Wl,-soname,$$(@F)'

LIBPREF="lib"

LIBSUF=".a"

FULLNAME='$(NAME)$(BUILDSUF)'

LIBNAME='$(LIBPREF)$(FULLNAME)$(LIBSUF)'

SLIBPREF="lib"

SLIBSUF=".so"

SLIBNAME='$(SLIBPREF)$(FULLNAME)$(SLIBSUF)'

SLIBNAME_WITH_VERSION='$(SLIBNAME).$(LIBVERSION)'

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_VERSION='$(SLIBNAME)'

SLIBNAME_WITH_MAJOR='$(SLIBNAME)'

LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'

SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'

SLIB_INSTALL_LINKS=

 

1.5.2         修改配置脚本

新建myconfig.sh

export NDK_ROOT=/opt/ndk

export TMPDIR=/tmp

./configure  --prefix=$NDK_ROOT/ffmpeg --sysroot=$NDK_ROOT/android-ndk-r8e/platforms/android-14/arch-arm  --cross-prefix=arm-linux-androideabi-  --target-os=linux --arch=arm   --extra-cflags="-I$NDK_ROOT/openlib/include -fPIC  " --extra-ldflags=-L$NDK_ROOT/openlib/lib   --disable-programs --disable-doc --enable-shared --enable-cross-compile  --enable-gpl --enable-nonfree --enable-libx264 --enable-libmp3lame --enable-libfdk-aac

 

这个脚本中是把x264, fdk-aac, lame全部编译上了,你可以视自己的情况来修改。

1.5.3         编译

1)   ./myconfig.sh

执行上述配置脚本,开始配置

2)  make

3)  make  install

 

1.6        在Android.mk中引用FFmpeg库

1.6.1         使用静态库

推荐使用静态库。需要注意,FFmpeg库的静态库引用顺序是不能随便写的,为了避免不必要的麻烦,请照抄以下配置。

在你的Android.mk中添加以下几行(见黑体字部分)

LOCAL_LDLIBS    += -llog -lz

 

# ffmpeg

FFMPEG=/opt/ndk

LOCAL_CFLAGS += -I$(FFMPEG)/include

LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavformat.a

LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavcodec.a

LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavdevice.a

LOCAL_LDLIBS += -l$(FFMPEG)/lib/libswresample.a

LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavdevice.a

LOCAL_LDLIBS += -l$(FFMPEG)/lib/libswscale.a

LOCAL_LDLIBS += -l$(FFMPEG)/lib/libpostproc.a

LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavutil.a

 

# fdk_aac

LOCAL_LDLIBS += -l/opt/ndk/lib/libfdk-aac.a

LOCAL_LDLIBS += -l/opt/ndk/lib/libmp3lame.a

LOCAL_LDLIBS += -l/opt/ndk/lib/ libx264.a

 

include $(BUILD_SHARED_LIBRARY)

 

1.6.2         使用动态库

不推荐使用动态库,此过程过于复杂。要注意的有两点:①编译的时候,必须去除库的版本号 ② 在Java代码中加载的时候,要注意加载的顺序。

以下可以加在Android.mk中,但是仅供参考,遇到自己问题需要自己调试

# ffmpeg

FFMPEG=f:/Ndk/ffmpeg

LOCAL_CFLAGS += -I$(FFMPEG)/include

LOCAL_LDLIBS += -L$(FFMPEG)/lib

LOCAL_LDLIBS += -lavformat -lavcodec  -lswresample -lswscale  -lavutil -lavfilter

 

include $(BUILD_SHARED_LIBRARY)

 

1.6.3         在C++中使用ffmpeg

ffmpeg的库是按C编译的,里面的符号都是C格式,因此,若在C++中使用,还是要使用extern "C"这种技术。相关语法请参考《C/C++语法指南》(作者:邵发,官网http://www.afanihao.cn)。

为了大家的方便,在/opt/ndk/ffmpeg/include下新建一个ffmpeg.h,内容为:

#ifndef _FFMPEG_H

#define _FFMPEG_H

 

#ifdef __cplusplus

extern "C" {

 

#define INT64_C(val) val##LL

#define UINT64_C(val) val##ULL

 

#endif

 

#include <libavcodec/avcodec.h>

#include <libavformat/avformat.h>

#include <libswscale/swscale.h>

#include <libavutil/avutil.h>

#include <libavutil/opt.h>

#include <libavutil/imgutils.h>

#include <libswresample/swresample.h>

 

#include <libavutil/error.h>

#include <libavfilter/avfiltergraph.h>

#include <libavfilter/avcodec.h>

#include <libavfilter/buffersink.h>

#include <libavfilter/buffersrc.h>

 

#ifdef __cplusplus

}

#endif

 

#endif

 

然后在C++代码中直接#include "ffmpeg.h"就可以了。





















第一篇文章我添加rtmp静态库没有遇到问题;但是我用别的ffmpeg的sh文件从新编译就遇到了问题;
 后面的文章是讲解,根据github工程,ffmpeg工程的configure文件修改为:
我们可以根据自己的工程修改;
#enabled librtmp           && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
enabled librtmp           && require librtmp librtmp/rtmp.h RTMP_Socket -L${LIBRTMP_DIR}/android/${CPU}/lib -lrtmp

sh文件为:
ADDI_CFLAGS="${CPU_CFLAGS} -I${OPENSSL_DIR}/include -I${LIBRTMP_DIR}/android/${CPU}/include -L${LIBRTMP_DIR}/android/${CPU}/lib -lrtmp"
ADDI_LFLAGS="-L${OPENSSL_DIR}/libs/armeabi -L${LIBRTMP_DIR}/android/${CPU}/lib -lrtmp" 




所以在下面写出看到的解决方法:
http://blog.csdn.net/glcdw/article/details/7558303

在mingw下编译ffmpeg,并加上对rtmp的支持,即要先编译librtmp. 编译过程出了个librtmp not found问题,google了一圈,发现有很多类似的问题,但都和我的不完全一样。我的根本问题是mingw下的pkg-config没有正确安装。librtmp经过make和make install后,库文件和头文件都已经分别拷贝到/usr/local/lib和/usr/local/include目录下,ffmpeg在configure时找不到librtmp,为什么找不到呢?百思不得其解,无奈之下google,最终得到提示。

 

打开configure文件,发现下面一行

enabled librtmp    && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
原来ffmpeg通过pkg-config去找librtmp,难怪找不着了。

 

解决办法:

以#符号注释掉enabled librtmp一行

在configure时加上参数

./configure \

... ...

--extra-ldflags="-L/usr/local/lib" \

--extra-cflags="-I/usr/local/include" \

--extra-libs="-lrtmp" \

... ...







ERROR: librtmp not found
http://stackoverflow.com/questions/9634496/building-ffmpeg-with-librtmp-for-android

I'm trying to build all-in-one static binary of FFMPEG with NDK r7b and everything works fine untill i try to build it with RTMP support.

I'm usind sources from https://github.com/guardianproject/android-ffmpeg with librtmp2.4 and custom config like this

.configure \
--target-os=linux \
--cross-prefix=arm-linux-androideabi- \
--arch=arm \
--sysroot=/home/andrey/android-ndk-r7b/platforms/android-3/arch-arm \
--enable-static \
--disable-shared \
--disable-symver \
--enable-small \
--disable-devices \
--disable-avdevice \
--enable-gpl \
--enable-librtmp \
--prefix=../build/ffmpeg/armeabi \
--extra-cflags=-I../rtmpdump/librtmp \
--extra-ldflags=-L../rtmpdump/librtmp \

and rtmpdump directory lays on the same level as ffmpeg. As i understand last two strings in my config says where compiler may find sources of librtmp. But all i get is ERROR: librtmp not found

I'm not expereienced with NDK and obviosly i missing some important part but i can't find it by myself.

share improve this question
 

1 Answer

up vote 10 down vote accepted

This is challenging, but I think I have a solution. The problem at configure-time is that FFmpeg wants to detect a proper librtmp installation via the pkg-config management system.

I'm assuming your have successfully cross-compiled librtmp in the directory referenced by ../rtmpdump. Edit the FFmpeg configure script and search for the line:

enabled librtmp    && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket

Comment that out (put a '#' at the front of the line). Now, re-run configure, only with these modifications:

--extra-cflags="-I/full/path/to/rtmpdump"

It may help to have an absolute path here. Also, omit /librtmp/ at the end since the #include directives already prefix the header files with librtmp/. Next:

--extra-ldflags="-L/full/path/to/rtmpdump -lrtmp"

Again, absolute path, and specify the library to link against since we commented out that logic via configure.

Now, configure should succeed and the cross-compilation should also be happy. The final ffmpeg binary should report the family of RTMP modules under protocols:

ffmpeg -protocols
[...]
rtmp
rtmpe
rtmps
rtmpt
rtmpte

Note that I don't have an NDK dev environment to test this on. But I tested on my desktop Ubuntu system by compiling librtmp (without the package being installed via pkg-config) and then performing the above steps.





如何使用ndk为ffmpeg编译rtmp+polarssl静态库

如何使用ndk为ffmpeg编译rtmp+polarssl静态库?这个问题花了我整整一天时间。其中遇到很多小问题,这里记录一下,方便自己也方便其他人。

1、编译polarssl,查看其Readme文件即可,不需要configure,只需要make时带上必要的参数即可,不过要记得在每一次执行make命令时都带上CC的参数(指向你的arm gcc),因为我试过在make install时没有带上CC的参数,虽然能编译出polarssl但是未能正确被rtmp引用到。

2、因为前面我用的polarssl是当前最新(1.3.7)版本,而librtmp使用的好像是polarssl1.0.0以下版本的api,所以需要修改rtmp部分源码,让其调用新版polarssl的api,这里的修改可以参照《Migrating from PolarSSL-1.2 to the PolarSSL 1.3 branch》和《[rtmpdump] branch master updated. a312ac7 Fix compat with PolarSSL >= 1.1.0》。

3、出现 undefined reference to `havege_random’错误,这里是因为polarssl默认关闭了havege模块,需要你手动开启,主要就是修改include/polarssl/config.h,去掉POLARSSL_HAVEGE_C前的注释,也就是要定义POLARSSL_HAVEGE_C,如下:
#define POLARSSL_HAVEGE_C

4、在编译出上面两个库之后,可以开始编译ffmpeg(2.1.1版本)了,如果遇到下面的问题 check_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
ERROR: librtmp not found
这里有三种解决方法:
第一种,因为是网络上传播最多的,算是比较简便的方法,就是修改ffmpeg的configure,将以下一行:
enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
改为:
enabled librtmp && require librtmp librtmp/rtmp.h RTMP_Socket -lrtmp -lpolarssl -lz
或者直接注释掉&& *** 部分,然后再自己加上librtmp的库路径也行

第二种,(比较推荐,因为解决了这个会顺带解决大部分找不到库的错误!)因为这里使用了pkg-config工具查找库,而这个工具ndk并没有附带提供,而出现check_pkg_config相关错误的话,只要稍加注意,会发现在使用configure配置ffmpeg的交叉编译时,已经有相应的pkg-config不存在的警告了。我对这个工具不熟悉,所以我只是简单地加上了一个软链接到系统的pkg-config,如下:
ln -s /usr/bin/pkg-config /home/cidy0106/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-pkg-config
这个时候重新configure的话可能会出现找不到polarssl库的错误提示,需要修改一下librtmp安装目录里的librtmp.pc,把以下内容:
Libs: -L${libdir} -lrtmp -lz
改为:
Libs: -L${libdir} -lrtmp -lz -lpolarssl

至此,就可以正确编译出ffmpeg了 






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值