mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
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
This commit is contained in:
parent
36de9b92a1
commit
32841d258d
3 changed files with 91 additions and 25 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue