diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvav1dec.c b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvav1dec.c index 0c6c8af732..bf717ecf98 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvav1dec.c +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvav1dec.c @@ -17,6 +17,21 @@ * Boston, MA 02110-1301, USA. */ +/** + * SECTION:element-nvav1dec + * @title: nvav1dec + * + * GstCodecs based NVIDIA AV1 video decoder + * + * ## Example launch line + * ``` + * gst-launch-1.0 filesrc location=/path/to/av1/file ! parsebin ! nvav1dec ! videoconvert ! autovideosink + * ``` + * + * Since: 1.22 + * + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -66,12 +81,11 @@ typedef struct _GstNvAV1DecClass guint cuda_device_id; } GstNvAV1DecClass; -typedef struct +enum { - GstCaps *sink_caps; - GstCaps *src_caps; - guint cuda_device_id; -} GstNvAV1DecClassData; + PROP_0, + PROP_CUDA_DEVICE_ID, +}; static GTypeClass *parent_class = NULL; @@ -79,6 +93,9 @@ static GTypeClass *parent_class = NULL; #define GST_NV_AV1_DEC_GET_CLASS(object) \ (G_TYPE_INSTANCE_GET_CLASS ((object),G_TYPE_FROM_INSTANCE (object),GstNvAV1DecClass)) +static void gst_nv_av1_dec_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + static void gst_nv_av1_dec_set_context (GstElement * element, GstContext * context); static gboolean gst_nv_av1_dec_open (GstVideoDecoder * decoder); @@ -108,12 +125,20 @@ static guint gst_nv_av1_dec_get_preferred_output_delay (GstAV1Decoder * decoder, static void gst_nv_av1_dec_class_init (GstNvAV1DecClass * klass, - GstNvAV1DecClassData * cdata) + GstNvDecoderClassData * cdata) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass); GstAV1DecoderClass *av1decoder_class = GST_AV1_DECODER_CLASS (klass); + object_class->get_property = gst_nv_av1_dec_get_property; + + g_object_class_install_property (object_class, PROP_CUDA_DEVICE_ID, + g_param_spec_uint ("cuda-device-id", "CUDA device id", + "Assigned CUDA device id", 0, G_MAXINT, 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_av1_dec_set_context); parent_class = (GTypeClass *) g_type_class_peek_parent (klass); @@ -164,6 +189,22 @@ gst_nv_av1_dec_init (GstNvAV1Dec * self) { } +static void +gst_nv_av1_dec_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstNvAV1DecClass *klass = GST_NV_AV1_DEC_GET_CLASS (object); + + switch (prop_id) { + case PROP_CUDA_DEVICE_ID: + g_value_set_uint (value, klass->cuda_device_id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void gst_nv_av1_dec_set_context (GstElement * element, GstContext * context) { @@ -874,11 +915,11 @@ gst_nv_av1_dec_register (GstPlugin * plugin, guint device_id, guint rank, 0, (GInstanceInitFunc) gst_nv_av1_dec_init, }; - GstNvAV1DecClassData *cdata; + GstNvDecoderClassData *cdata; GST_DEBUG_CATEGORY_INIT (gst_nv_av1_dec_debug, "nvav1dec", 0, "nvav1dec"); - cdata = g_new0 (GstNvAV1DecClassData, 1); + cdata = g_new0 (GstNvDecoderClassData, 1); cdata->sink_caps = gst_caps_ref (sink_caps); cdata->src_caps = gst_caps_ref (src_caps); cdata->cuda_device_id = device_id; diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvdecoder.h b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvdecoder.h index 635d63d865..635b301192 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvdecoder.h +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvdecoder.h @@ -49,6 +49,13 @@ typedef struct _GstNvDecoderFrame gint ref_count; } GstNvDecoderFrame; +typedef struct _GstNvDecoderClassData +{ + GstCaps *sink_caps; + GstCaps *src_caps; + guint cuda_device_id; +} GstNvDecoderClassData; + GstNvDecoder * gst_nv_decoder_new (GstCudaContext * context); gboolean gst_nv_decoder_is_configured (GstNvDecoder * decoder); diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264dec.c b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264dec.c index 3f5c33500d..61e9296c84 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264dec.c +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264dec.c @@ -70,6 +70,21 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/** + * SECTION:element-nvh264sldec + * @title: nvh264sldec + * + * GstCodecs based NVIDIA H.264 video decoder + * + * ## Example launch line + * ``` + * gst-launch-1.0 filesrc location=/path/to/h264/file ! parsebin ! nvh264sldec ! videoconvert ! autovideosink + * ``` + * + * Since: 1.18 + * + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -84,7 +99,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_nv_h264_dec_debug); #define GST_CAT_DEFAULT gst_nv_h264_dec_debug -struct _GstNvH264Dec +typedef struct _GstNvH264Dec { GstH264Decoder parent; @@ -114,18 +129,30 @@ struct _GstNvH264Dec gboolean interlaced; GArray *ref_list; -}; +} GstNvH264Dec; -struct _GstNvH264DecClass +typedef struct _GstNvH264DecClass { GstH264DecoderClass parent_class; guint cuda_device_id; +} GstNvH264DecClass; + +enum +{ + PROP_0, + PROP_CUDA_DEVICE_ID, }; -#define gst_nv_h264_dec_parent_class parent_class -G_DEFINE_TYPE (GstNvH264Dec, gst_nv_h264_dec, GST_TYPE_H264_DECODER); +static GTypeClass *parent_class = NULL; + +#define GST_NV_H264_DEC(object) ((GstNvH264Dec *) (object)) +#define GST_NV_H264_DEC_GET_CLASS(object) \ + (G_TYPE_INSTANCE_GET_CLASS ((object),G_TYPE_FROM_INSTANCE (object),GstNvH264DecClass)) static void gst_nv_h264_decoder_dispose (GObject * object); +static void gst_nv_h264_dec_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + static void gst_nv_h264_dec_set_context (GstElement * element, GstContext * context); static gboolean gst_nv_h264_dec_open (GstVideoDecoder * decoder); @@ -158,23 +185,44 @@ gst_nv_h264_dec_get_preferred_output_delay (GstH264Decoder * decoder, gboolean live); static void -gst_nv_h264_dec_class_init (GstNvH264DecClass * klass) +gst_nv_h264_dec_class_init (GstNvH264DecClass * klass, + GstNvDecoderClassData * cdata) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass); GstH264DecoderClass *h264decoder_class = GST_H264_DECODER_CLASS (klass); - /** - * GstNvH264Dec - * - * Since: 1.18 - */ - object_class->dispose = gst_nv_h264_decoder_dispose; + object_class->get_property = gst_nv_h264_dec_get_property; + + /** + * GstNvH264SLDec:cuda-device-id: + * + * Assigned CUDA device id + * + * Since: 1.22 + */ + g_object_class_install_property (object_class, PROP_CUDA_DEVICE_ID, + g_param_spec_uint ("cuda-device-id", "CUDA device id", + "Assigned CUDA device id", 0, G_MAXINT, 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_set_context); + parent_class = (GTypeClass *) g_type_class_peek_parent (klass); + gst_element_class_set_static_metadata (element_class, + "NVDEC H.264 Stateless Decoder", + "Codec/Decoder/Video/Hardware", + "NVIDIA H.264 video decoder", "Seungha Yang "); + + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, + cdata->sink_caps)); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, + cdata->src_caps)); + decoder_class->open = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_open); decoder_class->close = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_close); decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_negotiate); @@ -199,10 +247,11 @@ gst_nv_h264_dec_class_init (GstNvH264DecClass * klass) h264decoder_class->get_preferred_output_delay = GST_DEBUG_FUNCPTR (gst_nv_h264_dec_get_preferred_output_delay); - GST_DEBUG_CATEGORY_INIT (gst_nv_h264_dec_debug, - "nvh264dec", 0, "Nvidia H.264 Decoder"); + klass->cuda_device_id = cdata->cuda_device_id; - gst_type_mark_as_plugin_api (GST_TYPE_NV_H264_DEC, 0); + gst_caps_unref (cdata->sink_caps); + gst_caps_unref (cdata->src_caps); + g_free (cdata); } static void @@ -224,6 +273,22 @@ gst_nv_h264_decoder_dispose (GObject * object) G_OBJECT_CLASS (parent_class)->dispose (object); } +static void +gst_nv_h264_dec_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstNvH264DecClass *klass = GST_NV_H264_DEC_GET_CLASS (object); + + switch (prop_id) { + case PROP_CUDA_DEVICE_ID: + g_value_set_uint (value, klass->cuda_device_id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void gst_nv_h264_dec_set_context (GstElement * element, GstContext * context) { @@ -885,68 +950,32 @@ gst_nv_h264_dec_get_preferred_output_delay (GstH264Decoder * decoder, return 4; } -typedef struct -{ - GstCaps *sink_caps; - GstCaps *src_caps; - guint cuda_device_id; - gboolean is_default; -} GstNvH264DecClassData; - -static void -gst_nv_h264_dec_subclass_init (gpointer klass, GstNvH264DecClassData * cdata) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - GstNvH264DecClass *nvdec_class = (GstNvH264DecClass *) (klass); - gchar *long_name; - - if (cdata->is_default) { - long_name = g_strdup_printf ("NVDEC H.264 Stateless Decoder"); - } else { - long_name = g_strdup_printf ("NVDEC H.264 Stateless Decoder with device %d", - cdata->cuda_device_id); - } - - gst_element_class_set_metadata (element_class, long_name, - "Codec/Decoder/Video/Hardware", - "Nvidia H.264 video decoder", "Seungha Yang "); - g_free (long_name); - - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - cdata->sink_caps)); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - cdata->src_caps)); - - nvdec_class->cuda_device_id = cdata->cuda_device_id; - - gst_caps_unref (cdata->sink_caps); - gst_caps_unref (cdata->src_caps); - g_free (cdata); -} - void gst_nv_h264_dec_register (GstPlugin * plugin, guint device_id, guint rank, GstCaps * sink_caps, GstCaps * src_caps, gboolean is_primary) { - GTypeQuery type_query; - GTypeInfo type_info = { 0, }; - GType subtype; + GType type; gchar *type_name; gchar *feature_name; - GstNvH264DecClassData *cdata; - gboolean is_default = TRUE; + GstNvDecoderClassData *cdata; + gint index = 0; const GValue *value; GstStructure *s; + GTypeInfo type_info = { + sizeof (GstNvH264DecClass), + NULL, + NULL, + (GClassInitFunc) gst_nv_h264_dec_class_init, + NULL, + NULL, + sizeof (GstNvH264Dec), + 0, + (GInstanceInitFunc) gst_nv_h264_dec_init, + }; - /** - * element-nvh264sldec - * - * Since: 1.18 - */ + GST_DEBUG_CATEGORY_INIT (gst_nv_h264_dec_debug, "nvh264dec", 0, "nvh264dec"); - cdata = g_new0 (GstNvH264DecClassData, 1); + cdata = g_new0 (GstNvDecoderClassData, 1); cdata->sink_caps = gst_caps_from_string ("video/x-h264, " "stream-format= (string) { avc, avc3, byte-stream }, " "alignment= (string) au, " @@ -965,45 +994,37 @@ gst_nv_h264_dec_register (GstPlugin * plugin, guint device_id, guint rank, cdata->src_caps = gst_caps_ref (src_caps); cdata->cuda_device_id = device_id; - g_type_query (GST_TYPE_NV_H264_DEC, &type_query); - memset (&type_info, 0, sizeof (type_info)); - type_info.class_size = type_query.class_size; - type_info.instance_size = type_query.instance_size; - type_info.class_init = (GClassInitFunc) gst_nv_h264_dec_subclass_init; - type_info.class_data = cdata; - if (is_primary) { - type_name = g_strdup ("GstNvH264StatelessPrimaryDec"); + type_name = g_strdup ("GstNvH264Dec"); feature_name = g_strdup ("nvh264dec"); } else { - type_name = g_strdup ("GstNvH264StatelessDec"); + type_name = g_strdup ("GstNvH264SLDec"); feature_name = g_strdup ("nvh264sldec"); } - if (g_type_from_name (type_name) != 0) { + while (g_type_from_name (type_name)) { + index++; g_free (type_name); g_free (feature_name); if (is_primary) { - type_name = - g_strdup_printf ("GstNvH264StatelessPrimaryDevice%dDec", device_id); - feature_name = g_strdup_printf ("nvh264device%ddec", device_id); + type_name = g_strdup_printf ("GstNvH264Device%dDec", index); + feature_name = g_strdup_printf ("nvh264device%ddec", index); } else { - type_name = g_strdup_printf ("GstNvH264StatelessDevice%dDec", device_id); - feature_name = g_strdup_printf ("nvh264sldevice%ddec", device_id); + type_name = g_strdup_printf ("GstNvH264SLDevice%dDec", index); + feature_name = g_strdup_printf ("nvh264sldevice%ddec", index); } - - is_default = FALSE; } - cdata->is_default = is_default; - subtype = g_type_register_static (GST_TYPE_NV_H264_DEC, + type_info.class_data = cdata; + + type = g_type_register_static (GST_TYPE_H264_DECODER, type_name, &type_info, 0); /* make lower rank than default device */ - if (rank > 0 && !is_default) + if (rank > 0 && index > 0) rank--; - if (!gst_element_register (plugin, feature_name, rank, subtype)) + if (!gst_element_register (plugin, feature_name, rank, type)) GST_WARNING ("Failed to register plugin '%s'", type_name); g_free (type_name); diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264dec.h b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264dec.h index bc2e956e44..69d209a13b 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264dec.h +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh264dec.h @@ -25,16 +25,6 @@ G_BEGIN_DECLS -#define GST_TYPE_NV_H264_DEC (gst_nv_h264_dec_get_type()) -#define GST_NV_H264_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_NV_H264_DEC, GstNvH264Dec)) -#define GST_NV_H264_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_NV_H264_DEC, GstNvH264DecClass)) -#define GST_NV_H264_DEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_NV_H264_DEC, GstNvH264DecClass)) - -typedef struct _GstNvH264Dec GstNvH264Dec; -typedef struct _GstNvH264DecClass GstNvH264DecClass; - -GType gst_nv_h264_dec_get_type (void); - void gst_nv_h264_dec_register (GstPlugin * plugin, guint device_id, guint rank, diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265dec.c b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265dec.c index 75dae1d2c8..2770db9497 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265dec.c +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265dec.c @@ -70,6 +70,21 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/** + * SECTION:element-nvh265sldec + * @title: nvh265sldec + * + * GstCodecs based NVIDIA H.265 video decoder + * + * ## Example launch line + * ``` + * gst-launch-1.0 filesrc location=/path/to/h265/file ! parsebin ! nvh265sldec ! videoconvert ! autovideosink + * ``` + * + * Since: 1.18 + * + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -83,7 +98,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_nv_h265_dec_debug); #define GST_CAT_DEFAULT gst_nv_h265_dec_debug -struct _GstNvH265Dec +typedef struct _GstNvH265Dec { GstH265Decoder parent; @@ -108,16 +123,28 @@ struct _GstNvH265Dec guint coded_width, coded_height; guint bitdepth; guint chroma_format_idc; -}; +} GstNvH265Dec; -struct _GstNvH265DecClass +typedef struct _GstNvH265DecClass { GstH265DecoderClass parent_class; guint cuda_device_id; +} GstNvH265DecClass; + +enum +{ + PROP_0, + PROP_CUDA_DEVICE_ID, }; -#define gst_nv_h265_dec_parent_class parent_class -G_DEFINE_TYPE (GstNvH265Dec, gst_nv_h265_dec, GST_TYPE_H265_DECODER); +static GTypeClass *parent_class = NULL; + +#define GST_NV_H265_DEC(object) ((GstNvH265Dec *) (object)) +#define GST_NV_H265_DEC_GET_CLASS(object) \ + (G_TYPE_INSTANCE_GET_CLASS ((object),G_TYPE_FROM_INSTANCE (object),GstNvH265DecClass)) + +static void gst_nv_h265_dec_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); static void gst_nv_h265_dec_set_context (GstElement * element, GstContext * context); @@ -148,20 +175,43 @@ gst_nv_h265_dec_get_preferred_output_delay (GstH265Decoder * decoder, gboolean live); static void -gst_nv_h265_dec_class_init (GstNvH265DecClass * klass) +gst_nv_h265_dec_class_init (GstNvH265DecClass * klass, + GstNvDecoderClassData * cdata) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass); GstH265DecoderClass *h265decoder_class = GST_H265_DECODER_CLASS (klass); + object_class->get_property = gst_nv_h265_dec_get_property; + /** - * GstNvH265Dec + * GstNvH265SLDec:cuda-device-id: * - * Since: 1.18 + * Assigned CUDA device id + * + * Since: 1.22 */ + g_object_class_install_property (object_class, PROP_CUDA_DEVICE_ID, + g_param_spec_uint ("cuda-device-id", "CUDA device id", + "Assigned CUDA device id", 0, G_MAXINT, 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_h265_dec_set_context); + parent_class = (GTypeClass *) g_type_class_peek_parent (klass); + gst_element_class_set_static_metadata (element_class, + "NVDEC H.265 Stateless Decoder", + "Codec/Decoder/Video/Hardware", + "NVIDIA H.265 video decoder", "Seungha Yang "); + + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, + cdata->sink_caps)); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, + cdata->src_caps)); + decoder_class->open = GST_DEBUG_FUNCPTR (gst_nv_h265_dec_open); decoder_class->close = GST_DEBUG_FUNCPTR (gst_nv_h265_dec_close); decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_nv_h265_dec_negotiate); @@ -184,10 +234,11 @@ gst_nv_h265_dec_class_init (GstNvH265DecClass * klass) h265decoder_class->get_preferred_output_delay = GST_DEBUG_FUNCPTR (gst_nv_h265_dec_get_preferred_output_delay); - GST_DEBUG_CATEGORY_INIT (gst_nv_h265_dec_debug, - "nvh265dec", 0, "Nvidia H.265 Decoder"); + klass->cuda_device_id = cdata->cuda_device_id; - gst_type_mark_as_plugin_api (GST_TYPE_NV_H265_DEC, 0); + gst_caps_unref (cdata->sink_caps); + gst_caps_unref (cdata->src_caps); + g_free (cdata); } static void @@ -195,6 +246,22 @@ gst_nv_h265_dec_init (GstNvH265Dec * self) { } +static void +gst_nv_h265_dec_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstNvH265DecClass *klass = GST_NV_H265_DEC_GET_CLASS (object); + + switch (prop_id) { + case PROP_CUDA_DEVICE_ID: + g_value_set_uint (value, klass->cuda_device_id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void gst_nv_h265_dec_set_context (GstElement * element, GstContext * context) { @@ -931,68 +998,32 @@ gst_nv_h265_dec_get_preferred_output_delay (GstH265Decoder * decoder, return 4; } -typedef struct -{ - GstCaps *sink_caps; - GstCaps *src_caps; - guint cuda_device_id; - gboolean is_default; -} GstNvH265DecClassData; - -static void -gst_nv_h265_dec_subclass_init (gpointer klass, GstNvH265DecClassData * cdata) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - GstNvH265DecClass *nvdec_class = (GstNvH265DecClass *) (klass); - gchar *long_name; - - if (cdata->is_default) { - long_name = g_strdup_printf ("NVDEC H.265 Stateless Decoder"); - } else { - long_name = g_strdup_printf ("NVDEC H.265 Stateless Decoder with device %d", - cdata->cuda_device_id); - } - - gst_element_class_set_metadata (element_class, long_name, - "Codec/Decoder/Video/Hardware", - "Nvidia H.265 video decoder", "Seungha Yang "); - g_free (long_name); - - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - cdata->sink_caps)); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - cdata->src_caps)); - - nvdec_class->cuda_device_id = cdata->cuda_device_id; - - gst_caps_unref (cdata->sink_caps); - gst_caps_unref (cdata->src_caps); - g_free (cdata); -} - void gst_nv_h265_dec_register (GstPlugin * plugin, guint device_id, guint rank, GstCaps * sink_caps, GstCaps * src_caps, gboolean is_primary) { - GTypeQuery type_query; - GTypeInfo type_info = { 0, }; - GType subtype; + GType type; gchar *type_name; gchar *feature_name; - GstNvH265DecClassData *cdata; - gboolean is_default = TRUE; + GstNvDecoderClassData *cdata; + gint index = 0; GValue value_list = G_VALUE_INIT; GValue value = G_VALUE_INIT; + GTypeInfo type_info = { + sizeof (GstNvH265DecClass), + NULL, + NULL, + (GClassInitFunc) gst_nv_h265_dec_class_init, + NULL, + NULL, + sizeof (GstNvH265Dec), + 0, + (GInstanceInitFunc) gst_nv_h265_dec_init, + }; - /** - * element-nvh265sldec - * - * Since: 1.18 - */ + GST_DEBUG_CATEGORY_INIT (gst_nv_h265_dec_debug, "nvh265dec", 0, "nvh265dec"); - cdata = g_new0 (GstNvH265DecClassData, 1); + cdata = g_new0 (GstNvDecoderClassData, 1); cdata->sink_caps = gst_caps_copy (sink_caps); /* Update stream-format since we support packetized format as well */ @@ -1017,45 +1048,36 @@ gst_nv_h265_dec_register (GstPlugin * plugin, guint device_id, guint rank, cdata->src_caps = gst_caps_ref (src_caps); cdata->cuda_device_id = device_id; - g_type_query (GST_TYPE_NV_H265_DEC, &type_query); - memset (&type_info, 0, sizeof (type_info)); - type_info.class_size = type_query.class_size; - type_info.instance_size = type_query.instance_size; - type_info.class_init = (GClassInitFunc) gst_nv_h265_dec_subclass_init; - type_info.class_data = cdata; - if (is_primary) { - type_name = g_strdup ("GstNvH265StatelessPrimaryDec"); + type_name = g_strdup ("GstNvH265Dec"); feature_name = g_strdup ("nvh265dec"); } else { - type_name = g_strdup ("GstNvH265StatelessDec"); + type_name = g_strdup ("GstNvH265SLDec"); feature_name = g_strdup ("nvh265sldec"); } - if (g_type_from_name (type_name) != 0) { + while (g_type_from_name (type_name)) { + index++; g_free (type_name); g_free (feature_name); if (is_primary) { - type_name = - g_strdup_printf ("GstNvH265StatelessPrimaryDevice%dDec", device_id); - feature_name = g_strdup_printf ("nvh265device%ddec", device_id); + type_name = g_strdup_printf ("GstNvH265Device%dDec", index); + feature_name = g_strdup_printf ("nvh265device%ddec", index); } else { - type_name = g_strdup_printf ("GstNvH265StatelessDevice%dDec", device_id); - feature_name = g_strdup_printf ("nvh265sldevice%ddec", device_id); + type_name = g_strdup_printf ("GstNvH265SLDevice%dDec", index); + feature_name = g_strdup_printf ("nvh265sldevice%ddec", index); } - - is_default = FALSE; } - cdata->is_default = is_default; - subtype = g_type_register_static (GST_TYPE_NV_H265_DEC, + type_info.class_data = cdata; + type = g_type_register_static (GST_TYPE_H265_DECODER, type_name, &type_info, 0); /* make lower rank than default device */ - if (rank > 0 && !is_default) + if (rank > 0 && index > 0) rank--; - if (!gst_element_register (plugin, feature_name, rank, subtype)) + if (!gst_element_register (plugin, feature_name, rank, type)) GST_WARNING ("Failed to register plugin '%s'", type_name); g_free (type_name); diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265dec.h b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265dec.h index afca7f9f95..7dffa3e937 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265dec.h +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvh265dec.h @@ -25,16 +25,6 @@ G_BEGIN_DECLS -#define GST_TYPE_NV_H265_DEC (gst_nv_h265_dec_get_type()) -#define GST_NV_H265_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_NV_H265_DEC, GstNvH265Dec)) -#define GST_NV_H265_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_NV_H265_DEC, GstNvH265DecClass)) -#define GST_NV_H265_DEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_NV_H265_DEC, GstNvH265DecClass)) - -typedef struct _GstNvH265Dec GstNvH265Dec; -typedef struct _GstNvH265DecClass GstNvH265DecClass; - -GType gst_nv_h265_dec_get_type (void); - void gst_nv_h265_dec_register (GstPlugin * plugin, guint device_id, guint rank, diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp8dec.c b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp8dec.c index 3cbfe518fb..520c1697f1 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp8dec.c +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp8dec.c @@ -17,6 +17,21 @@ * Boston, MA 02110-1301, USA. */ +/** + * SECTION:element-nvvp8sldec + * @title: nvvp8sldec + * + * GstCodecs based NVIDIA VP8 video decoder + * + * ## Example launch line + * ``` + * gst-launch-1.0 filesrc location=/path/to/vp8/file ! parsebin ! nvvp8sldec ! videoconvert ! autovideosink + * ``` + * + * Since: 1.20 + * + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -31,7 +46,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_nv_vp8_dec_debug); #define GST_CAT_DEFAULT gst_nv_vp8_dec_debug -struct _GstNvVp8Dec +typedef struct _GstNvVp8Dec { GstVp8Decoder parent; @@ -42,22 +57,28 @@ struct _GstNvVp8Dec CUVIDPICPARAMS params; guint width, height; -}; +} GstNvVp8Dec; -struct _GstNvVp8DecClass +typedef struct _GstNvVp8DecClass { GstVp8DecoderClass parent_class; guint cuda_device_id; +} GstNvVp8DecClass; + +enum +{ + PROP_0, + PROP_CUDA_DEVICE_ID, }; -#define gst_nv_vp8_dec_parent_class parent_class +static GTypeClass *parent_class = NULL; -/** - * GstNvVp8Dec: - * - * Since: 1.20 - */ -G_DEFINE_TYPE (GstNvVp8Dec, gst_nv_vp8_dec, GST_TYPE_VP8_DECODER); +#define GST_NV_VP8_DEC(object) ((GstNvVp8Dec *) (object)) +#define GST_NV_VP8_DEC_GET_CLASS(object) \ + (G_TYPE_INSTANCE_GET_CLASS ((object),G_TYPE_FROM_INSTANCE (object),GstNvVp8DecClass)) + +static void gst_nv_vp8_dec_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); static void gst_nv_vp8_dec_set_context (GstElement * element, GstContext * context); @@ -82,14 +103,43 @@ static guint gst_nv_vp8_dec_get_preferred_output_delay (GstVp8Decoder * decoder, gboolean is_live); static void -gst_nv_vp8_dec_class_init (GstNvVp8DecClass * klass) +gst_nv_vp8_dec_class_init (GstNvVp8DecClass * klass, + GstNvDecoderClassData * cdata) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass); GstVp8DecoderClass *vp8decoder_class = GST_VP8_DECODER_CLASS (klass); + object_class->get_property = gst_nv_vp8_dec_get_property; + + /** + * GstNvVp8SLDec:cuda-device-id: + * + * Assigned CUDA device id + * + * Since: 1.22 + */ + g_object_class_install_property (object_class, PROP_CUDA_DEVICE_ID, + g_param_spec_uint ("cuda-device-id", "CUDA device id", + "Assigned CUDA device id", 0, G_MAXINT, 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_vp8_dec_set_context); + parent_class = (GTypeClass *) g_type_class_peek_parent (klass); + gst_element_class_set_metadata (element_class, + "NVDEC VP8 Stateless Decoder", + "Codec/Decoder/Video/Hardware", + "NVIDIA VP8 video decoder", "Seungha Yang "); + + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, + cdata->sink_caps)); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, + cdata->src_caps)); + decoder_class->open = GST_DEBUG_FUNCPTR (gst_nv_vp8_dec_open); decoder_class->close = GST_DEBUG_FUNCPTR (gst_nv_vp8_dec_close); decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_nv_vp8_dec_negotiate); @@ -108,10 +158,11 @@ gst_nv_vp8_dec_class_init (GstNvVp8DecClass * klass) vp8decoder_class->get_preferred_output_delay = GST_DEBUG_FUNCPTR (gst_nv_vp8_dec_get_preferred_output_delay); - GST_DEBUG_CATEGORY_INIT (gst_nv_vp8_dec_debug, - "nvvp8dec", 0, "NVIDIA VP8 Decoder"); + klass->cuda_device_id = cdata->cuda_device_id; - gst_type_mark_as_plugin_api (GST_TYPE_NV_VP8_DEC, 0); + gst_caps_unref (cdata->sink_caps); + gst_caps_unref (cdata->src_caps); + g_free (cdata); } static void @@ -119,6 +170,22 @@ gst_nv_vp8_dec_init (GstNvVp8Dec * self) { } +static void +gst_nv_vp8_dec_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstNvVp8DecClass *klass = GST_NV_VP8_DEC_GET_CLASS (object); + + switch (prop_id) { + case PROP_CUDA_DEVICE_ID: + g_value_set_uint (value, klass->cuda_device_id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void gst_nv_vp8_dec_set_context (GstElement * element, GstContext * context) { @@ -444,109 +511,64 @@ gst_nv_vp8_dec_get_preferred_output_delay (GstVp8Decoder * decoder, return 4; } -typedef struct -{ - GstCaps *sink_caps; - GstCaps *src_caps; - guint cuda_device_id; - gboolean is_default; -} GstNvVp8DecClassData; - -static void -gst_nv_vp8_dec_subclass_init (gpointer klass, GstNvVp8DecClassData * cdata) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - GstNvVp8DecClass *nvdec_class = (GstNvVp8DecClass *) (klass); - gchar *long_name; - - if (cdata->is_default) { - long_name = g_strdup_printf ("NVDEC VP8 Stateless Decoder"); - } else { - long_name = g_strdup_printf ("NVDEC VP8 Stateless Decoder with device %d", - cdata->cuda_device_id); - } - - gst_element_class_set_metadata (element_class, long_name, - "Codec/Decoder/Video/Hardware", - "NVIDIA VP8 video decoder", "Seungha Yang "); - g_free (long_name); - - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - cdata->sink_caps)); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - cdata->src_caps)); - - nvdec_class->cuda_device_id = cdata->cuda_device_id; - - gst_caps_unref (cdata->sink_caps); - gst_caps_unref (cdata->src_caps); - g_free (cdata); -} - void gst_nv_vp8_dec_register (GstPlugin * plugin, guint device_id, guint rank, GstCaps * sink_caps, GstCaps * src_caps, gboolean is_primary) { - GTypeQuery type_query; - GTypeInfo type_info = { 0, }; - GType subtype; + GType type; gchar *type_name; gchar *feature_name; - GstNvVp8DecClassData *cdata; - gboolean is_default = TRUE; + GstNvDecoderClassData *cdata; + gint index = 0; + GTypeInfo type_info = { + sizeof (GstNvVp8DecClass), + NULL, + NULL, + (GClassInitFunc) gst_nv_vp8_dec_class_init, + NULL, + NULL, + sizeof (GstNvVp8Dec), + 0, + (GInstanceInitFunc) gst_nv_vp8_dec_init, + }; - /** - * element-nvvp8sldec: - * - * Since: 1.20 - */ + GST_DEBUG_CATEGORY_INIT (gst_nv_vp8_dec_debug, "nvvp8dec", 0, "nvvp8dec"); - cdata = g_new0 (GstNvVp8DecClassData, 1); + cdata = g_new0 (GstNvDecoderClassData, 1); cdata->sink_caps = gst_caps_ref (sink_caps); cdata->src_caps = gst_caps_ref (src_caps); cdata->cuda_device_id = device_id; - g_type_query (GST_TYPE_NV_VP8_DEC, &type_query); - memset (&type_info, 0, sizeof (type_info)); - type_info.class_size = type_query.class_size; - type_info.instance_size = type_query.instance_size; - type_info.class_init = (GClassInitFunc) gst_nv_vp8_dec_subclass_init; - type_info.class_data = cdata; - if (is_primary) { - type_name = g_strdup ("GstNvVP8StatelessPrimaryDec"); + type_name = g_strdup ("GstNvVp8Dec"); feature_name = g_strdup ("nvvp8dec"); } else { - type_name = g_strdup ("GstNvVP8StatelessDec"); + type_name = g_strdup ("GstNvVp8SLDec"); feature_name = g_strdup ("nvvp8sldec"); } - if (g_type_from_name (type_name) != 0) { + while (g_type_from_name (type_name)) { + index++; g_free (type_name); g_free (feature_name); if (is_primary) { - type_name = - g_strdup_printf ("GstNvVP8StatelessPrimaryDevice%dDec", device_id); - feature_name = g_strdup_printf ("nvvp8device%ddec", device_id); + type_name = g_strdup_printf ("GstNvVp8Device%dDec", index); + feature_name = g_strdup_printf ("nvvp8device%ddec", index); } else { - type_name = g_strdup_printf ("GstNvVP8StatelessDevice%dDec", device_id); - feature_name = g_strdup_printf ("nvvp8sldevice%ddec", device_id); + type_name = g_strdup_printf ("GstNvVp8SLDevice%dDec", index); + feature_name = g_strdup_printf ("nvvp8sldevice%ddec", index); } - - is_default = FALSE; } - cdata->is_default = is_default; - subtype = g_type_register_static (GST_TYPE_NV_VP8_DEC, + type_info.class_data = cdata; + type = g_type_register_static (GST_TYPE_VP8_DECODER, type_name, &type_info, 0); /* make lower rank than default device */ - if (rank > 0 && !is_default) + if (rank > 0 && index > 0) rank--; - if (!gst_element_register (plugin, feature_name, rank, subtype)) + if (!gst_element_register (plugin, feature_name, rank, type)) GST_WARNING ("Failed to register plugin '%s'", type_name); g_free (type_name); diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp8dec.h b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp8dec.h index df55f2e0c4..3bc6c3085f 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp8dec.h +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp8dec.h @@ -25,16 +25,6 @@ G_BEGIN_DECLS -#define GST_TYPE_NV_VP8_DEC (gst_nv_vp8_dec_get_type()) -#define GST_NV_VP8_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_NV_VP8_DEC, GstNvVp8Dec)) -#define GST_NV_VP8_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_NV_VP8_DEC, GstNvVp8DecClass)) -#define GST_NV_VP8_DEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_NV_VP8_DEC, GstNvVp8DecClass)) - -typedef struct _GstNvVp8Dec GstNvVp8Dec; -typedef struct _GstNvVp8DecClass GstNvVp8DecClass; - -GType gst_nv_vp8_dec_get_type (void); - void gst_nv_vp8_dec_register (GstPlugin * plugin, guint device_id, guint rank, diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp9dec.c b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp9dec.c index fe2a9fa3a6..c21fbd351b 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp9dec.c +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp9dec.c @@ -17,6 +17,21 @@ * Boston, MA 02110-1301, USA. */ +/** + * SECTION:element-nvvp9sldec + * @title: nvvp9sldec + * + * GstCodecs based NVIDIA VP9 video decoder + * + * ## Example launch line + * ``` + * gst-launch-1.0 filesrc location=/path/to/vp9/file ! parsebin ! nvvp9sldec ! videoconvert ! autovideosink + * ``` + * + * Since: 1.20 + * + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -31,7 +46,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_nv_vp9_dec_debug); #define GST_CAT_DEFAULT gst_nv_vp9_dec_debug -struct _GstNvVp9Dec +typedef struct _GstNvVp9Dec { GstVp9Decoder parent; @@ -43,22 +58,28 @@ struct _GstNvVp9Dec guint width, height; GstVP9Profile profile; -}; +} GstNvVp9Dec; -struct _GstNvVp9DecClass +typedef struct _GstNvVp9DecClass { GstVp9DecoderClass parent_class; guint cuda_device_id; +} GstNvVp9DecClass; + +enum +{ + PROP_0, + PROP_CUDA_DEVICE_ID, }; -#define gst_nv_vp9_dec_parent_class parent_class +static GTypeClass *parent_class = NULL; -/** - * GstNvVp9Dec: - * - * Since: 1.20 - */ -G_DEFINE_TYPE (GstNvVp9Dec, gst_nv_vp9_dec, GST_TYPE_VP9_DECODER); +#define GST_NV_VP9_DEC(object) ((GstNvVp9Dec *) (object)) +#define GST_NV_VP9_DEC_GET_CLASS(object) \ + (G_TYPE_INSTANCE_GET_CLASS ((object),G_TYPE_FROM_INSTANCE (object),GstNvVp9DecClass)) + +static void gst_nv_vp9_dec_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); static void gst_nv_vp9_dec_set_context (GstElement * element, GstContext * context); @@ -85,14 +106,43 @@ static guint gst_nv_vp9_dec_get_preferred_output_delay (GstVp9Decoder * decoder, gboolean is_live); static void -gst_nv_vp9_dec_class_init (GstNvVp9DecClass * klass) +gst_nv_vp9_dec_class_init (GstNvVp9DecClass * klass, + GstNvDecoderClassData * cdata) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass); GstVp9DecoderClass *vp9decoder_class = GST_VP9_DECODER_CLASS (klass); + object_class->get_property = gst_nv_vp9_dec_get_property; + + /** + * GstNvVp9SLDec:cuda-device-id: + * + * Assigned CUDA device id + * + * Since: 1.22 + */ + g_object_class_install_property (object_class, PROP_CUDA_DEVICE_ID, + g_param_spec_uint ("cuda-device-id", "CUDA device id", + "Assigned CUDA device id", 0, G_MAXINT, 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + element_class->set_context = GST_DEBUG_FUNCPTR (gst_nv_vp9_dec_set_context); + parent_class = (GTypeClass *) g_type_class_peek_parent (klass); + gst_element_class_set_metadata (element_class, + "NVDEC VP9 Stateless Decoder", + "Codec/Decoder/Video/Hardware", + "NVIDIA VP9 video decoder", "Seungha Yang "); + + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, + cdata->sink_caps)); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, + cdata->src_caps)); + decoder_class->open = GST_DEBUG_FUNCPTR (gst_nv_vp9_dec_open); decoder_class->close = GST_DEBUG_FUNCPTR (gst_nv_vp9_dec_close); decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_nv_vp9_dec_negotiate); @@ -113,10 +163,11 @@ gst_nv_vp9_dec_class_init (GstNvVp9DecClass * klass) vp9decoder_class->get_preferred_output_delay = GST_DEBUG_FUNCPTR (gst_nv_vp9_dec_get_preferred_output_delay); - GST_DEBUG_CATEGORY_INIT (gst_nv_vp9_dec_debug, - "nvvp9dec", 0, "NVIDIA VP9 Decoder"); + klass->cuda_device_id = cdata->cuda_device_id; - gst_type_mark_as_plugin_api (GST_TYPE_NV_VP9_DEC, 0); + gst_caps_unref (cdata->sink_caps); + gst_caps_unref (cdata->src_caps); + g_free (cdata); } static void @@ -124,6 +175,22 @@ gst_nv_vp9_dec_init (GstNvVp9Dec * self) { } +static void +gst_nv_vp9_dec_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) +{ + GstNvVp9DecClass *klass = GST_NV_VP9_DEC_GET_CLASS (object); + + switch (prop_id) { + case PROP_CUDA_DEVICE_ID: + g_value_set_uint (value, klass->cuda_device_id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void gst_nv_vp9_dec_set_context (GstElement * element, GstContext * context) { @@ -539,66 +606,30 @@ gst_nv_vp9_dec_get_preferred_output_delay (GstVp9Decoder * decoder, return 4; } -typedef struct -{ - GstCaps *sink_caps; - GstCaps *src_caps; - guint cuda_device_id; - gboolean is_default; -} GstNvVp9DecClassData; - -static void -gst_nv_vp9_dec_subclass_init (gpointer klass, GstNvVp9DecClassData * cdata) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - GstNvVp9DecClass *nvdec_class = (GstNvVp9DecClass *) (klass); - gchar *long_name; - - if (cdata->is_default) { - long_name = g_strdup_printf ("NVDEC VP9 Stateless Decoder"); - } else { - long_name = g_strdup_printf ("NVDEC VP9 Stateless Decoder with device %d", - cdata->cuda_device_id); - } - - gst_element_class_set_metadata (element_class, long_name, - "Codec/Decoder/Video/Hardware", - "NVIDIA VP9 video decoder", "Seungha Yang "); - g_free (long_name); - - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - cdata->sink_caps)); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - cdata->src_caps)); - - nvdec_class->cuda_device_id = cdata->cuda_device_id; - - gst_caps_unref (cdata->sink_caps); - gst_caps_unref (cdata->src_caps); - g_free (cdata); -} - void gst_nv_vp9_dec_register (GstPlugin * plugin, guint device_id, guint rank, GstCaps * sink_caps, GstCaps * src_caps, gboolean is_primary) { - GTypeQuery type_query; - GTypeInfo type_info = { 0, }; - GType subtype; + GType type; gchar *type_name; gchar *feature_name; - GstNvVp9DecClassData *cdata; - gboolean is_default = TRUE; + GstNvDecoderClassData *cdata; + gint index = 0; + GTypeInfo type_info = { + sizeof (GstNvVp9DecClass), + NULL, + NULL, + (GClassInitFunc) gst_nv_vp9_dec_class_init, + NULL, + NULL, + sizeof (GstNvVp9Dec), + 0, + (GInstanceInitFunc) gst_nv_vp9_dec_init, + }; - /** - * element-nvvp9sldec: - * - * Since: 1.20 - */ + GST_DEBUG_CATEGORY_INIT (gst_nv_vp9_dec_debug, "nvvp9dec", 0, "nvvp9dec"); - cdata = g_new0 (GstNvVp9DecClassData, 1); + cdata = g_new0 (GstNvDecoderClassData, 1); cdata->sink_caps = gst_caps_copy (sink_caps); gst_caps_set_simple (cdata->sink_caps, "alignment", G_TYPE_STRING, "frame", NULL); @@ -607,45 +638,37 @@ gst_nv_vp9_dec_register (GstPlugin * plugin, guint device_id, guint rank, cdata->src_caps = gst_caps_ref (src_caps); cdata->cuda_device_id = device_id; - g_type_query (GST_TYPE_NV_VP9_DEC, &type_query); - memset (&type_info, 0, sizeof (type_info)); - type_info.class_size = type_query.class_size; - type_info.instance_size = type_query.instance_size; - type_info.class_init = (GClassInitFunc) gst_nv_vp9_dec_subclass_init; - type_info.class_data = cdata; - if (is_primary) { - type_name = g_strdup ("GstNvVP9StatelessPrimaryDec"); + type_name = g_strdup ("GstNvVp9Dec"); feature_name = g_strdup ("nvvp9dec"); } else { - type_name = g_strdup ("GstNvVP9StatelessDec"); + type_name = g_strdup ("GstNvVp9SLDec"); feature_name = g_strdup ("nvvp9sldec"); } - if (g_type_from_name (type_name) != 0) { + while (g_type_from_name (type_name)) { + index++; g_free (type_name); g_free (feature_name); if (is_primary) { - type_name = - g_strdup_printf ("GstNvVP9StatelessPrimaryDevice%dDec", device_id); - feature_name = g_strdup_printf ("nvvp9device%ddec", device_id); + type_name = g_strdup_printf ("GstNvVp9Device%dDec", index); + feature_name = g_strdup_printf ("nvvp9device%ddec", index); } else { - type_name = g_strdup_printf ("GstNvVP9StatelessDevice%dDec", device_id); - feature_name = g_strdup_printf ("nvvp9sldevice%ddec", device_id); + type_name = g_strdup_printf ("GstNvVp9SLDevice%dDec", index); + feature_name = g_strdup_printf ("nvvp9sldevice%ddec", index); } - - is_default = FALSE; } - cdata->is_default = is_default; - subtype = g_type_register_static (GST_TYPE_NV_VP9_DEC, + type_info.class_data = cdata; + + type = g_type_register_static (GST_TYPE_VP9_DECODER, type_name, &type_info, 0); /* make lower rank than default device */ - if (rank > 0 && !is_default) + if (rank > 0 && index > 0) rank--; - if (!gst_element_register (plugin, feature_name, rank, subtype)) + if (!gst_element_register (plugin, feature_name, rank, type)) GST_WARNING ("Failed to register plugin '%s'", type_name); g_free (type_name); diff --git a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp9dec.h b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp9dec.h index 1a5051faf8..9d53972955 100644 --- a/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp9dec.h +++ b/subprojects/gst-plugins-bad/sys/nvcodec/gstnvvp9dec.h @@ -25,16 +25,6 @@ G_BEGIN_DECLS -#define GST_TYPE_NV_VP9_DEC (gst_nv_vp9_dec_get_type()) -#define GST_NV_VP9_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_NV_VP9_DEC, GstNvVp9Dec)) -#define GST_NV_VP9_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_NV_VP9_DEC, GstNvVp9DecClass)) -#define GST_NV_VP9_DEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_NV_VP9_DEC, GstNvVp9DecClass)) - -typedef struct _GstNvVp9Dec GstNvVp9Dec; -typedef struct _GstNvVp9DecClass GstNvVp9DecClass; - -GType gst_nv_vp9_dec_get_type (void); - void gst_nv_vp9_dec_register (GstPlugin * plugin, guint device_id, guint rank,