diff --git a/libavutil/hwcontext_cuda.c b/libavutil/hwcontext_cuda.c index ba8ca589f7..a87c280cf7 100644 --- a/libavutil/hwcontext_cuda.c +++ b/libavutil/hwcontext_cuda.c @@ -336,17 +336,63 @@ error: return ret; } +static int cuda_context_init(AVHWDeviceContext *device_ctx, int flags) { + AVCUDADeviceContext *hwctx = device_ctx->hwctx; + CudaFunctions *cu; + CUcontext dummy; + int ret, dev_active = 0; + unsigned int dev_flags = 0; + + const unsigned int desired_flags = CU_CTX_SCHED_BLOCKING_SYNC; + + cu = hwctx->internal->cuda_dl; + + hwctx->internal->flags = flags; + + if (flags & AV_CUDA_USE_PRIMARY_CONTEXT) { + ret = CHECK_CU(cu->cuDevicePrimaryCtxGetState(hwctx->internal->cuda_device, + &dev_flags, &dev_active)); + if (ret < 0) + return ret; + + if (dev_active && dev_flags != desired_flags) { + av_log(device_ctx, AV_LOG_ERROR, "Primary context already active with incompatible flags.\n"); + return AVERROR(ENOTSUP); + } else if (dev_flags != desired_flags) { + ret = CHECK_CU(cu->cuDevicePrimaryCtxSetFlags(hwctx->internal->cuda_device, + desired_flags)); + if (ret < 0) + return ret; + } + + ret = CHECK_CU(cu->cuDevicePrimaryCtxRetain(&hwctx->cuda_ctx, + hwctx->internal->cuda_device)); + if (ret < 0) + return ret; + } else { + ret = CHECK_CU(cu->cuCtxCreate(&hwctx->cuda_ctx, desired_flags, + hwctx->internal->cuda_device)); + if (ret < 0) + return ret; + + CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + } + + hwctx->internal->is_allocated = 1; + + // Setting stream to NULL will make functions automatically use the default CUstream + hwctx->stream = NULL; + + return 0; +} + static int cuda_device_create(AVHWDeviceContext *device_ctx, const char *device, AVDictionary *opts, int flags) { AVCUDADeviceContext *hwctx = device_ctx->hwctx; CudaFunctions *cu; - CUcontext dummy; - int ret, dev_active = 0, device_idx = 0; - unsigned int dev_flags = 0; - - const unsigned int desired_flags = CU_CTX_SCHED_BLOCKING_SYNC; + int ret, device_idx = 0; if (device) device_idx = strtol(device, NULL, 0); @@ -364,37 +410,9 @@ static int cuda_device_create(AVHWDeviceContext *device_ctx, if (ret < 0) goto error; - hwctx->internal->flags = flags; - - if (flags & AV_CUDA_USE_PRIMARY_CONTEXT) { - ret = CHECK_CU(cu->cuDevicePrimaryCtxGetState(hwctx->internal->cuda_device, &dev_flags, &dev_active)); - if (ret < 0) - goto error; - - if (dev_active && dev_flags != desired_flags) { - av_log(device_ctx, AV_LOG_ERROR, "Primary context already active with incompatible flags.\n"); - goto error; - } else if (dev_flags != desired_flags) { - ret = CHECK_CU(cu->cuDevicePrimaryCtxSetFlags(hwctx->internal->cuda_device, desired_flags)); - if (ret < 0) - goto error; - } - - ret = CHECK_CU(cu->cuDevicePrimaryCtxRetain(&hwctx->cuda_ctx, hwctx->internal->cuda_device)); - if (ret < 0) - goto error; - } else { - ret = CHECK_CU(cu->cuCtxCreate(&hwctx->cuda_ctx, desired_flags, hwctx->internal->cuda_device)); - if (ret < 0) - goto error; - - CHECK_CU(cu->cuCtxPopCurrent(&dummy)); - } - - hwctx->internal->is_allocated = 1; - - // Setting stream to NULL will make functions automatically use the default CUstream - hwctx->stream = NULL; + ret = cuda_context_init(device_ctx, flags); + if (ret < 0) + goto error; return 0; @@ -409,11 +427,7 @@ static int cuda_device_derive(AVHWDeviceContext *device_ctx, AVCUDADeviceContext *hwctx = device_ctx->hwctx; CudaFunctions *cu; const char *src_uuid = NULL; - CUcontext dummy; - int ret, i, device_count, dev_active = 0; - unsigned int dev_flags = 0; - - const unsigned int desired_flags = CU_CTX_SCHED_BLOCKING_SYNC; + int ret, i, device_count; #if CONFIG_VULKAN VkPhysicalDeviceIDProperties vk_idp = { @@ -481,37 +495,9 @@ static int cuda_device_derive(AVHWDeviceContext *device_ctx, goto error; } - hwctx->internal->flags = flags; - - if (flags & AV_CUDA_USE_PRIMARY_CONTEXT) { - ret = CHECK_CU(cu->cuDevicePrimaryCtxGetState(hwctx->internal->cuda_device, &dev_flags, &dev_active)); - if (ret < 0) - goto error; - - if (dev_active && dev_flags != desired_flags) { - av_log(device_ctx, AV_LOG_ERROR, "Primary context already active with incompatible flags.\n"); - goto error; - } else if (dev_flags != desired_flags) { - ret = CHECK_CU(cu->cuDevicePrimaryCtxSetFlags(hwctx->internal->cuda_device, desired_flags)); - if (ret < 0) - goto error; - } - - ret = CHECK_CU(cu->cuDevicePrimaryCtxRetain(&hwctx->cuda_ctx, hwctx->internal->cuda_device)); - if (ret < 0) - goto error; - } else { - ret = CHECK_CU(cu->cuCtxCreate(&hwctx->cuda_ctx, desired_flags, hwctx->internal->cuda_device)); - if (ret < 0) - goto error; - - CHECK_CU(cu->cuCtxPopCurrent(&dummy)); - } - - hwctx->internal->is_allocated = 1; - - // Setting stream to NULL will make functions automatically use the default CUstream - hwctx->stream = NULL; + ret = cuda_context_init(device_ctx, flags); + if (ret < 0) + goto error; return 0;