summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2005-01-06 18:21:38 +0000
committerWim Taymans <wim.taymans@gmail.com>2005-01-06 18:21:38 +0000
commit84a221c30e826ffb36a23cd5782e60c6695178f4 (patch)
tree7ec7f5bfcca1cca8ef3751850b52d127b0f0f349
parentc1e8ac52ff88a3b920d4a136464e011ada0e27a4 (diff)
downloadgstreamer-plugins-base-84a221c30e826ffb36a23cd5782e60c6695178f4.tar.gz
Ogg fixes. xvimagesink clock unscheduling for faster state changes.
Original commit message from CVS: Ogg fixes. xvimagesink clock unscheduling for faster state changes. Small updates for plugins that use GstTask.
-rw-r--r--ChangeLog39
-rw-r--r--examples/seeking/seek.c9
-rw-r--r--ext/ogg/gstoggdemux.c31
-rw-r--r--gst/videotestsrc/gstvideotestsrc.c23
-rw-r--r--sys/xvimage/xvimagesink.c47
-rw-r--r--tests/examples/seek/seek.c9
6 files changed, 117 insertions, 41 deletions
diff --git a/ChangeLog b/ChangeLog
index 54a2c8a9f..8233fb2e4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,42 @@
+2005-01-06 Wim Taymans <wim@fluendo.com>
+
+ * examples/negotiation/queue.c: (message_received), (block_done),
+ (do_block), (do_renegotiate), (main):
+ * examples/seeking/seek.c: (dynamic_link), (make_vorbis_pipeline),
+ (make_theora_pipeline), (do_seek), (start_seek), (stop_seek):
+ * ext/ogg/gstoggdemux.c: (gst_ogg_pad_get_type),
+ (gst_ogg_pad_init), (gst_ogg_pad_src_query), (gst_ogg_pad_event),
+ (gst_ogg_demux_factory_filter), (compare_ranks),
+ (gst_ogg_pad_internal_chain), (gst_ogg_pad_typefind),
+ (gst_ogg_pad_submit_packet), (gst_ogg_pad_submit_page),
+ (gst_ogg_chain_new), (gst_ogg_chain_free),
+ (gst_ogg_chain_new_stream), (gst_ogg_chain_get_stream),
+ (gst_ogg_chain_has_stream), (gst_ogg_demux_base_init),
+ (gst_ogg_demux_init), (gst_ogg_demux_submit_buffer),
+ (gst_ogg_demux_seek), (gst_ogg_demux_get_data),
+ (gst_ogg_demux_get_next_page), (gst_ogg_demux_get_prev_page),
+ (gst_ogg_demux_perform_seek),
+ (gst_ogg_demux_bisect_forward_serialno),
+ (gst_ogg_demux_read_chain), (gst_ogg_demux_read_end_chain),
+ (gst_ogg_demux_find_pad), (gst_ogg_demux_find_chains),
+ (gst_ogg_demux_chain_unlocked), (gst_ogg_demux_chain),
+ (gst_ogg_demux_loop), (gst_ogg_demux_sink_activate),
+ (gst_ogg_print):
+ * gst/videotestsrc/gstvideotestsrc.c:
+ (gst_videotestsrc_src_negotiate), (gst_videotestsrc_src_link),
+ (gst_videotestsrc_parse_caps), (gst_videotestsrc_src_accept_caps),
+ (gst_videotestsrc_setcaps), (gst_videotestsrc_activate),
+ (gst_videotestsrc_init), (gst_videotestsrc_loop):
+ * sys/oss/gstosssrc.c: (gst_osssrc_src_link),
+ (gst_osssrc_negotiate), (gst_osssrc_loop):
+ * sys/xvimage/xvimagesink.c: (gst_xvimagesink_sink_link),
+ (gst_xvimagesink_change_state), (gst_xvimagesink_event),
+ (gst_xvimagesink_show_frame), (gst_xvimagesink_finish_preroll),
+ (gst_xvimagesink_chain), (gst_xvimagesink_buffer_alloc):
+ Ogg fixes.
+ xvimagesink clock unscheduling for faster state changes.
+ Small updates for plugins that use GstTask.
+
2005-01-04 Wim Taymans <wim@fluendo.com>
* examples/seeking/seek.c: (dynamic_link), (make_vorbis_pipeline),
diff --git a/examples/seeking/seek.c b/examples/seeking/seek.c
index a1d29b107..732c29300 100644
--- a/examples/seeking/seek.c
+++ b/examples/seeking/seek.c
@@ -899,8 +899,11 @@ start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
gst_element_set_state (pipeline, GST_STATE_PAUSED);
gtk_timeout_remove (update_id);
- changed_id = gtk_signal_connect (GTK_OBJECT (hscale),
- "value_changed", G_CALLBACK (do_seek), pipeline);
+ if (changed_id == 0) {
+ changed_id = gtk_signal_connect (GTK_OBJECT (hscale),
+ "value_changed", G_CALLBACK (do_seek), pipeline);
+ g_print ("connect %lu\n", changed_id);
+ }
return FALSE;
}
@@ -908,7 +911,9 @@ start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
static gboolean
stop_seek (GtkWidget * widget, gpointer user_data)
{
+ g_print ("disconnect %lu\n", changed_id);
g_signal_handler_disconnect (GTK_OBJECT (hscale), changed_id);
+ changed_id = 0;
gst_element_set_state (pipeline, GST_STATE_PLAYING);
update_id =
diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c
index 431f5598b..1a60403b7 100644
--- a/ext/ogg/gstoggdemux.c
+++ b/ext/ogg/gstoggdemux.c
@@ -793,7 +793,7 @@ static gint gst_ogg_demux_read_end_chain (GstOggDemux * ogg,
GstOggChain * chain);
static gboolean gst_ogg_demux_handle_event (GstPad * pad, GstEvent * event);
-static gboolean gst_ogg_demux_loop (GstOggPad * pad);
+static void gst_ogg_demux_loop (GstOggPad * pad);
static GstFlowReturn gst_ogg_demux_chain (GstPad * pad, GstBuffer * buffer);
static gboolean gst_ogg_demux_sink_activate (GstPad * sinkpad,
GstActivateMode mode);
@@ -1663,7 +1663,7 @@ gst_ogg_demux_chain (GstPad * pad, GstBuffer * buffer)
* - when seeking, we can use the chain info to perform the
* seek.
*/
-static gboolean
+static void
gst_ogg_demux_loop (GstOggPad * pad)
{
GstOggDemux *ogg;
@@ -1681,35 +1681,40 @@ gst_ogg_demux_loop (GstOggPad * pad)
GST_LOG_OBJECT (ogg, "pull data %lld", ogg->offset);
if (ogg->offset == ogg->length)
- goto error;
+ goto stop;
ret = gst_pad_pull_range (ogg->sinkpad, ogg->offset, CHUNKSIZE, &buffer);
if (ret != GST_FLOW_OK) {
GST_LOG_OBJECT (ogg, "got error %d", ret);
- goto error;
+ goto stop;
}
ogg->offset += GST_BUFFER_SIZE (buffer);
ret = gst_ogg_demux_chain_unlocked (ogg->sinkpad, buffer);
if (ret == GST_FLOW_UNEXPECTED) {
- gst_task_pause (GST_RPAD_TASK (ogg->sinkpad));
- GST_LOG_OBJECT (ogg, "got unexpected %d", ret);
- goto done;
+ GST_LOG_OBJECT (ogg, "got unexpected %d, pausing", ret);
+ goto pause;
}
if (ret != GST_FLOW_OK) {
GST_LOG_OBJECT (ogg, "got error %d", ret);
- goto error;
+ goto stop;
}
-done:
- GST_STREAM_UNLOCK (pad);
- return TRUE;
+ GST_STREAM_UNLOCK (pad);
+ return;
-error:
+pause:
+ GST_LOG_OBJECT (ogg, "pausing task");
+ gst_task_pause (GST_RPAD_TASK (ogg->sinkpad));
+ GST_STREAM_UNLOCK (pad);
+ return;
+stop:
+ GST_LOG_OBJECT (ogg, "stopping task");
+ gst_task_stop (GST_RPAD_TASK (ogg->sinkpad));
GST_STREAM_UNLOCK (pad);
- return FALSE;
+ return;
}
static gboolean
diff --git a/gst/videotestsrc/gstvideotestsrc.c b/gst/videotestsrc/gstvideotestsrc.c
index 84fc49faf..6977f1c5c 100644
--- a/gst/videotestsrc/gstvideotestsrc.c
+++ b/gst/videotestsrc/gstvideotestsrc.c
@@ -71,7 +71,7 @@ static void gst_videotestsrc_set_property (GObject * object, guint prop_id,
static void gst_videotestsrc_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
-static gboolean gst_videotestsrc_loop (GstPad * pad);
+static void gst_videotestsrc_loop (GstPad * pad);
static const GstQueryType *gst_videotestsrc_get_query_types (GstPad * pad);
static gboolean gst_videotestsrc_src_query (GstPad * pad,
@@ -611,7 +611,7 @@ gst_videotestsrc_handle_src_event (GstPad * pad, GstEvent * event)
return res;
}
-static gboolean
+static void
gst_videotestsrc_loop (GstPad * pad)
{
GstVideotestsrc *videotestsrc;
@@ -630,7 +630,8 @@ gst_videotestsrc_loop (GstPad * pad)
GST_ELEMENT_ERROR (videotestsrc, CORE, NEGOTIATION, (NULL),
("format could not be negotiated"));
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
- return FALSE;
+ gst_task_pause (videotestsrc->task);
+ return;
}
}
@@ -638,7 +639,8 @@ gst_videotestsrc_loop (GstPad * pad)
GST_ELEMENT_ERROR (videotestsrc, CORE, NEGOTIATION, (NULL),
("format wasn't negotiated before get function"));
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
- return FALSE;
+ gst_task_pause (videotestsrc->task);
+ return;
}
if (videotestsrc->need_discont) {
@@ -656,13 +658,15 @@ gst_videotestsrc_loop (GstPad * pad)
gst_pad_push_event (pad, gst_event_new (GST_EVENT_SEGMENT_DONE));
} else {
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
- return FALSE;
+ gst_task_pause (videotestsrc->task);
+ return;
}
}
if (videotestsrc->num_buffers_left == 0) {
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
- return FALSE;
+ gst_task_pause (videotestsrc->task);
+ return;
} else {
if (videotestsrc->num_buffers_left > 0)
videotestsrc->num_buffers_left--;
@@ -670,7 +674,7 @@ gst_videotestsrc_loop (GstPad * pad)
newsize = gst_videotestsrc_get_size (videotestsrc, videotestsrc->width,
videotestsrc->height);
- g_return_val_if_fail (newsize > 0, GST_FLOW_ERROR);
+ g_return_if_fail (newsize > 0);
GST_LOG_OBJECT (videotestsrc, "creating buffer of %ld bytes for %dx%d image",
newsize, videotestsrc->width, videotestsrc->height);
@@ -684,7 +688,8 @@ gst_videotestsrc_loop (GstPad * pad)
GST_ELEMENT_ERROR (videotestsrc, CORE, NEGOTIATION, (NULL),
("format wasn't accepted"));
gst_pad_push_event (pad, gst_event_new (GST_EVENT_EOS));
- return FALSE;
+ gst_task_pause (videotestsrc->task);
+ return;
}
}
@@ -704,8 +709,6 @@ gst_videotestsrc_loop (GstPad * pad)
videotestsrc->running_time += GST_BUFFER_DURATION (outbuf);
gst_pad_push (pad, outbuf);
-
- return TRUE;
}
static void
diff --git a/sys/xvimage/xvimagesink.c b/sys/xvimage/xvimagesink.c
index 53e1b8f2e..9bd90eb4c 100644
--- a/sys/xvimage/xvimagesink.c
+++ b/sys/xvimage/xvimagesink.c
@@ -1357,6 +1357,11 @@ gst_xvimagesink_change_state (GstElement * element)
case GST_STATE_PAUSED_TO_PLAYING:
break;
case GST_STATE_PLAYING_TO_PAUSED:
+ GST_LOCK (xvimagesink);
+ if (xvimagesink->clock_id) {
+ gst_clock_id_unschedule (xvimagesink->clock_id);
+ }
+ GST_UNLOCK (xvimagesink);
result = GST_STATE_ASYNC;
break;
case GST_STATE_PAUSED_TO_READY:
@@ -1404,25 +1409,35 @@ gst_xvimagesink_event (GstPad * pad, GstEvent * event)
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_EOS:
+ {
+ GstClockID id;
+
GST_STREAM_LOCK (pad);
gst_xvimagesink_finish_preroll (xvimagesink, pad, NULL);
- gst_clock_id_wait (gst_clock_new_single_shot_id (GST_VIDEOSINK_CLOCK
- (xvimagesink),
- xvimagesink->end_time + GST_ELEMENT (xvimagesink)->base_time),
- NULL);
+ /* wait for last frame to finish */
+ id = gst_clock_new_single_shot_id (GST_VIDEOSINK_CLOCK (xvimagesink),
+ xvimagesink->end_time + GST_ELEMENT (xvimagesink)->base_time);
+ gst_clock_id_wait (id, NULL);
+ gst_clock_id_unref (id);
gst_element_post_message (GST_ELEMENT (xvimagesink),
gst_message_new_eos (GST_OBJECT (xvimagesink)));
result = TRUE;
- break;
GST_STREAM_UNLOCK (pad);
+ break;
+ }
case GST_EVENT_FLUSH:
+ /* make sure we are not blocked on the clock */
+ GST_LOCK (xvimagesink);
if (xvimagesink->clock_id) {
- gst_clock_id_unlock (xvimagesink->clock_id);
- xvimagesink->clock_id = NULL;
+ gst_clock_id_unschedule (xvimagesink->clock_id);
}
+ GST_UNLOCK (xvimagesink);
+ /* unlock from a possible state change/preroll */
GST_STATE_LOCK (xvimagesink);
g_cond_broadcast (GST_STATE_GET_COND (xvimagesink));
GST_STATE_UNLOCK (xvimagesink);
+ /* now we are completely unblocked and the _chain method
+ * will return */
result = TRUE;
break;
default:
@@ -1485,14 +1500,11 @@ gst_xvimagesink_finish_preroll (GstXvImageSink * xvimagesink, GstPad * pad,
if (buf)
gst_xvimagesink_show_frame (xvimagesink, buf);
- //GST_STREAM_UNLOCK (pad);
-
/* here we wait for the next state change */
while (GST_STATE (xvimagesink) == GST_STATE_PAUSED) {
if (GST_RPAD_IS_FLUSHING (pad)) {
GST_DEBUG_OBJECT (xvimagesink, "pad is flushing");
result = GST_FLOW_UNEXPECTED;
- //GST_STREAM_LOCK (pad);
goto done;
}
@@ -1501,8 +1513,6 @@ gst_xvimagesink_finish_preroll (GstXvImageSink * xvimagesink, GstPad * pad,
GST_DEBUG_OBJECT (xvimagesink, "got unlocked, maybe a state change");
}
- //GST_STREAM_LOCK (pad);
-
/* check if we got playing */
if (GST_STATE (xvimagesink) != GST_STATE_PLAYING) {
/* not playing, we can't accept the buffer */
@@ -1565,19 +1575,28 @@ gst_xvimagesink_chain (GstPad * pad, GstBuffer * buffer)
if (GST_VIDEOSINK_CLOCK (xvimagesink)) {
GstClockReturn ret;
- //gst_element_wait (GST_ELEMENT (xvimagesink), xvimagesink->time);
+ /* save clock id so that we can unlock it if needed */
+ GST_LOCK (xvimagesink);
xvimagesink->clock_id =
gst_clock_new_single_shot_id (GST_VIDEOSINK_CLOCK (xvimagesink),
xvimagesink->time + GST_ELEMENT (xvimagesink)->base_time);
+ GST_UNLOCK (xvimagesink);
ret = gst_clock_id_wait (xvimagesink->clock_id, NULL);
+
+ GST_LOCK (xvimagesink);
+ gst_clock_id_unref (xvimagesink->clock_id);
xvimagesink->clock_id = NULL;
+ GST_UNLOCK (xvimagesink);
+
GST_LOG_OBJECT (xvimagesink, "clock entry done: %d", ret);
}
gst_xvimagesink_show_frame (xvimagesink, buf);
- /* set correct time for next buffer */
+ /* set correct time for next buffer in case the next buffer does not
+ * have a timestamp. FIXME, this is not the job of xvimagesink and will
+ * make preview pipelines fail. */
if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf) && xvimagesink->framerate > 0) {
xvimagesink->time += GST_SECOND / xvimagesink->framerate;
}
diff --git a/tests/examples/seek/seek.c b/tests/examples/seek/seek.c
index a1d29b107..732c29300 100644
--- a/tests/examples/seek/seek.c
+++ b/tests/examples/seek/seek.c
@@ -899,8 +899,11 @@ start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
gst_element_set_state (pipeline, GST_STATE_PAUSED);
gtk_timeout_remove (update_id);
- changed_id = gtk_signal_connect (GTK_OBJECT (hscale),
- "value_changed", G_CALLBACK (do_seek), pipeline);
+ if (changed_id == 0) {
+ changed_id = gtk_signal_connect (GTK_OBJECT (hscale),
+ "value_changed", G_CALLBACK (do_seek), pipeline);
+ g_print ("connect %lu\n", changed_id);
+ }
return FALSE;
}
@@ -908,7 +911,9 @@ start_seek (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
static gboolean
stop_seek (GtkWidget * widget, gpointer user_data)
{
+ g_print ("disconnect %lu\n", changed_id);
g_signal_handler_disconnect (GTK_OBJECT (hscale), changed_id);
+ changed_id = 0;
gst_element_set_state (pipeline, GST_STATE_PLAYING);
update_id =