+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,