Hi Haihao, Thanks for the review. This patch just moves all code from qsvdec_h2645.c to qsvdec.c. The original code in qsvdec_h2645.c did not free the point, so the code will not free it. The av_freep(&s->qsv.load_plugins); will addressed by https://patchwork.ffmpeg.org/project/ffmpeg/patch/20201126102026.27202-4-guangxin...@intel.com/
Your finding is a good example, tell us why we need to remove duplicate codes. :) thanks On Wed, Dec 2, 2020 at 12:50 PM Xiang, Haihao <haihao.xi...@intel.com> wrote: > On Thu, 2020-11-26 at 18:20 +0800, Xu Guangxin wrote: > > --- > > libavcodec/Makefile | 8 +- > > libavcodec/qsvdec.c | 215 ++++++++++++++++++++++++++++++++- > > libavcodec/qsvdec_h2645.c | 248 -------------------------------------- > > 3 files changed, 217 insertions(+), 254 deletions(-) > > delete mode 100644 libavcodec/qsvdec_h2645.c > > > > diff --git a/libavcodec/Makefile b/libavcodec/Makefile > > index a6435c9e85..3ee8aa7f86 100644 > > --- a/libavcodec/Makefile > > +++ b/libavcodec/Makefile > > @@ -374,7 +374,7 @@ OBJS-$(CONFIG_H264_NVENC_ENCODER) += > nvenc_h264.o > > OBJS-$(CONFIG_NVENC_ENCODER) += nvenc_h264.o > > OBJS-$(CONFIG_NVENC_H264_ENCODER) += nvenc_h264.o > > OBJS-$(CONFIG_H264_OMX_ENCODER) += omx.o > > -OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec_h2645.o > > +OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec.o > > OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o > > OBJS-$(CONFIG_H264_RKMPP_DECODER) += rkmppdec.o > > OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o > h264_levels.o > > @@ -394,7 +394,7 @@ OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += > mediacodecdec.o > > OBJS-$(CONFIG_HEVC_MF_ENCODER) += mfenc.o mf_utils.o > > OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o > > OBJS-$(CONFIG_NVENC_HEVC_ENCODER) += nvenc_hevc.o > > -OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec_h2645.o > > +OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec.o > > OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o > \ > > hevc_data.o > > OBJS-$(CONFIG_HEVC_RKMPP_DECODER) += rkmppdec.o > > @@ -922,14 +922,14 @@ OBJS-$(CONFIG_H263_VIDEOTOOLBOX_HWACCEL) += > > videotoolbox.o > > OBJS-$(CONFIG_H264_D3D11VA_HWACCEL) += dxva2_h264.o > > OBJS-$(CONFIG_H264_DXVA2_HWACCEL) += dxva2_h264.o > > OBJS-$(CONFIG_H264_NVDEC_HWACCEL) += nvdec_h264.o > > -OBJS-$(CONFIG_H264_QSV_HWACCEL) += qsvdec_h2645.o > > +OBJS-$(CONFIG_H264_QSV_HWACCEL) += qsvdec.o > > OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o > > OBJS-$(CONFIG_H264_VDPAU_HWACCEL) += vdpau_h264.o > > OBJS-$(CONFIG_H264_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o > > OBJS-$(CONFIG_HEVC_D3D11VA_HWACCEL) += dxva2_hevc.o > > OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL) += dxva2_hevc.o > > OBJS-$(CONFIG_HEVC_NVDEC_HWACCEL) += nvdec_hevc.o > > -OBJS-$(CONFIG_HEVC_QSV_HWACCEL) += qsvdec_h2645.o > > +OBJS-$(CONFIG_HEVC_QSV_HWACCEL) += qsvdec.o > > OBJS-$(CONFIG_HEVC_VAAPI_HWACCEL) += vaapi_hevc.o > > h265_profile_level.o > > OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o > > h265_profile_level.o > > OBJS-$(CONFIG_MJPEG_NVDEC_HWACCEL) += nvdec_mjpeg.o > > diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c > > index c666aaeb52..0a79d00eac 100644 > > --- a/libavcodec/qsvdec.c > > +++ b/libavcodec/qsvdec.c > > @@ -31,6 +31,7 @@ > > #include "libavutil/hwcontext_qsv.h" > > #include "libavutil/mem.h" > > #include "libavutil/log.h" > > +#include "libavutil/opt.h" > > #include "libavutil/pixdesc.h" > > #include "libavutil/pixfmt.h" > > #include "libavutil/time.h" > > @@ -228,7 +229,7 @@ static int qsv_decode_preinit(AVCodecContext *avctx, > > QSVContext *q, enum AVPixel > > return 0; > > } > > > > -static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q, > > mfxVideoParam *param) > > +static int qsv_decode_init_context(AVCodecContext *avctx, QSVContext *q, > > mfxVideoParam *param) > > { > > int ret; > > > > @@ -615,7 +616,7 @@ int ff_qsv_process_data(AVCodecContext *avctx, > QSVContext > > *q, > > } > > > > if (!q->initialized) { > > - ret = qsv_decode_init(avctx, q, ¶m); > > + ret = qsv_decode_init_context(avctx, q, ¶m); > > if (ret < 0) > > goto reinit_fail; > > q->initialized = 1; > > @@ -633,3 +634,213 @@ void ff_qsv_decode_flush(AVCodecContext *avctx, > > QSVContext *q) > > q->orig_pix_fmt = AV_PIX_FMT_NONE; > > q->initialized = 0; > > } > > + > > +enum LoadPlugin { > > + LOAD_PLUGIN_NONE, > > + LOAD_PLUGIN_HEVC_SW, > > + LOAD_PLUGIN_HEVC_HW, > > +}; > > + > > +typedef struct QSVDecContext { > > + AVClass *class; > > + QSVContext qsv; > > + > > + int load_plugin; > > + > > + AVFifoBuffer *packet_fifo; > > + > > + AVPacket buffer_pkt; > > +} QSVDecContext; > > + > > +static void qsv_clear_buffers(QSVDecContext *s) > > +{ > > + AVPacket pkt; > > + while (av_fifo_size(s->packet_fifo) >= sizeof(pkt)) { > > + av_fifo_generic_read(s->packet_fifo, &pkt, sizeof(pkt), NULL); > > + av_packet_unref(&pkt); > > + } > > + > > + av_packet_unref(&s->buffer_pkt); > > +} > > + > > +static av_cold int qsv_decode_close(AVCodecContext *avctx) > > +{ > > + QSVDecContext *s = avctx->priv_data; > > + > > av_strdup() is called for s->qsv.load_plugins, so need to call av_freep() > to > free s->qsv.load_plugins. > > av_freep(&s->qsv.load_plugins); > > > + ff_qsv_decode_close(&s->qsv); > > + > > + qsv_clear_buffers(s); > > + > > + av_fifo_free(s->packet_fifo); > > + > > + return 0; > > +} > > + > > +static av_cold int qsv_decode_init(AVCodecContext *avctx) > > +{ > > + QSVDecContext *s = avctx->priv_data; > > + int ret; > > + > > + if (avctx->codec_id == AV_CODEC_ID_HEVC && s->load_plugin != > > LOAD_PLUGIN_NONE) { > > + static const char * const uid_hevcdec_sw = > > "15dd936825ad475ea34e35f3f54217a6"; > > + static const char * const uid_hevcdec_hw = > > "33a61c0b4c27454ca8d85dde757c6f8e"; > > + > > + if (s->qsv.load_plugins[0]) { > > + av_log(avctx, AV_LOG_WARNING, > > + "load_plugins is not empty, but load_plugin is not > set to > > 'none'." > > + "The load_plugin value will be ignored.\n"); > > + } else { > > + av_freep(&s->qsv.load_plugins); > > + > > + if (s->load_plugin == LOAD_PLUGIN_HEVC_SW) > > + s->qsv.load_plugins = av_strdup(uid_hevcdec_sw); > > + else > > + s->qsv.load_plugins = av_strdup(uid_hevcdec_hw); > > + if (!s->qsv.load_plugins) > > + return AVERROR(ENOMEM); > > + } > > + } > > + > > + s->qsv.orig_pix_fmt = AV_PIX_FMT_NV12; > > + s->packet_fifo = av_fifo_alloc(sizeof(AVPacket)); > > + if (!s->packet_fifo) { > > + ret = AVERROR(ENOMEM); > > + goto fail; > > + } > > + > > + return 0; > > +fail: > > + qsv_decode_close(avctx); > > + return ret; > > +} > > + > > +static int qsv_decode_frame(AVCodecContext *avctx, void *data, > > + int *got_frame, AVPacket *avpkt) > > +{ > > + QSVDecContext *s = avctx->priv_data; > > + AVFrame *frame = data; > > + int ret; > > + > > + /* buffer the input packet */ > > + if (avpkt->size) { > > + AVPacket input_ref; > > + > > + if (av_fifo_space(s->packet_fifo) < sizeof(input_ref)) { > > + ret = av_fifo_realloc2(s->packet_fifo, > > + av_fifo_size(s->packet_fifo) + > > sizeof(input_ref)); > > + if (ret < 0) > > + return ret; > > + } > > + > > + ret = av_packet_ref(&input_ref, avpkt); > > + if (ret < 0) > > + return ret; > > + av_fifo_generic_write(s->packet_fifo, &input_ref, > sizeof(input_ref), > > NULL); > > + } > > + > > + /* process buffered data */ > > + while (!*got_frame) { > > + /* prepare the input data */ > > + if (s->buffer_pkt.size <= 0) { > > + /* no more data */ > > + if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket)) > > + return avpkt->size ? avpkt->size : > ff_qsv_process_data(avctx, > > &s->qsv, frame, got_frame, avpkt); > > + /* in progress of reinit, no read from fifo and keep the > > buffer_pkt */ > > + if (!s->qsv.reinit_flag) { > > + av_packet_unref(&s->buffer_pkt); > > + av_fifo_generic_read(s->packet_fifo, &s->buffer_pkt, > > sizeof(s->buffer_pkt), NULL); > > + } > > + } > > + > > + ret = ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, &s- > > >buffer_pkt); > > + if (ret < 0){ > > + /* Drop buffer_pkt when failed to decode the packet. > Otherwise, > > + the decoder will keep decoding the failure packet. */ > > + av_packet_unref(&s->buffer_pkt); > > + return ret; > > + } > > + if (s->qsv.reinit_flag) > > + continue; > > + > > + s->buffer_pkt.size -= ret; > > + s->buffer_pkt.data += ret; > > + } > > + > > + return avpkt->size; > > +} > > + > > +static void qsv_decode_flush(AVCodecContext *avctx) > > +{ > > + QSVDecContext *s = avctx->priv_data; > > + > > + qsv_clear_buffers(s); > > + ff_qsv_decode_flush(avctx, &s->qsv); > > +} > > + > > +#define OFFSET(x) offsetof(QSVDecContext, x) > > +#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM > > + > > +#define DEFINE_QSV_DECODER_WITH_OPTION(x, X, bsf_name, opt) \ > > +static const AVClass x##_qsv_class = { \ > > + .class_name = #x "_qsv", \ > > + .item_name = av_default_item_name, \ > > + .option = opt, \ > > + .version = LIBAVUTIL_VERSION_INT, \ > > +}; \ > > +AVCodec ff_##x##_qsv_decoder = { \ > > + .name = #x "_qsv", \ > > + .long_name = NULL_IF_CONFIG_SMALL(#X " video (Intel Quick Sync > Video > > acceleration)"), \ > > + .priv_data_size = sizeof(QSVDecContext), \ > > + .type = AVMEDIA_TYPE_VIDEO, \ > > + .id = AV_CODEC_ID_##X, \ > > + .init = qsv_decode_init, \ > > + .decode = qsv_decode_frame, \ > > + .flush = qsv_decode_flush, \ > > + .close = qsv_decode_close, \ > > + .bsfs = bsf_name, \ > > + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | > > AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HYBRID, \ > > + .priv_class = &x##_qsv_class, \ > > + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, \ > > + AV_PIX_FMT_P010, \ > > + AV_PIX_FMT_QSV, \ > > + AV_PIX_FMT_NONE }, \ > > + .hw_configs = ff_qsv_hw_configs, \ > > + .wrapper_name = "qsv", \ > > +}; \ > > + > > +#define DEFINE_QSV_DECODER(x, X, bsf_name) > DEFINE_QSV_DECODER_WITH_OPTION(x, > > X, bsf_name, options) > > + > > +#if CONFIG_HEVC_QSV_DECODER > > +static const AVOption hevc_options[] = { > > + { "async_depth", "Internal parallelization depth, the higher the > value > > the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { > .i64 = > > ASYNC_DEPTH_DEFAULT }, 1, INT_MAX, VD }, > > + > > + { "load_plugin", "A user plugin to load in an internal session", > > OFFSET(load_plugin), AV_OPT_TYPE_INT, { .i64 = LOAD_PLUGIN_HEVC_HW }, > > LOAD_PLUGIN_NONE, LOAD_PLUGIN_HEVC_HW, VD, "load_plugin" }, > > + { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_NONE > > }, 0, 0, VD, "load_plugin" }, > > + { "hevc_sw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = > LOAD_PLUGIN_HEVC_SW }, > > 0, 0, VD, "load_plugin" }, > > + { "hevc_hw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = > LOAD_PLUGIN_HEVC_HW }, > > 0, 0, VD, "load_plugin" }, > > + > > + { "load_plugins", "A :-separate list of hexadecimal plugin UIDs to > load > > in an internal session", > > + OFFSET(qsv.load_plugins), AV_OPT_TYPE_STRING, { .str = "" }, 0, > 0, VD > > }, > > + > > + { "gpu_copy", "A GPU-accelerated copy between video and system > memory", > > OFFSET(qsv.gpu_copy), AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_DEFAULT }, > > MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF, VD, "gpu_copy"}, > > + { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = > MFX_GPUCOPY_DEFAULT > > }, 0, 0, VD, "gpu_copy"}, > > + { "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON > > }, 0, 0, VD, "gpu_copy"}, > > + { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = > MFX_GPUCOPY_OFF > > }, 0, 0, VD, "gpu_copy"}, > > + { NULL }, > > +}; > > +DEFINE_QSV_DECODER_WITH_OPTION(hevc, HEVC, "hevc_mp4toannexb", > hevc_options) > > +#endif > > + > > +static const AVOption options[] = { > > + { "async_depth", "Internal parallelization depth, the higher the > value > > the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { > .i64 = > > ASYNC_DEPTH_DEFAULT }, 1, INT_MAX, VD }, > > + > > + { "gpu_copy", "A GPU-accelerated copy between video and system > memory", > > OFFSET(qsv.gpu_copy), AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_DEFAULT }, > > MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF, VD, "gpu_copy"}, > > + { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = > MFX_GPUCOPY_DEFAULT > > }, 0, 0, VD, "gpu_copy"}, > > + { "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON > > }, 0, 0, VD, "gpu_copy"}, > > + { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = > MFX_GPUCOPY_OFF > > }, 0, 0, VD, "gpu_copy"}, > > + { NULL }, > > +}; > > + > > +#if CONFIG_H264_QSV_DECODER > > +DEFINE_QSV_DECODER(h264, H264, "h264_mp4toannexb") > > +#endif > > diff --git a/libavcodec/qsvdec_h2645.c b/libavcodec/qsvdec_h2645.c > > deleted file mode 100644 > > index b0ab23a922..0000000000 > > --- a/libavcodec/qsvdec_h2645.c > > +++ /dev/null > > @@ -1,248 +0,0 @@ > > -/* > > - * Intel MediaSDK QSV based H.264 / HEVC decoder > > - * > > - * copyright (c) 2013 Luca Barbato > > - * copyright (c) 2015 Anton Khirnov > > - * > > - * 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 <stdint.h> > > -#include <string.h> > > - > > -#include <mfx/mfxvideo.h> > > - > > -#include "libavutil/common.h" > > -#include "libavutil/fifo.h" > > -#include "libavutil/opt.h" > > - > > -#include "avcodec.h" > > -#include "internal.h" > > -#include "qsv_internal.h" > > -#include "qsvdec.h" > > -#include "qsv.h" > > - > > -enum LoadPlugin { > > - LOAD_PLUGIN_NONE, > > - LOAD_PLUGIN_HEVC_SW, > > - LOAD_PLUGIN_HEVC_HW, > > -}; > > - > > -typedef struct QSVH2645Context { > > - AVClass *class; > > - QSVContext qsv; > > - > > - int load_plugin; > > - > > - AVFifoBuffer *packet_fifo; > > - > > - AVPacket buffer_pkt; > > -} QSVH2645Context; > > - > > -static void qsv_clear_buffers(QSVH2645Context *s) > > -{ > > - AVPacket pkt; > > - while (av_fifo_size(s->packet_fifo) >= sizeof(pkt)) { > > - av_fifo_generic_read(s->packet_fifo, &pkt, sizeof(pkt), NULL); > > - av_packet_unref(&pkt); > > - } > > - > > - av_packet_unref(&s->buffer_pkt); > > -} > > - > > -static av_cold int qsv_decode_close(AVCodecContext *avctx) > > -{ > > - QSVH2645Context *s = avctx->priv_data; > > - > > - ff_qsv_decode_close(&s->qsv); > > - > > - qsv_clear_buffers(s); > > - > > - av_fifo_free(s->packet_fifo); > > - > > - return 0; > > -} > > - > > -static av_cold int qsv_decode_init(AVCodecContext *avctx) > > -{ > > - QSVH2645Context *s = avctx->priv_data; > > - int ret; > > - > > - if (avctx->codec_id == AV_CODEC_ID_HEVC && s->load_plugin != > > LOAD_PLUGIN_NONE) { > > - static const char * const uid_hevcdec_sw = > > "15dd936825ad475ea34e35f3f54217a6"; > > - static const char * const uid_hevcdec_hw = > > "33a61c0b4c27454ca8d85dde757c6f8e"; > > - > > - if (s->qsv.load_plugins[0]) { > > - av_log(avctx, AV_LOG_WARNING, > > - "load_plugins is not empty, but load_plugin is not > set to > > 'none'." > > - "The load_plugin value will be ignored.\n"); > > - } else { > > - av_freep(&s->qsv.load_plugins); > > - > > - if (s->load_plugin == LOAD_PLUGIN_HEVC_SW) > > - s->qsv.load_plugins = av_strdup(uid_hevcdec_sw); > > - else > > - s->qsv.load_plugins = av_strdup(uid_hevcdec_hw); > > - if (!s->qsv.load_plugins) > > - return AVERROR(ENOMEM); > > - } > > - } > > - > > - s->qsv.orig_pix_fmt = AV_PIX_FMT_NV12; > > - s->packet_fifo = av_fifo_alloc(sizeof(AVPacket)); > > - if (!s->packet_fifo) { > > - ret = AVERROR(ENOMEM); > > - goto fail; > > - } > > - > > - return 0; > > -fail: > > - qsv_decode_close(avctx); > > - return ret; > > -} > > - > > -static int qsv_decode_frame(AVCodecContext *avctx, void *data, > > - int *got_frame, AVPacket *avpkt) > > -{ > > - QSVH2645Context *s = avctx->priv_data; > > - AVFrame *frame = data; > > - int ret; > > - > > - /* buffer the input packet */ > > - if (avpkt->size) { > > - AVPacket input_ref; > > - > > - if (av_fifo_space(s->packet_fifo) < sizeof(input_ref)) { > > - ret = av_fifo_realloc2(s->packet_fifo, > > - av_fifo_size(s->packet_fifo) + > > sizeof(input_ref)); > > - if (ret < 0) > > - return ret; > > - } > > - > > - ret = av_packet_ref(&input_ref, avpkt); > > - if (ret < 0) > > - return ret; > > - av_fifo_generic_write(s->packet_fifo, &input_ref, > sizeof(input_ref), > > NULL); > > - } > > - > > - /* process buffered data */ > > - while (!*got_frame) { > > - /* prepare the input data */ > > - if (s->buffer_pkt.size <= 0) { > > - /* no more data */ > > - if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket)) > > - return avpkt->size ? avpkt->size : > ff_qsv_process_data(avctx, > > &s->qsv, frame, got_frame, avpkt); > > - /* in progress of reinit, no read from fifo and keep the > > buffer_pkt */ > > - if (!s->qsv.reinit_flag) { > > - av_packet_unref(&s->buffer_pkt); > > - av_fifo_generic_read(s->packet_fifo, &s->buffer_pkt, > > sizeof(s->buffer_pkt), NULL); > > - } > > - } > > - > > - ret = ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, &s- > > >buffer_pkt); > > - if (ret < 0){ > > - /* Drop buffer_pkt when failed to decode the packet. > Otherwise, > > - the decoder will keep decoding the failure packet. */ > > - av_packet_unref(&s->buffer_pkt); > > - return ret; > > - } > > - if (s->qsv.reinit_flag) > > - continue; > > - > > - s->buffer_pkt.size -= ret; > > - s->buffer_pkt.data += ret; > > - } > > - > > - return avpkt->size; > > -} > > - > > -static void qsv_decode_flush(AVCodecContext *avctx) > > -{ > > - QSVH2645Context *s = avctx->priv_data; > > - > > - qsv_clear_buffers(s); > > - ff_qsv_decode_flush(avctx, &s->qsv); > > -} > > - > > -#define OFFSET(x) offsetof(QSVH2645Context, x) > > -#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM > > - > > -#define DEFINE_QSV_DECODER_WITH_OPTION(x, X, bsf_name, opt) \ > > -static const AVClass x##_qsv_class = { \ > > - .class_name = #x "_qsv", \ > > - .item_name = av_default_item_name, \ > > - .option = opt, \ > > - .version = LIBAVUTIL_VERSION_INT, \ > > -}; \ > > -AVCodec ff_##x##_qsv_decoder = { \ > > - .name = #x "_qsv", \ > > - .long_name = NULL_IF_CONFIG_SMALL(#X " video (Intel Quick Sync > Video > > acceleration)"), \ > > - .priv_data_size = sizeof(QSVH2645Context), \ > > - .type = AVMEDIA_TYPE_VIDEO, \ > > - .id = AV_CODEC_ID_##X, \ > > - .init = qsv_decode_init, \ > > - .decode = qsv_decode_frame, \ > > - .flush = qsv_decode_flush, \ > > - .close = qsv_decode_close, \ > > - .bsfs = bsf_name, \ > > - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1 | > > AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HYBRID, \ > > - .priv_class = &x##_qsv_class, \ > > - .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, \ > > - AV_PIX_FMT_P010, \ > > - AV_PIX_FMT_QSV, \ > > - AV_PIX_FMT_NONE }, \ > > - .hw_configs = ff_qsv_hw_configs, \ > > - .wrapper_name = "qsv", \ > > -}; \ > > - > > -#define DEFINE_QSV_DECODER(x, X, bsf_name) > DEFINE_QSV_DECODER_WITH_OPTION(x, > > X, bsf_name, options) > > - > > -#if CONFIG_HEVC_QSV_DECODER > > -static const AVOption hevc_options[] = { > > - { "async_depth", "Internal parallelization depth, the higher the > value > > the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { > .i64 = > > ASYNC_DEPTH_DEFAULT }, 1, INT_MAX, VD }, > > - > > - { "load_plugin", "A user plugin to load in an internal session", > > OFFSET(load_plugin), AV_OPT_TYPE_INT, { .i64 = LOAD_PLUGIN_HEVC_HW }, > > LOAD_PLUGIN_NONE, LOAD_PLUGIN_HEVC_HW, VD, "load_plugin" }, > > - { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = LOAD_PLUGIN_NONE > > }, 0, 0, VD, "load_plugin" }, > > - { "hevc_sw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = > LOAD_PLUGIN_HEVC_SW }, > > 0, 0, VD, "load_plugin" }, > > - { "hevc_hw", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = > LOAD_PLUGIN_HEVC_HW }, > > 0, 0, VD, "load_plugin" }, > > - > > - { "load_plugins", "A :-separate list of hexadecimal plugin UIDs to > load > > in an internal session", > > - OFFSET(qsv.load_plugins), AV_OPT_TYPE_STRING, { .str = "" }, 0, > 0, VD > > }, > > - > > - { "gpu_copy", "A GPU-accelerated copy between video and system > memory", > > OFFSET(qsv.gpu_copy), AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_DEFAULT }, > > MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF, VD, "gpu_copy"}, > > - { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = > MFX_GPUCOPY_DEFAULT > > }, 0, 0, VD, "gpu_copy"}, > > - { "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON > > }, 0, 0, VD, "gpu_copy"}, > > - { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = > MFX_GPUCOPY_OFF > > }, 0, 0, VD, "gpu_copy"}, > > - { NULL }, > > -}; > > -DEFINE_QSV_DECODER_WITH_OPTION(hevc, HEVC, "hevc_mp4toannexb", > hevc_options) > > -#endif > > - > > -static const AVOption options[] = { > > - { "async_depth", "Internal parallelization depth, the higher the > value > > the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { > .i64 = > > ASYNC_DEPTH_DEFAULT }, 1, INT_MAX, VD }, > > - > > - { "gpu_copy", "A GPU-accelerated copy between video and system > memory", > > OFFSET(qsv.gpu_copy), AV_OPT_TYPE_INT, { .i64 = MFX_GPUCOPY_DEFAULT }, > > MFX_GPUCOPY_DEFAULT, MFX_GPUCOPY_OFF, VD, "gpu_copy"}, > > - { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = > MFX_GPUCOPY_DEFAULT > > }, 0, 0, VD, "gpu_copy"}, > > - { "on", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_GPUCOPY_ON > > }, 0, 0, VD, "gpu_copy"}, > > - { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = > MFX_GPUCOPY_OFF > > }, 0, 0, VD, "gpu_copy"}, > > - { NULL }, > > -}; > > - > > -#if CONFIG_H264_QSV_DECODER > > -DEFINE_QSV_DECODER(h264, H264, "h264_mp4toannexb") > > -#endif > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".