You've already forked FFmpeg
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:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user