[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