Browse Source

avutil/hwcontext_cuda: allow using primary CUDA device context

Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org>
tags/n4.3
Oleg Dobkin Timo Rothenpieler 5 years ago
parent
commit
32ba563cfc
5 changed files with 63 additions and 15 deletions
  1. +4
    -4
      configure
  2. +39
    -10
      libavutil/hwcontext_cuda.c
  3. +17
    -0
      libavutil/hwcontext_cuda.h
  4. +2
    -0
      libavutil/hwcontext_cuda_internal.h
  5. +1
    -1
      libavutil/version.h

+ 4
- 4
configure View File

@@ -6139,10 +6139,10 @@ fi


if ! disabled ffnvcodec; then if ! disabled ffnvcodec; then
ffnv_hdr_list="ffnvcodec/nvEncodeAPI.h ffnvcodec/dynlink_cuda.h ffnvcodec/dynlink_cuviddec.h ffnvcodec/dynlink_nvcuvid.h" ffnv_hdr_list="ffnvcodec/nvEncodeAPI.h ffnvcodec/dynlink_cuda.h ffnvcodec/dynlink_cuviddec.h ffnvcodec/dynlink_nvcuvid.h"
check_pkg_config ffnvcodec "ffnvcodec >= 9.0.18.0" "$ffnv_hdr_list" "" || \
check_pkg_config ffnvcodec "ffnvcodec >= 8.2.15.8 ffnvcodec < 8.3" "$ffnv_hdr_list" "" || \
check_pkg_config ffnvcodec "ffnvcodec >= 8.1.24.9 ffnvcodec < 8.2" "$ffnv_hdr_list" "" || \
check_pkg_config ffnvcodec "ffnvcodec >= 8.0.14.9 ffnvcodec < 8.1" "$ffnv_hdr_list" ""
check_pkg_config ffnvcodec "ffnvcodec >= 9.1.23.1" "$ffnv_hdr_list" "" || \
check_pkg_config ffnvcodec "ffnvcodec >= 9.0.18.3 ffnvcodec < 9.1" "$ffnv_hdr_list" "" || \
check_pkg_config ffnvcodec "ffnvcodec >= 8.2.15.10 ffnvcodec < 8.3" "$ffnv_hdr_list" "" || \
check_pkg_config ffnvcodec "ffnvcodec >= 8.1.24.11 ffnvcodec < 8.2" "$ffnv_hdr_list" ""
fi fi


check_cpp_condition winrt windows.h "!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)" check_cpp_condition winrt windows.h "!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)"


+ 39
- 10
libavutil/hwcontext_cuda.c View File

@@ -280,10 +280,16 @@ static void cuda_device_uninit(AVHWDeviceContext *device_ctx)


if (hwctx->internal) { if (hwctx->internal) {
CudaFunctions *cu = hwctx->internal->cuda_dl; CudaFunctions *cu = hwctx->internal->cuda_dl;

if (hwctx->internal->is_allocated && hwctx->cuda_ctx) { if (hwctx->internal->is_allocated && hwctx->cuda_ctx) {
CHECK_CU(cu->cuCtxDestroy(hwctx->cuda_ctx));
if (hwctx->internal->flags & AV_CUDA_USE_PRIMARY_CONTEXT)
CHECK_CU(cu->cuDevicePrimaryCtxRelease(hwctx->internal->cuda_device));
else
CHECK_CU(cu->cuCtxDestroy(hwctx->cuda_ctx));

hwctx->cuda_ctx = NULL; hwctx->cuda_ctx = NULL;
} }

cuda_free_functions(&hwctx->internal->cuda_dl); cuda_free_functions(&hwctx->internal->cuda_dl);
} }


@@ -322,9 +328,11 @@ static int cuda_device_create(AVHWDeviceContext *device_ctx,
{ {
AVCUDADeviceContext *hwctx = device_ctx->hwctx; AVCUDADeviceContext *hwctx = device_ctx->hwctx;
CudaFunctions *cu; CudaFunctions *cu;
CUdevice cu_device;
CUcontext dummy; CUcontext dummy;
int ret, device_idx = 0;
int ret, dev_active = 0, device_idx = 0;
unsigned int dev_flags = 0;

const unsigned int desired_flags = CU_CTX_SCHED_BLOCKING_SYNC;


if (device) if (device)
device_idx = strtol(device, NULL, 0); device_idx = strtol(device, NULL, 0);
@@ -338,21 +346,42 @@ static int cuda_device_create(AVHWDeviceContext *device_ctx,
if (ret < 0) if (ret < 0)
goto error; goto error;


ret = CHECK_CU(cu->cuDeviceGet(&cu_device, device_idx));
ret = CHECK_CU(cu->cuDeviceGet(&hwctx->internal->cuda_device, device_idx));
if (ret < 0) if (ret < 0)
goto error; goto error;


ret = CHECK_CU(cu->cuCtxCreate(&hwctx->cuda_ctx, CU_CTX_SCHED_BLOCKING_SYNC, cu_device));
if (ret < 0)
goto error;
hwctx->internal->flags = flags;


// Setting stream to NULL will make functions automatically use the default CUstream
hwctx->stream = NULL;
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;


CHECK_CU(cu->cuCtxPopCurrent(&dummy));
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; hwctx->internal->is_allocated = 1;


// Setting stream to NULL will make functions automatically use the default CUstream
hwctx->stream = NULL;

return 0; return 0;


error: error:


+ 17
- 0
libavutil/hwcontext_cuda.h View File

@@ -49,4 +49,21 @@ typedef struct AVCUDADeviceContext {
* AVHWFramesContext.hwctx is currently not used * AVHWFramesContext.hwctx is currently not used
*/ */


/**
* @defgroup hwcontext_cuda Device context creation flags
*
* Flags for av_hwdevice_ctx_create.
*
* @{
*/

/**
* Use primary device context instead of creating a new one.
*/
#define AV_CUDA_USE_PRIMARY_CONTEXT (1 << 0)

/**
* @}
*/

#endif /* AVUTIL_HWCONTEXT_CUDA_H */ #endif /* AVUTIL_HWCONTEXT_CUDA_H */

+ 2
- 0
libavutil/hwcontext_cuda_internal.h View File

@@ -31,6 +31,8 @@
struct AVCUDADeviceContextInternal { struct AVCUDADeviceContextInternal {
CudaFunctions *cuda_dl; CudaFunctions *cuda_dl;
int is_allocated; int is_allocated;
CUdevice cuda_device;
int flags;
}; };


#endif /* AVUTIL_HWCONTEXT_CUDA_INTERNAL_H */ #endif /* AVUTIL_HWCONTEXT_CUDA_INTERNAL_H */


+ 1
- 1
libavutil/version.h View File

@@ -80,7 +80,7 @@


#define LIBAVUTIL_VERSION_MAJOR 56 #define LIBAVUTIL_VERSION_MAJOR 56
#define LIBAVUTIL_VERSION_MINOR 36 #define LIBAVUTIL_VERSION_MINOR 36
#define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_MICRO 101


#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
LIBAVUTIL_VERSION_MINOR, \ LIBAVUTIL_VERSION_MINOR, \


Loading…
Cancel
Save