欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-14 18:18:04
...

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

参考文章:

编译过程: 

  1. 下载MediaSDK 20.1.1 相关依赖库  https://github.com/Intel-Media-SDK/MediaSDK/releases/tag/intel-mediasdk-20.1.1
    1.  Unbuntu18.04 编译FFmpeg 支持 QSV 硬编解码
  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 硬编解码
  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 硬编解码
  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 硬编解码

  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 硬编解码

 

 

相关标签: FFmpeg ffmpeg