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>
* 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
on the pads if necessary, as in push()/chain(). Update docs.
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);
static gboolean gst_base_sink_set_flushing (GstBaseSink * basesink,
GstPad * pad, gboolean flushing);
static gboolean gst_base_sink_activate_pull (GstBaseSink * basesink,
gboolean active);
static GstStateChangeReturn gst_base_sink_change_state (GstElement * element,
GstStateChange transition);
static GstFlowReturn gst_base_sink_chain (GstPad * pad, GstBuffer * buffer);
static void gst_base_sink_loop (GstPad * pad);
static gboolean gst_base_sink_activate (GstPad * pad);
static gboolean gst_base_sink_activate_push (GstPad * pad, gboolean active);
static gboolean gst_base_sink_activate_pull (GstPad * pad, gboolean active);
static gboolean gst_base_sink_pad_activate (GstPad * pad);
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);
/* 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->buffer_alloc = GST_DEBUG_FUNCPTR (gst_base_sink_buffer_alloc);
klass->get_times = GST_DEBUG_FUNCPTR (gst_base_sink_get_times);
klass->activate_pull = GST_DEBUG_FUNCPTR (gst_base_sink_activate_pull);
}
static GstCaps *
@ -432,11 +435,11 @@ gst_base_sink_init (GstBaseSink * basesink, gpointer g_class)
gst_pad_set_bufferalloc_function (basesink->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_sink_pad_buffer_alloc));
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_DEBUG_FUNCPTR (gst_base_sink_activate_push));
GST_DEBUG_FUNCPTR (gst_base_sink_pad_activate_push));
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_DEBUG_FUNCPTR (gst_base_sink_event));
gst_pad_set_chain_function (basesink->sinkpad,
@ -2118,20 +2121,24 @@ gst_base_sink_set_flushing (GstBaseSink * basesink, GstPad * pad,
}
static gboolean
gst_base_sink_deactivate (GstBaseSink * basesink, GstPad * pad)
gst_base_sink_activate_pull (GstBaseSink * basesink, gboolean active)
{
gboolean result;
gst_base_sink_set_flushing (basesink, pad, TRUE);
if (active) {
/* start task */
result = gst_pad_start_task (basesink->sinkpad,
(GstTaskFunction) gst_base_sink_loop, basesink->sinkpad);
} else {
/* step 2, make sure streaming finishes */
result = gst_pad_stop_task (pad);
result = gst_pad_stop_task (basesink->sinkpad);
}
return result;
}
static gboolean
gst_base_sink_activate (GstPad * pad)
gst_base_sink_pad_activate (GstPad * pad)
{
gboolean result = FALSE;
GstBaseSink *basesink;
@ -2165,7 +2172,7 @@ gst_base_sink_activate (GstPad * pad)
}
static gboolean
gst_base_sink_activate_push (GstPad * pad, gboolean active)
gst_base_sink_pad_activate_push (GstPad * pad, gboolean active)
{
gboolean result;
GstBaseSink *basesink;
@ -2185,7 +2192,8 @@ gst_base_sink_activate_push (GstPad * pad, gboolean active)
g_warning ("Internal GStreamer activation error!!!");
result = FALSE;
} else {
result = gst_base_sink_deactivate (basesink, pad);
gst_base_sink_set_flushing (basesink, pad, TRUE);
result = TRUE;
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 */
static gboolean
gst_base_sink_activate_pull (GstPad * pad, gboolean active)
gst_base_sink_pad_activate_pull (GstPad * pad, gboolean active)
{
gboolean result = FALSE;
GstBaseSink *basesink;
GstBaseSinkClass *bclass;
basesink = GST_BASE_SINK (gst_pad_get_parent (pad));
bclass = GST_BASE_SINK_GET_CLASS (basesink);
if (active) {
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
correct state for the new thread... */
basesink->pad_mode = GST_ACTIVATE_PULL;
result =
gst_pad_start_task (pad, (GstTaskFunction) gst_base_sink_loop,
pad);
result = gst_base_sink_activate_pull (basesink, TRUE);
/* but if starting the thread fails, set it back */
if (!result)
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!!!");
result = FALSE;
} 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;
}
}

View file

@ -121,6 +121,12 @@ struct _GstBaseSink {
* @async_play: Subclasses should override this when they need to perform
* special processing when changing to the PLAYING state
* 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
* 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 */
GstStateChangeReturn (*async_play) (GstBaseSink *sink);
/* start or stop a pulling thread */
gboolean (*activate_pull)(GstBaseSink *sink, gboolean active);
/*< private >*/
gpointer _gst_reserved[GST_PADDING_LARGE-1];
gpointer _gst_reserved[GST_PADDING_LARGE-2];
};
GType gst_base_sink_get_type(void);

View file

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