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.
This commit is contained in:
Seungha Yang 2019-09-03 18:46:30 +09:00
parent f402cb07f9
commit b3b723462e
7 changed files with 230 additions and 134 deletions

View file

@ -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;
}

View file

@ -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__ */

View file

@ -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");
}

View file

@ -27,11 +27,17 @@
#include <string.h>
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 <tim@centricular.com>, "
"Matthew Waters <matthew@centricular.com>, "
"Seungha Yang <seungha.yang@navercorp.com>");
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);
}

View file

@ -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__ */

View file

@ -29,11 +29,17 @@
#include <string.h>
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 <tim@centricular.com>, "
"Matthew Waters <matthew@centricular.com>, "
"Seungha Yang <pudding8757@gmail.com>");
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);
}

View file

@ -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__ */