v4l2videodec: Simplify sub-instanciation mechanism
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Sun, 16 Mar 2014 10:38:07 +0000 (11:38 +0100)
committerNicolas Dufresne <nicolas.dufresne@collabora.co.uk>
Sun, 4 May 2014 03:11:34 +0000 (23:11 -0400)
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

sys/v4l2/gstv4l2videodec.c
sys/v4l2/gstv4l2videodec.h

index 50a5110..2594e8c 100644 (file)
@@ -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);
index 6ff2e73..48750a0 100644 (file)
@@ -72,6 +72,8 @@ struct _GstV4l2VideoDec
 struct _GstV4l2VideoDecClass
 {
   GstVideoDecoderClass parent_class;
+
+  gchar *default_device;
 };
 
 GType gst_v4l2_video_dec_get_type (void);