docs/ffmpeg.md
2025-01-15 10:24:25 +08:00

10 KiB
Raw Blame History

基于Ubuntu源码编译ffmpeg

编译SDL2可选

https://github.com/libsdl-org/SDL/releases/tag/release-2.30.8 # 下载源码
cd sdl/source/folder
./configure --prefix=/usr/local
make
sudo make install

安装ffmpeg依赖

  1. 安装包管理工具 aptitude aptitude 与 apt-get一样是 Debian 系中功能极其强大的包管理工具。 与 apt-get 不同的是aptitude 在处理依赖问题上更佳一些,当 aptitude 在删除一个包时,会同时删除本身所依赖的包。
    sudo apt install aptitude
    
  2. 安装 yasm、nasm yasm、nasm 是两个汇编器,编译 FFmpeg 需要用到。 安装命令:
    sudo aptitude install yasm nasm
    
  3. 其他依赖 FFmpeg 的安装依赖许多库(如,音频编码库,音频解码库,视频编解码库等),这里不介绍每个库的具体作用,按照命令安装即可。
    sudo apt-get install libgmp3-dev
    sudo apt install pkg-config
    sudo apt install gnutls-bin
    sudo aptitude install libaom-dev
    sudo aptitude install libass-dev
    sudo aptitude install libbluray-dev
    sudo aptitude install libfdk-aac-dev
    sudo aptitude install libmp3lame-dev
    sudo aptitude install libopencore-amrnb-dev
    sudo aptitude install libopencore-amrwb-dev
    sudo aptitude install libopenmpt-dev
    sudo aptitude install libopus-dev
    sudo aptitude install libshine-dev
    sudo aptitude install libsnappy-dev
    sudo aptitude install libsoxr-dev
    sudo aptitude install libspeex-dev
    sudo aptitude install libtheora-dev
    sudo aptitude install libtwolame-dev
    sudo aptitude install libvo-amrwbenc-dev
    sudo aptitude install llibvpx-dev
    sudo aptitude install libwavpack-dev
    sudo aptitude install libwebp-dev
    sudo aptitude install libx264-dev
    sudo aptitude install libx265-dev
    sudo aptitude install libxvidcore-dev
    sudo aptitude install liblzma-dev
    

编译ffmpeg

  1. 从官网下载源码
  2. 进入根目录编译
    ./configure --enable-shared --enable-gpl  --enable-sdl2 --enable-libx264 --enable-libx265  --enable-nvdec --enable-nvenc --enable-cuda --enable-cuvid
    # 其中 --enable-gpl --enable-libx264 --enable-libx265 必不可少 --enable-sdl2 是ffmpeg播放器需要的
    # 由于需要硬件英伟达显卡加速编解码 --enable-nvdec --enable-nvenc --enable-cuda --enable-cuvid
    # --enable-shared 使make install时将动态库也正确安装否则运行ffmpeg时会显示缺少动态库
    
    make
    sudo make install
    # 安装完后,确保安装目录,确保已经配置好动态库搜索的路径,
    
    如果需要硬件英伟达显卡加速编解码,需要安装相关依赖
    sudo apt install libdssialsacompat-dev
    git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git
    cd nv-codec-headers
    make
    sudo make install
    # ./ffmpeg -hwaccels 查看支持哪些硬件编码
    

编译ffmeg arm64安卓版本

在源码目录下创建buildarm64.sh内容如下

#!/bin/bash

export NDK=~/android/android-ndk-r20b #这里配置先你的 NDK 路径
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64

# 编译到安卓上,尽可能小一些(--enable-small),只是用来解码,也就取消编译封装编码相关的
function build_android
{

./configure \
--disable-programs \
--disable-avdevice \
--disable-encoders \
--disable-muxers \
--disable-filters \
--enable-neon  \
--enable-gpl   \
--disable-sdl2 \
--disable-postproc \
--disable-debug \
--enable-small \
--enable-static \
--enable-shared \
--disable-doc \
--enable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-avdevice \
--disable-doc \
--disable-symver \
--prefix=$PREFIX \
--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


chomd +x buildarm64.sh
./buildarm64.sh
# 编译好后,对应的源文件和库文件会安装到./android/armv-v8a中

在rk3568上交叉编译ffmpeg

使用瑞芯微上使用其硬件加速编码和解码 创建一个目录 ~/dev 之后所有的操作在这个目录下进行

  1. 编译mpp

    git clone -b jellyfin-mpp --depth=1 https://github.com/nyanmisaka/mpp.git rkmpp
    mkdir rkmpp_build
    pushd rkmpp_build
    # 在cmake中指定交叉工具链gcc和g++ 改成自己的目录
    # 注意在不要安装到本机的系统目录,最好新建一个目录,之后把所有的依赖安装到这个目录
    cmake \
    -DCMAKE_INSTALL_PREFIX=~/dev/rkffmpeg \
    -DCMAKE_BUILD_TYPE=Release \
    -DBUILD_SHARED_LIBS=ON \
    -DBUILD_TEST=OFF \
    -DCMAKE_C_COMPILER=/home/user/baidu/buildroot-cross/gcc_for_rk356x_buildroot/bin/aarch64-linux-gcc \
     -DCMAKE_CXX_COMPILER=/home/user/baidu/buildroot-cross/gcc_for_rk356x_buildroot/bin/aarch64-linux-g++ \
    ..
    make -j $(nproc)
    make install
    
  2. build rga

    创建一个在~/dev 目录下创建cross_file.txt, 将工具链换成自己的,以及安装目录

    [host_machine]
    system = 'linux'
    cpu_family = 'aarch64'
    cpu = 'armv8-a'
    endian = 'little'
    
    [binaries]
    c = '/home/user/baidu/buildroot-cross/gcc_for_rk356x_buildroot/bin/aarch64-linux-gcc'
    cpp = '/home/user/baidu/buildroot-cross/gcc_for_rk356x_buildroot/bin/aarch64-linux-g++'
    ar = '/home/user/baidu/buildroot-cross/gcc_for_rk356x_buildroot/aarch64-rockchip-linux-gnu/bin/ar'
    strip = '/home/user/baidu/buildroot-cross/gcc_for_rk356x_buildroot/aarch64-rockchip-linux-gnu/bin/strip'
    
    [properties]
    c_args = ['-fpermissive']
    cpp_args = ['-fpermissive']
    
    [paths]
    prefix = '~/dev/rkffmpeg'
    libdir = 'lib'
    
     git clone -b jellyfin-rga --depth=1 https://github.com/nyanmisaka/rk-mirrors.git rkrga
     # 不需要cd 进行
     meson setup rkrga rkrga_build \
     --prefix=/usr \
     --libdir=lib \
     --buildtype=release \
     --default-library=shared \
     -Dcpp_args=-fpermissive \
     -Dlibdrm=false \
     -cross-file=./cross_file.txt \
     -Dlibrga_demo=false
     meson configure rkrga_build
     ninja -C rkrga_build install
    
  3. 编译drm

    首先去官网下载源码包https://dri.freedesktop.org/libdrm/ 下载完成后开始解压缩解压缩完成后进入源码目录首先创建install和build目录然后创建cross_file.txt文件文件内容如下

    [host_machine]
    system = 'linux'
    cpu_family = 'aarch64'
    cpu = 'armv8-a'
    endian = 'little'
    
    [binaries]
    c = '/home/user/baidu/buildroot-cross/gcc_for_rk356x_buildroot/bin/aarch64-linux-gcc'
    cpp = '/home/user/baidu/buildroot-cross/gcc_for_rk356x_buildroot/bin/aarch64-linux-g++'
    ar = '/home/user/baidu/buildroot-cross/gcc_for_rk356x_buildroot/aarch64-rockchip-linux-gnu/bin/ar'
    strip = '/home/user/baidu/buildroot-cross/gcc_for_rk356x_buildroot/aarch64-rockchip-linux-gnu/bin/strip'
    
    [properties]
    c_args = ['-fpermissive']
    cpp_args = ['-fpermissive']
    
    [paths]
    prefix = '~/dev/rkffmpeg'
    libdir = 'lib'
    

    然后直接执行指令ninja && ninja install即可使用

  4. 编译ffmpeg

    上面的依赖编译并安装好后正式开始编译ffmpeg添加rk芯片的mpp来加速编解码 在~/dev 下载ffmpeg 进入到源码目录 创建build.sh 内容如下

    #!/bin/bash
    export TOOLCHAIN=/home/user/baidu/buildroot-cross/gcc_for_rk356x_buildroot/bin/aarch64-linux
    export GCC=$TOOLCHAIN-gcc
    export GXX=$TOOLCHAIN-g++
    
    # 编译到开发版,尽可能小一些(--enable-small),取消了一些其它硬件加速和封装
    # 更换 cc cxx ar strip 以及--extra-cflags --extra-ldflags
    function build_android
    {
    
    ./configure \
    --sysroot=./ \
    --extra-cflags="-I~/dev/rkffmpeg/include" \
    --extra-ldflags="-L~/dev/rkffmpeg/lib" \
    --prefix=$PREFIX \
    --enable-cross-compile \
    --arch=arm64 \
    --cpu=armv8-a \
    ar=/home/user/baidu/buildroot-cross/gcc_for_rk356x_buildroot/aarch64-rockchip-linux-gnu/bin/ar \
    strip=/home/user/baidu/buildroot-cross/gcc_for_rk356x_buildroot/aarch64-rockchip-linux-gnu/bin/strip \
    --cc=$GCC \
    --cxx=$GXX \
    --enable-libdrm \
    --disable-nvenc \
    --disable-nvdec \
    --disable-vdpau \
    --disable-vaapi \
    --enable-rkmpp \
    --enable-rkrga \
    --enable-version3 \
    --disable-programs \
    --disable-avdevice \
    --disable-muxers \
    --disable-filters \
    --enable-neon  \
    --enable-gpl   \
    --disable-sdl2 \
    --disable-postproc \
    --disable-debug \
    --enable-small \
    --enable-static \
    --enable-shared \
    --disable-doc \
    --enable-ffmpeg \
    --disable-ffprobe \
    --disable-avdevice \
    --disable-doc \
    --disable-symver
    
    
    
    echo "============================ build android arm64-v8a success =========================="
    
    }
    
    #arm64-v8a
    
    
    PREFIX=$(pwd)/rk-arm64
    
    build_android
    

    编译

    chmod +x build.sh
    
    make clean
    make -j16
    make install
    

    最后把编译好的ffmpeg 放到~/dev/rkffmpeg 中 一并打包移植到开发版上

硬编码

// 与软编码相比,没有很多额外的配置
// 仅仅是在查找编码器时按名称查找 hevc_nvenc ,其余和软编码一样
auto pCodec = avcodec_find_encoder_by_name("hevc_nvenc");
// ...
// 其次就是注意软编码出来的每一帧数据 前面都会带有SEI增强帧关键帧后面才是I帧或者P帧
	auto naluHeader = (pkt->data[4] & 0x7E) >> 1; // 前四个字节是0x00 00 00 01 分隔符
    if (naluHeader == 39) { // SEI
        auto header = getNextSplit(pkt->data, pkt->size); // 往后找跳过这个SEI
        if (header == nullptr)
            return 0;
        naluHeader = ((*header) & 0x7E) >> 1;
        // cout << "naluHeader: " << naluHeader << endl;
    }