1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-06-30 22:24:04 +02:00

lavc/qsv: fix the mfx allocator to support dynamic frame pool

When the external allocator is used for dynamic frame allocation, only
video memory is supported, the SDK doesn't lock/unlock the memory block
via Lock()/Unlock() calls.

Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
This commit is contained in:
Haihao Xiang
2024-05-08 14:03:12 +08:00
parent d3cc5ead42
commit cda721e01d

View File

@ -825,8 +825,16 @@ static mfxStatus qsv_frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req,
AVHWFramesContext *frames_ctx = (AVHWFramesContext*)ctx->hw_frames_ctx->data; AVHWFramesContext *frames_ctx = (AVHWFramesContext*)ctx->hw_frames_ctx->data;
AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx; AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
mfxFrameInfo *i = &req->Info; mfxFrameInfo *i = &req->Info;
mfxFrameInfo *i1 = &frames_hwctx->surfaces[0].Info; mfxFrameInfo *i1;
if (!frames_hwctx->nb_surfaces) {
av_log(ctx->logctx, AV_LOG_DEBUG,
"Dynamic frame pools, no frame is pre-allocated\n");
return MFX_ERR_NONE;
}
i1 = &frames_hwctx->surfaces[0].Info;
if (i->Width > i1->Width || i->Height > i1->Height || if (i->Width > i1->Width || i->Height > i1->Height ||
i->FourCC != i1->FourCC || i->ChromaFormat != i1->ChromaFormat) { i->FourCC != i1->FourCC || i->ChromaFormat != i1->ChromaFormat) {
av_log(ctx->logctx, AV_LOG_ERROR, "Mismatching surface properties in an " av_log(ctx->logctx, AV_LOG_ERROR, "Mismatching surface properties in an "
@ -845,6 +853,7 @@ static mfxStatus qsv_frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req,
} else if (req->Type & MFX_MEMTYPE_INTERNAL_FRAME) { } else if (req->Type & MFX_MEMTYPE_INTERNAL_FRAME) {
/* internal frames -- allocate a new hw frames context */ /* internal frames -- allocate a new hw frames context */
AVHWFramesContext *ext_frames_ctx = (AVHWFramesContext*)ctx->hw_frames_ctx->data; AVHWFramesContext *ext_frames_ctx = (AVHWFramesContext*)ctx->hw_frames_ctx->data;
AVQSVFramesContext *ext_frames_hwctx = ext_frames_ctx->hwctx;
mfxFrameInfo *i = &req->Info; mfxFrameInfo *i = &req->Info;
AVBufferRef *frames_ref; AVBufferRef *frames_ref;
@ -852,6 +861,9 @@ static mfxStatus qsv_frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req,
AVHWFramesContext *frames_ctx; AVHWFramesContext *frames_ctx;
AVQSVFramesContext *frames_hwctx; AVQSVFramesContext *frames_hwctx;
if (!ext_frames_hwctx->nb_surfaces)
return MFX_ERR_UNSUPPORTED;
frames_ref = av_hwframe_ctx_alloc(ext_frames_ctx->device_ref); frames_ref = av_hwframe_ctx_alloc(ext_frames_ctx->device_ref);
if (!frames_ref) if (!frames_ref)
return MFX_ERR_MEMORY_ALLOC; return MFX_ERR_MEMORY_ALLOC;
@ -899,6 +911,9 @@ static mfxStatus qsv_frame_alloc(mfxHDL pthis, mfxFrameAllocRequest *req,
static mfxStatus qsv_frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp) static mfxStatus qsv_frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp)
{ {
if (!resp->mids)
return MFX_ERR_NONE;
av_buffer_unref((AVBufferRef**)&resp->mids[resp->NumFrameActual]); av_buffer_unref((AVBufferRef**)&resp->mids[resp->NumFrameActual]);
ff_refstruct_unref(&resp->mids[resp->NumFrameActual + 1]); ff_refstruct_unref(&resp->mids[resp->NumFrameActual + 1]);
av_freep(&resp->mids); av_freep(&resp->mids);
@ -907,11 +922,20 @@ static mfxStatus qsv_frame_free(mfxHDL pthis, mfxFrameAllocResponse *resp)
static mfxStatus qsv_frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) static mfxStatus qsv_frame_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
{ {
QSVMid *qsv_mid = mid; QSVFramesContext *ctx = (QSVFramesContext *)pthis;
AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)qsv_mid->hw_frames_ref->data; AVHWFramesContext *frames_ctx = (AVHWFramesContext*)ctx->hw_frames_ctx->data;
AVQSVFramesContext *hw_frames_hwctx = hw_frames_ctx->hwctx; AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
QSVMid *qsv_mid;
AVHWFramesContext *hw_frames_ctx;
AVQSVFramesContext *hw_frames_hwctx;
int ret; int ret;
if (!frames_hwctx->nb_surfaces)
return MFX_ERR_UNSUPPORTED;
qsv_mid = mid;
hw_frames_ctx = (AVHWFramesContext*)qsv_mid->hw_frames_ref->data;
hw_frames_hwctx = hw_frames_ctx->hwctx;
if (qsv_mid->locked_frame) if (qsv_mid->locked_frame)
return MFX_ERR_UNDEFINED_BEHAVIOR; return MFX_ERR_UNDEFINED_BEHAVIOR;
@ -964,8 +988,15 @@ fail:
static mfxStatus qsv_frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr) static mfxStatus qsv_frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
{ {
QSVMid *qsv_mid = mid; QSVFramesContext *ctx = (QSVFramesContext *)pthis;
AVHWFramesContext *frames_ctx = (AVHWFramesContext*)ctx->hw_frames_ctx->data;
AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
QSVMid *qsv_mid;
if (!frames_hwctx->nb_surfaces)
return MFX_ERR_UNSUPPORTED;
qsv_mid = mid;
av_frame_free(&qsv_mid->locked_frame); av_frame_free(&qsv_mid->locked_frame);
av_frame_free(&qsv_mid->hw_frame); av_frame_free(&qsv_mid->hw_frame);
@ -974,9 +1005,18 @@ static mfxStatus qsv_frame_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
static mfxStatus qsv_frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl) static mfxStatus qsv_frame_get_hdl(mfxHDL pthis, mfxMemId mid, mfxHDL *hdl)
{ {
QSVMid *qsv_mid = (QSVMid*)mid; QSVFramesContext *ctx = (QSVFramesContext *)pthis;
AVHWFramesContext *frames_ctx = (AVHWFramesContext*)ctx->hw_frames_ctx->data;
AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
mfxHDLPair *pair_dst = (mfxHDLPair*)hdl; mfxHDLPair *pair_dst = (mfxHDLPair*)hdl;
mfxHDLPair *pair_src = (mfxHDLPair*)qsv_mid->handle_pair; mfxHDLPair *pair_src;
if (frames_hwctx->nb_surfaces) {
QSVMid *qsv_mid = (QSVMid*)mid;
pair_src = (mfxHDLPair*)qsv_mid->handle_pair;
} else {
pair_src = (mfxHDLPair*)mid;
}
pair_dst->first = pair_src->first; pair_dst->first = pair_src->first;
@ -1090,13 +1130,17 @@ int ff_qsv_init_session_frames(AVCodecContext *avctx, mfxSession *psession,
if (!opaque) { if (!opaque) {
qsv_frames_ctx->logctx = avctx; qsv_frames_ctx->logctx = avctx;
qsv_frames_ctx->mids = NULL;
qsv_frames_ctx->nb_mids = 0;
/* allocate the memory ids for the external frames */ /* allocate the memory ids for the external frames */
ff_refstruct_unref(&qsv_frames_ctx->mids); if (frames_hwctx->nb_surfaces) {
qsv_frames_ctx->mids = qsv_create_mids(qsv_frames_ctx->hw_frames_ctx); ff_refstruct_unref(&qsv_frames_ctx->mids);
if (!qsv_frames_ctx->mids) qsv_frames_ctx->mids = qsv_create_mids(qsv_frames_ctx->hw_frames_ctx);
return AVERROR(ENOMEM); if (!qsv_frames_ctx->mids)
qsv_frames_ctx->nb_mids = frames_hwctx->nb_surfaces; return AVERROR(ENOMEM);
qsv_frames_ctx->nb_mids = frames_hwctx->nb_surfaces;
}
err = MFXVideoCORE_SetFrameAllocator(session, &frame_allocator); err = MFXVideoCORE_SetFrameAllocator(session, &frame_allocator);
if (err != MFX_ERR_NONE) if (err != MFX_ERR_NONE)