Re: [FFmpeg-devel] [PATCH] examples/vaapi_dec: Add a VA-API hwaccel decoding example
On 2017/3/21 12:57, wm4 wrote: > On Tue, 21 Mar 2017 12:45:26 +0800 > Jun Zhaowrote: > >> 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
On Tue, 21 Mar 2017 12:45:26 +0800 Jun Zhaowrote: > 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
From 6b56c541ed7dd271ad0aa6eb6412a8427f009525 Mon Sep 17 00:00:00 2001 From: Jun ZhaoDate: 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