mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 12:32:29 +00:00
v4l2videodec: Simplify sub-instanciation mechanism
Simplify sub-instanciation by defining an absract type and using subtype class and instance init callback. This also fixes a bug where the template pads get initialized too late. https://bugzilla.gnome.org/show_bug.cgi?id=727925
This commit is contained in:
parent
e06c9f7fce
commit
f7d34bd237
2 changed files with 44 additions and 73 deletions
|
@ -37,9 +37,6 @@
|
|||
|
||||
#define DEFAULT_PROP_DEVICE "/dev/video0"
|
||||
|
||||
#define V4L2_VIDEO_DEC_QUARK \
|
||||
g_quark_from_static_string("gst-v4l2-video-dec-info")
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_v4l2_video_dec_debug);
|
||||
#define GST_CAT_DEFAULT gst_v4l2_video_dec_debug
|
||||
|
||||
|
@ -50,7 +47,7 @@ typedef struct
|
|||
gchar *device;
|
||||
GstCaps *sink_caps;
|
||||
GstCaps *src_caps;
|
||||
} Gstv4l2VideoDecQData;
|
||||
} GstV4l2VideoDecCData;
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -59,39 +56,9 @@ enum
|
|||
PROP_CAPTURE_IO_MODE,
|
||||
};
|
||||
|
||||
static void gst_v4l2_video_dec_class_init (GstV4l2VideoDecClass * klass);
|
||||
static void gst_v4l2_video_dec_init (GstV4l2VideoDec * self, gpointer g_class);
|
||||
static void gst_v4l2_video_dec_base_init (gpointer g_class);
|
||||
|
||||
static GstVideoDecoderClass *parent_class = NULL;
|
||||
|
||||
GType
|
||||
gst_v4l2_video_dec_get_type (void)
|
||||
{
|
||||
static volatile gsize type = 0;
|
||||
|
||||
if (g_once_init_enter (&type)) {
|
||||
GType _type;
|
||||
static const GTypeInfo info = {
|
||||
sizeof (GstV4l2VideoDecClass),
|
||||
gst_v4l2_video_dec_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_v4l2_video_dec_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstV4l2VideoDec),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_v4l2_video_dec_init,
|
||||
NULL
|
||||
};
|
||||
|
||||
_type = g_type_register_static (GST_TYPE_VIDEO_DECODER, "GstV4l2VideoDec",
|
||||
&info, 0);
|
||||
|
||||
g_once_init_leave (&type, _type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
#define gst_v4l2_video_dec_parent_class parent_class
|
||||
G_DEFINE_ABSTRACT_TYPE (GstV4l2VideoDec, gst_v4l2_video_dec,
|
||||
GST_TYPE_VIDEO_DECODER);
|
||||
|
||||
static void
|
||||
gst_v4l2_video_dec_set_property (GObject * object,
|
||||
|
@ -711,52 +678,33 @@ gst_v4l2_video_dec_finalize (GObject * object)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_v4l2_video_dec_base_init (gpointer g_class)
|
||||
gst_v4l2_video_dec_init (GstV4l2VideoDec * self)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
||||
Gstv4l2VideoDecQData *qdata;
|
||||
GstPadTemplate *templ;
|
||||
|
||||
qdata = g_type_get_qdata (G_TYPE_FROM_CLASS (g_class), V4L2_VIDEO_DEC_QUARK);
|
||||
if (!qdata)
|
||||
return;
|
||||
|
||||
templ =
|
||||
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
|
||||
qdata->sink_caps);
|
||||
gst_element_class_add_pad_template (element_class, templ);
|
||||
|
||||
templ =
|
||||
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
|
||||
qdata->src_caps);
|
||||
gst_element_class_add_pad_template (element_class, templ);
|
||||
/* V4L2 object are created in subinstance_init */
|
||||
}
|
||||
|
||||
static void
|
||||
gst_v4l2_video_dec_init (GstV4l2VideoDec * self, gpointer g_class)
|
||||
gst_v4l2_video_dec_subinstance_init (GTypeInstance * instance, gpointer g_class)
|
||||
{
|
||||
GstVideoDecoder *decoder = (GstVideoDecoder *) self;
|
||||
Gstv4l2VideoDecQData *qdata;
|
||||
|
||||
qdata = g_type_get_qdata (G_TYPE_FROM_CLASS (g_class), V4L2_VIDEO_DEC_QUARK);
|
||||
if (!qdata)
|
||||
return;
|
||||
GstV4l2VideoDecClass *klass = GST_V4L2_VIDEO_DEC_CLASS (g_class);
|
||||
GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (instance);
|
||||
GstVideoDecoder *decoder = GST_VIDEO_DECODER (instance);
|
||||
|
||||
gst_video_decoder_set_packetized (decoder, TRUE);
|
||||
|
||||
self->v4l2output = gst_v4l2_object_new (GST_ELEMENT (self),
|
||||
V4L2_BUF_TYPE_VIDEO_OUTPUT, qdata->device,
|
||||
V4L2_BUF_TYPE_VIDEO_OUTPUT, klass->default_device,
|
||||
gst_v4l2_get_output, gst_v4l2_set_output, NULL);
|
||||
self->v4l2output->no_initial_format = TRUE;
|
||||
self->v4l2output->keep_aspect = FALSE;
|
||||
|
||||
self->v4l2capture = gst_v4l2_object_new (GST_ELEMENT (self),
|
||||
V4L2_BUF_TYPE_VIDEO_CAPTURE, qdata->device,
|
||||
V4L2_BUF_TYPE_VIDEO_CAPTURE, klass->default_device,
|
||||
gst_v4l2_get_input, gst_v4l2_set_input, NULL);
|
||||
self->v4l2capture->no_initial_format = TRUE;
|
||||
self->v4l2output->keep_aspect = FALSE;
|
||||
|
||||
g_object_set (self, "device", qdata->device, NULL);
|
||||
g_object_set (self, "device", klass->default_device, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -825,6 +773,26 @@ gst_v4l2_video_dec_class_init (GstV4l2VideoDecClass * klass)
|
|||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_v4l2_video_dec_subclass_init (gpointer g_class, gpointer data)
|
||||
{
|
||||
GstV4l2VideoDecClass *klass = GST_V4L2_VIDEO_DEC_CLASS (g_class);
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
||||
GstV4l2VideoDecCData *cdata = data;
|
||||
|
||||
klass->default_device = cdata->device;
|
||||
|
||||
/* Note: gst_pad_template_new() take the floating ref from the caps */
|
||||
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));
|
||||
|
||||
g_free (cdata);
|
||||
}
|
||||
|
||||
/* Probing functions */
|
||||
static GstCaps *
|
||||
gst_v4l2_video_dec_probe_caps (gchar * device, gint video_fd,
|
||||
|
@ -911,24 +879,25 @@ gst_v4l2_video_dec_register (GstPlugin * plugin)
|
|||
GTypeInfo type_info = { 0, };
|
||||
GType type, subtype;
|
||||
gchar *type_name;
|
||||
Gstv4l2VideoDecQData *qdata;
|
||||
GstV4l2VideoDecCData *cdata;
|
||||
|
||||
cdata = g_new0 (GstV4l2VideoDecCData, 1);
|
||||
cdata->device = g_strdup (device);
|
||||
cdata->sink_caps = gst_caps_ref (sink_caps);
|
||||
cdata->src_caps = gst_caps_ref (src_caps);
|
||||
|
||||
type = gst_v4l2_video_dec_get_type ();
|
||||
g_type_query (type, &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_v4l2_video_dec_subclass_init;
|
||||
type_info.class_data = cdata;
|
||||
type_info.instance_init = gst_v4l2_video_dec_subinstance_init;
|
||||
|
||||
type_name = g_strdup_printf ("v4l2video%ddec", i);
|
||||
subtype = g_type_register_static (type, type_name, &type_info, 0);
|
||||
|
||||
qdata = g_new0 (Gstv4l2VideoDecQData, 1);
|
||||
qdata->device = g_strdup (device);
|
||||
qdata->sink_caps = gst_caps_ref (sink_caps);
|
||||
qdata->src_caps = gst_caps_ref (src_caps);
|
||||
|
||||
g_type_set_qdata (subtype, V4L2_VIDEO_DEC_QUARK, qdata);
|
||||
|
||||
gst_element_register (plugin, type_name, GST_RANK_PRIMARY + 1, subtype);
|
||||
|
||||
g_free (type_name);
|
||||
|
|
|
@ -72,6 +72,8 @@ struct _GstV4l2VideoDec
|
|||
struct _GstV4l2VideoDecClass
|
||||
{
|
||||
GstVideoDecoderClass parent_class;
|
||||
|
||||
gchar *default_device;
|
||||
};
|
||||
|
||||
GType gst_v4l2_video_dec_get_type (void);
|
||||
|
|
Loading…
Reference in a new issue