阅读本文之前,需要你
- 对 ffmpeg 工具集有一定的了解
- 熟悉 pkg_config 工具
- 熟悉源码编译步骤,能够思考并解决依赖链接相关问题
本文所述命令可能因为环境和时间问题导致不正确,需要你根据以上技能酌情解决。
安装 FFmpeg 的依赖
# 安装依赖工具
yum install autoconf automake bzip2 cmake freetype-devel gcc gcc-c++ git libtool make mercurial pkgconfig zlib-devel
# 创建编译路径及安装路径
mkdir ffmpeg_sources #编译路径
mkdir envs # 安装路径
# 安装nasm
cd ~/ffmpeg_sources
curl -O -L http://www.nasm.us/pub/nasm/releasebuilds/2.13.02/nasm-2.13.02.tar.bz2
tar xjvf nasm-2.13.02.tar.bz2
cd nasm-2.13.02
./autogen.sh
./configure --prefix="$HOME/envs"
make && make install
# 安装yasm
cd ~/ffmpeg_sources
curl -O -L http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
tar xzvf yasm-1.3.0.tar.gz
cd yasm-1.3.0
./configure --prefix="$HOME/envs"
make && make install
# 安装libx264
cd ~/ffmpeg_sources
git clone --depth 1 http://git.videolan.org/git/x264 # 链接可能失效
cd x264
PKG_CONFIG_PATH="$HOME/envs/lib/pkgconfig" ./configure --prefix="$HOME/envs" --enable-static
make && make install
# 安装 libfdk_acc
cd ~/ffmpeg_sources
git clone --depth 1 --branch v0.1.6 https://github.com/mstorsjo/fdk-aac.git
cd fdk-aac
autoreconf -fiv
./configure --prefix="$HOME/envs" --disable-shared
make && make install
# 安装libmp3lame
cd ~/ffmpeg_sources
curl -O -L http://downloads.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gz
tar xzvf lame-3.100.tar.gz
cd lame-3.100
./configure --prefix="$HOME/envs" --disable-shared --enable-nasm
make
make install
安装 Nvidia 显卡相关依赖
# 验证nvidia驱动是否正常
nvidia-smi # 如果不正常要先安装驱动
# 安装CUDA (一个GPU计算库)
# 去 https://developer.nvidia.com/cuda-downloads 下载相应平台安装包,官网上面有安装教程
rpm -i cuda-repo-rhel8-10-2-local-10.2.89-440.33.01-1.0-1.x86_64.rpm # 建议源码安装,最好安装10.0版本
yum clean all
yum install cuda
# 验证是否安装
/usr/local/cuda-10.2/bin/nvcc -V
ln -s /usr/local/cuda-10.2 /usr/local/cuda # 假如是源码安装软链一下
编译 ffmpeg
# 安装 nv-codec-headers 库
cd ~/ffmpeg_sources
git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git
make PREFIX="$HOME/envs"
make install PREFIX="$HOME/envs"
# 安装ffmpeg,以下命令基于cuda 10.0版本,更高版本,某些配置有所不同
cd ~/ffmpeg_sources
git clone https://github.com/FFmpeg/FFmpeg.git
PKG_CONFIG_PATH="$HOME/envs/lib/pkgconfig" ./configure \
--prefix="$HOME/envs" \
--pkg-config-flags="--static" \
--extra-cflags="-I$HOME/envs/include -I/usr/local/cuda/include" \
--extra-ldflags="-L$HOME/envs/lib -L/usr/local/cuda/lib64" \
--extra-libs=-lpthread \
--extra-libs=-lm \
--enable-gpl \
--enable-libfdk_aac \
--enable-libfreetype \
--enable-libmp3lame \
--enable-libx264 \
--enable-nonfree \
--enable-cuda \
--enable-cuvid \
--enable-nvenc \
--enable-libnpp
make && make install
验证 ffmpeg 是否支持硬件加速
# 主要查看是否有h264_cuvid和h264_nvenc
~/envs/bin/ffmpeg -decoders | grep h264
~/envs/bin/ffmpeg -encoders | grep nv
# 测试一下解码功能,假设有个test.mp4文件,转成test.yuv
~/envs/bin/ffmpeg -vsync 0 -c:v h264_cuvid -i test.mp4 -f rawvideo test.yuv
# 开另外一个shell 执行以下命令,可以观察到解码程序正在运行(时间很短)
watch -n 1 nvidia-smi
验证代码调用
编写如下代码,保存为 h264_nvenc.cpp
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
#include <libavutil/mathematics.h>
#include <libavutil/opt.h>
#include <libswscale/swscale.h>
#include <x264.h>
}
int main( int argc, char** argv )
{
const AVCodec *codec;
AVCodecContext *c= NULL;
av_register_all();
std::cout << "Loading codec" << std::endl;
// codec = avcodec_find_encoder_by_name( "libx264" ); // works
codec = avcodec_find_encoder_by_name( "h264_nvenc" );
// codec = avcodec_find_decoder_by_name( "h264_cuvid" );
if( !codec )
{
throw std::runtime_error( "Unable to find codec!" );
}
std::cout << "Allocating context" << std::endl;
return 0;
}
编译执行
# 编译
g++ h264_nvenc.cpp -o h264_nvenc `PKG_CONFIG_PATH=~/envs/lib/pkgconfig/ pkg-config --cflags libavformat libswscale libswresample libavutil libavcodec` `PKG_CONFIG_PATH=~/envs/lib/pkgconfig/ pkg-config --libs libavformat libswscale libswresample libavutil libavcodec` -L/usr/local/cuda/lib64 -std=gnu++11
# 执行
./h264_nvenv
# 按以上程序分别调试h264_nvenc和h264_cuvid,若流程正常则表示代码调用通过
cmake 项目编译
很多同学采用 cmake 来编译项目,推荐以下实践
# CMakeLists.txt
cmake_minimum_required ( VERSION 3.0)
project(test)
set(ENV{PKG_CONFIG_PATH} "~/envs/lib/pkgconfig/")
find_package(PkgConfig REQUIRED)
pkg_search_module(PKG_AVFORMAT REQUIRED libavformat)
pkg_search_module(PKG_AVDEVICE REQUIRED libavdevice)
pkg_search_module(PKG_AVCODEC REQUIRED libavcodec)
pkg_search_module(PKG_AVUTIL REQUIRED libavutil)
pkg_search_module(PKG_AVFILTER REQUIRED libavfilter)
pkg_search_module(PKG_SWSCALE REQUIRED libswscale)
pkg_search_module(PKG_SWRESAMPLE REQUIRED libswresample)
include_directories(/usr/local/cuda/include ~/envs/include/ # ... )
link_directories(/usr/local/cuda/lib64 ~/dev/envs/lib/ # ... )
# 其他内容
add_executable(${PROJECT_NAME} test.cpp)
target_link_libraries(${PROJECT_NAME} ${PKG_SWSCALE_LDFLAGS} ${PKG_SWRESAMPLE_LDFLAGS} ${PKG_AVFORMAT_LDFLAGS} ${PKG_AVDEVICE_LDFLAGS} ${PKG_AVCODEC_LDFLAGS} ${PKG_AVUTIL_LDFLAGS} ${PKG_AVFILTER_LDFLAGS} )
# 其他内容
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。