mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
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:
parent
f402cb07f9
commit
b3b723462e
7 changed files with 230 additions and 134 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Loading…
Reference in a new issue