Re: [FFmpeg-devel] [PATCH v3 2/5] ffmpeg: initialisation code for VAAPI, hwaccel helper

2016-01-19 Thread wm4
On Mon, 18 Jan 2016 22:50:50 +
Mark Thompson  wrote:

> ---
>  Makefile   |   1 +
>  ffmpeg.c   |   5 +
>  ffmpeg.h   |   5 +
>  ffmpeg_opt.c   |  14 ++
>  ffmpeg_vaapi.c | 622 
> +
>  5 files changed, 647 insertions(+)
>  create mode 100644 ffmpeg_vaapi.c
> 
> diff --git a/Makefile b/Makefile
> index 7836a20..be1d2ca 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -36,6 +36,7 @@ OBJS-ffmpeg-$(CONFIG_VDA) += ffmpeg_videotoolbox.o
>  endif
>  OBJS-ffmpeg-$(CONFIG_VIDEOTOOLBOX) += ffmpeg_videotoolbox.o
>  OBJS-ffmpeg-$(CONFIG_LIBMFX)  += ffmpeg_qsv.o
> +OBJS-ffmpeg-$(CONFIG_VAAPI)   += ffmpeg_vaapi.o
>  OBJS-ffserver += ffserver_config.o
> 
>  TESTTOOLS   = audiogen videogen rotozoom tiny_psnr tiny_ssim base64
> diff --git a/ffmpeg.c b/ffmpeg.c
> index 1f4277c..e76879a 100644
> --- a/ffmpeg.c
> +++ b/ffmpeg.c
> @@ -2603,6 +2603,11 @@ static int init_output_stream(OutputStream *ost, char 
> *error, int error_len)
>  !av_dict_get(ost->encoder_opts, "ab", NULL, 0))
>  av_dict_set(>encoder_opts, "b", "128000", 0);
> 
> +#if CONFIG_VAAPI
> +if(ost->enc->type == AVMEDIA_TYPE_VIDEO)
> +vaapi_hardware_set_options(>encoder_opts);
> +#endif
> +
>  if ((ret = avcodec_open2(ost->enc_ctx, codec, >encoder_opts)) < 
> 0) {
>  if (ret == AVERROR_EXPERIMENTAL)
>  abort_codec_experimental(codec, 1);
> diff --git a/ffmpeg.h b/ffmpeg.h
> index 20322b0..2134213 100644
> --- a/ffmpeg.h
> +++ b/ffmpeg.h
> @@ -65,6 +65,7 @@ enum HWAccelID {
>  HWACCEL_VDA,
>  HWACCEL_VIDEOTOOLBOX,
>  HWACCEL_QSV,
> +HWACCEL_VAAPI,
>  };
> 
>  typedef struct HWAccel {
> @@ -577,5 +578,9 @@ int vda_init(AVCodecContext *s);
>  int videotoolbox_init(AVCodecContext *s);
>  int qsv_init(AVCodecContext *s);
>  int qsv_transcode_init(OutputStream *ost);
> +int vaapi_decode_init(AVCodecContext *s);
> +
> +int vaapi_hardware_init(const char *device);
> +int vaapi_hardware_set_options(AVDictionary **dict);
> 
>  #endif /* FFMPEG_H */
> diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
> index 9b341cf..47ac467 100644
> --- a/ffmpeg_opt.c
> +++ b/ffmpeg_opt.c
> @@ -82,6 +82,9 @@ const HWAccel hwaccels[] = {
>  #if CONFIG_LIBMFX
>  { "qsv",   qsv_init,   HWACCEL_QSV,   AV_PIX_FMT_QSV },
>  #endif
> +#if CONFIG_VAAPI
> +{ "vaapi", vaapi_decode_init, HWACCEL_VAAPI, AV_PIX_FMT_VAAPI },
> +#endif
>  { 0 },
>  };
> 
> @@ -442,6 +445,13 @@ static int opt_sdp_file(void *optctx, const char *opt, 
> const char *arg)
>  return 0;
>  }
> 
> +static int opt_vaapi(void *optctx, const char *opt, const char *arg)
> +{
> +if(vaapi_hardware_init(arg))
> +exit_program(1);
> +return 0;
> +}
> +
>  /**
>   * Parse a metadata specifier passed as 'arg' parameter.
>   * @param arg  metadata string to parse
> @@ -3438,5 +3448,9 @@ const OptionDef options[] = {
>  { "dn", OPT_BOOL | OPT_VIDEO | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, { 
> .off = OFFSET(data_disable) },
>  "disable data" },
> 
> +#if CONFIG_VAAPI
> +{ "vaapi", HAS_ARG, { .func_arg = opt_vaapi }, "set VAAPI hardware 
> context" },
> +#endif
> +
>  { NULL, },
>  };
> diff --git a/ffmpeg_vaapi.c b/ffmpeg_vaapi.c
> new file mode 100644
> index 000..e04532c
> --- /dev/null
> +++ b/ffmpeg_vaapi.c
> @@ -0,0 +1,622 @@
> +/*
> + * VAAPI helper for hardware-accelerated decoding.
> + *
> + * Copyright (C) 2016 Mark Thompson 
> + *
> + * 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 
> +#include 
> +#include 
> +
> +#include "ffmpeg.h"
> +
> +#include "libavutil/avassert.h"
> +#include "libavutil/avconfig.h"
> +#include "libavutil/buffer.h"
> +#include "libavutil/frame.h"
> +#include "libavutil/imgutils.h"
> +#include "libavutil/opt.h"
> +#include "libavutil/pixfmt.h"
> +#include "libavutil/thread.h"
> +#include "libavutil/vaapi.h"
> +
> +#include "libavcodec/vaapi.h"
> +
> +#include 
> +#include 
> +
> +
> +static AVClass vaapi_class = {
> +.class_name = "VAAPI/driver",
> +.item_name  = av_default_item_name,
> +.version= LIBAVUTIL_VERSION_INT,
> +};
> +
> +
> +#define DEFAULT_SURFACES 20
> +
> 

Re: [FFmpeg-devel] [PATCH v3 2/5] ffmpeg: initialisation code for VAAPI, hwaccel helper

2016-01-19 Thread wm4
On Tue, 19 Jan 2016 13:54:25 +
Mark Thompson  wrote:

> >> +surface = (AVVAAPISurface*)input_frame->buf[0]->data;  
> > 
> > I haven't paid attention to this before. Shouldn't this be a vaapi
> > surface ID according to how libavcodec works?  
> 
> data[3] is the VAAPI surface ID, as used in libavcodec.
> 
> Here we need to carry more information around in order to have enough context 
> to map/unmap the surface.

Still slightly questionable. Does this mean the user can't create
surfaces and pass them to an API which happens to expect this set?

Also, it would be cleaner to set this on a data pointer too. For
example AVFrame.data[1]. (In fact, it would be pretty sane to do it
this way. This also fulfills the AVFrame "rule" that the memory
referenced by data pointers should be covered by AVFrame.buf. We even
thought about doing this in an uniform way across all hwaccels, so that
every hwaccel would use the same struct type.)

> >> +av_log(ctx, AV_LOG_DEBUG, "Retrieve data from surface %#x (format 
> >> %#x).\n",
> >> +   surface->id, output->av_format);
> >> +
> >> +av_vaapi_lock_hardware_context(ctx->hardware_context);
> >> +
> >> +if(output->av_format == AV_PIX_FMT_VAAPI) {
> >> +copying = 0;
> >> +av_log(ctx, AV_LOG_VERBOSE, "Surface %#x retrieved without 
> >> copy.\n",
> >> +   surface->id);  
> > 
> > I'm not sure if this (and the one below) deserves a log message, and at
> > a verbose level at that. If you really want this, a trace level might be
> > better.  
> 
> This was mainly so that at -v 55 I could see what was going on without being 
> totally spammed (well, several lines per frame).
> 
> I'll demote these (and others in the codecs which are saying the same thing).

In general, I'm not very fond of all these log calls (they just make
the code harder to read once you're done with the implementation), but
I'll leave this to you to decide. (Or maybe others have opinions.)

> >> +
> >> +} else {
> >> +err = ff_vaapi_map_surface(surface, 1);
> >> +if(err) {
> >> +av_log(ctx, AV_LOG_ERROR, "Failed to map surface %#x.",
> >> +   surface->id);
> >> +goto fail;
> >> +}
> >> +
> >> +copying = 1;
> >> +av_log(ctx, AV_LOG_VERBOSE, "Surface %#x mapped: image %#x data 
> >> %p.\n",
> >> +   surface->id, surface->image.image_id, 
> >> surface->mapped_address);
> >> +}
> >> +
> >> +// The actual frame need not fill the surface.
> >> +av_assert0(input_frame->width  <= output->width);
> >> +av_assert0(input_frame->height <= output->height);
> >> +
> >> +output_frame = >output_frame;
> >> +output_frame->width  = input_frame->width;
> >> +output_frame->height = input_frame->height;
> >> +output_frame->format = output->av_format;
> >> +
> >> +if(copying) {
> >> +err = av_frame_get_buffer(output_frame, 32);
> >> +if(err < 0) {
> >> +av_log(ctx, AV_LOG_ERROR, "Failed to get output buffer: %d 
> >> (%s).\n",
> >> +   err, av_err2str(err));
> >> +goto fail_unmap;
> >> +}
> >> +
> >> +err = ff_vaapi_copy_from_surface(output_frame, surface);
> >> +if(err < 0) {
> >> +av_log(ctx, AV_LOG_ERROR, "Failed to copy frame data: %d 
> >> (%s).\n",
> >> +   err, av_err2str(err));
> >> +goto fail_unmap;
> >> +}
> >> +
> >> +} else {
> >> +// Just copy the hidden ID field.
> >> +output_frame->data[3] = input_frame->data[3];
> >> +}
> >> +
> >> +err = av_frame_copy_props(output_frame, input_frame);
> >> +if(err < 0) {
> >> +av_log(ctx, AV_LOG_ERROR, "Failed to copy frame props: %d 
> >> (%s).\n",
> >> +   err, av_err2str(err));
> >> +goto fail_unmap;
> >> +}
> >> +
> >> +av_frame_unref(input_frame);
> >> +av_frame_move_ref(input_frame, output_frame);
> >> +
> >> +  fail_unmap:
> >> +if(copying)
> >> +ff_vaapi_unmap_surface(surface, 0);
> >> +  fail:
> >> +av_vaapi_unlock_hardware_context(ctx->hardware_context);
> >> +return err;
> >> +}  
> > 
> > This whole thing could be a utility function. (Libav was planning to do
> > this.)  
> 
> Unsure, I'll think about it along with AVFrame redesign.  If nothing else, 
> the map/copy/unmap could be abstracted out.
> 
> >> +
> >> +static const struct {
> >> +VAProfile from;
> >> +VAProfile to;
> >> +} vaapi_profile_compatibility[] = {
> >> +#define FT(f, t) { VAProfile ## f, VAProfile ## t }
> >> +FT(MPEG2Simple, MPEG2Main   ),
> >> +FT(H263Baseline, MPEG4AdvancedSimple),
> >> +FT(MPEG4Simple,  MPEG4AdvancedSimple),
> >> +FT(MPEG4AdvancedSimple, MPEG4Main   ),
> >> +FT(H264ConstrainedBaseline, H264Baseline),
> >> +FT(H264Baseline,H264Main), // (Not quite true.)
> >> +FT(H264Main,

Re: [FFmpeg-devel] [PATCH v3 2/5] ffmpeg: initialisation code for VAAPI, hwaccel helper

2016-01-19 Thread Mark Thompson
On 19/01/16 12:16, wm4 wrote:
> On Mon, 18 Jan 2016 22:50:50 +
> Mark Thompson  wrote:
> 
>> ---
>>  Makefile   |   1 +
>>  ffmpeg.c   |   5 +
>>  ffmpeg.h   |   5 +
>>  ffmpeg_opt.c   |  14 ++
>>  ffmpeg_vaapi.c | 622 
>> +
>>  5 files changed, 647 insertions(+)
>>  create mode 100644 ffmpeg_vaapi.c
>>
>> diff --git a/Makefile b/Makefile
>> index 7836a20..be1d2ca 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -36,6 +36,7 @@ OBJS-ffmpeg-$(CONFIG_VDA) += ffmpeg_videotoolbox.o
>>  endif
>>  OBJS-ffmpeg-$(CONFIG_VIDEOTOOLBOX) += ffmpeg_videotoolbox.o
>>  OBJS-ffmpeg-$(CONFIG_LIBMFX)  += ffmpeg_qsv.o
>> +OBJS-ffmpeg-$(CONFIG_VAAPI)   += ffmpeg_vaapi.o
>>  OBJS-ffserver += ffserver_config.o
>>
>>  TESTTOOLS   = audiogen videogen rotozoom tiny_psnr tiny_ssim base64
>> diff --git a/ffmpeg.c b/ffmpeg.c
>> index 1f4277c..e76879a 100644
>> --- a/ffmpeg.c
>> +++ b/ffmpeg.c
>> @@ -2603,6 +2603,11 @@ static int init_output_stream(OutputStream *ost, char 
>> *error, int error_len)
>>  !av_dict_get(ost->encoder_opts, "ab", NULL, 0))
>>  av_dict_set(>encoder_opts, "b", "128000", 0);
>>
>> +#if CONFIG_VAAPI
>> +if(ost->enc->type == AVMEDIA_TYPE_VIDEO)
>> +vaapi_hardware_set_options(>encoder_opts);
>> +#endif
>> +
>>  if ((ret = avcodec_open2(ost->enc_ctx, codec, >encoder_opts)) 
>> < 0) {
>>  if (ret == AVERROR_EXPERIMENTAL)
>>  abort_codec_experimental(codec, 1);
>> diff --git a/ffmpeg.h b/ffmpeg.h
>> index 20322b0..2134213 100644
>> --- a/ffmpeg.h
>> +++ b/ffmpeg.h
>> @@ -65,6 +65,7 @@ enum HWAccelID {
>>  HWACCEL_VDA,
>>  HWACCEL_VIDEOTOOLBOX,
>>  HWACCEL_QSV,
>> +HWACCEL_VAAPI,
>>  };
>>
>>  typedef struct HWAccel {
>> @@ -577,5 +578,9 @@ int vda_init(AVCodecContext *s);
>>  int videotoolbox_init(AVCodecContext *s);
>>  int qsv_init(AVCodecContext *s);
>>  int qsv_transcode_init(OutputStream *ost);
>> +int vaapi_decode_init(AVCodecContext *s);
>> +
>> +int vaapi_hardware_init(const char *device);
>> +int vaapi_hardware_set_options(AVDictionary **dict);
>>
>>  #endif /* FFMPEG_H */
>> diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
>> index 9b341cf..47ac467 100644
>> --- a/ffmpeg_opt.c
>> +++ b/ffmpeg_opt.c
>> @@ -82,6 +82,9 @@ const HWAccel hwaccels[] = {
>>  #if CONFIG_LIBMFX
>>  { "qsv",   qsv_init,   HWACCEL_QSV,   AV_PIX_FMT_QSV },
>>  #endif
>> +#if CONFIG_VAAPI
>> +{ "vaapi", vaapi_decode_init, HWACCEL_VAAPI, AV_PIX_FMT_VAAPI },
>> +#endif
>>  { 0 },
>>  };
>>
>> @@ -442,6 +445,13 @@ static int opt_sdp_file(void *optctx, const char *opt, 
>> const char *arg)
>>  return 0;
>>  }
>>
>> +static int opt_vaapi(void *optctx, const char *opt, const char *arg)
>> +{
>> +if(vaapi_hardware_init(arg))
>> +exit_program(1);
>> +return 0;
>> +}
>> +
>>  /**
>>   * Parse a metadata specifier passed as 'arg' parameter.
>>   * @param arg  metadata string to parse
>> @@ -3438,5 +3448,9 @@ const OptionDef options[] = {
>>  { "dn", OPT_BOOL | OPT_VIDEO | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, { 
>> .off = OFFSET(data_disable) },
>>  "disable data" },
>>
>> +#if CONFIG_VAAPI
>> +{ "vaapi", HAS_ARG, { .func_arg = opt_vaapi }, "set VAAPI hardware 
>> context" },
>> +#endif
>> +
>>  { NULL, },
>>  };
>> diff --git a/ffmpeg_vaapi.c b/ffmpeg_vaapi.c
>> new file mode 100644
>> index 000..e04532c
>> --- /dev/null
>> +++ b/ffmpeg_vaapi.c
>> @@ -0,0 +1,622 @@
>> +/*
>> + * VAAPI helper for hardware-accelerated decoding.
>> + *
>> + * Copyright (C) 2016 Mark Thompson 
>> + *
>> + * 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 
>> +#include 
>> +#include 
>> +
>> +#include "ffmpeg.h"
>> +
>> +#include "libavutil/avassert.h"
>> +#include "libavutil/avconfig.h"
>> +#include "libavutil/buffer.h"
>> +#include "libavutil/frame.h"
>> +#include "libavutil/imgutils.h"
>> +#include "libavutil/opt.h"
>> +#include "libavutil/pixfmt.h"
>> +#include "libavutil/thread.h"
>> +#include "libavutil/vaapi.h"
>> +
>> +#include "libavcodec/vaapi.h"
>> +
>> +#include 
>> +#include 
>> +
>> +
>> +static AVClass vaapi_class 

[FFmpeg-devel] [PATCH v3 2/5] ffmpeg: initialisation code for VAAPI, hwaccel helper

2016-01-18 Thread Mark Thompson

---
 Makefile   |   1 +
 ffmpeg.c   |   5 +
 ffmpeg.h   |   5 +
 ffmpeg_opt.c   |  14 ++
 ffmpeg_vaapi.c | 622 +
 5 files changed, 647 insertions(+)
 create mode 100644 ffmpeg_vaapi.c

diff --git a/Makefile b/Makefile
index 7836a20..be1d2ca 100644
--- a/Makefile
+++ b/Makefile
@@ -36,6 +36,7 @@ OBJS-ffmpeg-$(CONFIG_VDA) += ffmpeg_videotoolbox.o
 endif
 OBJS-ffmpeg-$(CONFIG_VIDEOTOOLBOX) += ffmpeg_videotoolbox.o
 OBJS-ffmpeg-$(CONFIG_LIBMFX)  += ffmpeg_qsv.o
+OBJS-ffmpeg-$(CONFIG_VAAPI)   += ffmpeg_vaapi.o
 OBJS-ffserver += ffserver_config.o

 TESTTOOLS   = audiogen videogen rotozoom tiny_psnr tiny_ssim base64
diff --git a/ffmpeg.c b/ffmpeg.c
index 1f4277c..e76879a 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -2603,6 +2603,11 @@ static int init_output_stream(OutputStream *ost, char 
*error, int error_len)
 !av_dict_get(ost->encoder_opts, "ab", NULL, 0))
 av_dict_set(>encoder_opts, "b", "128000", 0);

+#if CONFIG_VAAPI
+if(ost->enc->type == AVMEDIA_TYPE_VIDEO)
+vaapi_hardware_set_options(>encoder_opts);
+#endif
+
 if ((ret = avcodec_open2(ost->enc_ctx, codec, >encoder_opts)) < 
0) {
 if (ret == AVERROR_EXPERIMENTAL)
 abort_codec_experimental(codec, 1);
diff --git a/ffmpeg.h b/ffmpeg.h
index 20322b0..2134213 100644
--- a/ffmpeg.h
+++ b/ffmpeg.h
@@ -65,6 +65,7 @@ enum HWAccelID {
 HWACCEL_VDA,
 HWACCEL_VIDEOTOOLBOX,
 HWACCEL_QSV,
+HWACCEL_VAAPI,
 };

 typedef struct HWAccel {
@@ -577,5 +578,9 @@ int vda_init(AVCodecContext *s);
 int videotoolbox_init(AVCodecContext *s);
 int qsv_init(AVCodecContext *s);
 int qsv_transcode_init(OutputStream *ost);
+int vaapi_decode_init(AVCodecContext *s);
+
+int vaapi_hardware_init(const char *device);
+int vaapi_hardware_set_options(AVDictionary **dict);

 #endif /* FFMPEG_H */
diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
index 9b341cf..47ac467 100644
--- a/ffmpeg_opt.c
+++ b/ffmpeg_opt.c
@@ -82,6 +82,9 @@ const HWAccel hwaccels[] = {
 #if CONFIG_LIBMFX
 { "qsv",   qsv_init,   HWACCEL_QSV,   AV_PIX_FMT_QSV },
 #endif
+#if CONFIG_VAAPI
+{ "vaapi", vaapi_decode_init, HWACCEL_VAAPI, AV_PIX_FMT_VAAPI },
+#endif
 { 0 },
 };

@@ -442,6 +445,13 @@ static int opt_sdp_file(void *optctx, const char *opt, 
const char *arg)
 return 0;
 }

+static int opt_vaapi(void *optctx, const char *opt, const char *arg)
+{
+if(vaapi_hardware_init(arg))
+exit_program(1);
+return 0;
+}
+
 /**
  * Parse a metadata specifier passed as 'arg' parameter.
  * @param arg  metadata string to parse
@@ -3438,5 +3448,9 @@ const OptionDef options[] = {
 { "dn", OPT_BOOL | OPT_VIDEO | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, { .off 
= OFFSET(data_disable) },
 "disable data" },

+#if CONFIG_VAAPI
+{ "vaapi", HAS_ARG, { .func_arg = opt_vaapi }, "set VAAPI hardware 
context" },
+#endif
+
 { NULL, },
 };
diff --git a/ffmpeg_vaapi.c b/ffmpeg_vaapi.c
new file mode 100644
index 000..e04532c
--- /dev/null
+++ b/ffmpeg_vaapi.c
@@ -0,0 +1,622 @@
+/*
+ * VAAPI helper for hardware-accelerated decoding.
+ *
+ * Copyright (C) 2016 Mark Thompson 
+ *
+ * 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 
+#include 
+#include 
+
+#include "ffmpeg.h"
+
+#include "libavutil/avassert.h"
+#include "libavutil/avconfig.h"
+#include "libavutil/buffer.h"
+#include "libavutil/frame.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixfmt.h"
+#include "libavutil/thread.h"
+#include "libavutil/vaapi.h"
+
+#include "libavcodec/vaapi.h"
+
+#include 
+#include 
+
+
+static AVClass vaapi_class = {
+.class_name = "VAAPI/driver",
+.item_name  = av_default_item_name,
+.version= LIBAVUTIL_VERSION_INT,
+};
+
+
+#define DEFAULT_SURFACES 20
+
+typedef struct VAAPIDecoderContext {
+const AVClass *class;
+
+AVVAAPIHardwareContext *hardware_context;
+AVVAAPIPipelineConfig config;
+AVVAAPIPipelineContext codec;
+AVVAAPISurfaceConfig output;
+
+int codec_initialised;
+
+AVFrame output_frame;
+} VAAPIDecoderContext;
+
+
+static int vaapi_get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
+{
+InputStream *ist =