Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@overt.org>2018-11-11 09:47:28 +0300
committerPhilip Langdale <philipl@overt.org>2018-11-15 04:39:42 +0300
commit19d3d0c0570981ddc8a224f07d734ff75d76e234 (patch)
tree01f718e1878010605cd28d5947b676d42519dfc9 /libavutil
parentf0f2832a5ce93bad9b1d29f99df6bda2380fc41c (diff)
avutil/hwcontext_cuda: Define and use common CHECK_CU()
We have a pattern of wrapping CUDA calls to print errors and normalise return values that is used in a couple of places. To avoid duplication and increase consistency, let's put the wrapper implementation in a shared place and use it everywhere. Affects: * avcodec/cuviddec * avcodec/nvdec * avcodec/nvenc * avfilter/vf_scale_cuda * avfilter/vf_scale_npp * avfilter/vf_thumbnail_cuda * avfilter/vf_transpose_npp * avfilter/vf_yadif_cuda
Diffstat (limited to 'libavutil')
-rw-r--r--libavutil/Makefile5
-rw-r--r--libavutil/cuda_check.c45
-rw-r--r--libavutil/cuda_check.h43
-rw-r--r--libavutil/hwcontext_cuda.c148
4 files changed, 161 insertions, 80 deletions
diff --git a/libavutil/Makefile b/libavutil/Makefile
index 9ed24cfc82..b772111695 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -157,7 +157,7 @@ OBJS = adler32.o \
xtea.o \
tea.o \
-OBJS-$(CONFIG_CUDA) += hwcontext_cuda.o
+OBJS-$(CONFIG_CUDA) += hwcontext_cuda.o cuda_check.o
OBJS-$(CONFIG_D3D11VA) += hwcontext_d3d11va.o
OBJS-$(CONFIG_DXVA2) += hwcontext_dxva2.o
OBJS-$(CONFIG_LIBDRM) += hwcontext_drm.o
@@ -175,7 +175,8 @@ OBJS += $(COMPAT_OBJS:%=../compat/%)
SLIBOBJS-$(HAVE_GNU_WINDRES) += avutilres.o
SKIPHEADERS-$(HAVE_CUDA_H) += hwcontext_cuda.h
-SKIPHEADERS-$(CONFIG_CUDA) += hwcontext_cuda_internal.h
+SKIPHEADERS-$(CONFIG_CUDA) += hwcontext_cuda_internal.h \
+ cuda_check.h
SKIPHEADERS-$(CONFIG_D3D11VA) += hwcontext_d3d11va.h
SKIPHEADERS-$(CONFIG_DXVA2) += hwcontext_dxva2.h
SKIPHEADERS-$(CONFIG_QSV) += hwcontext_qsv.h
diff --git a/libavutil/cuda_check.c b/libavutil/cuda_check.c
new file mode 100644
index 0000000000..95c0256d12
--- /dev/null
+++ b/libavutil/cuda_check.c
@@ -0,0 +1,45 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "compat/cuda/dynlink_loader.h"
+#include "libavutil/cuda_check.h"
+
+int ff_cuda_check(void *avctx,
+ void *cuGetErrorName_fn,
+ void *cuGetErrorString_fn,
+ CUresult err, const char *func)
+{
+ const char *err_name;
+ const char *err_string;
+
+ av_log(avctx, AV_LOG_TRACE, "Calling %s\n", func);
+
+ if (err == CUDA_SUCCESS)
+ return 0;
+
+ ((tcuGetErrorName *)cuGetErrorName_fn)(err, &err_name);
+ ((tcuGetErrorString *)cuGetErrorString_fn)(err, &err_string);
+
+ av_log(avctx, AV_LOG_ERROR, "%s failed", func);
+ if (err_name && err_string)
+ av_log(avctx, AV_LOG_ERROR, " -> %s: %s", err_name, err_string);
+ av_log(avctx, AV_LOG_ERROR, "\n");
+
+ return AVERROR_EXTERNAL;
+}
+
diff --git a/libavutil/cuda_check.h b/libavutil/cuda_check.h
new file mode 100644
index 0000000000..0d45538c2f
--- /dev/null
+++ b/libavutil/cuda_check.h
@@ -0,0 +1,43 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#ifndef FF_CUDA_CHECK_H
+#define FF_CUDA_CHECK_H
+
+/**
+ * Wrap a CUDA function call and print error information if it fails.
+ */
+
+int ff_cuda_check(void *avctx,
+ void *cuGetErrorName_fn, void *cuGetErrorString_fn,
+ CUresult err, const char *func);
+
+/**
+ * Convenience wrapper for ff_cuda_check when directly linking libcuda.
+ */
+
+#define FF_CUDA_CHECK(avclass, x) ff_cuda_check(avclass, cuGetErrorName, cuGetErrorString, (x), #x)
+
+/**
+ * Convenience wrapper for ff_cuda_check when dynamically loading cuda symbols.
+ */
+
+#define FF_CUDA_CHECK_DL(avclass, cudl, x) ff_cuda_check(avclass, cudl->cuGetErrorName, cudl->cuGetErrorString, (x), #x)
+
+#endif /* FF_CUDA_CHECK_H */
diff --git a/libavutil/hwcontext_cuda.c b/libavutil/hwcontext_cuda.c
index 3b1d53e799..540a7610ef 100644
--- a/libavutil/hwcontext_cuda.c
+++ b/libavutil/hwcontext_cuda.c
@@ -21,6 +21,7 @@
#include "hwcontext.h"
#include "hwcontext_internal.h"
#include "hwcontext_cuda_internal.h"
+#include "cuda_check.h"
#include "mem.h"
#include "pixdesc.h"
#include "pixfmt.h"
@@ -43,6 +44,8 @@ static const enum AVPixelFormat supported_formats[] = {
AV_PIX_FMT_0BGR32,
};
+#define CHECK_CU(x) FF_CUDA_CHECK_DL(device_ctx, cu, x)
+
static int cuda_frames_get_constraints(AVHWDeviceContext *ctx,
const void *hwconfig,
AVHWFramesConstraints *constraints)
@@ -70,48 +73,48 @@ static int cuda_frames_get_constraints(AVHWDeviceContext *ctx,
static void cuda_buffer_free(void *opaque, uint8_t *data)
{
- AVHWFramesContext *ctx = opaque;
- AVCUDADeviceContext *hwctx = ctx->device_ctx->hwctx;
- CudaFunctions *cu = hwctx->internal->cuda_dl;
+ AVHWFramesContext *ctx = opaque;
+ AVHWDeviceContext *device_ctx = ctx->device_ctx;
+ AVCUDADeviceContext *hwctx = device_ctx->hwctx;
+ CudaFunctions *cu = hwctx->internal->cuda_dl;
CUcontext dummy;
- cu->cuCtxPushCurrent(hwctx->cuda_ctx);
+ CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx));
- cu->cuMemFree((CUdeviceptr)data);
+ CHECK_CU(cu->cuMemFree((CUdeviceptr)data));
- cu->cuCtxPopCurrent(&dummy);
+ CHECK_CU(cu->cuCtxPopCurrent(&dummy));
}
static AVBufferRef *cuda_pool_alloc(void *opaque, int size)
{
- AVHWFramesContext *ctx = opaque;
- AVCUDADeviceContext *hwctx = ctx->device_ctx->hwctx;
- CudaFunctions *cu = hwctx->internal->cuda_dl;
+ AVHWFramesContext *ctx = opaque;
+ AVHWDeviceContext *device_ctx = ctx->device_ctx;
+ AVCUDADeviceContext *hwctx = device_ctx->hwctx;
+ CudaFunctions *cu = hwctx->internal->cuda_dl;
AVBufferRef *ret = NULL;
CUcontext dummy = NULL;
CUdeviceptr data;
- CUresult err;
+ int err;
- err = cu->cuCtxPushCurrent(hwctx->cuda_ctx);
- if (err != CUDA_SUCCESS) {
- av_log(ctx, AV_LOG_ERROR, "Error setting current CUDA context\n");
+ err = CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx));
+ if (err < 0)
return NULL;
- }
- err = cu->cuMemAlloc(&data, size);
- if (err != CUDA_SUCCESS)
+ err = CHECK_CU(cu->cuMemAlloc(&data, size));
+ if (err < 0)
goto fail;
ret = av_buffer_create((uint8_t*)data, size, cuda_buffer_free, ctx, 0);
if (!ret) {
- cu->cuMemFree(data);
+ CHECK_CU(cu->cuMemFree(data));
goto fail;
}
fail:
- cu->cuCtxPopCurrent(&dummy);
+ CHECK_CU(cu->cuCtxPopCurrent(&dummy));
return ret;
}
@@ -194,17 +197,17 @@ static int cuda_transfer_get_formats(AVHWFramesContext *ctx,
static int cuda_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst,
const AVFrame *src)
{
- CUDAFramesContext *priv = ctx->internal->priv;
- AVCUDADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
- CudaFunctions *cu = device_hwctx->internal->cuda_dl;
+ CUDAFramesContext *priv = ctx->internal->priv;
+ AVHWDeviceContext *device_ctx = ctx->device_ctx;
+ AVCUDADeviceContext *hwctx = device_ctx->hwctx;
+ CudaFunctions *cu = hwctx->internal->cuda_dl;
CUcontext dummy;
- CUresult err;
- int i;
+ int i, ret;
- err = cu->cuCtxPushCurrent(device_hwctx->cuda_ctx);
- if (err != CUDA_SUCCESS)
- return AVERROR_UNKNOWN;
+ ret = CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx));
+ if (ret < 0)
+ return ret;
for (i = 0; i < FF_ARRAY_ELEMS(src->data) && src->data[i]; i++) {
CUDA_MEMCPY2D cpy = {
@@ -218,20 +221,17 @@ static int cuda_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst,
.Height = src->height >> (i ? priv->shift_height : 0),
};
- err = cu->cuMemcpy2DAsync(&cpy, device_hwctx->stream);
- if (err != CUDA_SUCCESS) {
- av_log(ctx, AV_LOG_ERROR, "Error transferring the data from the CUDA frame\n");
- return AVERROR_UNKNOWN;
- }
+ ret = CHECK_CU(cu->cuMemcpy2DAsync(&cpy, hwctx->stream));
+ if (ret < 0)
+ goto exit;
}
- err = cu->cuStreamSynchronize(device_hwctx->stream);
- if (err != CUDA_SUCCESS) {
- av_log(ctx, AV_LOG_ERROR, "Error synchronizing CUDA stream\n");
- return AVERROR_UNKNOWN;
- }
+ ret = CHECK_CU(cu->cuStreamSynchronize(hwctx->stream));
+ if (ret < 0)
+ goto exit;
- cu->cuCtxPopCurrent(&dummy);
+exit:
+ CHECK_CU(cu->cuCtxPopCurrent(&dummy));
return 0;
}
@@ -239,17 +239,17 @@ static int cuda_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst,
static int cuda_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst,
const AVFrame *src)
{
- CUDAFramesContext *priv = ctx->internal->priv;
- AVCUDADeviceContext *device_hwctx = ctx->device_ctx->hwctx;
- CudaFunctions *cu = device_hwctx->internal->cuda_dl;
+ CUDAFramesContext *priv = ctx->internal->priv;
+ AVHWDeviceContext *device_ctx = ctx->device_ctx;
+ AVCUDADeviceContext *hwctx = device_ctx->hwctx;
+ CudaFunctions *cu = hwctx->internal->cuda_dl;
CUcontext dummy;
- CUresult err;
- int i;
+ int i, ret;
- err = cu->cuCtxPushCurrent(device_hwctx->cuda_ctx);
- if (err != CUDA_SUCCESS)
- return AVERROR_UNKNOWN;
+ ret = CHECK_CU(cu->cuCtxPushCurrent(hwctx->cuda_ctx));
+ if (ret < 0)
+ return ret;
for (i = 0; i < FF_ARRAY_ELEMS(src->data) && src->data[i]; i++) {
CUDA_MEMCPY2D cpy = {
@@ -263,31 +263,29 @@ static int cuda_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst,
.Height = src->height >> (i ? priv->shift_height : 0),
};
- err = cu->cuMemcpy2DAsync(&cpy, device_hwctx->stream);
- if (err != CUDA_SUCCESS) {
- av_log(ctx, AV_LOG_ERROR, "Error transferring the data to the CUDA frame\n");
- return AVERROR_UNKNOWN;
- }
+ ret = CHECK_CU(cu->cuMemcpy2DAsync(&cpy, hwctx->stream));
+ if (ret < 0)
+ goto exit;
}
- err = cu->cuStreamSynchronize(device_hwctx->stream);
- if (err != CUDA_SUCCESS) {
- av_log(ctx, AV_LOG_ERROR, "Error synchronizing CUDA stream\n");
- return AVERROR_UNKNOWN;
- }
+ ret = CHECK_CU(cu->cuStreamSynchronize(hwctx->stream));
+ if (ret < 0)
+ goto exit;
- cu->cuCtxPopCurrent(&dummy);
+exit:
+ CHECK_CU(cu->cuCtxPopCurrent(&dummy));
return 0;
}
-static void cuda_device_uninit(AVHWDeviceContext *ctx)
+static void cuda_device_uninit(AVHWDeviceContext *device_ctx)
{
- AVCUDADeviceContext *hwctx = ctx->hwctx;
+ AVCUDADeviceContext *hwctx = device_ctx->hwctx;
if (hwctx->internal) {
+ CudaFunctions *cu = hwctx->internal->cuda_dl;
if (hwctx->internal->is_allocated && hwctx->cuda_ctx) {
- hwctx->internal->cuda_dl->cuCtxDestroy(hwctx->cuda_ctx);
+ CHECK_CU(cu->cuCtxDestroy(hwctx->cuda_ctx));
hwctx->cuda_ctx = NULL;
}
cuda_free_functions(&hwctx->internal->cuda_dl);
@@ -322,53 +320,47 @@ error:
return ret;
}
-static int cuda_device_create(AVHWDeviceContext *ctx, const char *device,
+static int cuda_device_create(AVHWDeviceContext *device_ctx,
+ const char *device,
AVDictionary *opts, int flags)
{
- AVCUDADeviceContext *hwctx = ctx->hwctx;
+ AVCUDADeviceContext *hwctx = device_ctx->hwctx;
CudaFunctions *cu;
CUdevice cu_device;
CUcontext dummy;
- CUresult err;
- int device_idx = 0;
+ int ret, device_idx = 0;
if (device)
device_idx = strtol(device, NULL, 0);
- if (cuda_device_init(ctx) < 0)
+ if (cuda_device_init(device_ctx) < 0)
goto error;
cu = hwctx->internal->cuda_dl;
- err = cu->cuInit(0);
- if (err != CUDA_SUCCESS) {
- av_log(ctx, AV_LOG_ERROR, "Could not initialize the CUDA driver API\n");
+ ret = CHECK_CU(cu->cuInit(0));
+ if (ret < 0)
goto error;
- }
- err = cu->cuDeviceGet(&cu_device, device_idx);
- if (err != CUDA_SUCCESS) {
- av_log(ctx, AV_LOG_ERROR, "Could not get the device number %d\n", device_idx);
+ ret = CHECK_CU(cu->cuDeviceGet(&cu_device, device_idx));
+ if (ret < 0)
goto error;
- }
- err = cu->cuCtxCreate(&hwctx->cuda_ctx, CU_CTX_SCHED_BLOCKING_SYNC, cu_device);
- if (err != CUDA_SUCCESS) {
- av_log(ctx, AV_LOG_ERROR, "Error creating a CUDA context\n");
+ ret = CHECK_CU(cu->cuCtxCreate(&hwctx->cuda_ctx, CU_CTX_SCHED_BLOCKING_SYNC, cu_device));
+ if (ret < 0)
goto error;
- }
// Setting stream to NULL will make functions automatically use the default CUstream
hwctx->stream = NULL;
- cu->cuCtxPopCurrent(&dummy);
+ CHECK_CU(cu->cuCtxPopCurrent(&dummy));
hwctx->internal->is_allocated = 1;
return 0;
error:
- cuda_device_uninit(ctx);
+ cuda_device_uninit(device_ctx);
return AVERROR_UNKNOWN;
}