ffmpeg硬件编解码

阅读本文以前,须要你ios

  1. 对 ffmpeg 工具集有必定的了解
  2. 熟悉 pkg_config 工具
  3. 熟悉源码编译步骤,可以思考并解决依赖连接相关问题

本文所述命令可能由于环境和时间问题致使不正确,须要你根据以上技能酌情解决。c++

安装 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.cppgit

#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;

}

编译执行github

# 编译
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 来编译项目,推荐如下实践shell

# 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} )

# 其余内容
相关文章
相关标签/搜索