C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > FFmpeg win编译集成

ffmpeg 在 win平台下的编译以及集成

作者:某昆real

这篇文章主要为大家介绍了ffmpeg 在 win平台下的编译以及集成详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪

引言

Java是 write once,run anywhre,但 C 不一样,各平台均有差异,无法只写一次,而且各个平台的编译都不一样。比如android的ndk工具链,不同平台的库都是不一样的

本文主要讲解下 ffmpeg 在 win 平台下的编译以及集成

1、交叉编译

交叉编译:交叉编译就是程序的编译环境和实际运行环境不一致,即在一个平台上生成另一个平台上的可执行代码。

为什么要交叉编译,其实之前原因已经说过了,因为不同平台的差异,指令集都不一样,比如win上面是intel的指令集,但android手机上几乎百分百都是arm的指令集,所以直接拿win上编译出来的库给android用,肯定无法使用的,所以需要交叉编译。

交叉编译主要是借助android 的ndk工具包

下面大致列举了一下经常会用到的组件。

下面来看一下 Android 所提供的 NDK 跟目录下的结构。

toolchains里一般会提供这么一些工具:

不过不同版本的ndk,里边的工具不一样,部分新的ndk里可能就没有ar 、strip 之类的,可能在新的ndk里这些工具命名不一样或者是放在其它地方了,比如本人发现的21.1.6352462(win)中包含 strip 和 ar,但 24.0.8215888 版本中没有相关库,而且这几个版本中都没有 nm 库,在编译 ffmpeg时一定会提示找不到nm,幸好 nm不是必须的,不慌,如果遇到找不到相关工具,说明路径设置的有问题,或者根本就是当前版本的ndk中没有此类工具或者已经改名,需要去找找资料看看新版本的工具叫啥或者干脆下载旧版本ndk

2、FFmpeg编译

一名优秀的c++开发,必须得对c++编译有一定了解。前文已经介绍了交叉编译,那现在就来学习如何编译 ffmpeg 吧

在ffmpeg官网下载源码:

git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg

根据自己需要,切换自己想要的版本。

ffmpeg的编译其实已经非常简单了,因为牛逼的ffmpeg开发者提供了一个脚本,叫 configure,其实我们写的编译脚本就是在指定编译工具的位置,然后调用 configure 脚本编译

本人是在win11上编译 ffmpeg,需要下载msys2工具并配置相关环境,必须以管理员运行msys2之后才能来配置环境,否则就会报异常

pacman -S make yasm diffutils pkg-config #在msys2上安装必要软件

然后在ffmpeg文件夹内建脚本文件,并把如下内容贴上:

 #!/bin/sh

NDK_PATH=/c/workspace/android_sdk/ndk/21.1.6352462

BUILD_PLATFORM=windows-x86_64

API=21

ANDROID_ARMV5_CFLAGS="-march=armv5te"
ANDROID_ARMV7_CFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=neon"
ANDROID_ARMV8_CFLAGS="-march=armv8-a"
ANDROID_X86_CFLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32"
ANDROID_X86_64_CFLAGS="-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel"


# params($1:arch,$2:arch_abi,$3:compiler,$4:cross_prefix,$5:cflags)
build_bin() {

    echo "-------------------star build $2-------------------------"

    ARCH=$1         # arm arm64 x86 x86_64
    # CPU
    ANDROID_ARCH_ABI=$2     # armeabi armeabi-v7a x86 mips

    COMPILER=$3

    PREFIX=$(pwd)/dist/${ANDROID_ARCH_ABI}/

    TOOLCHAIN=${NDK_PATH}/toolchains/llvm/prebuilt/${BUILD_PLATFORM}

    CC=${TOOLCHAIN}/bin/${COMPILER}-clang

    CXX=${TOOLCHAIN}/bin/${COMPILER}-clang++

    SYSROOT=${TOOLCHAIN}/sysroot

    CROSS_PREFIX=${TOOLCHAIN}/bin/$4-

    CFLAGS=$5

    echo "pwd==$(pwd)"
    echo "ARCH==${ARCH}"
    echo "PREFIX==${PREFIX}"
    echo "SYSROOT=${SYSROOT}"
    echo "CFLAGS=${CFLAGS}"
    echo "CC==${CC}"
    echo "CROSS_PREFIX=${CROSS_PREFIX}"

	sh ./configure \
        --prefix=${PREFIX} \
        --enable-neon \
        --enable-hwaccels \
        --enable-gpl \
        --disable-postproc \
        --disable-debug \
        --enable-small \
        --enable-jni \
        --enable-mediacodec \
        --enable-decoder=h264_mediacodec \
        --disable-static \
        --enable-shared \
        --disable-doc \
        --enable-ffmpeg \
        --disable-ffplay \
        --disable-ffprobe \
        --disable-avdevice \
        --disable-doc \
        --disable-symver \
        --target-os=android \
        --arch=${ARCH} \
        --cc=$CC \
        --sysroot=$SYSROOT \
        --enable-cross-compile \
        --cross-prefix=${CROSS_PREFIX} \
        --extra-cflags="-Os -fPIC -DANDROID -Wfatal-errors -Wno-deprecated $CFLAGS" \
        --extra-cxxflags="-D__thumb__ -fexceptions -frtti" \
        --extra-ldflags="-L${SYSROOT}/usr/lib" \

    make clean
    make -j8
    make install


    echo "-------------------$2 build end-------------------------"
}


# build armeabi
# build_bin arm armeabi arm-linux-androideabi arm-linux-androideabi "$ANDROID_ARMV5_CFLAGS"

#build armeabi-v7a
#build_bin arm armeabi-v7a armv7a-linux-androideabi${API} arm-linux-androideabi "$ANDROID_ARMV7_CFLAGS"

#build arm64-v8a
 build_bin arm64 arm64-v8a aarch64-linux-android${API} aarch64-linux-android "$ANDROID_ARMV8_CFLAGS"

#build x86
# build_bin x86 x86 i686-linux-android${API} i686-linux-android "$ANDROID_X86_CFLAGS"

#build x86_64
# build_bin x86_64 x86_64 x86_64-linux-android${API} x86_64-linux-android "$ANDROID_X86_64_CFLAGS"

相关解释:

另外编译脚本里边还有大量的 enable disable ,这些都是 configure 脚本里的编译选项,比如说 --enable-shared 意思就是编译动态库,所以上面的脚本最终会生成 so 文件,而不会生成 a 文件。

这些编译选项都可以使用 configure --help,可以查询到,大家可以试试

不管是这些 enable 编译选项,还是像 CC 一类的选项,都是在配置 configure 脚本,通过文本方式打开 configure 文件,可以看到:

--cc=CC                  use C compiler CC [$cc_default]
--target-os=OS           compiler targets OS [$target_os]
--enable-shared          build shared libraries [no]

运行编译脚本之后,如果编译成功了就会看到相关so库了,so库在lib文件夹中

3、FFmpeg集成

首先看cmakelist怎么写:

# 设置最小使用版本
cmake_minimum_required(VERSION 3.18.1)

project("demo")

include_directories(include)

# 添加本地so库 native-lib:这个是声明引用so库的名称 SHARED:表示共享so库文件
# 构建so库的源文件
add_library(
        demo
        SHARED
        native-lib.cpp
)

set(SO_DIR ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})

# 使用系统ndk 提供的库,如 log库
# log-lib 这个指定的是在NDK库中每个类型的库会存放一个特定的位置,而log库存放
# 在log-lib中
# log 指定使用log库
find_library(
        log-lib
        log
)

message("c_CMAKE_SOURCE_DIR:" ${CMAKE_SOURCE_DIR} )

# 加载avcodec-57库
add_library( avcodec
        SHARED
        IMPORTED)
set_target_properties( avcodec
        PROPERTIES IMPORTED_LOCATION
        ${SO_DIR}/libavcodec.so)

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

add_library( swresample
        SHARED
        IMPORTED)
set_target_properties( swresample
        PROPERTIES IMPORTED_LOCATION
        ${SO_DIR}/libswresample.so)

add_library( avfilter
        SHARED
        IMPORTED)
set_target_properties( avfilter
        PROPERTIES IMPORTED_LOCATION
        ${SO_DIR}/libavfilter.so)

add_library( avformat
        SHARED
        IMPORTED)
set_target_properties( avformat
        PROPERTIES IMPORTED_LOCATION
        ${SO_DIR}/libavformat.so)

add_library( swscale
        SHARED
        IMPORTED)
set_target_properties( swscale
        PROPERTIES IMPORTED_LOCATION
        ${SO_DIR}/libswscale.so)
#----------------------end-----------------------

# 如果你本地的库(native-lib)想要调用log库的方法,
# 那么就需要配置这个属性,意思是把NDK库关联到本地库。
# 第一个参数表示本地的库 native-lib 要调用到log库的方法,即要被关联的库名称,log-lib 要关联的库名称
target_link_libraries(
        demo
        #ffmpeg------start----------
        avcodec
        avutil
        swresample
        avfilter
        avformat
        swscale
        #ffmpeg------end------------
        ${log-lib}
)

其实这些写法都非常简单,如果出错肯定是没写对,注意下相关细节即可。 所有代码均已上传到本人github中

以上就是ffmpeg 在 win平台下的编译以及集成的详细内容,更多关于FFmpeg win编译集成的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文