• NDK20b FFmpeg4.2.2 编译和集成


    NDK20b FFmpeg4.2.2 编译和集成

    1 ffmpeg

    wget https://ffmpeg.org/releases/ffmpeg-4.2.2.tar.bz2 --no-check-certificate
    tar -jxvf ffmpeg-4.2.2.tar.bz2
    
    • 1
    • 2

    2 NDK20b

     wget https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip
     unizp android-ndk-r20b-linux-x86_64.zip
    
    • 1
    • 2

    3 build_android.sh

    #!/bin/bash
    
    export NDK=/root/workspace/android-ndk-r20b #这里配置先你的 NDK 路径
    TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
    
    
    function build_android
    {
    
    ./configure \
    --prefix=$PREFIX \
    --enable-neon  \
    --enable-hwaccels  \
    --enable-gpl   \
    --disable-postproc \
    --disable-debug \
    --enable-small \
    --enable-jni \
    --enable-mediacodec \
    --enable-decoder=h264_mediacodec \
    --enable-static \
    --enable-shared \
    --disable-doc \
    --enable-ffmpeg \
    --disable-ffplay \
    --disable-ffprobe \
    --disable-avdevice \
    --disable-doc \
    --disable-symver \
    --cross-prefix=$CROSS_PREFIX \
    --target-os=android \
    --arch=$ARCH \
    --cpu=$CPU \
    --cc=$CC \
    --cxx=$CXX \
    --enable-cross-compile \
    --sysroot=$SYSROOT \
    --extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \
    --extra-ldflags="$ADDI_LDFLAGS"
    
    make clean
    make -j16
    make install
    
    echo "============================ build android arm64-v8a success =========================="
    
    }
    
    #arm64-v8a
    ARCH=arm64
    CPU=armv8-a
    API=21
    CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
    CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
    SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
    CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
    PREFIX=$(pwd)/android/$CPU
    OPTIMIZE_CFLAGS="-march=$CPU"
    
    build_android
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    ./build_android.sh
    编译成功后会在 android 目录下生成对应六个模块的静态库和动态库。

    另外,若要编译成 32 位的库,则需修改对应的编译脚本:

    #armv7-a
    ARCH=arm
    CPU=armv7-a
    API=21
    CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang
    CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++
    SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
    CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
    PREFIX=$(pwd)/android/$CPU
    OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4 FFmpeg 集成

    基于上节编译好的 FFmpeg 静态库,我们在 Android Studio 上进行简单的集成测试。
    在这里插入图片描述我们可以按照上图所示,将 FFmpeg 各个模块的静态库和头文件放置到指定目录下,实现一个获取各个模块版本信息的 jni 。

    #include <cstdio>
    #include <cstring>
    #include "util/LogUtil.h"
    #include "jni.h"
    
    //由于 FFmpeg 库是 C 语言实现的,告诉编译器按照 C 的规则进行编译
    extern "C" {
    #include <libavcodec/version.h>
    #include <libavcodec/avcodec.h>
    #include <libavformat/version.h>
    #include <libavutil/version.h>
    #include <libavfilter/version.h>
    #include <libswresample/version.h>
    #include <libswscale/version.h>
    };
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_byteflow_learnffmpeg_media_FFMediaPlayer
     * Method:    native_GetFFmpegVersion
     * Signature: ()Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_com_byteflow_learnffmpeg_media_FFMediaPlayer_native_1GetFFmpegVersion
            (JNIEnv *env, jclass cls)
    {
        char strBuffer[1024 * 4] = {0};
        strcat(strBuffer, "libavcodec : ");
        strcat(strBuffer, AV_STRINGIFY(LIBAVCODEC_VERSION));
        strcat(strBuffer, "\nlibavformat : ");
        strcat(strBuffer, AV_STRINGIFY(LIBAVFORMAT_VERSION));
        strcat(strBuffer, "\nlibavutil : ");
        strcat(strBuffer, AV_STRINGIFY(LIBAVUTIL_VERSION));
        strcat(strBuffer, "\nlibavfilter : ");
        strcat(strBuffer, AV_STRINGIFY(LIBAVFILTER_VERSION));
        strcat(strBuffer, "\nlibswresample : ");
        strcat(strBuffer, AV_STRINGIFY(LIBSWRESAMPLE_VERSION));
        strcat(strBuffer, "\nlibswscale : ");
        strcat(strBuffer, AV_STRINGIFY(LIBSWSCALE_VERSION));
        strcat(strBuffer, "\navcodec_configure : \n");
        strcat(strBuffer, avcodec_configuration());
        strcat(strBuffer, "\navcodec_license : ");
        strcat(strBuffer, avcodec_license());
        LOGCATE("GetFFmpegVersion\n%s", strBuffer);
        return env->NewStringUTF(strBuffer);
    }
    
    #ifdef __cplusplus
    }
    #endif
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    Java 层的调用逻辑:

    package com.byteflow.learnffmpeg.media;
    
    public class FFMediaPlayer {
        static {
            System.loadLibrary("learn-ffmpeg");
        }
    
        public static String GetFFmpegVersion() {
            return native_GetFFmpegVersion();
        }
    
        private static native String native_GetFFmpegVersion();
    }
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ((TextView)findViewById(R.id.text_view)).setText(FFMediaPlayer.GetFFmpegVersion());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    CMakeLists.txt 构建脚本:

    # Sets the minimum version of CMake required to build the native library.
    cmake_minimum_required(VERSION 3.4.1)
    
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
    
    set(jnilibs ${CMAKE_SOURCE_DIR}/../jniLibs)
    set(libname learn-ffmpeg)
    
    include_directories(
            include
            ${CMAKE_SOURCE_DIR}/util
    )
    
    link_directories(
            ${jnilibs}/${ANDROID_ABI})
    
    file(GLOB src-files
            ${CMAKE_SOURCE_DIR}/*.cpp)
    
    add_library( # Sets the name of the library.
                 ${libname}
    
                 # Sets the library as a shared library.
                 SHARED
    
                 # Provides a relative path to your source file(s).
                 ${src-files}
            )
    
    set(third-party-libs
            avformat
            avcodec
            avfilter
            swresample
            swscale
            avutil
            )
    
    set(native-libs
            android
            EGL
            GLESv3
            OpenSLES
            log
            m
            z
            )
    
    target_link_libraries( # Specifies the target library.
                           ${libname}
    
                           # Links the target library to the log library
                           # included in the NDK.
                           ${log-lib}
                           ${third-party-libs}
                           ${native-libs}
                           )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    编译完成后,运行 App 获取 FFmpeg 各个模块版本和编译配置信息。
    在这里插入图片描述

    https://blog.csdn.net/leixiaohua1020
    https://juejin.im/post/5e1eace16fb9a02fec66474e

  • 相关阅读:
    VSCode+mingw/VSCode+CMake+mingw windows VSCode c++环境搭建
    2.4、编码与调制
    lerna 简单教学
    车牌识别平台开源(支持蓝牌、绿牌,准确率高达96%)
    GMO Research 2022年旅游调查:旅游业有望强劲增长
    5G高算力智能模组:引领AIoT进入摩尔定律时代
    IP地址最终弹,DNS,数据链路层,特殊地址
    3.JavaI/O和计算机网络学习总结
    LC 239.滑动窗口最大值
    JavaScript第三讲:解锁JavaScript的数据世界:基本数据类型与类型转换的奥秘
  • 原文地址:https://blog.csdn.net/qq_37705525/article/details/125456462