1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-11-23 21:54:53 +02:00

avutil/hwcontext_amf: Simplified blocking before frame submission

Instead of blocking the entire context, which can cause issues in more
complex pipelines, now only frame sending is blocked via AVMutex
This commit is contained in:
Dmitrii Ovchinnikov
2025-07-23 16:51:33 +02:00
parent 6cdd2cbe32
commit 62184be548
3 changed files with 11 additions and 90 deletions

View File

@@ -381,89 +381,6 @@ static AMF_RESULT amf_set_property_buffer(AMFSurface *object, const wchar_t *nam
return res;
}
static AMF_RESULT amf_lock_context(AVCodecContext *avctx)
{
AMFEncoderContext *ctx = avctx->priv_data;
AVHWDeviceContext *hw_device_ctx = (AVHWDeviceContext*)ctx->device_ctx_ref->data;
AVAMFDeviceContext *amf_device_ctx = (AVAMFDeviceContext *)hw_device_ctx->hwctx;
AMF_RESULT res;
switch(amf_device_ctx->memory_type) {
case AMF_MEMORY_DX11:
res = amf_device_ctx->context->pVtbl->LockDX11(amf_device_ctx->context);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR(ENOMEM), "LockDX11() failed with error %d\n", res);
break;
case AMF_MEMORY_DX12:
{
AMFContext2 *context2 = NULL;
AMFGuid guid = IID_AMFContext2();
res = amf_device_ctx->context->pVtbl->QueryInterface(amf_device_ctx->context, &guid, (void**)&context2);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "QueryInterface for AMFContext2 failed with error %d\n", res);
res = context2->pVtbl->LockDX12(context2);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR(ENOMEM), "LockDX12() failed with error %d\n", res);
context2->pVtbl->Release(context2);
}
break;
case AMF_MEMORY_DX9:
res = amf_device_ctx->context->pVtbl->LockDX9(amf_device_ctx->context);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR(ENOMEM), "LockDX9() failed with error %d\n", res);
case AMF_MEMORY_VULKAN:
{
AMFContext2 *context2 = NULL;
AMFGuid guid = IID_AMFContext2();
res = amf_device_ctx->context->pVtbl->QueryInterface(amf_device_ctx->context, &guid, (void**)&context2);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "QueryInterface for AMFContext2 failed with error %d\n", res);
res = context2->pVtbl->LockVulkan(context2);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR(ENOMEM), "LockVulkan() failed with error %d\n", res);
context2->pVtbl->Release(context2);
}
break;
}
return AMF_OK;
}
static AMF_RESULT amf_unlock_context(AVCodecContext *avctx)
{
AMFEncoderContext *ctx = avctx->priv_data;
AVHWDeviceContext *hw_device_ctx = (AVHWDeviceContext*)ctx->device_ctx_ref->data;
AVAMFDeviceContext *amf_device_ctx = (AVAMFDeviceContext *)hw_device_ctx->hwctx;
AMF_RESULT res;
switch(amf_device_ctx->memory_type) {
case AMF_MEMORY_DX11:
res = amf_device_ctx->context->pVtbl->UnlockDX11(amf_device_ctx->context);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR(ENOMEM), "LockDX11() failed with error %d\n", res);
break;
case AMF_MEMORY_DX12:
{
AMFContext2 *context2 = NULL;
AMFGuid guid = IID_AMFContext2();
res = amf_device_ctx->context->pVtbl->QueryInterface(amf_device_ctx->context, &guid, (void**)&context2);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "QueryInterface for AMFContext2 failed with error %d\n", res);
res = context2->pVtbl->UnlockDX12(context2);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR(ENOMEM), "LockDX12() failed with error %d\n", res);
context2->pVtbl->Release(context2);
}
break;
case AMF_MEMORY_DX9:
res = amf_device_ctx->context->pVtbl->UnlockDX9(amf_device_ctx->context);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR(ENOMEM), "LockDX9() failed with error %d\n", res);
case AMF_MEMORY_VULKAN:
{
AMFContext2 *context2 = NULL;
AMFGuid guid = IID_AMFContext2();
res = amf_device_ctx->context->pVtbl->QueryInterface(amf_device_ctx->context, &guid, (void**)&context2);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "QueryInterface for AMFContext2 failed with error %d\n", res);
res = context2->pVtbl->UnlockVulkan(context2);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR(ENOMEM), "LockVulkan() failed with error %d\n", res);
context2->pVtbl->Release(context2);
}
break;
}
return AMF_OK;
}
static AMF_RESULT amf_store_attached_frame_ref(AMFEncoderContext *ctx, const AVFrame *frame, AMFSurface *surface)
{
AMF_RESULT res = AMF_FAIL;
@@ -643,14 +560,14 @@ static int amf_submit_frame(AVCodecContext *avctx, AVFrame *frame, AMFSurface
static int amf_submit_frame_locked(AVCodecContext *avctx, AVFrame *frame, AMFSurface **surface_resubmit)
{
int ret;
int locked = amf_lock_context(avctx);
if(locked != AMF_OK)
av_log(avctx, AV_LOG_WARNING, "amf_lock_context() failed with %d - should not happen\n", locked);
AMFEncoderContext *ctx = avctx->priv_data;
AVHWDeviceContext *hw_device_ctx = (AVHWDeviceContext*)ctx->device_ctx_ref->data;
AVAMFDeviceContext *amf_device_ctx = (AVAMFDeviceContext *)hw_device_ctx->hwctx;
ff_mutex_lock(&amf_device_ctx->mutex);
ret = amf_submit_frame(avctx, frame, surface_resubmit);
ff_mutex_unlock(&amf_device_ctx->mutex);
if(locked == AMF_OK)
amf_unlock_context(avctx);
return ret;
}
static AMF_RESULT amf_query_output(AVCodecContext *avctx, AMFBuffer **buffer)

View File

@@ -137,7 +137,7 @@ enum AVPixelFormat av_amf_to_av_format(enum AMF_SURFACE_FORMAT fmt)
return format_map[i].av_format;
}
}
return AMF_SURFACE_UNKNOWN;
return AV_PIX_FMT_NONE;
}
static const enum AVPixelFormat supported_formats[] = {
@@ -378,6 +378,7 @@ static void amf_device_uninit(AVHWDeviceContext *device_ctx)
}
amf_ctx->version = 0;
ff_mutex_destroy(&amf_ctx->mutex);
}
static int amf_device_init(AVHWDeviceContext *ctx)
@@ -414,7 +415,8 @@ static int amf_device_init(AVHWDeviceContext *ctx)
}
}
#endif
return 0;
ff_mutex_init(&amf_ctx->mutex, NULL);
return 0;
}
static int amf_load_library(AVAMFDeviceContext* amf_ctx, void* avcl)

View File

@@ -26,6 +26,7 @@
#include <AMF/core/Context.h>
#include <AMF/core/Trace.h>
#include <AMF/core/Debug.h>
#include "thread.h"
/**
* This struct is allocated as AVHWDeviceContext.hwctx
@@ -38,6 +39,7 @@ typedef struct AVAMFDeviceContext {
int64_t version; ///< version of AMF runtime
AMFContext *context;
AMF_MEMORY_TYPE memory_type;
AVMutex mutex;
} AVAMFDeviceContext;
enum AMF_SURFACE_FORMAT av_av_to_amf_format(enum AVPixelFormat fmt);