中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站建設(shè)用英語怎么說排名優(yōu)化公司口碑哪家好

網(wǎng)站建設(shè)用英語怎么說,排名優(yōu)化公司口碑哪家好,wordpress frontpage,如何做網(wǎng)站么1 前言 前段時(shí)間介紹過使用xcode和qt creator編譯調(diào)試ffmepg.c,運(yùn)行平臺是在macOS上,本文擬介紹下android平臺如何用NDK編譯鏈編譯ffmepg庫并使用。 macOS上使用qt creator編譯調(diào)試ffmpeg.c macOS上將ffmpeg.c編譯成Framework 大體思路: 其…

?1 前言

? ? 前段時(shí)間介紹過使用xcode和qt creator編譯調(diào)試ffmepg.c,運(yùn)行平臺是在macOS上,本文擬介紹下android平臺如何用NDK編譯鏈編譯ffmepg庫并使用。

macOS上使用qt creator編譯調(diào)試ffmpeg.c

macOS上將ffmpeg.c編譯成Framework

? ? 大體思路:

  • 其一,分別介紹使用GCC和CLang編譯器來編譯ffmpeg庫的方法;
  • 其二,介紹如何將ffmpeg的多個(gè).a庫打包成1個(gè)so庫之法;
  • 其三,使用android studio新建一個(gè)native c++ Library工程,并將ffmepg庫引入到工程使用;

2 下載FFmpeg源碼

? ? 首先從git倉庫將ffmpeg代碼下載到本地:

git clone https://github.com/FFmpeg/FFmpeg.git && git checkout release/6.1

3 編譯FFmpeg

3.1 GCC編譯

? ? 編譯環(huán)境:

  • ffmpeg release/6.1分支
  • android ndk?17.2.4988734版本,可借助android studio工具下載;

? ? 通過給編譯腳本傳參(aarch64/x86_64)支持arm64和x86_64架構(gòu):??

#! /usr/bin/env bashset -eARG_COUNT=$#
#支持架構(gòu)aarch64 x86_64
ARCH_NAME=$1
if [[ ${ARG_COUNT} -lt 1 ]]||[[ ${ARCH_NAME} != "aarch64" && ${ARCH_NAME} != "x86_64" ]]; thenecho "Usage:./build_ffmpeg_for_android.sh aarch64/x86_64"exit -1
fiNDK_ROOT=/Users/mingo/Library/Android/sdk/ndk/17.2.4988734
SYSROOT=${NDK_ROOT}/sysroot
echo "ARCH_NAME=${ARCH_NAME}"
TOOLCHAIN_ARCH=${ARCH_NAME}-linux-android
FLATFORM=${NDK_ROOT}/platforms/android-28/arch-arm64
SYSROOT_INCLUDE_PATH="-I${SYSROOT}/usr/include/${ARCH_NAME}-linux-android -isysroot ${SYSROOT}"
COMPILER_PREFIX=${ARCH_NAME}-linux-android
CURRENT_DIR=`pwd`
BUILD_OUTPUT_DIR="${CURRENT_DIR}/android/arm64"
if [ ${ARCH_NAME} == "x86_64" ]; thenTOOLCHAIN_ARCH=${ARCH_NAME}FLATFORM=${NDK_ROOT}/platforms/android-28/arch-x86_64BUILD_OUTPUT_DIR="${CURRENT_DIR}/android/x86_64"
fi
if [ ! -d ${BUILD_OUTPUT_DIR} ]; thenmkdir -p ${BUILD_OUTPUT_DIR}
fi
echo "TOOLCHAIN_RCH=${TOOLCHAIN_ARCH}"
PREBUILT=${NDK_ROOT}/toolchains/${TOOLCHAIN_ARCH}-4.9/prebuilt/darwin-x86_64/binFF_CFLAGS="-O3 -Wall -pipe -std=c11 -ffast-math -fstrict-aliasing -Werror=strict-aliasing -Wno-psabi -Wa,--noexecstack -DANDROID -DDEBUG"
FF_CXXFLAGS="-D__thumb__ -fexceptions -frtti"function build_for() {echo "start to configure ffmpeg"./configure --prefix=${BUILD_OUTPUT_DIR} \--sysroot=${FLATFORM} \--cross-prefix=${PREBUILT}/${COMPILER_PREFIX}- \--cc=${PREBUILT}/${COMPILER_PREFIX}-gcc \--enable-cross-compile --arch=${ARCH_NAME} --target-os=android \--enable-shared \--enable-pic \--disable-symver \--disable-asm \--enable-inline-asm \--disable-optimizations \--enable-debug \--disable-small \--disable-ffmpeg \--disable-ffprobe \--disable-ffplay \--disable-doc \--extra-cflags="${SYSROOT_INCLUDE_PATH} ${FFLAGS}" \--extra-cxxflags="${FF_CXXFLAGS}" \--extra-ldflags="-L${FLATFORM}/usr/lib"make cleanmake -j9make install
}build_forif [ $? -eq 0 ]; thenecho "configure ffmpeg succ"
elseecho "configure ffmpeg fail"
fi

? ? ?起初所用NDK版本是16.1.4479499版本,遇到編譯問題:

? ? 通過將NDK版本升級到17.2.4988734解決:

? ? ?NDK的android api選擇android-28:

xxxxx@localhost:~/Library/Android/sdk/ndk/17.2.4988734/platforms$tree -L 1
.
├── NOTICE
├── android-14
├── android-15
├── android-16
├── android-17
├── android-18
├── android-19
├── android-21
├── android-22
├── android-23
├── android-24
├── android-26
├── android-27
├── android-28
└── repo.prop14 directories, 2 files

? ? 將shell腳本改成如下即可:?

NDK_ROOT=/Users/xxx/Library/Android/sdk/ndk/17.2.4988734FLATFORM=${NDK_ROOT}/platforms/android-28/arch-arm64--extra-ldflags="-L${FLATFORM}/usr/lib"

? ? ?然后執(zhí)行編譯安裝:

sh build_for_android.sh aarch64(或x86_64)
  • arm64平臺編譯后輸出目錄在ffmpeg的根目錄下android/arm64目錄;
  • x86_64平臺編譯后輸出目錄在ffmpeg的根目錄下的android/x86_64目錄;?

? ? 執(zhí)行腳本命令之后,可編譯成功:?

3.2 使用ffmpeg庫

? ? CMakeLists腳本如下:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html# Sets the minimum version of CMake required to build the native library.cmake_minimum_required(VERSION 3.22.1)# Declares and names the project.project("ndkffmpeg")# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.add_library( # Sets the name of the library.ndkffmpeg# Sets the library as a shared library.SHARED# Provides a relative path to your source file(s).native-lib.cpp)# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.find_library( # Sets the name of the path variable.log-lib# Specifies the name of the NDK library that# you want CMake to locate.log)# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.set(FFMPEG_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs)
set(FFMPEG_INCLUDE_DIR ${FFMPEG_ROOT_DIR}/include)
set(FFMPEG_LIB_DIR ${FFMPEG_ROOT_DIR}/${ANDROID_ABI})#導(dǎo)入ffmpeg相關(guān)依賴庫
list(APPEND DEPENDCY_LIB_LIST avutil avformat avcodec avfilter avdevice swscale swresample)
list(APPEND DEPENDCY_LIB_LIST ffmpeg)
foreach(libname IN LISTS DEPENDCY_LIB_LIST)add_library(${libname} SHARED IMPORTED)set_target_properties( ${libname} PROPERTIES IMPORTED_LOCATION  ${FFMPEG_LIB_DIR}/lib${libname}.so)
endforeach()include_directories(${FFMPEG_INCLUDE_DIR} ${FFMPEG_ROOT_DIR}/../)
target_link_directories(ndkffmpeg PRIVATE ${FFMPEG_LIB_DIR})# 設(shè)置庫文件的輸出路徑
set_target_properties(ndkffmpeg PROPERTIESLIBRARY_OUTPUT_DIRECTORY ${FFMPEG_LIB_DIR}ARCHIVE_OUTPUT_DIRECTORY ${FFMPEG_LIB_DIR})
target_link_libraries( # Specifies the target library.ndkffmpegavutilavformatavcodecavfilteravdeviceswresampleswscale# Links the target library to the log library# included in the NDK.${log-lib})

? ? 在編寫完成CMakeLists腳本后,并且在工程目錄下引入so和include文件:

? ? 在native-lib.cpp里寫一個(gè)簡單的程序看看效果:?

#include <jni.h>
#include <string>extern "C" {
#include "libavformat/avformat.h"
}static int decode_interrupt_cb(void *ctx) {return 0;
}static void test_ffmpeg_func() {AVFormatContext* ifmt = NULL;const char* filename = "rtmp://10.0.2.2/live/8";AVDictionary *d = NULL;//av_dict_set(&d, "timeout", NULL, 0);//av_dict_set(&d, "fflags", "nobuffer", 0);int ret = avformat_open_input(&ifmt, filename, NULL, &d);ret = avformat_find_stream_info(ifmt, NULL);AVPacket pkt;av_init_packet(&pkt);while (1) {int ret = av_read_frame(ifmt, &pkt);if (ret < 0) {av_log(NULL, AV_LOG_INFO, "error\n");}if (pkt.stream_index == AVMEDIA_TYPE_VIDEO && pkt.flags & AV_PKT_FLAG_KEY) {//av_log(NULL, AV_LOG_INFO, "keyframe\n");}}
}extern "C" JNIEXPORT jstring JNICALL
Java_com_example_ndkffmpeg_MainActivity_stringFromJNI(JNIEnv* env,jobject /* this */) {av_log_set_level(AV_LOG_DEBUG);test_ffmpeg_func();std::string hello = "Hello from C++";return env->NewStringUTF(hello.c_str());
}

? ? 調(diào)試運(yùn)行效果;?

? ? 可以看到,app已經(jīng)成功將ffmpeg各庫加載起來,并可使用了。?

?3.3 Clang編譯

? ? 以上是GCC編譯器編譯ffmpeg,此處再介紹使用clang編譯器來編譯ffmpeg,編譯環(huán)境:

  • ffmpeg release/6.1版本;
  • android ndk?21.3.6528147版本;

? ? 支持arm64和x86_64架構(gòu):?

#! /usr/bin/env bashset -eARG_COUNT=$#
#支持架構(gòu)aarch64 x86_64
ARCH_NAME=$1
if [[ ${ARG_COUNT} -lt 1 ]]||[[ ${ARCH_NAME} != "aarch64" && ${ARCH_NAME} != "x86_64" ]]; thenecho "Usage:./build_ffmpeg_for_android.sh aarch64/x86_64"exit -1
fiNDK_ROOT=/Users/mingo/Library/Android/sdk/ndk/21.3.6528147
ANDROID_VER=28
FLATFORM=${NDK_ROOT}/platforms/android-${ANDROID_VER}/arch-arm64
ENABLE_OPT="--enable-asm"
CURRENT_DIR=`pwd`
OUTPUT_DIR="${CURRENT_DIR}/android_clang/arm64"
if [ ${ARCH_NAME} == "x86_64" ]; thenFLATFORM=${NDK_ROOT}/platforms/android-${ANDROID_VER}/arch-x86_64ENABLE_OPT="--disable-asm"OUTPUT_DIR="${CURRENT_DIR}/android_clang/x86_64"
fi
if [ ! -d ${OUTPUT_DIR} ]; thenmkdir -p ${OUTPUT_DIR}
fi
PREBUILT=${NDK_ROOT}/toolchains/llvm/prebuilt/darwin-x86_64/bin
COMPILER_PREFIX=${ARCH_NAME}-linux-android
SYSROOT=${PREBUILT}/../sysrootFF_CFLAGS="-O3 -Wall -pipe -std=c11 -ffast-math -fstrict-aliasing -Werror=strict-aliasing -Wno-psabi -Wa,--noexecstack -DANDROID -DDEBUG"
FF_CXXFLAGS="-D__thumb__ -fexceptions -frtti"function build_for() {echo "start to configure ffmpeg"./configure --prefix=${OUTPUT_DIR} \--sysroot=${SYSROOT} \--cross-prefix=${PREBUILT}/${COMPILER_PREFIX}- \--cc=${PREBUILT}/${COMPILER_PREFIX}${ANDROID_VER}-clang \--cxx=${PREBUILT}/${COMPILER_PREFIX}${ANDROID_VER}-clang++ \--enable-cross-compile --arch=${ARCH_NAME} --target-os=android \--enable-shared \--enable-pic \--disable-symver \${ENABLE_OPT} \--enable-inline-asm \--disable-optimizations \--enable-debug \--disable-small \--disable-ffmpeg \--disable-ffprobe \--disable-ffplay \--disable-doc \--extra-cflags="${FFLAGS}"\--extra-cxxflags="${FF_CXXFLAGS}" \--extra-ldflags="-L${FLATFORM}/usr/lib"make cleanmake -j9make install
}build_forif [ $? -eq 0 ]; thenecho "configure ffmpeg succ"
elseecho "configure ffmpeg fail"
fi

? ? 然后,通過在命令行執(zhí)行如下命令編譯,編譯arm64架構(gòu)的:?

sh build_ffmpeg_for_android_with_clang.sh aarch64

? ? 編譯x86_64架構(gòu)的:?

sh build_ffmpeg_for_android_with_clang.sh x86_64

? ? ?編譯的輸出目錄在ffmpeg的目錄下:

  • arm64輸出在ffmpeg根目錄下android_clang/arm64目錄;
  • x86_64輸出在ffmpeg的根目錄下的android_clang/x86_64下;

? ? 提示:clang編譯僅做介紹,后續(xù)ffmpeg.c的編譯仍將使用NDK?17.2.4988734版本和GCC編譯器。

3.4 多個(gè).a庫打包成1個(gè)so

  • 將libavutil libavformat libavcodec libavfilter libavdevice libswsample libswscale幾個(gè).a庫打包成一個(gè)so庫;
  • *.a? =>? libffmpeg.so

? ? 主要思路:

  • configure的時(shí)候配置只編譯生成ffmpeg的static庫,而放棄編譯shared庫;
  • 用交叉編譯鏈中的鏈接器將ffmpeg的相關(guān).a庫鏈接成1個(gè)so庫;

? ? 貼出編譯&打包的shell腳本:

#! /usr/bin/env bashset -eARG_COUNT=$#
#支持架構(gòu)aarch64 x86_64
ARCH_NAME=$1
if [[ ${ARG_COUNT} -lt 1 ]]||[[ ${ARCH_NAME} != "aarch64" && ${ARCH_NAME} != "x86_64" ]]; thenecho "Usage:./build_ffmpeg_for_android.sh aarch64/x86_64"exit -1
fiNDK_ROOT=/Users/mingo/Library/Android/sdk/ndk/17.2.4988734
SYSROOT=${NDK_ROOT}/sysroot
echo "ARCH_NAME=${ARCH_NAME}"
TOOLCHAIN_ARCH=${ARCH_NAME}-linux-android
FLATFORM=${NDK_ROOT}/platforms/android-28/arch-arm64
echo "FLATFORM=${FLATFORM}"
SYSROOT_INCLUDE_PATH="-I${SYSROOT}/usr/include/${ARCH_NAME}-linux-android -isysroot ${SYSROOT}"
COMPILER_PREFIX=${ARCH_NAME}-linux-android
CURRENT_DIR=`pwd`
BUILD_OUTPUT_DIR="${CURRENT_DIR}/android/arm64"
if [ ${ARCH_NAME} == "x86_64" ]; thenTOOLCHAIN_ARCH=${ARCH_NAME}FLATFORM=${NDK_ROOT}/platforms/android-28/arch-x86_64BUILD_OUTPUT_DIR="${CURRENT_DIR}/android/x86_64"
fi
if [ ! -d ${BUILD_OUTPUT_DIR} ]; thenmkdir -p ${BUILD_OUTPUT_DIR}
fi
echo "TOOLCHAIN_RCH=${TOOLCHAIN_ARCH}"
PREBUILT=${NDK_ROOT}/toolchains/${TOOLCHAIN_ARCH}-4.9/prebuilt/darwin-x86_64/binFF_CFLAGS="-O3 -Wall -pipe -fpic -std=c11 -ffast-math -fstrict-aliasing -Werror=strict-aliasing -Wno-psabi -Wa,--noexecstack -DANDROID -DDEBUG"
FF_CXXFLAGS="-D__thumb__ -fexceptions -frtti"
FF_LDFLAGS="-lc -ldl -lm -lz -llog -lgcc"function build_for() {echo "start to configure ffmpeg"./configure --prefix=${BUILD_OUTPUT_DIR} \--sysroot=${FLATFORM} \--cross-prefix=${PREBUILT}/${COMPILER_PREFIX}- \--cc=${PREBUILT}/${COMPILER_PREFIX}-gcc \--enable-cross-compile --arch=${ARCH_NAME} --target-os=android \--disable-shared \--enable-static \--disable-optimizations \--enable-debug \--disable-small \--disable-ffmpeg \--disable-ffprobe \--disable-ffplay \--disable-doc \--extra-cflags="${SYSROOT_INCLUDE_PATH} ${FFLAGS}" \--extra-cxxflags="${FF_CXXFLAGS}" \--extra-ldflags="${FF_LDFLAGS} -L${FLATFORM}/usr/lib"make cleanmake -j9make install
}build_forif [ $? -eq 0 ]; thenecho "configure ffmpeg succ"
elseecho "configure ffmpeg fail"
fiGCC_PREFIX=${PREBUILT}/../lib/gcc/${COMPILER_PREFIX}/4.9.x
RPATH=${FLATFORM}/usr/lib
if [ ${ARCH_NAME} == "x86_64" ]; thenRPATH=${FLATFORM}/usr/lib64
fi
echo "RPATH=${RPATH}"
package_ffmpeg_libs() {${PREBUILT}/${COMPILER_PREFIX}-ld -L${BUILD_OUTPUT_DIR}/lib -L${GCC_PREFIX} -L${RPATH} \-rpath-link=${RPATH} -L${RPATH} -soname libffmpeg.so \-shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o ${BUILD_OUTPUT_DIR}/lib/libffmpeg.so \-lavformat -lavcodec -lavfilter -lavdevice -lswresample -lswscale -lavutil -lgcc \-lcamera2ndk -lmediandk -lnativewindow \-lc -ldl -lm -lz -llog \--dynamic-linker=/system/bin/linker# 設(shè)置動(dòng)態(tài)鏈接器,不同平臺的不同,android 使用的是/system/bin/linker
}package_ffmpeg_libsif [ $? -eq 0 ]; thenecho "package ffmpeg succ"
elseecho "package ffmpeg fail"
fi

? ? 遇到1個(gè)問題:

/Users/xxx/Applications/workspace/FFmpeg/android/arm64/lib/libswscale.a(half2float.o): In function `ff_init_half2float_tables':
/Users/xxx/Applications/workspace/FFmpeg/./libavutil/half2float.c:40: multiple definition of `ff_init_half2float_tables'
/Users/xxx/Applications/workspace/FFmpeg/android/arm64/lib/libavcodec.a(half2float.o):/Users/mingo/Applications/workspace/FFmpeg/./libavutil/half2float.c:40: first defined here

? ? 問題原因:

  • 上述問題的原因是libavcodec.a庫和libswscale.a庫均打包了half2float.o文件;
  • 在將上述庫最終鏈接打包成同一個(gè)so的時(shí)候就會出現(xiàn)上述重復(fù)定義問題;

? ? 解決辦法:

  • 打開libswscale/Makefile文件,將half2float.o文件去掉,libswscale不打包該文件,只讓libavcodec打包該文件;?

? ? 打包后的libffmpeg.so輸出在以下目錄,成功將ffmpeg相關(guān).a庫打包成libffmpeg.so庫:?

mingo@localhost:~/Applications/workspace/FFmpeg/android$tree -L 3
.
└── arm64├── include│?? ├── libavcodec│?? ├── libavdevice│?? ├── libavfilter│?? ├── libavformat│?? ├── libavutil│?? ├── libswresample│?? └── libswscale├── lib│?? ├── libavcodec.a│?? ├── libavdevice.a│?? ├── libavfilter.a│?? ├── libavformat.a│?? ├── libavutil.a│?? ├── libffmpeg.so│?? ├── libswresample.a│?? ├── libswscale.a│?? └── pkgconfig└── share└── ffmpeg14 directories, 8 files

?4 使用libffmpeg.so

? ? 使用android studio新建一個(gè)native c++ Library工程:

  • 在main目錄下新建jniLibs目錄,將libffmpeg.so庫放到arm64-v8a子目錄下;
  • ffmpeg相關(guān)頭文件放到j(luò)niLibs目錄下的include子目錄下;

? ? 在app的build.gradle文件下增加abiFilters

android {namespace 'com.example.ndkffmpeg'compileSdk 33defaultConfig {applicationId "com.example.ndkffmpeg"minSdk 24targetSdk 33versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"ndk {// 其他x86_64按此添加,逗號分割abiFilters 'arm64-v8a'}externalNativeBuild {cmake {cppFlags '-std=c++11'}}}
}

? ? ?貼出所寫CMakeLists腳本:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html# Sets the minimum version of CMake required to build the native library.cmake_minimum_required(VERSION 3.22.1)# Declares and names the project.project("ndkffmpeg")# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.add_library( # Sets the name of the library.ndkffmpeg# Sets the library as a shared library.SHARED# Provides a relative path to your source file(s).native-lib.cpp)# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.find_library( # Sets the name of the path variable.log-lib# Specifies the name of the NDK library that# you want CMake to locate.log)# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.set(FFMPEG_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs)
set(FFMPEG_INCLUDE_DIR ${FFMPEG_ROOT_DIR}/include)
set(FFMPEG_LIB_DIR ${FFMPEG_ROOT_DIR}/${ANDROID_ABI})include_directories(${FFMPEG_INCLUDE_DIR} ${FFMPEG_ROOT_DIR}/../)
target_link_directories(ndkffmpeg PRIVATE ${FFMPEG_LIB_DIR})# 設(shè)置庫文件的輸出路徑
set_target_properties(ndkffmpeg PROPERTIESLIBRARY_OUTPUT_DIRECTORY ${FFMPEG_LIB_DIR}ARCHIVE_OUTPUT_DIRECTORY ${FFMPEG_LIB_DIR})
target_link_libraries( # Specifies the target library.ndkffmpegffmpeg# Links the target library to the log library# included in the NDK.${log-lib})

? ? 在AndroidManifest.xml文件中請求網(wǎng)絡(luò)訪問權(quán)限:?

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.MyApplication"tools:targetApi="31"><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

? ? native-lib.cpp代碼貼出:

#include <jni.h>
#include <string>extern "C" {
#include "libavformat/avformat.h"
}static int decode_interrupt_cb(void *ctx) {return 0;
}static void test_ffmpeg_func() {AVFormatContext* ifmt = NULL;const char* filename = "rtmp://10.0.2.2/live/8";AVDictionary *d = NULL;//av_dict_set(&d, "timeout", NULL, 0);//av_dict_set(&d, "fflags", "nobuffer", 0);int ret = avformat_open_input(&ifmt, filename, NULL, &d);ret = avformat_find_stream_info(ifmt, NULL);AVPacket pkt;av_init_packet(&pkt);while (1) {int ret = av_read_frame(ifmt, &pkt);if (ret < 0) {av_log(NULL, AV_LOG_INFO, "error\n");}if (pkt.stream_index == AVMEDIA_TYPE_VIDEO && pkt.flags & AV_PKT_FLAG_KEY) {//av_log(NULL, AV_LOG_INFO, "keyframe\n");}}
}extern "C" JNIEXPORT jstring JNICALL
Java_com_example_ndkffmpeg_MainActivity_stringFromJNI(JNIEnv* env,jobject /* this */) {av_log_set_level(AV_LOG_DEBUG);test_ffmpeg_func();std::string hello = "Hello from C++";return env->NewStringUTF(hello.c_str());
}

? ? ?輸入正確的filename地址即調(diào)試運(yùn)行:

5 編譯ffmpeg.c為so

? ? 編譯環(huán)境如下:

  • ffmpeg release/6.1
  • NDK?17.2.4988734;

? ? 首先進(jìn)入到ffmpeg源碼目錄下的fftools子目錄,即為編譯ffmpeg命令行程序的工作目錄:

xxx@localhost:~/Applications/workspace/FFmpeg/fftools$tree -L 1
.
├── Makefile
├── build_ffmpeg_for_android.sh
├── cmdutils.c
├── cmdutils.h
├── ffmpeg.c
├── ffmpeg.h
├── ffmpeg_dec.c
├── ffmpeg_demux.c
├── ffmpeg_enc.c
├── ffmpeg_filter.c
├── ffmpeg_hw.c
├── ffmpeg_mux.c
├── ffmpeg_mux.h
├── ffmpeg_mux_init.c
├── ffmpeg_opt.c
├── ffplay.c
├── ffprobe.c
├── fftools.manifest
├── fftoolsres.rc
├── fopen_utf8.h
├── objpool.c
├── objpool.h
├── opt_common.c
├── opt_common.h
├── sync_queue.c
├── sync_queue.h
├── thread_queue.c
└── thread_queue.h1 directory, 28 files

5.1 改寫ffmpeg接口名

? ? 將ffmpeg命令行程序的main方法名改寫為ffmpeg名。頭文件和.c文件都需要修改:

int ffmpeg(int argc, char* argv[])

?5.1 工作目錄

? ? 在此列出主要工作目錄和fftools目錄結(jié)構(gòu)及輸出目錄接口,其他目錄結(jié)構(gòu)忽略掉:

├── CONTRIBUTING.md
├── COPYING.GPLv2
├── COPYING.GPLv3
├── COPYING.LGPLv2.1
├── COPYING.LGPLv3
├── CREDITS
├── Changelog
├── INSTALL.md
├── LICENSE.md
├── MAINTAINERS
├── Makefile
├── README.md
├── RELEASE
├── RELEASE_NOTES
├── android_arm64_output
│?? ├── include
│?? ├── lib
│?? └── share
├── android_x86_64_output
│?? ├── include
│?? ├── lib
│?? └── share
├── build_ffmpeg_for_android.sh
├── build_ffmpeg_for_android_with_clang.sh
├── config.h
├── config_components.h
├── configure
├── fftools
│?? ├── Makefile
│?? ├── build_ffmpeg_for_android.sh
│?? ├── cmdutils.c
│?? ├── cmdutils.h
│?? ├── ffmpeg.c
│?? ├── ffmpeg.h
│?? ├── ffmpeg_dec.c
│?? ├── ffmpeg_demux.c
│?? ├── ffmpeg_enc.c
│?? ├── ffmpeg_filter.c
│?? ├── ffmpeg_hw.c
│?? ├── ffmpeg_mux.c
│?? ├── ffmpeg_mux.h
│?? ├── ffmpeg_mux_init.c
│?? ├── ffmpeg_opt.c
│?? ├── ffplay.c
│?? ├── ffprobe.c
│?? ├── fftools.manifest
│?? ├── fftoolsres.rc
│?? ├── fopen_utf8.h
│?? ├── objpool.c
│?? ├── objpool.h
│?? ├── opt_common.c
│?? ├── opt_common.h
│?? ├── sync_queue.c
│?? ├── sync_queue.h
│?? ├── thread_queue.c
│?? └── thread_queue.h

5.2 GCC編譯

? ? 編寫shell腳本,放在fftools目錄下,使用GCC編譯ffmepg命令行程序?yàn)閟o庫,腳本如下,支持arm64和x86_64架構(gòu):

#! /usr/bin/env bashset -eARG_COUNT=$#
#支持架構(gòu)aarch64 x86_64
ARCH_NAME=$1
if [[ ${ARG_COUNT} -lt 1 ]]||[[ ${ARCH_NAME} != "aarch64" && ${ARCH_NAME} != "x86_64" ]]; thenecho "Usage:./build_ffmpeg_for_android.sh aarch64/x86_64"exit -1
fi
echo "ARCH_NAME=${ARCH_NAME}"NDK_ROOT=/Users/mingo/Library/Android/sdk/ndk/17.2.4988734
SYSROOT=${NDK_ROOT}/sysroot
TOOLCHAIN_ARCH=${ARCH_NAME}-linux-android
FLATFORM=${NDK_ROOT}/platforms/android-28/arch-arm64
SYSROOT_INCLUDE_PATH="${SYSROOT}/usr/include/${ARCH_NAME}-linux-android -isysroot ${SYSROOT}"
COMPILER_PREFIX=${ARCH_NAME}-linux-android
CURRENT_DIR=`pwd`
BUILD_OUTPUT_DIR="${CURRENT_DIR}/../android/arm64"
if [ ${ARCH_NAME} == "x86_64" ]; thenTOOLCHAIN_ARCH=${ARCH_NAME}FLATFORM=${NDK_ROOT}/platforms/android-28/arch-x86_64BUILD_OUTPUT_DIR="${CURRENT_DIR}/../android/x86_64"
fi
echo "BUILD_OUTPUT_DIR=${BUILD_OUTPUT_DIR}"
if [ ! -d ${BUILD_OUTPUT_DIR} ]; thenmkdir -p ${BUILD_OUTPUT_DIR}
fi
echo "TOOLCHAIN_RCH=${TOOLCHAIN_ARCH}"
PREBUILT=${NDK_ROOT}/toolchains/${TOOLCHAIN_ARCH}-4.9/prebuilt/darwin-x86_64/binFF_CFLAGS="-O3 -Wall -fpic -pipe -std=c11 -ffast-math -fstrict-aliasing -Werror=strict-aliasing -Wno-psabi -Wa,--noexecstack -Wpointer-sign -Wparentheses -DANDROID -DDEBUG"
FF_CXXFLAGS="-D__thumb__ -fexceptions -frtti"CC=${PREBUILT}/${COMPILER_PREFIX}-gcc
FFMPEG_ROOT_DIR=${BUILD_OUTPUT_DIR}
FFMPEG_INCLUDE_DIR=${FFMPEG_ROOT_DIR}/include
FFMPEG_LIB_DIR=${FFMPEG_ROOT_DIR}/lib
CONFIG_H_DIR=${CURRENT_DIR}/../
FFMPEG_LIBS="-lavutil -lavformat -lavcodec -lavfilter -lavdevice -lswresample -lswscale"
ANDROID_MEDIA_LIBS="-lcamera2ndk -lmediandk"function build_for() {echo "compile ffmpeg..."FFMPEG_SRC="cmdutils.c ffmpeg_dec.c ffmpeg_demux.c ffmpeg_enc.c ffmpeg_filter.c \ffmpeg_hw.c ffmpeg_mux_init.c ffmpeg_mux.c ffmpeg_opt.c ffmpeg.c \objpool.c opt_common.c \sync_queue.c thread_queue.c"${CC} --sysroot=${FLATFORM} ${FF_CFLAGS} -shared ${FFMPEG_SRC} -o ${FFMPEG_LIB_DIR}/libffmpegc.so \-I${FFMPEG_INCLUDE_DIR} -I${CONFIG_H_DIR} -I${SYSROOT_INCLUDE_PATH} \-L${FFMPEG_LIB_DIR} -L${PLATFORM}/usr/lib \${FFMPEG_LIBS} ${ANDROID_MEDIA_LIBS}
}build_forif [ $? -eq 0 ]; thenecho "compile ffmpegc succ"
elseecho "compile ffmpegc fail"
fi

? ? 按照以上腳本編譯,可順利完成arm64和x86_64的編譯工作。最后的輸出目錄在:

  • arm64和_x8664平臺輸出均與對應(yīng)平臺ffmpeg庫路徑一致;?

? ? 提示:此處編譯ffmpeg.c為so的時(shí)候,需要靜態(tài)鏈接ffmpeg的各.a庫。?

? ? 然后,使用工具可以看到libffmpegc.so相關(guān)so的依賴庫信息:

Dynamic section at offset 0x1c62808 contains 28 entries:Tag        Type                         Name/Value0x0000000000000001 (NEEDED)             Shared library: [libcamera2ndk.so]0x0000000000000001 (NEEDED)             Shared library: [libmediandk.so]0x0000000000000001 (NEEDED)             Shared library: [libc.so]0x0000000000000001 (NEEDED)             Shared library: [libdl.so]0x0000000000000001 (NEEDED)             Shared library: [libm.so]0x0000000000000001 (NEEDED)             Shared library: [libz.so]0x0000000000000001 (NEEDED)             Shared library: [liblog.so]0x000000000000001a (FINI_ARRAY)         0x1b703780x000000000000001c (FINI_ARRAYSZ)       8 (bytes)0x0000000000000004 (HASH)               0x1c80x0000000000000005 (STRTAB)             0x323100x0000000000000006 (SYMTAB)             0xab300x000000000000000a (STRSZ)              137735 (bytes)0x000000000000000b (SYMENT)             24 (bytes)0x0000000000000003 (PLTGOT)             0x1c72a080x0000000000000002 (PLTRELSZ)           73680 (bytes)0x0000000000000014 (PLTREL)             RELA0x0000000000000017 (JMPREL)             0x163c500x0000000000000007 (RELA)               0x572100x0000000000000008 (RELASZ)             1100352 (bytes)0x0000000000000009 (RELAENT)            24 (bytes)0x0000000000000018 (BIND_NOW)0x000000006ffffffb (FLAGS_1)            Flags: NOW0x000000006ffffffe (VERNEED)            0x571c00x000000006fffffff (VERNEEDNUM)         20x000000006ffffff0 (VERSYM)             0x53d180x000000006ffffff9 (RELACOUNT)          403180x0000000000000000 (NULL)               0x0

? ? 所用工具及其執(zhí)行命令如下:

~/Library/Android/sdk/ndk/21.3.6528147/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-readelf libffmpegc.so -d
http://www.risenshineclean.com/news/60475.html

相關(guān)文章:

  • 網(wǎng)站開發(fā) 國際網(wǎng)站國外黃岡網(wǎng)站推廣軟件
  • 北京專業(yè)建設(shè)網(wǎng)站價(jià)格排名第一的手機(jī)清理軟件
  • 網(wǎng)站模板怎么建站新東方在線教育平臺官網(wǎng)
  • 肅寧做網(wǎng)站湖南優(yōu)化電商服務(wù)有限公司
  • 上海速恒網(wǎng)絡(luò)科技有限公司天津seo優(yōu)化公司
  • 英文b2c網(wǎng)站營銷技巧有哪些
  • 做網(wǎng)站公司哪個(gè)好百度免費(fèi)推廣平臺
  • 天津做網(wǎng)站就到徽信xiala5如何制作網(wǎng)站二維碼
  • 煙臺高端品牌網(wǎng)站建設(shè)百度搜索使用方法
  • 壽光網(wǎng)站建設(shè)品牌網(wǎng)站建設(shè)方案
  • wordpress手機(jī)端響應(yīng)慢seo上排名
  • 安康做企業(yè)網(wǎng)站的2021百度模擬點(diǎn)擊工具
  • 公司想建立一個(gè)網(wǎng)站嗎app推廣好做嗎
  • 免費(fèi)外貿(mào)網(wǎng)站國際新聞最新消息2022
  • 建設(shè)網(wǎng)站需要先構(gòu)建好模型聊城seo整站優(yōu)化報(bào)價(jià)
  • 網(wǎng)站怎么做微博鏈接網(wǎng)絡(luò)營銷的8個(gè)基本職能
  • 做觸屏網(wǎng)站重慶seo教程博客
  • 車商城網(wǎng)站建設(shè)新媒體運(yùn)營培訓(xùn)課程
  • mail263企業(yè)郵箱登錄入口鄭州網(wǎng)站優(yōu)化外包
  • 新媒體公司網(wǎng)站怎么做鞍山seo公司
  • 做個(gè)網(wǎng)站多少錢怎么接廣告廣告代運(yùn)營公司
  • 如何擁有自己的專屬域名滁州網(wǎng)站seo
  • 安康做網(wǎng)站的公司電話小紅書搜索指數(shù)
  • 網(wǎng)站請人做要多少錢新聞稿營銷
  • 廣告型網(wǎng)站怎么做的如何查詢網(wǎng)站收錄情況
  • 萊蕪招聘的網(wǎng)站app開發(fā)公司有哪些
  • 網(wǎng)站備案好處如何進(jìn)行seo
  • 網(wǎng)站色彩運(yùn)用cba排名最新排名
  • 東莞網(wǎng)頁制作免費(fèi)網(wǎng)站制作如何在百度上發(fā)布廣告
  • 新時(shí)代政府網(wǎng)站建設(shè)網(wǎng)推什么平臺好用