交叉编译android环境下opencv+ffmpeg工具

当我们需要使用opencv在android设备上进行读取和写入结果视频的时候,需要使用视频的解码器。默认opencv不带解码器。一般借助于ffmpeg第三方模块。ffmpeg又依赖x264或者x265模块。单独编译比较费劲,使用以下脚本快速编译:

以下编译是aarch64位的版本,32位类似处理;

opencv版本是4.5.1
#!/bin/sh

BASE=`pwd`
BUILD_HOST=aarch64-linux-android
OUTPUT_PATH=${BASE}/aarch64-install

OTHER_LIB=${OUTPUT_PATH}/all_without_ffmpeg

set_env(){
        export CROSS_COMPILE=/home/yw/android-toolchain_64/bin/aarch64-linux-android-
        AS=${CROSS_COMPILE}as
        AR=${CROSS_COMPILE}ar
        NM=${CROSS_COMPILE}nm
        CC=${CROSS_COMPILE}gcc
        GG=${CROSS_COMPILE}g++
        CXX=${CROSS_COMPILE}c++
        LD=${CROSS_COMPILE}ld
        RANLIB=${CROSS_COMPILE}ranlib
        STRIP=${CROSS_COMPILE}strip
        export AS AR NM CC GG LD RANLIB STRIP
        export PATH=$PATH:/home/yw/android-toolchain_64/bin
}

make_dirs () {
    #为了方便管理,创建有关的目录
    cd ${BASE} && mkdir compressed aarch64-install source -p
}

tget () { #try wget
    filename=`basename $1`
    echo "Downloading [${filename}]..."
    if [ ! -f ${filename} ];then
        wget $1
    fi

    echo "[OK] Downloaded [${filename}] "
}

download_package () {
    cd ${BASE}/compressed
    tget https://code.videolan.org/videolan/x264/-/archive/master/x264-master.tar.bz2
    tget https://ffmpeg.org/releases/ffmpeg-4.4.2.tar.gz
    tget http://download.videolan.org/videolan/x265/x265_3.2.tar.gz
}
tar_package () {
    cd ${BASE}/compressed
    ls * > /tmp/list.txt
    for TAR in `cat /tmp/list.txt`
    do
        tar -xf $TAR -C  ../source
    done
    rm -rf /tmp/list.txt
}

make_x264() {
    cd ${BASE}/source/x264*

    ./configure \
    --prefix=${OUTPUT_PATH}/x264 \
    --host=${BUILD_HOST} \
    --enable-shared \
    --enable-static \
    --enable-pic \
    --disable-asm

    make -j8 && make install
}

make_x265() {
    cd ${BASE}/source/x265*/build
        mkdir arm-x265
        cd arm-x265
    # 获取 工具链所在位置
        GCC_FULL_PATH=`whereis ${BUILD_HOST}-gcc | awk -F: '{ print $2 }' | awk '{print $1}'` # 防止多个结果
    CROSS_PATH=`dirname ${GCC_FULL_PATH}`
        touch crosscompile.cmake
        #echo "set(CROSS_COMPILE_ARM 1)" > crosscompile.cmake
        echo "set(CMAKE_SYSTEM_NAME Linux)" > crosscompile.cmake
        echo "set(CMAKE_SYSTEM_PROCESSOR aarch64)" >> crosscompile.cmake
        echo "" >> crosscompile.cmake
        echo "# specify the cross compiler" >> crosscompile.cmake
        echo "set(CMAKE_C_COMPILER ${CROSS_PATH}/${BUILD_HOST}-gcc)" >> crosscompile.cmake
        echo "set(CMAKE_CXX_COMPILER ${CROSS_PATH}/${BUILD_HOST}-g++)" >> crosscompile.cmake
        echo "set(CMAKE_SHARED_LINKER_FLAGS \"-ldl \${CMAKE_SHARED_LINKER_FLAGS}\")" >> crosscompile.cmake
        echo "" >> crosscompile.cmake
        echo "# specify the target environment" >> crosscompile.cmake
        echo "SET(CMAKE_FIND_ROOT_PATH  ${CROSS_PATH})" >> crosscompile.cmake
        # 编译安装
        cmake -DCMAKE_TOOLCHAIN_FILE=crosscompile.cmake -G "Unix Makefiles" \
        -DCMAKE_C_FLAGS="-fPIC ${CMAKE_C_FLAGS}" -DCMAKE_CXX_FLAGS="-fPIC ${CMAKE_CXX_FLAGS}" \
        -DCMAKE_SHARED_LINKER_FLAGS="-ldl ${CMAKE_SHARED_LINKER_FLAGS}"  \
        -DCMAKE_INSTALL_PREFIX=${OUTPUT_PATH}/x265 \
        ../../source && make -j8
        make install
}

prepare_other_lib () {
    # 这一个是针对 ffmpeg 方便管理外部库使用的
    # 核心思想是把 所有的库都放到一起,再让 ffmpeg ld的时候在这里找(而不是添加多行) --extra-cflags="-I${X264_DIR}/include -I${xxx}/include" \
    cd ${BASE}/aarch64-install/
    rm ${OTHER_LIB} -rf
    ls > /tmp/list.txt
    mkdir ${OTHER_LIB} -p
    for sub_dir in `cat /tmp/list.txt`
    do
        cp ${sub_dir}/* ${OTHER_LIB} -r -v
    done
    rm -rf /tmp/list.txt
}

make_ffmpeg() {
    MYPKGCONFIG=${BASE}/aarch64-install/x265/lib/pkgconfig/
    export PKG_CONFIG_PATH=${MYPKGCONFIG}:$PKG_CONFIG_PATH
    cd ${BASE}/source/ffmpeg*

        ./configure \
        --prefix=${OUTPUT_PATH}/ffmpeg \
        --enable-cross-compile \
        --cross-prefix=${BUILD_HOST}- \
        --arch=aarch64 \
        --host-os=linux \
        --target-os=android \
        --cc=${BUILD_HOST}-gcc \
        --enable-shared \
        --enable-static \
        --enable-pic \
        --enable-gpl \
        --enable-nonfree \
        --enable-ffmpeg \
        --enable-swscale  \
        --enable-libx264 \
        --enable-libx265 \
        --enable-decoder=hevc \
    --enable-ffplay \
        --disable-stripping \
        --disable-doc  --disable-debug --disable-iconv --disable-armv5te --disable-armv6 --disable-armv6t2 \
        --pkg-config="pkg-config --static" \
        --extra-cflags=-I${OTHER_LIB}/include \
        --extra-ldflags=-L${OTHER_LIB}/lib

        make -j8 && make install
}

echo "Using ${BUILD_HOST}-gcc"
make_dirs
download_package
tar_package
set_env
make_x264
make_x265
prepare_other_lib
make_ffmpeg

注意:x265选择性编译,可以不包含进去,只保留x264编译即可。
上面脚本如果编译x265存在编译报错找不到pthread库,在android交叉编译时需要在CMakeLists.txt中去掉pthread库,其他Linux交叉编译没有此问题。
参考链接

Android libX265库的交叉编译

opencv编译脚本如下:

OPENCV_ROOT="${WD}"
N_JOBS=48

INSTALL_DIR="${WD}/build_android"
rm -rf "${INSTALL_DIR}"

### Make each ABI target iteratly and sequentially
for i in "${ANDROID_ABI_LIST[@]}"
do
    ANDROID_ABI="${i}"
    echo "Start building ${ANDROID_ABI} version"

    if [ "${ANDROID_ABI}" = "armeabi" ]; then
        API_LEVEL=21
    else
        API_LEVEL=21
    fi

    temp_build_dir="${OPENCV_ROOT}/platforms/build_android_${ANDROID_ABI}"

    ### Remove the build folder first, and create it
    rm -rf "${temp_build_dir}"
    mkdir -p "${temp_build_dir}"
    cd "${temp_build_dir}"

    echo ${INSTALL_DIR}
    cmake \
        -DCMAKE_MAKE_PROGRAM=/usr/bin/make \
        -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \
        -DCMAKE_TOOLCHAIN_FILE=${NDK_ROOT}/build/cmake/android.toolchain.cmake \
        -DANDROID_ABI=${ANDROID_ABI} \
        -DANDROID_STL=c++_static \
        -DCMAKE_BUILD_TYPE=Release \
        -DANDROID_NATIVE_API_LEVEL=${API_LEVEL} \
        -DCMAKE_BUILD_TYPE=Release \
        -DWITH_FFMPEG=ON \
        -D BUILD_opencv_java=ON \
        -D BUILD_ANDROID_PROJECTS=OFF \
        -D WITH_CUDA=OFF \
        -D WITH_MATLAB=OFF \
        -D BUILD_ANDROID_EXAMPLES=OFF \
        -D BUILD_DOCS=OFF \
        -D BUILD_PERF_TESTS=OFF \
        -D BUILD_TESTS=OFF \
        -D BUILD_SHARED_LIBS=ON \
        -D BUILD_TIFF=ON \
        -D BUILD_PNG=ON \
        -D OPENCV_GENERATE_PKGCONFIG=ON \
        -D OPENCV_FFMPEG_USE_FIND_PACKAGE=ON \
        -D OPENCV_FFMPEG_SKIP_BUILD_CHECK=ON \
        -DFFMPEG_DIR=/home/yw/opensource/ffmpeg+h264/aarch64-install/ffmpeg \
        -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
        -DANDROID_SDK=${SDK_ROOT} \
        ../..

    # Build it
    make -j${N_JOBS}

    # Install it
    make install/strip

    ### Remove temp build folder
    cd "${WD}"
    rm -rf "${temp_build_dir}"
    echo "end building ${ANDROID_ABI} version"
done

遇到问题:opencv无法找到我们自己编译的ffmpeg,参考如下:
🤓opencv+ffmpeg编译打包全解指南 - 知乎 (zhihu.com)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容