basesink: make it easy to override the pad query
authorWim Taymans <wim.taymans@collabora.co.uk>
Tue, 26 Jul 2011 10:21:38 +0000 (12:21 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Tue, 26 Jul 2011 10:21:38 +0000 (12:21 +0200)
Add a vmethod to handle the pad query.
Install a default handler for the pad query.
Add a vmethod to setup the allocation properties.
Use the new query function in filesink

libs/gst/base/gstbasesink.c
libs/gst/base/gstbasesink.h
plugins/elements/gstfilesink.c

index 0d7e173..426c432 100644 (file)
@@ -364,7 +364,7 @@ static void gst_base_sink_get_property (GObject * object, guint prop_id,
 
 static gboolean gst_base_sink_send_event (GstElement * element,
     GstEvent * event);
-static gboolean gst_base_sink_query (GstElement * element, GstQuery * query);
+static gboolean default_element_query (GstElement * element, GstQuery * query);
 static const GstQueryType *gst_base_sink_get_query_types (GstElement * element);
 
 static GstCaps *gst_base_sink_get_caps (GstBaseSink * sink, GstCaps * caps);
@@ -383,6 +383,7 @@ static gboolean gst_base_sink_default_prepare_seek_segment (GstBaseSink * sink,
 static GstStateChangeReturn gst_base_sink_change_state (GstElement * element,
     GstStateChange transition);
 
+static gboolean gst_base_sink_sink_query (GstPad * pad, GstQuery * query);
 static GstFlowReturn gst_base_sink_chain (GstPad * pad, GstBuffer * buffer);
 static GstFlowReturn gst_base_sink_chain_list (GstPad * pad,
     GstBufferList * list);
@@ -393,6 +394,8 @@ static gboolean gst_base_sink_pad_activate_push (GstPad * pad, gboolean active);
 static gboolean gst_base_sink_pad_activate_pull (GstPad * pad, gboolean active);
 static gboolean gst_base_sink_event (GstPad * pad, GstEvent * event);
 
+static gboolean default_sink_query (GstBaseSink * sink, GstQuery * query);
+
 static gboolean gst_base_sink_negotiate_pull (GstBaseSink * basesink);
 static GstCaps *gst_base_sink_pad_getcaps (GstPad * pad, GstCaps * filter);
 static void gst_base_sink_pad_fixate (GstPad * pad, GstCaps * caps);
@@ -544,7 +547,7 @@ gst_base_sink_class_init (GstBaseSinkClass * klass)
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_base_sink_change_state);
   gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_base_sink_send_event);
-  gstelement_class->query = GST_DEBUG_FUNCPTR (gst_base_sink_query);
+  gstelement_class->query = GST_DEBUG_FUNCPTR (default_element_query);
   gstelement_class->get_query_types =
       GST_DEBUG_FUNCPTR (gst_base_sink_get_query_types);
 
@@ -553,6 +556,7 @@ gst_base_sink_class_init (GstBaseSinkClass * klass)
   klass->get_times = GST_DEBUG_FUNCPTR (gst_base_sink_get_times);
   klass->activate_pull =
       GST_DEBUG_FUNCPTR (gst_base_sink_default_activate_pull);
+  klass->query = GST_DEBUG_FUNCPTR (default_sink_query);
 
   /* Registering debug symbols for function pointers */
   GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_getcaps);
@@ -644,6 +648,7 @@ gst_base_sink_init (GstBaseSink * basesink, gpointer g_class)
       gst_base_sink_pad_activate_push);
   gst_pad_set_activatepull_function (basesink->sinkpad,
       gst_base_sink_pad_activate_pull);
+  gst_pad_set_query_function (basesink->sinkpad, gst_base_sink_sink_query);
   gst_pad_set_event_function (basesink->sinkpad, gst_base_sink_event);
   gst_pad_set_chain_function (basesink->sinkpad, gst_base_sink_chain);
   gst_pad_set_chain_list_function (basesink->sinkpad, gst_base_sink_chain_list);
@@ -4735,7 +4740,7 @@ gst_base_sink_get_query_types (GstElement * element)
 }
 
 static gboolean
-gst_base_sink_query (GstElement * element, GstQuery * query)
+default_element_query (GstElement * element, GstQuery * query)
 {
   gboolean res = FALSE;
 
@@ -4860,6 +4865,56 @@ gst_base_sink_query (GstElement * element, GstQuery * query)
   return res;
 }
 
+
+static gboolean
+default_sink_query (GstBaseSink * basesink, GstQuery * query)
+{
+  gboolean res;
+  GstBaseSinkClass *bclass;
+
+  bclass = GST_BASE_SINK_GET_CLASS (basesink);
+
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_ALLOCATION:
+    {
+      if (bclass->setup_allocation)
+        res = bclass->setup_allocation (basesink, query);
+      else
+        res = FALSE;
+      break;
+    }
+    default:
+      res = gst_pad_query_default (basesink->sinkpad, query);
+      break;
+  }
+  return res;
+}
+
+static gboolean
+gst_base_sink_sink_query (GstPad * pad, GstQuery * query)
+{
+  GstBaseSink *basesink;
+  GstBaseSinkClass *bclass;
+  gboolean res;
+
+  basesink = GST_BASE_SINK_CAST (gst_pad_get_parent (pad));
+  if (G_UNLIKELY (basesink == NULL)) {
+    gst_query_unref (query);
+    return FALSE;
+  }
+
+  bclass = GST_BASE_SINK_GET_CLASS (basesink);
+
+  if (bclass->query)
+    res = bclass->query (basesink, query);
+  else
+    res = FALSE;
+
+  gst_object_unref (basesink);
+
+  return res;
+}
+
 static GstStateChangeReturn
 gst_base_sink_change_state (GstElement * element, GstStateChange transition)
 {
index c651a44..923f33a 100644 (file)
@@ -117,8 +117,17 @@ struct _GstBaseSink {
  * @parent_class: Element parent class
  * @get_caps: Called to get sink pad caps from the subclass
  * @set_caps: Notify subclass of changed caps
+ * @fixate: Only useful in pull mode, this vmethod will be called in response to
+ *     gst_pad_fixate_caps() being called on the sink pad. Implement if you have
+ *     ideas about what should be the default values for the caps you support.
+ * @activate_pull: Subclasses should override this when they can provide an
+ *     alternate method of spawning a thread to drive the pipeline in pull mode.
+ *     Should start or stop the pulling thread, depending on the value of the
+ *     "active" argument. Called after actually activating the sink pad in pull
+ *     mode. The default implementation starts a task on the sink pad.
  * @get_times: Called to get the start and end times for synchronising
  *     the passed buffer to the clock
+ * @setup_allocation: configure the allocation query
  * @start: Start processing. Ideal for opening resources in the subclass
  * @stop: Stop processing. Subclasses should use this to close resources.
  * @unlock: Unlock any pending access to the resource. Subclasses should
@@ -131,14 +140,6 @@ struct _GstBaseSink {
  *     correct moment if the #GstBaseSink has been set to sync to the clock.
  * @render_list: Same as @render but used whith buffer lists instead of
  *     buffers. Since: 0.10.24
- * @activate_pull: Subclasses should override this when they can provide an
- *     alternate method of spawning a thread to drive the pipeline in pull mode.
- *     Should start or stop the pulling thread, depending on the value of the
- *     "active" argument. Called after actually activating the sink pad in pull
- *     mode. The default implementation starts a task on the sink pad.
- * @fixate: Only useful in pull mode, this vmethod will be called in response to
- *     gst_pad_fixate_caps() being called on the sink pad. Implement if you have
- *     ideas about what should be the default values for the caps you support.
  *
  * Subclasses can override any of the available virtual methods or not, as
  * needed. At the minimum, the @render method should be overridden to
@@ -161,6 +162,9 @@ struct _GstBaseSinkClass {
   void          (*get_times)    (GstBaseSink *sink, GstBuffer *buffer,
                                  GstClockTime *start, GstClockTime *end);
 
+  /* setup allocation query */
+  gboolean      (*setup_allocation)   (GstBaseSink *sink, GstQuery *query);
+
   /* start and stop processing, ideal for opening/closing the resource */
   gboolean      (*start)        (GstBaseSink *sink);
   gboolean      (*stop)         (GstBaseSink *sink);
@@ -173,6 +177,9 @@ struct _GstBaseSinkClass {
    * set during unlock */
   gboolean      (*unlock_stop)  (GstBaseSink *sink);
 
+  /* notify subclass of query */
+  gboolean      (*query)        (GstBaseSink *sink, GstQuery *query);
+
   /* notify subclass of event, preroll buffer or real buffer */
   gboolean      (*event)        (GstBaseSink *sink, GstEvent *event);
 
index c5add2b..6935c01 100644 (file)
@@ -168,7 +168,7 @@ static gboolean gst_file_sink_do_seek (GstFileSink * filesink,
 static gboolean gst_file_sink_get_current_offset (GstFileSink * filesink,
     guint64 * p_pos);
 
-static gboolean gst_file_sink_query (GstPad * pad, GstQuery * query);
+static gboolean gst_file_sink_query (GstBaseSink * bsink, GstQuery * query);
 
 static void gst_file_sink_uri_handler_init (gpointer g_iface,
     gpointer iface_data);
@@ -229,6 +229,7 @@ gst_file_sink_class_init (GstFileSinkClass * klass)
 
   gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_file_sink_start);
   gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_file_sink_stop);
+  gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_file_sink_query);
   gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_file_sink_render);
   gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_file_sink_event);
 
@@ -241,12 +242,6 @@ gst_file_sink_class_init (GstFileSinkClass * klass)
 static void
 gst_file_sink_init (GstFileSink * filesink)
 {
-  GstPad *pad;
-
-  pad = GST_BASE_SINK_PAD (filesink);
-
-  gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_file_sink_query));
-
   filesink->filename = NULL;
   filesink->file = NULL;
   filesink->buffer_mode = DEFAULT_BUFFER_MODE;
@@ -449,36 +444,45 @@ close_failed:
 }
 
 static gboolean
-gst_file_sink_query (GstPad * pad, GstQuery * query)
+gst_file_sink_query (GstBaseSink * bsink, GstQuery * query)
 {
+  gboolean res;
   GstFileSink *self;
   GstFormat format;
 
-  self = GST_FILE_SINK (GST_PAD_PARENT (pad));
+  self = GST_FILE_SINK (bsink);
 
   switch (GST_QUERY_TYPE (query)) {
     case GST_QUERY_POSITION:
       gst_query_parse_position (query, &format, NULL);
+
       switch (format) {
         case GST_FORMAT_DEFAULT:
         case GST_FORMAT_BYTES:
           gst_query_set_position (query, GST_FORMAT_BYTES, self->current_pos);
-          return TRUE;
+          res = TRUE;
+          break;
         default:
-          return FALSE;
+          res = FALSE;
+          break;
       }
+      break;
 
     case GST_QUERY_FORMATS:
       gst_query_set_formats (query, 2, GST_FORMAT_DEFAULT, GST_FORMAT_BYTES);
-      return TRUE;
+      res = TRUE;
+      break;
 
     case GST_QUERY_URI:
       gst_query_set_uri (query, self->uri);
-      return TRUE;
+      res = TRUE;
+      break;
 
     default:
-      return gst_pad_query_default (pad, query);
+      res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
+      break;
   }
+  return res;
 }
 
 #ifdef HAVE_FSEEKO