docs/ffmpeg.md

171 lines
5.2 KiB
Markdown
Raw Normal View History

2024-10-19 11:31:30 +08:00
# 基于Ubuntu源码编译ffmpeg
2024-10-28 17:24:18 +08:00
## 编译SDL2可选
2024-10-19 11:31:30 +08:00
```shell
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 在删除一个包时,会同时删除本身所依赖的包。
```shell
sudo apt install aptitude
```
2. 安装 yasm、nasm
yasm、nasm 是两个汇编器,编译 FFmpeg 需要用到。
安装命令:
```shell
sudo aptitude install yasm nasm
```
3. 其他依赖
FFmpeg 的安装依赖许多库(如,音频编码库,音频解码库,视频编解码库等),这里不介绍每个库的具体作用,按照命令安装即可。
```shell
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. 进入根目录编译
```shell
2024-10-28 17:24:18 +08:00
./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时会显示缺少动态库
2024-10-19 11:31:30 +08:00
make
sudo make install
2024-10-28 17:24:18 +08:00
# 安装完后,确保安装目录,确保已经配置好动态库搜索的路径,
```
2024-10-19 11:31:30 +08:00
如果需要硬件英伟达显卡加速编解码,需要安装相关依赖
```shell
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
2025-01-07 15:09:50 +08:00
# ./ffmpeg -hwaccels 查看支持哪些硬件编码
2024-11-21 16:41:04 +08:00
```
2025-01-07 15:09:50 +08:00
**编译ffmeg arm64版本**
2024-11-21 16:41:04 +08:00
在源码目录下创建buildarm64.sh内容如下
```shell
#!/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
```
```shell
chomd +x buildarm64.sh
./buildarm64.sh
# 编译好后,对应的源文件和库文件会安装到./android/armv-v8a中
```
## 硬编码
```c++
// 与软编码相比,没有很多额外的配置
// 仅仅是在查找编码器时按名称查找 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;
}
```