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
        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_第1张图片
  3. 导入include文件
    FFmepg编译及CMake 集成到 Android_第2张图片
  4. 修改 build.gradle 文件
    FFmepg编译及CMake 集成到 Android_第3张图片
  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_第4张图片
#include 
#include 
#include 
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_第5张图片

遇到的问题

  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. 编译相关文章

你可能感兴趣的:(三方,linu,ffmepg,cmake)