libs/gst/base/gstbasesink.h: New GstBaseSinkClass vmethod, activate_pull(), providing for a way to specialize the pro...

Original commit message from CVS:
2007-01-06  Andy Wingo  <wingo@pobox.com>

* libs/gst/base/gstbasesink.h: New GstBaseSinkClass vmethod,
activate_pull(), providing for a way to specialize the process of
spawning a thread to pull on the sink pad. There is a default
implementation.

* libs/gst/base/gstbasesink.c (gst_base_sink_pad_activate_pull)
(gst_base_sink_pad_activate_push, gst_base_sink_pad_activate)
(gst_base_sink_init): Renamed pad activation functions (inserting
"_pad" in their names). Refactor to use the new activate_pull
vmethod, as appropriate.
(gst_base_sink_class_init, gst_base_sink_activate_pull): Set the
default activate_pull function to start a task pulling from the
sink pad, as before.
This commit is contained in:
Andy Wingo 2007-01-06 17:18:03 +00:00
parent 77472ddbd7
commit 4518a5c652
4 changed files with 54 additions and 21 deletions

View file

@ -1,5 +1,19 @@
2007-01-06 Andy Wingo <wingo@pobox.com> 2007-01-06 Andy Wingo <wingo@pobox.com>
* libs/gst/base/gstbasesink.h: New GstBaseSinkClass vmethod,
activate_pull(), providing for a way to specialize the process of
spawning a thread to pull on the sink pad. There is a default
implementation.
* libs/gst/base/gstbasesink.c (gst_base_sink_pad_activate_pull)
(gst_base_sink_pad_activate_push, gst_base_sink_pad_activate)
(gst_base_sink_init): Renamed pad activation functions (inserting
"_pad" in their names). Refactor to use the new activate_pull
vmethod, as appropriate.
(gst_base_sink_class_init, gst_base_sink_activate_pull): Set the
default activate_pull function to start a task pulling from the
sink pad, as before.
* gst/gstpad.c (gst_pad_get_range, gst_pad_pull_range): Set caps * gst/gstpad.c (gst_pad_get_range, gst_pad_pull_range): Set caps
on the pads if necessary, as in push()/chain(). Update docs. on the pads if necessary, as in push()/chain(). Update docs.
Shouldn't affect existing pull() usage as it is currently only Shouldn't affect existing pull() usage as it is currently only

View file

@ -274,15 +274,17 @@ static void gst_base_sink_get_times (GstBaseSink * basesink, GstBuffer * buffer,
GstClockTime * start, GstClockTime * end); GstClockTime * start, GstClockTime * end);
static gboolean gst_base_sink_set_flushing (GstBaseSink * basesink, static gboolean gst_base_sink_set_flushing (GstBaseSink * basesink,
GstPad * pad, gboolean flushing); GstPad * pad, gboolean flushing);
static gboolean gst_base_sink_activate_pull (GstBaseSink * basesink,
gboolean active);
static GstStateChangeReturn gst_base_sink_change_state (GstElement * element, static GstStateChangeReturn gst_base_sink_change_state (GstElement * element,
GstStateChange transition); GstStateChange transition);
static GstFlowReturn gst_base_sink_chain (GstPad * pad, GstBuffer * buffer); static GstFlowReturn gst_base_sink_chain (GstPad * pad, GstBuffer * buffer);
static void gst_base_sink_loop (GstPad * pad); static void gst_base_sink_loop (GstPad * pad);
static gboolean gst_base_sink_activate (GstPad * pad); static gboolean gst_base_sink_pad_activate (GstPad * pad);
static gboolean gst_base_sink_activate_push (GstPad * pad, gboolean active); static gboolean gst_base_sink_pad_activate_push (GstPad * pad, gboolean active);
static gboolean gst_base_sink_activate_pull (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 gst_base_sink_event (GstPad * pad, GstEvent * event);
/* check if an object was too late */ /* check if an object was too late */
@ -344,6 +346,7 @@ gst_base_sink_class_init (GstBaseSinkClass * klass)
klass->set_caps = GST_DEBUG_FUNCPTR (gst_base_sink_set_caps); klass->set_caps = GST_DEBUG_FUNCPTR (gst_base_sink_set_caps);
klass->buffer_alloc = GST_DEBUG_FUNCPTR (gst_base_sink_buffer_alloc); klass->buffer_alloc = GST_DEBUG_FUNCPTR (gst_base_sink_buffer_alloc);
klass->get_times = GST_DEBUG_FUNCPTR (gst_base_sink_get_times); klass->get_times = GST_DEBUG_FUNCPTR (gst_base_sink_get_times);
klass->activate_pull = GST_DEBUG_FUNCPTR (gst_base_sink_activate_pull);
} }
static GstCaps * static GstCaps *
@ -432,11 +435,11 @@ gst_base_sink_init (GstBaseSink * basesink, gpointer g_class)
gst_pad_set_bufferalloc_function (basesink->sinkpad, gst_pad_set_bufferalloc_function (basesink->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_sink_pad_buffer_alloc)); GST_DEBUG_FUNCPTR (gst_base_sink_pad_buffer_alloc));
gst_pad_set_activate_function (basesink->sinkpad, gst_pad_set_activate_function (basesink->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_sink_activate)); GST_DEBUG_FUNCPTR (gst_base_sink_pad_activate));
gst_pad_set_activatepush_function (basesink->sinkpad, gst_pad_set_activatepush_function (basesink->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_sink_activate_push)); GST_DEBUG_FUNCPTR (gst_base_sink_pad_activate_push));
gst_pad_set_activatepull_function (basesink->sinkpad, gst_pad_set_activatepull_function (basesink->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_sink_activate_pull)); GST_DEBUG_FUNCPTR (gst_base_sink_pad_activate_pull));
gst_pad_set_event_function (basesink->sinkpad, gst_pad_set_event_function (basesink->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_sink_event)); GST_DEBUG_FUNCPTR (gst_base_sink_event));
gst_pad_set_chain_function (basesink->sinkpad, gst_pad_set_chain_function (basesink->sinkpad,
@ -2118,20 +2121,24 @@ gst_base_sink_set_flushing (GstBaseSink * basesink, GstPad * pad,
} }
static gboolean static gboolean
gst_base_sink_deactivate (GstBaseSink * basesink, GstPad * pad) gst_base_sink_activate_pull (GstBaseSink * basesink, gboolean active)
{ {
gboolean result; gboolean result;
gst_base_sink_set_flushing (basesink, pad, TRUE); if (active) {
/* start task */
/* step 2, make sure streaming finishes */ result = gst_pad_start_task (basesink->sinkpad,
result = gst_pad_stop_task (pad); (GstTaskFunction) gst_base_sink_loop, basesink->sinkpad);
} else {
/* step 2, make sure streaming finishes */
result = gst_pad_stop_task (basesink->sinkpad);
}
return result; return result;
} }
static gboolean static gboolean
gst_base_sink_activate (GstPad * pad) gst_base_sink_pad_activate (GstPad * pad)
{ {
gboolean result = FALSE; gboolean result = FALSE;
GstBaseSink *basesink; GstBaseSink *basesink;
@ -2165,7 +2172,7 @@ gst_base_sink_activate (GstPad * pad)
} }
static gboolean static gboolean
gst_base_sink_activate_push (GstPad * pad, gboolean active) gst_base_sink_pad_activate_push (GstPad * pad, gboolean active)
{ {
gboolean result; gboolean result;
GstBaseSink *basesink; GstBaseSink *basesink;
@ -2185,7 +2192,8 @@ gst_base_sink_activate_push (GstPad * pad, gboolean active)
g_warning ("Internal GStreamer activation error!!!"); g_warning ("Internal GStreamer activation error!!!");
result = FALSE; result = FALSE;
} else { } else {
result = gst_base_sink_deactivate (basesink, pad); gst_base_sink_set_flushing (basesink, pad, TRUE);
result = TRUE;
basesink->pad_mode = GST_ACTIVATE_NONE; basesink->pad_mode = GST_ACTIVATE_NONE;
} }
} }
@ -2197,12 +2205,14 @@ gst_base_sink_activate_push (GstPad * pad, gboolean active)
/* this won't get called until we implement an activate function */ /* this won't get called until we implement an activate function */
static gboolean static gboolean
gst_base_sink_activate_pull (GstPad * pad, gboolean active) gst_base_sink_pad_activate_pull (GstPad * pad, gboolean active)
{ {
gboolean result = FALSE; gboolean result = FALSE;
GstBaseSink *basesink; GstBaseSink *basesink;
GstBaseSinkClass *bclass;
basesink = GST_BASE_SINK (gst_pad_get_parent (pad)); basesink = GST_BASE_SINK (gst_pad_get_parent (pad));
bclass = GST_BASE_SINK_GET_CLASS (basesink);
if (active) { if (active) {
if (!basesink->can_activate_pull) { if (!basesink->can_activate_pull) {
@ -2228,9 +2238,7 @@ gst_base_sink_activate_pull (GstPad * pad, gboolean active)
/* set the pad mode before starting the task so that it's in the /* set the pad mode before starting the task so that it's in the
correct state for the new thread... */ correct state for the new thread... */
basesink->pad_mode = GST_ACTIVATE_PULL; basesink->pad_mode = GST_ACTIVATE_PULL;
result = result = gst_base_sink_activate_pull (basesink, TRUE);
gst_pad_start_task (pad, (GstTaskFunction) gst_base_sink_loop,
pad);
/* but if starting the thread fails, set it back */ /* but if starting the thread fails, set it back */
if (!result) if (!result)
basesink->pad_mode = GST_ACTIVATE_NONE; basesink->pad_mode = GST_ACTIVATE_NONE;
@ -2247,7 +2255,9 @@ gst_base_sink_activate_pull (GstPad * pad, gboolean active)
g_warning ("Internal GStreamer activation error!!!"); g_warning ("Internal GStreamer activation error!!!");
result = FALSE; result = FALSE;
} else { } else {
result = gst_base_sink_deactivate (basesink, pad); result = gst_base_sink_set_flushing (basesink, pad, TRUE);
if (bclass->activate_pull)
result &= bclass->activate_pull (basesink, FALSE);
basesink->pad_mode = GST_ACTIVATE_NONE; basesink->pad_mode = GST_ACTIVATE_NONE;
} }
} }

View file

@ -121,6 +121,12 @@ struct _GstBaseSink {
* @async_play: Subclasses should override this when they need to perform * @async_play: Subclasses should override this when they need to perform
* special processing when changing to the PLAYING state * special processing when changing to the PLAYING state
* asynchronously. Called with the OBJECT_LOCK held. * asynchronously. Called with the OBJECT_LOCK held.
* @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.
* *
* Subclasses can override any of the available virtual methods or not, as * Subclasses can override any of the available virtual methods or not, as
* needed. At the minimum, the render method should be overridden to * needed. At the minimum, the render method should be overridden to
@ -160,8 +166,11 @@ struct _GstBaseSinkClass {
/* when an ASYNC state change to PLAYING happens */ /* with LOCK */ /* when an ASYNC state change to PLAYING happens */ /* with LOCK */
GstStateChangeReturn (*async_play) (GstBaseSink *sink); GstStateChangeReturn (*async_play) (GstBaseSink *sink);
/* start or stop a pulling thread */
gboolean (*activate_pull)(GstBaseSink *sink, gboolean active);
/*< private >*/ /*< private >*/
gpointer _gst_reserved[GST_PADDING_LARGE-1]; gpointer _gst_reserved[GST_PADDING_LARGE-2];
}; };
GType gst_base_sink_get_type(void); GType gst_base_sink_get_type(void);

View file

@ -175,7 +175,7 @@
#define HAVE_WIN32 1 #define HAVE_WIN32 1
/* Define host CPU */ /* Define host CPU */
#define HOST_CPU "i686" #define HOST_CPU "powerpc"
/* library dir */ /* library dir */
#ifdef _DEBUG #ifdef _DEBUG