diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2005-01-06 18:21:38 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2005-01-06 18:21:38 +0000 |
commit | 84a221c30e826ffb36a23cd5782e60c6695178f4 (patch) | |
tree | 7ec7f5bfcca1cca8ef3751850b52d127b0f0f349 | |
parent | c1e8ac52ff88a3b920d4a136464e011ada0e27a4 (diff) | |
download | gstreamer-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-- | ChangeLog | 39 | ||||
-rw-r--r-- | examples/seeking/seek.c | 9 | ||||
-rw-r--r-- | ext/ogg/gstoggdemux.c | 31 | ||||
-rw-r--r-- | gst/videotestsrc/gstvideotestsrc.c | 23 | ||||
-rw-r--r-- | sys/xvimage/xvimagesink.c | 47 | ||||
-rw-r--r-- | tests/examples/seek/seek.c | 9 |
6 files changed, 117 insertions, 41 deletions
@@ -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 = |