Unbuntu18.04 编译FFmpeg 支持 QSV 硬编解码

在Linux下,由于FFmpeg软解码CPU占用过高,所以打算使用h264_qsv硬解码,本文并非原创,主要参考以下文章,在此记录下编译过程,以便日后使用。

参考文章:

  • https://zhuanlan.zhihu.com/p/62246545

  • http://blog.chinaunix.net/uid-21501855-id-5835281.html

编译过程: 

  1. 下载MediaSDK 20.1.1 相关依赖库  https://github.com/Intel-Media-SDK/MediaSDK/releases/tag/intel-mediasdk-20.1.1
    1.  Unbuntu18.04 编译FFmpeg 支持 QSV 硬编解码_第1张图片
  2. 安装 libva 
    1. ./autogen.sh --prefix=/opt/intel/libva --libdir=/opt/intel/libva/lib
    2. make -j8 & sudo make install
    3. export PKG_CONFIG_PATH=/opt/intel/libva/lib/pkgconfig
    4. export LD_LIBRARY_PATH=/opt/intel/libva/lib:$LD_LIBRARY_PATH
    5. sudo ldconfig
    6. Unbuntu18.04 编译FFmpeg 支持 QSV 硬编解码_第2张图片
  3. 安装libva-util
    1. ./autogen.sh --prefix=/opt/intel/libva-utils  --libdir=/opt/intel/libva-utils/lib
    2. make -j8 & sudo make install
    3. Unbuntu18.04 编译FFmpeg 支持 QSV 硬编解码_第3张图片
  4. 安装media-driver
    1. 分别解压 gmmlib-intel-gmmlib-20.1.1.zip和 media-driver-intel-media-20.1.1.zip
    2. cd gmmlib-intel-gmmlib-20.1.1.zip
    3. mkdir build & cd build
    4. cmake .. & make -j8 & sudo make install
    5. 创建gmmlib-mediadriver目录
    6. cd gmmlib-mediadriver
    7. cmake ../media-driver \
          -DMEDIA_VERSION="2.0.0" \
          -DBUILD_ALONG_WITH_CMRTLIB=1 \
          -DBS_DIR_GMMLIB=`pwd`/../gmmlib/Source/GmmLib/ \
          -DBS_DIR_COMMON=`pwd`/../gmmlib/Source/Common/ \
          -DBS_DIR_INC=`pwd`/../gmmlib/Source/inc/ \
          -DBS_DIR_MEDIA=`pwd`/../media-driver \
          -DCMAKE_INSTALL_PREFIX=/opt/intel/media-driver \
          -DCMAKE_INSTALL_LIBDIR=/opt/intel/media-driver/lib \
          -DINSTALL_DRIVERS_SYSCONF=OFF \
          -DLIBVA_DRIVERS_PATH=/opt/intel/media-driver/lib/dri
      
      make -j8
      sudo make install

      8. Unbuntu18.04 编译FFmpeg 支持 QSV 硬编解码_第4张图片

  5. 配置环境变量

    1. export LIBVA_DRIVER_NAME=iHD

    2. export LIBVA_DRIVERS_PATH=/opt/intel/media-driver/lib/dri

  6. 验证

    1. cd /opt/intel/libva-utils/bin

    2. ./vainfo

  7. 安装intel media SDK

    mkdir build
    
    cd build
    
    make -j8 & sudo make install
    
    export LD_LIBRARY_PATH=/opt/intel/mediasdk/lib:$LD_LIBRARY_PATH
    
    export MFX_HOME=/opt/intel/mediasdk/lib/pkgconfig
    
    export PKG_CONFIG_PATH=/opt/intel/mediasdk/lib/pkgconfig:$PKG_CONFIG_PATH
    
    sudo ldconfig
    
    echo $LIBVA_DRIVER_NAME #应该输出 iHD
    
    echo $LIBVA_DRIVERS_PATH #应该输出 /opt/intel/media-driver/lib/dri
    
    echo $MFX_HOME #应该输出 /opt/intel/mediasdk/lib/pkgconfig
    
    echo $PKG_CONFIG_PATH #应该输出 "/opt/intel/mediasdk/lib/pkgconfig:/opt/intel/libva/lib/pkgconfig:"这部分内容。
    
    echo $LD_LIBRARY_PATH #输出的内容应该含有 "/opt/intel/mediasdk/lib:/opt/intel/libva/lib:"

     

  8. 编译 FFmpeg n4.3

    1. 修改libavformat/movenc.c 支持G711

    2. 修改 movenc.c

    3.  static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
      
          if (track->mode == MODE_MOV) {
                  avio_wb16(pb, track->par->channels);
                  if (track->par->codec_id == AV_CODEC_ID_PCM_U8 ||
                      track->par->codec_id == AV_CODEC_ID_PCM_S8)
                      avio_wb16(pb, 8); /* bits per sample */
                  else if (track->par->codec_id == AV_CODEC_ID_ADPCM_G726)
                      avio_wb16(pb, track->par->bits_per_coded_sample);
                  else
                      avio_wb16(pb, 16);
                  avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
              } else { /* reserved for mp4/3gp */
                  avio_wb16(pb, track->par->channels > 0 ?
                                track->par->channels : 1);
                  track->par->bits_per_coded_sample = av_get_bits_per_sample(track->par->codec_id);
                  avio_wb16(pb, track->par->bits_per_coded_sample > 0 ?
                                track->par->bits_per_coded_sample : 16);
                  avio_wb16(pb, 0);
              }
      
      
            avio_wb16(pb, 0); /* packet size (= 0) */
              if (track->par->codec_id == AV_CODEC_ID_OPUS)
                  avio_wb16(pb, 48000);
              else
                  avio_wb16(pb, track->par->sample_rate <= UINT16_MAX ?
                                track->par->sample_rate : 0);
              avio_wb16(pb, 0); /* Reserved */
      
      
      static unsigned int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
      {
          int tag;
      
      
          if (track->mode == MODE_MP4 || track->mode == MODE_PSP)
              tag = track->par->codec_tag;
          else if (track->mode == MODE_ISM)
              tag = track->par->codec_tag;
          else if (track->mode == MODE_IPOD) {
              if (!av_match_ext(s->filename, "m4a") &&
                  !av_match_ext(s->filename, "m4v") &&
                  !av_match_ext(s->filename, "m4b"))
                  av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
                         "Quicktime/Ipod might not play the file\n");
              tag = track->par->codec_tag;
          } else if (track->mode & MODE_3GP)
              tag = track->par->codec_tag;
          else if (track->mode == MODE_F4V)
              tag = track->par->codec_tag;
          else
              tag = mov_get_codec_tag(s, track);
      
      
          if (tag == 0){
              tag = mov_get_codec_tag(s, track);
          }
      
      
          return tag;
      }

       

    4. 编译FFmpeg:

      1. ./configure --enable-shared \
                      --disable-x86asm \
                      --disable-lzma \
                      --enable-pic \
                      --extra-cflags=-fPIC \
                      --extra-cxxflags=-fPIC \
                      --enable-libmfx \
                      --enable-nonfree \
                      --enable-encoder=h264_qsv \
                      --enable-decoder=h264_qsv \
                      --enable-libfreetype \
                      --enable-libfontconfig \
                      --enable-libfribidi \
                      --enable-encoder=pcm_alaw \
                      --enable-decoder=pcm_alaw \
                      --prefix=/opt/ffmpeg \
                      --libdir=/opt/ffmpeg/lib \
        
        make -j8
        sudo make install

         

  9. 测试

    1. ./ffplay -vcodec h264_qsv -i test.mp4

    2. ./ffmpeg -y -i 1.mp4 -pix_fmt nv12 -c:v h264_qsv -profile:v baseline -preset fast -b:v 4000k -an test_output.mp4

 

 

参考:

  1. http://blog.chinaunix.net/uid-21501855-id-5835281.html
  2. https://zhuanlan.zhihu.com/p/62246545

注:

  1. 编译所有流程最好在一个进程中进行
  2. LIBVA_DRIVER_NAME和LIBVA_DRIVER_PATH, 可配置系统环境 etc/environment
  3. MediaSDK 20.1.1 亲测 FFmpeg n4.3 h264_qsv成功 ,FFmpeg n4.1h264_qsv失败
    [h264_qsv @ 0x55ef1dc72040] Low power mode is unsupported
    [h264_qsv @ 0x55ef1dc72040] Current frame rate is unsupported
    [h264_qsv @ 0x55ef1dc72040] Current picture structure is unsupported
    [h264_qsv @ 0x55ef1dc72040] Current resolution is unsupported
    [h264_qsv @ 0x55ef1dc72040] Current pixel format is unsupported
    [h264_qsv @ 0x55ef1dc72040] some encoding parameters are not supported by the QSV runtime. Please double check the input parameters.
    Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height

 

END

Unbuntu18.04 编译FFmpeg 支持 QSV 硬编解码_第5张图片

 

 

你可能感兴趣的:(FFmpeg,ffmpeg)