ffmpeg学习---1.用android-ndk-r7编译ffmpeg-0.10
2016-09-01 14:01
603 查看
android-ndk-r7 编译 ffmpeg-0.10
看了这篇文章 http://blog.sina.com.cn/s/blog_69a04cf40100x1fr.html ,自己动手做的时候遇到了一些问题,记录一下。
1. 下载 android-ndk-r7-linux-x86.tar.bz2
解压到/works/sdk/ 目录
~/.bashrc中设定环境变量:
export PATH=$PATH:/works/sdk/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin
export PATH=$PATH:/works/sdk/android-sdk-linux/tools
2. 下载 ffmpeg-0.10.tar.gz
2.1 解压后 修改源文件
修改文件libavdevice/v4l.c,在
#include 之上增加2行:
typedef __signed__ long long __s64;
typedef unsigned long long __u64;
2.2 在源文件目录建立 build_android.sh
2.3 将 ffmpeg-0.10 改名为 jni, 并在改名后的jni目录建立 Android.mk
ndk-build V=1
这时候会出错:arm-linux-androideabi-g++: /works/cong/obj/local/armeabi/ffmpeg: No such file or directory
将Android.mk 中 LOCAL_MODULE := ffmpeg 改为LOCAL_MODULE := ffmpeg_234
再次编译出现一大堆连接错误,Android.mk实在不熟悉只能手动执行: 在打印出来的 arm-linux-androideabi-g++ 的选项中加入 -L../libs/ -lffmpeg.
ok,编译通过
build_andriod.sh
#!/bin/bash
######################################################
# FFmpeg builds script for Android+ARM platform
#
# This script is released under term of
# CDDL (http://www.opensource.org/licenses/cddl1)
# Wrote by pinxue (~@gmail.com) from
RockPlayer.com
# 2010-8 ~ 2011-4
######################################################
######################################################
# Usage:
# put this script in top of FFmpeg source tree
# ./build_android
#
# It generates binary for following architectures:
# ARMv6
# ARMv6+VFP
# ARMv7+VFPv3-d16 (Tegra2)
# ARMv7+Neon (Cortex-A8)
#
# Customizing:
# 1. Feel free to change ./configure
parameters for more features
# 2. To adapt other ARM variants
# set $CPU and $OPTIMIZE_CFLAGS
# call build_one
######################################################
#NDK=/work/sdk/android-ndk-r7
NDK=/works/sdk/android-ndk-r7
PLATFORM=$NDK/platforms/android-8/arch-arm/
#PREBUILT=../../prebuilt/linux-x86/toolchain/arm-eabi-4.4.3
PREBUILT=/works/sdk/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86
function build_one
{
# -fasm : required. Android header file uses asm keyword instead of __asm__ , but
most of c dialect (like ansi,c99,gnu99) implies -fno-asm.
# ~/android/android-ndk-r4/build/platforms/android-5/arch-arm//usr/include/asm/byteorder.h: In function '___arch__swab32':
# ~/android/android-ndk-r4/build/platforms/android-5/arch-arm//usr/include/asm/byteorder.h:25: error: expected ')' before ':' token
# -fno-short-enums : optimized. Else FFmpeg
obj will generate a huge number of warning for variable-size enums,
# though we may suppress them by --no-enum-size-warning, it
would be better to avoid it.
# .../ld: warning: cmdutils.o
uses variable-size enums yet the output is to use 32-bit
enums; use of enum values across objects may fail
# --extra-libs="-lgcc" : required. Else cannot
solve some runtime function symbols
# ... undefined reference to `__aeabi_f2uiz'
# --enable-protocols : required. Without
this option, the file open always fails mysteriously.
# FFmpeg's av_open_input_file will invoke file format probing functions, but because most of useful demuxers has flag of zero
# which cause them are ignored during file format probling and fall to url stream parsing,
# if protocols are disabled, the file:// url
cannot be opened as well.
# $PREBUILT/bin/arm-eabi-ar
d libavcodec/libavcodec.a inverse.o : required.
# FFmpeg includes two copies of inverse.c both in libavutil and libavcodec for performance
consideration (not sure the benifit yet)
# Without this step, final ld of generating libffmpeg.so will fail silently, if invoke
ld through gcc, gcc will collect more reasonable error message.
# -llog: debug only, FFmpeg itself doesn't
require it at all.
# With this option, we may simply includes "utils/Log.h" and use
LOGx() to observe FFmpeg's
behavior
# PS, it seems the toolchain implies -DNDEBUG somewhere, it would be safer to use
following syntax
# #ifdef NDEBUG
# #undef NDEBUG
# #define HAVE_NDEBUG
# #endif
# #include "utils/Log.h"
# #ifdef HAVE_NDEBUG
# #define NDEBUG
# #undef HAVE_NDEBUG
# #endif
# --whole-archive : required. Else ld
generate a small .so file (about 15k)
# --no-stdlib : required. Android
doesn't use standard c runtime but invited its own wheal (bionic libc) because
of license consideration.
# space before \ of configure lines: required for some
options. Else next line will be merged into previous lines's
content and cause problem.
# Especially the --extra-cflags, the next line
will pass to gcc in this case and configure
will say gcc cannot create executable.
# many options mentioned by articles over internet are implied by -O2 or -O3
already, need not repeat at all.
# two or three common optimization cflags are omitted because not sure about the trade off yet. invoke
NDK build system with V=1 to find them.
# -Wl,-T,$PREBUILT/arm-eabi/lib/ldscripts/armelf.x
mentioned by almost every articles over internet, but it is not required to specify
at all.
# -Dipv6mr_interface=ipv6mr_ifindex : required. Android
inet header doesn't use ipv6mr_interface which is required by rfc, seems
it generate this user space header file directly from kernel header file, but Linux kernel has decided to keep
its own name for ever and ask user space header to use
rfc name.
# HAVE_SYS_UIO_H : required. Else:
# In file included from ~/android/android-ndk-r4/build/platforms/android-5/arch-arm//usr/include/linux/socket.h:29,
# from ~/android/android-ndk-r4/build/platforms/android-5/arch-arm//usr/include/sys/socket.h:33,
# from libavformat/network.h:35,
# from libavformat/utils.c:46:
#~/android/android-ndk-r4/build/platforms/android-5/arch-arm//usr/include/linux/uio.h:19: error: redefinition
of 'struct iovec'
#
# --disable-doc : required
because of strange bug of toolchain.
./configure --target-os=linux \
--prefix=$PREFIX \
--enable-cross-compile \
--extra-libs="-lgcc" \
--arch=arm \
--cc=$PREBUILT/bin/arm-linux-androideabi-gcc \
--cross-prefix=$PREBUILT/bin/arm-linux-androideabi-\
--nm=$PREBUILT/bin/arm-linux-androideabi-nm \
--sysroot=$PLATFORM \
--extra-cflags="
-O3 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 -Dipv6mr_interface=ipv6mr_ifindex -fasm -Wno-psabi -fno-short-enums -fno-strict-aliasing -finline-limit=300 $OPTIMIZE_CFLAGS " \
--disable-shared \
--enable-static \
--extra-ldflags="-Wl,-rpath-link=$PLATFORM/usr/lib
-L$PLATFORM/usr/lib -nostdlib -lc -lm -ldl -llog" \
--enable-parsers \
--enable-encoders \
--enable-decoders \
--enable-muxers \
--enable-demuxers \
--enable-swscale \
--enable-swscale-alpha \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--enable-network \
--enable-indevs \
--disable-bsfs \
--enable-filters \
--enable-avfilter \
--enable-protocols \
--enable-asm \
$ADDITIONAL_CONFIGURE_FLAG
#make clean
make -j4 install
$PREBUILT/bin/arm-linux-androideabi-ar
d libavcodec/libavcodec.a inverse.o
$PREBUILT/bin/arm-linux-androideabi-ld -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -soname
libffmpeg.so -shared -nostdlib -z,noexecstack -Bsymbolic --whole-archive --no-undefined -o
$PREFIX/libffmpeg.so libavcodec/libavcodec.a
libavformat/libavformat.a libavutil/libavutil.a
libavfilter/libavfilter.a libswscale/libswscale.a
libavdevice/libavdevice.a libswresample/libswresample.a -lc -lm -lz -ldl -llog --warn-once --dynamic-linker=/system/bin/linker /works/sdk/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/lib/gcc/arm-linux-androideabi/4.4.3/libgcc.a
}
#$PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3/armv7-a/libgcc.a
#不需要编armv6
#arm v7vfpv3
CPU=armv7-a
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=$CPU "
PREFIX=./android/$CPU
ADDITIONAL_CONFIGURE_FLAG=
build_one
#arm v7vfp
CPU=armv7-a
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
PREFIX=./android/$CPU-vfp
ADDITIONAL_CONFIGURE_FLAG=
build_one
这个 /works/sdk/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/lib/gcc/arm-linux-androideabi/4.4.3/libgcc.a
用的是绝对路径,不太清这个 /works/sdk/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/ 路径下的两个
libgcc.a有什么区别,反正用上面的一个是可以编译成功,而用另一个编译不成功。
android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
#LOCAL_SRC_FILES:= cmdutils.cpp ffmpeg.cpp
LOCAL_SRC_FILES:= cmdutils.c ffmpeg.c
LOCAL_C_INCLUDES :=
LOCAL_SHARED_LIBRARIES := libffmpeg
#LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := ffmpeg_234
include $(BUILD_EXECUTABLE)
不改名为ffmpeg_234 而一直用 ffmpeg是不能编译通过的,不清楚为什么。
参考文章:http://blog.sina.com.cn/s/blog_69a04cf40100x1fr.html
看了这篇文章 http://blog.sina.com.cn/s/blog_69a04cf40100x1fr.html ,自己动手做的时候遇到了一些问题,记录一下。
1. 下载 android-ndk-r7-linux-x86.tar.bz2
解压到/works/sdk/ 目录
~/.bashrc中设定环境变量:
export PATH=$PATH:/works/sdk/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin
export PATH=$PATH:/works/sdk/android-sdk-linux/tools
2. 下载 ffmpeg-0.10.tar.gz
2.1 解压后 修改源文件
修改文件libavdevice/v4l.c,在
#include 之上增加2行:
typedef __signed__ long long __s64;
typedef unsigned long long __u64;
2.2 在源文件目录建立 build_android.sh
2.3 将 ffmpeg-0.10 改名为 jni, 并在改名后的jni目录建立 Android.mk
ndk-build V=1
这时候会出错:arm-linux-androideabi-g++: /works/cong/obj/local/armeabi/ffmpeg: No such file or directory
将Android.mk 中 LOCAL_MODULE := ffmpeg 改为LOCAL_MODULE := ffmpeg_234
再次编译出现一大堆连接错误,Android.mk实在不熟悉只能手动执行: 在打印出来的 arm-linux-androideabi-g++ 的选项中加入 -L../libs/ -lffmpeg.
ok,编译通过
build_andriod.sh
#!/bin/bash
######################################################
# FFmpeg builds script for Android+ARM platform
#
# This script is released under term of
# CDDL (http://www.opensource.org/licenses/cddl1)
# Wrote by pinxue (~@gmail.com) from
RockPlayer.com
# 2010-8 ~ 2011-4
######################################################
######################################################
# Usage:
# put this script in top of FFmpeg source tree
# ./build_android
#
# It generates binary for following architectures:
# ARMv6
# ARMv6+VFP
# ARMv7+VFPv3-d16 (Tegra2)
# ARMv7+Neon (Cortex-A8)
#
# Customizing:
# 1. Feel free to change ./configure
parameters for more features
# 2. To adapt other ARM variants
# set $CPU and $OPTIMIZE_CFLAGS
# call build_one
######################################################
#NDK=/work/sdk/android-ndk-r7
NDK=/works/sdk/android-ndk-r7
PLATFORM=$NDK/platforms/android-8/arch-arm/
#PREBUILT=../../prebuilt/linux-x86/toolchain/arm-eabi-4.4.3
PREBUILT=/works/sdk/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86
function build_one
{
# -fasm : required. Android header file uses asm keyword instead of __asm__ , but
most of c dialect (like ansi,c99,gnu99) implies -fno-asm.
# ~/android/android-ndk-r4/build/platforms/android-5/arch-arm//usr/include/asm/byteorder.h: In function '___arch__swab32':
# ~/android/android-ndk-r4/build/platforms/android-5/arch-arm//usr/include/asm/byteorder.h:25: error: expected ')' before ':' token
# -fno-short-enums : optimized. Else FFmpeg
obj will generate a huge number of warning for variable-size enums,
# though we may suppress them by --no-enum-size-warning, it
would be better to avoid it.
# .../ld: warning: cmdutils.o
uses variable-size enums yet the output is to use 32-bit
enums; use of enum values across objects may fail
# --extra-libs="-lgcc" : required. Else cannot
solve some runtime function symbols
# ... undefined reference to `__aeabi_f2uiz'
# --enable-protocols : required. Without
this option, the file open always fails mysteriously.
# FFmpeg's av_open_input_file will invoke file format probing functions, but because most of useful demuxers has flag of zero
# which cause them are ignored during file format probling and fall to url stream parsing,
# if protocols are disabled, the file:// url
cannot be opened as well.
# $PREBUILT/bin/arm-eabi-ar
d libavcodec/libavcodec.a inverse.o : required.
# FFmpeg includes two copies of inverse.c both in libavutil and libavcodec for performance
consideration (not sure the benifit yet)
# Without this step, final ld of generating libffmpeg.so will fail silently, if invoke
ld through gcc, gcc will collect more reasonable error message.
# -llog: debug only, FFmpeg itself doesn't
require it at all.
# With this option, we may simply includes "utils/Log.h" and use
LOGx() to observe FFmpeg's
behavior
# PS, it seems the toolchain implies -DNDEBUG somewhere, it would be safer to use
following syntax
# #ifdef NDEBUG
# #undef NDEBUG
# #define HAVE_NDEBUG
# #endif
# #include "utils/Log.h"
# #ifdef HAVE_NDEBUG
# #define NDEBUG
# #undef HAVE_NDEBUG
# #endif
# --whole-archive : required. Else ld
generate a small .so file (about 15k)
# --no-stdlib : required. Android
doesn't use standard c runtime but invited its own wheal (bionic libc) because
of license consideration.
# space before \ of configure lines: required for some
options. Else next line will be merged into previous lines's
content and cause problem.
# Especially the --extra-cflags, the next line
will pass to gcc in this case and configure
will say gcc cannot create executable.
# many options mentioned by articles over internet are implied by -O2 or -O3
already, need not repeat at all.
# two or three common optimization cflags are omitted because not sure about the trade off yet. invoke
NDK build system with V=1 to find them.
# -Wl,-T,$PREBUILT/arm-eabi/lib/ldscripts/armelf.x
mentioned by almost every articles over internet, but it is not required to specify
at all.
# -Dipv6mr_interface=ipv6mr_ifindex : required. Android
inet header doesn't use ipv6mr_interface which is required by rfc, seems
it generate this user space header file directly from kernel header file, but Linux kernel has decided to keep
its own name for ever and ask user space header to use
rfc name.
# HAVE_SYS_UIO_H : required. Else:
# In file included from ~/android/android-ndk-r4/build/platforms/android-5/arch-arm//usr/include/linux/socket.h:29,
# from ~/android/android-ndk-r4/build/platforms/android-5/arch-arm//usr/include/sys/socket.h:33,
# from libavformat/network.h:35,
# from libavformat/utils.c:46:
#~/android/android-ndk-r4/build/platforms/android-5/arch-arm//usr/include/linux/uio.h:19: error: redefinition
of 'struct iovec'
#
# --disable-doc : required
because of strange bug of toolchain.
./configure --target-os=linux \
--prefix=$PREFIX \
--enable-cross-compile \
--extra-libs="-lgcc" \
--arch=arm \
--cc=$PREBUILT/bin/arm-linux-androideabi-gcc \
--cross-prefix=$PREBUILT/bin/arm-linux-androideabi-\
--nm=$PREBUILT/bin/arm-linux-androideabi-nm \
--sysroot=$PLATFORM \
--extra-cflags="
-O3 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 -Dipv6mr_interface=ipv6mr_ifindex -fasm -Wno-psabi -fno-short-enums -fno-strict-aliasing -finline-limit=300 $OPTIMIZE_CFLAGS " \
--disable-shared \
--enable-static \
--extra-ldflags="-Wl,-rpath-link=$PLATFORM/usr/lib
-L$PLATFORM/usr/lib -nostdlib -lc -lm -ldl -llog" \
--enable-parsers \
--enable-encoders \
--enable-decoders \
--enable-muxers \
--enable-demuxers \
--enable-swscale \
--enable-swscale-alpha \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--enable-network \
--enable-indevs \
--disable-bsfs \
--enable-filters \
--enable-avfilter \
--enable-protocols \
--enable-asm \
$ADDITIONAL_CONFIGURE_FLAG
#make clean
make -j4 install
$PREBUILT/bin/arm-linux-androideabi-ar
d libavcodec/libavcodec.a inverse.o
$PREBUILT/bin/arm-linux-androideabi-ld -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -soname
libffmpeg.so -shared -nostdlib -z,noexecstack -Bsymbolic --whole-archive --no-undefined -o
$PREFIX/libffmpeg.so libavcodec/libavcodec.a
libavformat/libavformat.a libavutil/libavutil.a
libavfilter/libavfilter.a libswscale/libswscale.a
libavdevice/libavdevice.a libswresample/libswresample.a -lc -lm -lz -ldl -llog --warn-once --dynamic-linker=/system/bin/linker /works/sdk/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/lib/gcc/arm-linux-androideabi/4.4.3/libgcc.a
}
#$PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3/armv7-a/libgcc.a
#不需要编armv6
#arm v7vfpv3
CPU=armv7-a
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=$CPU "
PREFIX=./android/$CPU
ADDITIONAL_CONFIGURE_FLAG=
build_one
#arm v7vfp
CPU=armv7-a
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
PREFIX=./android/$CPU-vfp
ADDITIONAL_CONFIGURE_FLAG=
build_one
这个 /works/sdk/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/lib/gcc/arm-linux-androideabi/4.4.3/libgcc.a
用的是绝对路径,不太清这个 /works/sdk/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/ 路径下的两个
libgcc.a有什么区别,反正用上面的一个是可以编译成功,而用另一个编译不成功。
android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
#LOCAL_SRC_FILES:= cmdutils.cpp ffmpeg.cpp
LOCAL_SRC_FILES:= cmdutils.c ffmpeg.c
LOCAL_C_INCLUDES :=
LOCAL_SHARED_LIBRARIES := libffmpeg
#LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := ffmpeg_234
include $(BUILD_EXECUTABLE)
不改名为ffmpeg_234 而一直用 ffmpeg是不能编译通过的,不清楚为什么。
参考文章:http://blog.sina.com.cn/s/blog_69a04cf40100x1fr.html
相关文章推荐
- android-ndk-r7 编译 ffmpeg-0.10
- windows环境 cygwin android-ndk-r7 编译 ffmpeg
- android学习——NDK入门 windows下安装cygwin 与 Eclipse使用CDT 自动编译
- ffmpeg for android 独立ndk以及android项目下编译 --ubuntu
- buntu12.10 64位 + android-ndk-r9 编译ffmpeg遇到的问题
- 使用NDK交叉编译ffmpeg, android后台可执行。
- Ubuntu12.04 32位 + android-ndk-r9c 编译ffmpeg遇到的问题记录
- NDK学习三:[转载] android开发 NDK 编译和使用静态库、动态库 3ff0
- 在32位的Ubuntu 11.04中为Android NDK r6编译FFmpeg0.8.1版-Android中使用FFmpeg媒体库(一)
- Android-NDK-r9编译ffmpeg-0.11.3
- Ubuntu12.10 64位 + android-ndk-r9 编译ffmpeg遇到的问题
- Android-NDK-r9编译ffmpeg-0.11.3
- FFMPEG学习 之一: Windows XP、Cygwin、NDKr8b编译Android下的ffmpeg(转)
- android学习——NDK入门 windows下安装cygwin 与 Eclipse使用CDT 自动编译
- Android 音视频编解码系列(1)--ubuntu下ndk编译ffmpeg0.8.1
- android 用ndk编译ffmpeg
- Android本地视频播放器开发--NDK编译FFmpeg
- ubuntu 12.04 NDK + android 4.0.3_r1 编译libffmpeg.so
- buntu12.10 64位 + android-ndk-r9 编译ffmpeg遇到的问题
- 如何在android中利用NDK编译引入ffmpeg--- Syntax error: word unexpected (expecting ")")