【问题标题】:Unable to port FFmpeg C library into android无法将 FFmpeg C 库移植到 android
【发布时间】:2012-12-13 12:39:35
【问题描述】:

我到底想要做什么:访问ffmpeg.c文件修改int main(int argc, char **argv) strong> 函数到 JNI 并将 ffmpeg 的命令作为字符串传递。

我尝试将 ffmpeg C 库移植到 android(ARM 处理器)。我遵循了以下不同的方法来做到这一点。

第一次尝试:使用官方 ffmpeg 安装文档。步骤如下

a) git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg

b) 读取安装文件。

c) 下载 x264 库并使用构建成功的 build_x264.sh 构建。

    NDK=/home/nav/Work/android/ndk
    PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt
    PLATFORM=$NDK/platforms/android-8/arch-arm
    PREFIX=/home/nav/28ffmpeg/android-ffmpeg                
    ./configure --prefix=$PREFIX --enable-static --enable-pic --disable-asm --disable-cli --host=arm-linux --cross-prefix=$PREBUILT/linux-x86/bin/arm-linux-androideabi- --sysroot=$PLATFORM
  make
  sudo make install
  sudo ldconfig

d) 然后我从 (http://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2) 下载 ffmpeg 库 使用 build_android.sh

构建它
#!/bin/bash

NDK=/home/nav/Work/android/ndk
PLATFORM=$NDK/platforms/android-8/arch-arm
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86
PREFIX=/home/nav/28ffmpeg/android-ffmpeg

function build_one
                {
                ./configure --target-os=linux --prefix=$PREFIX \
                --enable-cross-compile \
                --enable-runtime-cpudetect \
                --disable-asm \
                --arch=arm \
                --cc=$PREBUILT/bin/arm-linux-androideabi-gcc \
                --cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \
                --disable-stripping \
                --nm=$PREBUILT/bin/arm-linux-androideabi-nm \
                --sysroot=$PLATFORM \
                --enable-nonfree \
                --enable-version3 \
                --disable-everything \
                --enable-gpl \
                --disable-doc \
                --enable-avresample \
                --enable-demuxer=rtsp \
                --enable-muxer=rtsp \
                --disable-ffplay \
                --disable-ffserver \
                --enable-ffmpeg \
                --disable-ffprobe \
                --enable-libx264 \
                --enable-encoder=libx264 \
                --enable-decoder=h264 \
                --enable-protocol=rtp \
                --enable-hwaccels \
                --enable-zlib \
                --disable-devices \
                --disable-avdevice \
--extra-cflags="-I/home/android-ffmpeg/include -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=armv7-a" \
                --extra-ldflags="-L/home/android-ffmpeg/lib"
                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 -L$PREFIX/lib  -soname libffmpeg.so -shared -nostdlib  -z,noexecstack -Bsymbolic --whole-archive --no-undefined -o $PREFIX/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/4.4.3/libgcc.a
                }

                build_one

e) 最初它运行良好。但在那之后错误来了:

libavformat/libavformat.a(log2_tab.o):(.rodata+0x0): multiple definition of `ff_log2_tab'
libavcodec/libavcodec.a(log2_tab.o):(.rodata+0x0): first defined here
libavutil/libavutil.a(log2_tab.o):(.rodata+0x0): multiple definition of `ff_log2_tab'
libavcodec/libavcodec.a(log2_tab.o):(.rodata+0x0): first defined here
build_android.sh: 48: build_one: not found

结果: libffmpeg.so 未找到。

第二次尝试:然后我按照http://dl.dropbox.com/u/22605641/ffmpeg_android/main.html-> Builds 中的步骤操作

a) 我从上面的链接下载了 Pre-Build libffmpeg.so

b) 将 libffmpeg.so 添加到 libs/armeabi/ 中。

c) 制作 Android.mk

include $(CLEAR_VARS)
LOCAL_MODULE := ffmpeg
LOCAL_SRC_FILES := libffmpeg.so
include $(PREBUILT_SHARED_LIBRARY)

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := main
LOCAL_STATIC_LIBRARIES += ffmpeg
LOCAL_SRC_FILES := ffmpeg-test.c
include $(BUILD_SHARED_LIBRARY)

d) 然后我进行所有 ndk 设置和 all.Copy ffmpeg.c 从库到 ffmpeg-test.c 通过更改其 int main 函数添加到我的 JNI 函数中,并包含所有必要的包含文件。

错误:

控制台:

  /home/nav/Work/android/ndk/ndk-build all 
Prebuilt       : libffmpeg.so <= jni/
Install        : libffmpeg.so => libs/armeabi/libffmpeg.so
Compile thumb  : main <= ffmpeg-test.c
jni/ffmpeg-test.c: In function 'print_report':
jni/ffmpeg-test.c:1139:94: warning: incompatible implicit declaration of built-in function 'log2' [enabled by default]
SharedLibrary  : libmain.so
/home/nav/Work/android/ndk/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/main/ffmpeg-test.o: in function check_keyboard_interaction:jni/ffmpeg-test.c:2496: error: undefined reference to 'qp_hist'

以及许多其他未定义的引用。

【问题讨论】:

  • 我认为这是最难的事情:为了让 FFMPEG 工作,我结合了几个教程并使用了 Android NDK v6,因为每个更高的 NDK 版本都会给我带来不同的错误。我可以给你一个广告,我希望它能节省你一些时间:当你尝试从命令行运行 FFMPEG 工具的main 方法时,在不同的进程中进行,导致当它完成工作或任何错误发生时代码将执行exit(0) 并杀死你的整个进程,包括你的Android app.GL!
  • undefined reference 通过将 LOCAL_ALLOW_UNDEFINED_SYMBOLS := true 这一行添加到 Android.mk 解决了问题....但是现在出现错误:无法加载“libmain.so”所需的库“libffmpeg.so”。意味着 libmain.so 无法找到 libffmpeg.so 预建库.....但两者都在 形成库/armeabi/ ......
  • 我无法访问 .so 文件中的函数,因为我收到 undefined reference 错误 ....plz 帮助
  • @Evos 你在windows for android 上成功编译了ffmpeg 吗?查看链接,如果你知道任何帖子,我会给你投票..stackoverflow.com/questions/17141348/…

标签: android android-ndk ffmpeg


【解决方案1】:

要解决多定义问题,您需要删除重复的 *.o,以免发生冲突。我能够使用以下命令实现相同的目的。

rm /libavcodec/log2_tab.o

rm /ffmpeg-3.0.1/libavcodec/reverse.o

【讨论】:

    【解决方案2】:

    要修复多个定义,请添加:

    $PREBUILT/bin/arm-linux-androideabi-ar -dv libavcodec.a log2_tab.o
    $PREBUILT/bin/arm-linux-androideabi-ar -dv libavutil.a log2_tab.o
    

    但您可能还想添加此配置选项:

    --disable-symver
    

    通过这种方式,我设法使用 ndk v8 编译了 ffmpeg 的 HEAD 版本,但使用了包含更少功能的 LGPL 许可证。

    【讨论】:

    【解决方案3】:

    https://github.com/guardianproject/android-ffmpeg

    在 git 上查看这个项目以获取有关更改 'ffmpeg.c.main()' 的线索 我相信这个项目的构建将在自述文件中提到的 NDK 发布时正常工作。

    注意:

    您应该花一些时间处理 NDK 发行版中的所有 doc 文件,以便您了解 make 的工作原理。

    'main()' 函数的退出条件通常需要针对 android JNI 稍作修改。

    【讨论】:

    • 我试图编译上面的项目,但我遇到了一些错误并且未能形成 .so 文件。而且我已经编辑了 ffmpeg.c 的 main() 函数,但是 libmain.so 找不到 libffmpeg.so 的错误
    • 当我将预构建的共享库 libffmpeg.so 包含到我的项目中时,它会成功包含在编译时,但无法加载库 libmylib.so 用于 libmain.so 请帮助....
    • @Robert Rowntree 你能告诉我步骤吗?我还更新了相关问题,请参阅链接...stackoverflow.com/questions/17141348/…
    • @Robert Rowntree 我给了你 +1...我希望 gurdianProject 对我有用....请提供一些步骤,以便我可以构建库并将您的答案发布在我的上面的链接,这样我就可以给你投票了。:)
    • 找不到链接。 @pratik - 如果你在 Windows 上,使用 NDK 和 ffmpeg.main(),IMO 考虑一个虚拟机。从长远来看,我认为你可能会得到比使用 cygwin 和所有拖入 ffmpeg 的 NDK 构建的问题更好的结果。
    猜你喜欢
    • 1970-01-01
    • 2013-03-05
    • 2012-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-16
    • 2011-03-13
    • 1970-01-01
    相关资源
    最近更新 更多