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
    FFmepg编译及CMake 集成到 Android
  3. 导入include文件
    FFmepg编译及CMake 集成到 Android
  4. 修改 build.gradle 文件
    FFmepg编译及CMake 集成到 Android
  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 文件
    FFmepg编译及CMake 集成到 Android
#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。调用,执行,不出意外看到如下:
FFmepg编译及CMake 集成到 Android

遇到的问题

  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. 编译相关文章
上一篇:Opensource Java ASN.1解码器,可以使用自动标签


下一篇:tensorflow seq2seq api使用及 seq2seq 实现