From c8a1c953d8c6766f213469d148b4792162b813da Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Thu, 3 Mar 2022 02:48:17 +0900 Subject: [PATCH] cudacontext: Require explicit gpu id instead of auto (-1) Sync up with GstD3D11Device implementation. The auto stuff should be handled in context sharing step, not device creation. Part-of: --- .../gst-plugins-bad/sys/nvcodec/gstcudacontext.c | 74 +++++++++------------- .../gst-plugins-bad/sys/nvcodec/gstcudacontext.h | 2 +- .../gst-plugins-bad/sys/nvcodec/gstcudautils.c | 11 +++- 3 files changed, 40 insertions(+), 47 deletions(-) diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstcudacontext.c b/subprojects/gst-plugins-bad/sys/nvcodec/gstcudacontext.c index dfa5155..063d715 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstcudacontext.c +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstcudacontext.c @@ -38,13 +38,11 @@ enum PROP_DEVICE_ID }; -#define DEFAULT_DEVICE_ID -1 - struct _GstCudaContextPrivate { CUcontext context; CUdevice device; - gint device_id; + guint device_id; gint tex_align; @@ -76,9 +74,9 @@ gst_cuda_context_class_init (GstCudaContextClass * klass) gobject_class->finalize = gst_cuda_context_finalize; g_object_class_install_property (gobject_class, PROP_DEVICE_ID, - g_param_spec_int ("cuda-device-id", "Cuda Device ID", - "Set the GPU device to use for operations (-1 = auto)", - -1, G_MAXINT, DEFAULT_DEVICE_ID, + g_param_spec_uint ("cuda-device-id", "Cuda Device ID", + "Set the GPU device to use for operations", + 0, G_MAXUINT, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); GST_DEBUG_CATEGORY_INIT (gst_cuda_context_debug, @@ -90,8 +88,6 @@ gst_cuda_context_init (GstCudaContext * context) { GstCudaContextPrivate *priv = gst_cuda_context_get_instance_private (context); - priv->context = NULL; - priv->device_id = DEFAULT_DEVICE_ID; priv->accessible_peer = g_hash_table_new (g_direct_hash, g_direct_equal); context->priv = priv; @@ -106,7 +102,7 @@ gst_cuda_context_set_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_DEVICE_ID: - priv->device_id = g_value_get_int (value); + priv->device_id = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -123,7 +119,7 @@ gst_cuda_context_get_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_DEVICE_ID: - g_value_set_int (value, priv->device_id); + g_value_set_uint (value, priv->device_id); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -137,11 +133,8 @@ gst_cuda_context_constructed (GObject * object) GstCudaContext *context = GST_CUDA_CONTEXT (object); GstCudaContextPrivate *priv = context->priv; CUcontext cuda_ctx, old_ctx; - CUdevice cdev = 0, cuda_dev = -1; + CUdevice cdev = 0; gint dev_count = 0; - gchar name[256]; - gint min = 0, maj = 0; - gint i; gint tex_align = 0; GList *iter; @@ -150,34 +143,30 @@ gst_cuda_context_constructed (GObject * object) return; } - for (i = 0; i < dev_count; ++i) { - if (gst_cuda_result (CuDeviceGet (&cdev, i)) && - gst_cuda_result (CuDeviceGetName (name, sizeof (name), cdev)) && - gst_cuda_result (CuDeviceGetAttribute (&maj, - CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, cdev)) && - gst_cuda_result (CuDeviceGetAttribute (&min, - CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, cdev)) && - gst_cuda_result (CuDeviceGetAttribute (&tex_align, - CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT, cdev))) { - GST_INFO ("GPU #%d supports NVENC: %s (%s) (Compute SM %d.%d)", i, - (((maj << 4) + min) >= 0x30) ? "yes" : "no", name, maj, min); - if (priv->device_id == -1 || priv->device_id == cdev) { - priv->device_id = cuda_dev = cdev; - priv->tex_align = tex_align; - break; - } - } + if (priv->device_id >= dev_count) { + GST_WARNING ("Unavailable device id %d", priv->device_id); + return; } - if (cuda_dev == -1) { - GST_WARNING ("Device with id %d does not exist", priv->device_id); + if (!gst_cuda_result (CuDeviceGet (&cdev, priv->device_id))) { + GST_WARNING ("Failed to get device for id %d", priv->device_id); return; } - GST_DEBUG ("Creating cuda context for device index %d", cuda_dev); + if (!gst_cuda_result (CuDeviceGetAttribute (&tex_align, + CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT, cdev))) { + GST_WARNING ("Failed to query texture alignment"); + return; + } + + priv->tex_align = tex_align; + + GST_DEBUG ("Creating cuda context for device index %d, Texture Alignment: %d", + priv->device_id, priv->tex_align); - if (!gst_cuda_result (CuCtxCreate (&cuda_ctx, 0, cuda_dev))) { - GST_WARNING ("Failed to create CUDA context for cuda device %d", cuda_dev); + if (!gst_cuda_result (CuCtxCreate (&cuda_ctx, 0, cdev))) { + GST_WARNING ("Failed to create CUDA context for cuda device %d", + priv->device_id); return; } @@ -185,10 +174,11 @@ gst_cuda_context_constructed (GObject * object) return; } - GST_INFO ("Created CUDA context %p with device-id %d", cuda_ctx, cuda_dev); + GST_INFO ("Created CUDA context %p with device-id %d", + cuda_ctx, priv->device_id); priv->context = cuda_ctx; - priv->device = cuda_dev; + priv->device = cdev; G_LOCK (list_lock); g_object_weak_ref (G_OBJECT (object), @@ -302,16 +292,14 @@ gst_cuda_context_finalize (GObject * object) /** * gst_cuda_context_new: - * @device_id: device-id for creating #GstCudaContext or -1 for auto selection + * @device_id: device-id for creating #GstCudaContext * - * Create #GstCudaContext with given device_id. If the @device_id was not -1 - * but was out of range (e.g., exceed the number of device), - * #GstCudaContext will not be created. + * Create #GstCudaContext with given device_id * * Returns: a new #GstCudaContext or %NULL on failure */ GstCudaContext * -gst_cuda_context_new (gint device_id) +gst_cuda_context_new (guint device_id) { GstCudaContext *self = g_object_new (GST_TYPE_CUDA_CONTEXT, "cuda-device-id", device_id, NULL); diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstcudacontext.h b/subprojects/gst-plugins-bad/sys/nvcodec/gstcudacontext.h index 08a3a86..2536296 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstcudacontext.h +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstcudacontext.h @@ -60,7 +60,7 @@ struct _GstCudaContextClass GType gst_cuda_context_get_type (void); -GstCudaContext * gst_cuda_context_new (gint device_id); +GstCudaContext * gst_cuda_context_new (guint device_id); gboolean gst_cuda_context_push (GstCudaContext * ctx); diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstcudautils.c b/subprojects/gst-plugins-bad/sys/nvcodec/gstcudautils.c index 6d33bc4..63e0357 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstcudautils.c +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstcudautils.c @@ -145,7 +145,7 @@ static void context_set_cuda_context (GstContext * context, GstCudaContext * cuda_ctx) { GstStructure *s; - gint device_id; + guint device_id; g_return_if_fail (context != NULL); @@ -180,6 +180,8 @@ gboolean gst_cuda_ensure_element_context (GstElement * element, gint device_id, GstCudaContext ** cuda_ctx) { + guint target_device_id = 0; + g_return_val_if_fail (element != NULL, FALSE); g_return_val_if_fail (cuda_ctx != NULL, FALSE); @@ -192,8 +194,11 @@ gst_cuda_ensure_element_context (GstElement * element, gint device_id, if (*cuda_ctx) return TRUE; + if (device_id > 0) + target_device_id = device_id; + /* No available CUDA context in pipeline, create new one here */ - *cuda_ctx = gst_cuda_context_new (device_id); + *cuda_ctx = gst_cuda_context_new (target_device_id); if (*cuda_ctx == NULL) { GST_CAT_ERROR_OBJECT (GST_CAT_CONTEXT, element, @@ -253,7 +258,7 @@ gst_cuda_handle_set_context (GstElement * element, if (g_strcmp0 (context_type, GST_CUDA_CONTEXT_TYPE) == 0) { const GstStructure *str; GstCudaContext *other_ctx = NULL; - gint other_device_id = 0; + guint other_device_id = 0; /* If we had context already, will not replace it */ if (*cuda_ctx) -- 2.7.4