Re: [FFmpeg-devel] [PATCH] examples/vaapi_dec: Add a VA-API hwaccel decoding example

2017-03-21 Thread Jun Zhao


On 2017/3/21 12:57, wm4 wrote:
> On Tue, 21 Mar 2017 12:45:26 +0800
> Jun Zhao  wrote:
> 
>> From 6b56c541ed7dd271ad0aa6eb6412a8427f009525 Mon Sep 17 00:00:00 2001
>> From: Jun Zhao 
>> Date: Tue, 21 Mar 2017 11:04:41 +0800
>> Subject: [PATCH] examples/vaapi_dec: Add a VA-API hwaccel decoding example.
>>
>> Add a VA-API hwaccel decoding example.
>>
>> Signed-off-by: Liu, Kaixuan 
>> Signed-off-by: Jun Zhao 
>> ---
>>  doc/examples/vaapi_dec.c | 346 
>> +++
>>  1 file changed, 346 insertions(+)
>>  create mode 100644 doc/examples/vaapi_dec.c
>>
>> diff --git a/doc/examples/vaapi_dec.c b/doc/examples/vaapi_dec.c
>> new file mode 100644
>> index 000..f975d86
>> --- /dev/null
>> +++ b/doc/examples/vaapi_dec.c
>> @@ -0,0 +1,346 @@
>> +/*
>> + * Video Acceleration API (video decoding) decode sample
>> + *
>> + * 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
>> + */
>> +
>> +/**
>> + * @file
>> + * Intel VAAPI-accelerated decoding example.
>> + *
>> + * @example vaapi_dec.c
>> + * This example shows how to do VAAPI-accelerated decoding with output
>> + * frames from the VAAPI video surfaces.
>> + */
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#define DEFAULT_SURFACES 20
>> +static enum AVPixelFormat decode_format = AV_PIX_FMT_NV12;
>> +static enum AVPixelFormat output_format = AV_PIX_FMT_NV12; /* default 
>> output format nv12 */
>> +static AVBufferRef *frames_ref = NULL;
>> +static AVBufferRef *device_ref = NULL;
>> +FILE *output_file = NULL;
>> +
>> +void decoder_uninit_vaapi(AVCodecContext *avctx, AVVAAPIDeviceContext 
>> *hwctx)
>> +{
>> +if (hwctx) {
>> +av_buffer_unref(_ref);
>> +av_buffer_unref(_ref);
>> +}
>> +return;
>> +}
>> +
>> +int decoder_init_vaapi(AVCodecContext *ctx)
>> +{
>> +AVBufferRef *hw_device_ctx = NULL;
>> +AVHWFramesContext *frames;
>> +int err = 0;
>> +char *dev_name = "/dev/dri/renderD128";
>> +AVBufferRef *device_ref = NULL;
>> +AVHWDeviceContext *device = NULL;
>> +AVVAAPIDeviceContext *hwctx = NULL;
>> +
>> +if ((err = av_hwdevice_ctx_create(_device_ctx, 
>> AV_HWDEVICE_TYPE_VAAPI,
>> +  dev_name, NULL, 0)) < 0) {
>> +fprintf(stderr, "Failed to create a VAAPI device.\n");
>> +return err;
>> +}
>> +
>> +device_ref = av_buffer_ref(hw_device_ctx);
>> +device = (AVHWDeviceContext *)device_ref->data;
>> +hwctx = (AVVAAPIDeviceContext *)device->hwctx;
>> +
>> +ctx->pix_fmt = output_format;
>> +if (!(frames_ref = av_hwframe_ctx_alloc(device_ref))) {
>> +fprintf(stderr, "Failed to create VAAPI frame context.\n");
>> +err = AVERROR(ENOMEM);
>> +goto fail;
>> +}
>> +frames = (AVHWFramesContext *)frames_ref->data;
>> +frames->format= AV_PIX_FMT_VAAPI;
>> +frames->sw_format = decode_format;
>> +frames->width = ctx->coded_width;
>> +frames->height= ctx->coded_height;
>> +frames->initial_pool_size = DEFAULT_SURFACES;
>> +if ((err = av_hwframe_ctx_init(frames_ref)) < 0) {
>> +fprintf(stderr, "Failed to initialize VAAPI frame.\n");
>> +goto fail;
>> +}
>> +
>> +ctx->hw_frames_ctx = av_buffer_ref(frames_ref);
>> +if (!ctx->hw_frames_ctx) {
>> +err = AVERROR(ENOMEM);
>> +fprintf(stderr, "Failed to ref VAAPI frame.\n");
>> +goto fail;
>> +}
> 
> All of this code (except device creation) will be unnecessary once the
> Libav change of improving the hw decoding API has been merged. See e.g.:
> 
> https://git.libav.org/?p=libav.git;a=commit;h=62a1ef9f26c654a3e988aa465c4ac1d776c4c356
> 

I like this change, hope it can be move to FFmpeg as quick. Then I will rework 
this part.

>> +
>> +fail:
>> +if (err < 0)
>> +decoder_uninit_vaapi(ctx, hwctx);
>> +return err;
>> +}
>> +
>> +static enum AVPixelFormat get_hw_vaapi_format(AVCodecContext *ctx,
>> +  const enum 

Re: [FFmpeg-devel] [PATCH] examples/vaapi_dec: Add a VA-API hwaccel decoding example

2017-03-20 Thread wm4
On Tue, 21 Mar 2017 12:45:26 +0800
Jun Zhao  wrote:

> From 6b56c541ed7dd271ad0aa6eb6412a8427f009525 Mon Sep 17 00:00:00 2001
> From: Jun Zhao 
> Date: Tue, 21 Mar 2017 11:04:41 +0800
> Subject: [PATCH] examples/vaapi_dec: Add a VA-API hwaccel decoding example.
> 
> Add a VA-API hwaccel decoding example.
> 
> Signed-off-by: Liu, Kaixuan 
> Signed-off-by: Jun Zhao 
> ---
>  doc/examples/vaapi_dec.c | 346 
> +++
>  1 file changed, 346 insertions(+)
>  create mode 100644 doc/examples/vaapi_dec.c
> 
> diff --git a/doc/examples/vaapi_dec.c b/doc/examples/vaapi_dec.c
> new file mode 100644
> index 000..f975d86
> --- /dev/null
> +++ b/doc/examples/vaapi_dec.c
> @@ -0,0 +1,346 @@
> +/*
> + * Video Acceleration API (video decoding) decode sample
> + *
> + * 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
> + */
> +
> +/**
> + * @file
> + * Intel VAAPI-accelerated decoding example.
> + *
> + * @example vaapi_dec.c
> + * This example shows how to do VAAPI-accelerated decoding with output
> + * frames from the VAAPI video surfaces.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define DEFAULT_SURFACES 20
> +static enum AVPixelFormat decode_format = AV_PIX_FMT_NV12;
> +static enum AVPixelFormat output_format = AV_PIX_FMT_NV12; /* default output 
> format nv12 */
> +static AVBufferRef *frames_ref = NULL;
> +static AVBufferRef *device_ref = NULL;
> +FILE *output_file = NULL;
> +
> +void decoder_uninit_vaapi(AVCodecContext *avctx, AVVAAPIDeviceContext *hwctx)
> +{
> +if (hwctx) {
> +av_buffer_unref(_ref);
> +av_buffer_unref(_ref);
> +}
> +return;
> +}
> +
> +int decoder_init_vaapi(AVCodecContext *ctx)
> +{
> +AVBufferRef *hw_device_ctx = NULL;
> +AVHWFramesContext *frames;
> +int err = 0;
> +char *dev_name = "/dev/dri/renderD128";
> +AVBufferRef *device_ref = NULL;
> +AVHWDeviceContext *device = NULL;
> +AVVAAPIDeviceContext *hwctx = NULL;
> +
> +if ((err = av_hwdevice_ctx_create(_device_ctx, AV_HWDEVICE_TYPE_VAAPI,
> +  dev_name, NULL, 0)) < 0) {
> +fprintf(stderr, "Failed to create a VAAPI device.\n");
> +return err;
> +}
> +
> +device_ref = av_buffer_ref(hw_device_ctx);
> +device = (AVHWDeviceContext *)device_ref->data;
> +hwctx = (AVVAAPIDeviceContext *)device->hwctx;
> +
> +ctx->pix_fmt = output_format;
> +if (!(frames_ref = av_hwframe_ctx_alloc(device_ref))) {
> +fprintf(stderr, "Failed to create VAAPI frame context.\n");
> +err = AVERROR(ENOMEM);
> +goto fail;
> +}
> +frames = (AVHWFramesContext *)frames_ref->data;
> +frames->format= AV_PIX_FMT_VAAPI;
> +frames->sw_format = decode_format;
> +frames->width = ctx->coded_width;
> +frames->height= ctx->coded_height;
> +frames->initial_pool_size = DEFAULT_SURFACES;
> +if ((err = av_hwframe_ctx_init(frames_ref)) < 0) {
> +fprintf(stderr, "Failed to initialize VAAPI frame.\n");
> +goto fail;
> +}
> +
> +ctx->hw_frames_ctx = av_buffer_ref(frames_ref);
> +if (!ctx->hw_frames_ctx) {
> +err = AVERROR(ENOMEM);
> +fprintf(stderr, "Failed to ref VAAPI frame.\n");
> +goto fail;
> +}

All of this code (except device creation) will be unnecessary once the
Libav change of improving the hw decoding API has been merged. See e.g.:

https://git.libav.org/?p=libav.git;a=commit;h=62a1ef9f26c654a3e988aa465c4ac1d776c4c356

> +
> +fail:
> +if (err < 0)
> +decoder_uninit_vaapi(ctx, hwctx);
> +return err;
> +}
> +
> +static enum AVPixelFormat get_hw_vaapi_format(AVCodecContext *ctx,
> +  const enum AVPixelFormat 
> *pix_fmts)
> +{
> +const enum AVPixelFormat *p;
> +int ret;
> +
> +for (p = pix_fmts; *p != -1; p++) {
> +const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p);
> +if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
> +break;
> 

[FFmpeg-devel] [PATCH] examples/vaapi_dec: Add a VA-API hwaccel decoding example

2017-03-20 Thread Jun Zhao
From 6b56c541ed7dd271ad0aa6eb6412a8427f009525 Mon Sep 17 00:00:00 2001
From: Jun Zhao 
Date: Tue, 21 Mar 2017 11:04:41 +0800
Subject: [PATCH] examples/vaapi_dec: Add a VA-API hwaccel decoding example.

Add a VA-API hwaccel decoding example.

Signed-off-by: Liu, Kaixuan 
Signed-off-by: Jun Zhao 
---
 doc/examples/vaapi_dec.c | 346 +++
 1 file changed, 346 insertions(+)
 create mode 100644 doc/examples/vaapi_dec.c

diff --git a/doc/examples/vaapi_dec.c b/doc/examples/vaapi_dec.c
new file mode 100644
index 000..f975d86
--- /dev/null
+++ b/doc/examples/vaapi_dec.c
@@ -0,0 +1,346 @@
+/*
+ * Video Acceleration API (video decoding) decode sample
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * Intel VAAPI-accelerated decoding example.
+ *
+ * @example vaapi_dec.c
+ * This example shows how to do VAAPI-accelerated decoding with output
+ * frames from the VAAPI video surfaces.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DEFAULT_SURFACES 20
+static enum AVPixelFormat decode_format = AV_PIX_FMT_NV12;
+static enum AVPixelFormat output_format = AV_PIX_FMT_NV12; /* default output 
format nv12 */
+static AVBufferRef *frames_ref = NULL;
+static AVBufferRef *device_ref = NULL;
+FILE *output_file = NULL;
+
+void decoder_uninit_vaapi(AVCodecContext *avctx, AVVAAPIDeviceContext *hwctx)
+{
+if (hwctx) {
+av_buffer_unref(_ref);
+av_buffer_unref(_ref);
+}
+return;
+}
+
+int decoder_init_vaapi(AVCodecContext *ctx)
+{
+AVBufferRef *hw_device_ctx = NULL;
+AVHWFramesContext *frames;
+int err = 0;
+char *dev_name = "/dev/dri/renderD128";
+AVBufferRef *device_ref = NULL;
+AVHWDeviceContext *device = NULL;
+AVVAAPIDeviceContext *hwctx = NULL;
+
+if ((err = av_hwdevice_ctx_create(_device_ctx, AV_HWDEVICE_TYPE_VAAPI,
+  dev_name, NULL, 0)) < 0) {
+fprintf(stderr, "Failed to create a VAAPI device.\n");
+return err;
+}
+
+device_ref = av_buffer_ref(hw_device_ctx);
+device = (AVHWDeviceContext *)device_ref->data;
+hwctx = (AVVAAPIDeviceContext *)device->hwctx;
+
+ctx->pix_fmt = output_format;
+if (!(frames_ref = av_hwframe_ctx_alloc(device_ref))) {
+fprintf(stderr, "Failed to create VAAPI frame context.\n");
+err = AVERROR(ENOMEM);
+goto fail;
+}
+frames = (AVHWFramesContext *)frames_ref->data;
+frames->format= AV_PIX_FMT_VAAPI;
+frames->sw_format = decode_format;
+frames->width = ctx->coded_width;
+frames->height= ctx->coded_height;
+frames->initial_pool_size = DEFAULT_SURFACES;
+if ((err = av_hwframe_ctx_init(frames_ref)) < 0) {
+fprintf(stderr, "Failed to initialize VAAPI frame.\n");
+goto fail;
+}
+
+ctx->hw_frames_ctx = av_buffer_ref(frames_ref);
+if (!ctx->hw_frames_ctx) {
+err = AVERROR(ENOMEM);
+fprintf(stderr, "Failed to ref VAAPI frame.\n");
+goto fail;
+}
+
+fail:
+if (err < 0)
+decoder_uninit_vaapi(ctx, hwctx);
+return err;
+}
+
+static enum AVPixelFormat get_hw_vaapi_format(AVCodecContext *ctx,
+  const enum AVPixelFormat 
*pix_fmts)
+{
+const enum AVPixelFormat *p;
+int ret;
+
+for (p = pix_fmts; *p != -1; p++) {
+const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p);
+if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
+break;
+
+if (!(strstr(desc->name, "vaapi")))
+continue;
+
+if ((ret = decoder_init_vaapi(ctx)) < 0) {
+fprintf(stderr, "hwaccel for decoder(VAAPI) cannot be 
initialized.\n");
+return AV_PIX_FMT_NONE;
+}
+break;
+}
+return *p;
+}
+
+static int get_hw_vaapi_buffer(AVCodecContext *ctx, AVFrame *frame, int flags)
+{
+int err;
+if ((err = av_hwframe_get_buffer(frames_ref, frame, 0)) < 0)
+av_log(NULL, AV_LOG_ERROR, "Failed to allocate decoder surface.\n");
+
+return err;
+}
+
+int retrieve_data(AVFrame