交叉編譯android環(huán)境下opencv+ffmpeg工具

當(dāng)我們需要使用opencv在android設(shè)備上進(jìn)行讀取和寫入結(jié)果視頻的時(shí)候蚜厉,需要使用視頻的解碼器。默認(rèn)opencv不帶解碼器。一般借助于ffmpeg第三方模塊惋耙。ffmpeg又依賴x264或者x265模塊乱陡。單獨(dú)編譯比較費(fèi)勁浇揩,使用以下腳本快速編譯:

以下編譯是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 () {
    #為了方便管理胳徽,創(chuàng)建有關(guān)的目錄
    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}'` # 防止多個(gè)結(jié)果
    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 () {
    # 這一個(gè)是針對(duì) ffmpeg 方便管理外部庫(kù)使用的
    # 核心思想是把 所有的庫(kù)都放到一起积锅,再讓 ffmpeg ld的時(shí)候在這里找(而不是添加多行) --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選擇性編譯,可以不包含進(jìn)去养盗,只保留x264編譯即可缚陷。
上面腳本如果編譯x265存在編譯報(bào)錯(cuò)找不到pthread庫(kù),在android交叉編譯時(shí)需要在CMakeLists.txt中去掉pthread庫(kù)往核,其他Linux交叉編譯沒(méi)有此問(wèn)題箫爷。
參考鏈接

Android libX265庫(kù)的交叉編譯

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

遇到問(wèn)題:opencv無(wú)法找到我們自己編譯的ffmpeg,參考如下:
??opencv+ffmpeg編譯打包全解指南 - 知乎 (zhihu.com)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末聂儒,一起剝皮案震驚了整個(gè)濱河市虎锚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌衩婚,老刑警劉巖窜护,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異非春,居然都是意外死亡柱徙,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門税娜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)坐搔,“玉大人,你說(shuō)我怎么就攤上這事敬矩「判校” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵弧岳,是天一觀的道長(zhǎng)凳忙。 經(jīng)常有香客問(wèn)我,道長(zhǎng)禽炬,這世上最難降的妖魔是什么涧卵? 我笑而不...
    開(kāi)封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮腹尖,結(jié)果婚禮上柳恐,老公的妹妹穿的比我還像新娘。我一直安慰自己热幔,他們只是感情好乐设,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著绎巨,像睡著了一般近尚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上场勤,一...
    開(kāi)封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天戈锻,我揣著相機(jī)與錄音歼跟,去河邊找鬼。 笑死格遭,一個(gè)胖子當(dāng)著我的面吹牛哈街,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播如庭,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼叹卷,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了坪它?” 一聲冷哼從身側(cè)響起骤竹,我...
    開(kāi)封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎往毡,沒(méi)想到半個(gè)月后蒙揣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡开瞭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年懒震,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗤详。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡个扰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出葱色,到底是詐尸還是另有隱情递宅,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布苍狰,位于F島的核電站办龄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏淋昭。R本人自食惡果不足惜俐填,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望翔忽。 院中可真熱鬧英融,春花似錦、人聲如沸歇式。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)贬丛。三九已至,卻和暖如春给涕,著一層夾襖步出監(jiān)牢的瞬間豺憔,已是汗流浹背额获。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留恭应,地道東北人抄邀。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像昼榛,于是被迫代替她去往敵國(guó)和親境肾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容