From: Wim T. <wt...@us...> - 2002-07-13 23:06:00
|
CVS Root: /cvsroot/gstreamer Module: gstreamer Changes by: wtay Date: Sat Jul 13 2002 16:05:58 PDT Log message: Small documentation updates Modified files: . : TODO gst : gst.c Links: http://cvs.sf.net/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/TODO.diff?r1=1.7&r2=1.8 http://cvs.sf.net/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gst.c.diff?r1=1.73&r2=1.74 ====Begin Diffs==== Index: TODO =================================================================== RCS file: /cvsroot/gstreamer/gstreamer/TODO,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- TODO 11 Jul 2002 21:10:44 -0000 1.7 +++ TODO 13 Jul 2002 23:05:45 -0000 1.8 @@ -9,7 +9,7 @@ target release ! description ! - ? ! expose and API to query the supported seek formats/flags on + 0.4.1 ! expose and API to query the supported seek formats/flags on ! pads, somthing like an extra arg to gst_pad_set_convert_function ! and gst_pad_set_event_function with some function to query the ! flags and formats. more ideas in docs/random/wtay/query_events Index: gst.c =================================================================== RCS file: /cvsroot/gstreamer/gstreamer/gst/gst.c,v retrieving revision 1.73 retrieving revision 1.74 diff -u -d -r1.73 -r1.74 --- gst.c 8 Jul 2002 19:22:01 -0000 1.73 +++ gst.c 13 Jul 2002 23:05:46 -0000 1.74 @@ -509,12 +509,28 @@ } } +/** + * gst_use_threads: + * @use_threads: flag indicating threads should be used + * + * Instructs the core to turn on/off threading. When threading + * is turned off, all thread operations such as mutexes and conditionals + * are turned into NOPs. use this if you want absolute minimal overhead + * and you don't use any threads in the pipeline. + */ void gst_use_threads (gboolean use_threads) { _gst_use_threads = use_threads; } +/** + * gst_has_threads: + * + * Query if GStreamer has threads enabled. + * + * Returns: TRUE if threads are enabled. + */ gboolean gst_has_threads (void) { |
From: Wim T. <wt...@pd...> - 2004-05-20 17:44:16
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Thu May 20 2004 10:44:15 PDT Log message: * gst/gstbuffer.c: (gst_buffer_default_copy): * gst/gstbuffer.h: Added Comment to a flag. copy relevant flags in _buffer_copy. Modified files: . : ChangeLog gst : gstbuffer.c gstbuffer.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.551&r2=1.552 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstbuffer.c.diff?r1=1.86&r2=1.87 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstbuffer.h.diff?r1=1.75&r2=1.76 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.551 retrieving revision 1.552 diff -u -d -r1.551 -r1.552 --- a/ChangeLog 20 May 2004 17:03:02 -0000 1.551 +++ b/ChangeLog 20 May 2004 17:44:03 -0000 1.552 @@ -1,3 +1,10 @@ +2004-05-20 Wim Taymans <wi...@fl...> + + * gst/gstbuffer.c: (gst_buffer_default_copy): + * gst/gstbuffer.h: + Added Comment to a flag. + copy relevant flags in _buffer_copy. 2004-05-20 Thomas Vander Stichele <thomas at apestaart dot org> reviewed by: Wim Taymans <wim at fluendo dot com> Index: gstbuffer.c RCS file: /cvs/gstreamer/gstreamer/gst/gstbuffer.c,v retrieving revision 1.86 retrieving revision 1.87 diff -u -d -r1.86 -r1.87 --- a/gstbuffer.c 13 Apr 2004 02:22:02 -0000 1.86 +++ b/gstbuffer.c 20 May 2004 17:44:03 -0000 1.87 @@ -140,15 +140,20 @@ gst_buffer_default_copy (GstBuffer * buffer) { GstBuffer *copy; + guint16 flags; g_return_val_if_fail (buffer != NULL, NULL); /* create a fresh new buffer */ copy = gst_buffer_alloc_chunk (); + /* copy relevant flags */ + flags = GST_DATA_FLAG_SHIFT (GST_BUFFER_KEY_UNIT) | + GST_DATA_FLAG_SHIFT (GST_BUFFER_IN_CAPS); _GST_DATA_INIT (GST_DATA (copy), _gst_buffer_type, - 0, + flags, (GstDataFreeFunction) gst_buffer_default_free, (GstDataCopyFunction) gst_buffer_default_copy); Index: gstbuffer.h RCS file: /cvs/gstreamer/gstreamer/gst/gstbuffer.h,v retrieving revision 1.75 retrieving revision 1.76 diff -u -d -r1.75 -r1.76 --- a/gstbuffer.h 20 May 2004 17:03:02 -0000 1.75 +++ b/gstbuffer.h 20 May 2004 17:44:03 -0000 1.76 @@ -78,7 +78,7 @@ GST_BUFFER_SUBBUFFER = GST_DATA_FLAG_LAST, GST_BUFFER_ORIGINAL, GST_BUFFER_DONTFREE, - GST_BUFFER_KEY_UNIT, + GST_BUFFER_KEY_UNIT, /* sync point in the stream */ GST_BUFFER_DONTKEEP, GST_BUFFER_IN_CAPS, GST_BUFFER_FLAG_LAST = GST_DATA_FLAG_LAST + 8 |
From: Wim T. <wt...@pd...> - 2004-07-09 15:04:17
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Sat Jul 10 2004 01:04:13 EST Log message: * gst/gstbin.c: (gst_bin_remove), (gst_bin_dispose): * gst/gstthread.c: (gst_thread_dispose), (gst_thread_catch), (gst_thread_main_loop): Since remove is virtual in GstBin we must not assume the elements GList to have anothing usefull. Add some more logging to GstThread and be a bit more paranoid when resetting the scheduler. Set the state of the bin to NULL before removing the children. Modified files: . : ChangeLog gst : gstbin.c gstthread.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.651&r2=1.652 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstbin.c.diff?r1=1.193&r2=1.194 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstthread.c.diff?r1=1.127&r2=1.128 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.651 retrieving revision 1.652 diff -u -d -r1.651 -r1.652 --- ChangeLog 9 Jul 2004 14:18:35 -0000 1.651 +++ ChangeLog 9 Jul 2004 15:03:51 -0000 1.652 @@ -1,3 +1,14 @@ +2004-07-09 Wim Taymans <wi...@fl...> + + * gst/gstbin.c: (gst_bin_remove), (gst_bin_dispose): + * gst/gstthread.c: (gst_thread_dispose), (gst_thread_catch), + (gst_thread_main_loop): + Since remove is virtual in GstBin we must not assume the + elements GList to have anothing usefull. + Add some more logging to GstThread and be a bit more paranoid + when resetting the scheduler. + Set the state of the bin to NULL before removing the children. 2004-07-09 Zaheer Abbas Merali <zaheerabbas at merali dot org> * testsuite/threads/Makefile.am: Index: gstbin.c RCS file: /cvs/gstreamer/gstreamer/gst/gstbin.c,v retrieving revision 1.193 retrieving revision 1.194 diff -u -d -r1.193 -r1.194 --- gstbin.c 9 Jul 2004 13:33:20 -0000 1.193 +++ gstbin.c 9 Jul 2004 15:03:51 -0000 1.194 @@ -588,7 +588,6 @@ g_return_if_fail (GST_IS_BIN (bin)); g_return_if_fail (GST_IS_ELEMENT (element)); - g_return_if_fail (bin->children != NULL); bclass = GST_BIN_GET_CLASS (bin); @@ -833,8 +832,7 @@ GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose"); - if (gst_element_get_state (GST_ELEMENT (object)) == GST_STATE_PLAYING) - gst_element_set_state (GST_ELEMENT (object), GST_STATE_PAUSED); + gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL); while (bin->children) { gst_bin_remove (bin, GST_ELEMENT (bin->children->data)); Index: gstthread.c RCS file: /cvs/gstreamer/gstreamer/gst/gstthread.c,v retrieving revision 1.127 retrieving revision 1.128 diff -u -d -r1.127 -r1.128 --- gstthread.c 9 Jul 2004 11:20:59 -0000 1.127 +++ gstthread.c 9 Jul 2004 15:03:51 -0000 1.128 @@ -223,6 +223,8 @@ g_assert (GST_STATE (thread) == GST_STATE_NULL); + GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "GstThread: dispose, freeing locks"); g_mutex_free (thread->lock); g_cond_free (thread->cond); @@ -369,12 +371,14 @@ if (thread == gst_thread_get_current ()) { /* we're trying to catch ourself */ if (!GST_FLAG_IS_SET (thread, GST_THREAD_MUTEX_LOCKED)) { + GST_DEBUG_OBJECT (thread, "catching itself, grabbing lock"); g_mutex_lock (thread->lock); GST_FLAG_SET (thread, GST_THREAD_MUTEX_LOCKED); } GST_DEBUG_OBJECT (thread, "catching itself"); GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING); } else { + GST_DEBUG_OBJECT (thread, "catching thread, grabbing lock"); /* another thread is trying to catch us */ g_mutex_lock (thread->lock); wait = !GST_FLAG_IS_SET (thread, GST_THREAD_STATE_SPINNING); @@ -555,6 +559,7 @@ { GstThread *thread = NULL; gboolean status; + GstScheduler *sched; thread = GST_THREAD (arg); g_mutex_lock (thread->lock); @@ -595,7 +600,9 @@ /* we need to destroy the scheduler here because it has mapped it's * stack into the threads stack space */ - gst_scheduler_reset (GST_ELEMENT_SCHED (thread)); + sched = GST_ELEMENT_SCHED (thread); + if (sched) + gst_scheduler_reset (sched); /* must do that before releasing the lock - we might get disposed before being done */ g_signal_emit (G_OBJECT (thread), gst_thread_signals[SHUTDOWN], 0); |
From: <wt...@fr...> - 2004-07-28 10:15:21
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Wed Jul 28 2004 20:15:20 EST Log message: * gst/gstbin.c: (set_kid_state_func), (gst_bin_set_state): * gst/gstthread.c: (gst_thread_release), (gst_thread_set_state): Make sure that a bin state change tries to keep the children in sync. Added debug logging to the thread. Modified files: . : ChangeLog gst : gstbin.c gstthread.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.732&r2=1.733 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstbin.c.diff?r1=1.198&r2=1.199 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstthread.c.diff?r1=1.130&r2=1.131 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.732 retrieving revision 1.733 diff -u -d -r1.732 -r1.733 --- ChangeLog 27 Jul 2004 21:33:04 -0000 1.732 +++ ChangeLog 28 Jul 2004 10:15:07 -0000 1.733 @@ -1,3 +1,11 @@ +2004-07-28 Wim Taymans <wi...@fl...> + + * gst/gstbin.c: (set_kid_state_func), (gst_bin_set_state): + * gst/gstthread.c: (gst_thread_release), (gst_thread_set_state): + Make sure that a bin state change tries to keep the children + in sync. + Added debug logging to the thread. 2004-07-27 Steve Lhomme <ste...@fr...> * win32/GStreamer.vcproj: Index: gstbin.c RCS file: /cvs/gstreamer/gstreamer/gst/gstbin.c,v retrieving revision 1.198 retrieving revision 1.199 diff -u -d -r1.198 -r1.199 --- gstbin.c 21 Jul 2004 21:28:57 -0000 1.198 +++ gstbin.c 28 Jul 2004 10:15:08 -0000 1.199 @@ -793,6 +793,7 @@ typedef struct { + GstElementState intermediate; GstElementState pending; GstElementStateReturn result; } @@ -810,17 +811,49 @@ old_child_state = GST_STATE (child); + /* are we moving up or down? */ + if (data->intermediate < data->pending) { + /* up, check if we are already closer to target */ + if (old_child_state >= data->intermediate && + old_child_state < data->pending) { + GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, + "state of child %s is %s, inbetween intermediate %s and pending %s", + GST_ELEMENT_NAME (child), + gst_element_state_get_name (old_child_state), + gst_element_state_get_name (data->intermediate), + gst_element_state_get_name (data->pending)); + return TRUE; + } + } else if (data->intermediate > data->pending) { + /* down, check if we are already closer to target */ + if (old_child_state < data->intermediate) { + } else { + /* same state */ + GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, + "setting final state on child %s, now in %s, going to %s", + GST_ELEMENT_NAME (child), gst_element_state_get_name (old_child_state), + gst_element_state_get_name (data->intermediate)); + } GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, - "changing state of child %s from current %s to pending %s", + "changing state of child %s from current %s to intermediate %s", GST_ELEMENT_NAME (child), gst_element_state_get_name (old_child_state), - gst_element_state_get_name (data->pending)); + gst_element_state_get_name (data->intermediate)); - switch (gst_element_set_state (child, data->pending)) { + switch (gst_element_set_state (child, data->intermediate)) { case GST_STATE_FAILURE: GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin, "child '%s' failed to go to state %d(%s)", GST_ELEMENT_NAME (child), - data->pending, gst_element_state_get_name (data->pending)); + data->intermediate, gst_element_state_get_name (data->intermediate)); gst_element_set_state (child, old_child_state); return FALSE; /* error out to the caller */ @@ -834,8 +867,8 @@ case GST_STATE_SUCCESS: GST_CAT_DEBUG (GST_CAT_STATES, "child '%s' changed state to %d(%s) successfully", - GST_ELEMENT_NAME (child), data->pending, - gst_element_state_get_name (data->pending)); + GST_ELEMENT_NAME (child), data->intermediate, + gst_element_state_get_name (data->intermediate)); data->result = GST_STATE_SUCCESS; return TRUE; @@ -850,14 +883,49 @@ GstBin *bin = GST_BIN (element); SetKidStateData data; + GstElementStateReturn ret = GST_STATE_FAILURE; + GstElementState pending; - data.pending = state; - data.result = GST_STATE_ASYNC; - if (!gst_bin_foreach (bin, set_kid_state_func, &data)) { - return GST_STATE_FAILURE; - } else { - return data.result; + /* we start with the state of the bin */ + intermediate = GST_STATE (element); + pending = state; + GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, + "setting state of bin %s from current %s to pending %s", + GST_ELEMENT_NAME (element), gst_element_state_get_name (intermediate), + gst_element_state_get_name (pending)); + do { + data.intermediate = intermediate; + data.pending = pending; + data.result = GST_STATE_ASYNC; + "setting state of children to intermediate %s", + gst_element_state_get_name (intermediate)); + if (!gst_bin_foreach (bin, set_kid_state_func, &data)) { + ret = GST_STATE_FAILURE; + /* break out of the loop after failure */ + break; + } else { + ret = data.result; + /* if we have reached the target state, we can stop */ + if (intermediate == pending) + /* move intermediate state closer to target state */ + if (intermediate < pending) + intermediate <<= 1; + else + intermediate >>= 1; } + while (TRUE); + return ret; static GstElementStateReturn Index: gstthread.c RCS file: /cvs/gstreamer/gstreamer/gst/gstthread.c,v retrieving revision 1.130 retrieving revision 1.131 diff -u -d -r1.130 -r1.131 --- gstthread.c 21 Jul 2004 21:28:57 -0000 1.130 +++ gstthread.c 28 Jul 2004 10:15:08 -0000 1.131 @@ -406,6 +406,7 @@ gst_thread_release (GstThread * thread) if (thread != gst_thread_get_current ()) { + GST_DEBUG_OBJECT (thread, "releasing lock"); g_cond_signal (thread->cond); g_mutex_unlock (thread->lock); @@ -419,12 +420,14 @@ gst_thread_catch (thread); result = GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS, set_state, (element, state), GST_STATE_FAILURE); + GST_DEBUG_OBJECT (thread, "grabbing lock"); g_mutex_lock (thread->lock); gst_thread_release (thread); |
From: <wt...@fr...> - 2004-08-03 09:51:52
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Tue Aug 03 2004 19:51:49 EST Log message: * gst/gstbin.c: (gst_bin_get_type), (gst_bin_child_state_change_func): * gst/gstthread.c: (gst_thread_change_state): Backported some debug logging from a reverted patch Don't try to destroy the thread twice. Added some more debugging in GstThread. Unlock and signal even if we are in the thread context. Modified files: . : ChangeLog gst : gstbin.c gstthread.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.746&r2=1.747 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstbin.c.diff?r1=1.201&r2=1.202 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstthread.c.diff?r1=1.132&r2=1.133 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.746 retrieving revision 1.747 diff -u -d -r1.746 -r1.747 --- ChangeLog 3 Aug 2004 08:52:20 -0000 1.746 +++ ChangeLog 3 Aug 2004 09:51:36 -0000 1.747 @@ -1,3 +1,13 @@ +2004-08-03 Wim Taymans <wi...@fl...> + + * gst/gstbin.c: (gst_bin_get_type), + (gst_bin_child_state_change_func): + * gst/gstthread.c: (gst_thread_change_state): + Backported some debug logging from a reverted patch + Don't try to destroy the thread twice. Added some more + debugging in GstThread. Unlock and signal even if we + are in the thread context. 2004-08-03 Thomas Vander Stichele <thomas at apestaart dot org> * po/uk.po: Index: gstbin.c RCS file: /cvs/gstreamer/gstreamer/gst/gstbin.c,v retrieving revision 1.201 retrieving revision 1.202 diff -u -d -r1.201 -r1.202 --- gstbin.c 29 Jul 2004 20:33:48 -0000 1.201 +++ gstbin.c 3 Aug 2004 09:51:36 -0000 1.202 @@ -34,6 +34,15 @@ #include "gstindex.h" #include "gstutils.h" +GST_DEBUG_CATEGORY_STATIC (bin_debug); +#define GST_CAT_DEFAULT bin_debug +#define GST_LOG_BIN_CONTENTS(bin, text) GST_LOG_OBJECT ((bin), \ + text ": %d elements: %u PLAYING, %u PAUSED, %u READY, %u NULL, own state: %s", \ + (bin)->numchildren, (guint) (bin)->child_states[3], \ + (guint) (bin)->child_states[2], (bin)->child_states[1], \ + (bin)->child_states[0], gst_element_state_get_name (GST_STATE (bin))) static GstElementDetails gst_bin_details = GST_ELEMENT_DETAILS ("Generic bin", "Generic/Bin", "Simple container object", @@ -116,6 +125,9 @@ _gst_bin_type = g_type_register_static (GST_TYPE_ELEMENT, "GstBin", &bin_info, 0); + GST_DEBUG_CATEGORY_INIT (bin_debug, "bin", GST_DEBUG_BOLD, + "debugging info for the 'bin' container element"); } return _gst_bin_type; } @@ -685,6 +697,7 @@ new_idx++; GST_LOCK (bin); + GST_LOG_BIN_CONTENTS (bin, "before child state change"); bin->child_states[old_idx]--; bin->child_states[new_idx]++; @@ -703,11 +716,13 @@ g_warning ("%s: state change in callback %d %d", GST_ELEMENT_NAME (bin), state, GST_STATE (bin)); } + GST_LOG_BIN_CONTENTS (bin, "after child state change"); return; } break; } + GST_LOG_BIN_CONTENTS (bin, "after child state change"); GST_UNLOCK (bin); Index: gstthread.c RCS file: /cvs/gstreamer/gstreamer/gst/gstthread.c,v retrieving revision 1.132 retrieving revision 1.133 diff -u -d -r1.132 -r1.133 --- gstthread.c 29 Jul 2004 20:33:48 -0000 1.132 +++ gstthread.c 3 Aug 2004 09:51:37 -0000 1.133 @@ -482,27 +482,37 @@ by ourself (ouch) */ GST_LOG_OBJECT (thread, "destroying GThread %p", thread->thread_id); GST_FLAG_SET (thread, GST_THREAD_STATE_REAPING); - thread->thread_id = NULL; - if (thread == gst_thread_get_current ()) { - /* or should we continue? */ - g_warning - ("Thread %s is destroying itself. Function call will not return!", - GST_ELEMENT_NAME (thread)); - gst_scheduler_reset (GST_ELEMENT_SCHED (thread)); + /* thread was already gone */ + if (thread->thread_id != NULL) { + thread->thread_id = NULL; + if (thread == gst_thread_get_current ()) { + /* or should we continue? */ + GST_LOG_OBJECT (thread, + "Thread %s is destroying itself. Function call will not return!", + GST_ELEMENT_NAME (thread)); + gst_scheduler_reset (GST_ELEMENT_SCHED (thread)); - /* unlock and signal - we are out */ - gst_thread_release (thread); + /* unlock and signal - we are out, note that gst_thread_release does + * nothing when we are running in the thread context */ + GST_DEBUG_OBJECT (thread, "releasing lock"); + g_cond_signal (thread->cond); + g_mutex_unlock (thread->lock); - GST_INFO_OBJECT (thread, "GThread %p is exiting", g_thread_self ()); + GST_INFO_OBJECT (thread, "GThread %p is exiting", g_thread_self ()); - g_signal_emit (G_OBJECT (thread), gst_thread_signals[SHUTDOWN], 0); + g_signal_emit (G_OBJECT (thread), gst_thread_signals[SHUTDOWN], 0); - g_thread_exit (NULL); + g_thread_exit (NULL); + return GST_STATE_SUCCESS; + } + /* now wait for the thread to destroy itself */ + GST_DEBUG_OBJECT (thread, "signal"); + g_cond_signal (thread->cond); + GST_DEBUG_OBJECT (thread, "wait"); + g_cond_wait (thread->cond, thread->lock); + GST_DEBUG_OBJECT (thread, "done"); + /* it should be dead now */ - /* now wait for the thread to destroy itself */ - g_cond_signal (thread->cond); - g_cond_wait (thread->cond, thread->lock); - /* it should be dead now */ default: |
From: <wt...@fr...> - 2004-09-06 15:03:06
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Mon Sep 06 2004 08:03:00 PDT Log message: * gst/gstpad.c: (gst_pad_link_call_link_functions): Fix debug info. Modified files: . : ChangeLog gst : gstpad.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.782&r2=1.783 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstpad.c.diff?r1=1.343&r2=1.344 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.782 retrieving revision 1.783 diff -u -d -r1.782 -r1.783 --- ChangeLog 6 Sep 2004 14:55:56 -0000 1.782 +++ ChangeLog 6 Sep 2004 15:02:48 -0000 1.783 @@ -1,5 +1,10 @@ 2004-09-06 Wim Taymans <wi...@fl...> + * gst/gstpad.c: (gst_pad_link_call_link_functions): + Fix debug info. + +2004-09-06 Wim Taymans <wi...@fl...> * gst/schedulers/gstoptimalscheduler.c: (add_to_group), (remove_from_group): Some more debug info. Index: gstpad.c RCS file: /cvs/gstreamer/gstreamer/gst/gstpad.c,v retrieving revision 1.343 retrieving revision 1.344 diff -u -d -r1.343 -r1.344 --- gstpad.c 18 Aug 2004 21:46:55 -0000 1.343 +++ gstpad.c 6 Sep 2004 15:02:48 -0000 1.344 @@ -1338,7 +1338,7 @@ res = GST_RPAD_LINKFUNC (link->sinkpad) (GST_PAD (link->sinkpad), link->caps); - GST_DEBUG_OBJECT (link->sinkpad, "got reply %d from link function"); + GST_DEBUG_OBJECT (link->sinkpad, "got reply %d from link function", res); if (GST_PAD_LINK_FAILED (res)) { GST_CAT_INFO_OBJECT (GST_CAT_CAPS, link->sinkpad, |
From: <wt...@fr...> - 2004-09-06 15:14:16
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Mon Sep 06 2004 08:14:13 PDT Log message: * gst/gstelement.c: (gst_element_threadsafe_properties_pre_run), (gst_element_threadsafe_properties_post_run), (gst_element_set_state), (gst_element_change_state): Added extra refcounting around various places. Modified files: . : ChangeLog gst : gstelement.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.783&r2=1.784 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstelement.c.diff?r1=1.300&r2=1.301 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.783 retrieving revision 1.784 diff -u -d -r1.783 -r1.784 --- ChangeLog 6 Sep 2004 15:02:48 -0000 1.783 +++ ChangeLog 6 Sep 2004 15:14:01 -0000 1.784 @@ -1,5 +1,12 @@ 2004-09-06 Wim Taymans <wi...@fl...> + * gst/gstelement.c: (gst_element_threadsafe_properties_pre_run), + (gst_element_threadsafe_properties_post_run), + (gst_element_set_state), (gst_element_change_state): + Added extra refcounting around various places. + +2004-09-06 Wim Taymans <wi...@fl...> * gst/gstpad.c: (gst_pad_link_call_link_functions): Fix debug info. Index: gstelement.c RCS file: /cvs/gstreamer/gstreamer/gst/gstelement.c,v retrieving revision 1.300 retrieving revision 1.301 diff -u -d -r1.300 -r1.301 --- gstelement.c 17 Aug 2004 09:16:42 -0000 1.300 +++ gstelement.c 6 Sep 2004 15:14:01 -0000 1.301 @@ -296,6 +296,9 @@ static void gst_element_threadsafe_properties_pre_run (GstElement * element) { + /* need to ref the object because we don't want to lose the object + * before the post run function is called */ + gst_object_ref (GST_OBJECT (element)); GST_DEBUG ("locking element %s", GST_OBJECT_NAME (element)); g_mutex_lock (element->property_mutex); gst_element_set_pending_properties (element); @@ -306,6 +309,7 @@ GST_DEBUG ("unlocking element %s", GST_OBJECT_NAME (element)); g_mutex_unlock (element->property_mutex); + gst_object_unref (GST_OBJECT (element)); } /** @@ -2722,14 +2726,20 @@ gst_element_set_state (GstElement * element, GstElementState state) GstElementClass *klass = GST_ELEMENT_GET_CLASS (element); + GstElementStateReturn ret; g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE); GST_DEBUG_OBJECT (element, "setting state to %s", gst_element_state_get_name (state)); klass = GST_ELEMENT_GET_CLASS (element); - /* a set_state function is mandatory */ g_return_val_if_fail (klass->set_state, GST_STATE_FAILURE); - return klass->set_state (element, state); + /* a set_state function is mandatory */ + ret = klass->set_state (element, state); + return ret; static GstElementStateReturn @@ -3004,7 +3014,6 @@ * - a new state was added * - somehow the element was asked to jump across an intermediate state */ - g_assert_not_reached (); break; } @@ -3036,9 +3045,7 @@ 0, old_state, GST_STATE (element)); /* signal the state change in case somebody is waiting for us */ - g_mutex_lock (element->state_mutex); g_cond_signal (element->state_cond); - g_mutex_unlock (element->state_mutex); gst_object_unref (GST_OBJECT (element)); return GST_STATE_SUCCESS; |
From: <wt...@fr...> - 2004-10-06 09:42:50
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Wed Oct 06 2004 02:42:39 PDT Log message: * gst/gstthread.c: (gst_thread_init), (gst_thread_change_state), (gst_thread_main_loop): Lock the iteration and the state change so that automatic negotiation and fixation does not happen at the same time as the in stream negotiation. Modified files: . : ChangeLog gst : gstthread.c gstthread.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.798&r2=1.799 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstthread.c.diff?r1=1.135&r2=1.136 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstthread.h.diff?r1=1.31&r2=1.32 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.798 retrieving revision 1.799 diff -u -d -r1.798 -r1.799 --- ChangeLog 5 Oct 2004 13:33:18 -0000 1.798 +++ ChangeLog 6 Oct 2004 09:42:27 -0000 1.799 @@ -1,3 +1,11 @@ +2004-10-06 Wim Taymans <wim at fluendo dot com> + + * gst/gstthread.c: (gst_thread_init), (gst_thread_change_state), + (gst_thread_main_loop): + Lock the iteration and the state change so that automatic + negotiation and fixation does not happen at the same time + as the in stream negotiation. 2004-10-05 Thomas Vander Stichele <thomas at apestaart dot org> * configure.ac: Index: gstthread.c RCS file: /cvs/gstreamer/gstreamer/gst/gstthread.c,v retrieving revision 1.135 retrieving revision 1.136 diff -u -d -r1.135 -r1.136 --- gstthread.c 5 Oct 2004 08:52:37 -0000 1.135 +++ gstthread.c 6 Oct 2004 09:42:27 -0000 1.136 @@ -206,6 +206,7 @@ thread->lock = g_mutex_new (); thread->cond = g_cond_new (); + thread->iterate_lock = g_mutex_new (); thread->thread_id = (GThread *) NULL; /* set in NULL -> READY */ thread->priority = G_THREAD_PRIORITY_NORMAL; @@ -552,11 +553,13 @@ GST_LOG_OBJECT (thread, "unlocking lock"); g_mutex_unlock (thread->lock); + g_mutex_lock (thread->iterate_lock); if (GST_ELEMENT_CLASS (parent_class)->change_state) { ret = GST_ELEMENT_CLASS (parent_class)->change_state (GST_ELEMENT (thread)); } else { ret = GST_STATE_SUCCESS; } + g_mutex_unlock (thread->iterate_lock); return ret; @@ -664,7 +667,9 @@ gboolean status; g_mutex_unlock (thread->lock); + g_mutex_lock (thread->iterate_lock); status = gst_bin_iterate (GST_BIN (thread)); + g_mutex_unlock (thread->iterate_lock); g_mutex_lock (thread->lock); if (!status) { Index: gstthread.h RCS file: /cvs/gstreamer/gstreamer/gst/gstthread.h,v retrieving revision 1.31 retrieving revision 1.32 diff -u -d -r1.31 -r1.32 --- gstthread.h 6 Sep 2004 15:57:11 -0000 1.31 +++ gstthread.h 6 Oct 2004 09:42:27 -0000 1.32 @@ -61,7 +61,9 @@ GMutex *lock; /* thread lock/condititon pairs */ GCond *cond; /* used to control the thread */ - gpointer _gst_reserved[GST_PADDING]; + GMutex *iterate_lock; /* lock iteration in state change */ + gpointer _gst_reserved[GST_PADDING-1]; }; struct _GstThreadClass { |
From: <wt...@fr...> - 2004-10-07 17:41:56
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Thu Oct 07 2004 10:41:52 PDT Log message: * gst/gstthread.c: (gst_thread_dispose), (gst_thread_sync), (gst_thread_change_state), (gst_thread_child_state_change): Do not try to grab the iterate lock in the state change method when we are in the same thread as the iterate or else we could deadlock. Some other cleanups. Modified files: . : ChangeLog gst : gstthread.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.803&r2=1.804 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstthread.c.diff?r1=1.136&r2=1.137 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.803 retrieving revision 1.804 diff -u -d -r1.803 -r1.804 --- ChangeLog 6 Oct 2004 17:16:35 -0000 1.803 +++ ChangeLog 7 Oct 2004 17:41:39 -0000 1.804 @@ -1,3 +1,11 @@ +2004-10-07 Wim Taymans <wim at fluendo dot com> + + * gst/gstthread.c: (gst_thread_dispose), (gst_thread_sync), + (gst_thread_change_state), (gst_thread_child_state_change): + Do not try to grab the iterate lock in the state change method + when we are in the same thread as the iterate or else we + could deadlock. Some other cleanups. 2004-10-06 Thomas Vander Stichele <thomas at apestaart dot org> * configure.ac: Index: gstthread.c RCS file: /cvs/gstreamer/gstreamer/gst/gstthread.c,v retrieving revision 1.136 retrieving revision 1.137 diff -u -d -r1.136 -r1.137 --- gstthread.c 6 Oct 2004 09:42:27 -0000 1.136 +++ gstthread.c 7 Oct 2004 17:41:40 -0000 1.137 @@ -36,7 +36,8 @@ "Generic/Bin", "Container that creates/manages a thread", "Erik Walthinsen <om...@cs...>, " - "Benjamin Otte <in...@in..."); + "Benjamin Otte <in...@in..." + "Wim Taymans <wi...@fl..."); /* Thread signals and args */ enum @@ -74,7 +75,7 @@ static void gst_thread_child_state_change (GstBin * bin, GstElementState oldstate, GstElementState newstate, GstElement * element); -static void gst_thread_sync (GstThread * thread); +static void gst_thread_sync (GstThread * thread, gboolean is_self); #ifndef GST_DISABLE_LOADSAVE static xmlNodePtr gst_thread_save_thyself (GstObject * object, @@ -248,6 +249,7 @@ g_mutex_free (thread->lock); g_cond_free (thread->cond); + g_mutex_free (thread->iterate_lock); gst_object_replace ((GstObject **) & GST_ELEMENT_SCHED (thread), NULL); } @@ -390,7 +392,7 @@ * This function should be called with the thread lock held. */ static void -gst_thread_sync (GstThread * thread) +gst_thread_sync (GstThread * thread, gboolean is_self) { if (thread->thread_id == NULL) return; @@ -398,7 +400,7 @@ /* need to stop spinning in any case */ GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING); - if (thread == gst_thread_get_current ()) { + if (is_self) { /* we're trying to sync ourself. Not much we can do here but hope * that the thread will stop spinning and end up in the waiting * state */ @@ -435,6 +437,7 @@ GstThread *thread; GstElementStateReturn ret; gint transition; + gboolean is_self; g_return_val_if_fail (GST_IS_THREAD (element), GST_STATE_FAILURE); @@ -446,10 +449,14 @@ thread = GST_THREAD (element); + /* boolean to check if we called the state change in the same thread as + * the iterate thread */ + is_self = (thread == gst_thread_get_current ()); GST_LOG_OBJECT (thread, "grabbing lock"); g_mutex_lock (thread->lock); - gst_thread_sync (thread); + gst_thread_sync (thread, is_self); /* FIXME: (or GStreamers ideas about "threading"): the element variables are commonly accessed by multiple threads at the same time (see bug #111146 @@ -517,7 +524,7 @@ /* thread was already gone */ if (thread->thread_id != NULL) { thread->thread_id = NULL; - if (thread == gst_thread_get_current ()) { + if (is_self) { /* or should we continue? */ GST_LOG_OBJECT (thread, "Thread %s is destroying itself. Function call will not return!", @@ -553,13 +560,18 @@ GST_LOG_OBJECT (thread, "unlocking lock"); g_mutex_unlock (thread->lock); - g_mutex_lock (thread->iterate_lock); + /* do not try to grab the lock if this method is called from the + * same thread as the iterate thread, the lock might be held and we + * might deadlock */ + if (!is_self) + g_mutex_lock (thread->iterate_lock); if (GST_ELEMENT_CLASS (parent_class)->change_state) { ret = GST_ELEMENT_CLASS (parent_class)->change_state (GST_ELEMENT (thread)); } else { ret = GST_STATE_SUCCESS; } - g_mutex_unlock (thread->iterate_lock); + g_mutex_unlock (thread->iterate_lock); return ret; @@ -586,9 +598,15 @@ GstElementState newstate, GstElement * element) GstThread *thread = GST_THREAD (bin); + GstThread *current; + current = gst_thread_get_current (); + is_self = (current == thread); GST_LOG_OBJECT (bin, "(from thread %s) child %s changed state from %s to %s", - gst_thread_get_current ()? GST_ELEMENT_NAME (gst_thread_get_current ()) : + current ? GST_ELEMENT_NAME (current) : "(none)", GST_ELEMENT_NAME (element), gst_element_state_get_name (oldstate), gst_element_state_get_name (newstate)); @@ -597,7 +615,7 @@ parent_class->child_state_change (bin, oldstate, newstate, element); /* see if we have to wake up the thread now. */ GST_LOG_OBJECT (element, "we are in the thread context"); /* we are the thread, set the spinning flag so that we start spinning * next time */ |
From: <wt...@fr...> - 2004-10-07 18:35:12
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Thu Oct 07 2004 11:35:09 PDT Log message: * gst/gstthread.c: (gst_thread_change_state), (gst_thread_child_state_change): Make sure no iteration happens while performing the state change as it could mess up the internal consistency of the thread state. Modified files: . : ChangeLog gst : gstthread.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.804&r2=1.805 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstthread.c.diff?r1=1.137&r2=1.138 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.804 retrieving revision 1.805 diff -u -d -r1.804 -r1.805 --- ChangeLog 7 Oct 2004 17:41:39 -0000 1.804 +++ ChangeLog 7 Oct 2004 18:34:57 -0000 1.805 @@ -1,5 +1,13 @@ 2004-10-07 Wim Taymans <wim at fluendo dot com> + * gst/gstthread.c: (gst_thread_change_state), + (gst_thread_child_state_change): + Make sure no iteration happens while performing + the state change as it could mess up the internal + consistency of the thread state. + +2004-10-07 Wim Taymans <wim at fluendo dot com> * gst/gstthread.c: (gst_thread_dispose), (gst_thread_sync), (gst_thread_change_state), (gst_thread_child_state_change): Do not try to grab the iterate lock in the state change method Index: gstthread.c RCS file: /cvs/gstreamer/gstreamer/gst/gstthread.c,v retrieving revision 1.137 retrieving revision 1.138 diff -u -d -r1.137 -r1.138 --- gstthread.c 7 Oct 2004 17:41:40 -0000 1.137 +++ gstthread.c 7 Oct 2004 18:34:57 -0000 1.138 @@ -445,8 +445,6 @@ gst_element_state_get_name (GST_STATE (element)), gst_element_state_get_name (GST_STATE_PENDING (element))); - transition = GST_STATE_TRANSITION (element); - thread = GST_THREAD (element); /* boolean to check if we called the state change in the same thread as @@ -458,12 +456,15 @@ gst_thread_sync (thread, is_self); - /* FIXME: (or GStreamers ideas about "threading"): the element variables are - commonly accessed by multiple threads at the same time (see bug #111146 - for an example) */ - if (transition != GST_STATE_TRANSITION (element)) { - g_warning ("inconsistent state information, fix threading please"); - } + /* no iteration is allowed during this state change because an iteration + * can cause another state change conflicting with this one */ + /* do not try to grab the lock if this method is called from the + * same thread as the iterate thread, the lock might be held and we + * might deadlock */ + if (!is_self) + g_mutex_lock (thread->iterate_lock); + transition = GST_STATE_TRANSITION (element); switch (transition) { case GST_STATE_NULL_TO_READY: @@ -560,11 +561,6 @@ GST_LOG_OBJECT (thread, "unlocking lock"); g_mutex_unlock (thread->lock); - /* do not try to grab the lock if this method is called from the - * same thread as the iterate thread, the lock might be held and we - * might deadlock */ - if (!is_self) - g_mutex_lock (thread->iterate_lock); if (GST_ELEMENT_CLASS (parent_class)->change_state) { ret = GST_ELEMENT_CLASS (parent_class)->change_state (GST_ELEMENT (thread)); } else { @@ -583,6 +579,9 @@ + g_mutex_unlock (thread->iterate_lock); return GST_STATE_FAILURE; } |
From: <wt...@fr...> - 2004-11-02 12:33:43
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Tue Nov 02 2004 04:33:36 PST Log message: * gst/gstscheduler.c: (gst_scheduler_add_element), (gst_scheduler_remove_element), (gst_scheduler_state_transition): Aplied clock distribution patch, this should fix bug #148787. Modified files: . : ChangeLog gst : gstscheduler.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.818&r2=1.819 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstscheduler.c.diff?r1=1.103&r2=1.104 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.818 retrieving revision 1.819 diff -u -d -r1.818 -r1.819 --- ChangeLog 27 Oct 2004 21:10:44 -0000 1.818 +++ ChangeLog 2 Nov 2004 12:33:24 -0000 1.819 @@ -1,3 +1,10 @@ +2004-11-02 Wim Taymans <wi...@fl...> + + * gst/gstscheduler.c: (gst_scheduler_add_element), + (gst_scheduler_remove_element), (gst_scheduler_state_transition): + Aplied clock distribution patch, this should fix bug + #148787. 2004-10-27 Thomas Vander Stichele <thomas at apestaart dot org> Submitted by: Kjartan Maraas <km...@br...> Index: gstscheduler.c RCS file: /cvs/gstreamer/gstreamer/gst/gstscheduler.c,v retrieving revision 1.103 retrieving revision 1.104 diff -u -d -r1.103 -r1.104 --- gstscheduler.c 12 Aug 2004 10:56:40 -0000 1.103 +++ gstscheduler.c 2 Nov 2004 12:33:24 -0000 1.104 @@ -215,6 +215,7 @@ gst_scheduler_add_element (GstScheduler * sched, GstElement * element) { GstSchedulerClass *sclass; + gboolean redistribute_clock = FALSE; g_return_if_fail (GST_IS_SCHEDULER (sched)); g_return_if_fail (GST_IS_ELEMENT (element)); @@ -233,15 +234,24 @@ sched->clock_providers = g_list_prepend (sched->clock_providers, element); GST_CAT_DEBUG (GST_CAT_CLOCK, "added clock provider %s", GST_ELEMENT_NAME (element)); + redistribute_clock = TRUE; } if (gst_element_requires_clock (element)) { sched->clock_receivers = g_list_prepend (sched->clock_receivers, element); GST_CAT_DEBUG (GST_CAT_CLOCK, "added clock receiver %s", gst_element_set_scheduler (element, sched); + if (redistribute_clock) { + GstClock *clock; + clock = gst_scheduler_get_clock (sched); + gst_scheduler_set_clock (sched, clock); + } sclass = GST_SCHEDULER_GET_CLASS (sched); if (sclass->add_element) @@ -259,12 +269,33 @@ gst_scheduler_remove_element (GstScheduler * sched, GstElement * element) + GList *link; - sched->clock_providers = g_list_remove (sched->clock_providers, element); - sched->clock_receivers = g_list_remove (sched->clock_receivers, element); + link = g_list_find (sched->clock_providers, element); + if (link) { + sched->clock_providers = g_list_delete_link (sched->clock_providers, link); + GST_CAT_DEBUG (GST_CAT_CLOCK, "removed clock provider %s", + GST_ELEMENT_NAME (element)); + link = g_list_find (sched->clock_receivers, element); + sched->clock_receivers = g_list_delete_link (sched->clock_receivers, link); + GST_CAT_DEBUG (GST_CAT_CLOCK, "removed clock receiver %s", @@ -295,6 +326,8 @@ g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE); if (element == sched->parent && sched->parent_sched == NULL) { + /* FIXME is distributing the clock in the state change still needed + * when we distribute as soon as we add/remove elements? I think not.*/ switch (transition) { case GST_STATE_READY_TO_PAUSED: { |
From: <wt...@fr...> - 2004-11-02 12:39:48
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Tue Nov 02 2004 04:39:40 PST Log message: * gst/gststructure.c: (gst_structure_get_abbrs), (gst_structure_from_abbr), (gst_structure_to_abbr): Remove that ugly if-then thing in the code that converts between strings and types. Modified files: . : ChangeLog gst : gststructure.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.819&r2=1.820 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gststructure.c.diff?r1=1.37&r2=1.38 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.819 retrieving revision 1.820 diff -u -d -r1.819 -r1.820 --- ChangeLog 2 Nov 2004 12:33:24 -0000 1.819 +++ ChangeLog 2 Nov 2004 12:39:27 -0000 1.820 @@ -1,5 +1,12 @@ 2004-11-02 Wim Taymans <wi...@fl...> + * gst/gststructure.c: (gst_structure_get_abbrs), + (gst_structure_from_abbr), (gst_structure_to_abbr): + Remove that ugly if-then thing in the code that converts + between strings and types. + +2004-11-02 Wim Taymans <wi...@fl...> * gst/gstscheduler.c: (gst_scheduler_add_element), (gst_scheduler_remove_element), (gst_scheduler_state_transition): Aplied clock distribution patch, this should fix bug Index: gststructure.c RCS file: /cvs/gstreamer/gstreamer/gst/gststructure.c,v retrieving revision 1.37 retrieving revision 1.38 diff -u -d -r1.37 -r1.38 --- gststructure.c 13 Aug 2004 13:31:22 -0000 1.37 +++ gststructure.c 2 Nov 2004 12:39:27 -0000 1.38 @@ -987,50 +987,75 @@ } GstStructureAbbreviation; -static GstStructureAbbreviation gst_structure_abbrs[] = { - {"int", G_TYPE_INT}, - {"i", G_TYPE_INT}, - {"float", G_TYPE_FLOAT}, - {"f", G_TYPE_FLOAT}, - {"double", G_TYPE_DOUBLE}, - {"d", G_TYPE_DOUBLE}, -/* these are implemented with strcmp below */ -//{ "buffer", GST_TYPE_BUFFER }, -//{ "fourcc", GST_TYPE_FOURCC }, -//{ "4", GST_TYPE_FOURCC }, -//{ "fraction", GST_TYPE_FRACTION }, - {"boolean", G_TYPE_BOOLEAN}, - {"bool", G_TYPE_BOOLEAN}, - {"b", G_TYPE_BOOLEAN}, - {"string", G_TYPE_STRING}, - {"str", G_TYPE_STRING}, - {"s", G_TYPE_STRING} -}; +static GstStructureAbbreviation * +gst_structure_get_abbrs (gint * n_abbrs) +{ + static GstStructureAbbreviation *abbrs = NULL; + static gint num = 0; + if (abbrs == NULL) { + /* dynamically generate the array */ + GstStructureAbbreviation dyn_abbrs[] = { + {"int", G_TYPE_INT} + , + {"i", G_TYPE_INT} + {"float", G_TYPE_FLOAT} + {"f", G_TYPE_FLOAT} + {"double", G_TYPE_DOUBLE} + {"d", G_TYPE_DOUBLE} + {"buffer", GST_TYPE_BUFFER} + {"fourcc", GST_TYPE_FOURCC} + {"4", GST_TYPE_FOURCC} + {"fraction", GST_TYPE_FRACTION} + {"boolean", G_TYPE_BOOLEAN} + {"bool", G_TYPE_BOOLEAN} + {"b", G_TYPE_BOOLEAN} + {"string", G_TYPE_STRING} + {"str", G_TYPE_STRING} + {"s", G_TYPE_STRING} + }; + num = G_N_ELEMENTS (dyn_abbrs); + /* permanently allocate and copy the array now */ + abbrs = g_new0 (GstStructureAbbreviation, num); + memcpy (abbrs, dyn_abbrs, sizeof (GstStructureAbbreviation) * num); + } + *n_abbrs = num; + return abbrs; +} static GType gst_structure_from_abbr (const char *type_name) { int i; + GstStructureAbbreviation *abbrs; + gint n_abbrs; g_return_val_if_fail (type_name != NULL, G_TYPE_INVALID); - for (i = 0; i < G_N_ELEMENTS (gst_structure_abbrs); i++) { - if (strcmp (type_name, gst_structure_abbrs[i].type_name) == 0) { - return gst_structure_abbrs[i].type; - } - } + abbrs = gst_structure_get_abbrs (&n_abbrs); - /* FIXME shouldn't be a special case */ - if (strcmp (type_name, "fourcc") == 0 || strcmp (type_name, "4") == 0) { - return GST_TYPE_FOURCC; - if (strcmp (type_name, "buffer") == 0) { - return GST_TYPE_BUFFER; - if (strcmp (type_name, "fraction") == 0) { - return GST_TYPE_FRACTION; + for (i = 0; i < n_abbrs; i++) { + if (strcmp (type_name, abbrs[i].type_name) == 0) { + return abbrs[i].type; + } } + /* this is the fallback */ return g_type_from_name (type_name); @@ -1038,24 +1063,17 @@ gst_structure_to_abbr (GType type) g_return_val_if_fail (type != G_TYPE_INVALID, NULL); - if (type == gst_structure_abbrs[i].type) { - return gst_structure_abbrs[i].type_name; - if (type == GST_TYPE_FOURCC) { - return "fourcc"; - if (type == GST_TYPE_BUFFER) { - return "buffer"; - if (type == GST_TYPE_FRACTION) { - return "fraction"; + if (type == abbrs[i].type) { + return abbrs[i].type_name; return g_type_name (type); |
From: <wt...@fr...> - 2004-11-25 12:46:50
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Thu Nov 25 2004 04:47:02 PST Log message: * gst/gstthread.c: (gst_thread_dispose), (gst_thread_change_state), (gst_thread_child_state_change), (gst_thread_main_loop): Ref the thread object in the GThread mainloop. Break out of the thread mainloop if it holds the last ref. This properly exits the threads when disposing the thread from its own context. It also avoids possible deadlocks in the dispose function. Modified files: . : ChangeLog gst : gstthread.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.842&r2=1.843 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstthread.c.diff?r1=1.138&r2=1.139 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.842 retrieving revision 1.843 diff -u -d -r1.842 -r1.843 --- ChangeLog 24 Nov 2004 18:54:35 -0000 1.842 +++ ChangeLog 25 Nov 2004 12:46:50 -0000 1.843 @@ -1,3 +1,12 @@ +2004-11-25 Wim Taymans <wi...@fl...> + + * gst/gstthread.c: (gst_thread_dispose), (gst_thread_change_state), + (gst_thread_child_state_change), (gst_thread_main_loop): + Ref the thread object in the GThread mainloop. Break out of the + thread mainloop if it holds the last ref. This properly exits + the threads when disposing the thread from its own context. It + also avoids possible deadlocks in the dispose function. 2004-11-24 Martin Soto <mar...@us...> * gst/gstqueue.c (gst_queue_link_sink): Grab the lock only when Index: gstthread.c RCS file: /cvs/gstreamer/gstreamer/gst/gstthread.c,v retrieving revision 1.138 retrieving revision 1.139 diff -u -d -r1.138 -r1.139 --- gstthread.c 7 Oct 2004 18:34:57 -0000 1.138 +++ gstthread.c 25 Nov 2004 12:46:50 -0000 1.139 @@ -220,33 +220,15 @@ GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "GstThread: dispose"); + /* if we get here, the thread is really stopped as it has released + * the last refcount to the thread object, so we can safely free the + * mutex and cond vars */ G_OBJECT_CLASS (parent_class)->dispose (object); g_assert (GST_STATE (thread) == GST_STATE_NULL); GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "GstThread: dispose, freeing locks"); - if (thread->thread_id != NULL) { - /* thread is still alive */ - g_mutex_lock (thread->lock); - /* thread can be spinning or waiting */ - GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING); - GST_FLAG_SET (thread, GST_THREAD_STATE_REAPING); - - if (!GST_FLAG_IS_SET (thread, GST_THREAD_STATE_WAITING)) { - GST_DEBUG_OBJECT (thread, "wait"); - g_cond_wait (thread->cond, thread->lock); - GST_DEBUG_OBJECT (thread, "done"); - } - /* now wait for the thread to destroy itself */ - GST_DEBUG_OBJECT (thread, "signal"); - g_cond_signal (thread->cond); - GST_DEBUG_OBJECT (thread, "wait"); - g_cond_wait (thread->cond, thread->lock); - GST_DEBUG_OBJECT (thread, "done"); - g_mutex_unlock (thread->lock); - } g_mutex_free (thread->lock); g_cond_free (thread->cond); g_mutex_free (thread->iterate_lock); @@ -674,6 +656,7 @@ g_cond_signal (thread->cond); GST_LOG_OBJECT (element, "unlocking lock"); + gst_object_ref (GST_OBJECT (thread)); /* as long as we're not dying we can continue */ while (!(GST_FLAG_IS_SET (thread, GST_THREAD_STATE_REAPING))) { /* in the playing state we need to do something special */ @@ -697,24 +680,35 @@ GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING); } } + /* if we hold the last refcount, the app unreffed the + * thread and we should stop ASAP */ + if (G_OBJECT (thread)->ref_count == 1) { + GST_DEBUG_OBJECT (thread, "reaping as refcount is only 1"); + GST_FLAG_SET (thread, GST_THREAD_STATE_REAPING); + GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING); + } } } - /* sync section */ - GST_LOG_OBJECT (thread, "entering sync"); - GST_FLAG_SET (thread, GST_THREAD_STATE_WAITING); - GST_FLAG_UNSET (thread, GST_THREAD_STATE_WAITING); - GST_LOG_OBJECT (thread, "wait done"); + /* do not try to sync when we are REAPING */ + if (!(GST_FLAG_IS_SET (thread, GST_THREAD_STATE_REAPING))) { + /* sync section */ + GST_LOG_OBJECT (thread, "entering sync"); + GST_DEBUG_OBJECT (thread, "signal"); + g_cond_signal (thread->cond); + GST_DEBUG_OBJECT (thread, "wait"); + GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING); + GST_FLAG_SET (thread, GST_THREAD_STATE_WAITING); + g_cond_wait (thread->cond, thread->lock); + GST_FLAG_UNSET (thread, GST_THREAD_STATE_WAITING); + GST_LOG_OBJECT (thread, "wait done"); + } } GST_LOG_OBJECT (thread, "unlocking lock"); + thread->thread_id = NULL; g_mutex_unlock (thread->lock); - /* we need to destroy the scheduler here because it has mapped it's - * stack into the threads stack space */ + /* we need to destroy the scheduler here because it might have + * mapped it's stack into the threads stack space */ sched = GST_ELEMENT_SCHED (thread); if (sched) gst_scheduler_reset (sched); @@ -724,6 +718,7 @@ /* signal - we are out */ GST_LOG_OBJECT (thread, "Thread %p exits main loop", g_thread_self ()); + gst_object_unref (GST_OBJECT (thread)); /* don't assume the GstThread object exists anymore now */ return NULL; |
From: <wt...@fr...> - 2004-12-03 11:23:34
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Fri Dec 03 2004 03:24:13 PST Log message: * gst/gstqueue.c: (gst_queue_init), (gst_queue_getcaps), (gst_queue_link), (gst_queue_handle_src_query): Reverted to 1.110 until this makes the testsuite and various apps work. Modified files: . : ChangeLog gst : gstqueue.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.852&r2=1.853 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstqueue.c.diff?r1=1.113&r2=1.114 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.852 retrieving revision 1.853 diff -u -d -r1.852 -r1.853 --- ChangeLog 1 Dec 2004 17:58:05 -0000 1.852 +++ ChangeLog 3 Dec 2004 11:24:01 -0000 1.853 @@ -1,3 +1,10 @@ +2004-12-03 Wim Taymans <wi...@fl...> + + * gst/gstqueue.c: (gst_queue_init), (gst_queue_getcaps), + (gst_queue_link), (gst_queue_handle_src_query): + Reverted to 1.110 until this makes the testsuite and various + apps work. 2004-12-01 Christian Fredrik Kalager Schaller chr...@fl... * docs/upload.mak: fix included CVS conflict strings Index: gstqueue.c RCS file: /cvs/gstreamer/gstreamer/gst/gstqueue.c,v retrieving revision 1.113 retrieving revision 1.114 diff -u -d -r1.113 -r1.114 --- gstqueue.c 29 Nov 2004 17:02:09 -0000 1.113 +++ gstqueue.c 3 Dec 2004 11:24:01 -0000 1.114 @@ -41,24 +41,6 @@ GST_STATIC_CAPS_ANY); GST_DEBUG_CATEGORY_STATIC (queue_dataflow); -#define GST_CAT_DEFAULT (queue_dataflow) - -#define STATUS(queue, msg) \ - GST_CAT_LOG_OBJECT (queue_dataflow, queue, \ - "(%s:%s) " msg ": %u of %u-%u buffers, %u of %u-%u " \ - "bytes, %" G_GUINT64_FORMAT " of %" G_GUINT64_FORMAT \ - "-%" G_GUINT64_FORMAT " ns, %u elements", \ - GST_DEBUG_PAD_NAME (pad), \ - queue->cur_level.buffers, \ - queue->min_threshold.buffers, \ - queue->max_size.buffers, \ - queue->cur_level.bytes, \ - queue->min_threshold.bytes, \ - queue->max_size.bytes, \ - queue->cur_level.time, \ - queue->min_threshold.time, \ - queue->max_size.time, \ - queue->queue->length) static GstElementDetails gst_queue_details = GST_ELEMENT_DETAILS ("Queue", "Generic", @@ -138,9 +120,7 @@ GstQueryType type, GstFormat * fmt, gint64 * value); static GstCaps *gst_queue_getcaps (GstPad * pad); -static GstPadLinkReturn -gst_queue_link_sink (GstPad * pad, const GstCaps * caps); -static GstPadLinkReturn gst_queue_link_src (GstPad * pad, const GstCaps * caps); +static GstPadLinkReturn gst_queue_link (GstPad * pad, const GstCaps * caps); static void gst_queue_locked_flush (GstQueue * queue); static GstElementStateReturn gst_queue_change_state (GstElement * element); @@ -308,7 +288,7 @@ GST_DEBUG_FUNCPTR (gst_queue_chain)); gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad); gst_pad_set_link_function (queue->sinkpad, - GST_DEBUG_FUNCPTR (gst_queue_link_sink)); + GST_DEBUG_FUNCPTR (gst_queue_link)); gst_pad_set_getcaps_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_queue_getcaps)); gst_pad_set_active (queue->sinkpad, TRUE); @@ -318,8 +298,7 @@ "src"); gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_get)); gst_element_add_pad (GST_ELEMENT (queue), queue->srcpad); - gst_pad_set_link_function (queue->srcpad, - GST_DEBUG_FUNCPTR (gst_queue_link_src)); + gst_pad_set_link_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_link)); gst_pad_set_getcaps_function (queue->srcpad, gst_pad_set_event_function (queue->srcpad, @@ -395,7 +374,7 @@ queue = GST_QUEUE (gst_pad_get_parent (pad)); - if (pad == queue->srcpad && queue->cur_level.bytes > 0) { + if (queue->cur_level.bytes > 0) { return gst_caps_copy (queue->negotiated_caps); } @@ -403,45 +382,7 @@ } static GstPadLinkReturn -gst_queue_link_sink (GstPad * pad, const GstCaps * caps) -{ - GstQueue *queue; - GstPadLinkReturn link_ret; - queue = GST_QUEUE (gst_pad_get_parent (pad)); - if (queue->cur_level.bytes > 0) { - if (gst_caps_is_equal (caps, queue->negotiated_caps)) { - GST_QUEUE_MUTEX_UNLOCK; - return GST_PAD_LINK_OK; - } - /* Wait until the queue is empty before attempting the pad - negotiation. */ - GST_QUEUE_MUTEX_LOCK; - STATUS (queue, "waiting for queue to get empty"); - while (queue->cur_level.bytes > 0) { - g_cond_wait (queue->item_del, queue->qlock); - STATUS (queue, "queue is now empty"); - GST_QUEUE_MUTEX_UNLOCK; - } - link_ret = gst_pad_proxy_pad_link (pad, caps); - if (GST_PAD_LINK_SUCCESSFUL (link_ret)) { - /* we store an extra copy of the negotiated caps, just in case - * the pads become unnegotiated while we have buffers */ - gst_caps_replace (&queue->negotiated_caps, gst_caps_copy (caps)); - return link_ret; -} -gst_queue_link_src (GstPad * pad, const GstCaps * caps) +gst_queue_link (GstPad * pad, const GstCaps * caps) { GstQueue *queue; GstPadLinkReturn link_ret; @@ -524,6 +465,23 @@ g_mutex_unlock (queue->event_lock); +#define STATUS(queue, msg) \ + GST_CAT_LOG_OBJECT (queue_dataflow, queue, \ + "(%s:%s) " msg ": %u of %u-%u buffers, %u of %u-%u " \ + "bytes, %" G_GUINT64_FORMAT " of %" G_GUINT64_FORMAT \ + "-%" G_GUINT64_FORMAT " ns, %u elements", \ + GST_DEBUG_PAD_NAME (pad), \ + queue->cur_level.buffers, \ + queue->min_threshold.buffers, \ + queue->max_size.buffers, \ + queue->cur_level.bytes, \ + queue->min_threshold.bytes, \ + queue->max_size.bytes, \ + queue->cur_level.time, \ + queue->min_threshold.time, \ + queue->max_size.time, \ + queue->queue->length) static void gst_queue_chain (GstPad * pad, GstData * data) @@ -953,10 +911,10 @@ GstQueryType type, GstFormat * fmt, gint64 * value) GstQueue *queue = GST_QUEUE (gst_pad_get_parent (pad)); + gboolean res; - if (!GST_PAD_PEER (queue->sinkpad)) - return FALSE; - if (!gst_pad_query (GST_PAD_PEER (queue->sinkpad), type, fmt, value)) + res = gst_pad_query (GST_PAD_PEER (queue->sinkpad), type, fmt, value); + if (!res) return FALSE; if (type == GST_QUERY_POSITION) { |
From: <wt...@fr...> - 2004-12-09 21:07:35
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Thu Dec 09 2004 13:08:25 PST Branch: BRANCH-THREADED Log message: * gst/gst_private.h: * gst/gstbin.c: (gst_bin_class_init), (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_get_clock), (gst_bin_iterate_elements), (gst_bin_get_by_name), (gst_bin_get_by_name_recurse_up), (gst_bin_get_by_interface), (gst_bin_get_all_by_interface): * gst/gstbin.h: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (gst_element_request_pad), (gst_element_post_message), (gst_element_error_full), (gst_element_is_locked_state), (gst_element_set_locked_state), (gst_element_create_task): * gst/gstelement.h: * gst/gstinfo.h: * gst/gstiterator.h: * gst/gstobject.c: (gst_object_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_dispose), (gst_object_finalize), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_get_name), (gst_object_set_parent), (gst_object_get_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_save_thyself), (gst_object_restore_thyself), (gst_object_real_restore_thyself), (gst_object_set_property), (gst_object_get_property), (gst_object_get_path_string): * gst/gstobject.h: * gst/gstpad.c: (gst_pad_get_direction), (gst_pad_unlink), (gst_pad_is_linked), (gst_pad_link_filtered), (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range): * gst/gstpad.h: More MT safety fixes following the desing doc. Modified files: . : ChangeLog gst : gst_private.h gstbin.c gstbin.h gstelement.c gstelement.h gstinfo.h gstiterator.h gstobject.c gstobject.h gstpad.c gstpad.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.858.2.2&r2=1.858.2.3 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gst_private.h.diff?r1=1.17.2.1&r2=1.17.2.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstbin.c.diff?r1=1.206.2.1&r2=1.206.2.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstbin.h.diff?r1=1.65.2.1&r2=1.65.2.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstelement.c.diff?r1=1.305.2.1&r2=1.305.2.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstelement.h.diff?r1=1.177.2.1&r2=1.177.2.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstinfo.h.diff?r1=1.81&r2=1.81.2.1 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstiterator.h.diff?r1=1.1.2.1&r2=1.1.2.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstobject.c.diff?r1=1.79.2.1&r2=1.79.2.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstobject.h.diff?r1=1.47.2.1&r2=1.47.2.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstpad.c.diff?r1=1.350.2.1&r2=1.350.2.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstpad.h.diff?r1=1.152.2.1&r2=1.152.2.2 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.858.2.2 retrieving revision 1.858.2.3 diff -u -d -r1.858.2.2 -r1.858.2.3 --- ChangeLog 9 Dec 2004 17:25:00 -0000 1.858.2.2 +++ ChangeLog 9 Dec 2004 21:08:12 -0000 1.858.2.3 @@ -1,5 +1,39 @@ 2004-12-09 Wim Taymans <wi...@fl...> + * gst/gst_private.h: + * gst/gstbin.c: (gst_bin_class_init), (gst_bin_set_index), + (gst_bin_set_clock), (gst_bin_get_clock), + (gst_bin_iterate_elements), (gst_bin_get_by_name), + (gst_bin_get_by_name_recurse_up), (gst_bin_get_by_interface), + (gst_bin_get_all_by_interface): + * gst/gstbin.h: + * gst/gstelement.c: (gst_element_add_pad), + (gst_element_remove_pad), (gst_element_request_pad), + (gst_element_post_message), (gst_element_error_full), + (gst_element_is_locked_state), (gst_element_set_locked_state), + (gst_element_create_task): + * gst/gstelement.h: + * gst/gstinfo.h: + * gst/gstiterator.h: + * gst/gstobject.c: (gst_object_init), (gst_object_ref), + (gst_object_unref), (gst_object_sink), (gst_object_dispose), + (gst_object_finalize), (gst_object_dispatch_properties_changed), + (gst_object_set_name), (gst_object_get_name), + (gst_object_set_parent), (gst_object_get_parent), + (gst_object_unparent), (gst_object_check_uniqueness), + (gst_object_save_thyself), (gst_object_restore_thyself), + (gst_object_real_restore_thyself), (gst_object_set_property), + (gst_object_get_property), (gst_object_get_path_string): + * gst/gstobject.h: + * gst/gstpad.c: (gst_pad_get_direction), (gst_pad_unlink), + (gst_pad_is_linked), (gst_pad_link_filtered), + (gst_pad_relink_filtered), (gst_pad_get_peer), (gst_pad_push), + (gst_pad_pull), (gst_pad_pull_range): + * gst/gstpad.h: + More MT safety fixes following the desing doc. + +2004-12-09 Wim Taymans <wi...@fl...> * docs/design/part-MT-refcounting.txt: * docs/design/part-conventions.txt: Added design doc for MT-safe API implementation Index: gst_private.h RCS file: /cvs/gstreamer/gstreamer/gst/gst_private.h,v retrieving revision 1.17.2.1 retrieving revision 1.17.2.2 diff -u -d -r1.17.2.1 -r1.17.2.2 --- gst_private.h 8 Dec 2004 17:40:36 -0000 1.17.2.1 +++ gst_private.h 9 Dec 2004 21:08:13 -0000 1.17.2.2 @@ -37,6 +37,12 @@ #include <stdlib.h> #include <string.h> +#define GST_UNLOCK_RETURN(obj,val) \ +G_STMT_START { \ + GST_UNLOCK(obj); \ + return val; \ +} G_STMT_END gboolean __gst_in_valgrind (void); /*** debugging categories *****************************************************/ Index: gstbin.c RCS file: /cvs/gstreamer/gstreamer/gst/gstbin.c,v retrieving revision 1.206.2.1 retrieving revision 1.206.2.2 diff -u -d -r1.206.2.1 -r1.206.2.2 --- gstbin.c 8 Dec 2004 17:40:36 -0000 1.206.2.1 +++ gstbin.c 9 Dec 2004 21:08:13 -0000 1.206.2.2 @@ -64,7 +64,6 @@ static void gst_bin_add_func (GstBin * bin, GstElement * element); static void gst_bin_remove_func (GstBin * bin, GstElement * element); -static GstIterator *gst_bin_iterate_elements_func (GstBin * bin); #ifndef GST_DISABLE_LOADSAVE static xmlNodePtr gst_bin_save_thyself (GstObject * object, xmlNodePtr parent); @@ -171,7 +170,6 @@ klass->add_element = GST_DEBUG_FUNCPTR (gst_bin_add_func); klass->remove_element = GST_DEBUG_FUNCPTR (gst_bin_remove_func); - klass->iterate_elements = GST_DEBUG_FUNCPTR (gst_bin_iterate_elements_func); } static void @@ -198,67 +196,59 @@ #ifndef GST_DISABLE_INDEX -bin_set_index_func (GstElement * element, GstIndex * index) -{ - gst_element_set_index (element, index); - gst_object_unref (GST_OBJECT (element)); -} - -static void gst_bin_set_index (GstElement * element, GstIndex * index) { - GstIterator *it = gst_bin_iterate_elements (GST_BIN (element)); + GstBin *bin; + GList *children; - gst_iterator_foreach (it, (GFunc) bin_set_index_func, index); - gst_iterator_free (it); -#endif + bin = GST_BIN (element); -bin_set_clock_func (GstElement * element, GstClock * clock) - gst_element_set_clock (element, clock); + GST_LOCK (bin); + for (children = bin->children; children; children = g_list_next (children)) { + GstElement *child = GST_ELEMENT (children->data); + gst_element_set_index (child, index); + } + GST_UNLOCK (bin); +#endif gst_bin_set_clock (GstElement * element, GstClock * clock) - gst_iterator_foreach (it, (GFunc) bin_set_clock_func, clock); -static gint -bin_get_clock_func (GstElement * element, GstClock ** clock) - GstClock *result; - result = gst_element_get_clock (element); - if (result) { - *clock = result; - return 0; /* found */ + gst_element_set_clock (child, clock); } - return 1; static GstClock * gst_bin_get_clock (GstElement * element) - GstIterator *children; - GstElement *found; GstClock *result = NULL; - children = gst_bin_iterate_elements (GST_BIN (element)); - found = (GstElement *) gst_iterator_find_custom (children, &result, - (GCompareFunc) bin_get_clock_func); - gst_iterator_free (children); - if (found) { - gst_object_unref (GST_OBJECT (found)); + result = gst_element_get_clock (child); + if (result) + break; return result; @@ -437,26 +427,6 @@ g_free (it); -static GstIterator * -gst_bin_iterate_elements_func (GstBin * bin) - GstBinIterator *result; - GST_LOCK (bin); - result = (GstBinIterator *) gst_iterator_new (sizeof (GstBinIterator), - GST_GET_LOCK (bin), - &bin->children_cookie, - (GstIteratorNextFunction) gst_bin_iterator_next, - (GstIteratorResyncFunction) gst_bin_iterator_resync, - (GstIteratorFreeFunction) gst_bin_iterator_free); - result->bin = GST_BIN (gst_object_ref (GST_OBJECT (bin))); - result->list = bin->children; - GST_UNLOCK (bin); - return GST_ITERATOR (result); /** * gst_bin_iterate_elements: * @bin: #Gstbin to iterate the elements of @@ -471,20 +441,21 @@ GstIterator * gst_bin_iterate_elements (GstBin * bin) - GstBinClass *bclass; - GstIterator *result; + GstBinIterator *result; - g_return_val_if_fail (GST_IS_BIN (bin), NULL); + result = (GstBinIterator *) gst_iterator_new (sizeof (GstBinIterator), + GST_GET_LOCK (bin), + &bin->children_cookie, + (GstIteratorNextFunction) gst_bin_iterator_next, + (GstIteratorResyncFunction) gst_bin_iterator_resync, + (GstIteratorFreeFunction) gst_bin_iterator_free); - bclass = GST_BIN_GET_CLASS (bin); + result->bin = GST_BIN (gst_object_ref (GST_OBJECT (bin))); + result->list = bin->children; - if (bclass->iterate_elements) { - result = bclass->iterate_elements (bin); - } else { - g_warning ("cannot iterate elements of bin %s", GST_ELEMENT_NAME (bin)); - result = NULL; - } - return result; + return GST_ITERATOR (result); /* returns 0 if the element is a sink, this is made so that @@ -811,8 +782,6 @@ GST_CAT_INFO (GST_CAT_PARENTAGE, "[%s]: looking up child element %s", GST_ELEMENT_NAME (bin), name); - /* FIXME, does not use the virtual method to get - * the children */ GST_LOCK (bin); children = bin->children; while (children) { @@ -863,6 +832,7 @@ if (parent && GST_IS_BIN (parent)) { result = gst_bin_get_by_name_recurse_up (GST_BIN (parent), name); } + gst_object_unref (parent); @@ -890,8 +860,6 @@ g_return_val_if_fail (GST_IS_BIN (bin), NULL); g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface), NULL); walk = bin->children; while (walk) { @@ -932,8 +900,7 @@ - /* FIXME, not MT safe and does not use the virtual method to get if (G_TYPE_CHECK_INSTANCE_TYPE (walk->data, interface)) { @@ -947,6 +914,7 @@ walk = g_list_next (walk); return ret; Index: gstbin.h RCS file: /cvs/gstreamer/gstreamer/gst/gstbin.h,v retrieving revision 1.65.2.1 retrieving revision 1.65.2.2 diff -u -d -r1.65.2.1 -r1.65.2.2 --- gstbin.h 8 Dec 2004 17:40:36 -0000 1.65.2.1 +++ gstbin.h 9 Dec 2004 21:08:13 -0000 1.65.2.2 @@ -48,9 +48,14 @@ /*typedef struct _GstBin GstBin; */ /*typedef struct _GstBinClass GstBinClass; */ +#define GST_BIN_NUMCHILDREN(bin) (GST_BIN_CAST(bin)->numchildren); +#define GST_BIN_CHILDREN(bin) (GST_BIN_CAST(bin)->children); +#define GST_BIN_CHILDREN_COOKIE(bin) (GST_BIN_CAST(bin)->children_cookie); struct _GstBin { GstElement element; + /*< public >*/ /* with LOCK */ /* our children */ gint numchildren; GList *children; @@ -65,7 +70,6 @@ /* vtable */ void (*add_element) (GstBin *bin, GstElement *element); void (*remove_element) (GstBin *bin, GstElement *element); - GstIterator* (*iterate_elements) (GstBin *bin); /* signals */ void (*element_added) (GstBin *bin, GstElement *child); Index: gstelement.c RCS file: /cvs/gstreamer/gstreamer/gst/gstelement.c,v retrieving revision 1.305.2.1 retrieving revision 1.305.2.2 diff -u -d -r1.305.2.1 -r1.305.2.2 --- gstelement.c 8 Dec 2004 17:40:36 -0000 1.305.2.1 +++ gstelement.c 9 Dec 2004 21:08:13 -0000 1.305.2.2 @@ -197,6 +197,8 @@ * The user data passed to the g_signal_connect is ignored. * * The default handler will simply print the error string using g_print. + * + * MT safe. */ void gst_element_default_error (GObject * object, GstObject * source, GError * error, @@ -211,21 +213,6 @@ g_free (name); -static GstPad * -gst_element_request_pad (GstElement * element, GstPadTemplate * templ, - const gchar * name) - GstPad *newpad = NULL; - GstElementClass *oclass; - oclass = GST_ELEMENT_GET_CLASS (element); - if (oclass->request_new_pad) - newpad = (oclass->request_new_pad) (element, templ, name); - return newpad; * gst_element_release_request_pad: * @element: a #GstElement to release the request pad of. @@ -233,6 +220,8 @@ * Makes the element free the previously requested pad as obtained * with gst_element_get_request_pad(). gst_element_release_request_pad (GstElement * element, GstPad * pad) @@ -255,6 +244,8 @@ * Query if the element requiresd a clock * Returns: TRUE if the element requires a clock gboolean gst_element_requires_clock (GstElement * element) @@ -272,9 +263,11 @@ * gst_element_provides_clock: * @element: a #GstElement to query - * Query if the element provides a clock + * Query if the element provides a clock. * Returns: TRUE if the element provides a clock gst_element_provides_clock (GstElement * element) @@ -293,7 +286,11 @@ * @element: a #GstElement to set the clock for. * @clock: the #GstClock to set for the element. - * Sets the clock for the element. + * Sets the clock for the element. This function increases the + * refcount on the clock. Any previously set clock on the object + * is unreffed. gst_element_set_clock (GstElement * element, GstClock * clock) @@ -316,9 +313,13 @@ * gst_element_get_clock: * @element: a #GstElement to get the clock of. - * Gets the clock of the element. + * Gets the clock of the element. If the element provides a clock, + * this function will return this clock. For elements that do not + * provide a clock, this function returns NULL. - * Returns: the #GstClock of the element. + * Returns: the #GstClock of the element. unref after usage. GstClock * gst_element_get_clock (GstElement * element) @@ -343,6 +344,8 @@ * Queries if the element can be indexed. * Returns: TRUE if the element can be indexed. gst_element_is_indexable (GstElement * element) @@ -361,7 +364,9 @@ * @element: a #GstElement. * @index: a #GstIndex. - * Set the specified GstIndex on the element. + * Set the specified GstIndex on the element. gst_element_set_index (GstElement * element, GstIndex * index) @@ -384,7 +389,9 @@ * Gets the index from the element. * Returns: a #GstIndex or NULL when no index was set on the - * element. + * element. unref after usage. GstIndex * gst_element_get_index (GstElement * element) @@ -408,37 +415,45 @@ * @pad: the #GstPad to add to the element. * Adds a pad (link point) to @element. @pad's parent will be set to @element; - * see gst_object_set_parent() for refcounting information. + * see gst_object_set_parent() for refcounting information. * Pads are automatically activated when the element is in state PLAYING. + * The pad and the element should be unlocked when calling this function. * Returns: TRUE if the pad could be added. This function can fail when * passing bad arguments or when a pad with the same name already existed. gst_element_add_pad (GstElement * element, GstPad * pad) + GstElement *old_parent; g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); g_return_val_if_fail (GST_IS_PAD (pad), FALSE); /* first check to make sure the pad hasn't already been added to another * element */ - g_return_val_if_fail (GST_PAD_PARENT (pad) == NULL, FALSE); + old_parent = gst_pad_get_parent (pad); + if (G_UNLIKELY (old_parent != NULL)) + goto had_parent; GST_LOCK (element); + GST_LOCK (pad); /* then check to see if there's already a pad by that name here */ - if (!gst_object_check_uniqueness (element->pads, GST_PAD_NAME (pad))) { - g_warning ("Padname %s:%s is not unique in element %s, not adding\n", - GST_DEBUG_PAD_NAME (pad), GST_ELEMENT_NAME (element)); - GST_UNLOCK (element); - return FALSE; + if (G_UNLIKELY (!gst_object_check_uniqueness (element->pads, + GST_PAD_NAME (pad)))) + goto name_exists; GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "adding pad '%s'", - GST_STR_NULL (GST_OBJECT_NAME (pad))); + GST_STR_NULL (GST_PAD_NAME (pad))); + GST_UNLOCK (pad); /* set the pad's parent */ - gst_object_set_parent (GST_OBJECT (pad), GST_OBJECT (element)); + gst_object_set_parent (GST_OBJECT_CAST (pad), GST_OBJECT_CAST (element)); /* add it to the list */ switch (gst_pad_get_direction (pad)) { @@ -469,6 +484,30 @@ g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad); return TRUE; +had_parent: + { + gchar *parent_name = gst_element_get_name (old_parent); + gst_object_unref (GST_OBJECT (old_parent)); + GST_LOCK (pad); + GST_LOCK (element); + g_critical + ("Padname %s:%s already has parent when trying to add to element %s", + parent_name, GST_PAD_NAME (pad), GST_ELEMENT_NAME (element)); + GST_UNLOCK (element); + GST_UNLOCK (pad); + g_free (parent_name); + return FALSE; +name_exists: + g_critical ("Padname %s is not unique in element %s, not adding\n", + GST_PAD_NAME (pad), GST_ELEMENT_NAME (element)); + GST_UNLOCK (element); + return FALSE; @@ -482,6 +521,8 @@ * gst_element_add_pad(). * Returns: the added ghost #GstPad, or NULL on error. GstPad * gst_element_add_ghost_pad (GstElement * element, GstPad * pad, @@ -509,21 +550,31 @@ * Removes @pad from @element. @pad will be destroyed if it has not been * referenced elsewhere. gst_element_remove_pad (GstElement * element, GstPad * pad) - g_return_if_fail (element != NULL); + GstElement *current_parent; g_return_if_fail (GST_IS_ELEMENT (element)); - g_return_if_fail (pad != NULL); g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (GST_PAD_PARENT (pad) == element); + current_parent = gst_pad_get_parent (pad); + if (G_UNLIKELY (current_parent != element)) + goto not_our_pad; if (GST_IS_REAL_PAD (pad)) { + GstPad *peer = gst_pad_get_peer (pad); /* unlink */ - if (GST_RPAD_PEER (pad) != NULL) { - gst_pad_unlink (pad, GST_PAD (GST_RPAD_PEER (pad))); + if (peer != NULL) { + /* window for MT unsafeness, someone else could unlink here + * and then we call unlink with wrong pads. The unlink + * function would catch this and safely return failed. */ + gst_pad_unlink (pad, GST_PAD_CAST (peer)); + gst_object_unref (GST_OBJECT (peer)); } else if (GST_IS_GHOST_PAD (pad)) { g_object_set (pad, "real-pad", NULL, NULL); @@ -552,6 +603,23 @@ g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad); gst_object_unparent (GST_OBJECT (pad)); + return; +not_our_pad: + gchar *parent_name = gst_element_get_name (current_parent); + gst_object_unref (GST_OBJECT (current_parent)); + g_critical ("Padname %s:%s does not belong to element %s when removing", + return; @@ -563,6 +631,8 @@ * pads have been added by the element itself. Elements with GST_PAD_SOMETIMES * pad templates use this in combination with autopluggers to figure out that * the element is done initializing its pads. gst_element_no_more_pads (GstElement * element) @@ -641,6 +711,21 @@ +static GstPad * +gst_element_request_pad (GstElement * element, GstPadTemplate * templ, + const gchar * name) +{ + GstPad *newpad = NULL; + GstElementClass *oclass; + oclass = GST_ELEMENT_GET_CLASS (element); + if (oclass->request_new_pad) + newpad = (oclass->request_new_pad) (element, templ, name); + return newpad; +} * gst_element_get_request_pad: * @element: a #GstElement to find a request pad of. @@ -1116,6 +1201,7 @@ return FALSE; +/* MT safe */ gst_element_post_message (GstElement * element, GstMessage * message) @@ -1125,14 +1211,18 @@ g_return_val_if_fail (GST_IS_ELEMENT (element), result); g_return_val_if_fail (message != NULL, result); + GST_LOCK (element); manager = element->manager; if (manager == NULL) { gst_data_unref (GST_DATA (message)); return result; + gst_object_ref (GST_OBJECT (manager)); result = gst_pipeline_post_message (manager, message); + gst_object_unref (GST_OBJECT (manager)); @@ -1187,10 +1277,13 @@ gchar *name; gchar *sent_message; gchar *sent_debug; + gchar *elem_name; /* checks */ + elem_name = gst_element_get_name (element); /* check if we send the given message or the default error message */ if ((message == NULL) || (message[0] == 0)) { /* we got this message from g_strdup_printf (""); */ @@ -1207,11 +1300,10 @@ /* create error message */ GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "signaling error in %s: %s", - GST_ELEMENT_NAME (element), sent_message); + elem_name, sent_message); error = g_error_new_literal (domain, code, sent_message); /* emit the signal, make sure the element stays available */ - gst_object_ref (GST_OBJECT (element)); name = gst_object_get_path_string (GST_OBJECT (element)); if (debug) sent_debug = g_strdup_printf ("%s(%d): %s: %s:\n%s", @@ -1225,11 +1317,11 @@ gst_message_new_error (GST_OBJECT (element), error, sent_debug)); GST_CAT_INFO (GST_CAT_ERROR_SYSTEM, "signalled error in %s: %s", /* cleanup */ g_free (sent_message); + g_free (elem_name); @@ -1243,16 +1335,19 @@ * state before changing the state from #GST_STATE_NULL. * Returns: TRUE, if the element's state is locked. gst_element_is_locked_state (GstElement * element) gboolean result = FALSE; - g_return_val_if_fail (GST_IS_ELEMENT (element), result); + g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); - result = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE) ? TRUE : FALSE; + /* be careful with the flag tests */ + result = !!GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE); GST_UNLOCK (element); @@ -1265,19 +1360,22 @@ * Locks the state of an element, so state changes of the parent don't affect * this element anymore. + * Returns: TRUE if the state was changed, FALSE if bad params were given or + * the element was already in the correct state. -void +gboolean gst_element_set_locked_state (GstElement * element, gboolean locked_state) gboolean old; - g_return_if_fail (GST_IS_ELEMENT (element)); - old = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE); + old = !!GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE); - if (old == locked_state) - goto exit; + if (G_UNLIKELY (old == locked_state)) + goto was_ok; if (locked_state) { GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s", @@ -1288,9 +1386,12 @@ GST_ELEMENT_NAME (element)); GST_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE); + return TRUE; -exit: +was_ok: @@ -1869,6 +1970,8 @@ * Returns the manager of the element. * Returns: the element's #GstPipeline. GstPipeline * gst_element_get_manager (GstElement * element) @@ -1884,6 +1987,18 @@ +/** + * gst_element_create_task: + * @element: a #GstElement to get the manager of. + * @func: the taskfunction to run + * @data: user data passed to the taskfunction. + * Creates a new GstTask. + * Returns: the newly created #GstTask. + */ GstTask * gst_element_create_task (GstElement * element, GstTaskFunction func, gpointer data) @@ -1893,10 +2008,12 @@ pipeline = GST_ELEMENT_MANAGER (element); + gst_object_ref (GST_OBJECT (pipeline)); if (pipeline) { result = gst_scheduler_create_task (pipeline->scheduler, func, data); + gst_object_unref (GST_OBJECT (pipeline)); - GST_UNLOCK (element); Index: gstelement.h RCS file: /cvs/gstreamer/gstreamer/gst/gstelement.h,v retrieving revision 1.177.2.1 retrieving revision 1.177.2.2 diff -u -d -r1.177.2.1 -r1.177.2.2 --- gstelement.h 8 Dec 2004 17:40:36 -0000 1.177.2.1 +++ gstelement.h 9 Dec 2004 21:08:13 -0000 1.177.2.2 @@ -1,6 +1,7 @@ /* GStreamer * Copyright (C) 1999,2000 Erik Walthinsen <om...@cs...> * 2000 Wim Taymans <wt...@ch...> + * 2004 Wim Taymans <wi...@fl...> * gstelement.h: Header for GstElement @@ -42,14 +43,16 @@ /* FIXME: need translatable stuff in here (how handle in registry)? */ struct _GstElementDetails { + /*< public >*/ gchar *longname; /* long, english name */ gchar *klass; /* type of element, as hierarchy */ gchar *description; /* insights of one form or another */ gchar *author; /* who wrote this thing? */ + /*< private >*/ gpointer _gst_reserved[GST_PADDING]; }; -#define GST_ELEMENT_DETAILS(longname,klass,description,author) \ +#define GST_ELEMENT_DETAILS(longname,klass,description,author) \ { longname, klass, description, author, GST_PADDING_INIT } #define GST_IS_ELEMENT_DETAILS(details) ( \ (details) && ((details)->longname != NULL) && ((details)->klass != NULL) \ @@ -80,6 +83,7 @@ #define GST_ELEMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_ELEMENT, GstElementClass)) #define GST_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_ELEMENT, GstElement)) #define GST_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_ELEMENT, GstElementClass)) +#define GST_ELEMENT_CAST(obj) ((GstElement*)(obj)) /* convenience functions */ #ifdef G_HAVE_ISO_VARARGS @@ -112,9 +116,9 @@ #define GST_ELEMENT_NAME(obj) (GST_OBJECT_NAME(obj)) #define GST_ELEMENT_PARENT(obj) (GST_OBJECT_PARENT(obj)) -#define GST_ELEMENT_MANAGER(obj) (((GstElement*)(obj))->manager) -#define GST_ELEMENT_CLOCK(obj) (((GstElement*)(obj))->clock) -#define GST_ELEMENT_PADS(obj) ((obj)->pads) +#define GST_ELEMENT_MANAGER(obj) (GST_ELEMENT_CAST(obj)->manager) +#define GST_ELEMENT_CLOCK(obj) (GST_ELEMENT_CAST(obj)->clock) +#define GST_ELEMENT_PADS(obj) (GST_ELEMENT_CAST(obj)->pads) #define GST_ELEMENT_ERROR(el, domain, code, message, debug) G_STMT_START { \ gchar *__msg = _gst_element_error_printf message; \ @@ -129,11 +133,11 @@ } G_STMT_END /* the state change mutexes and conds */ -#define GST_STATE_GET_LOCK(elem) (((GstElement *)(elem))->state_lock) +#define GST_STATE_GET_LOCK(elem) (GST_ELEMENT_CAST(elem)->state_lock) #define GST_STATE_LOCK(elem) g_mutex_lock(GST_STATE_GET_LOCK(elem)) #define GST_STATE_TRYLOCK(elem) g_mutex_trylock(GST_STATE_GET_LOCK(elem)) #define GST_STATE_UNLOCK(elem) g_mutex_unlock(GST_STATE_GET_LOCK(elem)) -#define GST_STATE_GET_COND(elem) (((GstElement *)(elem))->state_cond) +#define GST_STATE_GET_COND(elem) (GST_ELEMENT_CAST(elem)->state_cond) #define GST_STATE_WAIT(elem) g_cond_wait (GST_STATE_GET_COND (elem), GST_STATE_GET_LOCK (elem)) #define GST_STATE_TIMED_WAIT(elem, timeval) g_cond_timed_wait (GST_STATE_GET_COND (elem), GST_STATE_GET_LOCK (elem),\ timeval) @@ -144,12 +148,14 @@ struct _GstElement { GstObject object; + /*< public >*/ /* with STATE_LOCK */ /* element state */ GMutex *state_lock; GCond *state_cond; guint8 current_state; guint8 pending_state; /* element manager */ GstPipeline *manager; /* private pointer for the scheduler */ @@ -160,7 +166,7 @@ GstClockTimeDiff base_time; /* NULL/READY: 0 - PAUSED: current time - PLAYING: difference to clock */ /* element pads, these lists can only be iterated while holding - * the element lock or checking the cookie after each lock. */ + * the LOCK or checking the cookie after each LOCK. */ guint16 numpads; GList *pads; guint16 numsrcpads; @@ -169,6 +175,7 @@ GList *sinkpads; guint32 pads_cookie; @@ -241,9 +248,9 @@ GType gst_element_get_type (void); -#define gst_element_get_name(elem) gst_object_get_name(GST_OBJECT(elem)) -#define gst_element_set_name(elem,name) gst_object_set_name(GST_OBJECT(elem),name) -#define gst_element_get_parent(elem) gst_object_get_parent(GST_OBJECT(elem)) +#define gst_element_get_name(elem) gst_object_get_name(GST_OBJECT(elem)) +#define gst_element_set_name(elem,name) gst_object_set_name(GST_OBJECT(elem),name) +#define gst_element_get_parent(elem) gst_object_get_parent(GST_OBJECT(elem)) #define gst_element_set_parent(elem,parent) gst_object_set_parent(GST_OBJECT(elem),parent) /* clocking */ @@ -310,7 +317,7 @@ /* state management */ gboolean gst_element_is_locked_state (GstElement *element); -void gst_element_set_locked_state (GstElement *element, gboolean locked_state); +gboolean gst_element_set_locked_state (GstElement *element, gboolean locked_state); gboolean gst_element_sync_state_with_parent (GstElement *element); gboolean gst_element_get_state (GstElement *element, GstElementState *state, Index: gstinfo.h RCS file: /cvs/gstreamer/gstreamer/gst/gstinfo.h,v retrieving revision 1.81 retrieving revision 1.81.2.1 diff -u -d -r1.81 -r1.81.2.1 --- gstinfo.h 3 Nov 2004 09:21:01 -0000 1.81 +++ gstinfo.h 9 Dec 2004 21:08:13 -0000 1.81.2.1 @@ -109,6 +109,7 @@ #define GST_STR_NULL(str) ((str) ? (str) : "(NULL)") /* easier debugging for pad names */ +/* FIXME, not MT safe */ #define GST_DEBUG_PAD_NAME(pad) \ (GST_OBJECT_PARENT(pad) != NULL) ? \ GST_STR_NULL (GST_OBJECT_NAME (GST_OBJECT_PARENT(pad))) : \ Index: gstiterator.h RCS file: /cvs/gstreamer/gstreamer/gst/Attic/gstiterator.h,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -d -r1.1.2.1 -r1.1.2.2 --- gstiterator.h 8 Dec 2004 18:05:14 -0000 1.1.2.1 +++ gstiterator.h 9 Dec 2004 21:08:13 -0000 1.1.2.2 @@ -62,6 +62,10 @@ GstIteratorResyncFunction resync, GstIteratorFreeFunction free); +GstIterator* gst_iterator_new_list (GMutex *lock, + guint32 *master_cookie, + GList *list); GstIteratorResult gst_iterator_next (GstIterator *it, gpointer *result); void gst_iterator_resync (GstIterator *it); void gst_iterator_free (GstIterator *it); Index: gstobject.c RCS file: /cvs/gstreamer/gstreamer/gst/gstobject.c,v retrieving revision 1.79.2.1 retrieving revision 1.79.2.2 diff -u -d -r1.79.2.1 -r1.79.2.2 --- gstobject.c 8 Dec 2004 17:40:36 -0000 1.79.2.1 +++ gstobject.c 9 Dec 2004 21:08:13 -0000 1.79.2.2 @@ -179,15 +179,13 @@ gst_object_init (GstObject * object) - //object->lock = g_new0(GStaticRecMutex, 1); - //g_static_rec_mutex_init (object->lock); object->lock = g_mutex_new (); object->parent = NULL; object->name = NULL; object->flags = 0; - GST_FLAG_SET (object, GST_FLOATING); + GST_FLAG_SET (object, GST_OBJECT_FLOATING); #ifndef GST_DISABLE_TRACE @@ -216,7 +214,13 @@ * gst_object_ref: * @object: GstObject to reference - * Increments the refence count on the object. + * Increments the refence count on the object. This function + * does not take the lock on the object because it relies on + * atomic refcounting. + * This object returns the input parameter to ease writing + * constructs like : + * result = gst_object_ref (object->parent); * Returns: A pointer to the object @@ -228,7 +232,7 @@ GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "ref %d->%d", G_OBJECT (object)->ref_count, G_OBJECT (object)->ref_count + 1); - /* FIXME, not threadsafe */ + /* FIXME, not MT safe because glib is not MT safe */ g_object_ref (G_OBJECT (object)); return object; @@ -238,7 +242,8 @@ * @object: GstObject to unreference * Decrements the refence count on the object. If reference count hits - * zero, destroy the object. + * zero, destroy the object. This function does not take the lock + * on the object as it relies on atomic refcounting. gst_object_unref (GstObject * object) @@ -249,7 +254,7 @@ GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "unref %d->%d", G_OBJECT (object)->ref_count, G_OBJECT (object)->ref_count - 1); g_object_unref (G_OBJECT (object)); @@ -261,19 +266,24 @@ * a refcount of 1 and is FLOATING. This function should be used when * creating a new object to symbolically 'take ownership' of the object. * Use #gst_object_set_parent to have this done for you. + * This function takes the object lock. gst_object_sink (GstObject * object) - g_return_if_fail (object != NULL); g_return_if_fail (GST_IS_OBJECT (object)); GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "sink"); - if (GST_OBJECT_FLOATING (object)) { - GST_FLAG_UNSET (object, GST_FLOATING); + GST_LOCK (object); + if (GST_OBJECT_IS_FLOATING (object)) { + GST_FLAG_UNSET (object, GST_OBJECT_FLOATING); gst_object_unref (object); + GST_UNLOCK (object); @@ -282,7 +292,10 @@ * @newobj: new GstObject * Unrefs the object pointer to by oldobj, refs the newobj and - * puts the newobj in *oldobj. + * puts the newobj in *oldobj. Be carefull when calling this + * function, it does not take any locks. You might want to lock + * the object owning the oldobj pointer before calling this + * function. gst_object_replace (GstObject ** oldobj, GstObject * newobj) @@ -312,7 +325,7 @@ GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose"); - GST_FLAG_SET (GST_OBJECT (object), GST_DESTROYED); + GST_FLAG_SET (GST_OBJECT (object), GST_OBJECT_DESTROYED); GST_OBJECT_PARENT (object) = NULL; parent_class->dispose (object); @@ -329,10 +342,7 @@ g_signal_handlers_destroy (object); g_free (gstobject->name); - //g_static_rec_mutex_free (gstobject->lock); g_mutex_free (gstobject->lock); - g_free (gstobject->lock); { @@ -349,6 +359,7 @@ parent_class->finalize (object); +/* FIXME a class wide mutex is enough */ static GStaticRecMutex dispatch_mutex = G_STATIC_REC_MUTEX_INIT; /* Changing a GObject property of a GstObject will result in "deep_notify" @@ -360,30 +371,43 @@ gst_object_dispatch_properties_changed (GObject * object, guint n_pspecs, GParamSpec ** pspecs) - GstObject *gst_object; + GstObject *gst_object, *parent, *old_parent; guint i; + const gchar *name; g_static_rec_mutex_lock (&dispatch_mutex); /* do the standard dispatching */ G_OBJECT_CLASS (parent_class)->dispatch_properties_changed (object, n_pspecs, pspecs); + /* we fail when this is not a GstObject */ + g_return_if_fail (GST_IS_OBJECT (object)); + gst_object = GST_OBJECT_CAST (object); + name = gst_object_get_name (gst_object); /* now let the parent dispatch those, too */ - gst_object = GST_OBJECT_PARENT (object); - while (gst_object) { + parent = gst_object_get_parent (gst_object); + while (parent) { + /* for debugging ... */ + gchar *parent_name = gst_object_get_name (parent); /* need own category? */ for (i = 0; i < n_pspecs; i++) { GST_CAT_LOG (GST_CAT_EVENT, "deep notification from %s to %s (%s)", - GST_OBJECT_NAME (object) ? GST_OBJECT_NAME (object) : "(null)", - GST_OBJECT_NAME (gst_object) ? GST_OBJECT_NAME (gst_object) : - "(null)", pspecs[i]->name); - /* FIXME, not thread safe */ - g_signal_emit (gst_object, gst_object_signals[DEEP_NOTIFY], - g_quark_from_string (pspecs[i]->name), (GstObject *) object, + name ? name : "(null)", + parent_name ? parent_name : "(null)", pspecs[i]->name); + /* FIXME, not MT safe because of glib */ + g_signal_emit (parent, gst_object_signals[DEEP_NOTIFY], + g_quark_from_string (pspecs[i]->name), GST_OBJECT_CAST (object), pspecs[i]); - gst_object = GST_OBJECT_PARENT (gst_object); + old_parent = parent; + parent = gst_object_get_parent (old_parent); + gst_object_unref (old_parent); g_static_rec_mutex_unlock (&dispatch_mutex); @@ -485,46 +509,48 @@ * @name: new name of object * Sets the name of the object, or gives the element a guaranteed unique - * name (if @name is NULL). + * name (if @name is NULL). This function makes a copy of the provided + * name so the called must g_free() the name it sent as a parameter. gst_object_set_name (GstObject * object, const gchar * name) GST_LOCK (object); - if (object->name != NULL) - g_free (object->name); + g_free (object->name); - if (name != NULL) + if (name != NULL) { object->name = g_strdup (name); - else { + GST_UNLOCK (object); + } else { GST_UNLOCK (object); gst_object_set_name_default (object); - GST_LOCK (object); - GST_UNLOCK (object); * gst_object_get_name: * @object: GstObject to get the name of - * Get the name of the object. + * Get the name of the object. This function returns a copy + * of the name, you should call g_free() on it after usage. - * Returns: name of the object + * Returns: name of the object. g_free() after usage. -const gchar * +gchar * gst_object_get_name (GstObject * object) - const gchar *result = NULL; + gchar *result = NULL; - g_return_val_if_fail (GST_IS_OBJECT (object), result); + g_return_val_if_fail (GST_IS_OBJECT (object), NULL); - result = object->name; + result = g_strdup (object->name); GST_UNLOCK (object); @@ -539,6 +565,8 @@ * and any floating reference will be removed (see gst_object_sink()). * Causes the parent-set signal to be emitted. gst_object_set_parent (GstObject * object, GstObject * parent) @@ -546,36 +574,60 @@ g_return_if_fail (GST_IS_OBJECT (parent)); g_return_if_fail (object != parent); - g_return_if_fail (object->parent == NULL); GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "set parent (ref and sink)"); - GST_LOCK (object); + /* no need to hold locks here as object is either floating and + * owned by this thread only or has a refcount bigger than 1 when + * concurrent access is performed */ gst_object_ref (object); - gst_object_sink (object); + if G_UNLIKELY + (object->parent != NULL) + goto had_parent; + /* sink object, we don't call our own function because we don't + * need to release/acquire the lock needlessly */ + gst_object_unref (object); object->parent = parent; g_signal_emit (G_OBJECT (object), gst_object_signals[PARENT_SET], 0, parent); + g_critical ("object already had a parent"); * gst_object_get_parent: * @object: GstObject to get parent of - * Returns the parent of @object. + * Returns the parent of @object. This function increases the refcount + * of the parent object so you should gst_object_unref() it after usage. - * Returns: parent of the object + * Returns: parent of the object, this can be NULL if the object has no + * parent. unref after usage. GstObject * gst_object_get_parent (GstObject * object) GstObject *result = NULL; result = object->parent; + if (result) + gst_object_ref (result); @@ -586,6 +638,10 @@ * @object: GstObject to unparent * Clear the parent of @object, removing the associated reference. + * This function decreases the refcount of the object so the object + * might not point to valid memory anymore after calling this function. gst_object_unparent (GstObject * object) @@ -597,12 +653,11 @@ parent = object->parent; - if (parent == NULL) { - GST_UNLOCK (object); - return; - GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "unparent"); - object->parent = NULL; + if G_LIKELY + (parent != NULL) { + GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "unparent"); + object->parent = NULL; + } g_signal_emit (G_OBJECT (object), gst_object_signals[PARENT_UNSET], 0, @@ -616,25 +671,36 @@ * @list: a list of #GstObject to check through * @name: the name to search for - * Checks to see if there is any object named @name in @list. + * Checks to see if there is any object named @name in @list. This function + * does not do any locking of any kind. You might want to protect the + * provided list with the lock of the owner of the list. This function + * will lock each GstObject in the list to compare the name, so be + * carefull when passing a list with a locked object. * Returns: TRUE if the name does not appear in the list, FALSE if it does. gst_object_check_uniqueness (GList * list, const gchar * name) - g_return_val_if_fail (name != NULL, FALSE); + gboolean result = TRUE; - while (list) { - GstObject *child = GST_OBJECT (list->data); + g_return_val_if_fail (name != NULL, FALSE); - list = g_list_next (list); + for (; list; list = g_list_next (list)) { + GstObject *child; - if (strcmp (gst_object_get_name (child), name) == 0) - return FALSE; + child = GST_OBJECT (list->data); + GST_LOCK (child); + if (strcmp (GST_OBJECT_NAME (child), name) == 0) { + GST_UNLOCK (child); + result = FALSE; + GST_UNLOCK (child); - return TRUE; + return result; @@ -653,7 +719,6 @@ GstObjectClass *oclass; - g_return_val_if_fail (object != NULL, parent); g_return_val_if_fail (GST_IS_OBJECT (object), parent); g_return_val_if_fail (parent != NULL, parent); @@ -680,7 +745,6 @@ g_return_if_fail (self != NULL); @@ -693,7 +757,6 @@ gst_object_real_restore_thyself (GstObject * object, xmlNodePtr self) @@ -707,9 +770,6 @@ GstObject *gstobject; - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_OBJECT (object)); gstobject = GST_OBJECT (object); switch (prop_id) { @@ -728,14 +788,11 @@ case ARG_NAME: - g_value_set_string (value, (gchar *) GST_OBJECT_NAME (gstobject)); + g_value_take_string (value, gst_object_get_name (gstobject)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -750,61 +807,62 @@ * Generates a string describing the path of the object in * the object hierarchy. Only useful (or used) for debugging. - * Returns: a string describing the path of the object + * Returns: a string describing the path of the object. You must + * g_free() the string after usage. gchar * gst_object_get_path_string (GstObject * object) - GSList *parentage = NULL; + GSList *parentage; GSList *parents; void *parent; gchar *prevpath, *path; - const char *component; - gchar *separator = ""; - gboolean free_component; + gchar *component; + gchar *separator; + /* ref object before adding to list */ + gst_object_ref (object); parentage = g_slist_prepend (NULL, object); path = g_strdup (""); - /* first walk the object hierarchy to build a list of the parents */ + /* first walk the object hierarchy to build a list of the parents, + * be carefull here with refcounting. */ do { if (GST_IS_OBJECT (object)) { parent = gst_object_get_parent (object); - } else { - parentage = g_slist_prepend (parentage, NULL); - parent = NULL; - } - if (parent != NULL) { + /* add parents to list, refcount remains increased while + * we handle the object */ parentage = g_slist_prepend (parentage, parent); + } else { object = parent; } while (object != NULL); - /* then walk the parent list and print them out */ - parents = parentage; - while (parents) { + /* then walk the parent list and print them out. we need to + * decrease the refcounting on each element after we handled + * it. */ + for (parents = parentage; parents; parents = g_slist_next (parents)) { if (GST_IS_OBJECT (parents->data)) { - GstObjectClass *oclass = GST_OBJECT_GET_CLASS (parents->data); + GstObject *item = GST_OBJECT_CAST (parents->data); + GstObjectClass *oclass = GST_OBJECT_GET_CLASS (item); - component = gst_object_get_name (parents->data); + component = gst_object_get_name (item); separator = oclass->path_string_separator; - free_component = FALSE; + /* and unref now */ + gst_object_unref (item); } else { component = g_strdup_printf ("%p", parents->data); separator = "/"; - free_component = TRUE; prevpath = path; path = g_strjoin (separator, prevpath, component, NULL); g_free (prevpath); - if (free_component) - g_free ((gchar *) component); - parents = g_slist_next (parents); + g_free (component); g_slist_free (parentage); @@ -812,8 +870,6 @@ return path; struct _GstSignalObject GObject object; Index: gstobject.h RCS file: /cvs/gstreamer/gstreamer/gst/gstobject.h,v retrieving revision 1.47.2.1 retrieving revision 1.47.2.2 diff -u -d -r1.47.2.1 -r1.47.2.2 --- gstobject.h 8 Dec 2004 17:40:36 -0000 1.47.2.1 +++ gstobject.h 9 Dec 2004 21:08:13 -0000 1.47.2.2 * gstobject.h: Header for base GstObject @@ -40,6 +41,7 @@ #define GST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_OBJECT, GstObjectClass)) #define GST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_OBJECT, GstObject)) #define GST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_OBJECT, GstObjectClass)) +#define GST_OBJECT_CAST(obj) ((GstObject*)(obj)) /* make sure we don't change the object size but stil make it compile * without libxml */ @@ -49,41 +51,40 @@ typedef enum - GST_DESTROYED = 0, - GST_FLOATING, + GST_OBJECT_DESTROYED = 0, + GST_OBJECT_FLOATING, GST_OBJECT_FLAG_LAST = 4 } GstObjectFlags; -#ifdef USE_REC_LOCKS - #define GST_LOCK(obj) (g_static_rec_mutex_lock(GST_OBJECT(obj)->lock)) - #define GST_TRYLOCK(obj) (g_static_rec_mutex_trylock(GST_OBJECT(obj)->lock)) - #define GST_UNLOCK(obj) (g_static_rec_mutex_unlock(GST_OBJECT(obj)->lock)) - #define GST_GET_LOCK(obj) (g_static_mutex_get_mutex(&GST_OBJECT(obj)->lock->mutex)) - #define GST_LOCK_TYPE GStaticRecMutex - #define GST_LOCK_CREATE g_static_rec_mutex_new() -#else - #define GST_LOCK(obj) (g_mutex_lock(GST_OBJECT(obj)->lock)) - #define GST_TRYLOCK(obj) (g_mutex_trylock(GST_OBJECT(obj)->lock)) - #define GST_UNLOCK(obj) (g_mutex_unlock(GST_OBJECT(obj)->lock)) - #define GST_GET_LOCK(obj) (GST_OBJECT(obj)->lock) - #define GST_LOCK_TYPE GMutex - #define GST_LOCK_CREATE g_mutex_new() +/* we do a GST_OBJECT_CAST to avoid type checking, better call these + * function with a valid object! */ +#define GST_LOCK(obj) (g_mutex_lock(GST_OBJECT_CAST(obj)->lock)) +#define GST_TRYLOCK(obj) (g_mutex_trylock(GST_OBJECT_CAST(obj)->lock)) +#define GST_UNLOCK(obj) (g_mutex_unlock(GST_OBJECT_CAST(obj)->lock)) +#define GST_GET_LOCK(obj) (GST_OBJECT_CAST(obj)->lock) -struct _GstObject { - GObject object; +#define GST_OBJECT_NAME(obj) (GST_OBJECT_CAST(obj)->name) +#define GST_OBJECT_PARENT(obj) (GST_OBJECT_CAST(obj)->parent) - gchar *name; +#define GST_FLAGS(obj) (GST_OBJECT_CAST (obj)->flags) +#define GST_FLAG_IS_SET(obj,flag) (GST_FLAGS (obj) & (1<<(flag))) +#define GST_FLAG_SET(obj,flag) G_STMT_START{ (GST_FLAGS (obj) |= (1<<(flag))); }G_STMT_END +#define GST_FLAG_UNSET(obj,flag) G_STMT_START{ (GST_FLAGS (obj) &= ~(1<<(flag))); }G_STMT_END - /* locking for all sorts of things */ - GST_LOCK_TYPE *lock; - - /* this object's parent */ - GstObject *parent; +#define GST_OBJECT_IS_DESTROYED(obj) (GST_FLAG_IS_SET (obj, GST_OBJECT_DESTROYED)) +#define GST_OBJECT_IS_FLOATING(obj) (GST_FLAG_IS_SET (obj, GST_OBJECT_FLOATING)) - guint32 flags; +struct _GstObject { + GObject object; + GMutex *lock; /* locking for all sorts of things */ + gchar *name; /* name */ + GstObject *parent; /* this object's parent */ + guint32 flags; @@ -100,25 +101,16 @@ void (*object_saved) (GstObject *object, xmlNodePtr parent); void (*deep_notify) (GstObject *object, GstObject *orig, GParamSpec *pspec); - /* functions go here */ + /* vtable */ void (*destroy) (GstObject *object); xmlNodePtr (*save_thyself) (GstObject *object, xmlNodePtr parent); void (*restore_thyself) (GstObject *object, xmlNodePtr self); -#define GST_FLAGS(obj) (GST_OBJECT (obj)->flags) -#define GST_FLAG_IS_SET(obj,flag) (GST_FLAGS (obj) & (1<<(flag))) -#define GST_FLAG_SET(obj,flag) G_STMT_START{ (GST_FLAGS (obj) |= (1<<(flag))); }G_STMT_END -#define GST_FLAG_UNSET(obj,flag) G_STMT_START{ (GST_FLAGS (obj) &= ~(1<<(flag))); }G_STMT_END -#define GST_OBJECT_NAME(obj) (const gchar*)(((GstObject *)(obj))->name) -#define GST_OBJECT_PARENT(obj) (((GstObject *)(obj))->parent) -#define GST_OBJECT_DESTROYED(obj) (GST_FLAG_IS_SET (obj, GST_DESTROYED)) -#define GST_OBJECT_FLOATING(obj) (GST_FLAG_IS_SET (obj, GST_FLOATING)) @@ -127,8 +119,7 @@ /* name routines */ void gst_object_set_name (GstObject *object, const gchar *name); -G_CONST_RETURN gchar* - gst_object_get_name (GstObject *object); +gchar* gst_object_get_name (GstObject *object); /* parentage routines */ void gst_object_set_parent (GstObject *object, GstObject *parent); @@ -136,10 +127,23 @@ void gst_object_unparent (GstObject *object); void gst_object_default_deep_notify (GObject *object, GstObject *orig, - GParamSpec *pspec, gchar **excluded_props); + GParamSpec *pspec, gchar **excluded_props); +/* refcounting + life cycle */ +GstObject * gst_object_ref (GstObject *object); +void gst_object_unref (GstObject *object); +void gst_object_sink (GstObject *object); +/* replace object pointer */ +void gst_object_replace (GstObject **oldobj, GstObject *newobj); +/* printing out the 'path' of the object */ +gchar * gst_object_get_path_string (GstObject *object); +/* misc utils */ gboolean gst_object_check_uniqueness (GList *list, const gchar *name); +/* load/save */ #ifndef GST_DISABLE_LOADSAVE_REGISTRY xmlNodePtr gst_object_save_thyself (GstObject *object, xmlNodePtr parent); void gst_object_restore_thyself (GstObject *object, xmlNodePtr self); @@ -150,17 +154,7 @@ #endif -/* refcounting + life cycle */ -GstObject * gst_object_ref (GstObject *object); -void gst_object_unref (GstObject *object); -void gst_object_sink (GstObject *object); -/* replace object pointer */ -void gst_object_replace (GstObject **oldobj, GstObject *newobj); -/* printing out the 'path' of the object */ -gchar * gst_object_get_path_string (GstObject *object); +/* class signal stuff */ guint gst_class_signal_connect (GstObjectClass *klass, const gchar *name, gpointer func, Index: gstpad.c RCS file: /cvs/gstreamer/gstreamer/gst/gstpad.c,v retrieving revision 1.350.2.1 retrieving revision 1.350.2.2 diff -u -d -r1.350.2.1 -r1.350.2.2 --- gstpad.c 8 Dec 2004 17:40:36 -0000 1.350.2.1 +++ gstpad.c 9 Dec 2004 21:08:13 -0000 1.350.2.2 @@ -385,9 +385,9 @@ g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN); - GST_LOCK (pad); + /* since the direction cannot change at runtime we can + * safely read without locking. */ result = GST_PAD_DIRECTION (pad); - GST_UNLOCK (pad); @@ -998,27 +998,49 @@ * Unlinks the source pad from the sink pad. Will emit the "unlinked" signal on * both pads. + * Returns: TRUE if the pads were unlinked. This function returns FALSE if + * the pads were not linked together. gst_pad_unlink (GstPad * srcpad, GstPad * sinkpad) GstRealPad *realsrc, *realsink; - g_return_if_fail (GST_IS_PAD (srcpad)); - g_return_if_fail (GST_IS_PAD (sinkpad)); + g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE); + g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE); GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinking %s:%s(%p) and %s:%s(%p)", GST_DEBUG_PAD_NAME (srcpad), srcpad, GST_DEBUG_PAD_NAME (sinkpad), sinkpad); + GST_LOCK (srcpad); realsrc = GST_PAD_REALIZE (srcpad); - realsink = GST_PAD_REALIZE (sinkpad); + if (srcpad != GST_PAD_CAST (realsrc)) { + GST_LOCK (realsrc); + /* we don't care if the ghostpad goes away now */ + GST_UNLOCK (srcpad); + if (G_UNLIKELY (GST_RPAD_DIRECTION (realsrc) != GST_PAD_SRC)) + goto not_srcpad; - g_return_if_fail (GST_RPAD_PEER (realsrc) != NULL); - g_return_if_fail (GST_RPAD_PEER (realsink) == realsrc); + if (G_UNLIKELY (GST_RPAD_PEER (realsrc) == NULL)) + goto was_unlinked; - g_return_if_fail ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) && - (GST_RPAD_DIRECTION (realsink) == GST_PAD_SINK)); + GST_LOCK (sinkpad); + realsink = GST_PAD_REALIZE (sinkpad); + if (sinkpad != GST_PAD_CAST (realsink)) { + GST_LOCK (realsink); + GST_UNLOCK (sinkpad); + if (G_UNLIKELY (GST_RPAD_DIRECTION (realsink) != GST_PAD_SINK)) + goto not_sinkpad; + if (G_UNLIKELY (GST_RPAD_PEER (realsrc) != realsink)) + goto not_linked_together; if (GST_RPAD_UNLINKFUNC (realsrc)) { GST_RPAD_UNLINKFUNC (realsrc) (GST_PAD (realsrc)); @@ -1035,9 +1057,8 @@ gst_caps_replace (&GST_RPAD_APPFILTER (realsrc), NULL); gst_caps_replace (&GST_RPAD_APPFILTER (realsink), NULL); - /* hold a reference, as they can go away in the signal handlers */ - gst_object_ref (GST_OBJECT (realsrc)); - gst_object_ref (GST_OBJECT (realsink)); + GST_UNLOCK (realsrc); + GST_UNLOCK (realsink); /* fire off a signal to each of the pads telling them * that they've been unlinked */ @@ -1049,8 +1070,36 @@ GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinked %s:%s and %s:%s", GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad)); - gst_object_unref (GST_OBJECT (realsrc)); - gst_object_unref (GST_OBJECT (realsink)); +not_srcpad: + g_critical ("pad %s is not a source pad", GST_PAD_NAME (realsrc)); + GST_UNLOCK (realsrc); +not_sinkpad: + g_critical ("pad %s is not a sink pad", GST_PAD_NAME (realsink)); + GST_UNLOCK (realsink); +was_unlinked: + /* we do not emit a warning in this case because unlinking cannot + * be made MT safe.*/ +not_linked_together: @@ -1060,13 +1109,21 @@ * Checks if a @pad is linked to another pad or not. * Returns: TRUE if the pad is linked, FALSE otherwise. gst_pad_is_linked (GstPad * pad) + gboolean result; - return GST_PAD_PEER (pad) != NULL; + result = (GST_PAD_PEER (pad) != NULL); @@ -1092,9 +1149,7 @@ GstPadLinkReturn result; /* generic checks */ - g_return_val_if_fail (srcpad != NULL, GST_PAD_LINK_REFUSED); g_return_val_if_fail (GST_IS_PAD (srcpad), GST_PAD_LINK_REFUSED); - g_return_val_if_fail (sinkpad != NULL, GST_PAD_LINK_REFUSED); g_return_val_if_fail (GST_IS_PAD (sinkpad), GST_PAD_LINK_REFUSED); GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s", @@ -1321,13 +1376,17 @@ * and an error code is returned. * Returns: The result code of the operation. + * MT safe GstPadLinkReturn gst_pad_relink_filtered (GstPad * srcpad, GstPad * sinkpad, const GstCaps * filtercaps) - GstCaps *filtercopy = gst_caps_copy (filtercaps); + GstCaps *filtercopy; + /* create copy with two refs */ + filtercopy = gst_caps_copy (filtercaps); filtercopy = gst_caps_ref (filtercopy); /* probably check if intersection with new filter is ok */ @@ -1454,6 +1513,8 @@ * Returns: TRUE if the caps could be set. FALSE if the caps were not fixed * or bad parameters were provided to this function. gst_pad_set_caps (GstPad * pad, GstCaps * caps) @@ -1501,16 +1562,32 @@ * gst_pad_get_peer: * @pad: a #GstPad to get the peer of. - * Gets the peer of @pad. + * Gets the peer of @pad. This function refs the peer pad so + * you need to unref it after use. - * Returns: the peer #GstPad. + * Returns: the peer #GstPad. Unref after usage. gst_pad_get_peer (GstPad * pad) + GstRealPad *realpad; + GstRealPad *result; g_return_val_if_fail (GST_IS_PAD (pad), NULL); - return GST_PAD (GST_PAD_PEER (pad)); + realpad = GST_PAD_REALIZE (pad); + if (pad != GST_PAD_CAST (realpad)) { + GST_LOCK (realpad); + result = GST_RPAD_PEER (realpad); + gst_object_ref (GST_OBJECT (result)); + GST_UNLOCK (realpad); + return GST_PAD_CAST (result); @@ -1857,16 +1934,16 @@ GST_LOCK (pad); - while (GST_RPAD_IS_BLOCKED (pad)) + while (G_UNLIKELY (GST_RPAD_IS_BLOCKED (pad))) handle_pad_block (pad); - if ((peer = GST_RPAD_PEER (pad)) == NULL) + if (G_UNLIKELY ((peer = GST_RPAD_PEER (pad)) == NULL)) goto not_linked; - if (!GST_RPAD_IS_ACTIVE (peer)) + if (G_UNLIKELY (!GST_RPAD_IS_ACTIVE (peer))) goto not_active; - if ((chainfunc = peer->chainfunc) == NULL) + if (G_UNLIKELY ((chainfunc = peer->chainfunc) == NULL)) goto no_function; GST_UNLOCK (pad); @@ -1883,25 +1960,17 @@ not_linked: GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pushing, but it was not linked"); - ret = GST_FLOW_NOT_CONNECTED; - goto error; + GST_UNLOCK_RETURN (pad, GST_FLOW_NOT_CONNECTED); not_active: GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pushing, but it was inactive"); - ret = GST_FLOW_WRONG_STATE; + GST_UNLOCK_RETURN (pad, GST_FLOW_WRONG_STATE); no_function: GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pushing, but not chainhandler"); g_warning ("push on pad %s:%s but it has no chainhandler, file a bug.", GST_DEBUG_PAD_NAME (peer)); - ret = GST_FLOW_ERROR; -error: - return ret; + GST_UNLOCK_RETURN (pad, GST_FLOW_ERROR); @@ -1928,13 +1997,13 @@ goto not_connected; - if ((getfunc = peer->getfunc) == NULL) + if (G_UNLIKELY ((getfunc = peer->getfunc) == NULL)) @@ -1951,20 +2020,13 @@ not_connected: "pulling, but it was not linked"); GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL), ("pull on pad %s:%s but the peer pad %s:%s has no getfunc", GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer))); @@ -1994,13 +2056,13 @@ - if ((getrangefunc = peer->getrangefunc) == NULL) + if (G_UNLIKELY ((getrangefunc = peer->getrangefunc) == NULL)) @@ -2017,22 +2079,13 @@ "pulling range, but it was not linked"); ("pullrange on pad %s:%s but the peer pad %s:%s has no getrangefunction", /************************************************************************ Index: gstpad.h RCS file: /cvs/gstreamer/gstreamer/gst/gstpad.h,v retrieving revision 1.152.2.1 retrieving revision 1.152.2.2 diff -u -d -r1.152.2.1 -r1.152.2.2 --- gstpad.h 8 Dec 2004 17:40:36 -0000 1.152.2.1 +++ gstpad.h 9 Dec 2004 21:08:13 -0000 1.152.2.2 @@ -187,10 +187,15 @@ struct _GstRealPad { GstPad pad; + /* direction cannot change after creating the pad */ + GstPadDirection direction; + /*< public >*/ /* with STREAM_LOCK */ /* streaming lock and cond */ GMutex *stream_lock; GCond *stream_cond; /* block cond, mutex is from the object */ GCond *block_cond; GstPadBlockCallback block_callback; @@ -200,8 +205,6 @@ GstCaps *caps; GstCaps *appfilter; GstPadGetCapsFunction getcapsfunc; - GstPadDirection direction; GstPadActivateFunction activatefunc; @@ -232,6 +235,7 @@ GstProbeDispatcher probedisp; @@ -265,30 +269,30 @@ /* GstPad */ #define GST_PAD_NAME(pad) (GST_OBJECT_NAME(pad)) #define GST_PAD_PARENT(pad) ((GstElement *)(GST_OBJECT_PARENT(pad))) -#define GST_PAD_ELEMENT_PRIVATE(pad) (((GstPad *)(pad))->element_private) -#define GST_PAD_PAD_TEMPLATE(pad) (((GstPad *)(pad))->padtemplate) +#define GST_PAD_ELEMENT_PRIVATE(pad) (GST_PAD_CAST(pad)->element_private) +#define GST_PAD_PAD_TEMPLATE(pad) (GST_PAD_CAST(pad)->padtemplate) /* GstRealPad */ -#define GST_RPAD_DIRECTION(pad) (((GstRealPad *)(pad))->direction) -#define GST_RPAD_CAPS(pad) (((GstRealPad *)(pad))->caps) -#define GST_RPAD_APPFILTER(pad) (((GstRealPad *)(pad))->appfilter) -#define GST_RPAD_PEER(pad) (((GstRealPad *)(pad))->peer) -#define GST_RPAD_ACTIVATEFUNC(pad) (((GstRealPad *)(pad))->activatefunc) -#define GST_RPAD_CHAINFUNC(pad) (((GstRealPad *)(pad))->chainfunc) -#define GST_RPAD_GETFUNC(pad) (((GstRealPad *)(pad))->getfunc) -#define GST_RPAD_GETRANGEFUNC(pad) (((GstRealPad *)(pad))->getrangefunc) -#define GST_RPAD_EVENTFUNC(pad) (((GstRealPad *)(pad))->eventfunc) -#define GST_RPAD_CONVERTFUNC(pad) (((GstRealPad *)(pad))->convertfunc) -#define GST_RPAD_QUERYFUNC(pad) (((GstRealPad *)(pad))->queryfunc) -#define GST_RPAD_INTLINKFUNC(pad) (((GstRealPad *)(pad))->intlinkfunc) -#define GST_RPAD_FORMATSFUNC(pad) (((GstRealPad *)(pad))->formatsfunc) -#define GST_RPAD_QUERYTYPEFUNC(pad) (((GstRealPad *)(pad))->querytypefunc) -#define GST_RPAD_EVENTMASKFUNC(pad) (((GstRealPad *)(pad))->eventmaskfunc) +#define GST_RPAD_DIRECTION(pad) (GST_REAL_PAD_CAST(pad)->direction) +#define GST_RPAD_CAPS(pad) (GST_REAL_PAD_CAST(pad)->caps) +#define GST_RPAD_APPFILTER(pad) (GST_REAL_PAD_CAST(pad)->appfilter) +#define GST_RPAD_PEER(pad) (GST_REAL_PAD_CAST(pad)->peer) +#define GST_RPAD_ACTIVATEFUNC(pad) (GST_REAL_PAD_CAST(pad)->activatefunc) +#define GST_RPAD_CHAINFUNC(pad) (GST_REAL_PAD_CAST(pad)->chainfunc) +#define GST_RPAD_GETFUNC(pad) (GST_REAL_PAD_CAST(pad)->getfunc) +#define GST_RPAD_GETRANGEFUNC(pad) (GST_REAL_PAD_CAST(pad)->getrangefunc) +#define GST_RPAD_EVENTFUNC(pad) (GST_REAL_PAD_CAST(pad)->eventfunc) +#define GST_RPAD... [truncated message content] |
From: <wt...@fr...> - 2004-12-09 22:02:47
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Thu Dec 09 2004 14:03:40 PST Branch: BRANCH-THREADED Log message: * gst/gstpad.c: (gst_pad_custom_new), (gst_pad_get_direction), (gst_pad_set_active), (gst_pad_is_active), (gst_pad_set_blocked_async), (gst_pad_unlink), (gst_pad_get_real_parent), (gst_pad_relink_filtered), (gst_pad_alloc_buffer), (handle_pad_block), (gst_pad_push), (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): * gst/gstpad.h: More MT fixes. Modified files: . : ChangeLog gst : gstpad.c gstpad.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.858.2.3&r2=1.858.2.4 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstpad.c.diff?r1=1.350.2.2&r2=1.350.2.3 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstpad.h.diff?r1=1.152.2.2&r2=1.152.2.3 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.858.2.3 retrieving revision 1.858.2.4 diff -u -d -r1.858.2.3 -r1.858.2.4 --- ChangeLog 9 Dec 2004 21:08:12 -0000 1.858.2.3 +++ ChangeLog 9 Dec 2004 22:03:28 -0000 1.858.2.4 @@ -1,5 +1,16 @@ 2004-12-09 Wim Taymans <wi...@fl...> + * gst/gstpad.c: (gst_pad_custom_new), (gst_pad_get_direction), + (gst_pad_set_active), (gst_pad_is_active), + (gst_pad_set_blocked_async), (gst_pad_unlink), + (gst_pad_get_real_parent), (gst_pad_relink_filtered), + (gst_pad_alloc_buffer), (handle_pad_block), (gst_pad_push), + (gst_pad_pull), (gst_pad_pull_range), (gst_pad_push_event): + * gst/gstpad.h: + More MT fixes. + +2004-12-09 Wim Taymans <wi...@fl...> * gst/gst_private.h: * gst/gstbin.c: (gst_bin_class_init), (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_get_clock), Index: gstpad.c RCS file: /cvs/gstreamer/gstreamer/gst/gstpad.c,v retrieving revision 1.350.2.2 retrieving revision 1.350.2.3 diff -u -d -r1.350.2.2 -r1.350.2.3 --- gstpad.c 9 Dec 2004 21:08:13 -0000 1.350.2.2 +++ gstpad.c 9 Dec 2004 22:03:28 -0000 1.350.2.3 @@ -284,7 +284,7 @@ } /* FIXME-0.9: Replace these custom functions with proper inheritance via _init - functions and object properties */ + functions and object properties. update: probably later in the cycle. */ /** * gst_pad_custom_new: * @type: the #Gtype of the pad. @@ -293,9 +293,12 @@ * * Creates a new pad with the given name and type in the given direction. * If name is NULL, a guaranteed unique name (across all pads) - * will be assigned. + * will be assigned. + * This function makes a copy of the name so you can safely free the name. * Returns: a new #GstPad, or NULL in case of an error. + * + * MT safe. */ GstPad * gst_pad_custom_new (GType type, const gchar * name, GstPadDirection direction) @@ -306,7 +309,7 @@ gst_object_set_name (GST_OBJECT (pad), name); GST_RPAD_DIRECTION (pad) = direction; - return GST_PAD (pad); + return GST_PAD_CAST (pad); @@ -317,6 +320,7 @@ * Creates a new real pad with the given name in the given direction. * will be assigned. @@ -335,6 +339,7 @@ * Creates a new custom pad with the given name from the given template. @@ -360,6 +365,7 @@ * Creates a new real pad with the given name from the given template. @@ -374,15 +380,21 @@ * gst_pad_get_direction: * @pad: a #GstPad to get the direction of. - * Gets the direction of the pad. + * Gets the direction of the pad. The direction of the pad is + * decided at construction time so this function does not take + * the LOCK. * Returns: the #GstPadDirection of the pad. GstPadDirection gst_pad_get_direction (GstPad * pad) { GstPadDirection result; + /* pad unkown is a little silly but we need some sort of + * error return value */ g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN); /* since the direction cannot change at runtime we can @@ -400,6 +412,8 @@ * Activates or deactivates the given pad. * Returns: TRUE if the operation was successfull. gboolean gst_pad_set_active (GstPad * pad, gboolean active) @@ -409,13 +423,13 @@ gboolean result = FALSE; GstPadActivateFunction activatefunc; - g_return_val_if_fail (GST_IS_PAD (pad), result); + g_return_val_if_fail (GST_IS_PAD (pad), FALSE); GST_LOCK (pad); old = GST_PAD_IS_ACTIVE (pad); - if (old == active) - goto done; + if (G_UNLIKELY (old == active)) + goto exit; realpad = GST_PAD_REALIZE (pad); @@ -445,7 +459,8 @@ GST_DEBUG_PAD_NAME (realpad)); GST_FLAG_UNSET (realpad, GST_PAD_DISABLED); } -done: +exit: GST_UNLOCK (pad); return result; @@ -458,13 +473,15 @@ * Query if a pad is active * Returns: TRUE if the pad is active. gst_pad_is_active (GstPad * pad) result = !GST_FLAG_IS_SET (pad, GST_PAD_DISABLED); @@ -493,31 +510,31 @@ * Returns: TRUE if the pad could be blocked. This function can fail * wrong parameters were passed or the pad was already in the * requested state. gst_pad_set_blocked_async (GstPad * pad, gboolean blocked, GstPadBlockCallback callback, gpointer user_data) - gboolean result = TRUE; gboolean was_blocked; GstRealPad *realpad; - /* only for real pads for now, need to transfer the lock - * to the realized pad */ g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE); + if (GST_PAD_CAST (realpad) != pad) { + GST_LOCK (realpad); + GST_UNLOCK (pad); + } /* beware for turning flags into booleans */ was_blocked = !!GST_RPAD_IS_BLOCKED (realpad); - if (was_blocked == blocked) { - GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pad %s:%s was in right state", - GST_DEBUG_PAD_NAME (pad)); - result = FALSE; - } + if (G_UNLIKELY (was_blocked == blocked)) + goto had_right_state; if (blocked) { GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "blocking pad %s:%s", GST_DEBUG_PAD_NAME (pad)); @@ -548,10 +565,15 @@ GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "unblocked"); } - return result; + return TRUE; +had_right_state: + GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pad %s:%s was in right state", + GST_DEBUG_PAD_NAME (pad)); + GST_UNLOCK (pad); + return FALSE; @@ -566,6 +588,8 @@ gst_pad_set_blocked (GstPad * pad, gboolean blocked) @@ -582,6 +606,8 @@ * is actually blocked at this point. * Returns: TRUE if the pad is blocked. gst_pad_is_blocked (GstPad * pad) @@ -1323,15 +1349,31 @@ * Gets the real parent object of this pad. If the pad * is a ghost pad, the actual owner of the real pad is * returned, as opposed to #gst_pad_get_parent(). + * Unref the object after use. * Returns: the parent #GstElement. GstElement * gst_pad_get_real_parent (GstPad * pad) + GstRealPad *realpad; + GstElement *element; g_return_val_if_fail (GST_IS_PAD (pad), NULL); - return GST_PAD_PARENT (GST_PAD (GST_PAD_REALIZE (pad))); + GST_LOCK (pad); + realpad = GST_PAD_REALIZE (pad); + if (pad != GST_PAD_CAST (realpad)) { + element = GST_PAD_PARENT (realpad); + gst_object_ref (GST_OBJECT (element)); + GST_UNLOCK (realpad); + return element; /* FIXME not MT safe */ @@ -1640,7 +1682,10 @@ * caps of the buffer after performing this function and renegotiate * to the format if needed. - * Returns: a new, empty #GstBuffer, or NULL if there is an error + * Returns: a new, empty #GstBuffer, or NULL if wrong parameters + * were provided. GstBuffer * gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size) @@ -1648,32 +1693,42 @@ GstRealPad *peer; GstBuffer *result = NULL; GstPadBufferAllocFunction bufferallocfunc; + GstCaps *caps; g_return_val_if_fail (GST_IS_REAL_PAD (pad), NULL); g_return_val_if_fail (GST_PAD_IS_SRC (pad), NULL); - if ((peer = GST_RPAD_PEER (pad)) == NULL) + if (G_UNLIKELY ((peer = GST_RPAD_PEER (pad)) == NULL)) goto fallback; - if ((bufferallocfunc = peer->bufferallocfunc) == NULL) + if (G_LIKELY ((bufferallocfunc = peer->bufferallocfunc) == NULL)) GST_CAT_DEBUG (GST_CAT_PADS, "calling bufferallocfunc &%s (@%p) of peer pad %s:%s", GST_DEBUG_FUNCPTR_NAME (bufferallocfunc), - &bufferallocfunc, GST_DEBUG_PAD_NAME (((GstPad *) peer))); + &bufferallocfunc, GST_DEBUG_PAD_NAME (peer)); result = bufferallocfunc (GST_PAD (peer), offset, size, GST_PAD_CAPS (pad)); - if (result == NULL) + if (result == NULL) { + GST_LOCK (pad); /* fallback case */ fallback: + caps = GST_PAD_CAPS (pad); + gst_caps_ref (caps); result = gst_buffer_new_and_alloc (size); - gst_buffer_set_caps (result, GST_PAD_CAPS (pad)); + gst_buffer_set_caps (result, caps); + gst_caps_unref (caps); @@ -1871,24 +1926,28 @@ #endif /* GST_DISABLE_LOADSAVE */ -/* should be called with pad lock held */ +/* + * should be called with pad lock held + */ static void -handle_pad_block (GstPad * pad) +handle_pad_block (GstRealPad * pad) GstPadBlockCallback callback; gpointer user_data; - GstRealPad *realpad; - - realpad = GST_REAL_PAD (pad); GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "signal block taken on pad %s:%s", GST_DEBUG_PAD_NAME (pad)); - callback = realpad->block_callback; + /* need to grab extra ref for the callbacks */ + gst_object_ref (GST_OBJECT (pad)); + callback = pad->block_callback; if (callback) { - user_data = realpad->block_data; + user_data = pad->block_data; GST_UNLOCK (pad); - callback (pad, TRUE, user_data); + callback (GST_PAD_CAST (pad), TRUE, user_data); GST_LOCK (pad); } else { GST_PAD_BLOCK_SIGNAL (pad); @@ -1899,15 +1958,17 @@ GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "got unblocked"); - callback (pad, FALSE, user_data); + callback (GST_PAD_CAST (pad), FALSE, user_data); + gst_object_unref (GST_OBJECT (pad)); @@ -1919,6 +1980,8 @@ * only be called by @pad's parent. * Returns: a #GstFlowReturn from the peer pad. GstFlowReturn gst_pad_push (GstPad * pad, GstBuffer * buffer) @@ -1935,7 +1998,7 @@ while (G_UNLIKELY (GST_RPAD_IS_BLOCKED (pad))) - handle_pad_block (pad); + handle_pad_block (GST_REAL_PAD_CAST (pad)); if (G_UNLIKELY ((peer = GST_RPAD_PEER (pad)) == NULL)) goto not_linked; @@ -1943,10 +2006,19 @@ if (G_UNLIKELY (!GST_RPAD_IS_ACTIVE (peer))) goto not_active; + gst_object_ref (GST_OBJECT (peer)); + GST_LOCK (peer); if (G_UNLIKELY ((chainfunc = peer->chainfunc) == NULL)) goto no_function; - GST_UNLOCK (pad); + /* NOTE: after this unlock the peer could change chainfunction, + * we cannot hold the lock for the peer so we might send + * the data to the wrong function. This is not really a + * problem since functions are assigned at creation time + * and don't change that often... */ + GST_UNLOCK (peer); "calling chainfunction &%s of peer pad %s:%s", @@ -1954,6 +2026,8 @@ ret = chainfunc (GST_PAD_CAST (peer), buffer); + gst_object_unref (GST_OBJECT (peer)); return ret; /* ERROR recovery here */ @@ -1970,7 +2044,7 @@ GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pushing, but not chainhandler"); g_warning ("push on pad %s:%s but it has no chainhandler, file a bug.", GST_DEBUG_PAD_NAME (peer)); - GST_UNLOCK_RETURN (pad, GST_FLOW_ERROR); + GST_UNLOCK_RETURN (peer, GST_FLOW_ERROR); @@ -1982,6 +2056,8 @@ * parent. gst_pad_pull (GstPad * pad, GstBuffer ** buffer) @@ -1998,15 +2074,20 @@ goto not_connected; if (G_UNLIKELY ((getfunc = peer->getfunc) == NULL)) + /* see note in above function */ "calling getfunc %s of peer pad %s:%s", @@ -2014,6 +2095,8 @@ ret = getfunc (GST_PAD_CAST (peer), buffer); @@ -2026,7 +2109,7 @@ GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL), ("pull on pad %s:%s but the peer pad %s:%s has no getfunc", GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer))); @@ -2040,6 +2123,8 @@ gst_pad_pull_range (GstPad * pad, guint64 offset, guint size, @@ -2057,15 +2142,20 @@ if (G_UNLIKELY ((getrangefunc = peer->getrangefunc) == NULL)) "calling getrangefunc %s of peer pad %s:%s", @@ -2073,6 +2163,8 @@ ret = getrangefunc (GST_PAD_CAST (peer), offset, size, buffer); @@ -2085,7 +2177,7 @@ ("pullrange on pad %s:%s but the peer pad %s:%s has no getrangefunction", /************************************************************************ @@ -2641,6 +2733,8 @@ * Sends the event to the peer of the given pad. * Returns: TRUE if the event was handled. gst_pad_push_event (GstPad * pad, GstEvent * event) @@ -2655,11 +2749,13 @@ peerpad = GST_RPAD_PEER (pad); if (peerpad == NULL) + gst_object_ref (GST_OBJECT_CAST (peerpad)); result = gst_pad_send_event (GST_PAD_CAST (peerpad), event); + gst_object_unref (GST_OBJECT_CAST (peerpad)); /* ERROR handling */ Index: gstpad.h RCS file: /cvs/gstreamer/gstreamer/gst/gstpad.h,v retrieving revision 1.152.2.2 retrieving revision 1.152.2.3 diff -u -d -r1.152.2.2 -r1.152.2.3 --- gstpad.h 9 Dec 2004 21:08:13 -0000 1.152.2.2 +++ gstpad.h 9 Dec 2004 22:03:28 -0000 1.152.2.3 @@ -268,7 +268,7 @@ /***** helper macros *****/ /* GstPad */ #define GST_PAD_NAME(pad) (GST_OBJECT_NAME(pad)) -#define GST_PAD_PARENT(pad) ((GstElement *)(GST_OBJECT_PARENT(pad))) +#define GST_PAD_PARENT(pad) (GST_ELEMENT_CAST(GST_OBJECT_PARENT(pad))) #define GST_PAD_ELEMENT_PRIVATE(pad) (GST_PAD_CAST(pad)->element_private) #define GST_PAD_PAD_TEMPLATE(pad) (GST_PAD_CAST(pad)->padtemplate) |
From: <wt...@fr...> - 2004-12-31 18:19:03
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Fri Dec 31 2004 10:18:57 PST Branch: BRANCH-THREADED Log message: * gst/gstevent.c: (gst_event_new_discontinuous_valist), (gst_event_discont_get_value): * gst/gstevent.h: We'll need the end offset in discont soon. Modified files: . : ChangeLog gst : gstevent.c gstevent.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.858.2.16&r2=1.858.2.17 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstevent.c.diff?r1=1.48&r2=1.48.2.1 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstevent.h.diff?r1=1.51.2.3&r2=1.51.2.4 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.858.2.16 retrieving revision 1.858.2.17 diff -u -d -r1.858.2.16 -r1.858.2.17 --- ChangeLog 31 Dec 2004 10:44:46 -0000 1.858.2.16 +++ ChangeLog 31 Dec 2004 18:18:45 -0000 1.858.2.17 @@ -1,5 +1,12 @@ 2004-12-31 Wim Taymans <wi...@fl...> + * gst/gstevent.c: (gst_event_new_discontinuous_valist), + (gst_event_discont_get_value): + * gst/gstevent.h: + We'll need the end offset in discont soon. + +2004-12-31 Wim Taymans <wi...@fl...> * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_set_bus), (gst_bin_set_scheduler), (gst_bin_add_func), (gst_bin_iterate_elements), (gst_bin_change_state), Index: gstevent.c RCS file: /cvs/gstreamer/gstreamer/gst/gstevent.c,v retrieving revision 1.48 retrieving revision 1.48.2.1 diff -u -d -r1.48 -r1.48.2.1 --- gstevent.c 7 Jul 2004 16:50:30 -0000 1.48 +++ gstevent.c 31 Dec 2004 18:18:45 -0000 1.48.2.1 @@ -220,20 +220,23 @@ * Returns: A new discontinuous event. */ GstEvent * -gst_event_new_discontinuous_valist (gboolean new_media, GstFormat format1, +gst_event_new_discontinuous_valist (gdouble rate, GstFormat format1, va_list var_args) { GstEvent *event; gint count = 0; event = gst_event_new (GST_EVENT_DISCONTINUOUS); - GST_EVENT_DISCONT_NEW_MEDIA (event) = new_media; + GST_EVENT_DISCONT_RATE (event) = rate; while (format1 != GST_FORMAT_UNDEFINED && count < 8) { GST_EVENT_DISCONT_OFFSET (event, count).format = format1 & GST_SEEK_FORMAT_MASK; - GST_EVENT_DISCONT_OFFSET (event, count).value = va_arg (var_args, gint64); + GST_EVENT_DISCONT_OFFSET (event, count).start_value = + va_arg (var_args, gint64); + GST_EVENT_DISCONT_OFFSET (event, count).end_value = format1 = va_arg (var_args, GstFormat); @@ -285,18 +288,21 @@ * format/value pair. gboolean -gst_event_discont_get_value (GstEvent * event, GstFormat format, gint64 * value) +gst_event_discont_get_value (GstEvent * event, GstFormat format, + gint64 * start_value, gint64 * end_value) gint i, n; g_return_val_if_fail (event != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); + g_return_val_if_fail (start_value != NULL, FALSE); + g_return_val_if_fail (end_value != NULL, FALSE); n = GST_EVENT_DISCONT_OFFSET_LEN (event); for (i = 0; i < n; i++) { if (GST_EVENT_DISCONT_OFFSET (event, i).format == format) { - *value = GST_EVENT_DISCONT_OFFSET (event, i).value; + *start_value = GST_EVENT_DISCONT_OFFSET (event, i).start_value; + *end_value = GST_EVENT_DISCONT_OFFSET (event, i).end_value; return TRUE; } } Index: gstevent.h RCS file: /cvs/gstreamer/gstreamer/gst/gstevent.h,v retrieving revision 1.51.2.3 retrieving revision 1.51.2.4 diff -u -d -r1.51.2.3 -r1.51.2.4 --- gstevent.h 31 Dec 2004 10:44:46 -0000 1.51.2.3 +++ gstevent.h 31 Dec 2004 18:18:45 -0000 1.51.2.4 @@ -130,7 +130,8 @@ typedef struct GstFormat format; - gint64 value; + gint64 start_value; + gint64 end_value; } GstFormatValue; #define GST_EVENT_SEEK_TYPE(event) (GST_EVENT(event)->event_data.seek.type) @@ -141,7 +142,7 @@ #define GST_EVENT_SEEK_ENDOFFSET(event) (GST_EVENT(event)->event_data.seek.endoffset) #define GST_EVENT_SEEK_ACCURACY(event) (GST_EVENT(event)->event_data.seek.accuracy) -#define GST_EVENT_DISCONT_NEW_MEDIA(event) (GST_EVENT(event)->event_data.discont.new_media) +#define GST_EVENT_DISCONT_RATE(event) (GST_EVENT(event)->event_data.discont.rate) #define GST_EVENT_DISCONT_OFFSET(event,i) (GST_EVENT(event)->event_data.discont.offsets[i]) #define GST_EVENT_DISCONT_OFFSET_LEN(event) (GST_EVENT(event)->event_data.discont.noffsets) @@ -168,7 +169,7 @@ struct { GstFormatValue offsets[8]; gint noffsets; - gboolean new_media; + gdouble rate; } discont; GstFormat format; @@ -212,10 +213,11 @@ /* discontinous event */ GstEvent* gst_event_new_discontinuous (gboolean new_media, GstFormat format1, ...); -GstEvent* gst_event_new_discontinuous_valist (gboolean new_media, +GstEvent* gst_event_new_discontinuous_valist (gdouble rate, GstFormat format1, va_list var_args); -gboolean gst_event_discont_get_value (GstEvent *event, GstFormat format, gint64 *value); +gboolean gst_event_discont_get_value (GstEvent *event, GstFormat format, + gint64 *start_value, gint64 *end_value); #define gst_event_new_filler() gst_event_new(GST_EVENT_FILLER) |
From: <wt...@fr...> - 2005-01-07 16:05:54
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Fri Jan 07 2005 08:05:53 PST Branch: BRANCH-THREADED Log message: * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (gst_element_pads_activate), (gst_element_dispose): Small cleanups, free the state mutex. Modified files: . : ChangeLog gst : gstelement.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.858.2.19&r2=1.858.2.20 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstelement.c.diff?r1=1.305.2.8&r2=1.305.2.9 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.858.2.19 retrieving revision 1.858.2.20 diff -u -d -r1.858.2.19 -r1.858.2.20 --- ChangeLog 6 Jan 2005 18:17:11 -0000 1.858.2.19 +++ ChangeLog 7 Jan 2005 16:05:41 -0000 1.858.2.20 @@ -1,3 +1,10 @@ +2005-01-07 Wim Taymans <wi...@fl...> + + * gst/gstelement.c: (gst_element_add_pad), + (gst_element_remove_pad), (gst_element_pads_activate), + (gst_element_dispose): + Small cleanups, free the state mutex. 2005-01-06 Wim Taymans <wi...@fl...> * gst/elements/gstfakesrc.c: (gst_fakesrc_loop), Index: gstelement.c RCS file: /cvs/gstreamer/gstreamer/gst/gstelement.c,v retrieving revision 1.305.2.8 retrieving revision 1.305.2.9 diff -u -d -r1.305.2.8 -r1.305.2.9 --- gstelement.c 6 Jan 2005 18:17:11 -0000 1.305.2.8 +++ gstelement.c 7 Jan 2005 16:05:41 -0000 1.305.2.9 @@ -443,6 +443,8 @@ /* locking pad to look at the name */ GST_LOCK (pad); pad_name = g_strdup (GST_PAD_NAME (pad)); + GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "adding pad '%s'", + GST_STR_NULL (pad_name)); GST_UNLOCK (pad); /* then check to see if there's already a pad by that name here */ @@ -455,9 +457,6 @@ GST_OBJECT_CAST (element)))) goto had_parent; - GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "adding pad '%s'", - GST_STR_NULL (GST_PAD_NAME (pad))); - /* add it to the list */ switch (gst_pad_get_direction (pad)) { case GST_PAD_SRC: @@ -487,6 +486,8 @@ /* emit the NEW_PAD signal */ g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad); + g_free (pad_name); return TRUE; name_exists: @@ -558,16 +559,21 @@ gboolean gst_element_remove_pad (GstElement * element, GstPad * pad) { - GstElement *current_parent; + gchar *pad_name; g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); g_return_val_if_fail (GST_IS_PAD (pad), FALSE); - current_parent = gst_pad_get_parent (pad); - if (G_UNLIKELY (current_parent != element)) - goto not_our_pad; + /* locking pad to look at the name and parent */ + GST_LOCK (pad); + pad_name = g_strdup (GST_PAD_NAME (pad)); - gst_object_unref (GST_OBJECT_CAST (current_parent)); + GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "removing pad '%s'", + if (G_UNLIKELY (GST_PAD_PARENT (pad) != element)) + goto not_our_pad; + GST_UNLOCK (pad); /* FIXME, is this redundant with pad disposal? */ if (GST_IS_REAL_PAD (pad)) { @@ -613,20 +619,19 @@ gst_object_unparent (GST_OBJECT (pad)); not_our_pad: { - gchar *parent_name = gst_element_get_name (current_parent); - gst_object_unref (GST_OBJECT (current_parent)); - GST_LOCK (pad); GST_LOCK (element); g_critical ("Padname %s:%s does not belong to element %s when removing", - parent_name, GST_PAD_NAME (pad), GST_ELEMENT_NAME (element)); + GST_ELEMENT_NAME (GST_PAD_PARENT (pad)), GST_PAD_NAME (pad), + GST_ELEMENT_NAME (element)); GST_UNLOCK (element); GST_UNLOCK (pad); - g_free (parent_name); + g_free (pad_name); return FALSE; } } @@ -2009,6 +2014,8 @@ element->state_cond = NULL; GST_STATE_UNLOCK (element); + g_mutex_free (element->state_lock); GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose parent"); G_OBJECT_CLASS (parent_class)->dispose (object); @@ -2246,6 +2253,8 @@ * * Sets the bus of the element. For internal use only, unless you're * testing elements. + * + * MT safe. */ void gst_element_set_bus (GstElement * element, GstBus * bus) @@ -2267,6 +2276,8 @@ * Returns the bus of the element. * Returns: the element's #GstBus. GstBus * gst_element_get_bus (GstElement * element) @@ -2289,6 +2300,8 @@ * Sets the scheduler of the element. For internal use only, unless you're gst_element_set_scheduler (GstElement * element, GstScheduler * scheduler) @@ -2310,6 +2323,8 @@ * Returns the scheduler of the element. * Returns: the element's #GstScheduler. GstScheduler * gst_element_get_scheduler (GstElement * element) |
From: <wt...@fr...> - 2005-01-12 18:54:57
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Wed Jan 12 2005 10:54:54 PST Branch: BRANCH-THREADED Log message: * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), (gst_bin_set_bus), (gst_bin_set_scheduler), (gst_bin_add_func), (gst_bin_iterate_elements), (gst_bin_get_state), (gst_bin_change_state), (gst_bin_get_by_name_recurse_up): * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), (gst_element_get_state_func), (gst_element_get_state), (gst_element_abort_state), (gst_element_set_state), (gst_element_pads_activate): * gst/gstelement.h: Patch state changes according to design document. Modified files: . : ChangeLog gst : gstbin.c gstelement.c gstelement.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.858.2.21&r2=1.858.2.22 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstbin.c.diff?r1=1.206.2.8&r2=1.206.2.9 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstelement.c.diff?r1=1.305.2.9&r2=1.305.2.10 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstelement.h.diff?r1=1.177.2.7&r2=1.177.2.8 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.858.2.21 retrieving revision 1.858.2.22 diff -u -d -r1.858.2.21 -r1.858.2.22 --- ChangeLog 11 Jan 2005 14:58:11 -0000 1.858.2.21 +++ ChangeLog 12 Jan 2005 18:54:42 -0000 1.858.2.22 @@ -1,3 +1,16 @@ +2005-01-12 Wim Taymans <wi...@fl...> + + * gst/gstbin.c: (gst_bin_set_index), (gst_bin_set_clock), + (gst_bin_set_bus), (gst_bin_set_scheduler), (gst_bin_add_func), + (gst_bin_iterate_elements), (gst_bin_get_state), + (gst_bin_change_state), (gst_bin_get_by_name_recurse_up): + * gst/gstelement.c: (gst_element_add_pad), + (gst_element_remove_pad), (gst_element_get_state_func), + (gst_element_get_state), (gst_element_abort_state), + (gst_element_set_state), (gst_element_pads_activate): + * gst/gstelement.h: + Patch state changes according to design document. 2005-01-11 Wim Taymans <wi...@fl...> * configure.ac: Index: gstbin.c RCS file: /cvs/gstreamer/gstreamer/gst/gstbin.c,v retrieving revision 1.206.2.8 retrieving revision 1.206.2.9 diff -u -d -r1.206.2.8 -r1.206.2.9 --- gstbin.c 6 Jan 2005 18:17:11 -0000 1.206.2.8 +++ gstbin.c 12 Jan 2005 18:54:42 -0000 1.206.2.9 @@ -53,7 +53,7 @@ static void gst_bin_dispose (GObject * object); static GstElementStateReturn gst_bin_change_state (GstElement * element); -static gboolean gst_bin_get_state (GstElement * element, +static GstElementStateReturn gst_bin_get_state (GstElement * element, GstElementState * state, GstElementState * pending, GTimeVal * timeout); #ifndef GST_DISABLE_INDEX @@ -645,12 +645,12 @@ * * MT safe */ -static gboolean +static GstElementStateReturn gst_bin_get_state (GstElement * element, GstElementState * state, GstElementState * pending, GTimeVal * timeout) { GstBin *bin = GST_BIN (element); - gboolean ret; + GstElementStateReturn ret; GList *children; guint32 children_cookie; @@ -661,7 +661,7 @@ * is still busy with its state change. */ GST_LOCK (bin); restart: - ret = TRUE; + ret = GST_STATE_SUCCESS; children = bin->children; children_cookie = bin->children_cookie; while (children) { @@ -670,13 +670,14 @@ gst_object_ref (GST_OBJECT_CAST (child)); GST_UNLOCK (bin); - /* ret is false if some child is still performing the state change */ + /* ret is ASYNC if some child is still performing the state change */ ret = gst_element_get_state (child, NULL, NULL, timeout); gst_object_unref (GST_OBJECT_CAST (child)); - if (!ret) { - /* some child is still busy, return FALSE */ + if (ret != GST_STATE_SUCCESS) { + /* some child is still busy or in error, we can report that + * right away. */ goto done; } /* now grab the lock to iterate to the next child */ @@ -692,9 +693,18 @@ done: /* now we can take the state lock */ GST_STATE_LOCK (bin); - if (ret) { - /* no async children, we can commit the state */ - gst_element_commit_state (element); + switch (ret) { + case GST_STATE_SUCCESS: + /* we can commit the state */ + gst_element_commit_state (element); + break; + case GST_STATE_FAILURE: + /* some element failed, abort the state change */ + gst_element_abort_state (element); + default: + /* other cases are just passed along */ } /* and report the state if needed */ Index: gstelement.c RCS file: /cvs/gstreamer/gstreamer/gst/gstelement.c,v retrieving revision 1.305.2.9 retrieving revision 1.305.2.10 diff -u -d -r1.305.2.9 -r1.305.2.10 --- gstelement.c 7 Jan 2005 16:05:41 -0000 1.305.2.9 +++ gstelement.c 12 Jan 2005 18:54:42 -0000 1.305.2.10 @@ -66,7 +66,7 @@ static void gst_element_dispose (GObject * object); static GstElementStateReturn gst_element_change_state (GstElement * element); -static gboolean gst_element_get_state_func (GstElement * element, +static GstElementStateReturn gst_element_get_state_func (GstElement * element, static void gst_element_set_manager_func (GstElement * element, GstPipeline * manager); @@ -1559,11 +1559,11 @@ } /* MT safe */ gst_element_get_state_func (GstElement * element, GstElementState * state, GstElementState * pending, GTimeVal * timeout) - gboolean ret = FALSE; + GstElementStateReturn ret = GST_STATE_FAILURE; GstElementState old_pending; g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); @@ -1578,10 +1578,14 @@ *state = GST_STATE (element); if (pending) *pending = GST_STATE_PENDING (element); - ret = FALSE; + ret = GST_STATE_ASYNC; } else { - /* could be success or failure, we could check here if the - * state is equal to the old pending state */ + /* could be success or failure */ + if (old_pending == GST_STATE (element)) { + ret = GST_STATE_SUCCESS; + } else { + ret = GST_STATE_FAILURE; + } /* if nothing is pending anymore we can return TRUE and @@ -1591,7 +1595,7 @@ *state = GST_STATE (element); if (pending) *pending = GST_STATE_VOID_PENDING; - ret = TRUE; + ret = GST_STATE_SUCCESS; GST_STATE_UNLOCK (element); @@ -1605,23 +1609,32 @@ * @pending: a pointer to #GstElementState to hold the pending state. * Can be NULL. * @timeout: a #GTimeVal to specify the timeout for an async - * state change. + * state change or NULL for infinite timeout. - * Gets the state of the element. + * Gets the state of the element. - * Returns: TRUE if the element has no more pending state, FALSE - * if the element is still performing a state change. + * For elements that performed an ASYNC state change, as reported by + * #gst_element_set_state(), this function will block up to the + * specified timeout value for the state change to complete. + * If the element completes the state change or goes into + * an error, this function returns immediatly with a return value of + * GST_STATE_SUCCESS or GST_STATE_FAILURE respectively. + * + * Returns: GST_STATE_SUCCESS if the element has no more pending state and + * the last state change succeeded, GST_STATE_ASYNC + * if the element is still performing a state change or + * GST_STATE_FAILURE if the last state change failed. * MT safe. -gboolean +GstElementStateReturn gst_element_get_state (GstElement * element, GstElementClass *oclass; - gboolean result = FALSE; + GstElementStateReturn result = GST_STATE_FAILURE; - g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); + g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE); oclass = GST_ELEMENT_GET_CLASS (element); @@ -1652,14 +1665,14 @@ pending = GST_STATE_PENDING (element); - if (pending != GST_STATE_VOID_PENDING) { + if (pending != GST_STATE_VOID_PENDING && !GST_STATE_ERROR (element)) { GstElementState old_state = GST_STATE (element); GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "aborting state from %s to %s", gst_element_state_get_name (old_state), gst_element_state_get_name (pending)); - GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING; + GST_STATE_ERROR (element) = TRUE; GST_STATE_BROADCAST (element); @@ -1726,6 +1739,9 @@ /* get the element state lock */ GST_STATE_LOCK (element); + /* clear the error flag */ + GST_STATE_ERROR (element) = FALSE; /* start with the current state */ current = GST_STATE (element); @@ -1749,17 +1765,11 @@ /* set the pending state variable */ GST_STATE_PENDING (element) = pending; - if (pending != state) { - GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, - "intermediate: setting state from %s to %s", - gst_element_state_get_name (current), - gst_element_state_get_name (pending)); - } else { - "final: setting state from %s to %s", - } + GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, + "%s: setting state from %s to %s", + (pending != state ? "intermediate" : "final"), + gst_element_state_get_name (current), + gst_element_state_get_name (pending)); /* call the state change function so it can set the state */ if (oclass->change_state) Index: gstelement.h RCS file: /cvs/gstreamer/gstreamer/gst/gstelement.h,v retrieving revision 1.177.2.7 retrieving revision 1.177.2.8 diff -u -d -r1.177.2.7 -r1.177.2.8 --- gstelement.h 6 Jan 2005 18:17:11 -0000 1.177.2.7 +++ gstelement.h 12 Jan 2005 18:54:42 -0000 1.177.2.8 @@ -66,6 +66,7 @@ #define GST_STATE(obj) (GST_ELEMENT(obj)->current_state) #define GST_STATE_PENDING(obj) (GST_ELEMENT(obj)->pending_state) +#define GST_STATE_ERROR(obj) (GST_ELEMENT(obj)->state_error) /* Note: using 8 bit shift mostly "just because", it leaves us enough room to grow <g> */ #define GST_STATE_TRANSITION(obj) ((GST_STATE(obj)<<8) | GST_STATE_PENDING(obj)) @@ -173,32 +174,34 @@ /*< public > *//* with STATE_LOCK */ /* element state */ - GMutex *state_lock; - GCond *state_cond; - guint8 current_state; - guint8 pending_state; + GMutex *state_lock; + GCond *state_cond; + guint8 current_state; + guint8 pending_state; + gboolean state_error; /* flag is set when the element has an error in the last state + change. it is cleared when doing another state change. */ /*< public > *//* with LOCK */ /* element manager */ - GstPipeline *manager; - GstBus *bus; + GstPipeline *manager; + GstBus *bus; GstScheduler *scheduler; /* private pointer for the scheduler */ - gpointer sched_private; + gpointer sched_private; /* allocated clock */ - GstClock *clock; - GstClockTimeDiff base_time; /* NULL/READY: 0 - PAUSED: current time - PLAYING: difference to clock */ + GstClock *clock; + GstClockTimeDiff base_time; /* NULL/READY: 0 - PAUSED: current time - PLAYING: difference to clock */ /* element pads, these lists can only be iterated while holding * the LOCK or checking the cookie after each LOCK. */ - guint16 numpads; - GList *pads; - guint16 numsrcpads; - GList *srcpads; - guint16 numsinkpads; - GList *sinkpads; - guint32 pads_cookie; + guint16 numpads; + GList *pads; + guint16 numsrcpads; + GList *srcpads; + guint16 numsinkpads; + GList *sinkpads; + guint32 pads_cookie; /*< private > */ gpointer _gst_reserved[GST_PADDING]; @@ -236,9 +239,9 @@ void (*release_pad) (GstElement * element, GstPad * pad); /* state changes */ - gboolean (*get_state) (GstElement * element, GstElementState * state, - GstElementState * pending, GTimeVal * timeout); - GstElementStateReturn (*change_state) (GstElement * element); + GstElementStateReturn (*get_state) (GstElement * element, GstElementState * state, + GstElementState * pending, GTimeVal * timeout); + GstElementStateReturn (*change_state) (GstElement * element); /* manager */ void (*set_manager) (GstElement * element, GstPipeline * pipeline); @@ -353,18 +356,20 @@ const gchar * function, gint line); /* state management */ -gboolean gst_element_is_locked_state (GstElement * element); -gboolean gst_element_set_locked_state (GstElement * element, - gboolean locked_state); -gboolean gst_element_sync_state_with_parent (GstElement * element); +gboolean gst_element_is_locked_state (GstElement * element); +gboolean gst_element_set_locked_state (GstElement * element, + gboolean locked_state); +gboolean gst_element_sync_state_with_parent (GstElement * element); -gboolean gst_element_get_state (GstElement * element, GstElementState * state, - GstElementState * pending, GTimeVal * timeout); -GstElementStateReturn gst_element_set_state (GstElement * element, - GstElementState state); +GstElementStateReturn gst_element_get_state (GstElement * element, + GstElementState * state, + GstElementState * pending, + GTimeVal * timeout); +GstElementStateReturn gst_element_set_state (GstElement * element, + GstElementState state); -void gst_element_abort_state (GstElement * element); -void gst_element_commit_state (GstElement * element); +void gst_element_abort_state (GstElement * element); +void gst_element_commit_state (GstElement * element); /* factory management */ GstElementFactory *gst_element_get_factory (GstElement * element); |
From: <wt...@fr...> - 2005-02-03 17:05:43
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Thu Feb 03 2005 09:05:34 PST Branch: BRANCH-THREADED Log message: * gst/gstcaps.c: (gst_caps_intersect): * gst/gstclock.c: (gst_clock_id_ref), (gst_clock_id_unref), (gst_clock_id_compare_func), (gst_clock_id_wait), (gst_clock_id_wait_async), (gst_clock_init), (gst_clock_adjust_unlocked), (gst_clock_get_time): * gst/gstinfo.c: * gst/gstobject.c: (gst_object_class_init), (gst_object_ref), (gst_object_unref), (gst_object_sink), (gst_object_dispose), (gst_object_dispatch_properties_changed), (gst_object_set_name), (gst_object_set_parent), (gst_object_unparent), (gst_object_check_uniqueness), (gst_object_get_path_string): * gst/gstutils.c: (gst_element_finish_preroll), (gst_element_get_compatible_pad_filtered), (gst_element_link_pads_filtered), (gst_element_unlink), (gst_pad_use_fixed_caps), (gst_pad_get_fixed_caps_func): * gst/gstutils.h: Inline refcounting.. not sure why it wasn't before. Added use_fixed_caps method to change default getcaps behaviour. Modified files: . : ChangeLog gst : gstcaps.c gstclock.c gstinfo.c gstobject.c gstutils.c gstutils.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.858.2.28&r2=1.858.2.29 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstcaps.c.diff?r1=1.127.2.3&r2=1.127.2.4 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstclock.c.diff?r1=1.49.2.6&r2=1.49.2.7 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstinfo.c.diff?r1=1.94.2.1&r2=1.94.2.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstobject.c.diff?r1=1.79.2.11&r2=1.79.2.12 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstutils.c.diff?r1=1.48.2.8&r2=1.48.2.9 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstutils.h.diff?r1=1.26.2.2&r2=1.26.2.3 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.858.2.28 retrieving revision 1.858.2.29 diff -u -d -r1.858.2.28 -r1.858.2.29 --- ChangeLog 1 Feb 2005 17:26:43 -0000 1.858.2.28 +++ ChangeLog 3 Feb 2005 17:05:21 -0000 1.858.2.29 @@ -1,3 +1,25 @@ +2005-02-03 Wim Taymans <wi...@fl...> + + * gst/gstcaps.c: (gst_caps_intersect): + * gst/gstclock.c: (gst_clock_id_ref), (gst_clock_id_unref), + (gst_clock_id_compare_func), (gst_clock_id_wait), + (gst_clock_id_wait_async), (gst_clock_init), + (gst_clock_adjust_unlocked), (gst_clock_get_time): + * gst/gstinfo.c: + * gst/gstobject.c: (gst_object_class_init), (gst_object_ref), + (gst_object_unref), (gst_object_sink), (gst_object_dispose), + (gst_object_dispatch_properties_changed), (gst_object_set_name), + (gst_object_set_parent), (gst_object_unparent), + (gst_object_check_uniqueness), (gst_object_get_path_string): + * gst/gstutils.c: (gst_element_finish_preroll), + (gst_element_get_compatible_pad_filtered), + (gst_element_link_pads_filtered), (gst_element_unlink), + (gst_pad_use_fixed_caps), (gst_pad_get_fixed_caps_func): + * gst/gstutils.h: + Inline refcounting.. not sure why it wasn't before. + Added use_fixed_caps method to change default getcaps + behaviour. 2005-02-01 Ronald S. Bultje <rb...@ro...> * gst/gstelement.h: Index: gstcaps.c RCS file: /cvs/gstreamer/gstreamer/gst/gstcaps.c,v retrieving revision 1.127.2.3 retrieving revision 1.127.2.4 diff -u -d -r1.127.2.3 -r1.127.2.4 --- gstcaps.c 20 Dec 2004 16:07:04 -0000 1.127.2.3 +++ gstcaps.c 3 Feb 2005 17:05:21 -0000 1.127.2.4 @@ -24,6 +24,7 @@ #include <signal.h> #include "gst_private.h" +#include "gstatomic_impl.h" #include <gst/gst.h> //#define DEBUG_REFCOUNT Index: gstclock.c RCS file: /cvs/gstreamer/gstreamer/gst/gstclock.c,v retrieving revision 1.49.2.6 retrieving revision 1.49.2.7 diff -u -d -r1.49.2.6 -r1.49.2.7 --- gstclock.c 26 Jan 2005 10:56:08 -0000 1.49.2.6 +++ gstclock.c 3 Feb 2005 17:05:21 -0000 1.49.2.7 @@ -28,6 +28,7 @@ #include "gstclock.h" #include "gstinfo.h" #include "gstmemchunk.h" #ifndef GST_DISABLE_TRACE /* #define GST_WITH_ALLOC_TRACE */ Index: gstinfo.c RCS file: /cvs/gstreamer/gstreamer/gst/gstinfo.c,v retrieving revision 1.94.2.1 retrieving revision 1.94.2.2 diff -u -d -r1.94.2.1 -r1.94.2.2 --- gstinfo.c 8 Dec 2004 17:40:36 -0000 1.94.2.1 +++ gstinfo.c 3 Feb 2005 17:05:21 -0000 1.94.2.2 @@ -41,6 +41,7 @@ #include "gstpad.h" #include "gstscheduler.h" #ifdef HAVE_VALGRIND #include <valgrind/valgrind.h> #endif Index: gstobject.c RCS file: /cvs/gstreamer/gstreamer/gst/gstobject.c,v retrieving revision 1.79.2.11 retrieving revision 1.79.2.12 diff -u -d -r1.79.2.11 -r1.79.2.12 --- gstobject.c 26 Jan 2005 10:56:08 -0000 1.79.2.11 +++ gstobject.c 3 Feb 2005 17:05:21 -0000 1.79.2.12 @@ -26,6 +26,7 @@ #include "gstobject.h" #include "gstmarshal.h" #include "gsttrace.h" Index: gstutils.c RCS file: /cvs/gstreamer/gstreamer/gst/gstutils.c,v retrieving revision 1.48.2.8 retrieving revision 1.48.2.9 diff -u -d -r1.48.2.8 -r1.48.2.9 --- gstutils.c 1 Feb 2005 17:26:44 -0000 1.48.2.8 +++ gstutils.c 3 Feb 2005 17:05:21 -0000 1.48.2.9 @@ -1339,6 +1339,68 @@ } /** + * gst_pad_use_fixed_caps: + * @pad: the pad to use + * + * A helper function you can use that sets the + * @gst_pad_get_fixed_caps_func as the gstcaps function for the + * pad. This way the function will always return the negotiated caps + * or in case the pad is not negotiated, the padtemplate caps. + */ +void +gst_pad_use_fixed_caps (GstPad * pad) +{ + gst_pad_set_getcaps_function (pad, gst_pad_get_fixed_caps_func); +} +/** + * gst_pad_get_fixed_caps_func: + * A helper function you can use as a GetCaps function that + * will return the currently negotiated caps or the padtemplate + * when NULL. + * Returns: The currently negotiated caps or the padtemplate. +GstCaps * +gst_pad_get_fixed_caps_func (GstPad * pad) + GstCaps *result; + GstRealPad *realpad; + g_return_val_if_fail (GST_IS_REAL_PAD (pad), NULL); + realpad = GST_REAL_PAD_CAST (pad); + if (GST_RPAD_CAPS (realpad)) { + result = GST_RPAD_CAPS (realpad); + GST_CAT_DEBUG (GST_CAT_CAPS, + "using pad caps %p %" GST_PTR_FORMAT, result, result); + result = gst_caps_ref (result); + goto done; + } + if (GST_PAD_PAD_TEMPLATE (realpad)) { + GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (realpad); + result = GST_PAD_TEMPLATE_CAPS (templ); + "using pad template %p with caps %p %" GST_PTR_FORMAT, templ, result, + result); + GST_CAT_DEBUG (GST_CAT_CAPS, "pad has no caps"); + result = gst_caps_new_empty (); +done: + return result; * gst_object_default_error: * @object: a #GObject that signalled the error. * @orig: the #GstObject that initiated the error. Index: gstutils.h RCS file: /cvs/gstreamer/gstreamer/gst/gstutils.h,v retrieving revision 1.26.2.2 retrieving revision 1.26.2.3 diff -u -d -r1.26.2.2 -r1.26.2.3 --- gstutils.h 1 Feb 2005 17:26:44 -0000 1.26.2.2 +++ gstutils.h 3 Feb 2005 17:05:21 -0000 1.26.2.3 @@ -265,6 +265,8 @@ gboolean gst_pad_can_link (GstPad *srcpad, GstPad *sinkpad); gboolean gst_pad_can_link_filtered (GstPad *srcpad, GstPad *sinkpad, const GstCaps *filtercaps); +void gst_pad_use_fixed_caps (GstPad *pad); +GstCaps* gst_pad_get_fixed_caps_func (GstPad *pad); /* bin functions */ void gst_bin_add_many (GstBin *bin, GstElement *element_1, ...); |
From: <wt...@fr...> - 2005-02-11 16:45:10
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Fri Feb 11 2005 08:45:09 PST Branch: BRANCH-THREADED Log message: * gst/gstevent.c: (gst_event_new_discontinuous_valist), (gst_event_discont_get_value), (gst_event_new_segment_seek): stop time can be -1. Modified files: . : ChangeLog gst : gstevent.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.858.2.44&r2=1.858.2.45 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstevent.c.diff?r1=1.48.2.4&r2=1.48.2.5 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.858.2.44 retrieving revision 1.858.2.45 diff -u -d -r1.858.2.44 -r1.858.2.45 --- ChangeLog 11 Feb 2005 16:39:13 -0000 1.858.2.44 +++ ChangeLog 11 Feb 2005 16:44:57 -0000 1.858.2.45 @@ -1,3 +1,9 @@ +2005-02-11 Wim Taymans <wi...@fl...> + + * gst/gstevent.c: (gst_event_new_discontinuous_valist), + (gst_event_discont_get_value), (gst_event_new_segment_seek): + stop time can be -1. 2005-02-11 Thomas Vander Stichele <thomas at apestaart dot org> * docs/gst/gstreamer-sections.txt: Index: gstevent.c RCS file: /cvs/gstreamer/gstreamer/gst/gstevent.c,v retrieving revision 1.48.2.4 retrieving revision 1.48.2.5 diff -u -d -r1.48.2.4 -r1.48.2.5 --- gstevent.c 11 Feb 2005 15:50:52 -0000 1.48.2.4 +++ gstevent.c 11 Feb 2005 16:44:57 -0000 1.48.2.5 @@ -352,7 +352,7 @@ { GstEvent *event; - g_return_val_if_fail (start < stop, NULL); + g_return_val_if_fail (start < stop || stop == -1, NULL); event = gst_event_new (GST_EVENT_SEEK); |
From: <wt...@fr...> - 2005-03-07 18:29:52
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Mon Mar 07 2005 10:29:49 PST Log message: * gst/gstiterator.c: (gst_iterator_init), (gst_iterator_new), (gst_list_iterator_next), (gst_list_iterator_resync), (gst_list_iterator_free), (gst_iterator_new_list), (gst_iterator_pop), (gst_iterator_next), (gst_iterator_resync), (gst_iterator_free), (gst_iterator_push), (filter_next), (filter_resync), (filter_uninit), (filter_free), (gst_iterator_filter), (gst_iterator_fold), (foreach_fold_func), (gst_iterator_foreach), (find_custom_fold_func), (gst_iterator_find_custom): * gst/gstiterator.h: Added missing files. Modified files: . : ChangeLog gst : gstiterator.c gstiterator.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.978&r2=1.979 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstiterator.c.diff?r1=1.1&r2=1.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstiterator.h.diff?r1=1.1&r2=1.2 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.978 retrieving revision 1.979 diff -u -d -r1.978 -r1.979 --- ChangeLog 7 Mar 2005 18:27:37 -0000 1.978 +++ ChangeLog 7 Mar 2005 18:29:36 -0000 1.979 @@ -1,5 +1,19 @@ 2005-03-07 Wim Taymans <wi...@fl...> + * gst/gstiterator.c: (gst_iterator_init), (gst_iterator_new), + (gst_list_iterator_next), (gst_list_iterator_resync), + (gst_list_iterator_free), (gst_iterator_new_list), + (gst_iterator_pop), (gst_iterator_next), (gst_iterator_resync), + (gst_iterator_free), (gst_iterator_push), (filter_next), + (filter_resync), (filter_uninit), (filter_free), + (gst_iterator_filter), (gst_iterator_fold), (foreach_fold_func), + (gst_iterator_foreach), (find_custom_fold_func), + (gst_iterator_find_custom): + * gst/gstiterator.h: + Added missing files. + +2005-03-07 Wim Taymans <wi...@fl...> * Makefile.am: * configure.ac: * docs/design/part-MT-refcounting.txt: Index: gstiterator.c RCS file: gstiterator.c diff -N gstiterator.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gstiterator.c 7 Mar 2005 18:29:36 -0000 1.2 @@ -0,0 +1,549 @@ +/* GStreamer + * Copyright (C) 2004 Wim Taymans <wi...@fl...> + * + * gstiterator.h: Base class for iterating datastructures. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#include "gst_private.h" +#include <gst/gstiterator.h> +static void +gst_iterator_init (GstIterator * it, + GMutex * lock, + guint32 * master_cookie, + GstIteratorNextFunction next, + GstIteratorItemFunction item, + GstIteratorResyncFunction resync, GstIteratorFreeFunction free) +{ + it->lock = lock; + it->master_cookie = master_cookie; + it->cookie = *master_cookie; + it->next = next; + it->item = item; + it->resync = resync; + it->free = free; + it->pushed = NULL; +} +/** + * gst_iterator_new: + * @size: the size of the iterator structure + * @lock: pointer to a #GMutex. + * @master_cookie: pointer to a guint32 to protect the iterated object. + * @next: function to get next item + * @item: function to call on each item retrieved + * @resync: function to resync the iterator + * @free: function to free the iterator + * Create a new iterator. This function is mainly used for objects + * implementing the next/resync/free function to iterate a data structure. + * + * Returns: the new #GstIterator. + * MT safe. +GstIterator * +gst_iterator_new (guint size, + GstIterator *result; + g_return_val_if_fail (size >= sizeof (GstIterator), NULL); + g_return_val_if_fail (master_cookie != NULL, NULL); + g_return_val_if_fail (next != NULL, NULL); + g_return_val_if_fail (resync != NULL, NULL); + g_return_val_if_fail (free != NULL, NULL); + result = g_malloc (size); + gst_iterator_init (result, lock, master_cookie, next, item, resync, free); + return result; +/* + * list iterator +typedef struct _GstListIterator + GstIterator iterator; + gpointer owner; + GList **orig; + GList *list; /* pointer in list */ + GstIteratorDisposeFunction freefunc; +} GstListIterator; +static GstIteratorResult +gst_list_iterator_next (GstListIterator * it, gpointer * elem) + if (it->list == NULL) + return GST_ITERATOR_DONE; + *elem = it->list->data; + it->list = g_list_next (it->list); + return GST_ITERATOR_OK; +gst_list_iterator_resync (GstListIterator * it) + it->list = *it->orig; +gst_list_iterator_free (GstListIterator * it) + if (it->freefunc) { + it->freefunc (it->owner); + } + g_free (it); + * gst_iterator_new_list: + * @lock: pointer to a #GMutex protecting the list. + * @master_cookie: pointer to a guint32 to protect the list. + * @list: pointer to the list + * @owner: object owning the list + * @ref: function to ref each item + * @unref: function to unref each item + * @free: function to free the owner of the list + * Create a new iterator designed for iterating @list. + * Returns: the new #GstIterator for @list. +gst_iterator_new_list (GMutex * lock, + GList ** list, + gpointer owner, + GstIteratorItemFunction item, GstIteratorDisposeFunction free) + GstListIterator *result; + /* no need to lock, nothing can change here */ + result = (GstListIterator *) gst_iterator_new (sizeof (GstListIterator), + lock, + master_cookie, + (GstIteratorNextFunction) gst_list_iterator_next, + (GstIteratorItemFunction) item, + (GstIteratorResyncFunction) gst_list_iterator_resync, + (GstIteratorFreeFunction) gst_list_iterator_free); + result->owner = owner; + result->orig = list; + result->list = *list; + result->freefunc = free; + return GST_ITERATOR (result); +gst_iterator_pop (GstIterator * it) + if (it->pushed) { + gst_iterator_free (it->pushed); + it->pushed = NULL; + * gst_iterator_next: + * @it: The #GstIterator to iterate + * @elem: pointer to hold next element + * Get the next item from the iterator. + * Returns: The result of the iteration. +GstIteratorResult +gst_iterator_next (GstIterator * it, gpointer * elem) + GstIteratorResult result; + g_return_val_if_fail (it != NULL, GST_ITERATOR_ERROR); + g_return_val_if_fail (elem != NULL, GST_ITERATOR_ERROR); +restart: + result = gst_iterator_next (it->pushed, elem); + if (result == GST_ITERATOR_DONE) { + /* we are done with this iterator, pop it and + * fallthrough iterating the main iterator again. */ + gst_iterator_pop (it); + } else { + return result; + } + if (G_LIKELY (it->lock)) + g_mutex_lock (it->lock); + if (G_UNLIKELY (*it->master_cookie != it->cookie)) { + result = GST_ITERATOR_RESYNC; + goto done; + result = it->next (it, elem); + if (result == GST_ITERATOR_OK && it->item) { + GstIteratorItem itemres; + itemres = it->item (it, *elem); + switch (itemres) { + case GST_ITERATOR_ITEM_SKIP: + if (G_LIKELY (it->lock)) + g_mutex_unlock (it->lock); + goto restart; + case GST_ITERATOR_ITEM_END: + result = GST_ITERATOR_DONE; + break; + case GST_ITERATOR_ITEM_PASS: +done: + g_mutex_unlock (it->lock); + * gst_iterator_resync: + * @it: The #GstIterator to resync + * Resync the iterator. this function is mostly called + * after #gst_iterator_next() returned #GST_ITERATOR_RESYNC. +void +gst_iterator_resync (GstIterator * it) + g_return_if_fail (it != NULL); + gst_iterator_pop (it); + it->resync (it); + it->cookie = *it->master_cookie; + * gst_iterator_free: + * @it: The #GstIterator to free + * Free the iterator. +gst_iterator_free (GstIterator * it) + it->free (it); + * gst_iterator_push: + * @it: The #GstIterator to use + * @other: The #GstIterator to push + * Pushes @other iterator onto @it. All calls performed on @it are + * forwarded tot @other. If @other returns #GST_ITERATOR_DONE, it is + * popped again and calls are handled by @it again. + * This function is mainly used by objects implementing the iterator + * next function to recurse into substructures. +gst_iterator_push (GstIterator * it, GstIterator * other) + g_return_if_fail (other != NULL); + it->pushed = other; +typedef struct _GstIteratorFilter + GstIterator *slave; + GCompareFunc func; + gpointer user_data; +} GstIteratorFilter; +filter_next (GstIteratorFilter * it, gpointer * elem) + GstIteratorResult result = GST_ITERATOR_ERROR; + gboolean done = FALSE; + *elem = NULL; + while (G_LIKELY (!done)) { + gpointer item; + result = gst_iterator_next (it->slave, &item); + switch (result) { + case GST_ITERATOR_OK: + if (G_LIKELY (GST_ITERATOR (it)->lock)) + g_mutex_unlock (GST_ITERATOR (it)->lock); + if (it->func (item, it->user_data) == 0) { + *elem = item; + done = TRUE; + } + g_mutex_lock (GST_ITERATOR (it)->lock); + case GST_ITERATOR_RESYNC: + case GST_ITERATOR_DONE: + done = TRUE; + default: + g_assert_not_reached (); +filter_resync (GstIteratorFilter * it) + gst_iterator_resync (it->slave); +filter_uninit (GstIteratorFilter * it) + it->slave->lock = GST_ITERATOR (it)->lock; +filter_free (GstIteratorFilter * it) + filter_uninit (it); + gst_iterator_free (it->slave); + * gst_iterator_filter: + * @it: The #GstIterator to filter + * @user_data: user data passed to the compare function + * @func: the compare function to select elements + * Create a new iterator from an existing iterator. The new iterator + * will only return those elements that match the given compare function. + * The GCompareFunc should return 0 for elements that should be included + * in the iterator. + * When this iterator is freed, @it will also be freed. + * Returns: a new #GstIterator. +gst_iterator_filter (GstIterator * it, GCompareFunc func, gpointer user_data) + GstIteratorFilter *result; + g_return_val_if_fail (it != NULL, NULL); + g_return_val_if_fail (func != NULL, NULL); + result = (GstIteratorFilter *) gst_iterator_new (sizeof (GstIteratorFilter), + it->lock, it->master_cookie, + (GstIteratorNextFunction) filter_next, + (GstIteratorItemFunction) NULL, + (GstIteratorResyncFunction) filter_resync, + (GstIteratorFreeFunction) filter_free); + it->lock = NULL; + result->func = func; + result->user_data = user_data; + result->slave = it; + * gst_iterator_fold: + * @iter: The #GstIterator to fold over + * @func: the fold function + * @ret: the seed value passed to the fold function + * @user_data: user data passed to the fold function + * Folds @func over the elements of @iter. That is to say, @proc will be called + * as @proc (object, @ret, @user_data) for each object in @iter. The normal use + * of this procedure is to accumulate the results of operating on the objects in + * @ret. + * This procedure can be used (and is used internally) to implement the foreach + * and find_custom operations. + * The fold will proceed as long as @func returns TRUE. When the iterator has no + * more arguments, GST_ITERATOR_DONE will be returned. If @func returns FALSE, + * the fold will stop, and GST_ITERATOR_OK will be returned. Errors or resyncs + * will cause fold to return GST_ITERATOR_ERROR or GST_ITERATOR_RESYNC as + * appropriate. + * The iterator will not be freed. + * Returns: A #GstIteratorResult, as described above. +gst_iterator_fold (GstIterator * iter, GstIteratorFoldFunction func, + GValue * ret, gpointer user_data) + gpointer item; + while (1) { + result = gst_iterator_next (iter, &item); + /* fixme: is there a way to ref/unref items? */ + if (!func (item, ret, user_data)) + goto fold_done; + else + break; + case GST_ITERATOR_ERROR: + goto fold_done; +fold_done: +typedef struct + GFunc func; +} ForeachFoldData; +static gboolean +foreach_fold_func (gpointer item, GValue * unused, ForeachFoldData * data) + data->func (item, data->user_data); + return TRUE; + * gst_iterator_foreach: + * @function: the function to call for each element. + * @user_data: user data passed to the function + * Iterate over all element of @it and call the given function for + * each element. + * Returns: the result call to gst_iterator_fold(). The iterator will not be + * freed. +gst_iterator_foreach (GstIterator * iter, GFunc func, gpointer user_data) + ForeachFoldData data; + data.func = func; + data.user_data = user_data; + return gst_iterator_fold (iter, (GstIteratorFoldFunction) foreach_fold_func, + NULL, &data); +} FindCustomFoldData; +find_custom_fold_func (gpointer item, GValue * ret, FindCustomFoldData * data) + if (data->func (item, data->user_data)) { + g_value_set_pointer (ret, item); + return FALSE; + } else { + return TRUE; + * gst_iterator_find_custom: + * @func: the compare function to use + * Find the first element in @it that matches the compare function. + * The compare function should return 0 when the element is found. + * Returns: The element in the iterator that matches the compare + * function or NULL when no element matched. +gpointer +gst_iterator_find_custom (GstIterator * iter, GCompareFunc func, + gpointer user_data) + GValue ret = { 0, }; + GstIteratorResult res; + FindCustomFoldData data; + g_value_init (&ret, G_TYPE_POINTER); + res = + gst_iterator_fold (iter, (GstIteratorFoldFunction) find_custom_fold_func, + &ret, &data); + /* no need to unset, it's just a pointer */ + return g_value_get_pointer (&ret); Index: gstiterator.h RCS file: gstiterator.h diff -N gstiterator.h +++ gstiterator.h 7 Mar 2005 18:29:36 -0000 1.2 @@ -0,0 +1,108 @@ + * gstiterator.h: Header for GstIterator +#ifndef __GST_ITERATOR_H__ +#define __GST_ITERATOR_H__ +#include <glib.h> +G_BEGIN_DECLS +typedef enum { + GST_ITERATOR_DONE = 0, /* no more items in the iterator */ + GST_ITERATOR_OK = 1, /* item retrieved */ + GST_ITERATOR_RESYNC = 2, /* datastructures changed while iterating */ + GST_ITERATOR_ERROR = 3, /* some error happened */ +} GstIteratorResult; +typedef struct _GstIterator GstIterator; + GST_ITERATOR_ITEM_SKIP = 0, /* skip item */ + GST_ITERATOR_ITEM_PASS = 1, /* return item */ + GST_ITERATOR_ITEM_END = 2, /* stop after this item */ +} GstIteratorItem; +typedef void (*GstIteratorDisposeFunction) (gpointer owner); +typedef GstIteratorResult (*GstIteratorNextFunction) (GstIterator *it, gpointer *result); +typedef GstIteratorItem (*GstIteratorItemFunction) (GstIterator *it, gpointer item); +typedef void (*GstIteratorResyncFunction) (GstIterator *it); +typedef void (*GstIteratorFreeFunction) (GstIterator *it); +typedef gboolean (*GstIteratorFoldFunction) (gpointer item, GValue *ret, gpointer user_data); +#define GST_ITERATOR(it) ((GstIterator*)(it)) +#define GST_ITERATOR_LOCK(it) (GST_ITERATOR(it)->lock) +#define GST_ITERATOR_COOKIE(it) (GST_ITERATOR(it)->cookie) +#define GST_ITERATOR_ORIG_COOKIE(it) (GST_ITERATOR(it)->master_cookie) +struct _GstIterator { + GstIteratorNextFunction next; + GstIteratorItemFunction item; + GstIteratorResyncFunction resync; + GstIteratorFreeFunction free; + GstIterator *pushed; /* pushed iterator */ + GMutex *lock; + guint32 cookie; /* cookie of the iterator */ + guint32 *master_cookie; /* pointer to guint32 holding the cookie when this + iterator was created */ +}; + +/* creating iterators */ +GstIterator* gst_iterator_new (guint size, + GMutex *lock, + guint32 *master_cookie, + GstIteratorNextFunction next, + GstIteratorItemFunction item, + GstIteratorResyncFunction resync, + GstIteratorFreeFunction free); +GstIterator* gst_iterator_new_list (GMutex *lock, + GList **list, + gpointer owner, + GstIteratorDisposeFunction free); +/* using iterators */ +GstIteratorResult gst_iterator_next (GstIterator *it, gpointer *result); +void gst_iterator_resync (GstIterator *it); +void gst_iterator_free (GstIterator *it); +void gst_iterator_push (GstIterator *it, GstIterator *other); +/* higher-order functions that operate on iterators */ +GstIterator* gst_iterator_filter (GstIterator *it, GCompareFunc func, + gpointer user_data); +GstIteratorResult gst_iterator_fold (GstIterator *iter, + GstIteratorFoldFunction func, + GValue *ret, gpointer user_data); +GstIteratorResult gst_iterator_foreach (GstIterator *iter, + GFunc func, gpointer user_data); +gpointer gst_iterator_find_custom (GstIterator *it, GCompareFunc func, +G_END_DECLS +#endif /* __GST_ITERATOR_H__ */ |
From: <wt...@fr...> - 2005-03-09 11:08:31
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Wed Mar 09 2005 03:08:30 PST Log message: * configure.ac: * gst/gst_private.h: * gst/gstbin.c: (gst_bin_add_func), (gst_bin_add), (gst_bin_remove_func), (gst_bin_remove), (gst_bin_get_by_name_recurse_up): * gst/gstclock.c: (gst_clock_id_ref), (gst_clock_id_unref), (gst_clock_id_compare_func), (gst_clock_id_wait), (gst_clock_id_wait_async), (gst_clock_init), (gst_clock_adjust_unlocked), (gst_clock_get_time): * gst/gstelement.h: * gst/gstinfo.c: (_gst_debug_init): * gst/gstobject.h: * gst/gstpad.c: (_gst_pad_default_fixate_foreach), (gst_pad_collectv), (gst_pad_collect_valist), (gst_pad_query): * gst/gstpad.h: Bump version number, we're now 0.9.0 Add future debugging category. Fix NULL _unref() in _get_by_name_recurse_up Rearrange gstpad.h. Update some docs. Modified files: . : ChangeLog configure.ac gst : gst_private.h gstbin.c gstclock.c gstelement.h gstinfo.c gstobject.h gstpad.c gstpad.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.983&r2=1.984 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/configure.ac.diff?r1=1.350&r2=1.351 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gst_private.h.diff?r1=1.19&r2=1.20 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstbin.c.diff?r1=1.212&r2=1.213 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstclock.c.diff?r1=1.50&r2=1.51 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstelement.h.diff?r1=1.181&r2=1.182 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstinfo.c.diff?r1=1.99&r2=1.100 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstobject.h.diff?r1=1.49&r2=1.50 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstpad.c.diff?r1=1.358&r2=1.359 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstpad.h.diff?r1=1.156&r2=1.157 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.983 retrieving revision 1.984 diff -u -d -r1.983 -r1.984 --- ChangeLog 8 Mar 2005 17:42:28 -0000 1.983 +++ ChangeLog 9 Mar 2005 11:08:17 -0000 1.984 @@ -1,3 +1,26 @@ +2005-03-09 Wim Taymans <wi...@fl...> + + * configure.ac: + * gst/gst_private.h: + * gst/gstbin.c: (gst_bin_add_func), (gst_bin_add), + (gst_bin_remove_func), (gst_bin_remove), + (gst_bin_get_by_name_recurse_up): + * gst/gstclock.c: (gst_clock_id_ref), (gst_clock_id_unref), + (gst_clock_id_compare_func), (gst_clock_id_wait), + (gst_clock_id_wait_async), (gst_clock_init), + (gst_clock_adjust_unlocked), (gst_clock_get_time): + * gst/gstelement.h: + * gst/gstinfo.c: (_gst_debug_init): + * gst/gstobject.h: + * gst/gstpad.c: (_gst_pad_default_fixate_foreach), + (gst_pad_collectv), (gst_pad_collect_valist), (gst_pad_query): + * gst/gstpad.h: + Bump version number, we're now 0.9.0 + Add future debugging category. + Fix NULL _unref() in _get_by_name_recurse_up + Rearrange gstpad.h. + Update some docs. 2005-03-08 Wim Taymans <wi...@fl...> * gst/elements/gstaggregator.c: (gst_aggregator_class_init): Index: configure.ac RCS file: /cvs/gstreamer/gstreamer/configure.ac,v retrieving revision 1.350 retrieving revision 1.351 diff -u -d -r1.350 -r1.351 --- configure.ac 7 Mar 2005 18:27:37 -0000 1.350 +++ configure.ac 9 Mar 2005 11:08:17 -0000 1.351 @@ -3,7 +3,7 @@ dnl when going to/from release please set the nano (fourth number) right ! dnl releases only do Wall, cvs and prerelease does Werror too -AS_VERSION(gstreamer, GST_VERSION, 0, 8, 90, 1, GST_CVS="no", GST_CVS="yes") +AS_VERSION(gstreamer, GST_VERSION, 0, 9, 0, 1, GST_CVS="no", GST_CVS="yes") dnl AM_MAINTAINER_MODE only provides the option to configure to enable it AM_MAINTAINER_MODE Index: gst_private.h RCS file: /cvs/gstreamer/gstreamer/gst/gst_private.h,v retrieving revision 1.19 retrieving revision 1.20 diff -u -d -r1.19 -r1.20 --- gst_private.h 13 Jan 2005 16:50:49 -0000 1.19 +++ gst_private.h 9 Mar 2005 11:08:17 -0000 1.20 @@ -69,6 +69,7 @@ extern GstDebugCategory *GST_CAT_REFCOUNTING; extern GstDebugCategory *GST_CAT_ERROR_SYSTEM; extern GstDebugCategory *GST_CAT_EVENT; +extern GstDebugCategory *GST_CAT_MESSAGE; extern GstDebugCategory *GST_CAT_PARAMS; extern GstDebugCategory *GST_CAT_CALL_TRACE; extern GstDebugCategory *GST_CAT_SIGNAL; @@ -101,6 +102,7 @@ #define GST_CAT_REFCOUNTING NULL #define GST_CAT_ERROR_SYSTEM NULL #define GST_CAT_EVENT NULL +#define GST_CAT_MESSAGE NULL #define GST_CAT_PARAMS NULL #define GST_CAT_CALL_TRACE NULL #define GST_CAT_SIGNAL NULL Index: gstbin.c RCS file: /cvs/gstreamer/gstreamer/gst/gstbin.c,v retrieving revision 1.212 retrieving revision 1.213 diff -u -d -r1.212 -r1.213 --- gstbin.c 8 Mar 2005 14:38:06 -0000 1.212 +++ gstbin.c 9 Mar 2005 11:08:17 -0000 1.213 @@ -1114,11 +1114,12 @@ GstObject *parent; parent = gst_object_get_parent (GST_OBJECT_CAST (bin)); - - if (parent && GST_IS_BIN (parent)) { - result = gst_bin_get_by_name_recurse_up (GST_BIN_CAST (parent), name); + if (parent) { + if (GST_IS_BIN (parent)) { + result = gst_bin_get_by_name_recurse_up (GST_BIN_CAST (parent), name); + } + gst_object_unref (parent); } - gst_object_unref (parent); } return result; Index: gstelement.h RCS file: /cvs/gstreamer/gstreamer/gst/gstelement.h,v retrieving revision 1.181 retrieving revision 1.182 diff -u -d -r1.181 -r1.182 --- gstelement.h 8 Mar 2005 17:42:28 -0000 1.181 +++ gstelement.h 9 Mar 2005 11:08:17 -0000 1.182 @@ -87,7 +87,6 @@ #define GST_ELEMENT_CAST(obj) ((GstElement*)(obj)) /* convenience functions */ -#ifndef GST_DISABLE_DEPRECATED #ifdef G_HAVE_ISO_VARARGS #define GST_ELEMENT_QUERY_TYPE_FUNCTION(functionname, ...) \ GST_QUERY_TYPE_FUNCTION (GstElement*, functionname, __VA_ARGS__); @@ -103,7 +102,6 @@ #define GST_ELEMENT_EVENT_MASK_FUNCTION(functionname, a...) \ GST_EVENT_MASK_FUNCTION (GstElement*, functionname, a); #endif -#endif typedef enum { @@ -135,6 +133,7 @@ #define GST_ELEMENT_IS_THREAD_SUGGESTED(obj) (GST_FLAG_IS_SET(obj,GST_ELEMENT_THREAD_SUGGESTED)) #define GST_ELEMENT_IS_EVENT_AWARE(obj) (GST_FLAG_IS_SET(obj,GST_ELEMENT_EVENT_AWARE)) #define GST_ELEMENT_IS_DECOUPLED(obj) (GST_FLAG_IS_SET(obj,GST_ELEMENT_DECOUPLED)) +#define GST_ELEMENT_IS_LOCKED_STATE(obj) (GST_FLAG_IS_SET(obj,GST_ELEMENT_LOCKED_STATE)) #define GST_ELEMENT_NAME(obj) (GST_OBJECT_NAME(obj)) #define GST_ELEMENT_PARENT(obj) (GST_OBJECT_PARENT(obj)) Index: gstinfo.c RCS file: /cvs/gstreamer/gstreamer/gst/gstinfo.c,v retrieving revision 1.99 retrieving revision 1.100 diff -u -d -r1.99 -r1.100 --- gstinfo.c 7 Mar 2005 18:27:39 -0000 1.99 +++ gstinfo.c 9 Mar 2005 11:08:17 -0000 1.100 @@ -156,6 +156,7 @@ GstDebugCategory *GST_CAT_REFCOUNTING = NULL; GstDebugCategory *GST_CAT_ERROR_SYSTEM = NULL; GstDebugCategory *GST_CAT_EVENT = NULL; +GstDebugCategory *GST_CAT_MESSAGE = NULL; GstDebugCategory *GST_CAT_PARAMS = NULL; GstDebugCategory *GST_CAT_CALL_TRACE = NULL; GstDebugCategory *GST_CAT_SEEK = NULL; @@ -283,6 +284,8 @@ GST_CAT_EVENT = _gst_debug_category_new ("GST_EVENT", GST_DEBUG_BOLD | GST_DEBUG_FG_BLUE, NULL); + GST_CAT_MESSAGE = _gst_debug_category_new ("GST_MESSAGE", + GST_DEBUG_BOLD | GST_DEBUG_FG_WHITE | GST_DEBUG_BG_RED, NULL); GST_CAT_PARAMS = _gst_debug_category_new ("GST_PARAMS", GST_DEBUG_BOLD | GST_DEBUG_FG_BLACK | GST_DEBUG_BG_YELLOW, NULL); GST_CAT_CALL_TRACE = _gst_debug_category_new ("GST_CALL_TRACE", Index: gstobject.h RCS file: /cvs/gstreamer/gstreamer/gst/gstobject.h,v retrieving revision 1.49 retrieving revision 1.50 diff -u -d -r1.49 -r1.50 --- gstobject.h 8 Mar 2005 14:38:06 -0000 1.49 +++ gstobject.h 9 Mar 2005 11:08:17 -0000 1.50 @@ -132,9 +132,9 @@ /* name routines */ gboolean gst_object_set_name (GstObject *object, const gchar *name); -gchar* gst_object_get_name (GstObject *object); -void gst_object_set_name_prefix (GstObject *object, const gchar *name_prefix); -gchar* gst_object_get_name_prefix (GstObject *object); +gchar* gst_object_get_name (GstObject *object); +void gst_object_set_name_prefix (GstObject *object, const gchar *name_prefix); +gchar* gst_object_get_name_prefix (GstObject *object); /* parentage routines */ gboolean gst_object_set_parent (GstObject *object, GstObject *parent); @@ -142,7 +142,7 @@ void gst_object_unparent (GstObject *object); void gst_object_default_deep_notify (GObject *object, GstObject *orig, - GParamSpec *pspec, gchar **excluded_props); + GParamSpec *pspec, gchar **excluded_props); /* refcounting + life cycle */ GstObject * gst_object_ref (GstObject *object); Index: gstpad.c RCS file: /cvs/gstreamer/gstreamer/gst/gstpad.c,v retrieving revision 1.358 retrieving revision 1.359 diff -u -d -r1.358 -r1.359 --- gstpad.c 7 Mar 2005 18:27:39 -0000 1.358 +++ gstpad.c 9 Mar 2005 11:08:17 -0000 1.359 @@ -965,14 +965,14 @@ * but this is discouraged. * * You do not need to call this function if @pad's allowed caps are always the - * same as the pad template caps. + * same as the pad template caps. This can only be true if the padtemplate + * has fixed simple caps. * For most filters, the caps returned by @getcaps is directly affected by the * allowed caps on other pads. For demuxers and decoders, the caps returned by * the srcpad's getcaps function is directly related to the stream data. Again, * @getcaps should return the most specific caps it reasonably can, since this - * helps with autoplugging. However, the returned caps should not depend on the - * stream type currently negotiated for @pad. + * helps with autoplugging. * Note that the return value from @getcaps is owned by the caller. */ @@ -1972,22 +1972,6 @@ GST_GPAD_REALPAD (ghostpad) = NULL; } -/** - * gst_pad_get_ghost_pad_list: - * @pad: a #GstPad to get the ghost pads of. - * - * Gets the ghost pads of this pad. - * Returns: a #GList of ghost pads. - */ -GList * -gst_pad_get_ghost_pad_list (GstPad * pad) -{ - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - return GST_PAD_REALIZE (pad)->ghostpads; -} static gboolean _gst_pad_default_fixate_value (const GValue * value, GValue * dest) @@ -4227,7 +4211,7 @@ g_return_val_if_fail (rpad, FALSE); if (GST_RPAD_QUERYFUNC (rpad)) - return GST_RPAD_QUERYFUNC (rpad) (GST_PAD (rpad), type, format, value); + return GST_RPAD_QUERYFUNC (rpad) (GST_PAD_CAST (rpad), type, format, value); return FALSE; Index: gstpad.h RCS file: /cvs/gstreamer/gstreamer/gst/gstpad.h,v retrieving revision 1.156 retrieving revision 1.157 diff -u -d -r1.156 -r1.157 --- gstpad.h 7 Mar 2005 18:27:39 -0000 1.156 +++ gstpad.h 9 Mar 2005 11:08:18 -0000 1.157 @@ -134,6 +134,8 @@ typedef void (*GstPadChainFunction) (GstPad *pad,GstData *data); typedef GstData* (*GstPadGetFunction) (GstPad *pad); typedef gboolean (*GstPadEventFunction) (GstPad *pad, GstEvent *event); +/* convert/query/format functions */ typedef gboolean (*GstPadConvertFunction) (GstPad *pad, GstFormat src_format, gint64 src_value, GstFormat *dest_format, gint64 *dest_value); @@ -144,12 +146,16 @@ typedef const GstEventMask* (*GstPadEventMaskFunction) (GstPad *pad); typedef const GstQueryType* (*GstPadQueryTypeFunction) (GstPad *pad); +/* linking */ typedef GstPadLinkReturn (*GstPadLinkFunction) (GstPad *pad, const GstCaps *caps); typedef void (*GstPadUnlinkFunction) (GstPad *pad); +/* caps nego */ typedef GstCaps* (*GstPadGetCapsFunction) (GstPad *pad); typedef GstCaps* (*GstPadFixateFunction) (GstPad *pad, const GstCaps *caps); typedef GstBuffer* (*GstPadBufferAllocFunction) (GstPad *pad, guint64 offset, guint size); +/* misc */ typedef gboolean (*GstPadDispatcherFunction) (GstPad *pad, gpointer data); typedef enum { @@ -163,7 +169,7 @@ GST_PAD_NEGOTIATING, GST_PAD_DISPATCHING, - GST_PAD_FLAG_LAST = GST_OBJECT_FLAG_LAST + 4 + GST_PAD_FLAG_LAST = GST_OBJECT_FLAG_LAST + 8 } GstPadFlags; struct _GstPad { @@ -191,15 +197,17 @@ struct _GstRealPad { GstPad pad; + /* direction cannot change after creating the pad */ + GstPadDirection direction; /* the pad capabilities */ GstCaps *caps; - GstPadFixateFunction appfixatefunc; GstCaps *appfilter; GstPadGetCapsFunction getcapsfunc; + GstPadFixateFunction appfixatefunc; GstPadFixateFunction fixatefunc; - GstPadDirection direction; + /* pad link */ GstPadLinkFunction linkfunc; GstPadUnlinkFunction unlinkfunc; GstRealPad *peer; @@ -213,6 +221,7 @@ GstPadGetFunction gethandler; GstPadEventFunction eventfunc; GstPadEventFunction eventhandler; GstPadEventMaskFunction eventmaskfunc; /* ghostpads */ @@ -226,13 +235,14 @@ GstPadQueryTypeFunction querytypefunc; GstPadIntLinkFunction intlinkfunc; - GstPadBufferAllocFunction bufferallocfunc; + GstPadBufferAllocFunction bufferallocfunc; GstProbeDispatcher probedisp; GstPadLink *link; GstCaps *explicit_caps; + /*< private >*/ gpointer _gst_reserved[GST_PADDING]; }; @@ -240,12 +250,13 @@ GstPadClass parent_class; /* signal callbacks */ - void (*caps_nego_failed) (GstPad *pad, GstCaps *caps); void (*linked) (GstPad *pad, GstPad *peer); void (*unlinked) (GstPad *pad, GstPad *peer); GstPadFixateFunction appfixatefunc; + void (*caps_nego_failed) (GstPad *pad, GstCaps *caps); @@ -267,35 +278,44 @@ /***** helper macros *****/ /* GstPad */ #define GST_PAD_NAME(pad) (GST_OBJECT_NAME(pad)) -#define GST_PAD_PARENT(pad) ((GstElement *)(GST_OBJECT_PARENT(pad))) -#define GST_PAD_ELEMENT_PRIVATE(pad) (((GstPad *)(pad))->element_private) -#define GST_PAD_PAD_TEMPLATE(pad) (((GstPad *)(pad))->padtemplate) +#define GST_PAD_PARENT(pad) (GST_ELEMENT_CAST(GST_OBJECT_PARENT(pad))) +#define GST_PAD_ELEMENT_PRIVATE(pad) (GST_PAD_CAST(pad)->element_private) +#define GST_PAD_PAD_TEMPLATE(pad) (GST_PAD_CAST(pad)->padtemplate) /* GstRealPad */ -#define GST_RPAD_DIRECTION(pad) (((GstRealPad *)(pad))->direction) -#define GST_RPAD_CAPS(pad) (((GstRealPad *)(pad))->caps) -#define GST_RPAD_APPFILTER(pad) (((GstRealPad *)(pad))->appfilter) -#define GST_RPAD_PEER(pad) (((GstRealPad *)(pad))->peer) -#define GST_RPAD_CHAINFUNC(pad) (((GstRealPad *)(pad))->chainfunc) -#define GST_RPAD_CHAINHANDLER(pad) (((GstRealPad *)(pad))->chainhandler) -#define GST_RPAD_GETFUNC(pad) (((GstRealPad *)(pad))->getfunc) -#define GST_RPAD_GETHANDLER(pad) (((GstRealPad *)(pad))->gethandler) -#define GST_RPAD_EVENTFUNC(pad) (((GstRealPad *)(pad))->eventfunc) -#define GST_RPAD_EVENTHANDLER(pad) (((GstRealPad *)(pad))->eventhandler) -#define GST_RPAD_CONVERTFUNC(pad) (((GstRealPad *)(pad))->convertfunc) -#define GST_RPAD_QUERYFUNC(pad) (((GstRealPad *)(pad))->queryfunc) -#define GST_RPAD_INTLINKFUNC(pad) (((GstRealPad *)(pad))->intlinkfunc) -#define GST_RPAD_FORMATSFUNC(pad) (((GstRealPad *)(pad))->formatsfunc) -#define GST_RPAD_QUERYTYPEFUNC(pad) (((GstRealPad *)(pad))->querytypefunc) -#define GST_RPAD_EVENTMASKFUNC(pad) (((GstRealPad *)(pad))->eventmaskfunc) +#define GST_RPAD_DIRECTION(pad) (GST_REAL_PAD_CAST(pad)->direction) +#define GST_RPAD_CHAINFUNC(pad) (GST_REAL_PAD_CAST(pad)->chainfunc) +#define GST_RPAD_CHAINHANDLER(pad) (GST_REAL_PAD_CAST(pad)->chainhandler) +#define GST_RPAD_GETFUNC(pad) (GST_REAL_PAD_CAST(pad)->getfunc) +#define GST_RPAD_GETHANDLER(pad) (GST_REAL_PAD_CAST(pad)->gethandler) +#define GST_RPAD_EVENTFUNC(pad) (GST_REAL_PAD_CAST(pad)->eventfunc) +#define GST_RPAD_EVENTHANDLER(pad) (GST_REAL_PAD_CAST(pad)->eventhandler) +#define GST_RPAD_CONVERTFUNC(pad) (GST_REAL_PAD_CAST(pad)->convertfunc) +#define GST_RPAD_QUERYFUNC(pad) (GST_REAL_PAD_CAST(pad)->queryfunc) +#define GST_RPAD_INTLINKFUNC(pad) (GST_REAL_PAD_CAST(pad)->intlinkfunc) +#define GST_RPAD_FORMATSFUNC(pad) (GST_REAL_PAD_CAST(pad)->formatsfunc) +#define GST_RPAD_QUERYTYPEFUNC(pad) (GST_REAL_PAD_CAST(pad)->querytypefunc) +#define GST_RPAD_EVENTMASKFUNC(pad) (GST_REAL_PAD_CAST(pad)->eventmaskfunc) -#define GST_RPAD_LINKFUNC(pad) (((GstRealPad *)(pad))->linkfunc) -#define GST_RPAD_UNLINKFUNC(pad) (((GstRealPad *)(pad))->unlinkfunc) -#define GST_RPAD_GETCAPSFUNC(pad) (((GstRealPad *)(pad))->getcapsfunc) -#define GST_RPAD_FIXATEFUNC(pad) (((GstRealPad *)(pad))->fixatefunc) -#define GST_RPAD_BUFFERALLOCFUNC(pad) (((GstRealPad *)(pad))->bufferallocfunc) -#define GST_RPAD_LINK(pad) (((GstRealPad *)(pad))->link) -#define GST_RPAD_EXPLICIT_CAPS(pad) (((GstRealPad *)(pad))->explicit_caps) +#define GST_RPAD_PEER(pad) (GST_REAL_PAD_CAST(pad)->peer) +#define GST_RPAD_LINKFUNC(pad) (GST_REAL_PAD_CAST(pad)->linkfunc) +#define GST_RPAD_UNLINKFUNC(pad) (GST_REAL_PAD_CAST(pad)->unlinkfunc) +#define GST_RPAD_CAPS(pad) (GST_REAL_PAD_CAST(pad)->caps) +#define GST_RPAD_APPFILTER(pad) (GST_REAL_PAD_CAST(pad)->appfilter) +#define GST_RPAD_GETCAPSFUNC(pad) (GST_REAL_PAD_CAST(pad)->getcapsfunc) +#define GST_RPAD_FIXATEFUNC(pad) (GST_REAL_PAD_CAST(pad)->fixatefunc) +#define GST_RPAD_LINK(pad) (GST_REAL_PAD_CAST(pad)->link) +#define GST_RPAD_EXPLICIT_CAPS(pad) (GST_REAL_PAD_CAST(pad)->explicit_caps) +#define GST_RPAD_BUFFERALLOCFUNC(pad) (GST_REAL_PAD_CAST(pad)->bufferallocfunc) +#define GST_RPAD_IS_LINKED(pad) (GST_RPAD_PEER(pad) != NULL) +#define GST_RPAD_IS_ACTIVE(pad) (GST_FLAG_IS_SET (pad, GST_PAD_ACTIVE)) +#define GST_RPAD_IS_USABLE(pad) (GST_RPAD_IS_LINKED (pad) && \ + GST_RPAD_IS_ACTIVE(pad) && GST_RPAD_IS_ACTIVE(GST_RPAD_PEER (pad))) +#define GST_RPAD_IS_SRC(pad) (GST_RPAD_DIRECTION(pad) == GST_PAD_SRC) +#define GST_RPAD_IS_SINK(pad) (GST_RPAD_DIRECTION(pad) == GST_PAD_SINK) /* GstGhostPad */ #define GST_GPAD_REALPAD(pad) (((GstGhostPad *)(pad))->realpad) @@ -304,18 +324,17 @@ #define GST_PAD_REALIZE(pad) (GST_IS_REAL_PAD(pad) ? ((GstRealPad *)(pad)) : GST_GPAD_REALPAD(pad)) #define GST_PAD_DIRECTION(pad) GST_RPAD_DIRECTION(GST_PAD_REALIZE(pad)) #define GST_PAD_CAPS(pad) (gst_pad_get_negotiated_caps(GST_PAD (pad))) -#define GST_PAD_PEER(pad) GST_PAD(GST_RPAD_PEER(GST_PAD_REALIZE(pad))) +#define GST_PAD_PEER(pad) GST_PAD_CAST(GST_RPAD_PEER(GST_PAD_REALIZE(pad))) /* Some check functions (unused?) */ -#define GST_PAD_IS_LINKED(pad) (GST_PAD_PEER(pad) != NULL) -#define GST_PAD_IS_ACTIVE(pad) (GST_FLAG_IS_SET(GST_PAD_REALIZE(pad), GST_PAD_ACTIVE)) +#define GST_PAD_IS_LINKED(pad) (GST_RPAD_IS_LINKED(GST_PAD_REALIZE(pad))) +#define GST_PAD_IS_ACTIVE(pad) (GST_RPAD_IS_ACTIVE(GST_PAD_REALIZE(pad))) #define GST_PAD_IS_NEGOTIATING(pad) (GST_FLAG_IS_SET (pad, GST_PAD_NEGOTIATING)) #define GST_PAD_IS_DISPATCHING(pad) (GST_FLAG_IS_SET (pad, GST_PAD_DISPATCHING)) -#define GST_PAD_IS_USABLE(pad) (GST_PAD_IS_LINKED (pad) && \ - GST_PAD_IS_ACTIVE(pad) && GST_PAD_IS_ACTIVE(GST_PAD_PEER (pad))) +#define GST_PAD_IS_USABLE(pad) (GST_RPAD_IS_USABLE(GST_PAD_REALIZE(pad))) #define GST_PAD_CAN_PULL(pad) (GST_IS_REAL_PAD(pad) && GST_REAL_PAD(pad)->gethandler != NULL) -#define GST_PAD_IS_SRC(pad) (GST_PAD_DIRECTION(pad) == GST_PAD_SRC) -#define GST_PAD_IS_SINK(pad) (GST_PAD_DIRECTION(pad) == GST_PAD_SINK) +#define GST_PAD_IS_SRC(pad) (GST_RPAD_IS_SRC(GST_PAD_REALIZE(pad))) +#define GST_PAD_IS_SINK(pad) (GST_RPAD_IS_SINK(GST_PAD_REALIZE(pad))) /***** PadTemplate *****/ #define GST_TYPE_PAD_TEMPLATE (gst_pad_template_get_type ()) @@ -406,8 +425,6 @@ GstScheduler* gst_pad_get_scheduler (GstPad *pad); -GList* gst_pad_get_ghost_pad_list (GstPad *pad); GstPadTemplate* gst_pad_get_pad_template (GstPad *pad); void gst_pad_set_bufferalloc_function (GstPad *pad, GstPadBufferAllocFunction bufalloc); @@ -438,15 +455,6 @@ GstPad* gst_pad_realize (GstPad *pad); /* capsnego functions */ -G_CONST_RETURN GstCaps* gst_pad_get_negotiated_caps (GstPad *pad); -gboolean gst_pad_is_negotiated (GstPad *pad); -GstCaps* gst_pad_get_caps (GstPad *pad); -gboolean gst_pad_set_caps (GstPad *pad, GstCaps *caps); -G_CONST_RETURN GstCaps* gst_pad_get_pad_template_caps (GstPad *pad); -GstPadLinkReturn gst_pad_try_set_caps (GstPad *pad, const GstCaps *caps); -GstPadLinkReturn gst_pad_try_set_caps_nonfixed (GstPad *pad, const GstCaps *caps); -gboolean gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad); void gst_pad_set_getcaps_function (GstPad *pad, GstPadGetCapsFunction getcaps); void gst_pad_set_fixate_function (GstPad *pad, GstPadFixateFunction fixate); GstCaps * gst_pad_proxy_getcaps (GstPad *pad); @@ -457,13 +465,26 @@ GstPadLinkReturn gst_pad_renegotiate (GstPad *pad); void gst_pad_unnegotiate (GstPad *pad); gboolean gst_pad_try_relink_filtered (GstPad *srcpad, GstPad *sinkpad, const GstCaps *filtercaps); -GstCaps* gst_pad_get_allowed_caps (GstPad *pad); void gst_pad_caps_change_notify (GstPad *pad); gboolean gst_pad_recover_caps_error (GstPad *pad, const GstCaps *allowed); +G_CONST_RETURN GstCaps* gst_pad_get_pad_template_caps (GstPad *pad); +/* capsnego function for connected/unconnected pads */ +GstCaps* gst_pad_get_caps (GstPad *pad); +gboolean gst_pad_set_caps (GstPad *pad, GstCaps *caps); +GstPadLinkReturn gst_pad_try_set_caps (GstPad *pad, const GstCaps *caps); +GstPadLinkReturn gst_pad_try_set_caps_nonfixed (GstPad *pad, const GstCaps *caps); +gboolean gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad); GstCaps * gst_pad_peer_get_caps (GstPad * pad); +/* capsnego for connected pads */ +GstCaps* gst_pad_get_allowed_caps (GstPad *pad); +G_CONST_RETURN GstCaps* gst_pad_get_negotiated_caps (GstPad *pad); +gboolean gst_pad_is_negotiated (GstPad *pad); /* data passing functions */ void gst_pad_push (GstPad *pad, GstData *data); |
From: <wt...@fr...> - 2005-03-21 18:18:14
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Mon Mar 21 2005 10:18:09 PST Log message: * gst/gstbus.c: (gst_bus_post): Fix copy-and-paste error. Modified files: . : ChangeLog gst : gstbus.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.988&r2=1.989 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstbus.c.diff?r1=1.2&r2=1.3 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.988 retrieving revision 1.989 diff -u -d -r1.988 -r1.989 --- ChangeLog 21 Mar 2005 17:33:59 -0000 1.988 +++ ChangeLog 21 Mar 2005 18:17:57 -0000 1.989 @@ -1,5 +1,10 @@ 2005-03-21 Wim Taymans <wi...@fl...> + * gst/gstbus.c: (gst_bus_post): + Fix copy-and-paste error. + +2005-03-21 Wim Taymans <wi...@fl...> * check/Makefile.am: * gst/Makefile.am: * gst/elements/Makefile.am: Index: gstbus.c RCS file: /cvs/gstreamer/gstreamer/gst/gstbus.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- gstbus.c 21 Mar 2005 17:34:00 -0000 1.2 +++ gstbus.c 21 Mar 2005 18:17:57 -0000 1.3 @@ -229,8 +229,6 @@ g_queue_push_tail (bus->queue, message); g_mutex_unlock (bus->queue_lock); - if (g_queue_get_length (bus->queue) == 0) - need_write = TRUE; if (need_write) { c = 'p'; errno = EAGAIN; |
From: <wt...@fr...> - 2005-03-31 09:46:41
|
CVS Root: /cvs/gstreamer Module: gstreamer Changes by: wtay Date: Thu Mar 31 2005 01:46:40 PST Log message: * gst/gstevent.c: (gst_event_new_discontinuous_valist), (gst_event_new_discontinuous), (gst_event_discont_get_value): * gst/gstevent.h: * gst/gstpad.c: (gst_pad_set_active), (gst_pad_peer_set_active), (gst_pad_pull_range): Added rate to the discont event to prepare for variable speed and reverse playback. Modified files: . : ChangeLog gst : gstevent.c gstevent.h gstpad.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.1003&r2=1.1004 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstevent.c.diff?r1=1.51&r2=1.52 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstevent.h.diff?r1=1.54&r2=1.55 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstpad.c.diff?r1=1.365&r2=1.366 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.1003 retrieving revision 1.1004 diff -u -d -r1.1003 -r1.1004 --- ChangeLog 30 Mar 2005 03:57:38 -0000 1.1003 +++ ChangeLog 31 Mar 2005 09:46:27 -0000 1.1004 @@ -1,3 +1,13 @@ +2005-03-31 Wim Taymans <wi...@fl...> + + * gst/gstevent.c: (gst_event_new_discontinuous_valist), + (gst_event_new_discontinuous), (gst_event_discont_get_value): + * gst/gstevent.h: + * gst/gstpad.c: (gst_pad_set_active), (gst_pad_peer_set_active), + (gst_pad_pull_range): + Added rate to the discont event to prepare for variable speed + and reverse playback. 2005-03-29 David Schleef <ds...@sc...> * configure.ac: Index: gstevent.c RCS file: /cvs/gstreamer/gstreamer/gst/gstevent.c,v retrieving revision 1.51 retrieving revision 1.52 diff -u -d -r1.51 -r1.52 --- gstevent.c 21 Mar 2005 17:34:00 -0000 1.51 +++ gstevent.c 31 Mar 2005 09:46:28 -0000 1.52 @@ -223,20 +223,23 @@ * Returns: A new discontinuous event. */ GstEvent * -gst_event_new_discontinuous_valist (gboolean new_media, GstFormat format1, +gst_event_new_discontinuous_valist (gdouble rate, GstFormat format1, va_list var_args) { GstEvent *event; gint count = 0; event = gst_event_new (GST_EVENT_DISCONTINUOUS); - GST_EVENT_DISCONT_NEW_MEDIA (event) = new_media; + GST_EVENT_DISCONT_RATE (event) = rate; while (format1 != GST_FORMAT_UNDEFINED && count < 8) { GST_EVENT_DISCONT_OFFSET (event, count).format = format1 & GST_SEEK_FORMAT_MASK; - GST_EVENT_DISCONT_OFFSET (event, count).value = va_arg (var_args, gint64); + GST_EVENT_DISCONT_OFFSET (event, count).start_value = + va_arg (var_args, gint64); + GST_EVENT_DISCONT_OFFSET (event, count).end_value = format1 = va_arg (var_args, GstFormat); @@ -262,14 +265,14 @@ -gst_event_new_discontinuous (gboolean new_media, GstFormat format1, ...) +gst_event_new_discontinuous (gdouble rate, GstFormat format1, ...) va_list var_args; va_start (var_args, format1); - event = gst_event_new_discontinuous_valist (new_media, format1, var_args); + event = gst_event_new_discontinuous_valist (rate, format1, var_args); va_end (var_args); @@ -288,18 +291,21 @@ * format/value pair. gboolean -gst_event_discont_get_value (GstEvent * event, GstFormat format, gint64 * value) +gst_event_discont_get_value (GstEvent * event, GstFormat format, + gint64 * start_value, gint64 * end_value) gint i, n; g_return_val_if_fail (event != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); + g_return_val_if_fail (start_value != NULL, FALSE); + g_return_val_if_fail (end_value != NULL, FALSE); n = GST_EVENT_DISCONT_OFFSET_LEN (event); for (i = 0; i < n; i++) { if (GST_EVENT_DISCONT_OFFSET (event, i).format == format) { - *value = GST_EVENT_DISCONT_OFFSET (event, i).value; + *start_value = GST_EVENT_DISCONT_OFFSET (event, i).start_value; + *end_value = GST_EVENT_DISCONT_OFFSET (event, i).end_value; return TRUE; } } Index: gstevent.h RCS file: /cvs/gstreamer/gstreamer/gst/gstevent.h,v retrieving revision 1.54 retrieving revision 1.55 diff -u -d -r1.54 -r1.55 --- gstevent.h 21 Mar 2005 17:34:00 -0000 1.54 +++ gstevent.h 31 Mar 2005 09:46:28 -0000 1.55 @@ -142,7 +142,8 @@ typedef struct GstFormat format; - gint64 value; + gint64 start_value; + gint64 end_value; } GstFormatValue; #define GST_EVENT_SEEK_TYPE(event) (GST_EVENT(event)->event_data.seek.type) @@ -153,7 +154,7 @@ #define GST_EVENT_SEEK_ENDOFFSET(event) (GST_EVENT(event)->event_data.seek.endoffset) #define GST_EVENT_SEEK_ACCURACY(event) (GST_EVENT(event)->event_data.seek.accuracy) -#define GST_EVENT_DISCONT_NEW_MEDIA(event) (GST_EVENT(event)->event_data.discont.new_media) +#define GST_EVENT_DISCONT_RATE(event) (GST_EVENT(event)->event_data.discont.rate) #define GST_EVENT_DISCONT_OFFSET(event,i) (GST_EVENT(event)->event_data.discont.offsets[i]) #define GST_EVENT_DISCONT_OFFSET_LEN(event) (GST_EVENT(event)->event_data.discont.noffsets) @@ -182,7 +183,7 @@ struct { GstFormatValue offsets[8]; gint noffsets; - gboolean new_media; + gdouble rate; } discont; gboolean done; @@ -227,12 +228,13 @@ GstEvent* gst_event_new_size (GstFormat format, gint64 value); /* discontinous event */ -GstEvent* gst_event_new_discontinuous (gboolean new_media, +GstEvent* gst_event_new_discontinuous (gdouble rate, GstFormat format1, ...); -GstEvent* gst_event_new_discontinuous_valist (gboolean new_media, +GstEvent* gst_event_new_discontinuous_valist (gdouble rate, GstFormat format1, va_list var_args); -gboolean gst_event_discont_get_value (GstEvent *event, GstFormat format, gint64 *value); +gboolean gst_event_discont_get_value (GstEvent *event, GstFormat format, + gint64 *start_value, gint64 *end_value); #define gst_event_new_filler() gst_event_new(GST_EVENT_FILLER) Index: gstpad.c RCS file: /cvs/gstreamer/gstreamer/gst/gstpad.c,v retrieving revision 1.365 retrieving revision 1.366 diff -u -d -r1.365 -r1.366 --- gstpad.c 29 Mar 2005 16:18:12 -0000 1.365 +++ gstpad.c 31 Mar 2005 09:46:28 -0000 1.366 @@ -2957,7 +2957,6 @@ } - /** * gst_pad_check_pull_range: * @pad: a sink #GstRealPad. |