国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android.bp 構(gòu)建 FFmpeg 庫:從搭建編譯框架到處理編譯錯(cuò)誤的全過程

這篇具有很好參考價(jià)值的文章主要介紹了Android.bp 構(gòu)建 FFmpeg 庫:從搭建編譯框架到處理編譯錯(cuò)誤的全過程。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

前言

本文基于 FFmpeg 5.1.4 版本,詳細(xì)講述了使用 Android.bp 構(gòu)建 FFmpeg 庫的過程,旨在簡化 Android 源碼中 FFmpeg 庫的構(gòu)建以及集成過程。

  • 構(gòu)建過程需使用 NDK 工具輔助,請(qǐng)參考該專欄之前文章:使用 NDK 編譯 FFmpeg
  • github 倉庫:FFmpegDroidBuilder

搭建編譯框架

以編譯 libavutil、libavcodec、libavformat、libswresample、libswscale 模塊為例,在 FFmpeg 源碼根目錄下,創(chuàng)建以下 7 個(gè)文件:
Android.bp
 ├── compat_files.bp
 ├── avutil_files.bp
 ├── avcodec_files.bp
 ├── avformat_files.bp
 ├── swresample_files.bp
 └── swscale_files.bp

Android.bp 作為編譯入口,定義整體編譯架構(gòu),其余 6 個(gè) bp 文件作為 Android.bp 的依賴項(xiàng),聲明 FFmpeg 各模塊需編譯的源文件:

  • compat_files.bp 聲明 compat 目錄下需編譯的源碼文件,該目錄中存在很多為兼容各種平臺(tái)而創(chuàng)建的頭文件
  • 其他 bp 文件則分別聲明 libavutil、libavcodec、libavformat、libswresample、libswscale 目錄下需編譯的源文件

1. 創(chuàng)建 Android.bp 文件

首先,搭建整體編譯框架,后續(xù)章節(jié)再補(bǔ)充具體編譯參數(shù)。

// 依賴項(xiàng)
build = [
    "compat_files.bp",
    "avutil_files.bp",
    "avcodec_files.bp",
    "avformat_files.bp",
    "swresample_files.bp",
    "swscale_files.bp",
]

// 編譯選項(xiàng)默認(rèn)值
cc_defaults {
    name: "libFFmpeg_defaults",
    
    cflags: [
    ],
    
    arch: {
        arm: {
            cflags: [
            ],
            asflags: [
            ],
        },
        arm64: {
            cflags: [
            ],
            asflags: [
            ],
        },
    },
}

cc_library {
    name: "libFFmpeg",
    
    defaults: ["libFFmpeg_defaults"],
    
    local_include_dirs: [
    ],
    
    vendor_available: true,
    
    export_include_dirs: [
        ".",
    ],
    
    // android 10 平臺(tái)需設(shè)置該選項(xiàng)為 false 以停用 XOM
    // xom: false,
    
    // 默認(rèn)同時(shí)編譯 32 和 64 位的代碼。若放開下列注釋,則只編譯 64 位的代碼
    // compile_multilib: "64",
    arch: {
        arm: {
            instruction_set: "arm",
            srcs: [
                ":avutil-src-arm",
                ":avcodec-src-arm",
                ":swresample-src-arm",
                ":swrscale-src-arm",
            ],
            // ARM 架構(gòu)編譯選項(xiàng)
            cflags: [
            ],
            // ARM 架構(gòu)鏈接選項(xiàng)
            ldflags: [
            ],
            // ARM 架構(gòu)匯編選項(xiàng)
            asflags: [
            ]
        },
        arm64: {
            srcs: [
                ":avutil-src-arm64",
                ":avcodec-src-arm64",
                ":swresample-src-arm64",
                ":swrscale-src-arm64",
            ],
            // ARM64 架構(gòu)編譯選項(xiàng)
            cflags: [
            ],
            // ARM64 架構(gòu)鏈接選項(xiàng)
            ldflags: [
            ],
            // ARM64 架構(gòu)匯編選項(xiàng)
            asflags: [
            ],
        },
    },
    srcs: [
        ":compat-src",
        ":avutil-src-common",
        ":avcodec-src-common",
        ":swresample-src-common",
        ":swrscale-src-common",
        ":avformat-src",
    ],
    shared_libs: [
    ],
    static_libs: [
    ],
    // 全局編譯選項(xiàng)
    cflags: [
    ],
    // 全局鏈接選項(xiàng)
    ldflags: [
    ],
    // 全局匯編選項(xiàng)
    asflags: [
    ],
}
  • XOM 官當(dāng)說明:AArch64 二進(jìn)制文件的只執(zhí)行內(nèi)存 (XOM)

  • Android.bp 中定義的模塊間依賴關(guān)系如下:
    Android.bp
     └── libFFmpeg
        ├── libFFmpeg_defaults
        │
        ├── compat-src
        │
        ├── avutil-src-common
        ├── avutil-src-arm
        ├── avutil-src-arm64
        │
        ├── avcodec-src-common
        ├── avcodec-src-arm
        ├── avcodec-src-arm64
        │
        ├── swresample-src-common
        ├── swresample-src-arm
        ├── swresample-src-arm64
        │
        ├── swrscale-src-common
        ├── swrscale-src-arm
        ├── swrscale-src-arm64
        │
        └── avformat-src

2. 創(chuàng)建 avutil_files.bp

聲明 avutil-src-arm、avutil-src-arm64、avutil-src-common 模塊,后續(xù)章節(jié)再補(bǔ)充這些模塊所依賴的源文件。

filegroup {
  name: "avutil-src-arm",
  // ARM 架構(gòu)代碼
  srcs: [
  ],
}

filegroup {
  name: "avutil-src-arm64",
  // ARM64 架構(gòu)代碼
  srcs: [
  ],
}

filegroup {
  name: "avutil-src-common",
  // 多平臺(tái)共用代碼
  srcs: [
  ],
}

3. 創(chuàng)建其他 bp 文件

參考 avutil_files.bp,創(chuàng)建 compat_files.bp、avcodec_files.bp、avformat_files.bp、swresample_files.bp、swscale_files.bp 文件,并添加相應(yīng)的模塊聲明。

  • compat_files.bp
filegroup {
  name: "compat-src",
  // 無需區(qū)分 ARM 和 ARM64 架構(gòu)
  srcs: [
  ],
}
  • avcodec_files.bp
filegroup {
  name: "avcodec-src-arm",
  // ARM 架構(gòu)代碼
  srcs: [
  ],
}

filegroup {
  name: "avcodec-src-arm64",
  // ARM64 架構(gòu)代碼
  srcs: [
  ],
}

filegroup {
  name: "avcodec-src-common",
  // 多平臺(tái)共用代碼
  srcs: [
  ],
}
  • avformat_files.bp
filegroup {
  name: "avformat-src",
  srcs: [
  ]
}
  • swresample_files.bp
filegroup {
  name: "swresample-src-arm",
  // ARM 架構(gòu)代碼
  srcs: [
  ],
}
filegroup {
  name: "swresample-src-arm64",
  // ARM64 架構(gòu)代碼
  srcs: [
  ],
}
filegroup {
  name: "swresample-src-common",
  // 多平臺(tái)共用代碼
  srcs: [
  ],
}
  • swscale_files.bp
filegroup {
  name: "swrscale-src-arm",
  // ARM 架構(gòu)代碼
  srcs: [
  ],
}
filegroup {
  name: "swrscale-src-arm64",
  // ARM64 架構(gòu)代碼
  srcs: [
  ],
}
filegroup {
  name: "swrscale-src-common",
  // 多平臺(tái)共用代碼
  srcs: [
  ],
}

armv8-a 編譯參數(shù)

1. configure 源代碼

cpu 架構(gòu)配置為 armv8-a,參考專欄之前的文章:使用 NDK 編譯 FFmpeg。

2. 查看編譯參數(shù)

configure 指令執(zhí)行完成后,在生成的 ffbuild/config.mak 文件中,可查看編譯過程各階段所需參數(shù):

CPPFLAGS:預(yù)處理標(biāo)志
CFLAGS:C編譯標(biāo)志
CXXFLAGS:C++編譯標(biāo)志
ASFLAGS:匯編標(biāo)志
LDFLAGS:鏈接標(biāo)志
LDEXEFLAGS:用于鏈接可執(zhí)行文件的標(biāo)志

3. 添加編譯參數(shù)

前一小節(jié) CPPFLAGS、CFLAGS、CXXFLAGS 中的 flags 可分為以下兩類:

  • cpu 特定 flags:如 -mfpu=neon、-march=armv8-a
  • 多平臺(tái)共用 flags:如 -fPIC、-fPIE

FFmpeg 源碼根目錄下,執(zhí)行 vim find_flags.sh 編輯腳本文件,用于查找 ffbuild/config.mak 中的編譯參數(shù):

#!/bin/bash

#if [ "$#" -ne 1 ]; then
#    echo "Usage: $0 config_file"
#    exit 1
#fi

# 獲取配置文件
#config_file=$1
config_file=ffbuild/config.mak

# 定義需要查找的變量
vars=("CPPFLAGS" "CFLAGS" "CXXFLAGS" "ASFLAGS" "LDFLAGS")

# 定義需打印的 cpu 特定參數(shù)
cpu_specific_prefixes=("-mfpu" "-march")

# 定義需要過濾的標(biāo)志
filter_prefixes=("CPPFLAGS" "CFLAGS" "CXXFLAGS" "ASFLAGS" "LDFLAGS" "--sysroot" "-mfpu" "-march" "-Wl,-rpath-link")

print_flags() {
    # 將參數(shù)轉(zhuǎn)換為數(shù)組
    local -a local_filter_prefixes="($(echo "$1"))"
	
    local local_should_print=$2
	
    local var_prefix=$3

    for var in "${vars[@]}"; do	
        flags=$(grep "^$var" "$config_file")

        # 分割參數(shù)
        IFS=' ' read -r -a flagarray <<< "$flags"

        # 過濾重復(fù)參數(shù)參數(shù)
        flagarray=($(printf "%s\n" "${flagarray[@]}" | sort -u))

        echo "$3_$var: {"

        for flag in "${flagarray[@]}"; do
            # 檢查參數(shù)是否需要過濾
            if [ "$local_should_print" = true ] ; then
                should_print=false
            else
                should_print=true
            fi

            for prefix in "${local_filter_prefixes[@]}"; do
                if [[ "$flag" == $prefix* ]]; then
                    should_print=$local_should_print
                fi
            done

            # 如果不需要過濾,則打印
            if $should_print ; then
                echo "    \"$flag\","
            fi
        done

        echo "}"
    done
}

# 將數(shù)組轉(zhuǎn)換為字符串并傳遞給函數(shù)
print_flags "${filter_prefixes[*]}" false common
echo -e "\n"
print_flags "${cpu_specific_prefixes[*]}" true cpu_specific

執(zhí)行 ./find_flags.sh 指令,查找編譯參數(shù):

common_CPPFLAGS: {
    "-D_FILE_OFFSET_BITS=64",
    "-D_ISOC99_SOURCE",
    "-D_LARGEFILE_SOURCE",
    "-DPIC",
    "-Dstrtod=avpriv_strtod",
    "-DZLIB_CONST",
}
common_CFLAGS: {
    "-fno-math-errno",
    "-fno-signed-zeros",
    "-fomit-frame-pointer",
    "-fpic",
    "-fPIC",
    "-fPIE",
    "-g",
    "-mno-stackrealign",
    "-mstack-alignment=16",
    "-Os",
    "-Oz",
    "-pthread",
    "-Qunused-arguments",
    "-std=c11",
    "-Wall",
    "-Wdeclaration-after-statement",
    "-Wdisabled-optimization",
    "-Wempty-body",
    "-Werror=implicit-function-declaration",
    "-Werror=missing-prototypes",
    "-Werror=return-type",
    "-Wmissing-prototypes",
    "-Wno-bool-operation",
    "-Wno-char-subscripts",
    "-Wno-format-zero-length",
    "-Wno-parentheses",
    "-Wno-pointer-sign",
    "-Wno-switch",
    "-Wno-unused-const-variable",
    "-Wpointer-arith",
    "-Wredundant-decls",
    "-Wstrict-prototypes",
    "-Wtype-limits",
    "-Wundef",
    "-Wwrite-strings",
}
common_CXXFLAGS: {
    "-D__STDC_CONSTANT_MACROS",
    "-std=c++11",
}
common_ASFLAGS: {
    "-fpic",
    "-fPIC",
    "-g",
    "-mno-stackrealign",
    "-Os",
    "-Qunused-arguments",
}
common_LDFLAGS: {
    "-Qunused-arguments",
    "-Wl,--as-needed",
    "-Wl,--warn-common",
    "-Wl,-z,noexecstack",
}


cpu_specific_CPPFLAGS: {
}
cpu_specific_CFLAGS: {
    "-march=armv8-a",
    "-mfpu=neon",
}
cpu_specific_CXXFLAGS: {
}
cpu_specific_ASFLAGS: {
    "-march=armv8-a",
    "-mfpu=neon",
}
cpu_specific_LDFLAGS: {
    "-march=armv8-a",
}

將上述 cpu_specific_CPPFLAGS、cpu_specific_CFLAGS、cpu_specific_CXXFLAGS 添加到 Android.bp libFFmpeg 模塊 arm64 cflags 中,common_CPPFLAGS、common_CFLAGS、common_CXXFLAGS 添加到全局編譯選項(xiàng)中:

cc_library {
    name: "libFFmpeg",
    
    ... 省略部分代碼
    
    arch: {
        arm: {
            ... 省略部分代碼
        },
        
        arm64: {
            srcs: [
                ":avutil-src-arm64",
                ":avcodec-src-arm64",
                ":swresample-src-arm64",
                ":swrscale-src-arm64",
            ],
            
            // ARM64 架構(gòu)編譯選項(xiàng)
            cflags: [
                "-mfpu=neon",
                "-march=armv8-a",
            ],
            
            // ARM64 架構(gòu)鏈接選項(xiàng)
            ldflags: [
            ],
            
            // ARM64 架構(gòu)匯編選項(xiàng)
            asflags: [
            ],
        },
    },
    
    ... 省略部分代碼
    
    srcs: [
        ":compat-src",
        ":avutil-src-common",
        ":avcodec-src-common",
        ":swresample-src-common",
        ":swrscale-src-common",
        ":avformat-src",
    ],
    
    // 全局編譯選項(xiàng)
    cflags: [
        // CPPFLAGS
        "-D_FILE_OFFSET_BITS=64",
        "-D_ISOC99_SOURCE",
        "-D_LARGEFILE_SOURCE",
        "-DPIC",
        "-Dstrtod=avpriv_strtod",
        "-DZLIB_CONST",
        
        // CFLAGS
        "-fno-math-errno",
        "-fno-signed-zeros",
        "-fomit-frame-pointer",
        "-fpic",
        "-fPIC",
        "-fPIE",
        "-g",
        "-mno-stackrealign",
        "-mstack-alignment=16",
        "-Os",
        "-Oz",
        "-pthread",
        "-Qunused-arguments",
        "-std=c11",
        "-Wall",
        "-Wdeclaration-after-statement",
        "-Wdisabled-optimization",
        "-Wempty-body",
        "-Werror=implicit-function-declaration",
        "-Werror=missing-prototypes",
        "-Werror=return-type",
        "-Wmissing-prototypes",
        "-Wno-bool-operation",
        "-Wno-char-subscripts",
        "-Wno-format-zero-length",
        "-Wno-parentheses",
        "-Wno-pointer-sign",
        "-Wno-switch",
        "-Wno-unused-const-variable",
        "-Wpointer-arith",
        "-Wredundant-decls",
        "-Wstrict-prototypes",
        "-Wtype-limits",
        "-Wundef",
        "-Wwrite-strings",
        
        // CXXFLAGS
        "-D__STDC_CONSTANT_MACROS",
        "-std=c++11",
    ],
    
    // 全局鏈接選項(xiàng)
    ldflags: [
    ],
    
    // 全局匯編選項(xiàng)
    asflags: [
    ],
}

4. 添加匯編參數(shù)

上一章節(jié)編譯參數(shù)中的匯編參數(shù),cpu_specific_ASFLAGS 添加到 Android.bp libFFmpeg 模塊 arm64 asflags 中,common_ASFLAGS 添加到全局匯編選項(xiàng)中:

cc_library {
    name: "libFFmpeg",
    
    ... 省略部分代碼
    
    arch: {
        arm: {
            ... 省略部分代碼
        },
        
        arm64: {
            ... 省略部分代碼
            
            // ARM64 架構(gòu)鏈接選項(xiàng)
            ldflags: [
            ],
            
            // ARM64 架構(gòu)匯編選項(xiàng)
            asflags: [
                "-march=armv8-a",
                "-mfpu=neon",
            ],
        },
    },
    
    ... 省略部分代碼
    
    // 全局鏈接選項(xiàng)
    ldflags: [
    ],
    
    // 全局匯編選項(xiàng)
    asflags: [
        "-fpic",
        "-fPIC",
        "-g",
        "-mno-stackrealign",
        "-Os",
        "-Qunused-arguments",
    ],
}

5. 添加鏈接參數(shù)

參考前面章節(jié)內(nèi)容,過程不在贅述,部分代碼如下:

cc_library {
    name: "libFFmpeg",
    
    ... 省略部分代碼
    
    arch: {
        arm: {
            ... 省略部分代碼
        },
        
        arm64: {
            ... 省略部分代碼
            
            // ARM64 架構(gòu)匯編選項(xiàng)
            ldflags: [
                "-march=armv8-a",
            ],
            
            ... 省略部分代碼
        },
    },
    
    ... 省略部分代碼
    
    // 全局鏈接選項(xiàng)
    ldflags: [
        "-Qunused-arguments",
        "-Wl,--as-needed",
        "-Wl,--warn-common",
        "-Wl,-z,noexecstack",
    ],
    
    ... 省略部分代碼
}

6. HAVE_AV_CONFIG_H 參數(shù)

FFmpeg 源碼執(zhí)行完 configure 指定后,根目錄下會(huì)生成一個(gè) config.h 文件。該文件包含了編譯 FFmpeg 時(shí)配置的所有配置選項(xiàng)。config.h 文件中的每個(gè)宏都代表一個(gè)特定的配置選項(xiàng),例如是否啟用某個(gè)庫(如 libavcodec、libavformat 等),是否啟用某個(gè)功能(如硬件加速),以及一些特定的編譯選項(xiàng)(如優(yōu)化級(jí)別、調(diào)試選項(xiàng)等)。
FFmpeg 源碼編譯時(shí),會(huì)根據(jù) HAVE_AV_CONFIG_H 宏來確認(rèn)是否引用 config.h 文件,如 libavutil/bswap.h 中的代碼:

#ifdef HAVE_AV_CONFIG_H

#include "config.h"

#endif

因此我們需要將 -DHAVE_AV_CONFIG_H 添加到編譯選項(xiàng)中。在 Android.bp 文件中,我們將該選項(xiàng)添加到 libFFmpeg_defaults 模塊:

// 編譯選項(xiàng)默認(rèn)值
cc_defaults {
    name: "libFFmpeg_defaults",
	
    cflags: [
         "-DHAVE_AV_CONFIG_H",
    ],

    ... 省略部分代碼
}

armv7-a 編譯參數(shù)

1. 查看編譯參數(shù)

參考前面章節(jié) armv8-a 編譯參數(shù)查找流程:

  1. configure FFmpeg 源代碼,指定 cpu 架構(gòu)為 armv8-a
  2. 使用 find_flags.sh 腳本查找編譯參數(shù)

首先,比較 armv7-a 和 armv8-a 編譯參數(shù)差異:

  • 編譯參數(shù)差異
    Android.bp 構(gòu)建 FFmpeg 庫:從搭建編譯框架到處理編譯錯(cuò)誤的全過程,FFmpeg 在 Android 上的探索與實(shí)踐,ffmpeg,android
  • 匯編參數(shù)差異
    Android.bp 構(gòu)建 FFmpeg 庫:從搭建編譯框架到處理編譯錯(cuò)誤的全過程,FFmpeg 在 Android 上的探索與實(shí)踐,ffmpeg,android
  • cpu 特定參數(shù)差異
    Android.bp 構(gòu)建 FFmpeg 庫:從搭建編譯框架到處理編譯錯(cuò)誤的全過程,FFmpeg 在 Android 上的探索與實(shí)踐,ffmpeg,android

2. 添加編譯、匯編、鏈接參數(shù)

根據(jù)上一章節(jié) armv7-a 和 armv8-a 編譯參數(shù)差異,兩種 cpu 架構(gòu)絕大部分編譯參數(shù)可復(fù)用,我們僅需將上述 armv7-a 特定參數(shù)添加到 Android.bp arm 架構(gòu)特定編譯選項(xiàng)中:

cc_library {
    name: "libFFmpeg",
    
    ... 省略部分代碼
    
    arch: {
        arm: {
            instruction_set: "arm",

            ... 省略部分代碼

            // ARM 架構(gòu)編譯選項(xiàng)
            cflags: [
                "-marm",
                "-mfloat-abi=softfp",
                "-march=armv7-a",
                "-mfpu=neon",
            ],

            // ARM 架構(gòu)鏈接選項(xiàng)
            ldflags: [
                "-march=armv7-a",
            ],

            // ARM 架構(gòu)匯編選項(xiàng)
            asflags: [
                "-mfloat-abi=softfp",
                "-march=armv7-a",
                "-mfpu=neon",
            ]
        },
    },
    
    ... 省略部分代碼
}

添加 armv8-a 源文件

首先,我們需要使用 NDK 對(duì)源碼進(jìn)行編譯,參考專欄之前的文章:使用 NDK 編譯 FFmpeg 。然后根據(jù)編譯后的 .o 目標(biāo)文件,從源碼中匹配對(duì)應(yīng)的源文件(.c 或 .S 文件)。

1. 查找需編譯的源文件

配置 cpu 架構(gòu)為 armv8-a,并編譯 FFmpeg 源代碼。然后,在 FFmpeg 源碼目錄下,執(zhí)行 vim find_srcs.sh,編輯腳本文件如下:

#!/bin/bash

# 打印幫助提示
if [ "$#" -eq 0 ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
    echo "Usage: $0 dir1 [dir2 ...]"
    echo "Example: $0 libavutil libavutil/aarch64"
    exit 0
fi

# 定義查找源文件的函數(shù)
findSrc() {
    local dir=$1
    local f=`ls $dir/*.o 2>/dev/null`

	echo "$dir: {"
    
	for d in $f
    do
        local s=${d//.o/.c}
        if [ -f "$s" ]; then
            echo "    \"${d//.o/.c}\","
        else
            echo "    \"${d//.o/.S}\","
        fi
    done
	
	echo "}"
}

# 遍歷每個(gè)參數(shù)并查找源文件
for dir in "$@"; do
    echo "Source files in $dir:"
    findSrc $dir
done

在源碼目錄下執(zhí)行該腳本,查找需編譯的源文件,示例如下:

  • 執(zhí)行 ./find_srcs.sh compat,查找 compat 目錄
Source files in compat:
compat: {
    "compat/strtod.c",
}
  • 執(zhí)行 ./find_srcs.sh libavutil libavutil/aarch64,查找 libavutil、libavutil/aarch64 目錄
Source files in libavutil:
libavutil: {
    "libavutil/adler32.c",
    "libavutil/aes_ctr.c",
    "libavutil/aes.c",
    "libavutil/audio_fifo.c",
    "libavutil/avsscanf.c",
    "libavutil/avstring.c",
    "libavutil/base64.c",
    "libavutil/blowfish.c",
    "libavutil/bprint.c",
    "libavutil/buffer.c",
    "libavutil/camellia.c",
    "libavutil/cast5.c",
    "libavutil/channel_layout.c",
    "libavutil/color_utils.c",
    "libavutil/cpu.c",
    "libavutil/crc.c",
    "libavutil/csp.c",
    "libavutil/des.c",
    "libavutil/detection_bbox.c",
    "libavutil/dict.c",
    "libavutil/display.c",
    "libavutil/dovi_meta.c",
    "libavutil/downmix_info.c",
    "libavutil/encryption_info.c",
    "libavutil/error.c",
    "libavutil/eval.c",
    "libavutil/fifo.c",
    "libavutil/file.c",
    "libavutil/file_open.c",
    "libavutil/film_grain_params.c",
    "libavutil/fixed_dsp.c",
    "libavutil/float_dsp.c",
    "libavutil/frame.c",
    "libavutil/hash.c",
    "libavutil/hdr_dynamic_metadata.c",
    "libavutil/hdr_dynamic_vivid_metadata.c",
    "libavutil/hmac.c",
    "libavutil/hwcontext.c",
    "libavutil/hwcontext_stub.c",
    "libavutil/imgutils.c",
    "libavutil/integer.c",
    "libavutil/intmath.c",
    "libavutil/lfg.c",
    "libavutil/lls.c",
    "libavutil/log2_tab.c",
    "libavutil/log.c",
    "libavutil/lzo.c",
    "libavutil/mastering_display_metadata.c",
    "libavutil/mathematics.c",
    "libavutil/md5.c",
    "libavutil/mem.c",
    "libavutil/murmur3.c",
    "libavutil/opt.c",
    "libavutil/parseutils.c",
    "libavutil/pixdesc.c",
    "libavutil/pixelutils.c",
    "libavutil/random_seed.c",
    "libavutil/rational.c",
    "libavutil/rc4.c",
    "libavutil/reverse.c",
    "libavutil/ripemd.c",
    "libavutil/samplefmt.c",
    "libavutil/sha512.c",
    "libavutil/sha.c",
    "libavutil/slicethread.c",
    "libavutil/spherical.c",
    "libavutil/stereo3d.c",
    "libavutil/tea.c",
    "libavutil/threadmessage.c",
    "libavutil/timecode.c",
    "libavutil/time.c",
    "libavutil/tree.c",
    "libavutil/twofish.c",
    "libavutil/tx_double.c",
    "libavutil/tx_float.c",
    "libavutil/tx_int32.c",
    "libavutil/tx.c",
    "libavutil/utils.c",
    "libavutil/uuid.c",
    "libavutil/version.c",
    "libavutil/video_enc_params.c",
    "libavutil/xga_font_data.c",
    "libavutil/xtea.c",
}
Source files in libavutil/aarch64:
libavutil/aarch64: {
    "libavutil/aarch64/cpu.c",
    "libavutil/aarch64/float_dsp_init.c",
    "libavutil/aarch64/float_dsp_neon.S",
}

2. 添加 compat 源文件

編輯 compat_files.bp 文件,添加上一章節(jié)中查找到的 compat 源文件:

filegroup {
  name: "compat-src",
  srcs: [
	"compat/strtod.c",
  ],
}

3. 添加 libavutil 源文件

編輯 avutil_files.bp 文件,添加上一章節(jié)中查找到的 libavutil 源文件。libavutil/aarch64、libavutil 目錄下源文件分別添加到 avutil-src-arm64、avutil-src-common 目錄下:

filegroup {
  name: "avutil-src-arm",

  // ARM 架構(gòu)代碼
  srcs: [
  ],
}

filegroup {
  name: "avutil-src-arm64",

  // ARM64 架構(gòu)代碼
  srcs: [
	"libavutil/aarch64/cpu.c",
    "libavutil/aarch64/float_dsp_init.c",
    "libavutil/aarch64/float_dsp_neon.S",
  ],
}

filegroup {
  name: "avutil-src-common",

  // 多平臺(tái)共用代碼
  srcs: [
    "libavutil/adler32.c",
    "libavutil/aes_ctr.c",
    "libavutil/aes.c",
    "libavutil/audio_fifo.c",
    "libavutil/avsscanf.c",
    "libavutil/avstring.c",
    "libavutil/base64.c",
    "libavutil/blowfish.c",
    "libavutil/bprint.c",
    "libavutil/buffer.c",
    "libavutil/camellia.c",
    "libavutil/cast5.c",
    "libavutil/channel_layout.c",
    "libavutil/color_utils.c",
    "libavutil/cpu.c",
    "libavutil/crc.c",
    "libavutil/csp.c",
    "libavutil/des.c",
    "libavutil/detection_bbox.c",
    "libavutil/dict.c",
    "libavutil/display.c",
    "libavutil/dovi_meta.c",
    "libavutil/downmix_info.c",
    "libavutil/encryption_info.c",
    "libavutil/error.c",
    "libavutil/eval.c",
    "libavutil/fifo.c",
    "libavutil/file.c",
    "libavutil/file_open.c",
    "libavutil/film_grain_params.c",
    "libavutil/fixed_dsp.c",
    "libavutil/float_dsp.c",
    "libavutil/frame.c",
    "libavutil/hash.c",
    "libavutil/hdr_dynamic_metadata.c",
    "libavutil/hdr_dynamic_vivid_metadata.c",
    "libavutil/hmac.c",
    "libavutil/hwcontext.c",
    "libavutil/hwcontext_stub.c",
    "libavutil/imgutils.c",
    "libavutil/integer.c",
    "libavutil/intmath.c",
    "libavutil/lfg.c",
    "libavutil/lls.c",
    "libavutil/log2_tab.c",
    "libavutil/log.c",
    "libavutil/lzo.c",
    "libavutil/mastering_display_metadata.c",
    "libavutil/mathematics.c",
    "libavutil/md5.c",
    "libavutil/mem.c",
    "libavutil/murmur3.c",
    "libavutil/opt.c",
    "libavutil/parseutils.c",
    "libavutil/pixdesc.c",
    "libavutil/pixelutils.c",
    "libavutil/random_seed.c",
    "libavutil/rational.c",
    "libavutil/rc4.c",
    "libavutil/reverse.c",
    "libavutil/ripemd.c",
    "libavutil/samplefmt.c",
    "libavutil/sha512.c",
    "libavutil/sha.c",
    "libavutil/slicethread.c",
    "libavutil/spherical.c",
    "libavutil/stereo3d.c",
    "libavutil/tea.c",
    "libavutil/threadmessage.c",
    "libavutil/timecode.c",
    "libavutil/time.c",
    "libavutil/tree.c",
    "libavutil/twofish.c",
    "libavutil/tx_double.c",
    "libavutil/tx_float.c",
    "libavutil/tx_int32.c",
    "libavutil/tx.c",
    "libavutil/utils.c",
    "libavutil/uuid.c",
    "libavutil/version.c",
    "libavutil/video_enc_params.c",
    "libavutil/xga_font_data.c",
    "libavutil/xtea.c",
  ],
}

4. 添加其他模塊源文件

從 ffbuild/config.sh 中查看模塊間依賴關(guān)系:

swscale_deps="avutil"
avformat_deps="avcodec swresample avutil"
avcodec_deps="swresample avutil"
swresample_deps="avutil"

根據(jù)上述依賴關(guān)系依次添加 libswscale、libswresample、libavcodec、libavformat 模塊源文件(參考前面章節(jié)添加 compat 和 libavutil 源文件的過程,本章節(jié)不再贅述)。需要查找的目錄分為以下幾類,完整的 bp 文件請(qǐng)查找后續(xù)章節(jié)代碼倉庫:

  • libxxx/arm、libxxx/aarch64:平臺(tái)相關(guān)源文件路徑
  • libavxxx、libswxxx:公共源文件路徑
  • libxxx/neon:neon 相關(guān)源文件路徑

添加 armv7-a 源文件

除平臺(tái)相關(guān)代碼(位于 libxxx/arm,如 libavtuil/arm),其余代碼可與 armv8-a 復(fù)用。

1. 重新編寫 config.h 文件

為了同時(shí)兼容 armv8-a 和 armv7-a,編譯時(shí)需根據(jù) cpu 架構(gòu),引用不同的 config.h。因此,我們需要重新編寫 config.h 文件:

  • 配置 cpu 為 armv8-a,將 config.h 文件重命名為 config_arm64.h
  • 執(zhí)行 make clean ,配置 cpu 架構(gòu)為 armv7-a 并重新編譯 FFmpeg 源碼
  • 將生成的 config.h 重命名為 config_arm.h
  • 對(duì)比 config_arm64.h 和 config_arm.h,發(fā)現(xiàn) config.h 使用了 ARCH_AARCH64 和 ARCH_ARM 來區(qū)分不同的 cpu 架構(gòu)
    Android.bp 構(gòu)建 FFmpeg 庫:從搭建編譯框架到處理編譯錯(cuò)誤的全過程,FFmpeg 在 Android 上的探索與實(shí)踐,ffmpeg,android
  • 將 ARCH_AARCH64、ARCH_ARM 宏定義移到 Android.bp 的 libFFmpeg_defaults 模塊編譯和匯編選項(xiàng)中
// 編譯選項(xiàng)默認(rèn)值
cc_defaults {
    name: "libFFmpeg_defaults",
	
    cflags: [
        "-DHAVE_AV_CONFIG_H",
    ],

    arch: {
        arm: {
            cflags: [
                "-DARCH_ARM=1",
                "-DARCH_AARCH64=0",
            ],
            
            asflags: [
                "-DARCH_ARM=1",
                "-DARCH_AARCH64=0",
            ],
        },

        arm64: {
            cflags: [
                "-DARCH_AARCH64=1",
                "-DARCH_ARM=0",
            ],
            
            asflags: [
                "-DARCH_AARCH64=1",
                "-DARCH_ARM=0",
            ],
        },
    },
}
  • 重新創(chuàng)建和編輯 config.h 文件,根據(jù) cpu 架構(gòu)使用不同的配置
#if   ARCH_AARCH64
	#include "config_arm64.h"
#elif ARCH_ARM
	#include "config_arm.h"
#else
	#error "Unsupported CPU architecture"
#endif

2. 查找和添加源文件

參考前面 添加 armv8-a 源文件 章節(jié)的內(nèi)容,查找 libavutil/arm、libswscale/arm、libswresample/arm、libavcodec/arm 目錄下 armv7-a 平臺(tái)相關(guān)源文件,并添加到對(duì)應(yīng) bp 文件中,以 libavutil/arm 為例:

  • 執(zhí)行 ./find_srcs.sh libavutil/arm,查找 libavutil/arm 目錄下需編譯的源文件
Source files in libavutil/arm:
libavutil/arm: {
    "libavutil/arm/cpu.c",
    "libavutil/arm/float_dsp_init_arm.c",
    "libavutil/arm/float_dsp_init_neon.c",
    "libavutil/arm/float_dsp_init_vfp.c",
    "libavutil/arm/float_dsp_neon.S",
    "libavutil/arm/float_dsp_vfp.S",
}
  • 添加源文件到 avutil_files.bp 中
filegroup {
  name: "avutil-src-arm",

  // ARM 架構(gòu)代碼
  srcs: [
        "libavutil/arm/cpu.c",
        "libavutil/arm/float_dsp_init_arm.c",
        "libavutil/arm/float_dsp_init_neon.c",
        "libavutil/arm/float_dsp_init_vfp.c",
        "libavutil/arm/float_dsp_neon.S",
        "libavutil/arm/float_dsp_vfp.S",
  ],
}

參考上述流程,依次添加源文件到其余 bp 文件,過程不再贅述。完整的 bp 文件請(qǐng)查找后續(xù)章節(jié)代碼倉庫。

編譯錯(cuò)誤處理

  • 各模塊中存在一些相同的源文件。如 llibavutil/log2_tab.c,只能添加在 avutil_files.bp 中,否則會(huì)導(dǎo)致編譯錯(cuò)誤 ld.lld: error: duplicate symbol: ff_log2_tab。使用 cat ./libavformat/log2_tab.c 指令,可以發(fā)現(xiàn) libavformat 等模塊其實(shí)是引用了 llibavutil 目錄中的 log2_tab.c 文件, #include "libavutil/log2_tab.c"
./libavformat/log2_tab.c
./libavutil/log2_tab.c
./libavcodec/log2_tab.c
./libswscale/log2_tab.c
./libswresample/log2_tab.c
./libavfilter/log2_tab.c

類似的源文件還有
libavutil/reverse.c
libavcodec/mpegaudiotabs.c
libavcodec/to_upper4.c
libavcodec/mpeg4audio_sample_rates.c
libavcodec/jpegtables.c
libavcodec/ac3_channel_layout_tab.c
libavcodec/dca_sample_rate_tab.c
libavcodec/golomb.c(在 libavformat 中被 libavformat/golomb_tab.c 引用)

  • 添加 -Wl,-Bsymbolic 到全局 ldflags 中處理以下類型的鏈接錯(cuò)誤,詳細(xì)說明請(qǐng)查閱最后章節(jié)中參考資料
ld.lld: error: relocation R_AARCH64_ADR_PREL_PG_HI21 cannot be used against symbol ff_cos_32; recompile with -fPIC

編譯源代碼

至此,我們已搭建好構(gòu)建 FFmpeg 庫的完整框架,將代碼拷貝到 Android 源碼路徑下,例如:vendor/qcom/packages/apps/ffmpeg-5.1.4,進(jìn)入源碼目錄,執(zhí)行 Android 編譯指令 mma,即可編譯 FFmpeg 源碼。當(dāng)前代碼已在 Android 10 和 Android 11 平臺(tái)編譯測(cè)試通過。編譯完成后,在 Android 源碼 out 路徑下執(zhí)行 find . -name "libFFmpeg.so",即可看到已生成適用于 arm 及 arm64 平臺(tái)的庫文件:

./target/product/msmnile_gvmq/system/product/lib/libFFmpeg.so
./target/product/msmnile_gvmq/system/product/lib64/libFFmpeg.so
./target/product/msmnile_gvmq/system/lib/libFFmpeg.so
./target/product/msmnile_gvmq/system/lib64/libFFmpeg.so
./target/product/msmnile_gvmq/vendor/lib/libFFmpeg.so
./target/product/msmnile_gvmq/vendor/lib64/libFFmpeg.so

整體目錄結(jié)構(gòu)

下圖左側(cè)為 FFmpeg 未修改過的源碼,右側(cè)為修改且 configure 后的源碼:
Android.bp 構(gòu)建 FFmpeg 庫:從搭建編譯框架到處理編譯錯(cuò)誤的全過程,FFmpeg 在 Android 上的探索與實(shí)踐,ffmpeg,android
綠框部分為我們新創(chuàng)建的文件,黃框?yàn)樾薷暮蟮?config.h 配置文件,其余高亮部分由 configure 指令生成文件。文章來源地址http://www.zghlxwxcb.cn/news/detail-841232.html

源碼倉庫

  • github 倉庫:FFmpegDroidBuilder

參考資料

  • C語言解決動(dòng)態(tài)庫符號(hào)沖突_-wl,-bsymbolic

到了這里,關(guān)于Android.bp 構(gòu)建 FFmpeg 庫:從搭建編譯框架到處理編譯錯(cuò)誤的全過程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • FFmpeg開發(fā)筆記(八)Linux交叉編譯Android的FFmpeg庫

    ? 《FFmpeg開發(fā)實(shí)戰(zhàn):從零基礎(chǔ)到短視頻上線》一書的“12.1.2 ?交叉編譯Android需要的so庫”介紹了如何在Windows環(huán)境交叉編譯Android所需FFmpeg的so庫,接下來介紹如何在Linux環(huán)境交叉編譯Android所需FFmpeg的so庫。 登錄Linux服務(wù)器(比如華為云的歐拉系統(tǒng)),依次執(zhí)行下面的命令。 重

    2024年03月24日
    瀏覽(18)
  • Android編譯ijkplayer和ffmpeg4.0

    最近編譯了iOS的ijkplayer和android的ijkplayer,記錄一下: 1、bilibili/ijkplayer地址:https://github.com/bilibili/ijkplayer 2、bilibili/ffmpeg地址:GitHub - bilibili/FFmpeg: mirror of git://git.videolan.org/ffmpeg.git 3、ffmpeg官方下載地址:Download FFmpeg ---------------------------------------------------------------- 默認(rèn)按照

    2024年02月11日
    瀏覽(27)
  • window10_ffmpeg調(diào)試環(huán)境搭建-自己編譯

    window10_ffmpeg調(diào)試環(huán)境搭建-自己編譯

    《FFmpeg原理》的社群來了,想加入社群的朋友請(qǐng)購買?VIP?版,VIP 版有更高級(jí)的內(nèi)容與答疑服務(wù)。 《window10_ffmpeg調(diào)試環(huán)境搭建-極速版》已經(jīng)介紹了在qt creator里面 調(diào)試ffmpeg.c 工程。但是極速版的dll是現(xiàn)成的。所以本文來講解如何自己編譯出ffmpeg的dll。 window10 環(huán)境下 ffmpeg的編

    2023年04月09日
    瀏覽(25)
  • FFMPEG android mac 編譯 支持DASH/OPENSSL問題匯總

    FFMPEG android mac 編譯 支持DASH/OPENSSL問題匯總

    一 下載源碼 FFMPEG? https://github.com/FFmpeg/FFmpeg/tree/release/4.3 二 編寫腳本 支持https 就必須添加open SSL 的編譯 具體可以查看我的另一個(gè)關(guān)于open SSL 的 然后我們配置的一些路徑 涉及 ndk 的一定要查看你用的ndk 版本 是否存在這些路徑這是第一步 然后如果支持dash 需要你加入 --enabl

    2024年02月16日
    瀏覽(18)
  • android ndk clang交叉編譯ffmpeg動(dòng)態(tài)庫踩坑

    android ndk clang交叉編譯ffmpeg動(dòng)態(tài)庫踩坑

    1.ffmpeg默認(rèn)使用gcc編譯,在android上無法使用,否則各種報(bào)錯(cuò),所以要用ndk的clang編譯 2.下載ffmpeg源碼 修改configure文件,增加命令 cross_prefix_clang 修改以下命令 修改后 3.新建腳本文件,ffmpeg目錄下執(zhí)行腳本文件即可。 編譯32位,則ARCH改為arm,CPU改為armv7-a,TARGET改為armv7a-linux-

    2024年02月13日
    瀏覽(27)
  • 【Android音視頻】MacOS上FFmpeg5.0.1編譯

    【Android音視頻】MacOS上FFmpeg5.0.1編譯

    1. FFmpeg官網(wǎng)下載鏈接(推薦下載release的版本): Download FFmpeg http://ffmpeg.org/download.html#releases ?盡情去下載并開始編譯吧 2. 下載壓縮包,解壓至自己想要的文件路徑下即可。個(gè)人習(xí)慣用全英文路徑,避免出現(xiàn)奇怪的問題。 3. Android Studio請(qǐng)預(yù)先下載好。點(diǎn)擊AS右上角“SDK Manager”

    2024年02月02日
    瀏覽(29)
  • FFmpeg開發(fā)筆記(十六)Linux交叉編譯Android的OpenSSL庫

    ? 《FFmpeg開發(fā)實(shí)戰(zhàn):從零基礎(chǔ)到短視頻上線》一書的例程主要測(cè)試本地的音視頻文件,當(dāng)然為了安全起見,很多網(wǎng)絡(luò)視頻都采用了https地址。FFmpeg若要訪問https視頻,就必須集成第三方的openssl庫,但編譯FFmpeg時(shí)卻默認(rèn)關(guān)閉了openssl。為了讓App能夠播放采用https的在線視頻,需要

    2024年04月22日
    瀏覽(26)
  • 編譯FFmpeg4.3.1 、x264并移植到Android

    編譯FFmpeg4.3.1 、x264并移植到Android

    1、前言 FFmpeg 既是一款音視頻編解碼工具,同時(shí)也是一組音視頻編解碼開發(fā)套件。 2、準(zhǔn)備工作 系統(tǒng):Linux NDK:android-ndk-r21b-linux-x86_64.zip FFmpeg:ffmpeg-snapshot.tar.bz2 x264:x264 3、下載NDK 在linux環(huán)境中,使用命令如下: ? 4、下載FFmpeg 5、下載x264 6、開始編譯x264 build_x264_android-v7a

    2024年01月19日
    瀏覽(18)
  • MAC環(huán)境編譯Android環(huán)境下的FFmpeg6.0版本

    MAC環(huán)境編譯Android環(huán)境下的FFmpeg6.0版本

    該項(xiàng)目是基于FFmpeg6.0環(huán)境編寫 。文中涉及代碼在不同版本可能會(huì)有變動(dòng) 從以下兩個(gè)地址任選其一下載源碼: https://github.com/FFmpeg/FFmpeg https://ffmpeg.org/ 執(zhí)行根目錄的configure文件, 該方式會(huì)生成相關(guān)文件,否則項(xiàng)目不可運(yùn)行, 參考如下: https://ffmpeg.org/doxygen/6.0/md_INSTALL.html 編譯過

    2024年01月20日
    瀏覽(24)
  • FFmpeg開發(fā)筆記(九)Linux交叉編譯Android的x265庫

    ? 《FFmpeg開發(fā)實(shí)戰(zhàn):從零基礎(chǔ)到短視頻上線》一書的“12.1.2 ?交叉編譯Android需要的so庫”介紹了如何在Windows環(huán)境交叉編譯Android所需FFmpeg的so庫,前文又介紹了如何在Linux環(huán)境交叉編譯Android所需FFmpeg的so庫,接下來介紹如何在Linux環(huán)境交叉編譯Android所需x265的so庫。 執(zhí)行以下命

    2024年04月08日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包