[FFmpeg-devel] [PATCH] libi264: Add Hardware Accelerated H.264 Encoder based on libVA

Michael Niedermayer michael at niedermayer.cc
Thu Dec 31 22:07:56 CET 2015


On Thu, Dec 31, 2015 at 10:35:47PM +0500, hamza at mayartech.com wrote:
> From: Bryan Christ <bryan.christ at mediafire.com>
> 
> This commit adds a hardware accelerated H.264 encoder which utilizes
> libVA (open source implementation of VA-API). Information about libva
> is available at: https://en.wikipedia.org/wiki/Video_Acceleration_API
> This encoder is only availbale on linux and supported hardware which
> can be viewed at:
> https://en.wikipedia.org/wiki/Video_Acceleration_API#Supported_hardware_and_drivers
> 
> The short name for encoder is "libi264". The encoder must be enablde at
> configure time using the --enable-libi264 switch. By default it is
> turned off.
> ---
>  Changelog                           |    1 +
>  MAINTAINERS                         |    1 +
>  configure                           |    8 +-
>  doc/general.texi                    |   11 +
>  libavcodec/Makefile                 |    1 +
>  libavcodec/allcodecs.c              |    1 +
>  libavcodec/libi264.c                | 1476 +++++++++++++++++++++++++++++++++++
>  libavcodec/libi264.h                |  107 +++
>  libavcodec/libi264_param_set.c      |  425 ++++++++++
>  libavcodec/libi264_param_set.h      |   81 ++
>  libavcodec/libi264_va_display.c     |  104 +++
>  libavcodec/libi264_va_display.h     |   77 ++
>  libavcodec/libi264_va_display_drm.c |   96 +++
>  libavcodec/libi264_va_display_x11.c |  171 ++++
>  libavcodec/version.h                |    2 +-
>  15 files changed, 2560 insertions(+), 2 deletions(-)
>  create mode 100644 libavcodec/libi264.c
>  create mode 100644 libavcodec/libi264.h
>  create mode 100644 libavcodec/libi264_param_set.c
>  create mode 100644 libavcodec/libi264_param_set.h
>  create mode 100644 libavcodec/libi264_va_display.c
>  create mode 100644 libavcodec/libi264_va_display.h
>  create mode 100644 libavcodec/libi264_va_display_drm.c
>  create mode 100644 libavcodec/libi264_va_display_x11.c
> 
> diff --git a/Changelog b/Changelog
> index d9c2ea8..99acb56 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -49,6 +49,7 @@ version <next>:
>  - VAAPI VP9 hwaccel
>  - audio high-order multiband parametric equalizer
>  - automatic bitstream filtering
> +- H.264 hwaccelerated encoding through libVA
>  
>  
>  version 2.8:
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 9add13d..e37cb6f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -203,6 +203,7 @@ Codecs:
>    libcelt_dec.c                         Nicolas George
>    libdirac*                             David Conrad
>    libgsm.c                              Michel Bardiaux
> +  libi264*                              Bryan Christ
>    libkvazaar.c                          Arttu Ylä-Outinen
>    libopenjpeg.c                         Jaikrishnan Menon
>    libopenjpegenc.c                      Michael Bradshaw
> diff --git a/configure b/configure
> index da74ccd..335c172 100755
> --- a/configure
> +++ b/configure
> @@ -265,6 +265,7 @@ External library support:
>    --enable-libwavpack      enable wavpack encoding via libwavpack [no]
>    --enable-libwebp         enable WebP encoding via libwebp [no]
>    --enable-libx264         enable H.264 encoding via x264 [no]
> +  --enable-libi264         enable H.264 encoding via Intel's libva [no]
>    --enable-libx265         enable HEVC encoding via x265 [no]
>    --enable-libxavs         enable AVS encoding via xavs [no]
>    --enable-libxcb          enable X11 grabbing using XCB [autodetect]
> @@ -1484,6 +1485,9 @@ EXTERNAL_LIBRARY_LIST="
>      libtwolame
>      libutvideo
>      libv4l2
> +    libva
> +    libva-drm
> +    libva-x11
>      libvidstab
>      libvo_aacenc
>      libvo_amrwbenc

> @@ -1491,6 +1495,7 @@ EXTERNAL_LIBRARY_LIST="
>      libvpx
>      libwavpack
>      libwebp
> +    libX11
>      libx264
>      libx265
>      libxavs

?


> @@ -2658,7 +2663,7 @@ libwebp_anim_encoder_deps="libwebp"
>  libx262_encoder_deps="libx262"
>  libx264_encoder_deps="libx264"
>  libx264rgb_encoder_deps="libx264"
> -libx264rgb_encoder_select="libx264_encoder"

this looks unintended


> +libi264_encoder_deps="libi264"
>  libx265_encoder_deps="libx265"
>  libxavs_encoder_deps="libxavs"
>  libxvid_encoder_deps="libxvid"
> @@ -5528,6 +5533,7 @@ enabled libx264           && { use_pkg_config x264 "stdint.h x264.h" x264_encode
>                                 die "ERROR: libx264 must be installed and version must be >= 0.118."; } &&
>                               { check_cpp_condition x264.h "X264_MPEG2" &&
>                                 enable libx262; }
> +enabled libi264           && require libva va/va.h vaInitialize -lva -lX11 -lva-x11 -lva-drm
>  enabled libx265           && require_pkg_config x265 x265.h x265_api_get &&
>                               { check_cpp_condition x265.h "X265_BUILD >= 57" ||
>                                 die "ERROR: libx265 version must be >= 57."; }

also the patch breaks configure

./configure
./configure: 1: eval: libva-drm_checking=yes: not found
./configure: 1: eval: -drm_deps_checking=yes: not found
./configure: 1: eval: -drm_deps=no: not found
./configure: 1: eval: -drm_deps=no: not found
...

[...]
> index 0000000..272954c
> --- /dev/null
> +++ b/libavcodec/libi264.c
> @@ -0,0 +1,1476 @@
> +/*
> + * Interface for libva H.264 encoding using libva library meant for hardware
> + * encoding on intel processors
> + * Copyright (C) 2015 Bryan Christ
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#include <va/va.h>
> +
> +#include "libi264.h"
> +#include "libi264_param_set.h"
> +#include "libi264_va_display.h"
> +#include "avcodec.h"
> +#include "libavutil/internal.h"
> +#include "libavutil/pixdesc.h"
> +#include "libavutil/opt.h"
> +#include "libavcodec/internal.h"
> +
> +
> +#define FRAME_P 0
> +#define FRAME_B 1
> +#define FRAME_I 2
> +#define FRAME_IDR 7
> +
> +

> +static  unsigned int max_frame_num = (2<<16);
> +static  unsigned int max_pic_order_cnt_lsb = (2<<8);
> +static  unsigned int log2_max_frame_num = 16;
> +static  unsigned int log2_max_pic_order_cnt_lsb = 8;

these should be const or #defines


> +
> +
> +#define CHECK_VASTATUS(avctx, va_status,func)                                         \
> +    if (va_status != VA_STATUS_SUCCESS) {                                             \
> +        av_log(avctx, AV_LOG_ERROR, "%s:%s (%d) failed\n", __func__, func, __LINE__); \
> +        return -1;                                                                    \
> +    }
> +
> +#define current_slot(ictx) (ictx->current_frame_display % SURFACE_NUM)
> +

> +static int string_to_rc(char *str)
> +{
> +    int rc_mode;
> +
> +    if (!strncmp(str, "NONE", 4))
> +        rc_mode = VA_RC_NONE;
> +    else if (!strncmp(str, "CBR", 3))
> +        rc_mode = VA_RC_CBR;
> +    else if (!strncmp(str, "VBR", 3))
> +        rc_mode = VA_RC_VBR;
> +    else if (!strncmp(str, "VCM", 3))
> +        rc_mode = VA_RC_VCM;
> +    else if (!strncmp(str, "CQP", 3))
> +        rc_mode = VA_RC_CQP;
> +    else if (!strncmp(str, "VBR_CONSTRAINED", 15))
> +        rc_mode = VA_RC_VBR_CONSTRAINED;
> +    else {
> +        rc_mode = VA_RC_VBR;
> +    }
> +    return rc_mode;
> +}

AVOption supports named constants, this is not needed


[...]
> +    for (row = 0; row < frame->height/2; row++) {
> +        unsigned char *U_row = U_start + row * U_pitch;
> +        unsigned char *u_ptr = NULL, *v_ptr=NULL;
> +//      int j;
> +        int j, N, Nmod;
> +        switch (surface_image.format.fourcc) {
> +        case VA_FOURCC_NV12:
> +            u_ptr = frame->data[1] + row * frame->linesize[1];
> +            v_ptr = frame->data[2] + row * frame->linesize[2];
> +
> +
> +                        Nmod = (frame->width/2) & 7; // mod 8
> +                        N    = (frame->width/2) - Nmod;
> +                        __asm__(
> +                                "movq      %0,      %%rax  \n\t"
> +                                "movq      %1,      %%rbx  \n\t"
> +                                "movq      %2,      %%rcx  \n\t"
> +                                "movq      %3,      %%rdx  \n\t"
> +                                "asm_loop:                 \n\t"
> +                                "movq      (%%rax), %%xmm0 \n\t"
> +                                "movq      (%%rbx), %%xmm1 \n\t"
> +                                "punpcklbw %%xmm1,  %%xmm0 \n\t"
> +                                "movdqu    %%xmm0,  (%%rcx)\n\t"
> +                                "addq      $0x8,    %%rax  \n\t"
> +                                "addq      $0x8,    %%rbx  \n\t"
> +                                "addq      $0x10,   %%rcx  \n\t"
> +                                "cmp       %%rcx,   %%rdx  \n\t"
> +                                "jnz       asm_loop"
> +                                :
> +                                : "r"(u_ptr), "r"(v_ptr), "r"(U_row),
> +                                  "r" (U_row+2*N)
> +                                : "rax", "rbx", "rcx", "rdx", "xmm0", "xmm1"
> +                        );

x86* asm belongs in yasm files
colorspace convertion belongs to vf_scale / swscale, why is this
code here ?
also FFmpeg supports many platforms, not just x86 based ones
asm should be behind appropriate ARCH_* & cpuflags checks


[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

The real ebay dictionary, page 1
"Used only once"    - "Some unspecified defect prevented a second use"
"In good condition" - "Can be repaird by experienced expert"
"As is" - "You wouldnt want it even if you were payed for it, if you knew ..."
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20151231/c902a311/attachment.sig>


More information about the ffmpeg-devel mailing list