From: Wim Taymans Date: Tue, 26 Jul 2011 10:21:38 +0000 (+0200) Subject: basesink: make it easy to override the pad query X-Git-Tag: RELEASE-0.11.0~17 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=32841d258d91ba45dd05c906049ef396fbb924fb;p=platform%2Fupstream%2Fgstreamer.git basesink: make it easy to override the pad query 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 --- diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c index 0d7e173..426c432 100644 --- a/libs/gst/base/gstbasesink.c +++ b/libs/gst/base/gstbasesink.c @@ -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) { diff --git a/libs/gst/base/gstbasesink.h b/libs/gst/base/gstbasesink.h index c651a44..923f33a 100644 --- a/libs/gst/base/gstbasesink.h +++ b/libs/gst/base/gstbasesink.h @@ -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); diff --git a/plugins/elements/gstfilesink.c b/plugins/elements/gstfilesink.c index c5add2b..6935c01 100644 --- a/plugins/elements/gstfilesink.c +++ b/plugins/elements/gstfilesink.c @@ -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