From: <wi...@fr...> - 2005-08-18 16:53:38
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wingo Date: Thu Aug 18 2005 09:20:36 PDT Log message: 2005-08-18 Andy Wingo <wi...@po...> Make sure that when a pipeline goes to PLAYING, that data has actually hit the sink. * check/states/sinks.c (test_sink): A sink that doesn't get any data shouldn't return SUCCESS for going to either PLAYING or PAUSED. Test also the return values on the way back down. * gst/gstelement.c (gst_element_set_state): When changing the state of an element currently changing state asynchronously, go to lost-state after commiting the pending state. Makes future calls to get_state continue to return ASYNC. * gst/base/gstbasesink.c (gst_base_sink_change_state): Return ASYNC when going to PLAYING if we still don't have preroll, as can happen with live sources. Modified files: . : ChangeLog check/states : sinks.c gst : gstelement.c gst/base : gstbasesink.c gstbasesink.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.1362&r2=1.1363 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/check/states/sinks.c.diff?r1=1.4&r2=1.5 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstelement.c.diff?r1=1.353&r2=1.354 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/base/gstbasesink.c.diff?r1=1.41&r2=1.42 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/base/gstbasesink.h.diff?r1=1.15&r2=1.16 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.1362 retrieving revision 1.1363 diff -u -d -r1.1362 -r1.1363 --- ChangeLog 18 Aug 2005 16:15:28 -0000 1.1362 +++ ChangeLog 18 Aug 2005 16:20:23 -0000 1.1363 @@ -1,3 +1,21 @@ +2005-08-18 Andy Wingo <wi...@po...> + + Make sure that when a pipeline goes to PLAYING, that data has + actually hit the sink. + * check/states/sinks.c (test_sink): A sink that doesn't get any + data shouldn't return SUCCESS for going to either PLAYING or + PAUSED. Test also the return values on the way back down. + * gst/gstelement.c (gst_element_set_state): When changing the + state of an element currently changing state asynchronously, go to + lost-state after commiting the pending state. Makes future calls + to get_state continue to return ASYNC. + * gst/base/gstbasesink.c (gst_base_sink_change_state): Return + ASYNC when going to PLAYING if we still don't have preroll, as can + happen with live sources. 2005-08-18 Jan Schmidt <th...@ma...> * docs/pwg/advanced-types.xml: Index: sinks.c RCS file: /cvs/gstreamer/gstreamer/check/states/sinks.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- sinks.c 9 Jul 2005 16:36:18 -0000 1.4 +++ sinks.c 18 Aug 2005 16:20:23 -0000 1.5 @@ -28,6 +28,7 @@ GstElement *sink; GstElementStateReturn ret; GstElementState current, pending; + GTimeVal tv; sink = gst_element_factory_make ("fakesink", "sink"); @@ -35,12 +36,22 @@ fail_unless (ret == GST_STATE_ASYNC, "no async state return"); ret = gst_element_set_state (sink, GST_STATE_PLAYING); - fail_unless (ret == GST_STATE_SUCCESS, "cannot force play"); + fail_unless (ret == GST_STATE_ASYNC, "no forced async state change"); - ret = gst_element_get_state (sink, ¤t, &pending, NULL); - fail_unless (ret == GST_STATE_SUCCESS, "not playing"); - fail_unless (current == GST_STATE_PLAYING, "not playing"); - fail_unless (pending == GST_STATE_VOID_PENDING, "not playing"); + GST_TIME_TO_TIMEVAL ((GstClockTime) 0, tv); + ret = gst_element_get_state (sink, ¤t, &pending, &tv); + fail_unless (ret == GST_STATE_ASYNC, "not changing state async"); + fail_unless (current == GST_STATE_PAUSED, "bad current state"); + fail_unless (pending == GST_STATE_PLAYING, "bad pending state"); + ret = gst_element_set_state (sink, GST_STATE_PAUSED); + fail_unless (ret == GST_STATE_ASYNC, "no async going back to paused"); + ret = gst_element_set_state (sink, GST_STATE_READY); + fail_unless (ret == GST_STATE_SUCCESS, "failed to go to ready"); + gst_object_unref (sink); } GST_END_TEST Index: gstelement.c RCS file: /cvs/gstreamer/gstreamer/gst/gstelement.c,v retrieving revision 1.353 retrieving revision 1.354 diff -u -d -r1.353 -r1.354 --- gstelement.c 16 Aug 2005 09:42:50 -0000 1.353 +++ gstelement.c 18 Aug 2005 16:20:23 -0000 1.354 @@ -1778,6 +1778,7 @@ GST_STATE_FINAL (element) = state; if (ret == GST_STATE_ASYNC) { gst_element_commit_state (element); + gst_element_lost_state (element); } /* start with the current state */ Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/gst/base/gstbasesink.c,v retrieving revision 1.41 retrieving revision 1.42 diff -u -d -r1.41 -r1.42 --- gstbasesink.c 18 Aug 2005 15:31:28 -0000 1.41 +++ gstbasesink.c 18 Aug 2005 16:20:24 -0000 1.42 @@ -528,6 +528,9 @@ basesink->preroll_queued, basesink->buffers_queued, basesink->events_queued); + if (basesink->playing_async) + goto playing_async; /* check if we are prerolling */ if (!basesink->need_preroll) goto no_preroll; @@ -628,6 +631,34 @@ return ret; +playing_async: + { + GstFlowReturn ret; + gint t; + basesink->have_preroll = FALSE; + basesink->playing_async = FALSE; + /* handle buffer first */ + ret = gst_base_sink_preroll_queue_empty (basesink, pad); + /* unroll locks, commit state, reacquire stream lock */ + GST_PREROLL_UNLOCK (pad); + t = GST_STREAM_UNLOCK_FULL (pad); + GST_DEBUG ("released stream lock %d times", t); + if (t <= 0) { + GST_WARNING ("STREAM_LOCK should have been locked !!"); + g_warning ("STREAM_LOCK should have been locked !!"); + } + GST_STATE_LOCK (basesink); + GST_DEBUG ("commit state %p >", basesink); + gst_element_commit_state (GST_ELEMENT (basesink)); + GST_STATE_UNLOCK (basesink); + if (t > 0) + GST_STREAM_LOCK_FULL (pad, t); + return ret; + } flushing: { GST_UNLOCK (pad); @@ -1104,11 +1135,18 @@ * thread to do this. */ if (basesink->eos) { gst_base_sink_preroll_queue_empty (basesink, basesink->sinkpad); + } else if (!basesink->have_preroll) { + /* don't need preroll, but do queue a commit_state */ + basesink->need_preroll = FALSE; + basesink->playing_async = TRUE; + ret = GST_STATE_ASYNC; + /* we know it's not waiting, no need to signal */ + } else { + /* don't need the preroll anymore */ + /* now let it play */ + GST_PREROLL_SIGNAL (basesink->sinkpad); } - /* don't need the preroll anymore */ - basesink->need_preroll = FALSE; - /* now let it play */ - GST_PREROLL_SIGNAL (basesink->sinkpad); GST_PREROLL_UNLOCK (basesink->sinkpad); break; } @@ -1133,6 +1171,8 @@ GST_UNLOCK (basesink); + basesink->playing_async = FALSE; /* unlock any subclasses */ if (bclass->unlock) bclass->unlock (basesink); Index: gstbasesink.h RCS file: /cvs/gstreamer/gstreamer/gst/base/gstbasesink.h,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- gstbasesink.h 15 Aug 2005 16:57:34 -0000 1.15 +++ gstbasesink.h 18 Aug 2005 16:20:24 -0000 1.16 @@ -81,6 +81,7 @@ gboolean eos; gboolean need_preroll; gboolean have_preroll; + gboolean playing_async; /*< private >*/ gpointer _gst_reserved[GST_PADDING]; |