#endif
#include "gstnvbaseenc.h"
+#include "gstcudautils.h"
#include <gst/pbutils/codec-utils.h>
GstNvBaseEncClass *klass = GST_NV_BASE_ENC_GET_CLASS (enc);
GValue *formats = NULL;
- nvenc->cuda_ctx = gst_nvenc_create_cuda_context (klass->cuda_device_id);
- if (nvenc->cuda_ctx == NULL) {
- GST_ELEMENT_ERROR (enc, LIBRARY, INIT, (NULL),
- ("Failed to create CUDA context, perhaps CUDA is not supported."));
+ if (!gst_cuda_ensure_element_context (GST_ELEMENT_CAST (enc),
+ klass->cuda_device_id, &nvenc->cuda_ctx)) {
+ GST_ERROR_OBJECT (nvenc, "failed to create CUDA context");
return FALSE;
}
params.version = NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER;
params.apiVersion = NVENCAPI_VERSION;
- params.device = nvenc->cuda_ctx;
+ params.device = gst_cuda_context_get_handle (nvenc->cuda_ctx);
params.deviceType = NV_ENC_DEVICE_TYPE_CUDA;
nv_ret = NvEncOpenEncodeSessionEx (¶ms, &nvenc->encoder);
if (nv_ret != NV_ENC_SUCCESS) {
GST_ERROR ("Failed to create NVENC encoder session, ret=%d", nv_ret);
- if (gst_nvenc_destroy_cuda_context (nvenc->cuda_ctx))
- nvenc->cuda_ctx = NULL;
+ gst_clear_object (&nvenc->cuda_ctx);
return FALSE;
}
GST_INFO ("created NVENC encoder %p", nvenc->encoder);
static void
gst_nv_base_enc_set_context (GstElement * element, GstContext * context)
{
-#if HAVE_NVCODEC_GST_GL
GstNvBaseEnc *nvenc = GST_NV_BASE_ENC (element);
+ GstNvBaseEncClass *klass = GST_NV_BASE_ENC_GET_CLASS (nvenc);
+ if (gst_cuda_handle_set_context (element, context, klass->cuda_device_id,
+ &nvenc->cuda_ctx)) {
+ goto done;
+ }
+#if HAVE_NVCODEC_GST_GL
gst_gl_handle_set_context (element, context,
(GstGLDisplay **) & nvenc->display,
(GstGLContext **) & nvenc->other_context);
SUPPORTED_GL_APIS);
#endif
+done:
GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
}
static gboolean
gst_nv_base_enc_sink_query (GstVideoEncoder * enc, GstQuery * query)
{
-#if HAVE_NVCODEC_GST_GL
GstNvBaseEnc *nvenc = GST_NV_BASE_ENC (enc);
-#endif
switch (GST_QUERY_TYPE (query)) {
-#if HAVE_NVCODEC_GST_GL
case GST_QUERY_CONTEXT:{
- gboolean ret;
+ if (gst_cuda_handle_context_query (GST_ELEMENT (nvenc),
+ query, nvenc->cuda_ctx))
+ return TRUE;
- ret = gst_gl_handle_context_query ((GstElement *) nvenc, query,
- nvenc->display, NULL, nvenc->other_context);
- if (nvenc->display)
- gst_gl_display_filter_gl_api (GST_GL_DISPLAY (nvenc->display),
- SUPPORTED_GL_APIS);
+#if HAVE_NVCODEC_GST_GL
+ {
+ gboolean ret;
+
+ ret = gst_gl_handle_context_query ((GstElement *) nvenc, query,
+ nvenc->display, NULL, nvenc->other_context);
+ if (nvenc->display) {
+ gst_gl_display_filter_gl_api (GST_GL_DISPLAY (nvenc->display),
+ SUPPORTED_GL_APIS);
+ }
- if (ret)
- return ret;
+ if (ret)
+ return ret;
+ }
+#endif
break;
}
-#endif
default:
break;
}
nvenc->encoder = NULL;
}
- if (nvenc->cuda_ctx) {
- if (!gst_nvenc_destroy_cuda_context (nvenc->cuda_ctx))
- return FALSE;
- nvenc->cuda_ctx = NULL;
- }
+ gst_clear_object (&nvenc->cuda_ctx);
GST_OBJECT_LOCK (nvenc);
if (nvenc->input_formats)
if (nvenc->gl_input) {
struct gl_input_resource *in_gl_resource = nvenc->input_bufs[i];
- CuCtxPushCurrent (nvenc->cuda_ctx);
+ gst_cuda_context_push (nvenc->cuda_ctx);
if (in_gl_resource->mapped) {
GST_LOG_OBJECT (nvenc, "Unmap resource %p", in_gl_resource);
}
g_free (in_gl_resource);
- CuCtxPopCurrent (NULL);
+ gst_cuda_context_pop (NULL);
} else
#endif
{
pixel_depth += GST_VIDEO_INFO_COMP_DEPTH (info, i);
}
- CuCtxPushCurrent (nvenc->cuda_ctx);
+ gst_cuda_context_push (nvenc->cuda_ctx);
for (i = 0; i < nvenc->n_bufs; ++i) {
struct gl_input_resource *in_gl_resource =
g_new0 (struct gl_input_resource, 1);
g_async_queue_push (nvenc->in_bufs_pool, nvenc->input_bufs[i]);
}
- CuCtxPopCurrent (NULL);
+ gst_cuda_context_pop (NULL);
} else
#endif
{
guint i;
CUDA_MEMCPY2D param;
- CuCtxPushCurrent (data->nvenc->cuda_ctx);
+ gst_cuda_context_push (data->nvenc->cuda_ctx);
data_pointer = data->in_gl_resource->cuda_pointer;
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (data->info); i++) {
GstGLBuffer *gl_buf_obj;
data_pointer = data_pointer +
dest_stride * _get_plane_height (&data->nvenc->input_info, i);
}
- CuCtxPopCurrent (NULL);
+ gst_cuda_context_pop (NULL);
}
#endif
return NV_ENC_BUFFER_FORMAT_UNDEFINED;
}
-CUcontext
-gst_nvenc_create_cuda_context (guint device_id)
-{
- CUcontext cuda_ctx, old_ctx;
- CUresult cres = CUDA_SUCCESS;
- CUdevice cdev = 0, cuda_dev = -1;
- int dev_count = 0;
- char name[256];
- int min = 0, maj = 0;
- int i;
-
- GST_INFO ("Initialising CUDA..");
-
- cres = CuInit (0);
-
- if (cres != CUDA_SUCCESS) {
- GST_WARNING ("Failed to initialise CUDA, error code: 0x%08x", cres);
- return NULL;
- }
-
- GST_INFO ("Initialised CUDA");
-
- cres = CuDeviceGetCount (&dev_count);
- if (cres != CUDA_SUCCESS || dev_count == 0) {
- GST_WARNING ("No CUDA devices detected");
- return NULL;
- }
-
- GST_INFO ("%d CUDA device(s) detected", dev_count);
- for (i = 0; i < dev_count; ++i) {
- if (CuDeviceGet (&cdev, i) == CUDA_SUCCESS
- && CuDeviceGetName (name, sizeof (name), cdev) == CUDA_SUCCESS
- && CuDeviceGetAttribute (&maj,
- CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, cdev) == CUDA_SUCCESS
- && CuDeviceGetAttribute (&min,
- CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR,
- cdev) == CUDA_SUCCESS) {
- GST_INFO ("GPU #%d supports NVENC: %s (%s) (Compute SM %d.%d)", i,
- (((maj << 4) + min) >= 0x30) ? "yes" : "no", name, maj, min);
- if (i == device_id) {
- cuda_dev = cdev;
- }
- }
- }
-
- if (cuda_dev == -1) {
- GST_WARNING ("Device with id %d does not exist or does not support NVENC",
- device_id);
- return NULL;
- }
-
- if (CuCtxCreate (&cuda_ctx, 0, cuda_dev) != CUDA_SUCCESS) {
- GST_WARNING ("Failed to create CUDA context for cuda device %d", cuda_dev);
- return NULL;
- }
-
- if (CuCtxPopCurrent (&old_ctx) != CUDA_SUCCESS) {
- return NULL;
- }
-
- GST_INFO ("Created CUDA context %p", cuda_ctx);
-
- return cuda_ctx;
-}
-
-gboolean
-gst_nvenc_destroy_cuda_context (CUcontext ctx)
-{
- GST_INFO ("Destroying CUDA context %p", ctx);
- return (CuCtxDestroy (ctx) == CUDA_SUCCESS);
-}
-
static gboolean
load_nvenc_library (void)
{