FFmepg compilation and CMake integration to Android

FFmepg compilation and integration to Android

  1. Compile file modification
  2. Package so execution
  3. Integration to Android

Preparing for compilation

  • Compiled with ubuntu system, the system version does not affect
	 apt-get update
     apt-get install yasm
     apt-get install pkg-config
  • Installation of NDK
    ndk r15c or ndk r19
    After testing, the NDK version has little impact, as long as it is not too low
    ndk r15 Download
    ndk latest
  • Download FFmpeg version this article adopts ffmpeg3.4.5
    Version 4.1.3 was used, but there are some problems with the script file. It is not easy to use the script file on the Internet. Version 4.1.3 sh is provided at the end of the article (not necessarily easy to use, need to be modified).
  1. Modify 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. If you don't need the x264 script, you need to add# Download 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 < number of CPU cores >
        make -j4
        make install
    }
    
    #build arm64
    build armv7-a
    
    
  3. ffmpeg script

    #!/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
    
    

    Note that the script requires chmod +x build.sh , and sudo. / script executes

  • At this time, you finish executing the script. If you are lucky, you can get the so file.

Ready to integrate into the ndk android source code

  1. Create NDK project
  2. Import so under the source libs directory
  3. Import include file
  4. Modify the build.gradle file
  5. Edit CMake file
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. Modify the original native-lib.cpp file
#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. Call, execute, see the following unexpectedly:

Problems encountered

  1. ninja: error: xxxxxx missing and no known rule to make it
    Because your CMake file is wrong, check it.
  2. undefined reference to 'avcodec_configuration()'
    See if extern "C" is the source file imported like this
    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"
       }
    
Thank you for your help:
  1. Compile related articles

Keywords: Android Linux cmake Ubuntu

Added by TechMistress on Sat, 02 Nov 2019 13:34:05 +0200