|
|
@ -55,6 +55,8 @@ |
|
|
|
MFX_VERSION_MAJOR == (MAJOR) && MFX_VERSION_MINOR >= (MINOR)) |
|
|
|
MFX_VERSION_MAJOR == (MAJOR) && MFX_VERSION_MINOR >= (MINOR)) |
|
|
|
|
|
|
|
|
|
|
|
#define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl)) |
|
|
|
#define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl)) |
|
|
|
|
|
|
|
#define QSV_ONEVPL QSV_VERSION_ATLEAST(2, 0) |
|
|
|
|
|
|
|
#define QSV_HAVE_OPAQUE !QSV_ONEVPL |
|
|
|
|
|
|
|
|
|
|
|
typedef struct QSVDevicePriv { |
|
|
|
typedef struct QSVDevicePriv { |
|
|
|
AVBufferRef *child_device_ctx; |
|
|
|
AVBufferRef *child_device_ctx; |
|
|
@ -86,11 +88,13 @@ typedef struct QSVFramesContext { |
|
|
|
|
|
|
|
|
|
|
|
// used in the frame allocator for non-opaque surfaces
|
|
|
|
// used in the frame allocator for non-opaque surfaces
|
|
|
|
mfxMemId *mem_ids; |
|
|
|
mfxMemId *mem_ids; |
|
|
|
|
|
|
|
#if QSV_HAVE_OPAQUE |
|
|
|
// used in the opaque alloc request for opaque surfaces
|
|
|
|
// used in the opaque alloc request for opaque surfaces
|
|
|
|
mfxFrameSurface1 **surface_ptrs; |
|
|
|
mfxFrameSurface1 **surface_ptrs; |
|
|
|
|
|
|
|
|
|
|
|
mfxExtOpaqueSurfaceAlloc opaque_alloc; |
|
|
|
mfxExtOpaqueSurfaceAlloc opaque_alloc; |
|
|
|
mfxExtBuffer *ext_buffers[1]; |
|
|
|
mfxExtBuffer *ext_buffers[1]; |
|
|
|
|
|
|
|
#endif |
|
|
|
AVFrame realigned_upload_frame; |
|
|
|
AVFrame realigned_upload_frame; |
|
|
|
AVFrame realigned_download_frame; |
|
|
|
AVFrame realigned_download_frame; |
|
|
|
} QSVFramesContext; |
|
|
|
} QSVFramesContext; |
|
|
@ -299,7 +303,9 @@ static void qsv_frames_uninit(AVHWFramesContext *ctx) |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
av_freep(&s->mem_ids); |
|
|
|
av_freep(&s->mem_ids); |
|
|
|
|
|
|
|
#if QSV_HAVE_OPAQUE |
|
|
|
av_freep(&s->surface_ptrs); |
|
|
|
av_freep(&s->surface_ptrs); |
|
|
|
|
|
|
|
#endif |
|
|
|
av_freep(&s->surfaces_internal); |
|
|
|
av_freep(&s->surfaces_internal); |
|
|
|
av_freep(&s->handle_pairs_internal); |
|
|
|
av_freep(&s->handle_pairs_internal); |
|
|
|
av_frame_unref(&s->realigned_upload_frame); |
|
|
|
av_frame_unref(&s->realigned_upload_frame); |
|
|
@ -535,11 +541,17 @@ static int qsv_init_pool(AVHWFramesContext *ctx, uint32_t fourcc) |
|
|
|
return ret; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if QSV_HAVE_OPAQUE |
|
|
|
if (!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)) { |
|
|
|
if (!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)) { |
|
|
|
ret = qsv_init_child_ctx(ctx); |
|
|
|
ret = qsv_init_child_ctx(ctx); |
|
|
|
if (ret < 0) |
|
|
|
if (ret < 0) |
|
|
|
return ret; |
|
|
|
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->internal->pool_internal = av_buffer_pool_init2(sizeof(mfxFrameSurface1), |
|
|
|
ctx, qsv_pool_alloc, NULL); |
|
|
|
ctx, qsv_pool_alloc, NULL); |
|
|
@ -610,10 +622,9 @@ static mfxStatus frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl) |
|
|
|
static int qsv_init_internal_session(AVHWFramesContext *ctx, |
|
|
|
static int qsv_init_internal_session(AVHWFramesContext *ctx, |
|
|
|
mfxSession *session, int upload) |
|
|
|
mfxSession *session, int upload) |
|
|
|
{ |
|
|
|
{ |
|
|
|
QSVFramesContext *s = ctx->internal->priv; |
|
|
|
|
|
|
|
AVQSVFramesContext *frames_hwctx = ctx->hwctx; |
|
|
|
AVQSVFramesContext *frames_hwctx = ctx->hwctx; |
|
|
|
QSVDeviceContext *device_priv = ctx->device_ctx->internal->priv; |
|
|
|
QSVDeviceContext *device_priv = ctx->device_ctx->internal->priv; |
|
|
|
int opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME); |
|
|
|
int opaque = 0; |
|
|
|
|
|
|
|
|
|
|
|
mfxFrameAllocator frame_allocator = { |
|
|
|
mfxFrameAllocator frame_allocator = { |
|
|
|
.pthis = ctx, |
|
|
|
.pthis = ctx, |
|
|
@ -627,6 +638,11 @@ static int qsv_init_internal_session(AVHWFramesContext *ctx, |
|
|
|
mfxVideoParam par; |
|
|
|
mfxVideoParam par; |
|
|
|
mfxStatus err; |
|
|
|
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); |
|
|
|
err = MFXInit(device_priv->impl, &device_priv->ver, session); |
|
|
|
if (err != MFX_ERR_NONE) { |
|
|
|
if (err != MFX_ERR_NONE) { |
|
|
|
av_log(ctx, AV_LOG_ERROR, "Error initializing an internal session\n"); |
|
|
|
av_log(ctx, AV_LOG_ERROR, "Error initializing an internal session\n"); |
|
|
@ -648,15 +664,18 @@ static int qsv_init_internal_session(AVHWFramesContext *ctx, |
|
|
|
|
|
|
|
|
|
|
|
memset(&par, 0, sizeof(par)); |
|
|
|
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.ExtParam = s->ext_buffers; |
|
|
|
par.NumExtParam = FF_ARRAY_ELEMS(s->ext_buffers); |
|
|
|
par.NumExtParam = FF_ARRAY_ELEMS(s->ext_buffers); |
|
|
|
par.IOPattern = upload ? MFX_IOPATTERN_OUT_OPAQUE_MEMORY : |
|
|
|
par.IOPattern = upload ? MFX_IOPATTERN_OUT_OPAQUE_MEMORY : |
|
|
|
MFX_IOPATTERN_IN_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 : |
|
|
|
par.IOPattern |= upload ? MFX_IOPATTERN_IN_SYSTEM_MEMORY : |
|
|
|
MFX_IOPATTERN_OUT_SYSTEM_MEMORY; |
|
|
|
MFX_IOPATTERN_OUT_SYSTEM_MEMORY; |
|
|
@ -688,11 +707,15 @@ static int qsv_frames_init(AVHWFramesContext *ctx) |
|
|
|
QSVFramesContext *s = ctx->internal->priv; |
|
|
|
QSVFramesContext *s = ctx->internal->priv; |
|
|
|
AVQSVFramesContext *frames_hwctx = ctx->hwctx; |
|
|
|
AVQSVFramesContext *frames_hwctx = ctx->hwctx; |
|
|
|
|
|
|
|
|
|
|
|
int opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME); |
|
|
|
int opaque = 0; |
|
|
|
|
|
|
|
|
|
|
|
uint32_t fourcc; |
|
|
|
uint32_t fourcc; |
|
|
|
int i, ret; |
|
|
|
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); |
|
|
|
fourcc = qsv_fourcc_from_pix_fmt(ctx->sw_format); |
|
|
|
if (!fourcc) { |
|
|
|
if (!fourcc) { |
|
|
|
av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format\n"); |
|
|
|
av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format\n"); |
|
|
@ -707,7 +730,16 @@ static int qsv_frames_init(AVHWFramesContext *ctx) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (opaque) { |
|
|
|
if (!opaque) { |
|
|
|
|
|
|
|
s->mem_ids = av_calloc(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_calloc(frames_hwctx->nb_surfaces, |
|
|
|
s->surface_ptrs = av_calloc(frames_hwctx->nb_surfaces, |
|
|
|
sizeof(*s->surface_ptrs)); |
|
|
|
sizeof(*s->surface_ptrs)); |
|
|
|
if (!s->surface_ptrs) |
|
|
|
if (!s->surface_ptrs) |
|
|
@ -726,14 +758,8 @@ static int qsv_frames_init(AVHWFramesContext *ctx) |
|
|
|
s->opaque_alloc.Header.BufferSz = sizeof(s->opaque_alloc); |
|
|
|
s->opaque_alloc.Header.BufferSz = sizeof(s->opaque_alloc); |
|
|
|
|
|
|
|
|
|
|
|
s->ext_buffers[0] = (mfxExtBuffer*)&s->opaque_alloc; |
|
|
|
s->ext_buffers[0] = (mfxExtBuffer*)&s->opaque_alloc; |
|
|
|
} else { |
|
|
|
|
|
|
|
s->mem_ids = av_calloc(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_download = NULL; |
|
|
|
s->session_upload = NULL; |
|
|
|
s->session_upload = NULL; |
|
|
|