[FFmpeg-devel] [PATCH 6/6] qsv: libmfx no longer supports OPAQUE memory since version 2.0 (oneVPL)
Haihao Xiang
haihao.xiang at intel.com
Wed Sep 16 09:44:57 EEST 2020
---
libavcodec/qsv.c | 4 ++
libavcodec/qsv.h | 2 +
libavcodec/qsv_internal.h | 2 +
libavcodec/qsvdec.c | 9 ++++
libavcodec/qsvenc.c | 21 +++++++++
libavcodec/qsvenc.h | 2 +
libavfilter/qsvvpp.c | 24 ++++++++++-
libavfilter/qsvvpp.h | 2 +
libavfilter/vf_deinterlace_qsv.c | 56 +++++++++++++-----------
libavfilter/vf_scale_qsv.c | 74 ++++++++++++++++++--------------
libavutil/hwcontext_qsv.c | 56 +++++++++++++++++-------
11 files changed, 178 insertions(+), 74 deletions(-)
diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index 2b77fdb2bf..47adacf4f1 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -94,10 +94,14 @@ static const struct {
} qsv_iopatterns[] = {
{MFX_IOPATTERN_IN_VIDEO_MEMORY, "input is video memory surface" },
{MFX_IOPATTERN_IN_SYSTEM_MEMORY, "input is system memory surface" },
+#if QSV_HAVE_OPAQUE
{MFX_IOPATTERN_IN_OPAQUE_MEMORY, "input is opaque memory surface" },
+#endif
{MFX_IOPATTERN_OUT_VIDEO_MEMORY, "output is video memory surface" },
{MFX_IOPATTERN_OUT_SYSTEM_MEMORY, "output is system memory surface" },
+#if QSV_HAVE_OPAQUE
{MFX_IOPATTERN_OUT_OPAQUE_MEMORY, "output is opaque memory surface" },
+#endif
};
int ff_qsv_print_iopattern(void *log_ctx, int mfx_iopattern,
diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h
index 04ae0d6f34..be7b95c724 100644
--- a/libavcodec/qsv.h
+++ b/libavcodec/qsv.h
@@ -61,6 +61,8 @@ typedef struct AVQSVContext {
* required by the encoder and the user-provided value nb_opaque_surfaces.
* The array of the opaque surfaces will be exported to the caller through
* the opaque_surfaces field.
+ *
+ * The caller must set this field to zero for oneVPL (libmfx 2.0+)
*/
int opaque_alloc;
diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
index 4609e7a53b..420615bdce 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -60,6 +60,8 @@
((MFX_VERSION.Major > (MAJOR)) || \
(MFX_VERSION.Major == (MAJOR) && MFX_VERSION.Minor >= (MINOR)))
+#define QSV_HAVE_OPAQUE !QSV_VERSION_ATLEAST(2, 0)
+
typedef struct QSVMid {
AVBufferRef *hw_frames_ref;
mfxHDL handle;
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 9e319ae709..95931aad7d 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -119,7 +119,11 @@ static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession ses
ret = ff_qsv_init_session_frames(avctx, &q->internal_qs.session,
&q->frames_ctx, q->load_plugins,
+#if QSV_HAVE_OPAQUE
q->iopattern == MFX_IOPATTERN_OUT_OPAQUE_MEMORY,
+#else
+ 0,
+#endif
q->gpu_copy);
if (ret < 0) {
av_buffer_unref(&q->frames_ctx.hw_frames_ctx);
@@ -201,10 +205,15 @@ static int qsv_decode_preinit(AVCodecContext *avctx, QSVContext *q, enum AVPixel
AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
if (!iopattern) {
+#if QSV_HAVE_OPAQUE
if (frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)
iopattern = MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
else if (frames_hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET)
iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;
+#else
+ if (frames_hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET)
+ iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;
+#endif
}
}
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 88a8a99517..60e6d64458 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -1008,6 +1008,7 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
return 0;
}
+#if QSV_HAVE_OPAQUE
static int qsv_init_opaque_alloc(AVCodecContext *avctx, QSVEncContext *q)
{
AVQSVContext *qsv = avctx->hwaccel_context;
@@ -1044,6 +1045,7 @@ static int qsv_init_opaque_alloc(AVCodecContext *avctx, QSVEncContext *q)
return 0;
}
+#endif
static int qsvenc_init_session(AVCodecContext *avctx, QSVEncContext *q)
{
@@ -1059,7 +1061,11 @@ static int qsvenc_init_session(AVCodecContext *avctx, QSVEncContext *q)
ret = ff_qsv_init_session_frames(avctx, &q->internal_qs.session,
&q->frames_ctx, q->load_plugins,
+#if QSV_HAVE_OPAQUE
q->param.IOPattern == MFX_IOPATTERN_IN_OPAQUE_MEMORY,
+#else
+ 0,
+#endif
MFX_GPUCOPY_OFF);
if (ret < 0) {
av_buffer_unref(&q->frames_ctx.hw_frames_ctx);
@@ -1121,11 +1127,17 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
if (!iopattern) {
+#if QSV_HAVE_OPAQUE
if (frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)
iopattern = MFX_IOPATTERN_IN_OPAQUE_MEMORY;
else if (frames_hwctx->frame_type &
(MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET | MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET))
iopattern = MFX_IOPATTERN_IN_VIDEO_MEMORY;
+#else
+ if (frames_hwctx->frame_type &
+ (MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET | MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET))
+ iopattern = MFX_IOPATTERN_IN_VIDEO_MEMORY;
+#endif
}
}
@@ -1198,9 +1210,16 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
"Error querying (IOSurf) the encoding parameters");
if (opaque_alloc) {
+#if QSV_HAVE_OPAQUE
ret = qsv_init_opaque_alloc(avctx, q);
if (ret < 0)
return ret;
+#else
+ av_log(avctx, AV_LOG_ERROR, "User is requesting to allocate OPAQUE surface, "
+ "however libmfx %d.%d doesn't support OPAQUE memory.\n",
+ q->ver.Major, q->ver.Minor);
+ return AVERROR_UNKNOWN;
+#endif
}
ret = MFXVideoENCODE_Init(q->session, &q->param);
@@ -1647,8 +1666,10 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
av_fifo_free(q->async_fifo);
q->async_fifo = NULL;
+#if QSV_HAVE_OPAQUE
av_freep(&q->opaque_surfaces);
av_buffer_unref(&q->opaque_alloc_buf);
+#endif
av_freep(&q->extparam);
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 9f3dc0b2ad..295271cdf7 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -135,9 +135,11 @@ typedef struct QSVEncContext {
mfxExtVP9Param extvp9param;
#endif
+#if QSV_HAVE_OPAQUE
mfxExtOpaqueSurfaceAlloc opaque_alloc;
mfxFrameSurface1 **opaque_surfaces;
AVBufferRef *opaque_alloc_buf;
+#endif
mfxExtBuffer *extparam_internal[2 + QSV_HAVE_CO2 + QSV_HAVE_CO3 + (QSV_HAVE_MF * 2)];
int nb_extparam_internal;
diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c
index 8d5ff2eb65..ff6a871956 100644
--- a/libavfilter/qsvvpp.c
+++ b/libavfilter/qsvvpp.c
@@ -34,7 +34,9 @@
#define IS_VIDEO_MEMORY(mode) (mode & (MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET | \
MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET))
+#if QSV_HAVE_OPAQUE
#define IS_OPAQUE_MEMORY(mode) (mode & MFX_MEMTYPE_OPAQUE_FRAME)
+#endif
#define IS_SYSTEM_MEMORY(mode) (mode & MFX_MEMTYPE_SYSTEM_MEMORY)
typedef struct QSVFrame {
@@ -62,10 +64,12 @@ struct QSVVPPContext {
mfxFrameSurface1 **surface_ptrs_in;
mfxFrameSurface1 **surface_ptrs_out;
+#if QSV_HAVE_OPAQUE
/* MFXVPP extern parameters */
mfxExtOpaqueSurfaceAlloc opaque_alloc;
mfxExtBuffer **ext_buffers;
int nb_ext_buffers;
+#endif
};
static const mfxHandleType handle_types[] = {
@@ -449,9 +453,13 @@ static int init_vpp_session(AVFilterContext *avctx, QSVVPPContext *s)
if (!out_frames_ref)
return AVERROR(ENOMEM);
+#if QSV_HAVE_OPAQUE
s->out_mem_mode = IS_OPAQUE_MEMORY(s->in_mem_mode) ?
MFX_MEMTYPE_OPAQUE_FRAME :
MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
+#else
+ s->out_mem_mode = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
+#endif
out_frames_ctx = (AVHWFramesContext *)out_frames_ref->data;
out_frames_hwctx = out_frames_ctx->hwctx;
@@ -529,6 +537,7 @@ static int init_vpp_session(AVFilterContext *avctx, QSVVPPContext *s)
return AVERROR_UNKNOWN;
}
+#if QSV_HAVE_OPAQUE
if (IS_OPAQUE_MEMORY(s->in_mem_mode) || IS_OPAQUE_MEMORY(s->out_mem_mode)) {
s->opaque_alloc.In.Surfaces = s->surface_ptrs_in;
s->opaque_alloc.In.NumSurface = s->nb_surface_ptrs_in;
@@ -540,7 +549,9 @@ static int init_vpp_session(AVFilterContext *avctx, QSVVPPContext *s)
s->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
s->opaque_alloc.Header.BufferSz = sizeof(s->opaque_alloc);
- } else if (IS_VIDEO_MEMORY(s->in_mem_mode) || IS_VIDEO_MEMORY(s->out_mem_mode)) {
+ } else
+#endif
+ if (IS_VIDEO_MEMORY(s->in_mem_mode) || IS_VIDEO_MEMORY(s->out_mem_mode)) {
mfxFrameAllocator frame_allocator = {
.pthis = s,
.Alloc = frame_alloc,
@@ -612,6 +623,7 @@ int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *p
goto failed;
}
+#if QSV_HAVE_OPAQUE
if (IS_OPAQUE_MEMORY(s->in_mem_mode) || IS_OPAQUE_MEMORY(s->out_mem_mode)) {
s->nb_ext_buffers = param->num_ext_buf + 1;
s->ext_buffers = av_mallocz_array(s->nb_ext_buffers, sizeof(*s->ext_buffers));
@@ -629,6 +641,10 @@ int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *p
s->vpp_param.NumExtParam = param->num_ext_buf;
s->vpp_param.ExtParam = param->ext_buf;
}
+#else
+ s->vpp_param.NumExtParam = param->num_ext_buf;
+ s->vpp_param.ExtParam = param->ext_buf;
+#endif
s->vpp_param.AsyncDepth = 1;
@@ -636,15 +652,19 @@ int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *p
s->vpp_param.IOPattern |= MFX_IOPATTERN_IN_SYSTEM_MEMORY;
else if (IS_VIDEO_MEMORY(s->in_mem_mode))
s->vpp_param.IOPattern |= MFX_IOPATTERN_IN_VIDEO_MEMORY;
+#if QSV_HAVE_OPAQUE
else if (IS_OPAQUE_MEMORY(s->in_mem_mode))
s->vpp_param.IOPattern |= MFX_IOPATTERN_IN_OPAQUE_MEMORY;
+#endif
if (IS_SYSTEM_MEMORY(s->out_mem_mode))
s->vpp_param.IOPattern |= MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
else if (IS_VIDEO_MEMORY(s->out_mem_mode))
s->vpp_param.IOPattern |= MFX_IOPATTERN_OUT_VIDEO_MEMORY;
+#if QSV_HAVE_OPAQUE
else if (IS_OPAQUE_MEMORY(s->out_mem_mode))
s->vpp_param.IOPattern |= MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
+#endif
ret = MFXVideoVPP_Init(s->session, &s->vpp_param);
if (ret < 0) {
@@ -678,7 +698,9 @@ int ff_qsvvpp_free(QSVVPPContext **vpp)
clear_frame_list(&s->out_frame_list);
av_freep(&s->surface_ptrs_in);
av_freep(&s->surface_ptrs_out);
+#if QSV_HAVE_OPAQUE
av_freep(&s->ext_buffers);
+#endif
av_freep(&s->frame_infos);
av_freep(vpp);
diff --git a/libavfilter/qsvvpp.h b/libavfilter/qsvvpp.h
index cd3655b7a3..753d4fa767 100644
--- a/libavfilter/qsvvpp.h
+++ b/libavfilter/qsvvpp.h
@@ -39,6 +39,8 @@
((MFX_VERSION.Major > (MAJOR)) || \
(MFX_VERSION.Major == (MAJOR) && MFX_VERSION.Minor >= (MINOR)))
+#define QSV_HAVE_OPAQUE !QSV_VERSION_ATLEAST(2, 0)
+
typedef struct QSVVPPContext QSVVPPContext;
typedef struct QSVVPPCrop {
diff --git a/libavfilter/vf_deinterlace_qsv.c b/libavfilter/vf_deinterlace_qsv.c
index 99257be433..97b580cac9 100644
--- a/libavfilter/vf_deinterlace_qsv.c
+++ b/libavfilter/vf_deinterlace_qsv.c
@@ -68,7 +68,9 @@ typedef struct QSVDeintContext {
mfxFrameSurface1 **surface_ptrs;
int nb_surface_ptrs;
+#if QSV_HAVE_OPAQUE
mfxExtOpaqueSurfaceAlloc opaque_alloc;
+#endif
mfxExtVPPDeinterlacing deint_conf;
mfxExtBuffer *ext_buffers[2];
int num_ext_buffers;
@@ -174,9 +176,7 @@ static int init_out_session(AVFilterContext *ctx)
AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)s->hw_frames_ctx->data;
AVQSVFramesContext *hw_frames_hwctx = hw_frames_ctx->hwctx;
AVQSVDeviceContext *device_hwctx = hw_frames_ctx->device_ctx->hwctx;
-
- int opaque = !!(hw_frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME);
-
+ int opaque = 0;
mfxHDL handle = NULL;
mfxHandleType handle_type;
mfxVersion ver;
@@ -185,6 +185,9 @@ static int init_out_session(AVFilterContext *ctx)
mfxStatus err;
int i;
+#if QSV_HAVE_OPAQUE
+ opaque = !!(hw_frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME);
+#endif
/* extract the properties of the "master" session given to us */
err = MFXQueryIMPL(device_hwctx->session, &impl);
if (err == MFX_ERR_NONE)
@@ -235,28 +238,7 @@ static int init_out_session(AVFilterContext *ctx)
s->ext_buffers[s->num_ext_buffers++] = (mfxExtBuffer *)&s->deint_conf;
- if (opaque) {
- s->surface_ptrs = av_mallocz_array(hw_frames_hwctx->nb_surfaces,
- sizeof(*s->surface_ptrs));
- if (!s->surface_ptrs)
- return AVERROR(ENOMEM);
- for (i = 0; i < hw_frames_hwctx->nb_surfaces; i++)
- s->surface_ptrs[i] = hw_frames_hwctx->surfaces + i;
- s->nb_surface_ptrs = hw_frames_hwctx->nb_surfaces;
-
- s->opaque_alloc.In.Surfaces = s->surface_ptrs;
- s->opaque_alloc.In.NumSurface = s->nb_surface_ptrs;
- s->opaque_alloc.In.Type = hw_frames_hwctx->frame_type;
-
- s->opaque_alloc.Out = s->opaque_alloc.In;
-
- s->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
- s->opaque_alloc.Header.BufferSz = sizeof(s->opaque_alloc);
-
- s->ext_buffers[s->num_ext_buffers++] = (mfxExtBuffer *)&s->opaque_alloc;
-
- par.IOPattern = MFX_IOPATTERN_IN_OPAQUE_MEMORY | MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
- } else {
+ if (!opaque) {
mfxFrameAllocator frame_allocator = {
.pthis = ctx,
.Alloc = frame_alloc,
@@ -280,6 +262,30 @@ static int init_out_session(AVFilterContext *ctx)
par.IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY | MFX_IOPATTERN_OUT_VIDEO_MEMORY;
}
+#if QSV_HAVE_OPAQUE
+ else {
+ s->surface_ptrs = av_mallocz_array(hw_frames_hwctx->nb_surfaces,
+ sizeof(*s->surface_ptrs));
+ if (!s->surface_ptrs)
+ return AVERROR(ENOMEM);
+ for (i = 0; i < hw_frames_hwctx->nb_surfaces; i++)
+ s->surface_ptrs[i] = hw_frames_hwctx->surfaces + i;
+ s->nb_surface_ptrs = hw_frames_hwctx->nb_surfaces;
+
+ s->opaque_alloc.In.Surfaces = s->surface_ptrs;
+ s->opaque_alloc.In.NumSurface = s->nb_surface_ptrs;
+ s->opaque_alloc.In.Type = hw_frames_hwctx->frame_type;
+
+ s->opaque_alloc.Out = s->opaque_alloc.In;
+
+ s->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
+ s->opaque_alloc.Header.BufferSz = sizeof(s->opaque_alloc);
+
+ s->ext_buffers[s->num_ext_buffers++] = (mfxExtBuffer *)&s->opaque_alloc;
+
+ par.IOPattern = MFX_IOPATTERN_IN_OPAQUE_MEMORY | MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
+ }
+#endif
par.ExtParam = s->ext_buffers;
par.NumExtParam = s->num_ext_buffers;
diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c
index b79ef75b0f..69a5ac7d13 100644
--- a/libavfilter/vf_scale_qsv.c
+++ b/libavfilter/vf_scale_qsv.c
@@ -89,7 +89,9 @@ typedef struct QSVScaleContext {
mfxFrameSurface1 **surface_ptrs_out;
int nb_surface_ptrs_out;
+#if QSV_HAVE_OPAQUE
mfxExtOpaqueSurfaceAlloc opaque_alloc;
+#endif
#if QSV_HAVE_SCALING_CONFIG
mfxExtVPPScaling scale_conf;
@@ -284,7 +286,7 @@ static int init_out_session(AVFilterContext *ctx)
AVQSVFramesContext *out_frames_hwctx = out_frames_ctx->hwctx;
AVQSVDeviceContext *device_hwctx = in_frames_ctx->device_ctx->hwctx;
- int opaque = !!(in_frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME);
+ int opaque = 0;
mfxHDL handle = NULL;
mfxHandleType handle_type;
@@ -294,6 +296,9 @@ static int init_out_session(AVFilterContext *ctx)
mfxStatus err;
int i;
+#if QSV_HAVE_OPAQUE
+ opaque = !!(in_frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME);
+#endif
s->num_ext_buf = 0;
/* extract the properties of the "master" session given to us */
@@ -340,38 +345,7 @@ static int init_out_session(AVFilterContext *ctx)
memset(&par, 0, sizeof(par));
- if (opaque) {
- s->surface_ptrs_in = av_mallocz_array(in_frames_hwctx->nb_surfaces,
- sizeof(*s->surface_ptrs_in));
- if (!s->surface_ptrs_in)
- return AVERROR(ENOMEM);
- for (i = 0; i < in_frames_hwctx->nb_surfaces; i++)
- s->surface_ptrs_in[i] = in_frames_hwctx->surfaces + i;
- s->nb_surface_ptrs_in = in_frames_hwctx->nb_surfaces;
-
- s->surface_ptrs_out = av_mallocz_array(out_frames_hwctx->nb_surfaces,
- sizeof(*s->surface_ptrs_out));
- if (!s->surface_ptrs_out)
- return AVERROR(ENOMEM);
- for (i = 0; i < out_frames_hwctx->nb_surfaces; i++)
- s->surface_ptrs_out[i] = out_frames_hwctx->surfaces + i;
- s->nb_surface_ptrs_out = out_frames_hwctx->nb_surfaces;
-
- s->opaque_alloc.In.Surfaces = s->surface_ptrs_in;
- s->opaque_alloc.In.NumSurface = s->nb_surface_ptrs_in;
- s->opaque_alloc.In.Type = in_frames_hwctx->frame_type;
-
- s->opaque_alloc.Out.Surfaces = s->surface_ptrs_out;
- s->opaque_alloc.Out.NumSurface = s->nb_surface_ptrs_out;
- s->opaque_alloc.Out.Type = out_frames_hwctx->frame_type;
-
- s->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
- s->opaque_alloc.Header.BufferSz = sizeof(s->opaque_alloc);
-
- s->ext_buffers[s->num_ext_buf++] = (mfxExtBuffer*)&s->opaque_alloc;
-
- par.IOPattern = MFX_IOPATTERN_IN_OPAQUE_MEMORY | MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
- } else {
+ if (!opaque) {
mfxFrameAllocator frame_allocator = {
.pthis = ctx,
.Alloc = frame_alloc,
@@ -403,6 +377,40 @@ static int init_out_session(AVFilterContext *ctx)
par.IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY | MFX_IOPATTERN_OUT_VIDEO_MEMORY;
}
+#if QSV_HAVE_OPAQUE
+ else {
+ s->surface_ptrs_in = av_mallocz_array(in_frames_hwctx->nb_surfaces,
+ sizeof(*s->surface_ptrs_in));
+ if (!s->surface_ptrs_in)
+ return AVERROR(ENOMEM);
+ for (i = 0; i < in_frames_hwctx->nb_surfaces; i++)
+ s->surface_ptrs_in[i] = in_frames_hwctx->surfaces + i;
+ s->nb_surface_ptrs_in = in_frames_hwctx->nb_surfaces;
+
+ s->surface_ptrs_out = av_mallocz_array(out_frames_hwctx->nb_surfaces,
+ sizeof(*s->surface_ptrs_out));
+ if (!s->surface_ptrs_out)
+ return AVERROR(ENOMEM);
+ for (i = 0; i < out_frames_hwctx->nb_surfaces; i++)
+ s->surface_ptrs_out[i] = out_frames_hwctx->surfaces + i;
+ s->nb_surface_ptrs_out = out_frames_hwctx->nb_surfaces;
+
+ s->opaque_alloc.In.Surfaces = s->surface_ptrs_in;
+ s->opaque_alloc.In.NumSurface = s->nb_surface_ptrs_in;
+ s->opaque_alloc.In.Type = in_frames_hwctx->frame_type;
+
+ s->opaque_alloc.Out.Surfaces = s->surface_ptrs_out;
+ s->opaque_alloc.Out.NumSurface = s->nb_surface_ptrs_out;
+ s->opaque_alloc.Out.Type = out_frames_hwctx->frame_type;
+
+ s->opaque_alloc.Header.BufferId = MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION;
+ s->opaque_alloc.Header.BufferSz = sizeof(s->opaque_alloc);
+
+ s->ext_buffers[s->num_ext_buf++] = (mfxExtBuffer*)&s->opaque_alloc;
+
+ par.IOPattern = MFX_IOPATTERN_IN_OPAQUE_MEMORY | MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
+ }
+#endif
#if QSV_HAVE_SCALING_CONFIG
memset(&s->scale_conf, 0, sizeof(mfxExtVPPScaling));
diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index e36299896c..91c621850e 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -48,6 +48,8 @@
(MFX_VERSION_MAJOR > (MAJOR) || \
MFX_VERSION_MAJOR == (MAJOR) && MFX_VERSION_MINOR >= (MINOR))
+#define QSV_HAVE_OPAQUE !QSV_VERSION_ATLEAST(2, 0)
+
typedef struct QSVDevicePriv {
AVBufferRef *child_device_ctx;
} QSVDevicePriv;
@@ -78,11 +80,13 @@ typedef struct QSVFramesContext {
// used in the frame allocator for non-opaque surfaces
mfxMemId *mem_ids;
+#if QSV_HAVE_OPAQUE
// used in the opaque alloc request for opaque surfaces
mfxFrameSurface1 **surface_ptrs;
mfxExtOpaqueSurfaceAlloc opaque_alloc;
mfxExtBuffer *ext_buffers[1];
+#endif
} QSVFramesContext;
static const struct {
@@ -185,7 +189,9 @@ static void qsv_frames_uninit(AVHWFramesContext *ctx)
#endif
av_freep(&s->mem_ids);
+#if QSV_HAVE_OPAQUE
av_freep(&s->surface_ptrs);
+#endif
av_freep(&s->surfaces_internal);
av_buffer_unref(&s->child_frames_ref);
}
@@ -371,11 +377,17 @@ static int qsv_init_pool(AVHWFramesContext *ctx, uint32_t fourcc)
return ret;
}
+#if QSV_HAVE_OPAQUE
if (!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)) {
ret = qsv_init_child_ctx(ctx);
if (ret < 0)
return ret;
}
+#else
+ ret = qsv_init_child_ctx(ctx);
+ if (ret < 0)
+ return ret;
+#endif
ctx->internal->pool_internal = av_buffer_pool_init2(sizeof(mfxFrameSurface1),
ctx, qsv_pool_alloc, NULL);
@@ -440,10 +452,9 @@ static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
static int qsv_init_internal_session(AVHWFramesContext *ctx,
mfxSession *session, int upload)
{
- QSVFramesContext *s = ctx->internal->priv;
AVQSVFramesContext *frames_hwctx = ctx->hwctx;
QSVDeviceContext *device_priv = ctx->device_ctx->internal->priv;
- int opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME);
+ int opaque = 0;
mfxFrameAllocator frame_allocator = {
.pthis = ctx,
@@ -457,6 +468,11 @@ static int qsv_init_internal_session(AVHWFramesContext *ctx,
mfxVideoParam par;
mfxStatus err;
+#if QSV_HAVE_OPAQUE
+ QSVFramesContext *s = ctx->internal->priv;
+ opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME);
+#endif
+
err = MFXInit(device_priv->impl, &device_priv->ver, session);
if (err != MFX_ERR_NONE) {
av_log(ctx, AV_LOG_ERROR, "Error initializing an internal session\n");
@@ -478,15 +494,18 @@ static int qsv_init_internal_session(AVHWFramesContext *ctx,
memset(&par, 0, sizeof(par));
- if (opaque) {
+ if (!opaque) {
+ par.IOPattern = upload ? MFX_IOPATTERN_OUT_VIDEO_MEMORY :
+ MFX_IOPATTERN_IN_VIDEO_MEMORY;
+ }
+#if QSV_HAVE_OPAQUE
+ else {
par.ExtParam = s->ext_buffers;
par.NumExtParam = FF_ARRAY_ELEMS(s->ext_buffers);
par.IOPattern = upload ? MFX_IOPATTERN_OUT_OPAQUE_MEMORY :
MFX_IOPATTERN_IN_OPAQUE_MEMORY;
- } else {
- par.IOPattern = upload ? MFX_IOPATTERN_OUT_VIDEO_MEMORY :
- MFX_IOPATTERN_IN_VIDEO_MEMORY;
}
+#endif
par.IOPattern |= upload ? MFX_IOPATTERN_IN_SYSTEM_MEMORY :
MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
@@ -518,11 +537,15 @@ static int qsv_frames_init(AVHWFramesContext *ctx)
QSVFramesContext *s = ctx->internal->priv;
AVQSVFramesContext *frames_hwctx = ctx->hwctx;
- int opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME);
+ int opaque = 0;
uint32_t fourcc;
int i, ret;
+#if QSV_HAVE_OPAQUE
+ opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME);
+#endif
+
fourcc = qsv_fourcc_from_pix_fmt(ctx->sw_format);
if (!fourcc) {
av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format\n");
@@ -537,7 +560,16 @@ static int qsv_frames_init(AVHWFramesContext *ctx)
}
}
- if (opaque) {
+ if (!opaque) {
+ s->mem_ids = av_mallocz_array(frames_hwctx->nb_surfaces, sizeof(*s->mem_ids));
+ if (!s->mem_ids)
+ return AVERROR(ENOMEM);
+
+ for (i = 0; i < frames_hwctx->nb_surfaces; i++)
+ s->mem_ids[i] = frames_hwctx->surfaces[i].Data.MemId;
+ }
+#if QSV_HAVE_OPAQUE
+ else {
s->surface_ptrs = av_mallocz_array(frames_hwctx->nb_surfaces,
sizeof(*s->surface_ptrs));
if (!s->surface_ptrs)
@@ -556,14 +588,8 @@ static int qsv_frames_init(AVHWFramesContext *ctx)
s->opaque_alloc.Header.BufferSz = sizeof(s->opaque_alloc);
s->ext_buffers[0] = (mfxExtBuffer*)&s->opaque_alloc;
- } else {
- s->mem_ids = av_mallocz_array(frames_hwctx->nb_surfaces, sizeof(*s->mem_ids));
- if (!s->mem_ids)
- return AVERROR(ENOMEM);
-
- for (i = 0; i < frames_hwctx->nb_surfaces; i++)
- s->mem_ids[i] = frames_hwctx->surfaces[i].Data.MemId;
}
+#endif
s->session_download = NULL;
s->session_upload = NULL;
--
2.25.1
More information about the ffmpeg-devel
mailing list