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

# 其餘內容
相關文章
相關標籤/搜索