From b3b723462ef976ccfc4d808685221898f9d03208 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Tue, 3 Sep 2019 18:46:30 +0900 Subject: [PATCH] nvenc: Refactor class hierarchy to handle device capability dependent options Introducing new dynamic class between GstNvBaseEncClass and each subclass to be able to access device specific properties and capabilities from each subclass implementation side. --- sys/nvcodec/gstnvbaseenc.c | 84 ++++++----------------------- sys/nvcodec/gstnvbaseenc.h | 9 +--- sys/nvcodec/gstnvenc.c | 24 +++++---- sys/nvcodec/gstnvh264enc.c | 101 ++++++++++++++++++++++++++++++---- sys/nvcodec/gstnvh264enc.h | 20 +++---- sys/nvcodec/gstnvh265enc.c | 107 ++++++++++++++++++++++++++++++++----- sys/nvcodec/gstnvh265enc.h | 19 ++----- 7 files changed, 230 insertions(+), 134 deletions(-) diff --git a/sys/nvcodec/gstnvbaseenc.c b/sys/nvcodec/gstnvbaseenc.c index 8c3c504852..5c2fca5380 100644 --- a/sys/nvcodec/gstnvbaseenc.c +++ b/sys/nvcodec/gstnvbaseenc.c @@ -2243,91 +2243,41 @@ gst_nv_base_enc_get_property (GObject * object, guint prop_id, GValue * value, } } -typedef struct -{ - GstCaps *sink_caps; - GstCaps *src_caps; - guint cuda_device_id; - gboolean is_default; -} GstNvEncClassData; - static void gst_nv_base_enc_subclass_init (gpointer g_class, gpointer data) { - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); GstNvBaseEncClass *nvbaseenc_class = GST_NV_BASE_ENC_CLASS (g_class); - GstNvEncClassData *cdata = data; + guint device_id = GPOINTER_TO_UINT (data); - if (!cdata->is_default) { - const gchar *long_name; - gchar *new_long_name; - - long_name = gst_element_class_get_metadata (element_class, - GST_ELEMENT_METADATA_LONGNAME); - - new_long_name = g_strdup_printf ("%s with devide-id %d", long_name, - cdata->cuda_device_id); - - gst_element_class_add_metadata (element_class, - GST_ELEMENT_METADATA_LONGNAME, new_long_name); - g_free (new_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)); - - nvbaseenc_class->cuda_device_id = cdata->cuda_device_id; - - gst_caps_unref (cdata->sink_caps); - gst_caps_unref (cdata->src_caps); - g_free (cdata); + nvbaseenc_class->cuda_device_id = device_id; } -void -gst_nv_base_enc_register (GstPlugin * plugin, GType type, const char *codec, - guint device_id, guint rank, GstCaps * sink_caps, GstCaps * src_caps) +GType +gst_nv_base_enc_register (const char *codec, guint device_id) { GTypeQuery type_query; GTypeInfo type_info = { 0, }; GType subtype; gchar *type_name; - GstNvEncClassData *cdata; - gboolean is_default = TRUE; - cdata = g_new0 (GstNvEncClassData, 1); - cdata->sink_caps = gst_caps_ref (sink_caps); - cdata->src_caps = gst_caps_ref (src_caps); - cdata->cuda_device_id = device_id; + type_name = g_strdup_printf ("GstNvDevice%d%sEnc", device_id, codec); + subtype = g_type_from_name (type_name); - g_type_query (type, &type_query); + /* has already registered nvdeviceenc class */ + if (subtype) + goto done; + + g_type_query (GST_TYPE_NV_BASE_ENC, &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 = gst_nv_base_enc_subclass_init; - type_info.class_data = cdata; + type_info.class_init = (GClassInitFunc) gst_nv_base_enc_subclass_init; + type_info.class_data = GUINT_TO_POINTER (device_id); - type_name = g_strdup_printf ("nv%senc", codec); - - if (g_type_from_name (type_name) != 0) { - g_free (type_name); - type_name = g_strdup_printf ("nv%sdevice%denc", codec, device_id); - is_default = FALSE; - } - - cdata->is_default = is_default; - subtype = g_type_register_static (type, type_name, &type_info, 0); - - /* make lower rank than default device */ - if (rank > 0 && !is_default) - rank--; - - if (!gst_element_register (plugin, type_name, rank, subtype)) - GST_WARNING ("Failed to register plugin '%s'", type_name); + subtype = g_type_register_static (GST_TYPE_NV_BASE_ENC, + type_name, &type_info, 0); +done: g_free (type_name); + return subtype; } diff --git a/sys/nvcodec/gstnvbaseenc.h b/sys/nvcodec/gstnvbaseenc.h index 72be2fcc02..b03d504c7b 100644 --- a/sys/nvcodec/gstnvbaseenc.h +++ b/sys/nvcodec/gstnvbaseenc.h @@ -128,13 +128,8 @@ typedef struct { G_GNUC_INTERNAL GType gst_nv_base_enc_get_type (void); -void gst_nv_base_enc_register (GstPlugin * plugin, - GType type, - const char * codec, - guint device_id, - guint rank, - GstCaps * sink_caps, - GstCaps * src_caps); +GType gst_nv_base_enc_register (const char * codec, + guint device_id); #endif /* __GST_NV_BASE_ENC_H_INCLUDED__ */ diff --git a/sys/nvcodec/gstnvenc.c b/sys/nvcodec/gstnvenc.c index e08b611a90..49cff2e03c 100644 --- a/sys/nvcodec/gstnvenc.c +++ b/sys/nvcodec/gstnvenc.c @@ -593,8 +593,8 @@ gst_nvenc_get_supported_codec_profiles (gpointer enc, GUID codec_id) } static void -gst_nv_enc_register (GstPlugin * plugin, GType type, GUID codec_id, - const gchar * codec, guint rank, gint device_count) +gst_nv_enc_register (GstPlugin * plugin, GUID codec_id, const gchar * codec, + guint rank, gint device_count) { gint i; @@ -730,9 +730,15 @@ gst_nv_enc_register (GstPlugin * plugin, GType type, GUID codec_id, cuda_free: CuCtxDestroy (cuda_ctx); - if (sink_templ && src_templ) - gst_nv_base_enc_register (plugin, type, codec, i, rank, sink_templ, - src_templ); + if (sink_templ && src_templ) { + if (gst_nvenc_cmp_guid (codec_id, NV_ENC_CODEC_H264_GUID)) { + gst_nv_h264_enc_register (plugin, i, rank, sink_templ, src_templ); + } else if (gst_nvenc_cmp_guid (codec_id, NV_ENC_CODEC_HEVC_GUID)) { + gst_nv_h265_enc_register (plugin, i, rank, sink_templ, src_templ); + } else { + g_assert_not_reached (); + } + } gst_clear_caps (&sink_templ); gst_clear_caps (&src_templ); @@ -821,10 +827,10 @@ gst_nvenc_plugin_init (GstPlugin * plugin) return; } - gst_nv_enc_register (plugin, GST_TYPE_NV_H264_ENC, - NV_ENC_CODEC_H264_GUID, "h264", GST_RANK_PRIMARY * 2, dev_count); - gst_nv_enc_register (plugin, GST_TYPE_NV_H265_ENC, - NV_ENC_CODEC_HEVC_GUID, "h265", GST_RANK_PRIMARY * 2, dev_count); + gst_nv_enc_register (plugin, NV_ENC_CODEC_H264_GUID, + "h264", GST_RANK_PRIMARY * 2, dev_count); + gst_nv_enc_register (plugin, NV_ENC_CODEC_HEVC_GUID, + "h265", GST_RANK_PRIMARY * 2, dev_count); } else { GST_ERROR ("too old driver, could not load api vtable"); } diff --git a/sys/nvcodec/gstnvh264enc.c b/sys/nvcodec/gstnvh264enc.c index 78b7bb38ff..4a900c66d7 100644 --- a/sys/nvcodec/gstnvh264enc.c +++ b/sys/nvcodec/gstnvh264enc.c @@ -27,11 +27,17 @@ #include +typedef struct +{ + GstCaps *sink_caps; + GstCaps *src_caps; + gboolean is_default; +} GstNvH264EncClassData; + GST_DEBUG_CATEGORY_STATIC (gst_nv_h264_enc_debug); #define GST_CAT_DEFAULT gst_nv_h264_enc_debug -#define parent_class gst_nv_h264_enc_parent_class -G_DEFINE_TYPE (GstNvH264Enc, gst_nv_h264_enc, GST_TYPE_NV_BASE_ENC); +static GstElementClass *parent_class = NULL; static gboolean gst_nv_h264_enc_open (GstVideoEncoder * enc); static gboolean gst_nv_h264_enc_close (GstVideoEncoder * enc); @@ -48,12 +54,16 @@ static void gst_nv_h264_enc_get_property (GObject * object, guint prop_id, static void gst_nv_h264_enc_finalize (GObject * obj); static void -gst_nv_h264_enc_class_init (GstNvH264EncClass * klass) +gst_nv_h264_enc_class_init (GstNvH264EncClass * klass, gpointer data) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstVideoEncoderClass *videoenc_class = GST_VIDEO_ENCODER_CLASS (klass); GstNvBaseEncClass *nvenc_class = GST_NV_BASE_ENC_CLASS (klass); + GstNvH264EncClassData *cdata = (GstNvH264EncClassData *) data; + gchar *long_name; + + parent_class = g_type_class_peek_parent (klass); gobject_class->set_property = gst_nv_h264_enc_set_property; gobject_class->get_property = gst_nv_h264_enc_get_property; @@ -67,16 +77,33 @@ gst_nv_h264_enc_class_init (GstNvH264EncClass * klass) nvenc_class->set_src_caps = gst_nv_h264_enc_set_src_caps; nvenc_class->set_pic_params = gst_nv_h264_enc_set_pic_params; - gst_element_class_set_static_metadata (element_class, - "NVENC H.264 Video Encoder", + if (cdata->is_default) + long_name = g_strdup ("NVENC H.264 Video Encoder"); + else + long_name = g_strdup_printf ("NVENC H.264 Video Encoder with device %d", + nvenc_class->cuda_device_id); + + gst_element_class_set_metadata (element_class, long_name, "Codec/Encoder/Video/Hardware", "Encode H.264 video streams using NVIDIA's hardware-accelerated NVENC encoder API", "Tim-Philipp Müller , " "Matthew Waters , " "Seungha Yang "); + g_free (long_name); GST_DEBUG_CATEGORY_INIT (gst_nv_h264_enc_debug, "nvh264enc", 0, "Nvidia H.264 encoder"); + + 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)); + + gst_caps_unref (cdata->sink_caps); + gst_caps_unref (cdata->src_caps); + g_free (cdata); } static void @@ -87,7 +114,7 @@ gst_nv_h264_enc_init (GstNvH264Enc * nvenc) static void gst_nv_h264_enc_finalize (GObject * obj) { - G_OBJECT_CLASS (gst_nv_h264_enc_parent_class)->finalize (obj); + G_OBJECT_CLASS (parent_class)->finalize (obj); } static gboolean @@ -95,7 +122,7 @@ gst_nv_h264_enc_open (GstVideoEncoder * enc) { GstNvBaseEnc *base = GST_NV_BASE_ENC (enc); - if (!GST_VIDEO_ENCODER_CLASS (gst_nv_h264_enc_parent_class)->open (enc)) + if (!GST_VIDEO_ENCODER_CLASS (parent_class)->open (enc)) return FALSE; /* Check if H.264 is supported */ @@ -122,7 +149,7 @@ gst_nv_h264_enc_open (GstVideoEncoder * enc) static gboolean gst_nv_h264_enc_close (GstVideoEncoder * enc) { - return GST_VIDEO_ENCODER_CLASS (gst_nv_h264_enc_parent_class)->close (enc); + return GST_VIDEO_ENCODER_CLASS (parent_class)->close (enc); } static gboolean @@ -214,7 +241,7 @@ no_peer: static gboolean gst_nv_h264_enc_set_src_caps (GstNvBaseEnc * nvenc, GstVideoCodecState * state) { - GstNvH264Enc *h264enc = GST_NV_H264_ENC (nvenc); + GstNvH264Enc *h264enc = (GstNvH264Enc *) nvenc; GstVideoCodecState *out_state; GstStructure *s; GstCaps *out_caps; @@ -247,7 +274,7 @@ static gboolean gst_nv_h264_enc_set_encoder_config (GstNvBaseEnc * nvenc, GstVideoCodecState * state, NV_ENC_CONFIG * config) { - GstNvH264Enc *h264enc = GST_NV_H264_ENC (nvenc); + GstNvH264Enc *h264enc = (GstNvH264Enc *) nvenc; GstCaps *allowed_caps, *template_caps; GUID selected_profile = NV_ENC_CODEC_PROFILE_AUTOSELECT_GUID; int level_idc = NV_ENC_LEVEL_AUTOSELECT; @@ -376,3 +403,57 @@ gst_nv_h264_enc_get_property (GObject * object, guint prop_id, GValue * value, break; } } + +void +gst_nv_h264_enc_register (GstPlugin * plugin, guint device_id, guint rank, + GstCaps * sink_caps, GstCaps * src_caps) +{ + GType parent_type; + GType type; + gchar *type_name; + gchar *feature_name; + GstNvH264EncClassData *cdata; + gboolean is_default = TRUE; + GTypeInfo type_info = { + sizeof (GstNvH264EncClass), + NULL, + NULL, + (GClassInitFunc) gst_nv_h264_enc_class_init, + NULL, + NULL, + sizeof (GstNvH264Enc), + 0, + (GInstanceInitFunc) gst_nv_h264_enc_init, + }; + + parent_type = gst_nv_base_enc_register ("H264", device_id); + + cdata = g_new0 (GstNvH264EncClassData, 1); + cdata->sink_caps = gst_caps_ref (sink_caps); + cdata->src_caps = gst_caps_ref (src_caps); + type_info.class_data = cdata; + + type_name = g_strdup ("GstNvH264Enc"); + feature_name = g_strdup ("nvh264enc"); + + if (g_type_from_name (type_name) != 0) { + g_free (type_name); + g_free (feature_name); + type_name = g_strdup_printf ("GstNvH264Device%dEnc", device_id); + feature_name = g_strdup_printf ("nvh264device%denc", device_id); + is_default = FALSE; + } + + cdata->is_default = is_default; + type = g_type_register_static (parent_type, type_name, &type_info, 0); + + /* make lower rank than default device */ + if (rank > 0 && !is_default) + rank--; + + if (!gst_element_register (plugin, feature_name, rank, type)) + GST_WARNING ("Failed to register plugin '%s'", type_name); + + g_free (type_name); + g_free (feature_name); +} diff --git a/sys/nvcodec/gstnvh264enc.h b/sys/nvcodec/gstnvh264enc.h index 3ca1b4650f..c7722e0fbb 100644 --- a/sys/nvcodec/gstnvh264enc.h +++ b/sys/nvcodec/gstnvh264enc.h @@ -22,19 +22,6 @@ #include "gstnvbaseenc.h" -#define GST_TYPE_NV_H264_ENC \ - (gst_nv_h264_enc_get_type()) -#define GST_NV_H264_ENC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_NV_H264_ENC,GstNvH264Enc)) -#define GST_NV_H264_ENC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_NV_H264_ENC,GstNvH264EncClass)) -#define GST_NV_H264_ENC_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_NV_H264_ENC,GstNvH264EncClass)) -#define GST_IS_NV_H264_ENC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_NV_H264_ENC)) -#define GST_IS_NV_H264_ENC_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_NV_H264_ENC)) - typedef struct { GstNvBaseEnc base_nvenc; } GstNvH264Enc; @@ -44,6 +31,11 @@ typedef struct { } GstNvH264EncClass; G_GNUC_INTERNAL -GType gst_nv_h264_enc_get_type (void); +void gst_nv_h264_enc_register (GstPlugin * plugin, + guint device_id, + guint rank, + GstCaps * sink_caps, + GstCaps * src_caps); + #endif /* __GST_NV_H264_ENC_H_INCLUDED__ */ diff --git a/sys/nvcodec/gstnvh265enc.c b/sys/nvcodec/gstnvh265enc.c index 385e7ee404..0779a182c6 100644 --- a/sys/nvcodec/gstnvh265enc.c +++ b/sys/nvcodec/gstnvh265enc.c @@ -29,11 +29,17 @@ #include +typedef struct +{ + GstCaps *sink_caps; + GstCaps *src_caps; + gboolean is_default; +} GstNvH265EncClassData; + GST_DEBUG_CATEGORY_STATIC (gst_nv_h265_enc_debug); #define GST_CAT_DEFAULT gst_nv_h265_enc_debug -#define parent_class gst_nv_h265_enc_parent_class -G_DEFINE_TYPE (GstNvH265Enc, gst_nv_h265_enc, GST_TYPE_NV_BASE_ENC); +static GstElementClass *parent_class = NULL; static gboolean gst_nv_h265_enc_open (GstVideoEncoder * enc); static gboolean gst_nv_h265_enc_close (GstVideoEncoder * enc); @@ -51,12 +57,16 @@ static void gst_nv_h265_enc_get_property (GObject * object, guint prop_id, static void gst_nv_h265_enc_finalize (GObject * obj); static void -gst_nv_h265_enc_class_init (GstNvH265EncClass * klass) +gst_nv_h265_enc_class_init (GstNvH265EncClass * klass, gpointer data) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstVideoEncoderClass *videoenc_class = GST_VIDEO_ENCODER_CLASS (klass); GstNvBaseEncClass *nvenc_class = GST_NV_BASE_ENC_CLASS (klass); + GstNvH265EncClassData *cdata = (GstNvH265EncClassData *) data; + gchar *long_name; + + parent_class = g_type_class_peek_parent (klass); gobject_class->set_property = gst_nv_h265_enc_set_property; gobject_class->get_property = gst_nv_h265_enc_get_property; @@ -71,16 +81,33 @@ gst_nv_h265_enc_class_init (GstNvH265EncClass * klass) nvenc_class->set_src_caps = gst_nv_h265_enc_set_src_caps; nvenc_class->set_pic_params = gst_nv_h265_enc_set_pic_params; - gst_element_class_set_static_metadata (element_class, - "NVENC HEVC Video Encoder", + if (cdata->is_default) + long_name = g_strdup ("NVENC HEVC Video Encoder"); + else + long_name = g_strdup_printf ("NVENC HEVC Video Encoder with device %d", + nvenc_class->cuda_device_id); + + gst_element_class_set_metadata (element_class, long_name, "Codec/Encoder/Video/Hardware", "Encode HEVC video streams using NVIDIA's hardware-accelerated NVENC encoder API", "Tim-Philipp Müller , " "Matthew Waters , " "Seungha Yang "); + g_free (long_name); GST_DEBUG_CATEGORY_INIT (gst_nv_h265_enc_debug, "nvh265enc", 0, "Nvidia HEVC encoder"); + + 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)); + + gst_caps_unref (cdata->sink_caps); + gst_caps_unref (cdata->src_caps); + g_free (cdata); } static void @@ -91,7 +118,7 @@ gst_nv_h265_enc_init (GstNvH265Enc * nvenc) static void gst_nv_h265_enc_finalize (GObject * obj) { - G_OBJECT_CLASS (gst_nv_h265_enc_parent_class)->finalize (obj); + G_OBJECT_CLASS (parent_class)->finalize (obj); } static gboolean @@ -99,7 +126,7 @@ gst_nv_h265_enc_open (GstVideoEncoder * enc) { GstNvBaseEnc *base = GST_NV_BASE_ENC (enc); - if (!GST_VIDEO_ENCODER_CLASS (gst_nv_h265_enc_parent_class)->open (enc)) + if (!GST_VIDEO_ENCODER_CLASS (parent_class)->open (enc)) return FALSE; /* Check if HEVC is supported */ @@ -126,7 +153,7 @@ gst_nv_h265_enc_open (GstVideoEncoder * enc) static gboolean gst_nv_h265_enc_close (GstVideoEncoder * enc) { - return GST_VIDEO_ENCODER_CLASS (gst_nv_h265_enc_parent_class)->close (enc); + return GST_VIDEO_ENCODER_CLASS (parent_class)->close (enc); } static void @@ -148,11 +175,11 @@ gst_nv_h265_enc_clear_stream_data (GstNvH265Enc * h265enc) static gboolean gst_nv_h265_enc_stop (GstVideoEncoder * enc) { - GstNvH265Enc *h265enc = GST_NV_H265_ENC (enc); + GstNvH265Enc *h265enc = (GstNvH265Enc *) enc; gst_nv_h265_enc_clear_stream_data (h265enc); - return GST_VIDEO_ENCODER_CLASS (gst_nv_h265_enc_parent_class)->stop (enc); + return GST_VIDEO_ENCODER_CLASS (parent_class)->stop (enc); } static gboolean @@ -198,7 +225,7 @@ gst_nv_h265_enc_set_level_tier_and_profile (GstNvH265Enc * nvenc, static gboolean gst_nv_h265_enc_set_src_caps (GstNvBaseEnc * nvenc, GstVideoCodecState * state) { - GstNvH265Enc *h265enc = GST_NV_H265_ENC (nvenc); + GstNvH265Enc *h265enc = (GstNvH265Enc *) nvenc; GstVideoCodecState *out_state; GstStructure *s; GstCaps *out_caps; @@ -345,7 +372,7 @@ static gboolean gst_nv_h265_enc_set_encoder_config (GstNvBaseEnc * nvenc, GstVideoCodecState * state, NV_ENC_CONFIG * config) { - GstNvH265Enc *h265enc = GST_NV_H265_ENC (nvenc); + GstNvH265Enc *h265enc = (GstNvH265Enc *) nvenc; GstCaps *allowed_caps, *template_caps; GUID selected_profile = NV_ENC_CODEC_PROFILE_AUTOSELECT_GUID; int level_idc = NV_ENC_LEVEL_AUTOSELECT; @@ -493,7 +520,7 @@ static gboolean gst_nv_h265_enc_set_pic_params (GstNvBaseEnc * enc, GstVideoCodecFrame * frame, NV_ENC_PIC_PARAMS * pic_params) { - GstNvH265Enc *h265enc = GST_NV_H265_ENC (enc); + GstNvH265Enc *h265enc = (GstNvH265Enc *) enc; /* encode whole picture in one single slice */ pic_params->codecPicParams.hevcPicParams.sliceMode = 0; @@ -530,3 +557,57 @@ gst_nv_h265_enc_get_property (GObject * object, guint prop_id, GValue * value, break; } } + +void +gst_nv_h265_enc_register (GstPlugin * plugin, guint device_id, guint rank, + GstCaps * sink_caps, GstCaps * src_caps) +{ + GType parent_type; + GType type; + gchar *type_name; + gchar *feature_name; + GstNvH265EncClassData *cdata; + gboolean is_default = TRUE; + GTypeInfo type_info = { + sizeof (GstNvH265EncClass), + NULL, + NULL, + (GClassInitFunc) gst_nv_h265_enc_class_init, + NULL, + NULL, + sizeof (GstNvH265Enc), + 0, + (GInstanceInitFunc) gst_nv_h265_enc_init, + }; + + parent_type = gst_nv_base_enc_register ("H265", device_id); + + cdata = g_new0 (GstNvH265EncClassData, 1); + cdata->sink_caps = gst_caps_ref (sink_caps); + cdata->src_caps = gst_caps_ref (src_caps); + type_info.class_data = cdata; + + type_name = g_strdup ("GstNvH265Enc"); + feature_name = g_strdup ("nvh265enc"); + + if (g_type_from_name (type_name) != 0) { + g_free (type_name); + g_free (feature_name); + type_name = g_strdup_printf ("GstNvH265Device%dEnc", device_id); + feature_name = g_strdup_printf ("nvh265device%denc", device_id); + is_default = FALSE; + } + + cdata->is_default = is_default; + type = g_type_register_static (parent_type, type_name, &type_info, 0); + + /* make lower rank than default device */ + if (rank > 0 && !is_default) + rank--; + + if (!gst_element_register (plugin, feature_name, rank, type)) + GST_WARNING ("Failed to register plugin '%s'", type_name); + + g_free (type_name); + g_free (feature_name); +} diff --git a/sys/nvcodec/gstnvh265enc.h b/sys/nvcodec/gstnvh265enc.h index 98e54c19c0..bb8dbeb8f6 100644 --- a/sys/nvcodec/gstnvh265enc.h +++ b/sys/nvcodec/gstnvh265enc.h @@ -23,19 +23,6 @@ #include "gstnvbaseenc.h" -#define GST_TYPE_NV_H265_ENC \ - (gst_nv_h265_enc_get_type()) -#define GST_NV_H265_ENC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_NV_H265_ENC,GstNvH265Enc)) -#define GST_NV_H265_ENC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_NV_H265_ENC,GstNvH265EncClass)) -#define GST_NV_H265_ENC_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_NV_H265_ENC,GstNvH265EncClass)) -#define GST_IS_NV_H265_ENC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_NV_H265_ENC)) -#define GST_IS_NV_H265_ENC_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_NV_H265_ENC)) - typedef struct { GstNvBaseEnc base_nvenc; @@ -48,6 +35,10 @@ typedef struct { } GstNvH265EncClass; G_GNUC_INTERNAL -GType gst_nv_h265_enc_get_type (void); +void gst_nv_h265_enc_register (GstPlugin * plugin, + guint device_id, + guint rank, + GstCaps * sink_caps, + GstCaps * src_caps); #endif /* __GST_NV_HEVC_ENC_H_INCLUDED__ */