FFmepg編譯及CMake 集成到 Android

FFmepg編譯及集成到 Android

  1. 編譯文件修改
  2. 打包so 執行
  3. 集成到Android

準備編譯

  • 採用ubuntu系統編譯, 系統版本不影響
	 apt-get update
     apt-get install yasm
     apt-get install pkg-config
  • 安裝 NDK 本文采用
    ndk r15c 或 ndk r19
    經測試,NDK版本影響不大,只要不是太低就好
    ndk r15下載
    ndk 最新版
  • 下載FFmpeg 版本 本文采用 ffmpeg3.4.5
    曾採用4.1.3版本,但是腳本文件有些問題,網上查閱的並不好用,文章末尾提供4.1.3版本sh(不一定好用,需要修改)
  1. 修改 configure

    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)' 
    
  2. x264腳本 如果不需要,你需要將下方 ffmepg 腳本用的x264的地方加 # 下載 x264

    #!/bin/bash
    NDK=/home/oblvion/Desktop/ffmpeg/android-ndk-r15c
    
    configure()
    {
        CPU=$1
        PREFIX=$(pwd)/android/$CPU
        HOST=""
        CROSS_PREFIX=""
        SYSROOT=""
        if [ "$CPU" == "armv7-a" ]
        then
            HOST=arm-linux
            SYSROOT=$NDK/platforms/android-21/arch-arm/
            CROSS_PREFIX=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-
        else
            HOST=aarch64-linux
            SYSROOT=$NDK/platforms/android-21/arch-arm64/
            CROSS_PREFIX=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-
        fi
        ./configure \
        --prefix=$PREFIX \
        --host=$HOST \
        --enable-pic \
        --enable-static \
        --enalbe-neon \
        --extra-cflags="-fPIE -pie" \
        --extra-ldflags="-fPIE -pie" \
        --cross-prefix=$CROSS_PREFIX \
        --sysroot=$SYSROOT
    }
    
    build()
    {
        make clean
        cpu=$1
        echo "build $cpu"
    
        configure $cpu
        #-j<CPU核心數>
        make -j4
        make install
    }
    
    #build arm64
    build armv7-a
    
    
  3. ffmpeg 腳本

    #!/bin/bash
    NDK=/home/oblvion/Desktop/ffmpeg/android-ndk-r15c
    
    ADDI_CFLAGS="-fPIE -pie"
    ADDI_LDFLAGS="-fPIE -pie"
    
    configure()
    {
        CPU=$1
        PREFIX=$(pwd)/android/$CPU
        x264=$(pwd)/x264/android/$CPU
        HOST=""
        CROSS_PREFIX=""
        SYSROOT=""
        ARCH=""
        if [ "$CPU" == "armv7-a" ]
        then
            ARCH="arm"
            HOST=arm-linux
            SYSROOT=$NDK/platforms/android-21/arch-arm/ 
            CROSS_PREFIX=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-
        else
            ARCH="aarch64"
            HOST=aarch64-linux
            SYSROOT=$NDK/platforms/android-21/arch-arm64/
            CROSS_PREFIX=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-
        fi
        ./configure \
        --prefix=$PREFIX \
        --disable-encoders \
        --disable-decoders \
        --disable-avdevice \
        --disable-static \
        --disable-doc \
        --disable-ffplay \
        --disable-network \
        --disable-doc \
        --disable-symver \
        --enable-neon \
        --enable-shared \
        --enable-libx264 \
        --enable-gpl \
        --enable-pic \
        --enable-jni \
        --enable-pthreads \
        --enable-mediacodec \
        --enable-encoder=aac \
        --enable-encoder=gif \
        --enable-encoder=libopenjpeg \
        --enable-encoder=libmp3lame \
        --enable-encoder=libwavpack \
        --enable-encoder=libx264 \
        --enable-encoder=mpeg4 \
        --enable-encoder=pcm_s16le \
        --enable-encoder=png \
        --enable-encoder=srt \
        --enable-encoder=subrip \
        --enable-encoder=yuv4 \
        --enable-encoder=text \
        --enable-decoder=aac \
        --enable-decoder=aac_latm \
        --enable-decoder=libopenjpeg \
        --enable-decoder=mp3 \
        --enable-decoder=mpeg4_mediacodec \
        --enable-decoder=pcm_s16le \
        --enable-decoder=flac \
        --enable-decoder=flv \
        --enable-decoder=gif \
        --enable-decoder=png \
        --enable-decoder=srt \
        --enable-decoder=xsub \
        --enable-decoder=yuv4 \
        --enable-decoder=vp8_mediacodec \
        --enable-decoder=h264_mediacodec \
        --enable-decoder=hevc_mediacodec \
        --enable-hwaccel=h264_mediacodec \
        --enable-hwaccel=mpeg4_mediacodec \
        --enable-ffmpeg \
        --enable-bsf=aac_adtstoasc \
        --enable-bsf=h264_mp4toannexb \
        --enable-bsf=hevc_mp4toannexb \
        --enable-bsf=mpeg4_unpack_bframes \
        --enable-cross-compile \
        --cross-prefix=$CROSS_PREFIX \
        --target-os=android \
        --arch=$ARCH \
        --sysroot=$SYSROOT \
        --extra-cflags="-I$x264/include $ADDI_CFLAGS" \
        --extra-ldflags="-L$x264/lib"
    }
    
    build()
    {
        make clean
        cpu=$1
        echo "build $cpu"
        
        configure $cpu
        make -j4
        make install
    }
    
    #build arm64
    build armv7-a
    
    

    注意 腳本需要 chmod +x build.sh ,然後 sudo ./腳本執行

  • 這個時候 你執行完腳本,如果幸運 ,能拿到 so文件了

準備集成到 ndk android 源碼中

  1. 創建 NDK 項目
  2. 源碼libs 目錄下導入 so
    so
  3. 導入include文件
    include
  4. 修改 build.gradle 文件
    在這裏插入圖片描述
  5. 編輯CMake文件
cmake_minimum_required(VERSION 3.4.1)

set(lib_src_DIR ${CMAKE_SOURCE_DIR}/../../../libs/${ANDROID_ABI})

add_library(
        native-lib
        SHARED
        native-lib.cpp)

add_library(
        avcodec
        SHARED
        IMPORTED)

set_target_properties(
        avcodec
        PROPERTIES IMPORTED_LOCATION
        ${lib_src_DIR}/libavcodec.so)

add_library(
        avfilter
        SHARED
        IMPORTED)

set_target_properties(
        avfilter
        PROPERTIES IMPORTED_LOCATION
        ${lib_src_DIR}/libavfilter.so)

add_library(
        avformat
        SHARED
        IMPORTED)

set_target_properties(
        avformat
        PROPERTIES IMPORTED_LOCATION
        ${lib_src_DIR}/libavformat.so)

add_library(
        avutil
        SHARED
        IMPORTED)
set_target_properties(
        avutil
        PROPERTIES IMPORTED_LOCATION
        ${lib_src_DIR}/libavutil.so)

add_library(
        postproc
        SHARED
        IMPORTED)

set_target_properties(
        postproc
        PROPERTIES IMPORTED_LOCATION
        ${lib_src_DIR}/libpostproc.so)

add_library(
        swresample
        SHARED
        IMPORTED)

set_target_properties(
        swresample
        PROPERTIES IMPORTED_LOCATION
        ${lib_src_DIR}/libswresample.so)

add_library(
        swscale
        SHARED
        IMPORTED)

set_target_properties(
        swscale
        PROPERTIES IMPORTED_LOCATION
        ${lib_src_DIR}/libswscale.so)

find_library(
        log-lib
        log)

include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include)

target_link_libraries(
        native-lib
        avcodec
        avfilter
        avformat
        avutil
        postproc
        swresample
        swscale
        ${log-lib})
  1. 修改原來的 natice-lib.cpp 文件
    在這裏插入圖片描述
#include <jni.h>
#include <string>
#include <android/log.h>
extern "C" {
#include "include/libavcodec/avcodec.h"
#include "include/libavfilter/avfilter.h"
#include "include/libavformat/avformat.h"
#include "include/libavutil/imgutils.h"
#include "include/libswresample/swresample.h"
#include "include/libswscale/swscale.h"
#include "include/libx264/x264.h"
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_wmtc_ndktest_MainActivity_stringFromFFmpeg(
        JNIEnv *env,
        jobject /* this */) {
    char info[10000] = {0};
    sprintf(info, "%s\n", avcodec_configuration());
    return env->NewStringUTF(info);
}

OK。調用,執行,不出意外看到如下:
在這裏插入圖片描述

遇到的問題

  1. ninja: error: xxxxxx missing and no known rule to make it
    因爲你的 CMake文件錯誤,檢查一下
  2. undefined reference to 'avcodec_configuration()'
    看看是否 extern "C"是這樣導入的 源碼文件
    extern "C" {
       #include "include/libavcodec/avcodec.h"
       #include "include/libavfilter/avfilter.h"
       #include "include/libavformat/avformat.h"
       #include "include/libavutil/imgutils.h"
       #include "include/libswresample/swresample.h"
       #include "include/libswscale/swscale.h"
       #include "include/libx264/x264.h"
       }
    
感謝一下文章提供的幫助 :
  1. 編譯相關文章
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章