2014-09-23 952 views

回答

0

FFMPEG目前不支持(截至2015年10月1日)支持VAAPI编码。目前它仅支持使用VAAPI进行解码。

0

在这一天它似乎还没有实施。这是对google summer of code goals for 2013

但是也可以使用libva utils的(h264encode)之一来使用VAAPI hwaccel的: 据我所知,它只能在一个rawvideo文件(FOURCC NV12,IYUV,YV12,UYVY),您可以用v412获得与:

的ffmpeg -i的/ dev/video0的-c:v rawvideo -pix_fmt NV12 -vframes 1000 -y yourfilm.yuv

棘手的事情是你必须知道的帧数量和大小,h264encode无法从rawvideo中猜出它们,那么你可以:

h264encode -w 640 -h 480 -n 1000 --srcyuv yourfilm.yuv

h264编码的文件在默认情况下会在/tmp/test.264中丢失,您当然可以修改它。

的速度,它被编码和最终的质量仅仅是惊人的(440Mo到8Mo在不到两秒钟,并且没有质量损失可见)

现在,那岂不是巨大的,有一个编解码器在ffmpeg中可以直接使用GPU资源。有没有人在ffmpeg codec dev上有任何文档,或者至少可以指向接近vaapi_hwaccel编码的编解码器?

+0

FFmpeg支持NVENC。 – LordNeckbeard 2015-01-29 19:13:43

5

截至今天,FFmpeg的和libav已经实现了通过在支持的平台和硬件SKU和I have written a write-up on the same,使您能够建立,部署和使用都FFMPEG和libav来达到同样的效果VAAPI硬件加速编码。

并且在同一笔记中,我添加了对硬件表面限制的引用,以便您了解哪些硬件平台支持与VAAPI编码一起使用的特定视频编解码器。

该真实经由环境模块系统中加载的样品的FFmpeg构建如下所示,一步一步:

构建启用VAAPI-FFmpeg的与用于在VP8/9解码和编码硬件加速支持以Skylake验证测试台为例:

构建平台:Ubuntu 16.04LTS。

第一件事第一件事:

先构建依赖关系链。

  1. cmrt

这是英特尔G45 &高清显卡家族的下媒体运行GPU内核管理者。 这是构建intel-hybrid-driver程序包的先决条件。

git clone https://github.com/01org/cmrt 
cd cmrt 
./autogen.sh 
./configure 
time make -j$(nproc) VERBOSE=1 
sudo make -j$(nproc) install 
sudo ldconfig -vvvv 
  • intel-hybrid-driver
  • 这个包提供的WebM项目VPX编解码器支持。通过在Intel GEN GPU上执行的媒体内核提供GPU加速 。混合驱动器提供绑定熵(例如,CPBAC)解码并管理GEN GPU媒体内核参数和缓冲器。

    这是使用所需配置构建libva的先决条件,因此我们可以在支持的硬件配置上访问VPX系列混合解码功能。

    git clone https://github.com/01org/intel-hybrid-driver 
    cd intel-hybrid-driver 
    ./autogen.sh 
    ./configure 
    time make -j$(nproc) VERBOSE=1 
    sudo make -j$(nproc) install 
    sudo ldconfig -vvv 
    
  • intel-vaapi-driver
  • 此包提供了VA-API(视频加速API)的用户模式驱动程序英特尔GEN图形家族的SKU。 当前的视频驱动后端通过缓冲区和命令的封装为GEN GPU提供了一个桥梁,以发送给i915驱动程序,以执行视频解码,编码和处理的硬件和着色器功能。 当被调用来处理支持的硬件上的VP8/9混合解码任务时,它还为intel-hybrid-driver提供了一个包装(必须使用--enable-hybrid-codec选项进行配置)。

    git clone https://github.com/01org/intel-vaapi-driver 
    cd intel-vaapi-driver 
    ./autogen.sh 
    ./configure --enable-hybrid-codec 
    time make -j$(nproc) VERBOSE=1 
    sudo make -j$(nproc) install 
    sudo ldconfig -vvvv 
    
  • libva
  • Libva为VA-API(视频加速API)的实施

    VA-API是一个开源库和API规范,它提供了视频处理的图形硬件加速功能。它包含一个主库和每个受支持的硬件供应商的特定于驱动程序的加速后端。

    git clone https://github.com/01org/libva 
    cd libva 
    ./autogen.sh 
    ./configure 
    time make -j$(nproc) VERBOSE=1 
    sudo make -j$(nproc) install 
    sudo ldconfig -vvvv 
    

    完成后,通过运行vainfo测试支持的功能集的VAAPI:

    vainfo 
    

    对我目前的测试平台的输出是:

    libva info: VA-API version 0.40.0 
    libva info: va_getDriverName() returns 0 
    libva info: Trying to open /usr/local/lib/dri/i965_drv_video.so 
    libva info: Found init function __vaDriverInit_0_40 
    libva info: va_openDriver() returns 0 
    vainfo: VA-API version: 0.40 (libva 1.7.3) 
    vainfo: Driver version: Intel i965 driver for Intel(R) Skylake - 1.8.3.pre1 (glk-alpha-58-g5a984ae) 
    vainfo: Supported profile and entrypoints 
         VAProfileMPEG2Simple   : VAEntrypointVLD 
         VAProfileMPEG2Simple   : VAEntrypointEncSlice 
         VAProfileMPEG2Main    : VAEntrypointVLD 
         VAProfileMPEG2Main    : VAEntrypointEncSlice 
         VAProfileH264ConstrainedBaseline: VAEntrypointVLD 
         VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice 
         VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP 
         VAProfileH264Main    : VAEntrypointVLD 
         VAProfileH264Main    : VAEntrypointEncSlice 
         VAProfileH264Main    : VAEntrypointEncSliceLP 
         VAProfileH264High    : VAEntrypointVLD 
         VAProfileH264High    : VAEntrypointEncSlice 
         VAProfileH264High    : VAEntrypointEncSliceLP 
         VAProfileH264MultiviewHigh  : VAEntrypointVLD 
         VAProfileH264MultiviewHigh  : VAEntrypointEncSlice 
         VAProfileH264StereoHigh   : VAEntrypointVLD 
         VAProfileH264StereoHigh   : VAEntrypointEncSlice 
         VAProfileVC1Simple    : VAEntrypointVLD 
         VAProfileVC1Main    : VAEntrypointVLD 
         VAProfileVC1Advanced   : VAEntrypointVLD 
         VAProfileNone     : VAEntrypointVideoProc 
         VAProfileJPEGBaseline   : VAEntrypointVLD 
         VAProfileJPEGBaseline   : VAEntrypointEncPicture 
         VAProfileVP8Version0_3   : VAEntrypointVLD 
         VAProfileVP8Version0_3   : VAEntrypointEncSlice 
         VAProfileHEVCMain    : VAEntrypointVLD 
         VAProfileHEVCMain    : VAEntrypointEncSlice 
         VAProfileVP9Profile0   : VAEntrypointVLD 
    

    制作一个可用的FFmpeg构建测试编码器:

    现在,我们将构建一个FFmpeg二进制文件,它可以利用VAAPI来测试Skylake上的编码和解码功能,使用自定义前缀,因为我们通过environment-modules系统在测试台上加载FFmpeg。

    准备目标目录第一:

    sudo mkdir -p /apps/ffmpeg/dyn 
    sudo chown -Rc $USER:$USER /apps/ffmpeg/dyn 
    mkdir -p ~/ffmpeg_sources 
    

    根据需要包括额外的组件:

    (一)。构建和部署nasm: Nasm是由x264和FFmpeg使用的x86优化的汇编程序。强烈建议或您的最终构建可能会非常缓慢。

    请注意,我们现在已经从Yasm切换到nasm,因为这是目前的x265,x264等汇编程序正在采用。

    cd ~/ffmpeg_sources 
    wget wget http://www.nasm.us/pub/nasm/releasebuilds/2.14rc0/nasm-2.14rc0.tar.gz 
    tar xzvf nasm-2.14rc0.tar.gz 
    cd nasm-2.14rc0 
    ./configure --prefix="/apps/ffmpeg/dyn" --bindir="/apps/ffmpeg/dyn/bin" 
    make -j$(nproc) VERBOSE=1 
    make -j$(nproc) install 
    make -j$(nproc) distclean 
    

    (b)。静态构建和部署libx264: 此库提供了一个H.264视频编码器。有关更多信息和使用示例,请参见H.264 Encoding Guide。 这需要FFMPEG与--enable-GPL--enable-libx264进行配置。

    cd ~/ffmpeg_sources 
    wget http://download.videolan.org/pub/x264/snapshots/last_x264.tar.bz2 
    tar xjvf last_x264.tar.bz2 
    cd x264-snapshot* 
    PATH="/apps/ffmpeg/dyn/bin:$PATH" ./configure --prefix="/apps/ffmpeg/dyn" --bindir="/apps/ffmpeg/dyn/bin" --enable-static --disable-opencl 
    PATH="/apps/ffmpeg/dyn/bin:$PATH" make -j$(nproc) VERBOSE=1 
    make -j$(nproc) install VERBOSE=1 
    make -j$(nproc) distclean 
    

    (c)。构建和配置libx265: 此库提供H.265/HEVC视频编码器。有关更多信息和用法示例,请参见H.265 Encoding Guide

    sudo apt-get install cmake mercurial 
    cd ~/ffmpeg_sources 
    hg clone https://bitbucket.org/multicoreware/x265 
    cd ~/ffmpeg_sources/x265/build/linux 
    PATH="$/apps/ffmpeg/dyn/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="/apps/ffmpeg/dyn" -DENABLE_SHARED:bool=off ../../source 
    make -j$(nproc) VERBOSE=1 
    make -j$(nproc) install VERBOSE=1 
    make -j$(nproc) clean VERBOSE=1 
    

    (d)。构建和部署libfdk-aac库: 这提供了一个AAC音频编码器。有关更多信息和用法示例,请参阅AAC Audio Encoding Guide。 这需要的ffmpeg与--enable-libfdk-AAC配置(和--enable-非自由如果您还包括--enable-GPL)。

    cd ~/ffmpeg_sources 
    wget -O fdk-aac.tar.gz https://github.com/mstorsjo/fdk-aac/tarball/master 
    tar xzvf fdk-aac.tar.gz 
    cd mstorsjo-fdk-aac* 
    autoreconf -fiv 
    ./configure --prefix="/apps/ffmpeg/dyn" --disable-shared 
    make -j$(nproc) 
    make -j$(nproc) install 
    make -j$(nproc) distclean 
    

    (e)。构建和配置libvpx

    cd ~/ffmpeg_sources 
        git clone https://github.com/webmproject/libvpx/ 
        cd libvpx 
        ./configure --prefix="/apps/ffmpeg/dyn" --enable-runtime-cpu-detect --enable-vp9 --enable-vp8 \ 
        --enable-postproc --enable-vp9-postproc --enable-multi-res-encoding --enable-webm-io --enable-vp9-highbitdepth --enable-onthefly-bitpacking --enable-realtime-only \ 
        --cpu=native --as=yasm 
        time make -j$(nproc) 
        time make -j$(nproc) install 
        time make clean -j$(nproc) 
        time make distclean 
    

    (F)。建立LibVorbis

    cd ~/ffmpeg_sources 
        wget -c -v http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.5.tar.xz 
        tar -xvf libvorbis-1.3.5.tar.xz 
        cd libvorbis-1.3.5 
        ./configure --enable-static --prefix="/apps/ffmpeg/dyn" 
        time make -j$(nproc) 
        time make -j$(nproc) install 
        time make clean -j$(nproc) 
        time make distclean 
    

    (克)。构建FFmpeg的:

    cd ~/ffmpeg_sources 
    git clone https://github.com/FFmpeg/FFmpeg -b master 
    cd FFmpeg 
    PATH="/apps/ffmpeg/dyn/bin:$PATH" PKG_CONFIG_PATH="/apps/ffmpeg/dyn/lib/pkgconfig" ./configure \ 
        --pkg-config-flags="--static" \ 
        --prefix="/apps/ffmpeg/dyn" \ 
        --extra-cflags="-I/apps/ffmpeg/dyn/include" \ 
        --extra-ldflags="-L/apps/ffmpeg/dyn/lib" \ 
        --bindir="/apps/ffmpeg/dyn/bin" \ 
        --enable-debug=3 \ 
        --enable-vaapi \ 
        --enable-libvorbis \ 
        --enable-libvpx \ 
        --enable-gpl \ 
        --cpu=native \ 
        --enable-opengl \ 
        --enable-libfdk-aac \ 
        --enable-libx264 \ 
        --enable-libx265 \ 
        --enable-nonfree 
    PATH="/apps/ffmpeg/dyn/bin:$PATH" make -j$(nproc) 
    make -j$(nproc) install 
    make -j$(nproc) distclean 
    hash -r 
    

    注:要获得调试版本,省略distclean一步,你会发现来源子目录下ffmpeg_g二进制文件。

    当出现问题并且出于调试目的可能需要gdb跟踪时,我们经常希望调试构建。

    (如必要的,如果你的前缀不同,如果需要增加冲突编辑)环境模块文件的FFmpeg:

    less /usr/share/modules/modulefiles/ffmpeg/vaapi 
    
    
    #%Module1.0##################################################################### 
    ## 
    ## ffmpeg media transcoder modulefile 
    ## By Dennis Mungai <[email protected]> 
    ## February, 2016 
    ## 
    
    # for Tcl script use only 
    set  appname   ffmpeg 
    set  version   dyn 
    set  prefix   /apps/${appname}/${version} 
    set  exec_prefix  ${prefix}/bin 
    
    conflict  ffmpeg/git 
    
    prepend-path PATH   ${exec_prefix} 
    prepend-path LD_LIBRARY_PATH ${prefix}/lib 
    

    要加载和测试,运行:

    module load ffmpeg/vaapi 
    

    确认

    which ffmpeg 
    

    预期输出:

    所有经由是明智的个
    /apps/ffmpeg/dyn/bin/ffmpeg 
    

    样品片段来测试新的编码器:

    确认的VAAPI编码器已成功建成:

    ffmpeg -hide_banner -encoders | grep vaapi 
    
    V..... h264_vaapi   H.264/AVC (VAAPI) (codec h264) 
    V..... hevc_vaapi   H.265/HEVC (VAAPI) (codec hevc) 
    V..... mjpeg_vaapi   MJPEG (VAAPI) (codec mjpeg) 
    V..... mpeg2_vaapi   MPEG-2 (VAAPI) (codec mpeg2video) 
    V..... vp8_vaapi   VP8 (VAAPI) (codec vp8) 
    

    请参阅帮助文档有关每个编码器:

    ffmpeg -hide_banner -h encoder='encoder name' 
    

    测试编码器;

    使用GNU并行,我们将使用示例分别将系统上的〜/ src路径上的一些mp4文件(4k H.264测试样本,每个40分钟,AAC 6声道音频)编码为VP8和HEVC下面。请注意,我已经调整了编码器以适合我的使用情况,并且启用了重新缩放到1080p。必要时进行调整。

    要VP8,发射同时10个编码作业:

    parallel -j 10 --verbose '/apps/ffmpeg/dyn/bin/ffmpeg -loglevel debug -threads 4 -hwaccel vaapi -i "{}" -vaapi_device /dev/dri/renderD129 -c:v vp8_vaapi -loop_filter_level:v 63 -loop_filter_sharpness:v 15 -b:v 4500k -maxrate:v 7500k -vf 'format=nv12,hwupload,scale_vaapi=w=1920:h=1080' -c:a libvorbis -b:a 384k -ac 6 -f webm "{.}.webm"' ::: $(find . -type f -name '*.mp4') 
    

    要HEVC与GNU并行:

    要HEVC主轮廓,启动同时10个编码作业:

    parallel -j 4 --verbose '/apps/ffmpeg/dyn/bin/ffmpeg -loglevel debug -threads 4 -hwaccel vaapi -i "{}" -vaapi_device /dev/dri/renderD129 -c:v hevc_vaapi -qp:v 19 -b:v 2100k -maxrate:v 3500k -vf 'format=nv12,hwupload,scale_vaapi=w=1920:h=1080' -c:a libvorbis -b:a 384k -ac 6 -f matroska "{.}.mkv"' ::: $(find . -type f -name '*.mp4') 
    

    一些注意事项:

    1. 英特尔的QuickSync非常高效。使用10个同时运行的编码查看功率利用率曲线和平均系统负载here
    2. Skylake的HEVC编码器速度很慢,我怀疑在我的硬件上可能比基于软件的x265编码器和kvazaar的HEVC编码器慢。但是,如果调整得当,其质量显着优于其他基于硬件的编码器,例如Maxwell GM200系列SKU上的Nvidia NVENC HEVC编码器。然而,Pascal上的NVENC编码器速度更快,优于英特尔Skylake HEVC编码器。
    3. 与Nvidia的NVENC不同,消费者SKU没有同步编码限制。我能够与VAAPI同时运行10个编码会话,而使用NVENC时,我只能在测试台上的GeForce GTX系列GPU上同时进行两次编码。良好的工作,英特尔。

    嘿家伙,小小的更新:VP9硬件加速编码现在可用于FFmpeg。但是,您需要基于Intel Kabylake的集成GPU才能利用此功能。

    现在,使用新的vp9_vaapi编码器,这里是我们得到的。

    编码器选项现已:

    ffmpeg -h vp9_vaapi 
    

    输出:

    Encoder vp9_vaapi [VP9 (VAAPI)]: 
        General capabilities: delay 
        Threading capabilities: none 
        Supported pixel formats: vaapi_vld 
    vp9_vaapi AVOptions: 
        -loop_filter_level <int>  E..V.... Loop filter level (from 0 to 63) (default 16) 
        -loop_filter_sharpness <int>  E..V.... Loop filter sharpness (from 0 to 15) (default 4) 
    

    当您尝试退出这个功能在不支持的硬件,说SKYLAKE微架构会发生什么?

    请参见下面的示例输出:

    [Parsed_format_0 @ 0x42cb500] compat: called with args=[nv12] 
    [Parsed_format_0 @ 0x42cb500] Setting 'pix_fmts' to value 'nv12' 
    [Parsed_scale_vaapi_2 @ 0x42cc300] Setting 'w' to value '1920' 
    [Parsed_scale_vaapi_2 @ 0x42cc300] Setting 'h' to value '1080' 
    [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'video_size' to value '3840x2026' 
    [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'pix_fmt' to value '0' 
    [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'time_base' to value '1/1000' 
    [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'pixel_aspect' to value '1/1' 
    [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'sws_param' to value 'flags=2' 
    [graph 0 input from stream 0:0 @ 0x42cce00] Setting 'frame_rate' to value '24000/1001' 
    [graph 0 input from stream 0:0 @ 0x42cce00] w:3840 h:2026 pixfmt:yuv420p tb:1/1000 fr:24000/1001 sar:1/1 sws_param:flags=2 
    [format @ 0x42cba40] compat: called with args=[vaapi_vld] 
    [format @ 0x42cba40] Setting 'pix_fmts' to value 'vaapi_vld' 
    [auto_scaler_0 @ 0x42cd580] Setting 'flags' to value 'bicubic' 
    [auto_scaler_0 @ 0x42cd580] w:iw h:ih flags:'bicubic' interl:0 
    [Parsed_format_0 @ 0x42cb500] auto-inserting filter 'auto_scaler_0' between the filter 'graph 0 input from stream 0:0' and the filter 'Parsed_format_0' 
    [AVFilterGraph @ 0x42ca360] query_formats: 6 queried, 4 merged, 1 already done, 0 delayed 
    [auto_scaler_0 @ 0x42cd580] w:3840 h:2026 fmt:yuv420p sar:1/1 -> w:3840 h:2026 fmt:nv12 sar:1/1 flags:0x4 
    [hwupload @ 0x42cbcc0] Surface format is nv12. 
    [AVHWFramesContext @ 0x42ccbc0] Created surface 0x4000000. 
    [AVHWFramesContext @ 0x42ccbc0] Direct mapping possible. 
    [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000001. 
    [AVHWFramesContext @ 0x42c3e40] Direct mapping possible. 
    [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000002. 
    [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000003. 
    [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000004. 
    [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000005. 
    [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000006. 
    [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000007. 
    [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000008. 
    [AVHWFramesContext @ 0x42c3e40] Created surface 0x4000009. 
    [AVHWFramesContext @ 0x42c3e40] Created surface 0x400000a. 
    [vp9_vaapi @ 0x409da40] Encoding entrypoint not found (19/6). 
    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 
    [AVIOContext @ 0x40fdac0] Statistics: 0 seeks, 0 writeouts 
    [aac @ 0x40fcb00] Qavg: -nan 
    [AVIOContext @ 0x409f820] Statistics: 32768 bytes read, 0 seeks 
    Conversion failed! 
    

    有趣位用于VP9编码入口点的警告在此特定平台缺席,通过vainfo的输出作为确认:

    libva info: VA-API version 0.40.0 
    libva info: va_getDriverName() returns 0 
    libva info: Trying to open /usr/local/lib/dri/i965_drv_video.so 
    libva info: Found init function __vaDriverInit_0_40 
    libva info: va_openDriver() returns 0 
    vainfo: VA-API version: 0.40 (libva 1.7.3) 
    vainfo: Driver version: Intel i965 driver for Intel(R) Skylake - 1.8.4.pre1 (glk-alpha-71-gc3110dc) 
    vainfo: Supported profile and entrypoints 
         VAProfileMPEG2Simple   : VAEntrypointVLD 
         VAProfileMPEG2Simple   : VAEntrypointEncSlice 
         VAProfileMPEG2Main    : VAEntrypointVLD 
         VAProfileMPEG2Main    : VAEntrypointEncSlice 
         VAProfileH264ConstrainedBaseline: VAEntrypointVLD 
         VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice 
         VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP 
         VAProfileH264Main    : VAEntrypointVLD 
         VAProfileH264Main    : VAEntrypointEncSlice 
         VAProfileH264Main    : VAEntrypointEncSliceLP 
         VAProfileH264High    : VAEntrypointVLD 
         VAProfileH264High    : VAEntrypointEncSlice 
         VAProfileH264High    : VAEntrypointEncSliceLP 
         VAProfileH264MultiviewHigh  : VAEntrypointVLD 
         VAProfileH264MultiviewHigh  : VAEntrypointEncSlice 
         VAProfileH264StereoHigh   : VAEntrypointVLD 
         VAProfileH264StereoHigh   : VAEntrypointEncSlice 
         VAProfileVC1Simple    : VAEntrypointVLD 
         VAProfileVC1Main    : VAEntrypointVLD 
         VAProfileVC1Advanced   : VAEntrypointVLD 
         VAProfileNone     : VAEntrypointVideoProc 
         VAProfileJPEGBaseline   : VAEntrypointVLD 
         VAProfileJPEGBaseline   : VAEntrypointEncPicture 
         VAProfileVP8Version0_3   : VAEntrypointVLD 
         VAProfileVP8Version0_3   : VAEntrypointEncSlice 
         VAProfileHEVCMain    : VAEntrypointVLD 
         VAProfileHEVCMain    : VAEntrypointEncSlice 
         VAProfileVP9Profile0   : VAEntrypointVLD 
    

    的VLD(对于可变长度解码)VP9配置文件0的入口点是Skylake就VP9硬件加速而言最远的地方。

    这些与Kabylake测试床,运行这些编码测试和回报:-)