From: <wt...@fr...> - 2005-12-12 10:16:43
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Mon Dec 12 2005 02:16:23 PST Log message: * libs/gst/base/gstbasesink.c: (gst_base_sink_get_position): Take current playback rate into account when reporting the position. Modified files: . : ChangeLog libs/gst/base : gstbasesink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2117&r2=1.2118 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.c.diff?r1=1.105&r2=1.106 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2117 retrieving revision 1.2118 diff -u -d -r1.2117 -r1.2118 --- ChangeLog 11 Dec 2005 19:35:01 -0000 1.2117 +++ ChangeLog 12 Dec 2005 10:16:10 -0000 1.2118 @@ -1,3 +1,9 @@ +2005-12-12 Wim Taymans <wi...@fl...> + + * libs/gst/base/gstbasesink.c: (gst_base_sink_get_position): + Take current playback rate into account when reporting + the position. 2005-12-11 Tim-Philipp Müller <tim at centricular dot net> * docs/manual/mime-world.fig: Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.c,v retrieving revision 1.105 retrieving revision 1.106 diff -u -d -r1.105 -r1.106 --- gstbasesink.c 7 Dec 2005 15:16:43 -0000 1.105 +++ gstbasesink.c 12 Dec 2005 10:16:11 -0000 1.106 @@ -1366,7 +1366,9 @@ time = 0; base = GST_ELEMENT_CAST (basesink)->base_time; - *cur = now - base - basesink->segment.accum + time; + base += basesink->segment.accum; + base = MIN (now, base); + *cur = (now - base) * basesink->segment.abs_rate + time; GST_DEBUG_OBJECT (basesink, "now %" GST_TIME_FORMAT " - base %" GST_TIME_FORMAT " - accum %" |
From: <wt...@fr...> - 2005-12-12 14:44:30
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Mon Dec 12 2005 06:44:10 PST Log message: * libs/gst/base/gstpushsrc.c: Fix typo. Modified files: . : ChangeLog libs/gst/base : gstpushsrc.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2125&r2=1.2126 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstpushsrc.c.diff?r1=1.7&r2=1.8 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2125 retrieving revision 1.2126 diff -u -d -r1.2125 -r1.2126 --- ChangeLog 12 Dec 2005 14:42:11 -0000 1.2125 +++ ChangeLog 12 Dec 2005 14:43:57 -0000 1.2126 @@ -1,5 +1,10 @@ 2005-12-12 Wim Taymans <wi...@fl...> + * libs/gst/base/gstpushsrc.c: + Fix typo. + +2005-12-12 Wim Taymans <wi...@fl...> * docs/libs/gstreamer-libs-sections.txt: Added new symbol to docs. Index: gstpushsrc.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstpushsrc.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- gstpushsrc.c 5 Nov 2005 15:14:33 -0000 1.7 +++ gstpushsrc.c 12 Dec 2005 14:43:57 -0000 1.8 @@ -30,7 +30,7 @@ * prefers to push out a fixed size buffer. * * Classes extending this base class will usually be scheduled - * in a push based mode. It the peer accepts to operate without + * in a push based mode. If the peer accepts to operate without * offsets and withing the limits of the allowed block size, this * class can operate in getrange based mode automatically. |
From: <wt...@fr...> - 2006-01-18 16:42:30
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Wed Jan 18 2006 08:40:28 PST Log message: * libs/gst/base/gstbasesink.c: (gst_base_sink_set_property), (gst_base_sink_get_property), (gst_base_sink_do_sync), (gst_base_sink_chain): Small cleanups. GST_ELEMENT_CLOCK and sync are protected with LOCK. Don't store _last_stop if the buffer is dropped. Modified files: . : ChangeLog libs/gst/base : gstbasesink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2190&r2=1.2191 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.c.diff?r1=1.108&r2=1.109 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2190 retrieving revision 1.2191 diff -u -d -r1.2190 -r1.2191 --- ChangeLog 18 Jan 2006 16:31:49 -0000 1.2190 +++ ChangeLog 18 Jan 2006 16:40:16 -0000 1.2191 @@ -1,3 +1,12 @@ +2006-01-18 Wim Taymans <wi...@fl...> + + * libs/gst/base/gstbasesink.c: (gst_base_sink_set_property), + (gst_base_sink_get_property), (gst_base_sink_do_sync), + (gst_base_sink_chain): + Small cleanups. + GST_ELEMENT_CLOCK and sync are protected with LOCK. + Don't store _last_stop if the buffer is dropped. 2006-01-18 Tim-Philipp Müller <tim at centricular dot net> * plugins/elements/gsttypefindelement.c: Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.c,v retrieving revision 1.108 retrieving revision 1.109 diff -u -d -r1.108 -r1.109 --- gstbasesink.c 12 Jan 2006 22:04:58 -0000 1.108 +++ gstbasesink.c 18 Jan 2006 16:40:16 -0000 1.109 @@ -59,7 +59,8 @@ * When the element is set to PLAYING, #GstBaseSink will synchronize on the clock * using the times returned from ::get_times. If this function returns * #GST_CLOCK_TIME_NONE for the start time, no synchronisation will be done. - * Synchronisation can be disabled entirely by setting the sync property to FALSE. + * Synchronisation can be disabled entirely by setting the object "sync" property + * to FALSE. * * After synchronisation the virtual method #GstBaseSink::render will be called. * Subclasses should minimally implement this method. @@ -98,7 +99,7 @@ * operations they perform in the ::render method. This is mostly usefull when * the ::render method performs a blocking write on a file descripter. - * Last reviewed on 2005-12-18 (0.10.0) + * Last reviewed on 2006-01-18 (0.10.0) */ #ifdef HAVE_CONFIG_H @@ -371,7 +372,9 @@ GST_PAD_PREROLL_UNLOCK (sink->sinkpad); break; case PROP_SYNC: + GST_OBJECT_LOCK (sink); sink->sync = g_value_get_boolean (value); + GST_OBJECT_UNLOCK (sink); default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -385,19 +388,21 @@ { GstBaseSink *sink = GST_BASE_SINK (object); - GST_OBJECT_LOCK (sink); switch (prop_id) { case PROP_PREROLL_QUEUE_LEN: + GST_PAD_PREROLL_LOCK (sink->sinkpad); g_value_set_uint (value, sink->preroll_queue_max_len); + GST_PAD_PREROLL_UNLOCK (sink->sinkpad); g_value_set_boolean (value, sink->sync); } - GST_OBJECT_UNLOCK (sink); } static GstCaps * @@ -894,7 +899,7 @@ -/* with STREAM_LOCK and LOCK*/ +/* with STREAM_LOCK and LOCK */ static GstClockReturn gst_base_sink_wait (GstBaseSink * basesink, GstClockTime time) @@ -937,10 +942,12 @@ gst_base_sink_do_sync (GstBaseSink * basesink, GstBuffer * buffer) - GstClockReturn result = GST_CLOCK_OK; + GstClockReturn result; GstClockTime start, end; gint64 cstart, cend; GstBaseSinkClass *bclass; + GstClockTime base_time; + GstClockTimeDiff stream_start, stream_end; bclass = GST_BASE_SINK_GET_CLASS (basesink); @@ -952,81 +959,96 @@ ", end: %" GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (end)); /* if we don't have a timestamp, we don't sync */ - if (!GST_CLOCK_TIME_IS_VALID (start)) { - GST_DEBUG_OBJECT (basesink, "start not valid"); - goto done; - } + if (!GST_CLOCK_TIME_IS_VALID (start)) + goto invalid_start; if (basesink->segment.format == GST_FORMAT_TIME) { - /* save last times seen. */ + /* clip */ + if (!gst_segment_clip (&basesink->segment, GST_FORMAT_TIME, + (gint64) start, (gint64) end, &cstart, &cend)) + goto out_of_segment; + /* save last valid times seen. */ if (GST_CLOCK_TIME_IS_VALID (end)) gst_segment_set_last_stop (&basesink->segment, GST_FORMAT_TIME, (gint64) end); else (gint64) start); - - /* clip */ - if (!gst_segment_clip (&basesink->segment, GST_FORMAT_TIME, - (gint64) start, (gint64) end, &cstart, &cend)) - goto out_of_segment; } else { /* no clipping for formats different from GST_FORMAT_TIME */ cstart = start; cend = end; - if (!basesink->sync) { - GST_DEBUG_OBJECT (basesink, "no need to sync"); + GST_OBJECT_LOCK (basesink); + if (!basesink->sync) + goto no_sync; - /* now do clocking */ - if (GST_ELEMENT_CLOCK (basesink) - && ((basesink->segment.format == GST_FORMAT_TIME) - || (basesink->segment.accum == 0))) { - GstClockTime base_time; - GstClockTimeDiff stream_start, stream_end; + if (GST_ELEMENT_CLOCK (basesink) == NULL) + goto no_clock; - stream_start = - gst_segment_to_running_time (&basesink->segment, GST_FORMAT_TIME, - cstart); - stream_end = - gst_segment_to_running_time (&basesink->segment, GST_FORMAT_TIME, cend); + if (!((basesink->segment.format == GST_FORMAT_TIME) + || (basesink->segment.accum == 0))) + goto no_segment; - GST_OBJECT_LOCK (basesink); + /* now do clocking, LOCK is helt */ + stream_start = + gst_segment_to_running_time (&basesink->segment, GST_FORMAT_TIME, cstart); + stream_end = + gst_segment_to_running_time (&basesink->segment, GST_FORMAT_TIME, cend); - base_time = GST_ELEMENT_CAST (basesink)->base_time; + base_time = GST_ELEMENT_CAST (basesink)->base_time; - GST_LOG_OBJECT (basesink, - "waiting for clock, base time %" GST_TIME_FORMAT - " stream_start %" GST_TIME_FORMAT, - GST_TIME_ARGS (base_time), GST_TIME_ARGS (stream_start)); + GST_LOG_OBJECT (basesink, + "waiting for clock, base time %" GST_TIME_FORMAT + " stream_start %" GST_TIME_FORMAT, + GST_TIME_ARGS (base_time), GST_TIME_ARGS (stream_start)); - /* also save end_time of this buffer so that we can wait - * to signal EOS */ - if (GST_CLOCK_TIME_IS_VALID (stream_end)) - basesink->end_time = stream_end + base_time; - else - basesink->end_time = GST_CLOCK_TIME_NONE; + /* also save end_time of this buffer so that we can wait + * to signal EOS */ + if (GST_CLOCK_TIME_IS_VALID (stream_end)) + basesink->end_time = stream_end + base_time; + else + basesink->end_time = GST_CLOCK_TIME_NONE; - result = gst_base_sink_wait (basesink, stream_start + base_time); + result = gst_base_sink_wait (basesink, stream_start + base_time); - GST_OBJECT_UNLOCK (basesink); + GST_OBJECT_UNLOCK (basesink); - GST_LOG_OBJECT (basesink, "clock entry done: %d", result); - } else { - GST_DEBUG_OBJECT (basesink, "no clock, not syncing"); + GST_LOG_OBJECT (basesink, "clock entry done: %d", result); -done: return result; + /* special cases */ +invalid_start: + { + GST_DEBUG_OBJECT (basesink, "start not valid, cannot sync"); + return GST_CLOCK_OK; + } out_of_segment: { GST_LOG_OBJECT (basesink, "buffer skipped, not in segment"); return GST_CLOCK_UNSCHEDULED; +no_sync: + GST_DEBUG_OBJECT (basesink, "no need to sync"); + GST_OBJECT_UNLOCK (basesink); +no_clock: + GST_DEBUG_OBJECT (basesink, "no clock, can't sync"); +no_segment: + GST_DEBUG_OBJECT (basesink, "no segment info, can't sync"); @@ -1131,14 +1153,8 @@ basesink = GST_BASE_SINK (gst_pad_get_parent (pad)); - if (!(basesink->pad_mode == GST_ACTIVATE_PUSH)) { - GST_OBJECT_LOCK (pad); - g_warning ("Push on pad %s:%s, but it was not activated in push mode", - GST_DEBUG_PAD_NAME (pad)); - GST_OBJECT_UNLOCK (pad); - result = GST_FLOW_UNEXPECTED; + if (!(basesink->pad_mode == GST_ACTIVATE_PUSH)) + goto wrong_mode; result = gst_base_sink_handle_object (basesink, pad, GST_MINI_OBJECT_CAST (buf)); @@ -1147,6 +1163,17 @@ gst_object_unref (basesink); + /* ERRORS */ +wrong_mode: + GST_OBJECT_LOCK (pad); + g_warning ("Push on pad %s:%s, but it was not activated in push mode", + GST_DEBUG_PAD_NAME (pad)); + GST_OBJECT_UNLOCK (pad); + result = GST_FLOW_UNEXPECTED; + goto done; static void |
From: <wt...@fr...> - 2006-01-26 13:02:28
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Thu Jan 26 2006 05:00:04 PST Log message: * libs/gst/base/gstbasesrc.c: (gst_base_src_get_range): Add some debugging. Modified files: . : ChangeLog libs/gst/base : gstbasesrc.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2217&r2=1.2218 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesrc.c.diff?r1=1.91&r2=1.92 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2217 retrieving revision 1.2218 diff -u -d -r1.2217 -r1.2218 --- ChangeLog 26 Jan 2006 12:40:16 -0000 1.2217 +++ ChangeLog 26 Jan 2006 12:59:48 -0000 1.2218 @@ -1,3 +1,8 @@ +2006-01-26 Wim Taymans <wi...@fl...> + + * libs/gst/base/gstbasesrc.c: (gst_base_src_get_range): + Add some debugging. 2006-01-26 Julien MOUTTE <ju...@mo...> * plugins/elements/gsttee.c: (gst_tee_do_push), Index: gstbasesrc.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesrc.c,v retrieving revision 1.91 retrieving revision 1.92 diff -u -d -r1.91 -r1.92 --- gstbasesrc.c 10 Jan 2006 09:23:11 -0000 1.91 +++ gstbasesrc.c 26 Jan 2006 12:59:48 -0000 1.92 @@ -1127,6 +1127,9 @@ if (ret != GST_FLOW_OK) goto done; + GST_DEBUG_OBJECT (src, "offset %" G_GUINT64_FORMAT " %" G_GINT64_FORMAT, + offset, src->segment.time); /* no timestamp set and we are at offset 0 */ if (offset == 0 && src->segment.time == 0 && GST_BUFFER_TIMESTAMP (*buf) == -1) |
From: <wt...@fr...> - 2006-01-30 16:10:35
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Mon Jan 30 2006 08:08:01 PST Log message: * libs/gst/base/gstbasesink.c: (gst_base_sink_init), (gst_base_sink_preroll_queue_empty), (gst_base_sink_commit_state), (gst_base_sink_handle_object), (gst_base_sink_event), (gst_base_sink_is_prerolled), (gst_base_sink_wait), (gst_base_sink_do_sync), (gst_base_sink_handle_event), (gst_base_sink_handle_buffer), (gst_base_sink_set_flushing), (gst_base_sink_deactivate), (gst_base_sink_activate), (gst_base_sink_activate_pull), (gst_base_sink_get_position), (gst_base_sink_query), (gst_base_sink_change_state): Basesink cleanups, remove some old code. Handle the case where a subclass can preroll in the render method (mostly audiosinks). Handle more events. Remove some locks around variables that are now protected with the PREROLL_LOCK (clock_id, flushing, ..). Optimize position query some more, do correct locking. Remove old code to push queue in state change, this is not needed anymore since preroll blocks on all prerollable items now. Almost implemented as described in design doc. Modified files: . : ChangeLog libs/gst/base : gstbasesink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2229&r2=1.2230 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.c.diff?r1=1.113&r2=1.114 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2229 retrieving revision 1.2230 diff -u -d -r1.2229 -r1.2230 --- ChangeLog 30 Jan 2006 15:57:42 -0000 1.2229 +++ ChangeLog 30 Jan 2006 16:07:48 -0000 1.2230 @@ -1,5 +1,28 @@ 2006-01-30 Wim Taymans <wi...@fl...> + * libs/gst/base/gstbasesink.c: (gst_base_sink_init), + (gst_base_sink_preroll_queue_empty), (gst_base_sink_commit_state), + (gst_base_sink_handle_object), (gst_base_sink_event), + (gst_base_sink_is_prerolled), (gst_base_sink_wait), + (gst_base_sink_do_sync), (gst_base_sink_handle_event), + (gst_base_sink_handle_buffer), (gst_base_sink_set_flushing), + (gst_base_sink_deactivate), (gst_base_sink_activate), + (gst_base_sink_activate_pull), (gst_base_sink_get_position), + (gst_base_sink_query), (gst_base_sink_change_state): + Basesink cleanups, remove some old code. + Handle the case where a subclass can preroll in the render + method (mostly audiosinks). + Handle more events. + Remove some locks around variables that are now protected + with the PREROLL_LOCK (clock_id, flushing, ..). + Optimize position query some more, do correct locking. + Remove old code to push queue in state change, this is not + needed anymore since preroll blocks on all prerollable items + now. + Almost implemented as described in design doc. + +2006-01-30 Wim Taymans <wi...@fl...> * tests/check/gst/gstbin.c: (GST_START_TEST): Wait for refcount to settle down before checking. Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.c,v retrieving revision 1.113 retrieving revision 1.114 diff -u -d -r1.113 -r1.114 --- gstbasesink.c 25 Jan 2006 18:07:02 -0000 1.113 +++ gstbasesink.c 30 Jan 2006 16:07:48 -0000 1.114 @@ -1,5 +1,5 @@ /* GStreamer - * Copyright (C) 2005 Wim Taymans <wi...@fl...> + * Copyright (C) 2005,2006 Wim Taymans <wi...@fl...> * * gstbasesink.c: Base class for sink elements @@ -65,10 +65,16 @@ * After synchronisation the virtual method #GstBaseSink::render will be called. * Subclasses should minimally implement this method. - * Upon receiving the EOS event in th PLAYING state, #GstBaseSink will wait for [...1160 lines suppressed...] - * we need to wait for a preroll */ - GST_DEBUG_OBJECT (basesink, "have_preroll: %d, EOS: %d", - basesink->have_preroll, basesink->eos); - if (!basesink->have_preroll && !basesink->eos - && GST_STATE_PENDING (basesink) == GST_STATE_PAUSED) { - GST_DEBUG_OBJECT (basesink, "PLAYING to PAUSED, need preroll to TRUE"); - basesink->need_preroll = TRUE; + GST_DEBUG_OBJECT (basesink, "PLAYING to PAUSED, waiting for lock"); + /* if we don't have a preroll buffer we need to wait for a preroll and + * return ASYNC. */ + if (!gst_base_sink_is_prerolled (basesink)) { + GST_DEBUG_OBJECT (basesink, "PLAYING to PAUSED, need preroll"); ret = GST_STATE_CHANGE_ASYNC; } GST_PAD_PREROLL_UNLOCK (basesink->sinkpad); break; - } case GST_STATE_CHANGE_PAUSED_TO_READY: case GST_STATE_CHANGE_READY_TO_NULL: |
From: <wt...@fr...> - 2006-02-02 16:15:50
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Thu Feb 02 2006 08:12:47 PST Log message: * libs/gst/base/gstbasesink.c: (gst_base_sink_do_sync), (gst_base_sink_render_object), (gst_base_sink_queue_object_unlocked): Only keep track of prerollable items when we are prerolling. Before rendering after preroll, always check if we have queued items. Added some more debugging. Modified files: . : ChangeLog libs/gst/base : gstbasesink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2245&r2=1.2246 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.c.diff?r1=1.115&r2=1.116 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2245 retrieving revision 1.2246 diff -u -d -r1.2245 -r1.2246 --- ChangeLog 2 Feb 2006 13:58:11 -0000 1.2245 +++ ChangeLog 2 Feb 2006 16:12:34 -0000 1.2246 @@ -1,5 +1,16 @@ 2006-02-02 Wim Taymans <wi...@fl...> + * libs/gst/base/gstbasesink.c: (gst_base_sink_do_sync), + (gst_base_sink_render_object), + (gst_base_sink_queue_object_unlocked): + Only keep track of prerollable items when we are + prerolling. + Before rendering after preroll, always check if we + have queued items. + Added some more debugging. + +2006-02-02 Wim Taymans <wi...@fl...> * gst/gstelement.c: (gst_element_continue_state), (gst_element_set_state_func), (gst_element_change_state): Fixed #326576, been running this for quite some time with Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.c,v retrieving revision 1.115 retrieving revision 1.116 diff -u -d -r1.115 -r1.116 --- gstbasesink.c 2 Feb 2006 12:07:47 -0000 1.115 +++ gstbasesink.c 2 Feb 2006 16:12:35 -0000 1.116 @@ -765,6 +765,8 @@ * any clock sync in PAUSED because there is no clock. */ while (G_UNLIKELY (basesink->need_preroll)) { + GST_DEBUG_OBJECT (basesink, "prerolling object %p", obj); if (G_LIKELY (basesink->playing_async)) { basesink->playing_async = FALSE; /* commit state */ @@ -853,15 +855,20 @@ } else { GstEvent *event = GST_EVENT_CAST (obj); gboolean ok = TRUE; + GstEventType type; bclass = GST_BASE_SINK_GET_CLASS (basesink); - GST_DEBUG_OBJECT (basesink, "rendering event %p", obj); + type = GST_EVENT_TYPE (event); + GST_DEBUG_OBJECT (basesink, "rendering event %p, type %s", obj, + gst_event_type_get_name (type)); if (bclass->event) ok = bclass->event (basesink, event); if (G_LIKELY (ok)) { - switch (GST_EVENT_TYPE (event)) { + switch (type) { case GST_EVENT_EOS: /* the EOS event is completely handled so we mark * ourselves as being in the EOS state. eos is also @@ -968,40 +975,44 @@ { GstFlowReturn ret = GST_FLOW_OK; gint length; - - if (G_LIKELY (prerollable)) - basesink->preroll_queued++; - GST_DEBUG_OBJECT (basesink, "now %d prerolled items", - basesink->preroll_queued); + GQueue *q; if (G_UNLIKELY (basesink->need_preroll)) { + if (G_LIKELY (prerollable)) + basesink->preroll_queued++; length = basesink->preroll_queued; + GST_DEBUG_OBJECT (basesink, "now %d prerolled items", length); + /* first prerollable item needs to finish the preroll */ if (length == 1) { ret = gst_base_sink_preroll_object (basesink, pad, obj); if (G_UNLIKELY (ret != GST_FLOW_OK)) goto preroll_failed; } - /* need to recheck, commmit state during preroll could have made us - * not need more preroll. */ + /* need to recheck if we need preroll, commmit state during preroll + * could have made us not need more preroll. */ if (G_UNLIKELY (basesink->need_preroll)) { - GQueue *q; /* see if we can render now. */ if (G_UNLIKELY (length <= basesink->preroll_queue_max_len)) goto more_preroll; - /* we can start rendering (or blocking) */ - GST_DEBUG_OBJECT (basesink, "emptying queue"); - q = basesink->preroll_queue; - while (G_UNLIKELY (!g_queue_is_empty (q))) { - /* FIXME, do something with the return value? */ - ret = gst_base_sink_render_object (basesink, pad, g_queue_pop_head (q)); - } } + /* we can start rendering (or blocking) the queued object + * if any. */ + q = basesink->preroll_queue; + while (G_UNLIKELY (!g_queue_is_empty (q))) { + GstMiniObject *o; + o = g_queue_pop_head (q); + GST_DEBUG_OBJECT (basesink, "rendering queued object %p", o); + /* FIXME, do something with the return value? */ + ret = gst_base_sink_render_object (basesink, pad, o); + } /* now render the object */ ret = gst_base_sink_render_object (basesink, pad, obj); basesink->preroll_queued = 0; |
From: <wt...@ke...> - 2006-03-06 15:16:37
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Mon Mar 06 2006 15:16:35 UTC Log message: * libs/gst/base/gstbasesink.c: (gst_base_sink_wait_clock), (gst_base_sink_do_sync), (gst_base_sink_render_object): Don't ever draw a frame that is >10ms late. Modified files: . : ChangeLog libs/gst/base : gstbasesink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2321&r2=1.2322 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.c.diff?r1=1.119&r2=1.120 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2321 retrieving revision 1.2322 diff -u -d -r1.2321 -r1.2322 --- ChangeLog 6 Mar 2006 14:51:36 -0000 1.2321 +++ ChangeLog 6 Mar 2006 15:16:23 -0000 1.2322 @@ -1,3 +1,9 @@ +2006-03-06 Wim Taymans <wi...@fl...> + + * libs/gst/base/gstbasesink.c: (gst_base_sink_wait_clock), + (gst_base_sink_do_sync), (gst_base_sink_render_object): + Don't ever draw a frame that is >10ms late. 2006-03-06 Michael Smith <ms...@fl...> * gst/gstmessage.c: (_gst_message_copy): Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.c,v retrieving revision 1.119 retrieving revision 1.120 diff -u -d -r1.119 -r1.120 --- gstbasesink.c 14 Feb 2006 13:07:10 -0000 1.119 +++ gstbasesink.c 6 Mar 2006 15:16:23 -0000 1.120 @@ -681,13 +681,16 @@ * release the PREROLL_LOCK so that other threads can interrupt the entry. */ static GstClockReturn -gst_base_sink_wait_clock (GstBaseSink * basesink, GstClockTime time) +gst_base_sink_wait_clock (GstBaseSink * basesink, GstClockTime time, + GstClockTimeDiff * jitter) { GstClockID id; GstClockReturn ret; GstClock *clock; GstClockTime base_time; + *jitter = 0; if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (time))) goto invalid_time; @@ -706,7 +709,7 @@ /* release the preroll lock while waiting */ GST_PAD_PREROLL_UNLOCK (basesink->sinkpad); - ret = gst_clock_id_wait (id, NULL); + ret = gst_clock_id_wait (id, jitter); GST_PAD_PREROLL_LOCK (basesink->sinkpad); gst_clock_id_unref (id); @@ -750,9 +753,10 @@ static GstFlowReturn gst_base_sink_do_sync (GstBaseSink * basesink, GstPad * pad, - GstMiniObject * obj) + GstMiniObject * obj, gboolean * late) GstClockTime start, stop; + GstClockTimeDiff jitter; gboolean syncable; GstClockReturn status = GST_CLOCK_OK; @@ -797,7 +801,7 @@ /* preroll done, we can sync since we ar in PLAYING now. */ GST_DEBUG_OBJECT (basesink, "waiting for clock"); basesink->end_time = stop; - status = gst_base_sink_wait_clock (basesink, start); + status = gst_base_sink_wait_clock (basesink, start, &jitter); GST_DEBUG_OBJECT (basesink, "clock returned %d", status); /* waiting could be interrupted and we can be flushing now */ @@ -811,7 +815,14 @@ goto again; } - /* FIXME, update clock stats here and do some QoS */ + if (status == GST_CLOCK_EARLY && jitter > (10 * GST_MSECOND)) { + /* FIXME, update clock stats here and do some QoS */ + GST_DEBUG_OBJECT (basesink, "late: jitter!! %" G_GINT64_FORMAT "\n", + jitter); + *late = TRUE; + } else { + *late = FALSE; + } return GST_FLOW_OK; @@ -845,14 +856,19 @@ GstFlowReturn ret = GST_FLOW_OK; GstBaseSinkClass *bclass; + gboolean late = FALSE; /* synchronize this object */ - ret = gst_base_sink_do_sync (basesink, pad, obj); + ret = gst_base_sink_do_sync (basesink, pad, obj, &late); if (G_UNLIKELY (ret != GST_FLOW_OK)) goto sync_failed; /* and now render */ if (G_LIKELY (GST_IS_BUFFER (obj))) { + /* drop late messages unconditionally */ + if (late) + goto dropped; bclass = GST_BASE_SINK_GET_CLASS (basesink); GST_DEBUG_OBJECT (basesink, "rendering buffer %p", obj); @@ -912,6 +928,12 @@ return ret; +dropped: + { + GST_DEBUG_OBJECT (basesink, "buffer late, dropping, unref object %p", obj); + gst_mini_object_unref (obj); + return GST_FLOW_OK; } /* with STREAM_LOCK, PREROLL_LOCK |
From: <wt...@ke...> - 2006-03-06 16:02:50
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Mon Mar 06 2006 16:02:49 UTC Log message: * libs/gst/base/gstbasesink.c: (gst_base_sink_class_init), (gst_base_sink_init), (gst_base_sink_set_property), (gst_base_sink_get_property), (gst_base_sink_do_sync): * libs/gst/base/gstbasesink.h: Make max-lateness a property. Modified files: . : ChangeLog libs/gst/base : gstbasesink.c gstbasesink.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2322&r2=1.2323 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.c.diff?r1=1.120&r2=1.121 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.h.diff?r1=1.30&r2=1.31 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2322 retrieving revision 1.2323 diff -u -d -r1.2322 -r1.2323 --- ChangeLog 6 Mar 2006 15:16:23 -0000 1.2322 +++ ChangeLog 6 Mar 2006 16:02:37 -0000 1.2323 @@ -1,5 +1,13 @@ 2006-03-06 Wim Taymans <wi...@fl...> + * libs/gst/base/gstbasesink.c: (gst_base_sink_class_init), + (gst_base_sink_init), (gst_base_sink_set_property), + (gst_base_sink_get_property), (gst_base_sink_do_sync): + * libs/gst/base/gstbasesink.h: + Make max-lateness a property. + +2006-03-06 Wim Taymans <wi...@fl...> * libs/gst/base/gstbasesink.c: (gst_base_sink_wait_clock), (gst_base_sink_do_sync), (gst_base_sink_render_object): Don't ever draw a frame that is >10ms late. Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.c,v retrieving revision 1.120 retrieving revision 1.121 diff -u -d -r1.120 -r1.121 --- gstbasesink.c 6 Mar 2006 15:16:23 -0000 1.120 +++ gstbasesink.c 6 Mar 2006 16:02:37 -0000 1.121 @@ -132,13 +132,16 @@ #define DEFAULT_CAN_ACTIVATE_PULL FALSE /* fixme: enable me */ #define DEFAULT_CAN_ACTIVATE_PUSH TRUE -#define DEFAULT_SYNC TRUE +#define DEFAULT_PREROLL_QUEUE_LEN 0 +#define DEFAULT_SYNC TRUE +#define DEFAULT_MAX_LATENESS -1 enum { PROP_0, PROP_PREROLL_QUEUE_LEN, - PROP_SYNC + PROP_SYNC, + PROP_MAX_LATENESS }; static GstElementClass *parent_class = NULL; @@ -226,14 +229,21 @@ * upstream element, ie, the BUFFER_SIZE event. */ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PREROLL_QUEUE_LEN, - g_param_spec_uint ("preroll-queue-len", "preroll-queue-len", - "Number of buffers to queue during preroll", 0, G_MAXUINT, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_param_spec_uint ("preroll-queue-len", "Preroll queue length", + "Number of buffers to queue during preroll", 0, G_MAXUINT, + DEFAULT_PREROLL_QUEUE_LEN, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SYNC, g_param_spec_boolean ("sync", "Sync", "Sync on the clock", DEFAULT_SYNC, G_PARAM_READWRITE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), + PROP_MAX_LATENESS, + g_param_spec_int64 ("max-lateness", "Max Lateness", + "Maximum number of nanoseconds that a buffer can be late before it " + "is dropped (-1 unlimited)", -1, G_MAXINT64, DEFAULT_MAX_LATENESS, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_base_sink_change_state); gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_base_sink_send_event); @@ -342,6 +352,7 @@ basesink->pad_mode = GST_ACTIVATE_NONE; basesink->preroll_queue = g_queue_new (); basesink->abidata.ABI.clip_segment = gst_segment_new (); + basesink->abidata.ABI.max_lateness = -1; basesink->can_activate_push = DEFAULT_CAN_ACTIVATE_PUSH; basesink->can_activate_pull = DEFAULT_CAN_ACTIVATE_PULL; @@ -382,6 +393,11 @@ sink->sync = g_value_get_boolean (value); GST_OBJECT_UNLOCK (sink); break; + case PROP_MAX_LATENESS: + GST_OBJECT_LOCK (sink); + sink->abidata.ABI.max_lateness = g_value_get_int64 (value); + GST_OBJECT_UNLOCK (sink); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -405,6 +421,11 @@ g_value_set_boolean (value, sink->sync); + g_value_set_int64 (value, sink->abidata.ABI.max_lateness); @@ -815,13 +836,16 @@ goto again; } - if (status == GST_CLOCK_EARLY && jitter > (10 * GST_MSECOND)) { - /* FIXME, update clock stats here and do some QoS */ - GST_DEBUG_OBJECT (basesink, "late: jitter!! %" G_GINT64_FORMAT "\n", - jitter); - *late = TRUE; - } else { - *late = FALSE; + *late = FALSE; + if (basesink->abidata.ABI.max_lateness != -1) { + if (status == GST_CLOCK_EARLY + && jitter > basesink->abidata.ABI.max_lateness) { + /* FIXME, update clock stats here and do some QoS */ + GST_DEBUG_OBJECT (basesink, "late: jitter!! %" G_GINT64_FORMAT "\n", + jitter); + *late = TRUE; + } return GST_FLOW_OK; Index: gstbasesink.h RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.h,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- gstbasesink.h 2 Feb 2006 12:07:47 -0000 1.30 +++ gstbasesink.h 6 Mar 2006 16:02:37 -0000 1.31 @@ -91,7 +91,9 @@ union { struct { /* segment used for clipping incomming buffers */ - GstSegment *clip_segment; + GstSegment *clip_segment; + /* max amount of time a buffer can be late, -1 no limit. */ + gint64 max_lateness; } ABI; /* adding + 0 to mark ABI change to be undone later */ gpointer _gst_reserved[GST_PADDING_LARGE + 0]; |
From: <wt...@ke...> - 2006-03-06 16:10:55
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Mon Mar 06 2006 16:10:54 UTC Log message: * libs/gst/base/gstbasesink.c: (gst_base_sink_class_init): Make property overridable. Modified files: . : ChangeLog libs/gst/base : gstbasesink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2323&r2=1.2324 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.c.diff?r1=1.121&r2=1.122 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2323 retrieving revision 1.2324 diff -u -d -r1.2323 -r1.2324 --- ChangeLog 6 Mar 2006 16:02:37 -0000 1.2323 +++ ChangeLog 6 Mar 2006 16:10:42 -0000 1.2324 @@ -1,5 +1,10 @@ 2006-03-06 Wim Taymans <wi...@fl...> + * libs/gst/base/gstbasesink.c: (gst_base_sink_class_init): + Make property overridable. + +2006-03-06 Wim Taymans <wi...@fl...> * libs/gst/base/gstbasesink.c: (gst_base_sink_class_init), (gst_base_sink_init), (gst_base_sink_set_property), (gst_base_sink_get_property), (gst_base_sink_do_sync): Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.c,v retrieving revision 1.121 retrieving revision 1.122 diff -u -d -r1.121 -r1.122 --- gstbasesink.c 6 Mar 2006 16:02:37 -0000 1.121 +++ gstbasesink.c 6 Mar 2006 16:10:42 -0000 1.122 @@ -242,7 +242,7 @@ g_param_spec_int64 ("max-lateness", "Max Lateness", "Maximum number of nanoseconds that a buffer can be late before it " "is dropped (-1 unlimited)", -1, G_MAXINT64, DEFAULT_MAX_LATENESS, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE)); gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_base_sink_change_state); |
From: <wt...@ke...> - 2006-03-08 09:47:10
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Wed Mar 08 2006 09:47:06 UTC Log message: * libs/gst/base/gstbasesink.c: (gst_base_sink_do_sync): Use last buffer timestamp in qos message. Modified files: . : ChangeLog libs/gst/base : gstbasesink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2331&r2=1.2332 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.c.diff?r1=1.123&r2=1.124 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2331 retrieving revision 1.2332 diff -u -d -r1.2331 -r1.2332 --- ChangeLog 7 Mar 2006 17:06:53 -0000 1.2331 +++ ChangeLog 8 Mar 2006 09:46:53 -0000 1.2332 @@ -1,3 +1,8 @@ +2006-03-08 Wim Taymans <wi...@fl...> + + * libs/gst/base/gstbasesink.c: (gst_base_sink_do_sync): + Use last buffer timestamp in qos message. 2006-03-07 Wim Taymans <wi...@fl...> * docs/pwg/advanced-tagging.xml: Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.c,v retrieving revision 1.123 retrieving revision 1.124 diff -u -d -r1.123 -r1.124 --- gstbasesink.c 7 Mar 2006 16:21:02 -0000 1.123 +++ gstbasesink.c 8 Mar 2006 09:46:54 -0000 1.124 @@ -930,7 +930,7 @@ *late = FALSE; /* FIXME, update clock stats here and do some QoS */ - if (status == GST_CLOCK_EARLY) { + if (status == GST_CLOCK_EARLY && GST_IS_BUFFER (obj)) { if (basesink->abidata.ABI.max_lateness != -1 && jitter > basesink->abidata.ABI.max_lateness) { GstEvent *event; @@ -940,7 +940,7 @@ *late = TRUE; /* generate QoS event, FIXME, calculate decent proportion. */ - event = gst_event_new_qos (-1.0, jitter, start); + event = gst_event_new_qos (-1.0, jitter, GST_BUFFER_TIMESTAMP (obj)); /* send upstream */ gst_pad_push_event (basesink->sinkpad, event); |
From: <wt...@ke...> - 2006-03-08 10:17:56
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Wed Mar 08 2006 10:17:53 UTC Log message: * libs/gst/base/gstbasetransform.c: (gst_base_transform_transform_caps), (gst_base_transform_transform_size), (gst_base_transform_prepare_output_buffer), (gst_base_transform_get_unit_size), (gst_base_transform_buffer_alloc), (gst_base_transform_handle_buffer), (gst_base_transform_change_state): Cleanups, separate normal flow from errors, add sensible DEBUG lines. Don't try to renegotiate when allocating an output buffer. Also copy DISCONT buffer flag when copying a buffer. Reset the transform after we finish streaming, not during. Modified files: . : ChangeLog libs/gst/base : gstbasetransform.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2332&r2=1.2333 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasetransform.c.diff?r1=1.71&r2=1.72 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2332 retrieving revision 1.2333 diff -u -d -r1.2332 -r1.2333 --- ChangeLog 8 Mar 2006 09:46:53 -0000 1.2332 +++ ChangeLog 8 Mar 2006 10:17:40 -0000 1.2333 @@ -1,5 +1,21 @@ 2006-03-08 Wim Taymans <wi...@fl...> + * libs/gst/base/gstbasetransform.c: + (gst_base_transform_transform_caps), + (gst_base_transform_transform_size), + (gst_base_transform_prepare_output_buffer), + (gst_base_transform_get_unit_size), + (gst_base_transform_buffer_alloc), + (gst_base_transform_handle_buffer), + (gst_base_transform_change_state): + Cleanups, separate normal flow from errors, add sensible + DEBUG lines. + Don't try to renegotiate when allocating an output buffer. + Also copy DISCONT buffer flag when copying a buffer. + Reset the transform after we finish streaming, not during. + +2006-03-08 Wim Taymans <wi...@fl...> * libs/gst/base/gstbasesink.c: (gst_base_sink_do_sync): Use last buffer timestamp in qos message. Index: gstbasetransform.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasetransform.c,v retrieving revision 1.71 retrieving revision 1.72 diff -u -d -r1.71 -r1.72 --- gstbasetransform.c 5 Mar 2006 20:56:55 -0000 1.71 +++ gstbasetransform.c 8 Mar 2006 10:17:41 -0000 1.72 @@ -213,8 +213,8 @@ static void gst_base_transform_class_init (GstBaseTransformClass * klass); static void gst_base_transform_init (GstBaseTransform * trans, GstBaseTransformClass * klass); -static GstFlowReturn gst_base_transform_prepare_output_buf (GstBaseTransform * - trans, GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf); +static GstFlowReturn gst_base_transform_prepare_output_buffer (GstBaseTransform + * trans, GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf); GType gst_base_transform_get_type (void) @@ -370,6 +370,11 @@ } } +/* given @caps on the src or sink pad (given by @direction) + * calculate the possible caps on the other pad. + * + * Returns new caps, unref after usage. + */ static GstCaps * gst_base_transform_transform_caps (GstBaseTransform * trans, GstPadDirection direction, GstCaps * caps) @@ -384,6 +389,7 @@ GstCaps *temp; gint i; + /* start with empty caps */ ret = gst_caps_new_empty (); if (gst_caps_is_any (caps)) { @@ -427,7 +433,7 @@ { guint inunitsize, outunitsize, units; GstBaseTransformClass *klass; - gint ret = -1; + gboolean ret; klass = GST_BASE_TRANSFORM_GET_CLASS (trans); @@ -440,29 +446,46 @@ ret = klass->transform_size (trans, direction, caps, size, othercaps, othersize); } else { - gboolean got_in_unit_size, got_out_unit_size; + if (!gst_base_transform_get_unit_size (trans, caps, &inunitsize)) + goto no_in_size; - got_in_unit_size = gst_base_transform_get_unit_size (trans, caps, - &inunitsize); - g_return_val_if_fail (got_in_unit_size == TRUE, FALSE); GST_DEBUG_OBJECT (trans, "input size %d, input unit size %d", size, inunitsize); - g_return_val_if_fail (inunitsize != 0, FALSE); - if (size % inunitsize != 0) { - g_warning ("Size %u is not a multiple of unit size %u", size, inunitsize); - return FALSE; - } + if (inunitsize == 0 || (size % inunitsize != 0)) + goto no_multiple; units = size / inunitsize; - got_out_unit_size = gst_base_transform_get_unit_size (trans, othercaps, - &outunitsize); - g_return_val_if_fail (got_out_unit_size == TRUE, FALSE); + if (!gst_base_transform_get_unit_size (trans, othercaps, &outunitsize)) + goto no_out_size; *othersize = units * outunitsize; GST_DEBUG_OBJECT (trans, "transformed size to %d", *othersize); - } + ret = TRUE; + } return ret; + /* ERRORS */ +no_in_size: + { + GST_DEBUG_OBJECT (trans, "could not get in_size"); + g_warning ("could not get in_size"); + return FALSE; +no_multiple: + GST_DEBUG_OBJECT (trans, "Size %u is not a multiple of unit size %u", size, + inunitsize); + g_warning ("Size %u is not a multiple of unit size %u", size, inunitsize); +no_out_size: + GST_DEBUG_OBJECT (trans, "could not get out_size"); + g_warning ("could not get out_size"); @@ -519,6 +542,8 @@ return caps; +/* function triggered when the in and out caps are negotiated and need + * to be configured in the subclass. */ static gboolean gst_base_transform_configure_caps (GstBaseTransform * trans, GstCaps * in, GstCaps * out) @@ -554,6 +579,7 @@ +/* called when new caps arrive on the sink or source pad */ gst_base_transform_setcaps (GstPad * pad, GstCaps * caps) @@ -789,18 +815,12 @@ -/* Allocate a buffer using gst_pad_alloc_buffer_and_set_caps. +/* Allocate a buffer using gst_pad_alloc_buffer * - * This function can trigger a renegotiation on the source pad when the - * peer alloc_buffer function sets new caps. Since we currently are - * processing a buffer on the sinkpad when this function is called, we cannot - * reconfigure the transform with sinkcaps different from those of the current - * buffer. FIXME, we currently don't check if the pluging can transform to the - * new srcpad caps using the same sinkcaps, we alloc a proper outbuf buffer - * ourselves instead. + * This function does not do renegotiation on the source pad */ static GstFlowReturn -gst_base_transform_prepare_output_buf (GstBaseTransform * trans, +gst_base_transform_prepare_output_buffer (GstBaseTransform * trans, GstBuffer * in_buf, gint out_size, GstCaps * out_caps, GstBuffer ** out_buf) GstBaseTransformClass *bclass; @@ -850,8 +870,7 @@ if (*out_buf == NULL) { /* Sub-class didn't already provide a buffer for us. Make one */ - ret = - gst_pad_alloc_buffer_and_set_caps (trans->srcpad, + ret = gst_pad_alloc_buffer (trans->srcpad, GST_BUFFER_OFFSET (in_buf), out_size, out_caps, out_buf); if (ret != GST_FLOW_OK || *out_buf == NULL) goto done; @@ -868,15 +887,15 @@ /* If the output buffer metadata is modifiable, copy timestamps and * buffer flags */ - if (*out_buf != in_buf && gst_buffer_is_metadata_writable (*out_buf) == 1) { + if (*out_buf != in_buf && gst_buffer_is_metadata_writable (*out_buf)) { if (copy_inbuf && gst_buffer_is_writable (*out_buf)) memcpy (GST_BUFFER_DATA (*out_buf), GST_BUFFER_DATA (in_buf), out_size); gst_buffer_stamp (*out_buf, in_buf); GST_BUFFER_FLAGS (*out_buf) |= GST_BUFFER_FLAGS (in_buf) & - (GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_IN_CAPS | - GST_BUFFER_FLAG_DELTA_UNIT); + (GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_DISCONT | + GST_BUFFER_FLAG_IN_CAPS | GST_BUFFER_FLAG_DELTA_UNIT); done: @@ -887,6 +906,19 @@ +/* Given @caps calcultate the size of one unit. + * For video caps, this is the size of one frame (and thus one buffer). + * For audio caps, this is the size of one sample. + * These values are cached since they do not change and the calculation + * potentially involves parsing caps and other expensive stuff. + * We have two cache locations to store the size, one for the source caps + * and one for the sink caps. + * this function returns FALSE if no size could be calculated. gst_base_transform_get_unit_size (GstBaseTransform * trans, GstCaps * caps, guint * size) @@ -897,12 +929,12 @@ /* see if we have the result cached */ if (trans->cache_caps1 == caps) { *size = trans->cache_caps1_size; - GST_DEBUG_OBJECT (trans, "get size returned cached 1 %d", *size); + GST_DEBUG_OBJECT (trans, "returned %d from first cache", *size); return TRUE; if (trans->cache_caps2 == caps) { *size = trans->cache_caps2_size; - GST_DEBUG_OBJECT (trans, "get size returned cached 2 %d", *size); + GST_DEBUG_OBJECT (trans, "returned %d from second cached", *size); @@ -913,16 +945,21 @@ ") has unit size %d, result %s", caps, *size, res ? "TRUE" : "FALSE"); if (res) { + /* and cache the values */ if (trans->cache_caps1 == NULL) { gst_caps_replace (&trans->cache_caps1, caps); trans->cache_caps1_size = *size; + GST_DEBUG_OBJECT (trans, "caching %d in first cache", *size); } else if (trans->cache_caps2 == NULL) { gst_caps_replace (&trans->cache_caps2, caps); trans->cache_caps2_size = *size; + GST_DEBUG_OBJECT (trans, "caching %d in second cache", *size); + } else { + GST_DEBUG_OBJECT (trans, "no free spot to cache unit_size"); } } - GST_DEBUG ("Sub-class does not implement get_unit_size"); + GST_DEBUG_OBJECT (trans, "Sub-class does not implement get_unit_size"); return res; @@ -947,7 +984,7 @@ *buf = NULL; - GST_DEBUG_OBJECT (trans, "allocating a buffer of size %d ...", size, offset); + GST_DEBUG_OBJECT (trans, "allocating a buffer of size %d ...", size); if (offset == GST_BUFFER_OFFSET_NONE) GST_DEBUG_OBJECT (trans, "... and offset NONE"); else @@ -1022,8 +1059,9 @@ gst_caps_unref (srccaps); gst_caps_unref (sinkcaps); - g_mutex_unlock (trans->transform_lock); +done: + g_mutex_unlock (trans->transform_lock); gst_object_unref (trans); @@ -1032,25 +1070,17 @@ { /* let the default allocator handle it */ GST_DEBUG_OBJECT (trans, "not configured"); - if (*buf) { - gst_buffer_unref (*buf); - *buf = NULL; - g_mutex_unlock (trans->transform_lock); - gst_object_unref (trans); - return GST_FLOW_OK; + gst_buffer_replace (buf, NULL); + res = GST_FLOW_OK; + goto done; unknown_size: GST_DEBUG_OBJECT (trans, "unknown size"); @@ -1182,7 +1212,7 @@ * wish. */ GST_LOG_OBJECT (trans, "doing inplace transform"); - ret = gst_base_transform_prepare_output_buf (trans, inbuf, + ret = gst_base_transform_prepare_output_buffer (trans, inbuf, GST_BUFFER_SIZE (inbuf), GST_PAD_CAPS (trans->srcpad), outbuf); if (G_UNLIKELY (ret != GST_FLOW_OK)) goto no_buffer; @@ -1206,7 +1236,7 @@ /* no in place transform, get buffer, this might renegotiate. */ - ret = gst_base_transform_prepare_output_buf (trans, inbuf, out_size, + ret = gst_base_transform_prepare_output_buffer (trans, inbuf, out_size, GST_PAD_CAPS (trans->srcpad), outbuf); if (ret != GST_FLOW_OK) @@ -1253,7 +1283,8 @@ no_buffer: gst_buffer_unref (inbuf); - GST_DEBUG_OBJECT (trans, "could not get buffer from pool"); + GST_DEBUG_OBJECT (trans, "could not get buffer from pool: %s", + gst_flow_get_name (ret)); return ret; configure_failed: @@ -1414,15 +1445,6 @@ break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - case GST_STATE_CHANGE_PAUSED_TO_READY: - trans->have_same_caps = FALSE; - /* We can only reset the passthrough mode if the instance told us to - handle it in configure_caps */ - if (bclass->passthrough_on_same_caps) { - gst_base_transform_set_passthrough (trans, FALSE); - } - gst_caps_replace (&trans->cache_caps1, NULL); - gst_caps_replace (&trans->cache_caps2, NULL); default: @@ -1433,6 +1455,14 @@ case GST_STATE_CHANGE_PLAYING_TO_PAUSED: case GST_STATE_CHANGE_PAUSED_TO_READY: + trans->have_same_caps = FALSE; + /* We can only reset the passthrough mode if the instance told us to + handle it in configure_caps */ + if (bclass->passthrough_on_same_caps) { + gst_base_transform_set_passthrough (trans, FALSE); + } + gst_caps_replace (&trans->cache_caps1, NULL); + gst_caps_replace (&trans->cache_caps2, NULL); if (bclass->stop) result = bclass->stop (trans); |
From: <wt...@ke...> - 2006-03-13 11:16:59
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Mon Mar 13 2006 11:16:57 UTC Log message: * libs/gst/base/gstbasesink.c: (gst_base_sink_init), (gst_base_sink_do_sync): Small cleanups. Use QOS debug category. Modified files: . : ChangeLog libs/gst/base : gstbasesink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2352&r2=1.2353 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.c.diff?r1=1.126&r2=1.127 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2352 retrieving revision 1.2353 diff -u -d -r1.2352 -r1.2353 --- ChangeLog 13 Mar 2006 11:11:16 -0000 1.2352 +++ ChangeLog 13 Mar 2006 11:16:44 -0000 1.2353 @@ -1,5 +1,12 @@ 2006-03-13 Wim Taymans <wi...@fl...> + * libs/gst/base/gstbasesink.c: (gst_base_sink_init), + (gst_base_sink_do_sync): + Small cleanups. + Use QOS debug category. + +2006-03-13 Wim Taymans <wi...@fl...> * plugins/elements/gstqueue.c: Very small doc update. Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.c,v retrieving revision 1.126 retrieving revision 1.127 diff -u -d -r1.126 -r1.127 --- gstbasesink.c 10 Mar 2006 19:12:01 -0000 1.126 +++ gstbasesink.c 13 Mar 2006 11:16:45 -0000 1.127 @@ -124,6 +124,7 @@ #include "gstbasesink.h" #include <gst/gstmarshal.h> +#include <gst/gst_private.h> #include <gst/gst-i18n-lib.h> GST_DEBUG_CATEGORY_STATIC (gst_base_sink_debug); @@ -361,12 +362,12 @@ basesink->pad_mode = GST_ACTIVATE_NONE; basesink->preroll_queue = g_queue_new (); basesink->abidata.ABI.clip_segment = gst_segment_new (); - basesink->abidata.ABI.max_lateness = -1; basesink->can_activate_push = DEFAULT_CAN_ACTIVATE_PUSH; basesink->can_activate_pull = DEFAULT_CAN_ACTIVATE_PULL; basesink->sync = DEFAULT_SYNC; + basesink->abidata.ABI.max_lateness = DEFAULT_MAX_LATENESS; GST_OBJECT_FLAG_SET (basesink, GST_ELEMENT_IS_SINK); } @@ -600,6 +601,7 @@ /* with PREROLL_LOCK, STREAM_LOCK */ +/* FIXME, call change_state function, see #326311 */ static gboolean gst_base_sink_commit_state (GstBaseSink * basesink) { @@ -856,11 +858,18 @@ * if needed and then block if we still are not PLAYING. * * We start waiting on the clock in PLAYING. If we got interrupted, we - * immediatly try to repreroll. + * immediatly try to re-preroll. * Some objects do not need synchronisation (most events) and so this function * immediatly returns GST_FLOW_OK. + * objects that arrive later than max-lateness to be synchronized to the clock + * generate a QoS message upstream and the @late boolean is set to TRUE. + * + * This function keeps a running average of the jitter (the diff between the + * clock time and the requested sync time). The jitter is negative for + * objects that arrive in time and positive for late buffers. * does not take ownership of obj. */ static GstFlowReturn @@ -871,6 +880,7 @@ GstClockTimeDiff jitter; gboolean syncable; GstClockReturn status = GST_CLOCK_OK; + GstClockTime timestamp; /* get timing information for this object */ start = stop = -1; @@ -914,6 +924,8 @@ GST_DEBUG_OBJECT (basesink, "waiting for clock to reach %" GST_TIME_FORMAT, GST_TIME_ARGS (start)); basesink->end_time = stop; + /* this function will return immediatly if start == -1 with + * GST_CLOCK_OK and jitter = 0. */ status = gst_base_sink_wait_clock (basesink, start, &jitter); GST_DEBUG_OBJECT (basesink, "clock returned %d", status); @@ -930,24 +942,45 @@ *late = FALSE; - /* FIXME, update clock stats here and do some QoS */ - if (status == GST_CLOCK_EARLY && GST_IS_BUFFER (obj)) { + /* only do stats for buffers */ + if (G_UNLIKELY (!GST_IS_BUFFER (obj))) + goto done; + /* did not sync on this object, we don't need to do stats */ + if (start == -1) + /* can't do stats if we don't have a timestamp */ + if ((timestamp = GST_BUFFER_TIMESTAMP (obj)) == -1) + /* FIXME, do stats here in jitter. This could be used to derive + * a trend, which should then result in an updated proportion. */ + if (status == GST_CLOCK_EARLY) { if (basesink->abidata.ABI.max_lateness != -1 && jitter > basesink->abidata.ABI.max_lateness) { GstEvent *event; + gdouble proportion; - GST_DEBUG_OBJECT (basesink, "late: jitter!! %" G_GINT64_FORMAT "\n", - jitter); + GST_DEBUG_OBJECT (basesink, "late: jitter!! %" G_GINT64_FORMAT, jitter); *late = TRUE; - /* generate QoS event, FIXME, calculate decent proportion. */ - event = gst_event_new_qos (-1.0, jitter, GST_BUFFER_TIMESTAMP (obj)); + /* generate QoS event, proportion is still silly. */ + proportion = 0.0; + GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, basesink, + "qos: proportion: %lf, diff %" G_GUINT64_FORMAT ", timestamp %" + GST_TIME_FORMAT, proportion, jitter, GST_TIME_ARGS (timestamp)); + event = gst_event_new_qos (proportion, jitter, timestamp); /* send upstream */ gst_pad_push_event (basesink->sinkpad, event); } } +done: return GST_FLOW_OK; /* ERRORS */ |
From: <wt...@ke...> - 2006-03-13 11:28:11
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Mon Mar 13 2006 11:28:09 UTC Log message: * libs/gst/base/gstbasetransform.c: (gst_base_transform_class_init), (gst_base_transform_init), (gst_base_transform_sink_event), (gst_base_transform_sink_eventfunc), (gst_base_transform_src_event), (gst_base_transform_src_eventfunc), (gst_base_transform_handle_buffer), (gst_base_transform_chain), (gst_base_transform_set_property), (gst_base_transform_get_property), (gst_base_transform_change_state), (gst_base_transform_update_qos), (gst_base_transform_set_qos_enabled), (gst_base_transform_is_qos_enabled): * libs/gst/base/gstbasetransform.h: Make basetransform virtual method for src events too. Handle QOS in basetransform. API: gst_base_transform_update_qos API: gst_base_transform_set_qos_enabled API: gst_base_transform_is_qos_enabled Modified files: . : ChangeLog libs/gst/base : gstbasetransform.c gstbasetransform.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2353&r2=1.2354 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasetransform.c.diff?r1=1.72&r2=1.73 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasetransform.h.diff?r1=1.28&r2=1.29 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2353 retrieving revision 1.2354 diff -u -d -r1.2353 -r1.2354 --- ChangeLog 13 Mar 2006 11:16:44 -0000 1.2353 +++ ChangeLog 13 Mar 2006 11:27:57 -0000 1.2354 @@ -1,5 +1,25 @@ 2006-03-13 Wim Taymans <wi...@fl...> + * libs/gst/base/gstbasetransform.c: + (gst_base_transform_class_init), (gst_base_transform_init), + (gst_base_transform_sink_event), + (gst_base_transform_sink_eventfunc), + (gst_base_transform_src_event), (gst_base_transform_src_eventfunc), + (gst_base_transform_handle_buffer), (gst_base_transform_chain), + (gst_base_transform_set_property), + (gst_base_transform_get_property), + (gst_base_transform_change_state), (gst_base_transform_update_qos), + (gst_base_transform_set_qos_enabled), + (gst_base_transform_is_qos_enabled): + * libs/gst/base/gstbasetransform.h: + Make basetransform virtual method for src events too. + Handle QOS in basetransform. + API: gst_base_transform_update_qos + API: gst_base_transform_set_qos_enabled + API: gst_base_transform_is_qos_enabled + +2006-03-13 Wim Taymans <wi...@fl...> * libs/gst/base/gstbasesink.c: (gst_base_sink_init), (gst_base_sink_do_sync): Small cleanups. Index: gstbasetransform.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasetransform.c,v retrieving revision 1.72 retrieving revision 1.73 diff -u -d -r1.72 -r1.73 --- gstbasetransform.c 8 Mar 2006 10:17:41 -0000 1.72 +++ gstbasetransform.c 13 Mar 2006 11:27:57 -0000 1.73 @@ -188,6 +188,7 @@ #include <stdlib.h> #include <string.h> +#include "../../../gst/gst_private.h" #include "../../../gst/gst-i18n-lib.h" #include "gstbasetransform.h" #include <gst/gstmarshal.h> @@ -202,9 +203,23 @@ LAST_SIGNAL }; +#define DEFAULT_PROP_QOS FALSE enum { PROP_0, + PROP_QOS +}; +#define GST_BASE_TRANSFORM_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_BASE_TRANSFORM, GstBaseTransformPrivate)) +struct _GstBaseTransformPrivate +{ + /* QoS *//* with LOCK */ + gboolean qos_enabled; + gdouble proportion; + GstClockTime earliest_time; static GstElementClass *parent_class = NULL; @@ -255,8 +270,11 @@ static GstStateChangeReturn gst_base_transform_change_state (GstElement * element, GstStateChange transition); -static gboolean gst_base_transform_event (GstPad * pad, GstEvent * event); -static gboolean gst_base_transform_eventfunc (GstBaseTransform * trans, +static gboolean gst_base_transform_src_event (GstPad * pad, GstEvent * event); +static gboolean gst_base_transform_src_eventfunc (GstBaseTransform * trans, + GstEvent * event); +static gboolean gst_base_transform_sink_event (GstPad * pad, GstEvent * event); +static gboolean gst_base_transform_sink_eventfunc (GstBaseTransform * trans, GstEvent * event); static GstFlowReturn gst_base_transform_getrange (GstPad * pad, guint64 offset, guint length, GstBuffer ** buffer); @@ -297,6 +315,8 @@ gobject_class = G_OBJECT_CLASS (klass); gstelement_class = GST_ELEMENT_CLASS (klass); + g_type_class_add_private (klass, sizeof (GstBaseTransformPrivate)); parent_class = g_type_class_peek_parent (klass); gobject_class->set_property = @@ -304,13 +324,18 @@ gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_base_transform_get_property); + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_QOS, + g_param_spec_boolean ("qos", "QoS", "handle QoS messages", + DEFAULT_PROP_QOS, G_PARAM_READWRITE)); gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_base_transform_finalize); gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_base_transform_change_state); klass->passthrough_on_same_caps = FALSE; - klass->event = GST_DEBUG_FUNCPTR (gst_base_transform_eventfunc); + klass->event = GST_DEBUG_FUNCPTR (gst_base_transform_sink_eventfunc); + klass->src_event = GST_DEBUG_FUNCPTR (gst_base_transform_src_eventfunc); } static void @@ -321,6 +346,8 @@ GST_DEBUG ("gst_base_transform_init"); + trans->priv = GST_BASE_TRANSFORM_GET_PRIVATE (trans); pad_template = gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "sink"); g_return_if_fail (pad_template != NULL); @@ -330,7 +357,7 @@ gst_pad_set_setcaps_function (trans->sinkpad, GST_DEBUG_FUNCPTR (gst_base_transform_setcaps)); gst_pad_set_event_function (trans->sinkpad, - GST_DEBUG_FUNCPTR (gst_base_transform_event)); + GST_DEBUG_FUNCPTR (gst_base_transform_sink_event)); gst_pad_set_chain_function (trans->sinkpad, GST_DEBUG_FUNCPTR (gst_base_transform_chain)); gst_pad_set_activatepush_function (trans->sinkpad, @@ -347,6 +374,8 @@ GST_DEBUG_FUNCPTR (gst_base_transform_getcaps)); gst_pad_set_setcaps_function (trans->srcpad, + gst_pad_set_event_function (trans->srcpad, + GST_DEBUG_FUNCPTR (gst_base_transform_src_event)); gst_pad_set_getrange_function (trans->srcpad, GST_DEBUG_FUNCPTR (gst_base_transform_getrange)); gst_pad_set_activatepull_function (trans->srcpad, @@ -356,6 +385,7 @@ trans->transform_lock = g_mutex_new (); trans->delay_configure = FALSE; trans->pending_configure = FALSE; + trans->priv->qos_enabled = DEFAULT_PROP_QOS; trans->cache_caps1 = NULL; trans->cache_caps2 = NULL; @@ -1085,7 +1115,7 @@ static gboolean -gst_base_transform_event (GstPad * pad, GstEvent * event) +gst_base_transform_sink_event (GstPad * pad, GstEvent * event) GstBaseTransform *trans; GstBaseTransformClass *bclass; @@ -1100,7 +1130,7 @@ /* FIXME, do this in the default event handler so the subclass can do * something different. */ if (ret) - ret = gst_pad_event_default (pad, event); + ret = gst_pad_push_event (trans->srcpad, event); gst_object_unref (trans); @@ -1108,12 +1138,17 @@ -gst_base_transform_eventfunc (GstBaseTransform * trans, GstEvent * event) +gst_base_transform_sink_eventfunc (GstBaseTransform * trans, GstEvent * event) switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_START: break; case GST_EVENT_FLUSH_STOP: + GST_OBJECT_LOCK (trans); + /* reset QoS parameters */ + trans->priv->proportion = 1.0; + trans->priv->earliest_time = -1; + GST_OBJECT_UNLOCK (trans); /* we need new segment info after the flush. */ gst_segment_init (&trans->segment, GST_FORMAT_UNDEFINED); @@ -1163,6 +1198,53 @@ return TRUE; +static gboolean +gst_base_transform_src_event (GstPad * pad, GstEvent * event) + GstBaseTransform *trans; + GstBaseTransformClass *bclass; + gboolean ret = TRUE; + trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad)); + bclass = GST_BASE_TRANSFORM_GET_CLASS (trans); + if (bclass->src_event) + ret = bclass->src_event (trans, event); + gst_object_unref (trans); + return ret; +} +gst_base_transform_src_eventfunc (GstBaseTransform * trans, GstEvent * event) + gboolean ret; + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_SEEK: + break; + case GST_EVENT_NAVIGATION: + case GST_EVENT_QOS: + { + gdouble proportion; + GstClockTimeDiff diff; + GstClockTime timestamp; + gst_event_parse_qos (event, &proportion, &diff, ×tamp); + gst_base_transform_update_qos (trans, proportion, diff, timestamp); + } + default: + } + ret = gst_pad_push_event (trans->sinkpad, event); static GstFlowReturn gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf, GstBuffer ** outbuf) @@ -1171,6 +1253,7 @@ GstFlowReturn ret = GST_FLOW_OK; guint out_size; gboolean want_in_place; + GstClockTime outtime; bclass = GST_BASE_TRANSFORM_GET_CLASS (trans); @@ -1189,6 +1272,26 @@ if (!trans->negotiated && !trans->passthrough && (bclass->set_caps != NULL)) goto not_negotiated; + if ((outtime = GST_BUFFER_TIMESTAMP (inbuf)) != -1) { + gboolean need_skip; + GstClockTime earliest_time; + GST_OBJECT_LOCK (trans); + earliest_time = trans->priv->earliest_time; + /* check for QoS, don't perform conversion for buffers + * that are known to be late. */ + need_skip = trans->priv->qos_enabled && + earliest_time != -1 && outtime <= earliest_time; + GST_OBJECT_UNLOCK (trans); + if (need_skip) { + GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, trans, "skipping transform: outtime %" + GST_TIME_FORMAT " <= %" GST_TIME_FORMAT, + GST_TIME_ARGS (outtime), GST_TIME_ARGS (earliest_time)); + goto skip; if (trans->passthrough) { /* In passthrough mode, give transform_ip a look at the * buffer, without making it writable, or just push the @@ -1260,6 +1363,7 @@ if (!success) goto configure_failed; } +skip: gst_buffer_unref (inbuf); return ret; @@ -1334,10 +1438,13 @@ ret = gst_base_transform_handle_buffer (trans, buffer, &outbuf); g_mutex_unlock (trans->transform_lock); - if (ret == GST_FLOW_OK) { - ret = gst_pad_push (trans->srcpad, outbuf); - } else if (outbuf != NULL) - gst_buffer_unref (outbuf); + /* outbuf can be NULL, this means a dropped buffer */ + if (outbuf != NULL) { + if (ret == GST_FLOW_OK) + ret = gst_pad_push (trans->srcpad, outbuf); + else + gst_buffer_unref (outbuf); @@ -1353,6 +1460,9 @@ trans = GST_BASE_TRANSFORM (object); switch (prop_id) { + case PROP_QOS: + gst_base_transform_set_qos_enabled (trans, g_value_get_boolean (value)); default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1368,6 +1478,9 @@ + g_value_set_boolean (value, gst_base_transform_is_qos_enabled (trans)); @@ -1441,6 +1554,8 @@ trans->negotiated = FALSE; trans->have_newsegment = FALSE; GST_OBJECT_UNLOCK (trans); case GST_STATE_CHANGE_PAUSED_TO_PLAYING: @@ -1598,3 +1713,82 @@ return result; +/** + * gst_base_transform_update_qos: + * @trans: a #GstBaseTransform + * @proportion: the proportion + * @diff: the diff against the clock + * @timestamp: the timestamp of the buffer generating the QoS + * + * Set the QoS parameters in the transform. + * Since: 0.10.5 + * MT safe. + */ +void +gst_base_transform_update_qos (GstBaseTransform * trans, + gdouble proportion, GstClockTimeDiff diff, GstClockTime timestamp) + g_return_if_fail (trans != NULL); + GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, trans, + "qos: proportion: %lf, diff %" G_GINT64_FORMAT ", timestamp %" + GST_TIME_FORMAT, proportion, diff, GST_TIME_ARGS (timestamp)); + GST_OBJECT_LOCK (trans); + trans->priv->proportion = proportion; + trans->priv->earliest_time = timestamp + diff; + GST_OBJECT_UNLOCK (trans); + * gst_base_transform_set_qos_enabled: + * @enabled: new state + * Enable or disable QoS handling in the transform. +gst_base_transform_set_qos_enabled (GstBaseTransform * trans, gboolean enabled) + GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, trans, "enabled: %d", enabled); + trans->priv->qos_enabled = enabled; + * gst_base_transform_is_qos_enabled: + * Queries if the transform will handle QoS. + * Returns: TRUE if QoS is enabled. +gboolean +gst_base_transform_is_qos_enabled (GstBaseTransform * trans) + gboolean result; + g_return_val_if_fail (trans != NULL, FALSE); + result = trans->priv->qos_enabled; + return result; Index: gstbasetransform.h RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasetransform.h,v retrieving revision 1.28 retrieving revision 1.29 diff -u -d -r1.28 -r1.29 --- gstbasetransform.h 7 Mar 2006 15:14:51 -0000 1.28 +++ gstbasetransform.h 13 Mar 2006 11:27:57 -0000 1.29 @@ -70,6 +70,8 @@ typedef struct _GstBaseTransform GstBaseTransform; typedef struct _GstBaseTransformClass GstBaseTransformClass; +typedef struct _GstBaseTransformPrivate GstBaseTransformPrivate; /** * GstBaseTransform: @@ -107,7 +109,9 @@ GMutex *transform_lock; /*< private >*/ - gpointer _gst_reserved[GST_PADDING_LARGE]; + GstBaseTransformPrivate *priv; + gpointer _gst_reserved[GST_PADDING_LARGE - 1]; @@ -157,6 +161,7 @@ gboolean (*start) (GstBaseTransform *trans); gboolean (*stop) (GstBaseTransform *trans); + /* sink event */ gboolean (*event) (GstBaseTransform *trans, GstEvent *event); /* transform one incoming buffer to one outgoing buffer. @@ -180,8 +185,11 @@ GstFlowReturn (*prepare_output_buffer) (GstBaseTransform * trans, GstBuffer *input, gint size, GstCaps *caps, GstBuffer **buf); + /* src event */ + gboolean (*src_event) (GstBaseTransform *trans, GstEvent *event); GType gst_base_transform_get_type (void); @@ -194,6 +202,13 @@ gboolean in_place); gboolean gst_base_transform_is_in_place (GstBaseTransform *trans); +void gst_base_transform_update_qos (GstBaseTransform *trans, + gdouble proportion, + GstClockTimeDiff diff, + GstClockTime timestamp); +void gst_base_transform_set_qos_enabled (GstBaseTransform *trans, + gboolean enabled); +gboolean gst_base_transform_is_qos_enabled (GstBaseTransform *trans); G_END_DECLS |
From: <wt...@ke...> - 2006-03-14 11:18:21
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Tue Mar 14 2006 11:18:19 UTC Log message: * libs/gst/base/gstbasesink.c: (gst_base_sink_do_sync), (gst_base_sink_do_qos): Separate QoS calculation. Only drop buffers when lateness is bigger than the duration of the buffer. Modified files: . : ChangeLog libs/gst/base : gstbasesink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2355&r2=1.2356 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.c.diff?r1=1.127&r2=1.128 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2355 retrieving revision 1.2356 diff -u -d -r1.2355 -r1.2356 --- ChangeLog 13 Mar 2006 15:17:45 -0000 1.2355 +++ ChangeLog 14 Mar 2006 11:18:07 -0000 1.2356 @@ -1,3 +1,11 @@ +2006-03-14 Wim Taymans <wi...@fl...> + + * libs/gst/base/gstbasesink.c: (gst_base_sink_do_sync), + (gst_base_sink_do_qos): + Separate QoS calculation. + Only drop buffers when lateness is bigger than the + duration of the buffer. 2006-03-13 Wim Taymans <wi...@fl...> * gst/gstpipeline.c: (gst_pipeline_set_property), Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.c,v retrieving revision 1.127 retrieving revision 1.128 diff -u -d -r1.127 -r1.128 --- gstbasesink.c 13 Mar 2006 11:16:45 -0000 1.127 +++ gstbasesink.c 14 Mar 2006 11:18:07 -0000 1.128 @@ -213,6 +213,9 @@ static gboolean gst_base_sink_activate_pull (GstPad * pad, gboolean active); static gboolean gst_base_sink_event (GstPad * pad, GstEvent * event); +static gboolean gst_base_sink_do_qos (GstBaseSink * basesink, + GstMiniObject * obj, GstClockReturn status, GstClockTimeDiff jitter); static void gst_base_sink_base_init (gpointer g_class) { @@ -880,7 +883,6 @@ GstClockTimeDiff jitter; gboolean syncable; GstClockReturn status = GST_CLOCK_OK; - GstClockTime timestamp; /* get timing information for this object */ start = stop = -1; @@ -940,64 +942,116 @@ goto again; } - *late = FALSE; + /* perform QoS */ + *late = gst_base_sink_do_qos (basesink, obj, status, jitter); + return GST_FLOW_OK; + /* ERRORS */ +not_syncable: + { + GST_DEBUG_OBJECT (basesink, "non syncable object %p", obj); + return GST_FLOW_OK; + } +flushing: + GST_DEBUG_OBJECT (basesink, "we are flushing"); + return GST_FLOW_WRONG_STATE; +stopping: + GST_DEBUG_OBJECT (basesink, "stopping while commiting state"); +} +/* perform QoS on the given object. + * + * If the object was scheduled later that max_lateness we generate + * a QoS message upstream. + * returns TRUE if the buffer was too late. + */ +static gboolean +gst_base_sink_do_qos (GstBaseSink * basesink, GstMiniObject * obj, + GstClockReturn status, GstClockTimeDiff jitter) +{ + gboolean late; + GstClockTime timestamp, duration; + gint64 max_lateness; + /* only for buffers that are too late */ + if (status != GST_CLOCK_EARLY) + goto in_time; /* only do stats for buffers */ if (G_UNLIKELY (!GST_IS_BUFFER (obj))) - goto done; - - /* did not sync on this object, we don't need to do stats */ - if (start == -1) + goto not_buffer; /* can't do stats if we don't have a timestamp */ - if ((timestamp = GST_BUFFER_TIMESTAMP (obj)) == -1) + if (G_UNLIKELY ((timestamp = GST_BUFFER_TIMESTAMP (obj)) == -1)) + goto no_timestamp; + /* if the jitter bigger than duration we are too late */ + if (G_UNLIKELY ((duration = GST_BUFFER_DURATION (obj)) != -1)) + late = jitter > duration; + else + late = FALSE; + /* copy for code clarity */ + max_lateness = basesink->abidata.ABI.max_lateness; + /* check if we need to do qos */ + if (max_lateness == -1 || jitter <= max_lateness) + goto no_qos; /* FIXME, do stats here in jitter. This could be used to derive * a trend, which should then result in an updated proportion. */ + GstEvent *event; + gdouble proportion; - if (status == GST_CLOCK_EARLY) { - if (basesink->abidata.ABI.max_lateness != -1 - && jitter > basesink->abidata.ABI.max_lateness) { - GstEvent *event; - gdouble proportion; + GST_DEBUG_OBJECT (basesink, "late: jitter!! %" G_GINT64_FORMAT, jitter); - GST_DEBUG_OBJECT (basesink, "late: jitter!! %" G_GINT64_FORMAT, jitter); - *late = TRUE; + /* generate QoS event, proportion is still silly. */ + proportion = 0.0; - /* generate QoS event, proportion is still silly. */ - proportion = 0.0; + GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, basesink, + "qos: proportion: %lf, diff %" G_GUINT64_FORMAT ", timestamp %" + GST_TIME_FORMAT, proportion, jitter, GST_TIME_ARGS (timestamp)); - GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, basesink, - "qos: proportion: %lf, diff %" G_GUINT64_FORMAT ", timestamp %" - GST_TIME_FORMAT, proportion, jitter, GST_TIME_ARGS (timestamp)); + event = gst_event_new_qos (proportion, jitter, timestamp); - event = gst_event_new_qos (proportion, jitter, timestamp); + /* if no duration set, we assume lateness here as well. */ + if (duration == -1) + late = TRUE; - /* send upstream */ - gst_pad_push_event (basesink->sinkpad, event); - } + /* send upstream */ + gst_pad_push_event (basesink->sinkpad, event); -done: - return GST_FLOW_OK; + return late; - /* ERRORS */ -not_syncable: + /* cases where no qos is needed */ +in_time: { - GST_DEBUG_OBJECT (basesink, "non syncable object %p", obj); - return GST_FLOW_OK; + GST_DEBUG_OBJECT (basesink, "object was scheduled in time"); + return FALSE; -flushing: +not_buffer: - GST_DEBUG_OBJECT (basesink, "we are flushing"); - return GST_FLOW_WRONG_STATE; + GST_DEBUG_OBJECT (basesink, "object is not a buffer"); -stopping: +no_timestamp: - GST_DEBUG_OBJECT (basesink, "stopping while commiting state"); + GST_DEBUG_OBJECT (basesink, "buffer has no timestamp"); +no_qos: + GST_DEBUG_OBJECT (basesink, "qos disabled"); + return late; } |
From: <wt...@ke...> - 2006-03-14 19:36:18
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Tue Mar 14 2006 19:36:17 UTC Log message: * libs/gst/base/gstbasesink.c: (gst_base_sink_configure_segment), (gst_base_sink_get_sync_times), (gst_base_sink_wait_clock), (gst_base_sink_do_sync), (gst_base_sink_do_qos): Better debug info when we receive a segment event. Reorganize a bit so we can pass the get_times() results around. Use the segment format when calculating the running time. Don't do QoS is sync is disabled or we have no clock or the element does not want us to sync to the clock. Don't drop buffers if QoS is disabled for now. Modified files: . : ChangeLog libs/gst/base : gstbasesink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2361&r2=1.2362 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.c.diff?r1=1.129&r2=1.130 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2361 retrieving revision 1.2362 diff -u -d -r1.2361 -r1.2362 --- ChangeLog 14 Mar 2006 19:28:20 -0000 1.2361 +++ ChangeLog 14 Mar 2006 19:36:04 -0000 1.2362 @@ -1,5 +1,17 @@ 2006-03-14 Wim Taymans <wi...@fl...> + * libs/gst/base/gstbasesink.c: (gst_base_sink_configure_segment), + (gst_base_sink_get_sync_times), (gst_base_sink_wait_clock), + (gst_base_sink_do_sync), (gst_base_sink_do_qos): + Better debug info when we receive a segment event. + Reorganize a bit so we can pass the get_times() results around. + Use the segment format when calculating the running time. + Don't do QoS is sync is disabled or we have no clock or the + element does not want us to sync to the clock. + Don't drop buffers if QoS is disabled for now. + +2006-03-14 Wim Taymans <wi...@fl...> * gst/gstclock.c: (gst_clock_class_init), (do_linear_regression): Marked the stats property as unimplemented so people don't get wild ideas. Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.c,v retrieving revision 1.129 retrieving revision 1.130 diff -u -d -r1.129 -r1.130 --- gstbasesink.c 14 Mar 2006 18:25:54 -0000 1.129 +++ gstbasesink.c 14 Mar 2006 19:36:05 -0000 1.130 @@ -214,7 +214,8 @@ static gboolean gst_base_sink_event (GstPad * pad, GstEvent * event); static gboolean gst_base_sink_do_qos (GstBaseSink * basesink, - GstMiniObject * obj, GstClockReturn status, GstClockTimeDiff jitter); + GstMiniObject * obj, GstClockTime sstart, GstClockTime sstop, + GstClockReturn status, GstClockTimeDiff jitter); static void gst_base_sink_base_init (gpointer g_class) @@ -593,13 +594,22 @@ gst_segment_set_newsegment (segment, update, rate, format, start, stop, time); - GST_DEBUG_OBJECT (basesink, - "configured NEWSEGMENT %" GST_TIME_FORMAT " -- %" - GST_TIME_FORMAT ", time %" GST_TIME_FORMAT ", accum %" - GST_TIME_FORMAT, - GST_TIME_ARGS (segment->start), - GST_TIME_ARGS (segment->stop), - GST_TIME_ARGS (segment->time), GST_TIME_ARGS (segment->accum)); + if (format == GST_FORMAT_TIME) { + GST_DEBUG_OBJECT (basesink, + "configured NEWSEGMENT update %d, rate %lf, format GST_FORMAT_TIME, " + "%" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT + ", time %" GST_TIME_FORMAT ", accum %" GST_TIME_FORMAT, + update, rate, GST_TIME_ARGS (segment->start), + GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time), + GST_TIME_ARGS (segment->accum)); + } else { + "configured NEWSEGMENT update %d, rate %lf, format %d, " + "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %" + G_GINT64_FORMAT ", accum %" G_GINT64_FORMAT, update, rate, + segment->format, segment->start, segment->stop, segment->time, + segment->accum); + } GST_OBJECT_UNLOCK (basesink); } @@ -693,13 +703,16 @@ * Returns TRUE if the object needs synchronisation and takes therefore * part in prerolling. * + * sstart/sstop contain the raw timestamp start/stop times of the object. + * start/stop contain the times usefull for synchronising to the clock. + * * start and stop cannot be NULL. */ static gboolean gst_base_sink_get_sync_times (GstBaseSink * basesink, GstMiniObject * obj, + GstClockTime * sstart, GstClockTime * sstop, GstClockTime * start, GstClockTime * stop) { - GstClockTime sstart, sstop; gint64 cstart, cstop; GstBaseSinkClass *bclass; GstBuffer *buffer; @@ -729,21 +742,21 @@ bclass = GST_BASE_SINK_GET_CLASS (basesink); - sstart = sstop = -1; + *sstart = *sstop = -1; if (bclass->get_times) - bclass->get_times (basesink, buffer, &sstart, &sstop); + bclass->get_times (basesink, buffer, sstart, sstop); GST_DEBUG_OBJECT (basesink, "got times start: %" GST_TIME_FORMAT - ", stop: %" GST_TIME_FORMAT, GST_TIME_ARGS (sstart), - GST_TIME_ARGS (sstop)); + ", stop: %" GST_TIME_FORMAT, GST_TIME_ARGS (*sstart), + GST_TIME_ARGS (*sstop)); if (G_LIKELY (basesink->segment.format == GST_FORMAT_TIME)) { /* clip */ if (G_UNLIKELY (!gst_segment_clip (&basesink->segment, GST_FORMAT_TIME, - (gint64) sstart, (gint64) sstop, &cstart, &cstop))) + (gint64) * sstart, (gint64) * sstop, &cstart, &cstop))) goto out_of_segment; - if (G_UNLIKELY (sstart != cstart || sstop != cstop)) { + if (G_UNLIKELY (*sstart != cstart || *sstop != cstop)) { GST_DEBUG_OBJECT (basesink, "clipped to: start %" GST_TIME_FORMAT ", stop: %" GST_TIME_FORMAT, GST_TIME_ARGS (cstart), GST_TIME_ARGS (cstop)); @@ -759,25 +772,21 @@ } else { if (basesink->segment.accum == 0) { /* no clipping for formats different from GST_FORMAT_TIME */ - cstart = sstart; - cstop = sstop; + cstart = *sstart; + cstop = *sstop; } else { cstart = -1; cstop = -1; } } - if (G_LIKELY (basesink->segment.format == GST_FORMAT_TIME)) { - *start = - gst_segment_to_running_time (&basesink->segment, GST_FORMAT_TIME, - cstart); - *stop = - cstop); - } else { - *start = -1; - *stop = -1; - } + *start = + gst_segment_to_running_time (&basesink->segment, basesink->segment.format, + cstart); + *stop = + cstop); /* buffers always need syncing and preroll */ return TRUE; @@ -796,9 +805,10 @@ /* with STREAM_LOCK, PREROLL_LOCK * Waits for the clock to reach @time. If @time is not valid, no - * synchronisation is done. + * synchronisation is done and BADTIME is returned. * If synchronisation is disabled in the element or there is no - * clock, no synchronisation is done. + * clock, no synchronisation is done and BADTIME is returned. * Else a blocking wait is performed on the clock. We save the ClockID * so we can unlock the entry at any time. While we are blocking, we * release the PREROLL_LOCK so that other threads can interrupt the entry. @@ -812,8 +822,6 @@ GstClock *clock; GstClockTime base_time; - *jitter = 0; - if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (time))) goto invalid_time; @@ -840,22 +848,23 @@ return ret; + /* no syncing needed */ invalid_time: { GST_DEBUG_OBJECT (basesink, "time not valid, no sync needed"); - return GST_CLOCK_OK; + return GST_CLOCK_BADTIME; no_sync: GST_DEBUG_OBJECT (basesink, "sync disabled"); GST_OBJECT_UNLOCK (basesink); no_clock: GST_DEBUG_OBJECT (basesink, "no clock, can't sync"); @@ -885,14 +894,16 @@ gst_base_sink_do_sync (GstBaseSink * basesink, GstPad * pad, GstMiniObject * obj, gboolean * late) + GstClockTime sstart, sstop; GstClockTime start, stop; GstClockTimeDiff jitter; gboolean syncable; GstClockReturn status = GST_CLOCK_OK; /* get timing information for this object */ - start = stop = -1; - syncable = gst_base_sink_get_sync_times (basesink, obj, &start, &stop); + sstart = sstop = start = stop = -1; + syncable = gst_base_sink_get_sync_times (basesink, obj, + &sstart, &sstop, &start, &stop); /* a syncable object needs to participate in preroll and * clocking. All buffers and EOS are syncable. */ @@ -929,15 +940,20 @@ /* preroll done, we can sync since we are in PLAYING now. */ + basesink->end_time = stop; GST_DEBUG_OBJECT (basesink, "waiting for clock to reach %" GST_TIME_FORMAT, GST_TIME_ARGS (start)); - basesink->end_time = stop; - /* this function will return immediatly if start == -1 with - * GST_CLOCK_OK and jitter = 0. */ + /* this function will return immediatly if start == -1, no clock + * or sync is disabled with GST_CLOCK_BADTIME. */ status = gst_base_sink_wait_clock (basesink, start, &jitter); GST_DEBUG_OBJECT (basesink, "clock returned %d", status); - /* waiting could be interrupted and we can be flushing now */ + /* invalid time, no clock or sync disabled, don't do QoS */ + if (status == GST_CLOCK_BADTIME) + goto done; + /* waiting could have been interrupted and we can be flushing now */ if (G_UNLIKELY (basesink->flushing)) goto flushing; @@ -949,8 +965,9 @@ /* perform QoS */ - *late = gst_base_sink_do_qos (basesink, obj, status, jitter); + *late = gst_base_sink_do_qos (basesink, obj, sstart, sstop, status, jitter); +done: return GST_FLOW_OK; /* ERRORS */ @@ -980,13 +997,13 @@ gst_base_sink_do_qos (GstBaseSink * basesink, GstMiniObject * obj, + GstClockTime sstart, GstClockTime sstop, GstClockReturn status, GstClockTimeDiff jitter) gboolean late; - GstClockTime timestamp, duration; gint64 max_lateness; - /* only for buffers that are too late */ + /* only for objects that were too late */ if (status != GST_CLOCK_EARLY) goto in_time; @@ -995,21 +1012,27 @@ goto not_buffer; /* can't do stats if we don't have a timestamp */ - if (G_UNLIKELY ((timestamp = GST_BUFFER_TIMESTAMP (obj)) == -1)) + if (G_UNLIKELY (sstart == -1)) goto no_timestamp; + /* copy for code clarity */ + max_lateness = basesink->abidata.ABI.max_lateness; + /* check if QoS (and frame dropping) is enabled */ + /* FIXME, frame dropping should not depend on the QoS + * being enabled or not. We need another property for that. */ + if (max_lateness == -1) + goto no_qos; /* if the jitter bigger than duration we are too late */ - if (G_UNLIKELY ((duration = GST_BUFFER_DURATION (obj)) != -1)) - late = jitter > duration; + if (G_LIKELY (sstop != -1)) + late = sstart + jitter > sstop; else late = FALSE; - /* copy for code clarity */ - max_lateness = basesink->abidata.ABI.max_lateness; /* check if we need to do qos */ - if (max_lateness == -1 || jitter <= max_lateness) - goto no_qos; + if (jitter <= max_lateness) + goto in_qos_limit; /* FIXME, do stats here in jitter. This could be used to derive * a trend, which should then result in an updated proportion. */ @@ -1024,12 +1047,12 @@ GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, basesink, "qos: proportion: %lf, diff %" G_GUINT64_FORMAT ", timestamp %" - GST_TIME_FORMAT, proportion, jitter, GST_TIME_ARGS (timestamp)); + GST_TIME_FORMAT, proportion, jitter, GST_TIME_ARGS (sstart)); - event = gst_event_new_qos (proportion, jitter, timestamp); + event = gst_event_new_qos (proportion, jitter, sstart); /* if no duration set, we assume lateness here as well. */ - if (duration == -1) + if (sstop == -1) late = TRUE; /* send upstream */ @@ -1056,7 +1079,12 @@ no_qos: - GST_DEBUG_OBJECT (basesink, "qos disabled"); + GST_DEBUG_OBJECT (basesink, "QoS disabled"); + return FALSE; +in_qos_limit: + { + GST_DEBUG_OBJECT (basesink, "in QoS limit"); return late; |
From: <wt...@ke...> - 2006-03-15 16:22:45
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Wed Mar 15 2006 16:22:38 UTC Log message: * libs/gst/base/gstadapter.c: Add some docs. Modified files: . : ChangeLog libs/gst/base : gstadapter.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2363&r2=1.2364 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstadapter.c.diff?r1=1.15&r2=1.16 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2363 retrieving revision 1.2364 diff -u -d -r1.2363 -r1.2364 --- ChangeLog 15 Mar 2006 15:57:51 -0000 1.2363 +++ ChangeLog 15 Mar 2006 16:22:26 -0000 1.2364 @@ -1,3 +1,8 @@ +2006-03-15 Wim Taymans <wi...@fl...> + + * libs/gst/base/gstadapter.c: + Add some docs. 2006-03-15 Tim-Philipp Müller <tim at centricular dot net> * win32/common/libgstbase.def: Index: gstadapter.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstadapter.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- gstadapter.c 7 Mar 2006 16:21:02 -0000 1.15 +++ gstadapter.c 15 Mar 2006 16:22:26 -0000 1.16 @@ -27,6 +27,9 @@ * a file. So if you have undefined buffer sizes and require a specific size, * this object is for you. * + * An adapter is created with gst_adapter_new(). It can be freed again with + * g_object_unref(). + * * The theory of operation is like this: All buffers received are put * into the adapter using gst_adapter_push() and the data is then read back * in chunks of the desired size using gst_adapter_peek(). After the data is @@ -152,7 +155,7 @@ /** * gst_adapter_new: - * Creates a new #GstAdapter. + * Creates a new #GstAdapter. Free with g_object_unref(). * Returns: a new #GstAdapter */ |
From: <wt...@ke...> - 2006-03-23 16:20:56
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Thu Mar 23 2006 16:20:53 UTC Log message: * libs/gst/base/gstbasesink.c: (gst_base_sink_class_init), (gst_base_sink_init), (gst_base_sink_finalize), (gst_base_sink_set_qos_enabled), (gst_base_sink_is_qos_enabled), (gst_base_sink_set_property), (gst_base_sink_get_property), (gst_base_sink_commit_state), (gst_base_sink_get_sync_times), (gst_base_sink_wait_clock), (gst_base_sink_do_sync), (gst_base_sink_add_qos_observation), (gst_base_sink_send_qos), (gst_base_sink_perform_qos), (gst_base_sink_reset_qos), (gst_base_sink_is_too_late), (gst_base_sink_render_object), (gst_base_sink_preroll_object), (gst_base_sink_event), (gst_base_sink_chain_unlocked), (gst_base_sink_get_position_last), (gst_base_sink_get_position_paused), (gst_base_sink_get_position), (gst_base_sink_query), (gst_base_sink_change_state): Decouple max-lateness and the fact that QoS messages are generated with a new property (qos). Add vmethod so subclasses can be notified of ASYNC playing state changes. Collect timestamp start and stop to report better current position in EOS/PLAYING/PAUSED/READY/NULL. Refactor QoS/frame dropping and other measurements. API: GstBaseSrc::qos * libs/gst/base/gstbasesink.h: Added Private struct. API: gst_base_sink_set_qos_enabled API: gst_base_sink_is_qos_enabled Modified files: . : ChangeLog libs/gst/base : gstbasesink.c gstbasesink.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2387&r2=1.2388 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.c.diff?r1=1.130&r2=1.131 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.h.diff?r1=1.32&r2=1.33 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2387 retrieving revision 1.2388 diff -u -d -r1.2387 -r1.2388 --- ChangeLog 23 Mar 2006 11:54:50 -0000 1.2387 +++ ChangeLog 23 Mar 2006 16:20:40 -0000 1.2388 @@ -1,3 +1,32 @@ +2006-03-23 Wim Taymans <wi...@fl...> + + * libs/gst/base/gstbasesink.c: (gst_base_sink_class_init), + (gst_base_sink_init), (gst_base_sink_finalize), + (gst_base_sink_set_qos_enabled), (gst_base_sink_is_qos_enabled), + (gst_base_sink_set_property), (gst_base_sink_get_property), + (gst_base_sink_commit_state), (gst_base_sink_get_sync_times), + (gst_base_sink_wait_clock), (gst_base_sink_do_sync), + (gst_base_sink_add_qos_observation), (gst_base_sink_send_qos), + (gst_base_sink_perform_qos), (gst_base_sink_reset_qos), + (gst_base_sink_is_too_late), (gst_base_sink_render_object), + (gst_base_sink_preroll_object), (gst_base_sink_event), + (gst_base_sink_chain_unlocked), (gst_base_sink_get_position_last), + (gst_base_sink_get_position_paused), (gst_base_sink_get_position), + (gst_base_sink_query), (gst_base_sink_change_state): + Decouple max-lateness and the fact that QoS messages are generated + with a new property (qos). + Add vmethod so subclasses can be notified of ASYNC playing + state changes. + Collect timestamp start and stop to report better current + position in EOS/PLAYING/PAUSED/READY/NULL. + Refactor QoS/frame dropping and other measurements. + API: GstBaseSrc::qos + * libs/gst/base/gstbasesink.h: + Added Private struct. + API: gst_base_sink_set_qos_enabled + API: gst_base_sink_is_qos_enabled 2006-03-23 Tim-Philipp Müller <tim at centricular dot net> * gst/gstregistryxml.c: (gst_registry_xml_read_cache): Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.c,v retrieving revision 1.130 retrieving revision 1.131 diff -u -d -r1.130 -r1.131 --- gstbasesink.c 14 Mar 2006 19:36:05 -0000 1.130 +++ gstbasesink.c 23 Mar 2006 16:20:40 -0000 1.131 @@ -84,8 +84,7 @@ * * #GstBaseSink will by default report the current playback position in * GST_FORMAT_TIME based on the current clock time and segment information. - * If the element is EOS, PAUSED or no clock has been set on the element, the - * query will be forwarded upstream. + * If no clock has been set on the element, the query will be forwarded upstream. * * The ::set_caps function will be called when the subclass should configure itself * to process a specific media type. @@ -109,13 +108,18 @@ * The max-lateness property defines how the sink deals with buffers that arrive [...1028 lines suppressed...] @@ -2004,7 +2284,10 @@ basesink->have_preroll = FALSE; basesink->need_preroll = TRUE; basesink->playing_async = TRUE; + basesink->priv->last_cstart = 0; + basesink->priv->last_cstop = 0; basesink->eos = FALSE; + gst_base_sink_reset_qos (basesink); ret = GST_STATE_CHANGE_ASYNC; break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: @@ -2067,6 +2350,8 @@ GST_PAD_PREROLL_UNLOCK (basesink->sinkpad); case GST_STATE_CHANGE_PAUSED_TO_READY: case GST_STATE_CHANGE_READY_TO_NULL: if (bclass->stop) Index: gstbasesink.h RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.h,v retrieving revision 1.32 retrieving revision 1.33 diff -u -d -r1.32 -r1.33 --- gstbasesink.h 7 Mar 2006 16:21:02 -0000 1.32 +++ gstbasesink.h 23 Mar 2006 16:20:40 -0000 1.33 @@ -46,6 +46,7 @@ typedef struct _GstBaseSink GstBaseSink; typedef struct _GstBaseSinkClass GstBaseSinkClass; +typedef struct _GstBaseSinkPrivate GstBaseSinkPrivate; /** * GstBaseSink: @@ -88,6 +89,8 @@ gboolean flushing; /*< private >*/ + GstBaseSinkPrivate *priv; union { struct { /* segment used for clipping incomming buffers */ @@ -95,8 +98,7 @@ /* max amount of time a buffer can be late, -1 no limit. */ gint64 max_lateness; } ABI; - /* adding + 0 to mark ABI change to be undone later */ - gpointer _gst_reserved[GST_PADDING_LARGE + 0]; + gpointer _gst_reserved[GST_PADDING_LARGE - 1]; } abidata; }; @@ -130,8 +132,13 @@ GstFlowReturn (*preroll) (GstBaseSink *sink, GstBuffer *buffer); GstFlowReturn (*render) (GstBaseSink *sink, GstBuffer *buffer); + /* ABI additions */ + /* when an ASYNC state change to PLAYING happens */ /* with LOCK */ + GstStateChangeReturn (*async_play) (GstBaseSink *sink); - gpointer _gst_reserved[GST_PADDING_LARGE]; + gpointer _gst_reserved[GST_PADDING_LARGE-1]; GType gst_base_sink_get_type(void); @@ -142,6 +149,9 @@ void gst_base_sink_set_max_lateness (GstBaseSink *sink, gint64 max_lateness); gint64 gst_base_sink_get_max_lateness (GstBaseSink *sink); +void gst_base_sink_set_qos_enabled (GstBaseSink *sink, gboolean enabled); +gboolean gst_base_sink_is_qos_enabled (GstBaseSink *sink); G_END_DECLS #endif /* __GST_BASE_SINK_H__ */ |
From: <wt...@ke...> - 2006-03-24 09:48:54
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Fri Mar 24 2006 09:48:45 UTC Log message: * libs/gst/base/gstbasesink.h: Only add fields, not insert or we break ABI. Modified files: . : ChangeLog libs/gst/base : gstbasesink.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2391&r2=1.2392 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.h.diff?r1=1.33&r2=1.34 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2391 retrieving revision 1.2392 diff -u -d -r1.2391 -r1.2392 --- ChangeLog 23 Mar 2006 18:51:05 -0000 1.2391 +++ ChangeLog 24 Mar 2006 09:48:33 -0000 1.2392 @@ -1,3 +1,8 @@ +2006-03-24 Wim Taymans <wi...@fl...> + + * libs/gst/base/gstbasesink.h: + Only add fields, not insert or we break ABI. 2006-03-23 Tim-Philipp Müller <tim at centricular dot net> * win32/common/libgstbase.def: Index: gstbasesink.h RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.h,v retrieving revision 1.33 retrieving revision 1.34 diff -u -d -r1.33 -r1.34 --- gstbasesink.h 23 Mar 2006 16:20:40 -0000 1.33 +++ gstbasesink.h 24 Mar 2006 09:48:33 -0000 1.34 @@ -89,8 +89,6 @@ gboolean flushing; /*< private >*/ - GstBaseSinkPrivate *priv; - union { struct { /* segment used for clipping incomming buffers */ @@ -101,6 +99,7 @@ gpointer _gst_reserved[GST_PADDING_LARGE - 1]; } abidata; + GstBaseSinkPrivate *priv; }; struct _GstBaseSinkClass { |
From: <wt...@ke...> - 2006-03-27 11:48:29
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Mon Mar 27 2006 11:48:22 UTC Log message: Inspired by a patch of: Lutz Mueller <lutz at topfrose dot de> * libs/gst/base/gstbasesrc.c: (gst_base_src_finalize), (gst_base_src_send_event), (gst_base_src_change_state): Handle element seek correctly when we are streaming. Fixes #326998. Modified files: . : ChangeLog libs/gst/base : gstbasesrc.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2398&r2=1.2399 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesrc.c.diff?r1=1.99&r2=1.100 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2398 retrieving revision 1.2399 diff -u -d -r1.2398 -r1.2399 --- ChangeLog 24 Mar 2006 18:38:12 -0000 1.2398 +++ ChangeLog 27 Mar 2006 11:48:09 -0000 1.2399 @@ -1,3 +1,12 @@ +2006-03-27 Wim Taymans <wi...@fl...> + + Inspired by a patch of: Lutz Mueller <lutz at topfrose dot de> + * libs/gst/base/gstbasesrc.c: (gst_base_src_finalize), + (gst_base_src_send_event), (gst_base_src_change_state): + Handle element seek correctly when we are streaming. + Fixes #326998. 2006-03-24 Michael Smith <ms...@fl...> * docs/faq/gst-uninstalled: Index: gstbasesrc.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesrc.c,v retrieving revision 1.99 retrieving revision 1.100 diff -u -d -r1.99 -r1.100 --- gstbasesrc.c 8 Mar 2006 13:44:55 -0000 1.99 +++ gstbasesrc.c 27 Mar 2006 11:48:10 -0000 1.100 @@ -388,6 +388,7 @@ g_mutex_free (basesrc->live_lock); g_cond_free (basesrc->live_cond); + gst_event_replace (&basesrc->data.ABI.pending_seek, NULL); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -877,30 +878,64 @@ gst_base_src_send_event (GstElement * element, GstEvent * event) { GstBaseSrc *src; - gboolean result; + gboolean result = FALSE; src = GST_BASE_SRC (element); switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH_START: + case GST_EVENT_FLUSH_STOP: + break; + case GST_EVENT_EOS: + case GST_EVENT_NEWSEGMENT: + case GST_EVENT_TAG: + case GST_EVENT_BUFFERSIZE: + case GST_EVENT_QOS: case GST_EVENT_SEEK: { - GST_OBJECT_LOCK (src); - /* gst_event_replace? */ - if (src->data.ABI.pending_seek) - gst_event_unref (src->data.ABI.pending_seek); - gst_event_ref (event); - src->data.ABI.pending_seek = event; - GST_OBJECT_UNLOCK (src); - result = TRUE; + gboolean started; + GST_OBJECT_LOCK (src->srcpad); + if (GST_PAD_ACTIVATE_MODE (src->srcpad) == GST_ACTIVATE_PULL) + goto wrong_mode; + started = GST_PAD_ACTIVATE_MODE (src->srcpad) == GST_ACTIVATE_PUSH; + GST_OBJECT_UNLOCK (src->srcpad); + if (started) { + /* when we are running in push mode, we can execute the + * seek right now, we need to unlock. */ + result = gst_base_src_perform_seek (src, event, TRUE); + } else { + /* else we store the event and execute the seek when we + * get activated */ + GST_OBJECT_LOCK (src); + gst_event_replace (&src->data.ABI.pending_seek, event); + GST_OBJECT_UNLOCK (src); + /* assume the seek will work */ + result = TRUE; + } break; } + case GST_EVENT_NAVIGATION: default: - result = FALSE; } +done: gst_event_unref (event); return result; + /* ERRORS */ +wrong_mode: + { + GST_DEBUG_OBJECT (src, "cannot perform seek when operating in pull mode"); + GST_OBJECT_UNLOCK (src->srcpad); + result = FALSE; + goto done; + } static gboolean @@ -1833,6 +1868,7 @@ gst_pad_push_event (basesrc->srcpad, gst_event_new_eos ()); basesrc->priv->last_sent_eos = TRUE; } + gst_event_replace (&basesrc->data.ABI.pending_seek, NULL); case GST_STATE_CHANGE_READY_TO_NULL: |
From: <wt...@ke...> - 2006-03-29 13:39:48
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Wed Mar 29 2006 13:39:17 UTC Log message: * libs/gst/base/gstbasesrc.c: (gst_base_src_finalize), (gst_base_src_send_event), (gst_base_src_loop), (gst_base_src_change_state): Perform the EOS logic when we reach the segment stop position. Fix compilation on gcc4.1 Modified files: . : ChangeLog libs/gst/base : gstbasesrc.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2402&r2=1.2403 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesrc.c.diff?r1=1.100&r2=1.101 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2402 retrieving revision 1.2403 diff -u -d -r1.2402 -r1.2403 --- ChangeLog 29 Mar 2006 11:02:32 -0000 1.2402 +++ ChangeLog 29 Mar 2006 13:39:05 -0000 1.2403 @@ -1,5 +1,13 @@ 2006-03-29 Wim Taymans <wi...@fl...> + * libs/gst/base/gstbasesrc.c: (gst_base_src_finalize), + (gst_base_src_send_event), (gst_base_src_loop), + (gst_base_src_change_state): + Perform the EOS logic when we reach the segment stop position. + Fix compilation on gcc4.1 + +2006-03-29 Wim Taymans <wi...@fl...> Patch by Tommi Myöhänen <ext-tommi dot myohanen at nokia dot com> * plugins/elements/gstqueue.c: (gst_queue_init), Index: gstbasesrc.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesrc.c,v retrieving revision 1.100 retrieving revision 1.101 diff -u -d -r1.100 -r1.101 --- gstbasesrc.c 27 Mar 2006 11:48:10 -0000 1.100 +++ gstbasesrc.c 29 Mar 2006 13:39:05 -0000 1.101 @@ -383,12 +383,15 @@ gst_base_src_finalize (GObject * object) { GstBaseSrc *basesrc; + GstEvent **event_p; basesrc = GST_BASE_SRC (object); g_mutex_free (basesrc->live_lock); g_cond_free (basesrc->live_cond); - gst_event_replace (&basesrc->data.ABI.pending_seek, NULL); + event_p = &basesrc->data.ABI.pending_seek; + gst_event_replace ((GstEvent **) event_p, NULL); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -908,10 +911,13 @@ * seek right now, we need to unlock. */ result = gst_base_src_perform_seek (src, event, TRUE); } else { + GstEvent **event_p; /* else we store the event and execute the seek when we * get activated */ GST_OBJECT_LOCK (src); - gst_event_replace (&src->data.ABI.pending_seek, event); + event_p = &src->data.ABI.pending_seek; + gst_event_replace ((GstEvent **) event_p, event); GST_OBJECT_UNLOCK (src); /* assume the seek will work */ result = TRUE; @@ -1355,6 +1361,9 @@ GstBuffer *buf = NULL; GstFlowReturn ret; gint64 position; + gboolean eos; + eos = FALSE; src = GST_BASE_SRC (gst_pad_get_parent (pad)); @@ -1404,8 +1413,15 @@ position = -1; break; } - if (position != -1) + if (position != -1) { + if (src->segment.stop != -1) { + if (position >= src->segment.stop) { + eos = TRUE; + position = src->segment.stop; + } + } gst_segment_set_last_stop (&src->segment, src->segment.format, position); + } if (G_UNLIKELY (src->priv->discont)) { buf = gst_buffer_make_metadata_writable (buf); @@ -1417,6 +1433,9 @@ if (G_UNLIKELY (ret != GST_FLOW_OK)) goto pause; + if (eos) + goto eos; done: gst_object_unref (src); return; @@ -1860,6 +1879,9 @@ GST_LIVE_UNLOCK (element); case GST_STATE_CHANGE_PAUSED_TO_READY: + { + GstEvent **event_p; if (!gst_base_src_stop (basesrc)) goto error_stop; @@ -1868,8 +1890,10 @@ gst_pad_push_event (basesrc->srcpad, gst_event_new_eos ()); basesrc->priv->last_sent_eos = TRUE; } - gst_event_replace (&basesrc->data.ABI.pending_seek, NULL); + event_p = &basesrc->data.ABI.pending_seek; + gst_event_replace (event_p, NULL); case GST_STATE_CHANGE_READY_TO_NULL: default: |
From: <wt...@ke...> - 2006-03-30 16:36:26
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Thu Mar 30 2006 16:36:24 UTC Log message: * libs/gst/base/gstbasesink.c: (gst_base_sink_init), (gst_base_sink_finalize), (gst_base_sink_set_qos_enabled), (gst_base_sink_is_qos_enabled), (gst_base_sink_do_sync), (gst_base_sink_record_qos_observation), (gst_base_sink_perform_qos), (gst_base_sink_reset_qos), (gst_base_sink_is_too_late), (gst_base_sink_render_object), (gst_base_sink_change_state): More QoS measurements as described in the design doc. Get rid of ringbuffer with observations, running average is more simple and equally good. Calculates valid proportion now. Added beginning of flood measurement. Modified files: . : ChangeLog libs/gst/base : gstbasesink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2404&r2=1.2405 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.c.diff?r1=1.131&r2=1.132 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2404 retrieving revision 1.2405 diff -u -d -r1.2404 -r1.2405 --- ChangeLog 29 Mar 2006 13:45:15 -0000 1.2404 +++ ChangeLog 30 Mar 2006 16:36:12 -0000 1.2405 @@ -1,3 +1,18 @@ +2006-03-30 Wim Taymans <wi...@fl...> + + * libs/gst/base/gstbasesink.c: (gst_base_sink_init), + (gst_base_sink_finalize), (gst_base_sink_set_qos_enabled), + (gst_base_sink_is_qos_enabled), (gst_base_sink_do_sync), + (gst_base_sink_record_qos_observation), + (gst_base_sink_perform_qos), (gst_base_sink_reset_qos), + (gst_base_sink_is_too_late), (gst_base_sink_render_object), + (gst_base_sink_change_state): + More QoS measurements as described in the design doc. + Get rid of ringbuffer with observations, running average is + more simple and equally good. + Calculates valid proportion now. + Added beginning of flood measurement. 2006-03-29 Wim Taymans <wi...@fl...> * docs/design/part-qos.txt: Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.c,v retrieving revision 1.131 retrieving revision 1.132 diff -u -d -r1.131 -r1.132 --- gstbasesink.c 23 Mar 2006 16:20:40 -0000 1.131 +++ gstbasesink.c 30 Mar 2006 16:36:12 -0000 1.132 @@ -142,22 +142,39 @@ */ struct _GstBaseSinkPrivate { - gboolean qos_enabled; + gint qos_enabled; /* ATOMIC */ /* last position */ GstClockTime last_cstart; GstClockTime last_cstop; - /* for the linear regression when doing QoS */ - gboolean filling; - gint window_size; - gint window_threshold; - gint time_index; - gint64 *times; + /* start, stop and jitter of current buffer, stream time */ + GstClockTime current_start; + GstClockTime current_stop; + GstClockTimeDiff current_jitter; - /* stats go here. */ + /* last buffer that arrived in time, stream time */ + GstClockTime last_in_time; + /* when the last buffer left the sink, stream time */ + GstClockTime last_left; + /* running averages go here these are done on stream time */ + GstClockTime avg_pt; + GstClockTime avg_duration; + gdouble avg_rate; + /* these are done on system time. avg_jitter and avg_render are + * compared to eachother to see if the rendering time takes a + * huge amount of the processing, If so we are flooded with + * buffers. */ + GstClockTime last_left_systime; + GstClockTime avg_jitter; + GstClockTime avg_render; }; +#define RUNNING_AVG_WINDOW 8 +#define UPDATE_RUNNING_AVG(avg,val) ((val) + (RUNNING_AVG_WINDOW-1) * (avg)) / RUNNING_AVG_WINDOW /* BaseSink signals and properties */ enum @@ -175,10 +192,6 @@ #define DEFAULT_MAX_LATENESS -1 #define DEFAULT_QOS FALSE -/* for QoS, no properties yet */ -#define DEFAULT_WINDOW_SIZE 32 -#define DEFAULT_WINDOW_THRESHOLD 4 - PROP_0, @@ -253,8 +266,8 @@ GstClockReturn status, GstClockTimeDiff jitter); /* QoS */ -static void gst_base_sink_add_qos_observation (GstBaseSink * sink, - GstClockTime time, GstClockTimeDiff jitter); +static void gst_base_sink_record_qos_observation (GstBaseSink * sink, + GstClockTime start, GstClockTime stop, GstClockTimeDiff jitter); static void gst_base_sink_base_init (gpointer g_class) @@ -420,13 +433,7 @@ basesink->sync = DEFAULT_SYNC; basesink->abidata.ABI.max_lateness = DEFAULT_MAX_LATENESS; - priv->qos_enabled = DEFAULT_QOS; - priv->window_size = DEFAULT_WINDOW_SIZE; - priv->window_threshold = DEFAULT_WINDOW_THRESHOLD; - priv->filling = TRUE; - priv->time_index = 0; - priv->times = g_new0 (gint64, 4 * priv->window_size); + gst_atomic_int_set (&priv->qos_enabled, DEFAULT_QOS); GST_OBJECT_FLAG_SET (basesink, GST_ELEMENT_IS_SINK); } @@ -440,7 +447,6 @@ g_queue_free (basesink->preroll_queue); gst_segment_free (basesink->abidata.ABI.clip_segment); - g_free (basesink->priv->times); G_OBJECT_CLASS (parent_class)->finalize (object); @@ -546,9 +552,7 @@ void gst_base_sink_set_qos_enabled (GstBaseSink * sink, gboolean enabled) - GST_OBJECT_LOCK (sink); - sink->priv->qos_enabled = enabled; - GST_OBJECT_UNLOCK (sink); + gst_atomic_int_set (&sink->priv->qos_enabled, enabled); /** @@ -567,9 +571,7 @@ gboolean res; - res = sink->priv->qos_enabled; + res = g_atomic_int_get (&sink->priv->qos_enabled); return res; @@ -1032,6 +1034,8 @@ start = stop = cstart = cstop = -1; + basesink->priv->current_start = -1; /* update timing information for this object */ syncable = gst_base_sink_get_sync_times (basesink, obj, &start, &stop, &cstart, &cstop, &do_sync); @@ -1109,8 +1113,8 @@ goto again; } - /* successful syncing done, add observation */ - gst_base_sink_add_qos_observation (basesink, cstart, jitter); + /* successful syncing done, record observation */ + gst_base_sink_record_qos_observation (basesink, cstart, cstop, jitter); /* check if the object should be dropped */ *late = gst_base_sink_is_too_late (basesink, obj, start, stop, @@ -1137,27 +1141,26 @@ -/* add a qos observation to the ringbuffer of observations */ +/* record a qos observation for later processing */ -gst_base_sink_add_qos_observation (GstBaseSink * sink, GstClockTime time, - GstClockTimeDiff jitter) +gst_base_sink_record_qos_observation (GstBaseSink * sink, GstClockTime start, + GstClockTime stop, GstClockTimeDiff jitter) GstBaseSinkPrivate *priv; - gint index; priv = sink->priv; - if (!priv->qos_enabled || time == -1) + if (!g_atomic_int_get (&priv->qos_enabled)) return; GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, sink, - "adding QoS observation time: %" G_GUINT64_FORMAT ", jitter %" - G_GINT64_FORMAT, time, jitter); - index = priv->time_index << 2; + "recording QoS observation start: %" GST_TIME_FORMAT ", stop %" + GST_TIME_FORMAT ", jitter %" G_GINT64_FORMAT, + GST_TIME_ARGS (start), GST_TIME_ARGS (stop), jitter); - priv->times[index] = time; - priv->times[index + 2] = jitter; + priv->current_start = start; + priv->current_stop = stop; + priv->current_jitter = jitter; static gboolean @@ -1184,38 +1187,89 @@ gst_base_sink_perform_qos (GstBaseSink * sink, gboolean dropped) - gdouble proportion; + GstClockTime start, stop; + GstClockTimeDiff jitter; + GstClockTime pt, entered, left; + GstClockTime duration; + gdouble rate; + start = priv->current_start; /* if QoS disabled, do nothing */ - if (!priv->qos_enabled) + if (!g_atomic_int_get (&priv->qos_enabled) || start == -1) - /* no proportion yet */ - proportion = 0.0; - /* last observation caused a drop, send Qos */ - if (dropped) { - GstClockTime time; - GstClockTimeDiff diff; - gint index; + stop = priv->current_stop; + jitter = priv->current_jitter; - index = priv->time_index << 2; + /* this is the time the buffer entered the sink */ + entered = start + jitter; + /* this is the time the buffer left the sink */ + left = start + (jitter < 0 ? 0 : jitter); - time = priv->times[index]; - diff = priv->times[index + 2]; + /* calculate duration of the buffer */ + if (stop != -1) + duration = stop - start; + else + duration = -1; - gst_base_sink_send_qos (sink, proportion, time, diff); + /* if we have the time when the last buffer left us, calculate + * processing time */ + if (priv->last_left != -1 && entered > priv->last_left) { + pt = entered - priv->last_left; + } else { + pt = 0; - /* move to next observation */ - priv->time_index++; - if (G_UNLIKELY (priv->time_index == priv->window_size)) { - priv->filling = FALSE; - priv->time_index = 0; - } - return; + GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, sink, "start: %" GST_TIME_FORMAT + ", entered %" GST_TIME_FORMAT ", left %" GST_TIME_FORMAT ", pt: %" + GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT ",jitter %" + G_GINT64_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (entered), + GST_TIME_ARGS (left), GST_TIME_ARGS (pt), GST_TIME_ARGS (duration), + jitter); + GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, sink, "avg_duration: %" GST_TIME_FORMAT + ", avg_pt: %" GST_TIME_FORMAT ", avg_rate: %g", + GST_TIME_ARGS (priv->avg_duration), GST_TIME_ARGS (priv->avg_pt), + priv->avg_rate); + /* record when this buffer will leave us */ + priv->last_left = left; + /* collect running averages. for first observations, we copy the + * values */ + if (priv->avg_duration == -1) + priv->avg_duration = duration; + priv->avg_duration = UPDATE_RUNNING_AVG (priv->avg_duration, duration); + if (priv->avg_pt == -1) + priv->avg_pt = pt; + priv->avg_pt = UPDATE_RUNNING_AVG (priv->avg_pt, pt); + if (priv->avg_duration != 0) + rate = ((gdouble) priv->avg_pt) / priv->avg_duration; + rate = 1.0; + priv->avg_rate = UPDATE_RUNNING_AVG (priv->avg_rate, rate); + GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, sink, + "updated: avg_duration: %" GST_TIME_FORMAT ", avg_pt: %" GST_TIME_FORMAT + ", avg_rate: %g", GST_TIME_ARGS (priv->avg_duration), + GST_TIME_ARGS (priv->avg_pt), priv->avg_rate); + /* last observation did not cause a drop, no need to send + * a QoS event */ + if (G_LIKELY (!dropped)) + return; + gst_base_sink_send_qos (sink, priv->avg_rate, priv->current_start, + priv->current_jitter); /* reset all qos measuring */ @@ -1225,8 +1279,13 @@ + priv->last_in_time = -1; + priv->last_left = -1; + priv->avg_duration = -1; + priv->avg_pt = -1; + priv->avg_rate = 1.0; + priv->avg_render = -1; /* Checks if the object was scheduled too late. @@ -1245,6 +1304,11 @@ gboolean late; gint64 max_lateness; + GstBaseSinkPrivate *priv; + priv = basesink->priv; + late = FALSE; /* only for objects that were too late */ if (G_LIKELY (status != GST_CLOCK_EARLY)) @@ -1265,23 +1329,30 @@ goto no_timestamp; /* if the jitter bigger than duration and lateness we are too late */ - if (G_LIKELY (stop != -1)) - late = start + jitter > stop + max_lateness; - else - late = FALSE; + if (G_LIKELY (stop != -1)) { + if ((late = start + jitter > stop + max_lateness)) { + if (priv->last_in_time && start - priv->last_in_time > GST_SECOND) { + late = FALSE; + } + } + } +done: + if (!late) { + priv->last_in_time = start; return late; /* all is fine */ in_time: { GST_DEBUG_OBJECT (basesink, "object was scheduled in time"); - return FALSE; + goto done; no_drop: GST_DEBUG_OBJECT (basesink, "frame dropping disabled"); not_buffer: @@ -1317,16 +1388,48 @@ /* and now render, event or buffer. */ if (G_LIKELY (GST_IS_BUFFER (obj))) { + GTimeVal start, stop; /* drop late buffers unconditionally, let's hope it's unlikely */ if (G_UNLIKELY (late)) goto dropped; bclass = GST_BASE_SINK_GET_CLASS (basesink); - GST_DEBUG_OBJECT (basesink, "rendering buffer %p", obj); - if (G_LIKELY (bclass->render)) + if (G_LIKELY (bclass->render)) { + gint do_qos; + GstBaseSinkPrivate *priv; + priv = basesink->priv; + /* read once, to get same value before and after */ + do_qos = g_atomic_int_get (&priv->qos_enabled); + GST_DEBUG_OBJECT (basesink, "rendering buffer %p", obj); + /* record rendering time for QoS and stats */ + if (do_qos) + g_get_current_time (&start); ret = bclass->render (basesink, GST_BUFFER_CAST (obj)); + if (do_qos) { + GstClockTime elapsed; + g_get_current_time (&stop); + elapsed = GST_TIMEVAL_TO_TIME (stop) - GST_TIMEVAL_TO_TIME (start); + if (priv->avg_render == -1) + priv->avg_render = elapsed; + else + priv->avg_render = UPDATE_RUNNING_AVG (priv->avg_render, elapsed); + GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, basesink, + "avg_render: %" GST_TIME_FORMAT, GST_TIME_ARGS (priv->avg_render)); } else { GstEvent *event = GST_EVENT_CAST (obj); gboolean event_res = TRUE; @@ -2347,6 +2450,7 @@ basesink->playing_async = TRUE; ret = GST_STATE_CHANGE_ASYNC; } + gst_base_sink_reset_qos (basesink); GST_PAD_PREROLL_UNLOCK (basesink->sinkpad); break; case GST_STATE_CHANGE_PAUSED_TO_READY: |
From: <wt...@ke...> - 2006-04-07 14:50:19
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Fri Apr 07 2006 14:50:18 UTC Log message: * libs/gst/base/gstbasesink.c: (gst_base_sink_get_sync_times): Be a bit nicer to badly behaving upstream elements that expect us to deal with non TIME segments and timestamps (such as fakesrc in the testsuite). Modified files: . : ChangeLog libs/gst/base : gstbasesink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2424&r2=1.2425 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.c.diff?r1=1.134&r2=1.135 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2424 retrieving revision 1.2425 diff -u -d -r1.2424 -r1.2425 --- ChangeLog 7 Apr 2006 14:02:12 -0000 1.2424 +++ ChangeLog 7 Apr 2006 14:50:06 -0000 1.2425 @@ -1,5 +1,12 @@ 2006-04-07 Wim Taymans <wi...@fl...> + * libs/gst/base/gstbasesink.c: (gst_base_sink_get_sync_times): + Be a bit nicer to badly behaving upstream elements that expect + us to deal with non TIME segments and timestamps (such as fakesrc + in the testsuite). + +2006-04-07 Wim Taymans <wi...@fl...> * gst/gstbus.c: Small documentation clarification about the signal watch. Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.c,v retrieving revision 1.134 retrieving revision 1.135 diff -u -d -r1.134 -r1.135 --- gstbasesink.c 7 Apr 2006 14:02:12 -0000 1.134 +++ gstbasesink.c 7 Apr 2006 14:50:06 -0000 1.135 @@ -855,6 +855,8 @@ gint64 cstart, cstop; /* clipped raw timestamps */ gint64 rstart, rstop; /* clipped timestamps converted to running time */ GstClockTime sstart, sstop; /* clipped timestamps converted to stream time */ + GstFormat format; + GstSegment *segment; /* start with nothing */ sstart = sstop = rstart = rstop = -1; @@ -879,10 +881,6 @@ } } - /* no sync if we did not get a TIME segment format */ - if (G_UNLIKELY (basesink->segment.format != GST_FORMAT_TIME)) - goto done; - /* else do buffer sync code */ buffer = GST_BUFFER_CAST (obj); @@ -902,8 +900,19 @@ GST_DEBUG_OBJECT (basesink, "got times start: %" GST_TIME_FORMAT ", stop: %" GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (stop)); + /* collect segment and format for code clarity */ + segment = &basesink->segment; + format = segment->format; + /* no timestamp clipping if we did not * get a TIME segment format */ + if (G_UNLIKELY (format != GST_FORMAT_TIME)) { + cstart = start; + cstop = stop; + goto do_times; + } /* clip */ - if (G_UNLIKELY (!gst_segment_clip (&basesink->segment, GST_FORMAT_TIME, + if (G_UNLIKELY (!gst_segment_clip (segment, GST_FORMAT_TIME, (gint64) start, (gint64) stop, &cstart, &cstop))) goto out_of_segment; @@ -913,14 +922,13 @@ GST_TIME_ARGS (cstop)); - sstart = - gst_segment_to_stream_time (&basesink->segment, GST_FORMAT_TIME, cstart); - sstop = - gst_segment_to_stream_time (&basesink->segment, GST_FORMAT_TIME, cstop); - rstart = - gst_segment_to_running_time (&basesink->segment, GST_FORMAT_TIME, cstart); - rstop = - gst_segment_to_running_time (&basesink->segment, GST_FORMAT_TIME, cstop); +do_times: + /* this can produce wrong values if we accumulated non-TIME segments. If this happens, + * upstream is behaving very badly */ + sstart = gst_segment_to_stream_time (segment, format, cstart); + sstop = gst_segment_to_stream_time (segment, format, cstop); + rstart = gst_segment_to_running_time (segment, format, cstart); + rstop = gst_segment_to_running_time (segment, format, cstop); done: /* save times */ |
From: <wt...@ke...> - 2006-04-07 15:19:23
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Fri Apr 07 2006 15:19:20 UTC Log message: * libs/gst/base/gstbasesink.c: (gst_base_sink_get_sync_times): Initialize start and stop times, thanks valgrind. Modified files: . : ChangeLog libs/gst/base : gstbasesink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2425&r2=1.2426 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.c.diff?r1=1.135&r2=1.136 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2425 retrieving revision 1.2426 diff -u -d -r1.2425 -r1.2426 --- ChangeLog 7 Apr 2006 14:50:06 -0000 1.2425 +++ ChangeLog 7 Apr 2006 15:19:08 -0000 1.2426 @@ -1,6 +1,11 @@ 2006-04-07 Wim Taymans <wi...@fl...> * libs/gst/base/gstbasesink.c: (gst_base_sink_get_sync_times): + Initialize start and stop times, thanks valgrind. + +2006-04-07 Wim Taymans <wi...@fl...> + * libs/gst/base/gstbasesink.c: (gst_base_sink_get_sync_times): Be a bit nicer to badly behaving upstream elements that expect us to deal with non TIME segments and timestamps (such as fakesrc in the testsuite). Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.c,v retrieving revision 1.135 retrieving revision 1.136 diff -u -d -r1.135 -r1.136 --- gstbasesink.c 7 Apr 2006 14:50:06 -0000 1.135 +++ gstbasesink.c 7 Apr 2006 15:19:08 -0000 1.136 @@ -859,7 +859,7 @@ GstSegment *segment; /* start with nothing */ - sstart = sstop = rstart = rstop = -1; + start = stop = sstart = sstop = rstart = rstop = -1; if (G_UNLIKELY (GST_IS_EVENT (obj))) { GstEvent *event = GST_EVENT_CAST (obj); |
From: <wt...@ke...> - 2006-04-28 13:19:12
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Fri Apr 28 2006 13:18:53 UTC Log message: * libs/gst/base/gstbasesrc.c: (gst_base_src_perform_seek), (gst_base_src_send_event), (gst_base_src_change_state): Documentation updates. Modified files: . : ChangeLog libs/gst/base : gstbasesrc.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2446&r2=1.2447 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesrc.c.diff?r1=1.103&r2=1.104 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2446 retrieving revision 1.2447 diff -u -d -r1.2446 -r1.2447 --- ChangeLog 28 Apr 2006 13:16:03 -0000 1.2446 +++ ChangeLog 28 Apr 2006 13:18:41 -0000 1.2447 @@ -1,5 +1,11 @@ 2006-04-28 Wim Taymans <wi...@fl...> + * libs/gst/base/gstbasesrc.c: (gst_base_src_perform_seek), + (gst_base_src_send_event), (gst_base_src_change_state): + Documentation updates. + +2006-04-28 Wim Taymans <wi...@fl...> * plugins/elements/gstfdsink.c: (gst_fd_sink_render), (gst_fd_sink_check_fd), (gst_fd_sink_update_fd): handle EAGAIN, EINTR and short writes correctly. Also clean Index: gstbasesrc.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesrc.c,v retrieving revision 1.103 retrieving revision 1.104 diff -u -d -r1.103 -r1.104 --- gstbasesrc.c 8 Apr 2006 20:57:30 -0000 1.103 +++ gstbasesrc.c 28 Apr 2006 13:18:41 -0000 1.104 @@ -87,9 +87,10 @@ * value from the READY to PAUSED state will be GST_STATE_CHANGE_NO_PREROLL. * </para> * <para> - * A typical live source will timestamp the buffers they create with the - * current stream time of the pipeline. This is one reason that they can only - * produce data in PLAYING, when the clock is actually distributed and running. + * A typical live source will timestamp the buffers it creates with the + * current stream time of the pipeline. This is one reason why a live source + * can only produce data in the PLAYING state, when the clock is actually + * distributed and running. * The #GstBaseSrc::get_times method can be used to implement pseudo-live @@ -154,7 +155,12 @@ * </programlisting> - * Last reviewed on 2006-03-31 (0.10.5) + * Note that setting the source element to NULL or READY when the + * pipeline is in the PAUSED state may cause a deadlock since the streaming + * thread might be blocked in PREROLL. + * </para> + * <para> + * Last reviewed on 2006-04-14 (0.10.6) * </refsect2> */ @@ -405,8 +411,14 @@ * @src: base source instance * @live: new live-mode * - * If the element listens to a live source, the @livemode should - * be set to %TRUE. This declares that this source can't seek. + * If the element listens to a live source, @live should + * be set to %TRUE. + * + * A live source will not produce data in the PAUSED state and + * will therefore not be able to participate in the PREROLL phase + * of a pipeline. To signal this fact to the application and the + * pipeline, the state change return value of the live source will + * be GST_STATE_CHANGE_NO_PREROLL. void gst_base_src_set_live (GstBaseSrc * src, gboolean live) @@ -797,12 +809,12 @@ gst_base_src_unlock (src); /* grab streaming lock, this should eventually be possible, either - * because the task is paused or out streaming thread stopped + * because the task is paused or our streaming thread stopped * because our peer is flushing. */ GST_PAD_STREAM_LOCK (src->srcpad); /* make copy into temp structure, we can only update the main one - * when the subclass actually could to the seek. */ + * when the subclass actually could do the seek. */ memcpy (&seeksegment, &src->segment, sizeof (GstSegment)); /* now configure the seek segment */ @@ -892,9 +904,16 @@ switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_START: case GST_EVENT_FLUSH_STOP: + /* sending random flushes downstream can break stuff, + * especially sync since all segment info will get flushed */ break; case GST_EVENT_EOS: + /* FIXME, queue EOS and make sure the task or pull function + * perform the EOS actions. */ + break; case GST_EVENT_NEWSEGMENT: + /* sending random NEWSEGMENT downstream can break sync. */ case GST_EVENT_TAG: case GST_EVENT_BUFFERSIZE: @@ -1894,6 +1913,9 @@ if (!gst_base_src_stop (basesrc)) goto error_stop; + /* FIXME, deprecate this behaviour, it is very dangerous. + * the prefered way of sending EOS downstream is by sending + * the EOS event to the element */ if (!basesrc->priv->last_sent_eos) { GST_DEBUG_OBJECT (basesrc, "Sending EOS event"); gst_pad_push_event (basesrc->srcpad, gst_event_new_eos ()); |
From: <wt...@ke...> - 2006-04-28 13:26:22
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Fri Apr 28 2006 13:26:10 UTC Log message: * libs/gst/base/gstbasesink.c: (gst_base_sink_is_too_late), (gst_base_sink_do_render_stats), (gst_base_sink_render_object), (gst_base_sink_get_position), (gst_base_sink_change_state): When frame dropping is enabled, we should not ignore frames without a duration. Update some documentation. Modified files: . : ChangeLog libs/gst/base : gstbasesink.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.2447&r2=1.2448 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/libs/gst/base/gstbasesink.c.diff?r1=1.139&r2=1.140 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.2447 retrieving revision 1.2448 diff -u -d -r1.2447 -r1.2448 --- ChangeLog 28 Apr 2006 13:18:41 -0000 1.2447 +++ ChangeLog 28 Apr 2006 13:25:58 -0000 1.2448 @@ -1,5 +1,14 @@ 2006-04-28 Wim Taymans <wi...@fl...> + * libs/gst/base/gstbasesink.c: (gst_base_sink_is_too_late), + (gst_base_sink_do_render_stats), (gst_base_sink_render_object), + (gst_base_sink_get_position), (gst_base_sink_change_state): + When frame dropping is enabled, we should not ignore frames + without a duration. + Update some documentation. + +2006-04-28 Wim Taymans <wi...@fl...> * libs/gst/base/gstbasesrc.c: (gst_base_src_perform_seek), (gst_base_src_send_event), (gst_base_src_change_state): Documentation updates. Index: gstbasesink.c RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstbasesink.c,v retrieving revision 1.139 retrieving revision 1.140 diff -u -d -r1.139 -r1.140 --- gstbasesink.c 10 Apr 2006 10:46:44 -0000 1.139 +++ gstbasesink.c 28 Apr 2006 13:25:58 -0000 1.140 @@ -187,8 +187,12 @@ #define DO_RUNNING_AVG(avg,val,size) (((val) + ((size)-1) * (avg)) / (size)) +/* generic running average, this has a neutral window size */ #define UPDATE_RUNNING_AVG(avg,val) DO_RUNNING_AVG(avg,val,8) +/* the windows for these running averages are experimentally obtained. + * possitive values get averaged more while negative values use a small + * window so we can react faster to badness. */ #define UPDATE_RUNNING_AVG_P(avg,val) DO_RUNNING_AVG(avg,val,16) #define UPDATE_RUNNING_AVG_N(avg,val) DO_RUNNING_AVG(avg,val,4) @@ -1341,12 +1345,24 @@ if (G_UNLIKELY (start == -1)) goto no_timestamp; + /* we can add a valid stop time */ + if (stop != -1) + max_lateness += stop; + else + max_lateness += start; /* if the jitter bigger than duration and lateness we are too late */ - if (G_LIKELY (stop != -1)) { - if ((late = start + jitter > stop + max_lateness)) { - if (priv->last_in_time && start - priv->last_in_time > GST_SECOND) { - late = FALSE; - } + if ((late = start + jitter > max_lateness)) { + GST_DEBUG_OBJECT (basesink, "buffer is too late %" GST_TIME_FORMAT + " > %" GST_TIME_FORMAT, GST_TIME_ARGS (start + jitter), + GST_TIME_ARGS (max_lateness)); + /* !!emergency!!, if we did not receive anything valid for more than a + * second, render it anyway so the user sees something */ + if (priv->last_in_time && start - priv->last_in_time > GST_SECOND) { + late = FALSE; + GST_DEBUG_OBJECT (basesink, + "**emergency** last buffer at %" GST_TIME_FORMAT " > GST_SECOND", + GST_TIME_ARGS (priv->last_in_time)); } } @@ -1401,8 +1417,6 @@ else priv->avg_render = UPDATE_RUNNING_AVG (priv->avg_render, elapsed); - priv->rendered++; - GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, basesink, "avg_render: %" GST_TIME_FORMAT, GST_TIME_ARGS (priv->avg_render)); @@ -1453,6 +1467,8 @@ ret = bclass->render (basesink, GST_BUFFER_CAST (obj)); + priv->rendered++; if (do_qos) gst_base_sink_do_render_stats (basesink, FALSE); @@ -2268,15 +2284,16 @@ gst_object_ref (clock); /* need to release the object lock before we can get the time, - * a clock might take the LOCK of the provider. */ + * a clock might take the LOCK of the provider, which could be + * a basesink subclass. */ GST_OBJECT_UNLOCK (basesink); now = gst_clock_get_time (clock); base += accum; base = MIN (now, base); - /* never report more than last seen position */ *cur = gst_guint64_to_gdouble (now - base) * abs_rate + time; + /* never report more than last seen position */ if (last != -1) *cur = MIN (last, *cur); @@ -2472,6 +2489,10 @@ basesink->playing_async = TRUE; ret = GST_STATE_CHANGE_ASYNC; } + GST_DEBUG_OBJECT (basesink, "rendered: %" G_GUINT64_FORMAT + ", dropped: %" G_GUINT64_FORMAT, basesink->priv->rendered, + basesink->priv->dropped); gst_base_sink_reset_qos (basesink); GST_PAD_PREROLL_UNLOCK (basesink->sinkpad); break; |