您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“ffmpeg在Windows平臺下怎么編譯及集成”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“ffmpeg在Windows平臺下怎么編譯及集成”吧!
交叉編譯:交叉編譯就是程序的編譯環(huán)境和實(shí)際運(yùn)行環(huán)境不一致,即在一個平臺上生成另一個平臺上的可執(zhí)行代碼。
為什么要交叉編譯,其實(shí)之前原因已經(jīng)說過了,因?yàn)椴煌脚_的差異,指令集都不一樣,比如win上面是intel的指令集,但android手機(jī)上幾乎百分百都是arm的指令集,所以直接拿win上編譯出來的庫給android用,肯定無法使用的,所以需要交叉編譯。
交叉編譯主要是借助android 的ndk工具包
下面大致列舉了一下經(jīng)常會用到的組件。
ARM 交叉編譯器
構(gòu)建工具
Java 原生接口頭文件
C 庫
Math 庫
最小的 C++ 庫
ZLib 壓縮庫
POSIX 線程
Android 日志庫
Android 原生應(yīng)用 API
OpenGL ES 庫
OpenSL ES 庫
下面來看一下 Android 所提供的 NDK 跟目錄下的結(jié)構(gòu)。
ndk-build: 該 Shell 腳本是 Android NDK 構(gòu)建系統(tǒng)的起始點(diǎn),一般在項(xiàng)目中僅僅執(zhí)行這一個命令就可以編譯出對應(yīng)的動態(tài)鏈接庫了。
ndk-gdb: 該 Shell 腳本允許用 GUN 調(diào)試器調(diào)試 Native 代碼,并且可以配置到 AS 中,可以做到像調(diào)試 Java 代碼一樣調(diào)試 Native 代碼。
ndk-stack: 該 Shell 腳本可以幫組分析 Native 代碼崩潰時的堆棧信息。
build: 該目錄包含 NDK 構(gòu)建系統(tǒng)的所有模塊。
platforms: 該目錄包含支持不同 Android 目標(biāo)版本的頭文件和庫文件, NDK 構(gòu)建系統(tǒng)會根據(jù)具體的配置來引用指定平臺下的頭文件和庫文件。
toolchains: 該目錄包含目前 NDK 所支持的不同平臺下的交叉編譯器 - ARM 、X86、MIPS ,目前比較常用的是 ARM 。構(gòu)建系統(tǒng)會根據(jù)具體的配置選擇不同的交叉編譯器。
toolchains里一般會提供這么一些工具:
CC:編譯器,對C源文件進(jìn)行編譯處理,生成匯編文件。
AS:將匯編文件生成目標(biāo)文件(匯編文件使用的是指令助記符,AS將它翻譯成機(jī)器碼)。
AR:打包器,用于庫操作,可以通過該工具從一個庫中刪除或者增加目標(biāo)代碼模塊。
LD:鏈接器,為前面生成的目標(biāo)代碼分配地址空間,將多個目標(biāo)文件鏈接成一個庫或者是可執(zhí)行文件。
GDB:調(diào)試工具,可以對運(yùn)行過程中的程序進(jìn)行代碼調(diào)試工作。
STRIP:以最終生成的可執(zhí)行文件或者庫文件作為輸入,然后消除掉其中的源碼。
NM:查看靜態(tài)庫文件中的符號表。
Objdump:查看靜態(tài)庫或者動態(tài)庫的方法簽名。
不過不同版本的ndk,里邊的工具不一樣,部分新的ndk里可能就沒有ar 、strip 之類的,可能在新的ndk里這些工具命名不一樣或者是放在其它地方了,比如本人發(fā)現(xiàn)的21.1.6352462(win)中包含 strip 和 ar,但 24.0.8215888 版本中沒有相關(guān)庫,而且這幾個版本中都沒有 nm 庫,在編譯 ffmpeg時一定會提示找不到nm,幸好 nm不是必須的,不慌,如果遇到找不到相關(guān)工具,說明路徑設(shè)置的有問題,或者根本就是當(dāng)前版本的ndk中沒有此類工具或者已經(jīng)改名,需要去找找資料看看新版本的工具叫啥或者干脆下載舊版本ndk
一名優(yōu)秀的c++開發(fā),必須得對c++編譯有一定了解。前文已經(jīng)介紹了交叉編譯,那現(xiàn)在就來學(xué)習(xí)如何編譯 ffmpeg 吧
在ffmpeg官網(wǎng)下載源碼:
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
根據(jù)自己需要,切換自己想要的版本。
ffmpeg的編譯其實(shí)已經(jīng)非常簡單了,因?yàn)榕1频膄fmpeg開發(fā)者提供了一個腳本,叫 configure,其實(shí)我們寫的編譯腳本就是在指定編譯工具的位置,然后調(diào)用 configure 腳本編譯
本人是在win11上編譯 ffmpeg,需要下載msys2工具并配置相關(guān)環(huán)境,必須以管理員運(yùn)行msys2之后才能來配置環(huán)境,否則就會報異常
pacman -S make yasm diffutils pkg-config #在msys2上安裝必要軟件
然后在ffmpeg文件夾內(nèi)建腳本文件,并把如下內(nèi)容貼上:
#!/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=h364_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 aarch74-linux-android${API} aarch74-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"
相關(guān)解釋:
CC:指定c編譯器路徑
CROSS_PREFIX:指定交叉編譯工具文件路徑的統(tǒng)一前綴。各個工具的最終文件路徑為:cross-prefix + 工具名,比如上面腳本的prefix為TOOLCHAIN/bin/arm-linux-androideabi-,那么ar工具的路徑即為TOOLCHAIN/bin/arm-linux-androideabi-ar
target-os:指定目標(biāo)平臺,因?yàn)?ffmpeg 可以在各平臺上運(yùn)行的,各平臺上一些配置不太一樣,所以需要指定的
另外編譯腳本里邊還有大量的 enable disable ,這些都是 configure 腳本里的編譯選項(xiàng),比如說 --enable-shared 意思就是編譯動態(tài)庫,所以上面的腳本最終會生成 so 文件,而不會生成 a 文件。
這些編譯選項(xiàng)都可以使用 configure --help,可以查詢到,大家可以試試
不管是這些 enable 編譯選項(xiàng),還是像 CC 一類的選項(xiàng),都是在配置 configure 腳本,通過文本方式打開 configure 文件,可以看到:
--cc=CC use C compiler CC [$cc_default] --target-os=OS compiler targets OS [$target_os] --enable-shared build shared libraries [no]
運(yùn)行編譯腳本之后,如果編譯成功了就會看到相關(guān)so庫了,so庫在lib文件夾中
首先看cmakelist怎么寫:
# 設(shè)置最小使用版本 cmake_minimum_required(VERSION 3.18.1) project("demo") include_directories(include) # 添加本地so庫 native-lib:這個是聲明引用so庫的名稱 SHARED:表示共享so庫文件 # 構(gòu)建so庫的源文件 add_library( demo SHARED native-lib.cpp ) set(SO_DIR ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}) # 使用系統(tǒng)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)想要調(diào)用log庫的方法, # 那么就需要配置這個屬性,意思是把NDK庫關(guān)聯(lián)到本地庫。 # 第一個參數(shù)表示本地的庫 native-lib 要調(diào)用到log庫的方法,即要被關(guān)聯(lián)的庫名稱,log-lib 要關(guān)聯(lián)的庫名稱 target_link_libraries( demo #ffmpeg------start---------- avcodec avutil swresample avfilter avformat swscale #ffmpeg------end------------ ${log-lib} )
到此,相信大家對“ffmpeg在Windows平臺下怎么編譯及集成”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。