Merge branch 'master' into 0.11

Conflicts:
	configure.ac
	docs/gst/gstreamer-sections.txt
	gst/gstbin.c
	gst/gstelement.c
	gst/gstelement.h
	gst/gstghostpad.c
	gst/gstminiobject.c
	gst/gstminiobject.h
	libs/gst/base/gstbasesrc.c
	libs/gst/base/gstbasetransform.c
	plugins/elements/gstinputselector.c
	tests/check/gst/gstminiobject.c
This commit is contained in:
Sebastian Dröge 2011-05-16 16:53:04 +02:00
commit b935a814d9
67 changed files with 4664 additions and 320 deletions

3286
ChangeLog

File diff suppressed because it is too large Load diff

169
NEWS
View file

@ -1,4 +1,171 @@
This is GStreamer 0.10.32 "Take Me to the Bonus Level"
This is GStreamer 0.10.34 "Misfits"
Changes since 0.10.33:
* Fix multiqueue thread-safety regression
* Don't set artificial 0-timestamp on first packet for TIME-based live sources
* Otherwise identical to the previous release (0.10.33)
Bugs fixed since 0.10.33:
* 649369 : basesrc: do not set first buffer timestamp to 0 for live sources
* 649878 : multiqueue regression: gst_single_queue_new not MT-safe
Changes since 0.10.32:
* atomicqueue: add an atomic/lock-free queue structure based
* bufferlist: improve _add*() performance
* bus: in _add_watch() honour any per-thread default main context set via g_main_thread_push_thread_default()
* caps: new gst_caps_intersect_full() to intersect in different modes
* clock: add functions to re-init existing periodic GstClockIDs
* event: add QoS type (overflow, underflow, throttle) for QoS events
* ghostpad: The internally linked pad of the proxypad is the ghostpad
* gstpoll: retry reading the control socket to release properly all wakeups
* message: new progress message API for asynchronous operations
* pad: unlock before freeing the pad cache to avoid deadlock
* pad: better handling for when parent goes away during data/query/event flow
* parse-launch: allow element names to begin with digits
* pluginloader: call gst-plugin-scanner with the right arch on OSX, fixing hangs with firefox
* registry: fixes elements (features) disappearing if a plugin or plugin file is renamed
* structure: Add "(date)" as a type abbreviation of GDate
* structure: Don't allow invalid GDates in all structures and don't allow NULL GDates in taglists
* taglist: add a new "encoded-by" tag
* uri: add gst_filename_to_uri() that takes relative filenames
* utils: add gst_element_factory_can_{src|sink}_{any|all}_caps() to replace can_{sink,src}_caps()
* baseparse: new GstBaseParse class for parsers
* basesink: improve rate, duration, and average duration calculation
* basesink: use new QoS types and add add "throttle-time" property
* basesrc: Handle tag and custom downstream events the same
* basesrc: keep downstream caps order when fixating, to honour downstream preferences when negotiating
* basesrc: Return FALSE if we don't handle an event
* basesrc: Send synchronized custom downstream/both events downstream from the streaming thread
* basetransform: Be smarter with pad allocs
* basetransform: Check for pad alloc caps when suggestion is not fixed
* basetransform: Retain caps order when getting caps, to honour downstream preferences when negotiating
* funnel: new N-to-1 pipe fitting element imported from farsight
* fakesink: print buffer flags
* filesink: Fix escaping of URIs
* file{sink,src}: Check if non-URI characters are escaped, but only for the URI not the location property
* filesrc, filesink: fix URI creation regression for non-absolute locations
* filesrc: Fix escaping of file uris
* inputselector: Hold the selector lock while reading properties of the active pad
* inputselector: Make sure that EOS is always sent downstream for the active pad
* inputselector: Return GST_FLOW_OK until the selected pad pushed something downstream
* inputselector: Stop waiting for a pad switch when the pad is flushing
* multiqueue: fix some potential corner-case deadlocks and some leaks
* multiqueue: handle arbitrary sink + source pad naming
* queue2: don't read beyond the end of file upstream in pull mode; leak fixes
* plugins: make query and event functions more thread-safe, protect against parent-pad disappearing
* gst-launch: add GstIndex support
Bugs fixed since 0.10.32:
* 642356 : [Index] review api and add an example
* 402141 : gst_element_factory_can_{sink,src}_caps seems to be broken
* 518857 : [API] GstBaseParse: new base class for parsers
* 604094 : registry: do not remove features when removing a cached plugin that no longer is present
* 615357 : [macosx] Handle multi-arch plugin-scanner
* 617045 : [caps] New method for intersecting caps while retaining order
* 639674 : parse-launch: improve parsing resilience (for escapes at end of string)
* 639962 : design docs: Fix a few typos and a think
* 640071 : pluginloader: do not leak the description string of blacklisted plugin
* 640437 : design docs: fix 2 typos in part-MT-refcounting
* 640502 : fix a few typos
* 640622 : gst_element_link_pads_full function return wrong error information
* 640675 : high cpu-load with 0.10.32 release
* 640850 : GstElement: Fix warning with GCC 4.6
* 641212 : gst-uninstalled: use $GST_PREFIX variable
* 641928 : gst_pad_push fast path races with pad deactivation
* 642071 : Incorrect comparing of number of source and sink links when parsing a launch string
* 642130 : [basetransform] Check for pad alloc caps when suggestion is not fixed
* 642271 : crash in gst_caps_structure_intersect, encoder_match_media_type
* 642373 : [basetransform] Avoid too may pad allocs
* 642393 : [filesrc] Fails setting the same uri it's setting in the uri queries.
* 642504 : [mingw/cygwin build] correctly export plugin description
* 642522 : gstvalue.c does not include a deserialize function for uchar
* 642869 : gst_index_new: documentation typo
* 643301 : Adding a buffer to a buffer list iterates the list
* 643455 : [regression] Lots of dropouts in Empathy voip calls
* 644935 : [inputselector] During switching of streams it can happen that all pads returned not-linked last
* 645022 : GstTask: typo in GST_TASK_BROADCAST - g_cond_breadcast should probably be g_cond_broadcast
* 645267 : build: fix build with -Werror with GCC 4.6.0
* 645595 : bytereader, bytewriter: fix warnings when using inline functions with g++
* 645746 : [gstpoll] Regression causes 100% cpu usage in multifdsink
* 645877 : commit 14d7db1 causes cpu spinning and other bus weirdness
* 645931 : [gstmultiqueue] fix arbitrary sink + source pad naming
* 646118 : [gstmultiqueue] if arbitrary sink number is specified by caller, use this as single queue id
* 646341 : [baseparse] Add a queued flow return so parsers can keep frames in a queue
* 646531 : GST_BOILERPLATE: don't use " type " as both a variable name and a macro argument
* 646566 : Protect against Pad-Parent disappearing
* 646569 : poll: don't call WSAWaitForMultipleEvents with no events
* 646624 : GstBin: regression: creating too many bins fails, exhausting allowed file descriptor limit
* 646811 : baseparse: deadlock in gst_base_parse_set_index
* 646971 : iterator: resync to avoid infinite loop
* 647005 : GstBus: Only create the socketpair for async message delivery if required
* 647131 : recent multiqueue changes break DVD playback (again)
* 647293 : Fix pad callbacks so they handle when parent goes away
* 647763 : [bus] Bus is leaked if a watch is installed in the default main context
* 647844 : baseparse: Remove unused but set variable
* 647922 : [introspection] Needs to call gst_init() before anything else
* 648199 : pad: potential deadlock / crash when freeing cache
* 648215 : basetransform: unref in wrong place
* 648220 : Regression: videoscale fails to negotiate for PAR transformation
* 648297 : [bus] regression: critical assertion failure
* 649195 : [miniobject] Fix dup_mini_object function to handle NULL gvalues
* 635718 : [basesrc] custom, non-OOB events aren't pushed downstream
* 625396 : gst_debug_remove_log_function doesn't remove default log handler
* 640771 : amarok doesn't start with new phonon gstreamer
* 646972 : queue2: Fixes memory leak on out_flushing error in gst_queue2_create_read
* 640665 : basesink: drops too many buffers when there's no duration
API additions since 0.10.32:
* gst_atomic_queue_length()
* gst_atomic_queue_new()
* gst_atomic_queue_peek()
* gst_atomic_queue_pop()
* gst_atomic_queue_push()
* gst_atomic_queue_ref()
* gst_atomic_queue_unref()
* gst_buffer_list_iterator_get_type()
* gst_caps_intersect_full()
* gst_caps_intersect_mode_get_type()
* gst_clock_periodic_id_reinit()
* gst_element_factory_can_sink_all_caps()
* gst_element_factory_can_sink_any_caps()
* gst_element_factory_can_src_all_caps()
* gst_element_factory_can_src_any_caps()
* gst_event_new_qos_full()
* gst_event_parse_qos_full()
* gst_filename_to_uri()
* gst_message_new_progress()
* gst_message_parse_progress()
* gst_parse_context_get_type()
* gst_progress_type_get_type()
* gst_qos_type_get_type()
* GST_TAG_ENCODED_BY
* gst_base_parse_add_index_entry()
* gst_base_parse_convert_default()
* gst_base_parse_frame_free()
* gst_base_parse_frame_get_type()
* gst_base_parse_frame_init()
* gst_base_parse_frame_new()
* gst_base_parse_get_type()
* gst_base_parse_push_frame()
* gst_base_parse_set_average_bitrate()
* gst_base_parse_set_duration()
* gst_base_parse_set_frame_rate()
* gst_base_parse_set_has_timing_info()
* gst_base_parse_set_min_frame_size()
* gst_base_parse_set_passthrough()
* gst_base_parse_set_syncable()
* gst_base_sink_get_throttle_time()
* gst_base_sink_set_throttle_time()
API deprecated since 0.10.32:
* gst_element_factory_can_src_caps()
* gst_element_factory_can_sink_caps()
Changes since 0.10.31:

100
RELEASE
View file

@ -1,5 +1,5 @@
Release notes for GStreamer 0.10.32 "Take Me to the Bonus Level"
Release notes for GStreamer 0.10.34 "Misfits"
@ -9,6 +9,12 @@ core of the GStreamer streaming media framework.
The 0.10.x series is a stable series targeted at end users.
It is not API or ABI compatible with the stable 0.8.x series.
It is, however, parallel installable with the 0.8.x series.
The 0.10.x series has been reworked for threadsafety. It also features
various feature additions and enhancements.
This module, gstreamer, only contains core functionality.
@ -31,64 +37,14 @@ contains a set of less supported plug-ins that haven't passed the
Features of this release
* GLib requirement is now >= 2.22
* New core element: valve (moved from -bad)
* New core element: input-selector (N.B. without "select-all" property, use fsfunnel instead) (moved from -bad)
* New core element: output-selector (with different negotiation behaviour by default, set pad-negotiation-mode=active for previous behaviour) (moved from -bad)
* Performance improvements for many heavily-used code paths: GstPad, GstPoll, GstClock, GstTask, basesink, basesrc, queue2, multiqueue
* gobject-introspection: add annotations for most core API
* clock: make sync clock wait lockfree
* fdsrc/fdsink: reenable on MSVC
* registry: fix GStatBuf definition for win32 when building against older glib (fixes unnecessary rescanning of plugins at start-up)
* element: add a more flexible way to get request pads from elements
* multiqueue: return upon input when already eos
* object: fix creation of default name (when creating more than 100000 elements)
* pluginloader: fix hangs on OSX
* poll: fixes for (p)select backend (used e.g. on OSX)
* poll: refactor and make more lockfree; fixes for win32 and OSX (pselect backend)
* registry: don't replace valid existing plugins by blacklisted ones
* tags: don't produce duplicated entries when merging same value twice
* basesink: preroll fixes for async=false case
* basesink: rework position reporting code
* basetransform: handle downstream giving a buffer with new caps but invalid size
* Fix multiqueue thread-safety regression
* Don't set artificial 0-timestamp on first packet for TIME-based live sources
* Otherwise identical to the previous release (0.10.33)
Bugs fixed in this release
* 635785 : basesrc: fix deadlock
* 638599 : GST_PTR_FORMAT causes crashes if GLib-internal printf is used but system provides register_printf_specifier
* 503592 : gstpad.c does many ref/unref of peer pad in dataflow
* 564056 : Protect against umask(0177)
* 607513 : input-selector segfaults in g_object_notify()
* 632168 : [gsttask] MSVC thread names for task debugging
* 632447 : reduce static memory allocated by the registry
* 632557 : [macros] Define restrict keyword if not available
* 632778 : Optimisations to GstBaseSink
* 632779 : gstdataqueue: Only emit g_cond_signal when needed
* 632780 : queue: Remove useless checks from e406f7
* 633918 : [fakesink] [PATCH] print sink-message events like a message and its structure
* 634965 : sinks render buffers in state PAUSED when async is FALSE
* 635001 : basesink: fix position reporting in PAUSED
* 636268 : configure test fails on FreeBSD
* 636455 : basesrc: Avoid taking object locks for just checking tag presence
* 637057 : [plugin-scanner] gstpoll fails with select backend
* 637300 : [API] request pad based on caps
* 637549 : build fails: ./.libs/libgstbase-0.10.so: undefined reference to `gst_clock_single_shot_id_reinit'
* 637776 : merging the same tag values again produces lists containing duplicates
* 638381 : {input,output}-selector: double-check API before release
* 638399 : a few typos in GStreamer
* 638900 : [GstPoll] Doesn't compile with MinGW
* 638941 : registry scan/loading race and inconsistency
API changed in this release
- API additions:
* gst_clock_single_shot_id_reinit()
* gst_element_request_pad()
* GstElementClass::request_new_pad_full()
* gst_poll_get_read_gpollfd()
* gst_value_list_merge()
* GST_CLOCK_DONE
* 649369 : basesrc: do not set first buffer timestamp to 0 for live sources
* 649878 : [multiqueue] regression: gst_single_queue_new not MT-safe
Download
@ -113,31 +69,15 @@ subscribe to the gstreamer-devel list. If there is sufficient interest we
will create more lists as necessary.
Applications
Applications ported to GStreamer 0.10 include Totem, RhythmBox, Sound-Juicer,
Gnome Media, Flumotion, Amarok, Jamboree, Pitivi, Istanbul, AnnoAmp, Elisa, and others.
Let us know if you want to be added to this list.
Contributors to this release
* Andoni Morales Alastruey
* Benjamin Gaignard
* Benjamin Otte
* David Hoyt
* David Schleef
* Edward Hervey
* Havard Graff
* Jan Schmidt
* Kipp Cannon
* Koop Mast
* Lasse Laukkanen
* Mark Nauwelaerts
* Michael Smith
* Olivier Crete
* Olivier Crête
* Raimo Järvi
* Sebastian Dröge
* Stefan Kost
* Thiago Santos
* Tim-Philipp Müller
* Tommi Myöhänen
* Wim Taymans
* Zhang Wanming
* Christian Schaller
* Sjoerd Simons
* Vincent Penquerc'h
 

View file

@ -48,7 +48,7 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0
dnl - interfaces added -> increment AGE
dnl - interfaces removed -> AGE = 0
dnl sets GST_LT_LDFLAGS
AS_LIBTOOL(GST, 28, 0, 28)
AS_LIBTOOL(GST, 29, 0, 29)
dnl FIXME: this macro doesn't actually work;
dnl the generated libtool script has no support for the listed tags.

View file

@ -933,14 +933,43 @@ gst_format_get_type
<SECTION>
<FILE>gstghostpad</FILE>
<TITLE>GstGhostPad</TITLE>
GstProxyPad
GstGhostPad
gst_ghost_pad_new
gst_ghost_pad_new_no_target
gst_ghost_pad_new_from_template
gst_ghost_pad_new_no_target_from_template
gst_ghost_pad_set_target
gst_ghost_pad_get_target
gst_ghost_pad_construct
gst_ghost_pad_setcaps_default
gst_ghost_pad_unlink_default
gst_ghost_pad_link_default
gst_ghost_pad_activate_pull_default
gst_ghost_pad_activate_push_default
gst_ghost_pad_internal_activate_push_default
gst_ghost_pad_internal_activate_pull_default
gst_proxy_pad_get_internal
gst_proxy_pad_query_type_default
gst_proxy_pad_event_default
gst_proxy_pad_query_default
gst_proxy_pad_iterate_internal_links_default
gst_proxy_pad_chain_default
gst_proxy_pad_chain_list_default
gst_proxy_pad_getrange_default
gst_proxy_pad_checkgetrange_default
gst_proxy_pad_getcaps_default
gst_proxy_pad_acceptcaps_default
gst_proxy_pad_fixatecaps_default
gst_proxy_pad_setcaps_default
gst_proxy_pad_unlink_default
<SUBSECTION Standard>
GstGhostPadClass
GST_GHOST_PAD
@ -1393,6 +1422,7 @@ GstMiniObjectFlags
GstMiniObjectCopyFunction
GstMiniObjectDisposeFunction
GstMiniObjectFreeFunction
GstMiniObjectWeakNotify
GST_MINI_OBJECT_TYPE
GST_MINI_OBJECT_FLAGS
@ -1413,6 +1443,9 @@ gst_mini_object_make_writable
gst_mini_object_ref
gst_mini_object_unref
gst_mini_object_weak_ref
gst_mini_object_weak_unref
gst_mini_object_replace
<SUBSECTION Standard>
@ -1540,11 +1573,6 @@ gst_pad_new
gst_pad_new_from_template
gst_pad_new_from_static_template
gst_pad_alloc_buffer
gst_pad_alloc_buffer_and_set_caps
gst_pad_set_bufferalloc_function
GstPadBufferAllocFunction
gst_pad_set_chain_function
GstPadChainFunction

View file

@ -848,6 +848,16 @@
<DEFAULT>FALSE</DEFAULT>
</ARG>
<ARG>
<NAME>GstMultiQueue::sync-by-running-time</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Sync By Running Time</NICK>
<BLURB>Synchronize deactivated or not-linked streams by running time.</BLURB>
<DEFAULT>FALSE</DEFAULT>
</ARG>
<ARG>
<NAME>GstBin::async-handling</NAME>
<TYPE>gboolean</TYPE>
@ -1068,3 +1078,13 @@
<DEFAULT>FALSE</DEFAULT>
</ARG>
<ARG>
<NAME>GstInputSelector::sync-streams</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Sync Streams</NICK>
<BLURB>Synchronize inactive streams to the running time of the active stream.</BLURB>
<DEFAULT>FALSE</DEFAULT>
</ARG>

View file

@ -3,10 +3,10 @@
<description>standard GStreamer elements</description>
<filename>../../plugins/elements/.libs/libgstcoreelements.so</filename>
<basename>libgstcoreelements.so</basename>
<version>0.10.32.4</version>
<version>0.10.34.1</version>
<license>LGPL</license>
<source>gstreamer</source>
<package>GStreamer prerelease</package>
<package>GStreamer git</package>
<origin>Unknown package origin</origin>
<elements>
<element>

View file

@ -3,10 +3,10 @@
<description>GStreamer core indexers</description>
<filename>../../plugins/indexers/.libs/libgstcoreindexers.so</filename>
<basename>libgstcoreindexers.so</basename>
<version>0.10.32.4</version>
<version>0.10.34.1</version>
<license>LGPL</license>
<source>gstreamer</source>
<package>GStreamer prerelease</package>
<package>GStreamer git</package>
<origin>Unknown package origin</origin>
<elements>
</elements>

View file

@ -51,6 +51,9 @@ extern const char g_log_domain_gstreamer[];
/* for the pad cache */
#include "gstpad.h"
/* for GstElement */
#include "gstelement.h"
G_BEGIN_DECLS
/* used by gstparse.c and grammar.y */
@ -115,6 +118,10 @@ gboolean _gst_plugin_loader_client_run (void);
void _priv_gst_pad_invalidate_cache (GstPad *pad);
/* Used in GstBin for manual state handling */
void _priv_gst_element_state_changed (GstElement *element, GstState oldstate,
GstState newstate, GstState pending);
/* used in both gststructure.c and gstcaps.c; numbers are completely made up */
#define STRUCTURE_ESTIMATED_STRING_LEN(s) (16 + gst_structure_n_fields(s) * 22)

View file

@ -222,6 +222,8 @@ static void gst_bin_get_property (GObject * object, guint prop_id,
static GstStateChangeReturn gst_bin_change_state_func (GstElement * element,
GstStateChange transition);
static void gst_bin_state_changed (GstElement * element, GstState oldstate,
GstState newstate, GstState pending);
static GstStateChangeReturn gst_bin_get_state_func (GstElement * element,
GstState * state, GstState * pending, GstClockTime timeout);
static void bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret,
@ -468,6 +470,7 @@ gst_bin_class_init (GstBinClass * klass)
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_bin_change_state_func);
gstelement_class->state_changed = GST_DEBUG_FUNCPTR (gst_bin_state_changed);
gstelement_class->get_state = GST_DEBUG_FUNCPTR (gst_bin_get_state_func);
gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_bin_get_index_func);
gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_bin_set_index_func);
@ -983,6 +986,7 @@ static gboolean
is_eos (GstBin * bin, guint32 * seqnum)
{
gboolean result;
gint n_eos = 0;
GList *walk, *msgs;
result = TRUE;
@ -996,6 +1000,7 @@ is_eos (GstBin * bin, guint32 * seqnum)
find_message (bin, GST_OBJECT_CAST (element), GST_MESSAGE_EOS))) {
GST_DEBUG ("sink '%s' posted EOS", GST_ELEMENT_NAME (element));
*seqnum = gst_message_get_seqnum (GST_MESSAGE_CAST (msgs->data));
n_eos++;
} else {
GST_DEBUG ("sink '%s' did not post EOS yet",
GST_ELEMENT_NAME (element));
@ -1004,7 +1009,13 @@ is_eos (GstBin * bin, guint32 * seqnum)
}
}
}
return result;
/* FIXME: Some tests (e.g. elements/capsfilter) use
* pipelines with a dangling sinkpad but no sink element.
* These tests assume that no EOS message is ever
* posted on the bus so let's keep that behaviour.
* In valid pipelines this doesn't make a difference.
*/
return result && n_eos > 0;
}
static void
@ -2238,7 +2249,6 @@ activate_pads (const GValue * vpad, GValue * ret, gboolean * active)
if (!(cont = gst_pad_set_active (pad, *active)))
g_value_set_boolean (ret, FALSE);
/* unref the object that was reffed for us by _fold */
return cont;
}
@ -2387,6 +2397,19 @@ gst_bin_do_latency_func (GstBin * bin)
return res;
}
static void
gst_bin_state_changed (GstElement * element, GstState oldstate,
GstState newstate, GstState pending)
{
GstElementClass *pklass = (GstElementClass *) parent_class;
if (newstate == GST_STATE_PLAYING && pending == GST_STATE_VOID_PENDING)
bin_do_eos (GST_BIN_CAST (element));
if (pklass->state_changed)
pklass->state_changed (element, oldstate, newstate, pending);
}
static GstStateChangeReturn
gst_bin_change_state_func (GstElement * element, GstStateChange transition)
{
@ -2621,8 +2644,6 @@ state_end:
gst_element_state_get_name (GST_STATE (element)),
gst_element_state_change_return_get_name (ret));
bin_do_eos (bin);
return ret;
/* ERRORS */
@ -2736,8 +2757,6 @@ gst_bin_continue_func (BinContinueData * data)
GST_STATE_UNLOCK (bin);
GST_DEBUG_OBJECT (bin, "state continue done");
bin_do_eos (bin);
gst_object_unref (bin);
g_slice_free (BinContinueData, data);
return;
@ -2832,9 +2851,8 @@ bin_handle_async_start (GstBin * bin, gboolean new_base_time)
GST_OBJECT_UNLOCK (bin);
/* post message */
gst_element_post_message (GST_ELEMENT_CAST (bin),
gst_message_new_state_changed (GST_OBJECT_CAST (bin),
new_state, new_state, new_state));
_priv_gst_element_state_changed (GST_ELEMENT_CAST (bin), new_state, new_state,
new_state);
post_start:
if (amessage) {
@ -2876,8 +2894,8 @@ bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret,
GstState current, pending, target;
GstStateChangeReturn old_ret;
GstState old_state, old_next;
gboolean toplevel;
GstMessage *smessage = NULL, *amessage = NULL;
gboolean toplevel, state_changed = FALSE;
GstMessage *amessage = NULL;
BinContinueData *cont = NULL;
if (GST_STATE_RETURN (bin) == GST_STATE_CHANGE_FAILURE)
@ -2956,15 +2974,14 @@ bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret,
if (old_next != GST_STATE_PLAYING) {
if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC) {
smessage = gst_message_new_state_changed (GST_OBJECT_CAST (bin),
old_state, old_next, pending);
state_changed = TRUE;
}
}
GST_OBJECT_UNLOCK (bin);
if (smessage) {
GST_DEBUG_OBJECT (bin, "posting state change message");
gst_element_post_message (GST_ELEMENT_CAST (bin), smessage);
if (state_changed) {
_priv_gst_element_state_changed (GST_ELEMENT_CAST (bin), old_state,
old_next, pending);
}
if (amessage) {
/* post our combined ASYNC_DONE when all is ASYNC_DONE. */
@ -2972,9 +2989,6 @@ bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret,
gst_element_post_message (GST_ELEMENT_CAST (bin), amessage);
}
if (!cont)
bin_do_eos (bin);
GST_OBJECT_LOCK (bin);
if (cont) {
/* toplevel, start continue state */

View file

@ -2227,6 +2227,28 @@ nothing_aborted:
}
}
/* Not static because GstBin has manual state handling too */
void
_priv_gst_element_state_changed (GstElement * element, GstState oldstate,
GstState newstate, GstState pending)
{
GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
GstMessage *message;
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"notifying about state-changed %s to %s (%s pending)",
gst_element_state_get_name (oldstate),
gst_element_state_get_name (newstate),
gst_element_state_get_name (pending));
if (klass->state_changed)
klass->state_changed (element, oldstate, newstate, pending);
message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
oldstate, newstate, pending);
gst_element_post_message (element, message);
}
/**
* gst_element_continue_state:
* @element: a #GstElement to continue the state change of.
@ -2254,7 +2276,6 @@ gst_element_continue_state (GstElement * element, GstStateChangeReturn ret)
GstStateChangeReturn old_ret;
GstState old_state, old_next;
GstState current, next, pending;
GstMessage *message;
GstStateChange transition;
GST_OBJECT_LOCK (element);
@ -2290,9 +2311,7 @@ gst_element_continue_state (GstElement * element, GstStateChangeReturn ret)
gst_element_state_get_name (old_next),
gst_element_state_get_name (pending), gst_element_state_get_name (next));
message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
old_state, old_next, pending);
gst_element_post_message (element, message);
_priv_gst_element_state_changed (element, old_state, old_next, pending);
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"continue state change %s to %s, final %s",
@ -2324,16 +2343,9 @@ complete:
* previous return value.
* We do signal the cond though as a _get_state() might be blocking
* on it. */
if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC) {
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"posting state-changed %s to %s",
gst_element_state_get_name (old_state),
gst_element_state_get_name (old_next));
message =
gst_message_new_state_changed (GST_OBJECT_CAST (element), old_state,
old_next, GST_STATE_VOID_PENDING);
gst_element_post_message (element, message);
}
if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC)
_priv_gst_element_state_changed (element, old_state, old_next,
GST_STATE_VOID_PENDING);
GST_STATE_BROADCAST (element);
@ -2402,9 +2414,7 @@ gst_element_lost_state (GstElement * element, gboolean new_base_time)
GST_ELEMENT_START_TIME (element) = 0;
GST_OBJECT_UNLOCK (element);
message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
new_state, new_state, new_state);
gst_element_post_message (element, message);
_priv_gst_element_state_changed (element, new_state, new_state, new_state);
message =
gst_message_new_async_start (GST_OBJECT_CAST (element), new_base_time);
@ -2691,7 +2701,6 @@ activate_pads (const GValue * vpad, GValue * ret, gboolean * active)
if (!(cont = gst_pad_set_active (pad, *active)))
g_value_set_boolean (ret, FALSE);
/* unref the object that was reffed for us by _fold */
return cont;
}

View file

@ -597,6 +597,7 @@ struct _GstElement
* @get_query_types: get the supported #GstQueryType of this element
* @query: perform a #GstQuery on the element
* @request_new_pad_full: called when a new pad is requested. Since: 0.10.32.
* @state_changed: called immediately after a new state was set. Since: 0.10.35.
*
* GStreamer element class. Override the vmethods to implement the element
* functionality.
@ -636,6 +637,8 @@ struct _GstElementClass
GstState * pending, GstClockTime timeout);
GstStateChangeReturn (*set_state) (GstElement *element, GstState state);
GstStateChangeReturn (*change_state) (GstElement *element, GstStateChange transition);
void (*state_changed) (GstElement *element, GstState oldstate,
GstState newstate, GstState pending);
/* bus */
void (*set_bus) (GstElement * element, GstBus * bus);

View file

@ -73,7 +73,6 @@ struct _GstProxyPadPrivate
G_DEFINE_TYPE (GstProxyPad, gst_proxy_pad, GST_TYPE_PAD);
static GstPad *gst_proxy_pad_get_target (GstPad * pad);
static GstPad *gst_proxy_pad_get_internal (GstPad * pad);
static void gst_proxy_pad_dispose (GObject * object);
static void gst_proxy_pad_finalize (GObject * object);
@ -83,12 +82,26 @@ static void on_src_target_notify (GstPad * target,
static GParamSpec *pspec_caps = NULL;
static const GstQueryType *
gst_proxy_pad_do_query_type (GstPad * pad)
/**
* gst_proxy_pad_query_type_default:
* @pad: a #GstPad.
*
* Invoke the default query type handler of the proxy pad.
*
* Returns: (transfer none) (array zero-terminated=1): a zero-terminated array
* of #GstQueryType.
*
* Since: 0.10.35
*/
const GstQueryType *
gst_proxy_pad_query_type_default (GstPad * pad)
{
GstPad *target = gst_proxy_pad_get_target (pad);
GstPad *target;
const GstQueryType *res = NULL;
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);
target = gst_proxy_pad_get_target (pad);
if (target) {
res = gst_pad_get_query_types (target);
gst_object_unref (target);
@ -96,12 +109,28 @@ gst_proxy_pad_do_query_type (GstPad * pad)
return res;
}
static gboolean
gst_proxy_pad_do_event (GstPad * pad, GstEvent * event)
/**
* gst_proxy_pad_event_default:
* @pad: a #GstPad to push the event to.
* @event: (transfer full): the #GstEvent to send to the pad.
*
* Invoke the default event of the proxy pad.
*
* Returns: TRUE if the event was handled.
*
* Since: 0.10.35
*/
gboolean
gst_proxy_pad_event_default (GstPad * pad, GstEvent * event)
{
gboolean res = FALSE;
GstPad *internal = gst_proxy_pad_get_internal (pad);
GstPad *internal;
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
internal =
GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD_CAST (pad)));
if (internal) {
res = gst_pad_push_event (internal, event);
gst_object_unref (internal);
@ -110,12 +139,27 @@ gst_proxy_pad_do_event (GstPad * pad, GstEvent * event)
return res;
}
static gboolean
gst_proxy_pad_do_query (GstPad * pad, GstQuery ** query)
/**
* gst_proxy_pad_query_default:
* @pad: a #GstPad to invoke the default query on.
* @query: (transfer none): the #GstQuery to perform.
*
* Invoke the default query function of the proxy pad.
*
* Returns: TRUE if the query could be performed.
*
* Since: 0.10.35
*/
gboolean
gst_proxy_pad_query_default (GstPad * pad, GstQuery ** query)
{
gboolean res = FALSE;
GstPad *target = gst_proxy_pad_get_target (pad);
GstPad *target;
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
g_return_val_if_fail (GST_IS_QUERY (query), FALSE);
target = gst_proxy_pad_get_target (pad);
if (target) {
res = gst_pad_query (target, query);
gst_object_unref (target);
@ -124,11 +168,27 @@ gst_proxy_pad_do_query (GstPad * pad, GstQuery ** query)
return res;
}
static GstIterator *
gst_proxy_pad_do_iterate_internal_links (GstPad * pad)
/**
* gst_proyx_pad_iterate_internal_links_default:
* @pad: the #GstPad to get the internal links of.
*
* Invoke the default iterate internal links function of the proxy pad.
*
* Returns: a #GstIterator of #GstPad, or NULL if @pad has no parent. Unref each
* returned pad with gst_object_unref().
*
* Since: 0.10.35
*/
GstIterator *
gst_proxy_pad_iterate_internal_links_default (GstPad * pad)
{
GstIterator *res = NULL;
GstPad *internal = GST_PROXY_PAD_INTERNAL (pad);
GstPad *internal;
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);
internal =
GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD_CAST (pad)));
if (internal) {
GValue v = { 0, };
@ -137,63 +197,142 @@ gst_proxy_pad_do_iterate_internal_links (GstPad * pad)
g_value_set_object (&v, internal);
res = gst_iterator_new_single (GST_TYPE_PAD, &v);
g_value_unset (&v);
gst_object_unref (internal);
}
return res;
}
static GstFlowReturn
gst_proxy_pad_do_chain (GstPad * pad, GstBuffer * buffer)
/**
* gst_proxy_pad_chain_default:
* @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
* @buffer: (transfer full): the #GstBuffer to send, return GST_FLOW_ERROR
* if not.
*
* Invoke the default chain function of the proxy pad.
*
* Returns: a #GstFlowReturn from the pad.
*
* Since: 0.10.35
*/
GstFlowReturn
gst_proxy_pad_chain_default (GstPad * pad, GstBuffer * buffer)
{
GstFlowReturn res;
GstPad *internal = GST_PROXY_PAD_INTERNAL (pad);
GstPad *internal;
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), GST_FLOW_ERROR);
g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
internal = GST_PROXY_PAD_INTERNAL (pad);
res = gst_pad_push (internal, buffer);
return res;
}
static GstFlowReturn
gst_proxy_pad_do_chain_list (GstPad * pad, GstBufferList * list)
/**
* gst_proxy_pad_chain_list_default:
* @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
* @list: (transfer full): the #GstBufferList to send, return GST_FLOW_ERROR
* if not.
*
* Invoke the default chain list function of the proxy pad.
*
* Returns: a #GstFlowReturn from the pad.
*
* Since: 0.10.35
*/
GstFlowReturn
gst_proxy_pad_chain_list_default (GstPad * pad, GstBufferList * list)
{
GstFlowReturn res;
GstPad *internal = GST_PROXY_PAD_INTERNAL (pad);
GstPad *internal;
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), GST_FLOW_ERROR);
g_return_val_if_fail (GST_IS_BUFFER_LIST (list), GST_FLOW_ERROR);
internal = GST_PROXY_PAD_INTERNAL (pad);
res = gst_pad_push_list (internal, list);
return res;
}
static GstFlowReturn
gst_proxy_pad_do_getrange (GstPad * pad, guint64 offset, guint size,
/**
* gst_proxy_pad_get_range_default:
* @pad: a src #GstPad, returns #GST_FLOW_ERROR if not.
* @offset: The start offset of the buffer
* @size: The length of the buffer
* @buffer: (out callee-allocates): a pointer to hold the #GstBuffer,
* returns #GST_FLOW_ERROR if %NULL.
*
* Invoke the default getrange function of the proxy pad.
*
* Returns: a #GstFlowReturn from the pad.
*
* Since: 0.10.35
*/
GstFlowReturn
gst_proxy_pad_getrange_default (GstPad * pad, guint64 offset, guint size,
GstBuffer ** buffer)
{
GstFlowReturn res;
GstPad *internal = GST_PROXY_PAD_INTERNAL (pad);
GstPad *internal;
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), GST_FLOW_ERROR);
g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
internal = GST_PROXY_PAD_INTERNAL (pad);
res = gst_pad_pull_range (internal, offset, size, buffer);
return res;
}
static gboolean
gst_proxy_pad_do_checkgetrange (GstPad * pad)
/**
* gst_proxy_pad_checkgetrange_default:
* @pad: a src #GstPad, returns #GST_FLOW_ERROR if not.
*
* Invoke the default checkgetrange function of the proxy pad.
*
* Returns: a #gboolean from the pad.
*
* Since: 0.10.35
*/
gboolean
gst_proxy_pad_checkgetrange_default (GstPad * pad)
{
gboolean result;
GstPad *internal = GST_PROXY_PAD_INTERNAL (pad);
GstPad *internal;
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
internal = GST_PROXY_PAD_INTERNAL (pad);
result = gst_pad_check_pull_range (internal);
return result;
}
static GstCaps *
gst_proxy_pad_do_getcaps (GstPad * pad, GstCaps * filter)
/**
* gst_proxy_pad_getcaps_default:
* @pad: a #GstPad to get the capabilities of.
* @filter: a #GstCaps filter.
*
* Invoke the default getcaps function of the proxy pad.
*
* Returns: (transfer full): the caps of the pad with incremented ref-count
*
* Since: 0.10.35
*/
GstCaps *
gst_proxy_pad_getcaps_default (GstPad * pad, GstCaps * filter)
{
GstPad *target = gst_proxy_pad_get_target (pad);
GstPad *target;
GstCaps *res;
GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (pad);
GstPadTemplate *templ;
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);
templ = GST_PAD_PAD_TEMPLATE (pad);
target = gst_proxy_pad_get_target (pad);
if (target) {
/* if we have a real target, proxy the call */
res = gst_pad_get_caps (target, filter);
@ -245,12 +384,27 @@ done:
return res;
}
static gboolean
gst_proxy_pad_do_acceptcaps (GstPad * pad, GstCaps * caps)
/**
* gst_proxy_pad_acceptcaps_default:
* @pad: a #GstPad to check
* @caps: a #GstCaps to check on the pad
*
* Invoke the default acceptcaps function of the proxy pad.
*
* Returns: TRUE if the pad can accept the caps.
*
* Since: 0.10.35
*/
gboolean
gst_proxy_pad_acceptcaps_default (GstPad * pad, GstCaps * caps)
{
GstPad *target = gst_proxy_pad_get_target (pad);
GstPad *target;
gboolean res;
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
g_return_val_if_fail (caps == NULL || GST_IS_CAPS (caps), FALSE);
target = gst_proxy_pad_get_target (pad);
if (target) {
res = gst_pad_accept_caps (target, caps);
gst_object_unref (target);
@ -263,23 +417,52 @@ gst_proxy_pad_do_acceptcaps (GstPad * pad, GstCaps * caps)
return res;
}
static void
gst_proxy_pad_do_fixatecaps (GstPad * pad, GstCaps * caps)
/**
* gst_proxy_pad_fixatecaps_default:
* @pad: a #GstPad to fixate
* @caps: the #GstCaps to fixate
*
* Invoke the default fixatecaps function of the proxy pad.
*
* Since: 0.10.35
*/
void
gst_proxy_pad_fixatecaps_default (GstPad * pad, GstCaps * caps)
{
GstPad *target = gst_proxy_pad_get_target (pad);
GstPad *target;
g_return_if_fail (GST_IS_PROXY_PAD (pad));
g_return_if_fail (GST_IS_CAPS (caps));
target = gst_proxy_pad_get_target (pad);
if (target) {
gst_pad_fixate_caps (target, caps);
gst_object_unref (target);
}
}
static gboolean
gst_proxy_pad_do_setcaps (GstPad * pad, GstCaps * caps)
/**
* gst_proxy_pad_setcaps_default:
* @pad: a #GstPad to set the capabilities of.
* @caps: (transfer none): a #GstCaps to set.
*
* Invoke the default setcaps function of the proxy pad.
*
* Returns: TRUE if the caps could be set. FALSE if the caps were not fixed
* or bad parameters were provided to this function.
*
* Since: 0.10.35
*/
gboolean
gst_proxy_pad_setcaps_default (GstPad * pad, GstCaps * caps)
{
GstPad *target = gst_proxy_pad_get_target (pad);
GstPad *target;
gboolean res;
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
g_return_val_if_fail (caps == NULL || GST_IS_CAPS (caps), FALSE);
target = gst_proxy_pad_get_target (pad);
if (target) {
res = gst_pad_set_caps (target, caps);
gst_object_unref (target);
@ -353,22 +536,46 @@ gst_proxy_pad_get_target (GstPad * pad)
return target;
}
static GstPad *
gst_proxy_pad_get_internal (GstPad * pad)
/**
* gst_proxy_pad_get_internal:
* @pad: the #GstProxyPad
*
* Get the internal pad of @pad. Unref target pad after usage.
*
* The internal pad of a #GstGhostPad is the internally used
* pad of opposite direction, which is used to link to the target.
*
* Returns: (transfer full): the target #GstProxyPad, can be NULL.
* Unref target pad after usage.
*
* Since: 0.10.35
*/
GstProxyPad *
gst_proxy_pad_get_internal (GstProxyPad * pad)
{
GstPad *internal;
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);
GST_PROXY_LOCK (pad);
internal = GST_PROXY_PAD_INTERNAL (pad);
if (internal)
gst_object_ref (internal);
GST_PROXY_UNLOCK (pad);
return internal;
return GST_PROXY_PAD_CAST (internal);
}
static void
gst_proxy_pad_do_unlink (GstPad * pad)
/**
* gst_proxy_pad_unlink_default:
* @pad: a #GstPad to unlink
*
* Invoke the default unlink function of the proxy pad.
*
* Since: 0.10.35
*/
void
gst_proxy_pad_unlink_default (GstPad * pad)
{
GstPad *internal;
@ -396,19 +603,19 @@ gst_proxy_pad_class_init (GstProxyPadClass * klass)
gobject_class->finalize = gst_proxy_pad_finalize;
/* Register common function pointer descriptions */
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_query_type);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_event);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_query);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_iterate_internal_links);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_getcaps);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_acceptcaps);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_fixatecaps);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_setcaps);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_unlink);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_chain);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_chain_list);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_getrange);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_checkgetrange);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_query_type_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_event_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_query_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_iterate_internal_links_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_getcaps_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_acceptcaps_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_fixatecaps_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_setcaps_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_unlink_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_chain_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_chain_list_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_getrange_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_checkgetrange_default);
}
static void
@ -449,17 +656,17 @@ gst_proxy_pad_init (GstProxyPad * ppad)
GST_TYPE_PROXY_PAD, GstProxyPadPrivate);
GST_PROXY_GET_LOCK (pad) = g_mutex_new ();
gst_pad_set_query_type_function (pad, gst_proxy_pad_do_query_type);
gst_pad_set_event_function (pad, gst_proxy_pad_do_event);
gst_pad_set_query_function (pad, gst_proxy_pad_do_query);
gst_pad_set_query_type_function (pad, gst_proxy_pad_query_type_default);
gst_pad_set_event_function (pad, gst_proxy_pad_event_default);
gst_pad_set_query_function (pad, gst_proxy_pad_query_default);
gst_pad_set_iterate_internal_links_function (pad,
gst_proxy_pad_do_iterate_internal_links);
gst_proxy_pad_iterate_internal_links_default);
gst_pad_set_getcaps_function (pad, gst_proxy_pad_do_getcaps);
gst_pad_set_acceptcaps_function (pad, gst_proxy_pad_do_acceptcaps);
gst_pad_set_fixatecaps_function (pad, gst_proxy_pad_do_fixatecaps);
gst_pad_set_setcaps_function (pad, gst_proxy_pad_do_setcaps);
gst_pad_set_unlink_function (pad, gst_proxy_pad_do_unlink);
gst_pad_set_getcaps_function (pad, gst_proxy_pad_getcaps_default);
gst_pad_set_acceptcaps_function (pad, gst_proxy_pad_acceptcaps_default);
gst_pad_set_fixatecaps_function (pad, gst_proxy_pad_fixatecaps_default);
gst_pad_set_setcaps_function (pad, gst_proxy_pad_setcaps_default);
gst_pad_set_unlink_function (pad, gst_proxy_pad_unlink_default);
}
@ -482,13 +689,26 @@ G_DEFINE_TYPE (GstGhostPad, gst_ghost_pad, GST_TYPE_PROXY_PAD);
static void gst_ghost_pad_dispose (GObject * object);
/* see gstghostpad design docs */
static gboolean
gst_ghost_pad_internal_do_activate_push (GstPad * pad, gboolean active)
/**
* gst_ghost_pad_internal_activate_push_default:
* @pad: the #GstPad to activate or deactivate.
* @active: whether the pad should be active or not.
*
* Invoke the default activate push function of a proxy pad that is
* owned by a ghost pad.
*
* Returns: %TRUE if the operation was successful.
*
* Since: 0.10.35
*/
gboolean
gst_ghost_pad_internal_activate_push_default (GstPad * pad, gboolean active)
{
gboolean ret;
GstPad *other;
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
GST_LOG_OBJECT (pad, "%sactivate push on %s:%s, we're ok",
(active ? "" : "de"), GST_DEBUG_PAD_NAME (pad));
@ -500,12 +720,26 @@ gst_ghost_pad_internal_do_activate_push (GstPad * pad, gboolean active)
return ret;
}
static gboolean
gst_ghost_pad_internal_do_activate_pull (GstPad * pad, gboolean active)
/**
* gst_ghost_pad_internal_activate_pull_default:
* @pad: the #GstPad to activate or deactivate.
* @active: whether the pad should be active or not.
*
* Invoke the default activate pull function of a proxy pad that is
* owned by a ghost pad.
*
* Returns: %TRUE if the operation was successful.
*
* Since: 0.10.35
*/
gboolean
gst_ghost_pad_internal_activate_pull_default (GstPad * pad, gboolean active)
{
gboolean ret;
GstPad *other;
g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
GST_LOG_OBJECT (pad, "%sactivate pull on %s:%s", (active ? "" : "de"),
GST_DEBUG_PAD_NAME (pad));
@ -513,7 +747,7 @@ gst_ghost_pad_internal_do_activate_pull (GstPad * pad, gboolean active)
/* we are activated in pull mode by our peer element, which is a sinkpad
* that wants to operate in pull mode. This activation has to propagate
* upstream throught the pipeline. We call the internal activation function,
* which will trigger gst_ghost_pad_do_activate_pull, which propagates even
* which will trigger gst_ghost_pad_activate_pull_default, which propagates even
* further upstream */
GST_LOG_OBJECT (pad, "pad is src, activate internal");
other = GST_PROXY_PAD_INTERNAL (pad);
@ -533,12 +767,25 @@ gst_ghost_pad_internal_do_activate_pull (GstPad * pad, gboolean active)
return ret;
}
static gboolean
gst_ghost_pad_do_activate_push (GstPad * pad, gboolean active)
/**
* gst_ghost_pad_activate_push_default:
* @pad: the #GstPad to activate or deactivate.
* @active: whether the pad should be active or not.
*
* Invoke the default activate push function of a ghost pad.
*
* Returns: %TRUE if the operation was successful.
*
* Since: 0.10.35
*/
gboolean
gst_ghost_pad_activate_push_default (GstPad * pad, gboolean active)
{
gboolean ret;
GstPad *other;
g_return_val_if_fail (GST_IS_GHOST_PAD (pad), FALSE);
GST_LOG_OBJECT (pad, "%sactivate push on %s:%s, proxy internal",
(active ? "" : "de"), GST_DEBUG_PAD_NAME (pad));
@ -549,12 +796,25 @@ gst_ghost_pad_do_activate_push (GstPad * pad, gboolean active)
return ret;
}
static gboolean
gst_ghost_pad_do_activate_pull (GstPad * pad, gboolean active)
/**
* gst_ghost_pad_activate_pull_default:
* @pad: the #GstPad to activate or deactivate.
* @active: whether the pad should be active or not.
*
* Invoke the default activate pull function of a ghost pad.
*
* Returns: %TRUE if the operation was successful.
*
* Since: 0.10.35
*/
gboolean
gst_ghost_pad_activate_pull_default (GstPad * pad, gboolean active)
{
gboolean ret;
GstPad *other;
g_return_val_if_fail (GST_IS_GHOST_PAD (pad), FALSE);
GST_LOG_OBJECT (pad, "%sactivate pull on %s:%s", (active ? "" : "de"),
GST_DEBUG_PAD_NAME (pad));
@ -580,12 +840,26 @@ gst_ghost_pad_do_activate_pull (GstPad * pad, gboolean active)
return ret;
}
static GstPadLinkReturn
gst_ghost_pad_do_link (GstPad * pad, GstPad * peer)
/**
* gst_ghost_pad_link_default:
* @pad: the #GstPad to link.
* @peer: the #GstPad peer
*
* Invoke the default link function of a ghost pad.
*
* Returns: #GstPadLinkReturn of the operation
*
* Since: 0.10.35
*/
GstPadLinkReturn
gst_ghost_pad_link_default (GstPad * pad, GstPad * peer)
{
GstPadLinkReturn ret;
GstPad *internal;
g_return_val_if_fail (GST_IS_GHOST_PAD (pad), GST_PAD_LINK_REFUSED);
g_return_val_if_fail (GST_IS_PAD (peer), GST_PAD_LINK_REFUSED);
GST_DEBUG_OBJECT (pad, "linking ghostpad");
internal = GST_PROXY_PAD_INTERNAL (pad);
@ -619,11 +893,21 @@ link_failed:
}
}
static void
gst_ghost_pad_do_unlink (GstPad * pad)
/**
* gst_ghost_pad_unlink_default:
* @pad: the #GstPad to link.
*
* Invoke the default unlink function of a ghost pad.
*
* Since: 0.10.35
*/
void
gst_ghost_pad_unlink_default (GstPad * pad)
{
GstPad *internal;
g_return_if_fail (GST_IS_GHOST_PAD (pad));
internal = GST_PROXY_PAD_INTERNAL (pad);
GST_DEBUG_OBJECT (pad, "unlinking ghostpad");
@ -722,31 +1006,27 @@ done:
gst_caps_unref (caps);
}
static gboolean
gst_ghost_pad_do_setcaps (GstPad * pad, GstCaps * caps)
/**
* gst_ghost_pad_setcaps_default:
* @pad: the #GstPad to link.
* @caps: (transfer none): the #GstCaps to set
*
* Invoke the default setcaps function of a ghost pad.
*
* Returns: %TRUE if the operation was successful
*
* Since: 0.10.35
*/
gboolean
gst_ghost_pad_setcaps_default (GstPad * pad, GstCaps * caps)
{
g_return_val_if_fail (GST_IS_GHOST_PAD (pad), FALSE);
g_return_val_if_fail (caps == NULL || GST_IS_CAPS (caps), FALSE);
if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
return TRUE;
return gst_proxy_pad_do_setcaps (pad, caps);
}
static GstIterator *
gst_ghost_pad_do_iterate_internal_links (GstPad * pad)
{
GstIterator *res = NULL;
GstPad *internal = GST_PROXY_PAD_INTERNAL (GST_GHOST_PAD_CAST (pad));
if (internal) {
GValue v = { 0, };
g_value_init (&v, GST_TYPE_PAD);
g_value_set_object (&v, internal);
res = gst_iterator_new_single (GST_TYPE_PAD, &v);
g_value_unset (&v);
}
return res;
return gst_proxy_pad_setcaps_default (pad, caps);
}
static void
@ -760,10 +1040,10 @@ gst_ghost_pad_class_init (GstGhostPadClass * klass)
gobject_class->dispose = gst_ghost_pad_dispose;
GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_do_setcaps);
GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_do_activate_pull);
GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_do_activate_push);
GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_do_link);
GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_setcaps_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_activate_pull_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_activate_push_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_link_default);
}
static void
@ -772,13 +1052,12 @@ gst_ghost_pad_init (GstGhostPad * pad)
GST_GHOST_PAD_PRIVATE (pad) = G_TYPE_INSTANCE_GET_PRIVATE (pad,
GST_TYPE_GHOST_PAD, GstGhostPadPrivate);
gst_pad_set_setcaps_function (GST_PAD_CAST (pad), gst_ghost_pad_do_setcaps);
gst_pad_set_setcaps_function (GST_PAD_CAST (pad),
gst_ghost_pad_setcaps_default);
gst_pad_set_activatepull_function (GST_PAD_CAST (pad),
gst_ghost_pad_do_activate_pull);
gst_ghost_pad_activate_pull_default);
gst_pad_set_activatepush_function (GST_PAD_CAST (pad),
gst_ghost_pad_do_activate_push);
gst_pad_set_iterate_internal_links_function (GST_PAD_CAST (pad),
gst_ghost_pad_do_iterate_internal_links);
gst_ghost_pad_activate_push_default);
}
static void
@ -795,7 +1074,7 @@ gst_ghost_pad_dispose (GObject * object)
gst_ghost_pad_set_target (GST_GHOST_PAD (pad), NULL);
/* Unlink here so that gst_pad_dispose doesn't. That would lead to a call to
* gst_ghost_pad_do_unlink when the ghost pad is in an inconsistent state */
* gst_ghost_pad_unlink_default when the ghost pad is in an inconsistent state */
peer = gst_pad_get_peer (pad);
if (peer) {
if (GST_PAD_IS_SRC (pad))
@ -859,16 +1138,17 @@ gst_ghost_pad_construct (GstGhostPad * gpad)
/* Set directional padfunctions for ghostpad */
if (dir == GST_PAD_SINK) {
gst_pad_set_chain_function (pad, gst_proxy_pad_do_chain);
gst_pad_set_chain_list_function (pad, gst_proxy_pad_do_chain_list);
gst_pad_set_chain_function (pad, gst_proxy_pad_chain_default);
gst_pad_set_chain_list_function (pad, gst_proxy_pad_chain_list_default);
} else {
gst_pad_set_getrange_function (pad, gst_proxy_pad_do_getrange);
gst_pad_set_checkgetrange_function (pad, gst_proxy_pad_do_checkgetrange);
gst_pad_set_getrange_function (pad, gst_proxy_pad_getrange_default);
gst_pad_set_checkgetrange_function (pad,
gst_proxy_pad_checkgetrange_default);
}
/* link/unlink functions */
gst_pad_set_link_function (pad, gst_ghost_pad_do_link);
gst_pad_set_unlink_function (pad, gst_ghost_pad_do_unlink);
gst_pad_set_link_function (pad, gst_ghost_pad_link_default);
gst_pad_set_unlink_function (pad, gst_ghost_pad_unlink_default);
/* INTERNAL PAD, it always exists and is child of the ghostpad */
otherdir = (dir == GST_PAD_SRC) ? GST_PAD_SINK : GST_PAD_SRC;
@ -887,12 +1167,13 @@ gst_ghost_pad_construct (GstGhostPad * gpad)
/* Set directional padfunctions for internal pad */
if (dir == GST_PAD_SRC) {
gst_pad_set_chain_function (internal, gst_proxy_pad_do_chain);
gst_pad_set_chain_list_function (internal, gst_proxy_pad_do_chain_list);
gst_pad_set_chain_function (internal, gst_proxy_pad_chain_default);
gst_pad_set_chain_list_function (internal,
gst_proxy_pad_chain_list_default);
} else {
gst_pad_set_getrange_function (internal, gst_proxy_pad_do_getrange);
gst_pad_set_getrange_function (internal, gst_proxy_pad_getrange_default);
gst_pad_set_checkgetrange_function (internal,
gst_proxy_pad_do_checkgetrange);
gst_proxy_pad_checkgetrange_default);
}
GST_PROXY_LOCK (pad);
@ -924,9 +1205,9 @@ gst_ghost_pad_construct (GstGhostPad * gpad)
/* special activation functions for the internal pad */
gst_pad_set_activatepull_function (internal,
gst_ghost_pad_internal_do_activate_pull);
gst_ghost_pad_internal_activate_pull_default);
gst_pad_set_activatepush_function (internal,
gst_ghost_pad_internal_do_activate_push);
gst_ghost_pad_internal_activate_push_default);
GST_PROXY_UNLOCK (pad);

View file

@ -59,6 +59,22 @@ struct _GstProxyPadClass
GType gst_proxy_pad_get_type (void);
GstProxyPad* gst_proxy_pad_get_internal (GstProxyPad *pad);
const GstQueryType* gst_proxy_pad_query_type_default (GstPad *pad);
gboolean gst_proxy_pad_event_default (GstPad *pad, GstEvent *event);
gboolean gst_proxy_pad_query_default (GstPad *pad, GstQuery **query);
GstIterator* gst_proxy_pad_iterate_internal_links_default (GstPad *pad);
GstFlowReturn gst_proxy_pad_chain_default (GstPad *pad, GstBuffer *buf);
GstFlowReturn gst_proxy_pad_chain_list_default (GstPad *pad, GstBufferList *list);
GstFlowReturn gst_proxy_pad_getrange_default (GstPad *pad, guint64 offset, guint size, GstBuffer **buffer);
gboolean gst_proxy_pad_checkgetrange_default (GstPad *pad);
GstCaps* gst_proxy_pad_getcaps_default (GstPad *pad, GstCaps * filter);
gboolean gst_proxy_pad_acceptcaps_default (GstPad *pad, GstCaps *caps);
void gst_proxy_pad_fixatecaps_default (GstPad *pad, GstCaps *caps);
gboolean gst_proxy_pad_setcaps_default (GstPad *pad, GstCaps *caps);
void gst_proxy_pad_unlink_default (GstPad * pad);
#define GST_TYPE_GHOST_PAD (gst_ghost_pad_get_type ())
#define GST_IS_GHOST_PAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_GHOST_PAD))
@ -106,6 +122,15 @@ gboolean gst_ghost_pad_set_target (GstGhostPad *gpad, GstPad *newtarget);
gboolean gst_ghost_pad_construct (GstGhostPad *gpad);
gboolean gst_ghost_pad_setcaps_default (GstPad * pad, GstCaps * caps);
void gst_ghost_pad_unlink_default (GstPad * pad);
GstPadLinkReturn gst_ghost_pad_link_default (GstPad * pad, GstPad * peer);
gboolean gst_ghost_pad_activate_pull_default (GstPad * pad, gboolean active);
gboolean gst_ghost_pad_activate_push_default (GstPad * pad, gboolean active);
gboolean gst_ghost_pad_internal_activate_push_default (GstPad * pad, gboolean active);
gboolean gst_ghost_pad_internal_activate_pull_default (GstPad * pad, gboolean active);
G_END_DECLS
#endif /* __GST_GHOST_PAD_H__ */

View file

@ -45,8 +45,8 @@
static GstAllocTrace *_gst_mini_object_trace;
#endif
#define GST_MINI_OBJECT_GET_CLASS_UNCHECKED(obj) \
((GstMiniObjectClass *) (((GTypeInstance*)(obj))->g_class))
/* Mutex used for weak referencing */
G_LOCK_DEFINE_STATIC (weak_refs_mutex);
/* boxed copy and free functions. Don't real copy or free but simply
* change the refcount */
@ -109,6 +109,8 @@ gst_mini_object_init (GstMiniObject * mini_object, GType type, gsize size)
mini_object->refcount = 1;
mini_object->flags = 0;
mini_object->size = size;
mini_object->n_weak_refs = 0;
mini_object->weak_refs = NULL;
}
/**
@ -223,6 +225,16 @@ gst_mini_object_ref (GstMiniObject * mini_object)
return mini_object;
}
static void
weak_refs_notify (GstMiniObject * obj)
{
guint i;
for (i = 0; i < obj->n_weak_refs; i++)
obj->weak_refs[i].notify (obj->weak_refs[i].data, obj);
g_free (obj->weak_refs);
}
/**
* gst_mini_object_unref:
* @mini_object: the mini-object
@ -253,6 +265,10 @@ gst_mini_object_unref (GstMiniObject * mini_object)
/* decrement the refcount again, if the subclass recycled the object we don't
* want to free the instance anymore */
if (G_LIKELY (g_atomic_int_dec_and_test (&mini_object->refcount))) {
/* The weak reference stack is freed in the notification function */
if (mini_object->n_weak_refs)
weak_refs_notify (mini_object);
#ifndef GST_DISABLE_TRACE
gst_alloc_trace_free (_gst_mini_object_trace, mini_object);
#endif
@ -299,3 +315,95 @@ gst_mini_object_replace (GstMiniObject ** olddata, GstMiniObject * newdata)
if (olddata_val)
gst_mini_object_unref (olddata_val);
}
/**
* gst_mini_object_weak_ref: (skip)
* @mini_object: #GstMiniObject to reference weakly
* @notify: callback to invoke before the mini object is freed
* @data: extra data to pass to notify
*
* Adds a weak reference callback to a mini object. Weak references are
* used for notification when a mini object is finalized. They are called
* "weak references" because they allow you to safely hold a pointer
* to the mini object without calling gst_mini_object_ref()
* (gst_mini_object_ref() adds a strong reference, that is, forces the object
* to stay alive).
*
* Since: 0.10.35
*/
void
gst_mini_object_weak_ref (GstMiniObject * object,
GstMiniObjectWeakNotify notify, gpointer data)
{
guint i;
g_return_if_fail (object != NULL);
g_return_if_fail (notify != NULL);
g_return_if_fail (GST_MINI_OBJECT_REFCOUNT_VALUE (object) >= 1);
G_LOCK (weak_refs_mutex);
if (object->n_weak_refs) {
/* Don't add the weak reference if it already exists. */
for (i = 0; i < object->n_weak_refs; i++) {
if (object->weak_refs[i].notify == notify &&
object->weak_refs[i].data == data) {
g_warning ("%s: Attempt to re-add existing weak ref %p(%p) failed.",
G_STRFUNC, notify, data);
goto found;
}
}
i = object->n_weak_refs++;
object->weak_refs =
g_realloc (object->weak_refs, sizeof (object->weak_refs[0]) * i);
} else {
object->weak_refs = g_malloc0 (sizeof (object->weak_refs[0]));
object->n_weak_refs = 1;
i = 0;
}
object->weak_refs[i].notify = notify;
object->weak_refs[i].data = data;
found:
G_UNLOCK (weak_refs_mutex);
}
/**
* gst_mini_object_weak_unref: (skip)
* @mini_object: #GstMiniObject to remove a weak reference from
* @notify: callback to search for
* @data: data to search for
*
* Removes a weak reference callback to a mini object.
*
* Since: 0.10.35
*/
void
gst_mini_object_weak_unref (GstMiniObject * object,
GstMiniObjectWeakNotify notify, gpointer data)
{
gboolean found_one = FALSE;
g_return_if_fail (object != NULL);
g_return_if_fail (notify != NULL);
G_LOCK (weak_refs_mutex);
if (object->n_weak_refs) {
guint i;
for (i = 0; i < object->n_weak_refs; i++)
if (object->weak_refs[i].notify == notify &&
object->weak_refs[i].data == data) {
found_one = TRUE;
object->n_weak_refs -= 1;
if (i != object->n_weak_refs)
object->weak_refs[i] = object->weak_refs[object->n_weak_refs];
break;
}
}
G_UNLOCK (weak_refs_mutex);
if (!found_one)
g_warning ("%s: couldn't find weak ref %p(%p)", G_STRFUNC, notify, data);
}

View file

@ -65,6 +65,22 @@ typedef void (*GstMiniObjectDisposeFunction) (GstMiniObject *obj);
*/
typedef void (*GstMiniObjectFreeFunction) (GstMiniObject *obj);
/**
* GstMiniObjectWeakNotify:
* @data: data that was provided when the weak reference was established
* @where_the_mini_object_was: the mini object being finalized
*
* A #GstMiniObjectWeakNotify function can be added to a mini object as a
* callback that gets triggered when the mini object is finalized. Since the
* mini object is already being finalized when the #GstMiniObjectWeakNotify is
* called, there's not much you could do with the object, apart from e.g. using
* its adress as hash-index or the like.
*
* Since: 0.10.35
*/
typedef void (*GstMiniObjectWeakNotify) (gpointer data,
GstMiniObject * where_the_mini_object_was);
/**
* GST_MINI_OBJECT_FLAGS:
* @obj: MiniObject to return flags for.
@ -165,6 +181,15 @@ struct _GstMiniObject {
GstMiniObjectCopyFunction copy;
GstMiniObjectDisposeFunction dispose;
GstMiniObjectFreeFunction free;
/* < private > */
/* Used to keep track of weak ref notifies */
guint n_weak_refs;
struct
{
GstMiniObjectWeakNotify notify;
gpointer data;
} *weak_refs;
};
GType gst_mini_object_register (const gchar *name);
@ -180,6 +205,13 @@ GstMiniObject* gst_mini_object_make_writable (GstMiniObject *mini_object);
GstMiniObject* gst_mini_object_ref (GstMiniObject *mini_object);
void gst_mini_object_unref (GstMiniObject *mini_object);
void gst_mini_object_weak_ref (GstMiniObject *object,
GstMiniObjectWeakNotify notify,
gpointer data);
void gst_mini_object_weak_unref (GstMiniObject *object,
GstMiniObjectWeakNotify notify,
gpointer data);
void gst_mini_object_replace (GstMiniObject **olddata, GstMiniObject *newdata);

View file

@ -326,9 +326,16 @@ gst_system_clock_add_wakeup (GstSystemClock * sysclock)
if (sysclock->priv->wakeup_count == 0) {
GST_CAT_DEBUG (GST_CAT_CLOCK, "writing control");
while (!gst_poll_write_control (sysclock->priv->timer)) {
g_warning
("gstsystemclock: write control failed in wakeup_async, trying again : %d:%s\n",
errno, g_strerror (errno));
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
g_warning
("gstsystemclock: write control failed in wakeup_async, trying again: %d:%s\n",
errno, g_strerror (errno));
} else {
g_critical
("gstsystemclock: write control failed in wakeup_async: %d:%s\n",
errno, g_strerror (errno));
return;
}
}
}
sysclock->priv->wakeup_count++;

View file

@ -38,6 +38,28 @@ hierarchy, and a set of media-agnostic core elements.
</GitRepository>
</repository>
<release>
<Version>
<revision>0.10.34</revision>
<branch>0.10</branch>
<name>Misfits</name>
<created>2011-05-13</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-0.10.34.tar.bz2" />
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-0.10.34.tar.gz" />
</Version>
</release>
<release>
<Version>
<revision>0.10.33</revision>
<branch>0.10</branch>
<name>Prior Spaceflight Experience is an Advantage</name>
<created>2011-05-10</created>
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-0.10.33.tar.bz2" />
<file-release rdf:resource="http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-0.10.33.tar.gz" />
</Version>
</release>
<release>
<Version>
<revision>0.10.32</revision>

View file

@ -2112,7 +2112,7 @@ again:
/* no timestamp set and we are at offset 0, we can timestamp with 0 */
if (offset == 0 && src->segment.time == 0
&& GST_BUFFER_TIMESTAMP (*buf) == -1) {
&& GST_BUFFER_TIMESTAMP (*buf) == -1 && !src->is_live) {
*buf = gst_buffer_make_writable (*buf);
GST_BUFFER_TIMESTAMP (*buf) = 0;
}

View file

@ -95,9 +95,12 @@ enum
{
PROP_0,
PROP_N_PADS,
PROP_ACTIVE_PAD
PROP_ACTIVE_PAD,
PROP_SYNC_STREAMS
};
#define DEFAULT_SYNC_STREAMS FALSE
#define DEFAULT_PAD_ALWAYS_OK TRUE
enum
@ -520,6 +523,105 @@ gst_input_selector_wait (GstInputSelector * self, GstSelectorPad * pad)
return self->flushing;
}
/* must be called with the SELECTOR_LOCK, will block until the running time
* of the active pad is after this pad or return TRUE when flushing */
static gboolean
gst_input_selector_wait_running_time (GstInputSelector * sel,
GstSelectorPad * pad, GstBuffer * buf)
{
GstPad *active_sinkpad;
GstSelectorPad *active_selpad;
GstSegment *seg, *active_seg;
GstClockTime running_time, active_running_time = -1;
seg = &pad->segment;
active_sinkpad =
gst_input_selector_activate_sinkpad (sel, GST_PAD_CAST (pad));
active_selpad = GST_SELECTOR_PAD_CAST (active_sinkpad);
active_seg = &active_selpad->segment;
/* We can only sync if the segments are in time format or
* if the active pad had no newsegment event yet */
if (seg->format != GST_FORMAT_TIME ||
(active_seg->format != GST_FORMAT_TIME
&& active_seg->format != GST_FORMAT_UNDEFINED))
return FALSE;
/* If we have no valid timestamp we can't sync this buffer */
if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf))
return FALSE;
running_time = GST_BUFFER_TIMESTAMP (buf);
/* If possible try to get the running time at the end of the buffer */
if (GST_BUFFER_DURATION_IS_VALID (buf))
running_time += GST_BUFFER_DURATION (buf);
if (running_time > seg->stop)
running_time = seg->stop;
running_time =
gst_segment_to_running_time (seg, GST_FORMAT_TIME, running_time);
/* If this is outside the segment don't sync */
if (running_time == -1)
return FALSE;
/* Get active pad's running time, if no configured segment yet keep at -1 */
if (active_seg->format == GST_FORMAT_TIME)
active_running_time =
gst_segment_to_running_time (active_seg, GST_FORMAT_TIME,
active_seg->position);
/* Wait until
* a) this is the active pad
* b) the pad or the selector is flushing
* c) the selector is not blocked
* d) the active pad has no running time or the active
* pad's running time is before this running time
* e) the active pad has a non-time segment
*/
while (pad != active_selpad && !sel->flushing && !pad->flushing &&
(sel->blocked || active_running_time == -1
|| running_time >= active_running_time)) {
if (!sel->blocked)
GST_DEBUG_OBJECT (pad,
"Waiting for active streams to advance. %" GST_TIME_FORMAT " >= %"
GST_TIME_FORMAT, GST_TIME_ARGS (running_time),
GST_TIME_ARGS (active_running_time));
GST_INPUT_SELECTOR_WAIT (sel);
/* Get new active pad, it might have changed */
active_sinkpad =
gst_input_selector_activate_sinkpad (sel, GST_PAD_CAST (pad));
active_selpad = GST_SELECTOR_PAD_CAST (active_sinkpad);
active_seg = &active_selpad->segment;
/* If the active segment is configured but not to time format
* we can't do any syncing at all */
if (active_seg->format != GST_FORMAT_TIME
&& active_seg->format != GST_FORMAT_UNDEFINED)
break;
/* Get the new active pad running time */
if (active_seg->format == GST_FORMAT_TIME)
active_running_time =
gst_segment_to_running_time (active_seg, GST_FORMAT_TIME,
active_seg->position);
else
active_running_time = -1;
if (!sel->blocked)
GST_DEBUG_OBJECT (pad,
"Waited for active streams to advance. %" GST_TIME_FORMAT " >= %"
GST_TIME_FORMAT, GST_TIME_ARGS (running_time),
GST_TIME_ARGS (active_running_time));
}
/* Return TRUE if the selector or the pad is flushing */
return (sel->flushing || pad->flushing);
}
static GstFlowReturn
gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
{
@ -549,6 +651,16 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
prev_active_sinkpad = sel->active_sinkpad;
active_sinkpad = gst_input_selector_activate_sinkpad (sel, pad);
/* In sync mode wait until the active pad has advanced
* after the running time of the current buffer */
if (sel->sync_streams && active_sinkpad != pad) {
if (gst_input_selector_wait_running_time (sel, selpad, buf))
goto flushing;
}
/* Might have changed while waiting */
active_sinkpad = gst_input_selector_activate_sinkpad (sel, pad);
/* update the segment on the srcpad */
start_time = GST_BUFFER_TIMESTAMP (buf);
if (GST_CLOCK_TIME_IS_VALID (start_time)) {
@ -567,6 +679,10 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
if (pad != active_sinkpad)
goto ignore;
/* Tell all non-active pads that we advanced the running time */
if (sel->sync_streams)
GST_INPUT_SELECTOR_BROADCAST (sel);
/* if we have a pending segment, push it out now */
if (G_UNLIKELY (selpad->segment_pending)) {
GST_DEBUG_OBJECT (pad,
@ -763,6 +879,21 @@ gst_input_selector_class_init (GstInputSelectorClass * klass)
"The currently active sink pad", GST_TYPE_PAD,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstInputSelector:sync-streams
*
* If set to %TRUE all inactive streams will be synced to the
* running time of the active stream. This makes sure that no
* buffers are dropped by input-selector that might be needed
* when switching the active pad.
*
* Since: 0.10.35
*/
g_object_class_install_property (gobject_class, PROP_SYNC_STREAMS,
g_param_spec_boolean ("sync-streams", "Sync Streams",
"Synchronize inactive streams to the running time of the active stream",
DEFAULT_SYNC_STREAMS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstInputSelector::block:
* @inputselector: the #GstInputSelector
@ -864,6 +995,7 @@ gst_input_selector_init (GstInputSelector * sel)
sel->active_sinkpad = NULL;
sel->padcount = 0;
gst_segment_init (&sel->segment, GST_FORMAT_UNDEFINED);
sel->sync_streams = DEFAULT_SYNC_STREAMS;
sel->lock = g_mutex_new ();
sel->cond = g_cond_new ();
@ -979,6 +1111,12 @@ gst_input_selector_set_active_pad (GstInputSelector * self,
active_pad_p = &self->active_sinkpad;
gst_object_replace ((GstObject **) active_pad_p, GST_OBJECT_CAST (pad));
/* Wake up all non-active pads in sync mode, they might be
* the active pad now */
if (self->sync_streams)
GST_INPUT_SELECTOR_BROADCAST (self);
GST_DEBUG_OBJECT (self, "New active pad is %" GST_PTR_FORMAT,
self->active_sinkpad);
@ -1004,6 +1142,13 @@ gst_input_selector_set_property (GObject * object, guint prop_id,
GST_INPUT_SELECTOR_UNLOCK (sel);
break;
}
case PROP_SYNC_STREAMS:
{
GST_INPUT_SELECTOR_LOCK (sel);
sel->sync_streams = g_value_get_boolean (value);
GST_INPUT_SELECTOR_UNLOCK (sel);
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1027,6 +1172,11 @@ gst_input_selector_get_property (GObject * object, guint prop_id,
g_value_set_object (value, sel->active_sinkpad);
GST_INPUT_SELECTOR_UNLOCK (object);
break;
case PROP_SYNC_STREAMS:
GST_INPUT_SELECTOR_LOCK (object);
g_value_set_boolean (value, sel->sync_streams);
GST_INPUT_SELECTOR_UNLOCK (object);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;

View file

@ -56,6 +56,7 @@ struct _GstInputSelector {
GstPad *active_sinkpad;
guint n_pads;
guint padcount;
gboolean sync_streams;
GstSegment segment; /* the output segment */
gboolean pending_close; /* if we should push a close first */

View file

@ -156,6 +156,8 @@ struct _GstSingleQueue
guint32 nextid; /* ID of the next object waiting to be pushed */
guint32 oldid; /* ID of the last object pushed (last in a series) */
guint32 last_oldid; /* Previously observed old_id, reset to MAXUINT32 on flush */
GstClockTime next_time; /* End running time of next buffer to be pushed */
GstClockTime last_time; /* Start running time of last pushed buffer */
GCond *turn; /* SingleQueue turn waiting conditional */
};
@ -179,6 +181,7 @@ static void gst_single_queue_free (GstSingleQueue * squeue);
static void wake_up_next_non_linked (GstMultiQueue * mq);
static void compute_high_id (GstMultiQueue * mq);
static void compute_high_time (GstMultiQueue * mq);
static void single_queue_overrun_cb (GstDataQueue * dq, GstSingleQueue * sq);
static void single_queue_underrun_cb (GstDataQueue * dq, GstSingleQueue * sq);
@ -224,6 +227,7 @@ enum
#define DEFAULT_USE_BUFFERING FALSE
#define DEFAULT_LOW_PERCENT 10
#define DEFAULT_HIGH_PERCENT 99
#define DEFAULT_SYNC_BY_RUNNING_TIME FALSE
enum
{
@ -237,6 +241,7 @@ enum
PROP_USE_BUFFERING,
PROP_LOW_PERCENT,
PROP_HIGH_PERCENT,
PROP_SYNC_BY_RUNNING_TIME,
PROP_LAST
};
@ -382,6 +387,22 @@ gst_multi_queue_class_init (GstMultiQueueClass * klass)
"High threshold for buffering to finish", 0, 100,
DEFAULT_HIGH_PERCENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstMultiQueue:sync-by-running-time
*
* If enabled multiqueue will synchronize deactivated or not-linked streams
* to the activated and linked streams by taking the running time.
* Otherwise multiqueue will synchronize the deactivated or not-linked
* streams by keeping the order in which buffers and events arrived compared
* to active and linked streams.
*
* Since: 0.10.35
*/
g_object_class_install_property (gobject_class, PROP_SYNC_BY_RUNNING_TIME,
g_param_spec_boolean ("sync-by-running-time", "Sync By Running Time",
"Synchronize deactivated or not-linked streams by running time",
DEFAULT_SYNC_BY_RUNNING_TIME,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gobject_class->finalize = gst_multi_queue_finalize;
@ -419,8 +440,11 @@ gst_multi_queue_init (GstMultiQueue * mqueue)
mqueue->low_percent = DEFAULT_LOW_PERCENT;
mqueue->high_percent = DEFAULT_HIGH_PERCENT;
mqueue->sync_by_running_time = DEFAULT_SYNC_BY_RUNNING_TIME;
mqueue->counter = 1;
mqueue->highid = -1;
mqueue->high_time = GST_CLOCK_TIME_NONE;
mqueue->qlock = g_mutex_new ();
}
@ -493,6 +517,9 @@ gst_multi_queue_set_property (GObject * object, guint prop_id,
case PROP_HIGH_PERCENT:
mq->high_percent = g_value_get_int (value);
break;
case PROP_SYNC_BY_RUNNING_TIME:
mq->sync_by_running_time = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -535,6 +562,9 @@ gst_multi_queue_get_property (GObject * object, guint prop_id,
case PROP_HIGH_PERCENT:
g_value_set_int (value, mq->high_percent);
break;
case PROP_SYNC_BY_RUNNING_TIME:
g_value_set_boolean (value, mq->sync_by_running_time);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -737,8 +767,15 @@ gst_single_queue_flush (GstMultiQueue * mq, GstSingleQueue * sq, gboolean flush)
sq->nextid = 0;
sq->oldid = 0;
sq->last_oldid = G_MAXUINT32;
sq->next_time = GST_CLOCK_TIME_NONE;
sq->last_time = GST_CLOCK_TIME_NONE;
gst_data_queue_set_flushing (sq->queue, FALSE);
/* Reset high time to be recomputed next */
GST_MULTI_QUEUE_MUTEX_LOCK (mq);
mq->high_time = GST_CLOCK_TIME_NONE;
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
sq->flushing = FALSE;
GST_LOG_OBJECT (mq, "SingleQueue %d : starting task", sq->id);
@ -932,6 +969,63 @@ apply_buffer (GstMultiQueue * mq, GstSingleQueue * sq, GstClockTime timestamp,
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
}
static GstClockTime
get_running_time (GstSegment * segment, GstMiniObject * object, gboolean end)
{
GstClockTime time = GST_CLOCK_TIME_NONE;
if (GST_IS_BUFFER (object)) {
GstBuffer *buf = GST_BUFFER_CAST (object);
if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
time = GST_BUFFER_TIMESTAMP (buf);
if (end && GST_BUFFER_DURATION_IS_VALID (buf))
time += GST_BUFFER_DURATION (buf);
if (time > segment->stop)
time = segment->stop;
time = gst_segment_to_running_time (segment, GST_FORMAT_TIME, time);
}
} else if (GST_IS_BUFFER_LIST (object)) {
GstBufferList *list = GST_BUFFER_LIST_CAST (object);
gint i, n;
GstBuffer *buf;
n = gst_buffer_list_len (list);
for (i = 0; i < n; i++) {
buf = gst_buffer_list_get (list, i);
if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
time = GST_BUFFER_TIMESTAMP (buf);
if (end && GST_BUFFER_DURATION_IS_VALID (buf))
time += GST_BUFFER_DURATION (buf);
if (time > segment->stop)
time = segment->stop;
time = gst_segment_to_running_time (segment, GST_FORMAT_TIME, time);
if (!end)
goto done;
} else if (!end) {
goto done;
}
}
} else if (GST_IS_EVENT (object)) {
GstEvent *event = GST_EVENT_CAST (object);
/* For newsegment events return the running time of the start position */
if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
GstSegment new_segment = *segment;
gst_event_parse_segment (event, &new_segment);
if (new_segment.format == GST_FORMAT_TIME) {
time =
gst_segment_to_running_time (&new_segment, GST_FORMAT_TIME,
new_segment.start);
}
}
}
done:
return time;
}
static GstFlowReturn
gst_single_queue_push_one (GstMultiQueue * mq, GstSingleQueue * sq,
GstMiniObject * object)
@ -1070,6 +1164,7 @@ gst_multi_queue_loop (GstPad * pad)
GstMiniObject *object = NULL;
guint32 newid;
GstFlowReturn result;
GstClockTime next_time;
sq = (GstSingleQueue *) gst_pad_get_element_private (pad);
mq = sq->mqueue;
@ -1091,6 +1186,9 @@ gst_multi_queue_loop (GstPad * pad)
object = gst_multi_queue_item_steal_object (item);
gst_multi_queue_item_destroy (item);
/* Get running time of the item. Events will have GST_CLOCK_TIME_NONE */
next_time = get_running_time (&sq->src_segment, object, TRUE);
GST_LOG_OBJECT (mq, "SingleQueue %d : newid:%d , oldid:%d",
sq->id, newid, sq->last_oldid);
@ -1099,9 +1197,9 @@ gst_multi_queue_loop (GstPad * pad)
* or it's the first loop, or we just passed the previous highid,
* we might need to wake some sleeping pad up, so there's extra work
* there too */
if (sq->srcresult == GST_FLOW_NOT_LINKED ||
(sq->last_oldid == G_MAXUINT32) || (newid != (sq->last_oldid + 1)) ||
sq->last_oldid > mq->highid) {
if (sq->srcresult == GST_FLOW_NOT_LINKED
|| (sq->last_oldid == G_MAXUINT32) || (newid != (sq->last_oldid + 1))
|| sq->last_oldid > mq->highid) {
GST_LOG_OBJECT (mq, "CHECKING sq->srcresult: %s",
gst_flow_get_name (sq->srcresult));
@ -1116,6 +1214,7 @@ gst_multi_queue_loop (GstPad * pad)
/* Update the nextid so other threads know when to wake us up */
sq->nextid = newid;
sq->next_time = next_time;
/* Update the oldid (the last ID we output) for highid tracking */
if (sq->last_oldid != G_MAXUINT32)
@ -1126,10 +1225,20 @@ gst_multi_queue_loop (GstPad * pad)
/* Recompute the highid */
compute_high_id (mq);
while (newid > mq->highid && sq->srcresult == GST_FLOW_NOT_LINKED) {
GST_DEBUG_OBJECT (mq, "queue %d sleeping for not-linked wakeup with "
"newid %u and highid %u", sq->id, newid, mq->highid);
/* Recompute the high time */
compute_high_time (mq);
while (((mq->sync_by_running_time && next_time != GST_CLOCK_TIME_NONE &&
(mq->high_time == GST_CLOCK_TIME_NONE
|| next_time >= mq->high_time))
|| (!mq->sync_by_running_time && newid > mq->highid))
&& sq->srcresult == GST_FLOW_NOT_LINKED) {
GST_DEBUG_OBJECT (mq,
"queue %d sleeping for not-linked wakeup with "
"newid %u, highid %u, next_time %" GST_TIME_FORMAT
", high_time %" GST_TIME_FORMAT, sq->id, newid, mq->highid,
GST_TIME_ARGS (next_time), GST_TIME_ARGS (mq->high_time));
/* Wake up all non-linked pads before we sleep */
wake_up_next_non_linked (mq);
@ -1143,8 +1252,13 @@ gst_multi_queue_loop (GstPad * pad)
goto out_flushing;
}
/* Recompute the high time */
compute_high_time (mq);
GST_DEBUG_OBJECT (mq, "queue %d woken from sleeping for not-linked "
"wakeup with newid %u and highid %u", sq->id, newid, mq->highid);
"wakeup with newid %u, highid %u, next_time %" GST_TIME_FORMAT
", high_time %" GST_TIME_FORMAT, sq->id, newid, mq->highid,
GST_TIME_ARGS (next_time), GST_TIME_ARGS (mq->high_time));
}
/* Re-compute the high_id in case someone else pushed */
@ -1154,8 +1268,9 @@ gst_multi_queue_loop (GstPad * pad)
/* Wake up all non-linked pads */
wake_up_next_non_linked (mq);
}
/* We're done waiting, we can clear the nextid */
/* We're done waiting, we can clear the nextid and nexttime */
sq->nextid = 0;
sq->next_time = GST_CLOCK_TIME_NONE;
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
}
@ -1166,6 +1281,18 @@ gst_multi_queue_loop (GstPad * pad)
GST_LOG_OBJECT (mq, "BEFORE PUSHING sq->srcresult: %s",
gst_flow_get_name (sq->srcresult));
/* Update time stats */
next_time = get_running_time (&sq->src_segment, object, FALSE);
if (next_time != GST_CLOCK_TIME_NONE) {
if (sq->last_time == GST_CLOCK_TIME_NONE || sq->last_time < next_time)
sq->last_time = next_time;
if (mq->high_time == GST_CLOCK_TIME_NONE || mq->high_time <= next_time) {
/* Wake up all non-linked pads now that we advanceed the high time */
mq->high_time = next_time;
wake_up_next_non_linked (mq);
}
}
/* Try to push out the new object */
result = gst_single_queue_push_one (mq, sq, object);
sq->srcresult = result;
@ -1179,6 +1306,7 @@ gst_multi_queue_loop (GstPad * pad)
gst_flow_get_name (sq->srcresult));
sq->last_oldid = newid;
return;
out_flushing:
@ -1499,7 +1627,10 @@ wake_up_next_non_linked (GstMultiQueue * mq)
GstSingleQueue *sq = (GstSingleQueue *) tmp->data;
if (sq->srcresult == GST_FLOW_NOT_LINKED) {
if (sq->nextid != 0 && sq->nextid <= mq->highid) {
if ((mq->sync_by_running_time && mq->high_time != GST_CLOCK_TIME_NONE
&& sq->next_time != GST_CLOCK_TIME_NONE
&& sq->next_time >= mq->high_time)
|| (sq->nextid != 0 && sq->nextid <= mq->highid)) {
GST_LOG_OBJECT (mq, "Waking up singlequeue %d", sq->id);
g_cond_signal (sq->turn);
}
@ -1550,6 +1681,49 @@ compute_high_id (GstMultiQueue * mq)
lowest);
}
/* WITH LOCK TAKEN */
static void
compute_high_time (GstMultiQueue * mq)
{
/* The high-id is either the highest id among the linked pads, or if all
* pads are not-linked, it's the lowest not-linked pad */
GList *tmp;
GstClockTime highest = GST_CLOCK_TIME_NONE;
GstClockTime lowest = GST_CLOCK_TIME_NONE;
for (tmp = mq->queues; tmp; tmp = g_list_next (tmp)) {
GstSingleQueue *sq = (GstSingleQueue *) tmp->data;
GST_LOG_OBJECT (mq,
"inspecting sq:%d , next_time:%" GST_TIME_FORMAT ", last_time:%"
GST_TIME_FORMAT ", srcresult:%s", sq->id, GST_TIME_ARGS (sq->next_time),
GST_TIME_ARGS (sq->last_time), gst_flow_get_name (sq->srcresult));
if (sq->srcresult == GST_FLOW_NOT_LINKED) {
/* No need to consider queues which are not waiting */
if (sq->next_time == GST_CLOCK_TIME_NONE) {
GST_LOG_OBJECT (mq, "sq:%d is not waiting - ignoring", sq->id);
continue;
}
if (lowest == GST_CLOCK_TIME_NONE || sq->next_time < lowest)
lowest = sq->next_time;
} else if (sq->srcresult != GST_FLOW_UNEXPECTED) {
/* If we don't have a global highid, or the global highid is lower than
* this single queue's last outputted id, store the queue's one,
* unless the singlequeue is at EOS (srcresult = UNEXPECTED) */
if (highest == GST_CLOCK_TIME_NONE || sq->last_time > highest)
highest = sq->last_time;
}
}
mq->high_time = highest;
GST_LOG_OBJECT (mq,
"High time is now : %" GST_TIME_FORMAT ", lowest non-linked %"
GST_TIME_FORMAT, GST_TIME_ARGS (mq->high_time), GST_TIME_ARGS (lowest));
}
#define IS_FILLED(q, format, value) (((q)->max_size.format) != 0 && \
((q)->max_size.format) <= (value))
@ -1738,8 +1912,6 @@ gst_single_queue_new (GstMultiQueue * mqueue, gint id)
sq->extra_size.bytes = mqueue->extra_size.bytes;
sq->extra_size.time = mqueue->extra_size.time;
GST_MULTI_QUEUE_MUTEX_UNLOCK (mqueue);
GST_DEBUG_OBJECT (mqueue, "Creating GstSingleQueue id:%d", sq->id);
sq->mqueue = mqueue;
@ -1755,6 +1927,8 @@ gst_single_queue_new (GstMultiQueue * mqueue, gint id)
sq->nextid = 0;
sq->oldid = 0;
sq->next_time = GST_CLOCK_TIME_NONE;
sq->last_time = GST_CLOCK_TIME_NONE;
sq->turn = g_cond_new ();
sq->sinktime = GST_CLOCK_TIME_NONE;
@ -1799,6 +1973,8 @@ gst_single_queue_new (GstMultiQueue * mqueue, gint id)
gst_pad_set_element_private (sq->sinkpad, (gpointer) sq);
gst_pad_set_element_private (sq->srcpad, (gpointer) sq);
GST_MULTI_QUEUE_MUTEX_UNLOCK (mqueue);
/* only activate the pads when we are not in the NULL state
* and add the pad under the state_lock to prevend state changes
* between activating and adding */

View file

@ -50,6 +50,8 @@ typedef struct _GstMultiQueueClass GstMultiQueueClass;
struct _GstMultiQueue {
GstElement element;
gboolean sync_by_running_time;
/* number of queues */
guint nbqueues;
@ -65,6 +67,7 @@ struct _GstMultiQueue {
guint32 counter; /* incoming object counter, use atomic accesses */
guint32 highid; /* contains highest id of last outputted object */
GstClockTime high_time; /* highest start running time */
GMutex * qlock; /* Global queue lock (vs object lock or individual */
/* queues lock). Protects nbqueues, queues, global */

View file

@ -855,6 +855,7 @@ reset_rate_timer (GstQueue2 * queue)
queue->bytes_in = 0;
queue->bytes_out = 0;
queue->byte_in_rate = 0.0;
queue->byte_in_period = 0;
queue->byte_out_rate = 0.0;
queue->last_in_elapsed = 0.0;
queue->last_out_elapsed = 0.0;
@ -867,8 +868,11 @@ reset_rate_timer (GstQueue2 * queue)
/* Tuning for rate estimation. We use a large window for the input rate because
* it should be stable when connected to a network. The output rate is less
* stable (the elements preroll, queues behind a demuxer fill, ...) and should
* therefore adapt more quickly. */
#define AVG_IN(avg,val) ((avg) * 15.0 + (val)) / 16.0
* therefore adapt more quickly.
* However, initial input rate may be subject to a burst, and should therefore
* initially also adapt more quickly to changes, and only later on give higher
* weight to previous values. */
#define AVG_IN(avg,val,w1,w2) ((avg) * (w1) + (val) * (w2)) / ((w1) + (w2))
#define AVG_OUT(avg,val) ((avg) * 3.0 + (val)) / 4.0
static void
@ -890,14 +894,20 @@ update_in_rates (GstQueue2 * queue)
period = elapsed - queue->last_in_elapsed;
GST_DEBUG_OBJECT (queue,
"rates: period %f, in %" G_GUINT64_FORMAT, period, queue->bytes_in);
"rates: period %f, in %" G_GUINT64_FORMAT ", global period %f",
period, queue->bytes_in, queue->byte_in_period);
byte_in_rate = queue->bytes_in / period;
if (queue->byte_in_rate == 0.0)
queue->byte_in_rate = byte_in_rate;
else
queue->byte_in_rate = AVG_IN (queue->byte_in_rate, byte_in_rate);
queue->byte_in_rate = AVG_IN (queue->byte_in_rate, byte_in_rate,
(double) queue->byte_in_period, period);
/* another data point, cap at 16 for long time running average */
if (queue->byte_in_period < 16 * RATE_INTERVAL)
queue->byte_in_period += period;
/* reset the values to calculate rate over the next interval */
queue->last_in_elapsed = elapsed;

View file

@ -116,6 +116,7 @@ struct _GstQueue2
gdouble last_in_elapsed;
guint64 bytes_in;
gdouble byte_in_rate;
gdouble byte_in_period;
GTimer *out_timer;
gboolean out_timer_started;

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.9.7\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2005-12-05 11:45+0200\n"
"Last-Translator: Petri Jooste <rkwjpj@puk.ac.za>\n"
"Language-Team: Afrikaans <i18n@af.org.za>\n"

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer-0.8.0\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2004-03-19 18:40+0200\n"
"Last-Translator: Metin Amiroff <metin@karegen.com>\n"
"Language-Team: Azerbaijani <translation-team-az@lists.sourceforge.net>\n"

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.9.7\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2006-01-18 22:26+0200\n"
"Last-Translator: Ales Nyakhaychyk <nab@mail.by>\n"
"Language-Team: Belarusian <i18n@mova.org>\n"

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.32.2\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-27 11:27+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2011-04-26 22:40+0300\n"
"Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
"Language-Team: Bulgarian <dict@fsa-bg.org>\n"

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.30.3\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2010-11-04 19:41+0100\n"
"Last-Translator: Jordi Mallach <jordi@sindominio.net>\n"
"Language-Team: Catalan <ca@dodds.net>\n"

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.20.3\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2008-10-12 12:12+0200\n"
"Last-Translator: Miloslav Trmac <mitr@volny.cz>\n"
"Language-Team: Czech <translation-team-cs@lists.sourceforge.net>\n"

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.30.3\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2010-11-06 22:52+0100\n"
"Last-Translator: Mogens Jaeger <mogensjaeger@gmail.com>\n"
"Language-Team: Danish <dansk@dansk-gruppen.dk>\n"

View file

@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.32.2\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-30 15:35+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2011-04-27 23:44+0200\n"
"Last-Translator: Christian Kirbach <christian.kirbach@googlemail.com>\n"
"Language-Team: German <translation-team-de@lists.sourceforge.net>\n"

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer-0.10.30.3\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2010-11-29 11:14+0200\n"
"Last-Translator: Michael Kotsarinis <mk73628@gmail.com>\n"
"Language-Team: Greek <team@lists.gnome.gr>\n"

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.8.1\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2004-04-26 10:36-0400\n"
"Last-Translator: Gareth Owen <gowen72@yahoo.com>\n"
"Language-Team: English (British) <en_gb@li.org>\n"

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.30.3\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2010-11-01 18:11+0100\n"
"Last-Translator: Jorge González González <aloriel@gmail.com>\n"
"Language-Team: Spanish <es@li.org>\n"

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer-0.10.26.2\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2010-03-25 13:10+0100\n"
"Last-Translator: Mikel Olasagasti Uranga <hey_neken@mundurat.net>\n"
"Language-Team: Basque <translation-team-eu@lists.sourceforge.net>\n"

View file

@ -12,7 +12,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.30.3\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2010-11-17 23:10+0200\n"
"Last-Translator: Tommi Vainikainen <Tommi.Vainikainen@iki.fi>\n"
"Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n"

View file

@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.32.2\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-30 15:35+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2011-04-28 09:34+0200\n"
"Last-Translator: Claude Paroz <claude@2xlibre.net>\n"
"Language-Team: French <traduc@traduc.org>\n"

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.31.2\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2011-04-13 05:19+0000\n"
"Last-Translator: Francisco Diéguez <frandieguez@ubuntu.com>\n"
"Language-Team: Galician <proxecto@trasno.net>\n"

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.30.3\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2010-11-01 13:39+0100\n"
"Last-Translator: Gabor Kelemen <kelemeng@gnome.hu>\n"
"Language-Team: Hungarian <translation-team-hu@lists.sourceforge.net>\n"

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.29.2\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2010-06-29 21:55+0700\n"
"Last-Translator: Andhika Padmawan <andhika.padmawan@gmail.com>\n"
"Language-Team: Indonesian <translation-team-id@lists.sourceforge.net>\n"

View file

@ -106,7 +106,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.30.3\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2010-10-25 10:03+0200\n"
"Last-Translator: Luca Ferretti <elle.uca@infinito.it>\n"
"Language-Team: Italian <tp@lists.linux.it>\n"

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.20.3\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2008-10-16 19:57+0900\n"
"Last-Translator: Makoto Kato <makoto.kt@gmail.com>\n"
"Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n"

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.29.2\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2010-07-16 00:50+0300\n"
"Last-Translator: Žygimantas Beručka <uid0@akl.lt>\n"
"Language-Team: Lithuanian <komp_lt@konferencijos.lt>\n"

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.30.3\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2010-10-24 21:36+0200\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Language-Team: Norwegian Bokmaal <i18n-nb@lister.ping.uio.no>\n"

View file

@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.32.2\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-27 11:27+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2011-04-26 23:10+0200\n"
"Last-Translator: Freek de Kruijf <f.de.kruijf@gmail.com>\n"
"Language-Team: Dutch <vertaling@vrijschrift.org>\n"

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.32.2\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-27 11:27+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2011-04-26 17:54+0200\n"
"Last-Translator: Jakub Bogusz <qboosh@pld-linux.org>\n"
"Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"

View file

@ -17,7 +17,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer-0.10.31.2\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2011-01-08 01:36-0300\n"
"Last-Translator: Fabrício Godoy <skarllot@gmail.com>\n"
"Language-Team: Brazilian Portuguese <ldp-br@bazar.conectiva.com.br>\n"

View file

@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.29.2\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2010-08-16 01:10+0300\n"
"Last-Translator: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>\n"
"Language-Team: Romanian <translation-team-ro@lists.sourceforge.net>\n"

View file

@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer-0.10.32.2\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-27 11:27+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2011-04-26 20:25+0400\n"
"Last-Translator: Yuri Kozlov <yuray@komyakino.ru>\n"
"Language-Team: Russian <gnu@mx.ru>\n"

View file

@ -15,7 +15,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.8.8\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2005-04-04 10:55-0700\n"
"Last-Translator: Steven Michael Murphy <murf@e-tools.com>\n"
"Language-Team: Kinyarwanda <translation-team-rw@lists.sourceforge.net>\n"

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.30.3\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2010-11-08 16:13+0100\n"
"Last-Translator: Peter Tuhársky <tuharsky@misbb.sk>\n"
"Language-Team: Slovak <sk-i18n@lists.linux.sk>\n"

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.29.2\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2010-09-18 20:21+0100\n"
"Last-Translator: Matej Urbančič <matej.urban@gmail.com>\n"
"Language-Team: Slovenian <translation-team-sl@lists.sourceforge.net>\n"

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.8.4\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2004-08-07 23:46+0200\n"
"Last-Translator: Laurent Dhima <laurenti@alblinux.net>\n"
"Language-Team: Albanian <begraj@hotmail.com>\n"

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.8.8\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2005-01-27 16:58+0100\n"
"Last-Translator: Danilo Segan <dsegan@gmx.net>\n"
"Language-Team: Serbian <gnu@prevod.org>\n"

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.31.2\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2011-01-09 19:46+0100\n"
"Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.8.0\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2004-04-03 03:14+0300\n"
"Last-Translator: Baris Cicek <baris@teamforce.name.tr>\n"
"Language-Team: Turkish <gnu-tr-u12a@lists.sourceforge.net>\n"

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.14\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2007-09-07 11:16+0300\n"
"Last-Translator: Maxim V. Dziumanenko <dziumanenko@gmail.com>\n"
"Language-Team: Ukrainian <translation-team-uk@lists.sourceforge.net>\n"

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.29.2\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2010-10-03 19:09+1030\n"
"Last-Translator: Clytie Siddall <clytie@riverland.net.au>\n"
"Language-Team: Vietnamese <vi-VN@googlegroups.com>\n"

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.10.25.2\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2010-02-02 18:58+0800\n"
"Last-Translator: Ji ZhengYu <zhengyuji@gmail.com>\n"
"Language-Team: Chinese (simplified) <i18n-zh@googlegroups.com>\n"

View file

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer 0.8.8\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
"POT-Creation-Date: 2011-04-16 14:53+0100\n"
"POT-Creation-Date: 2011-05-10 08:32+0100\n"
"PO-Revision-Date: 2005-04-27 14:55+0800\n"
"Last-Translator: Abel Cheung <abelcheung@gmail.com>\n"
"Language-Team: Chinese (traditional) <zh-l10n@linux.org.tw>\n"

View file

@ -255,7 +255,7 @@ GST_END_TEST;
GST_START_TEST (test_link)
{
GstElement *b1, *b2, *src, *sink;
GstPad *srcpad, *sinkpad, *gpad;
GstPad *srcpad, *sinkpad, *gpad, *ppad, *tmp;
GstPadLinkReturn ret;
b1 = gst_element_factory_make ("pipeline", NULL);
@ -278,6 +278,14 @@ GST_START_TEST (test_link)
/* now setup a ghostpad */
gpad = gst_ghost_pad_new ("sink", sinkpad);
/* Check if the internal pads are set correctly */
ppad = GST_PAD (gst_proxy_pad_get_internal (GST_PROXY_PAD (gpad)));
fail_unless (ppad == GST_PAD_PEER (sinkpad));
tmp = GST_PAD (gst_proxy_pad_get_internal (GST_PROXY_PAD (ppad)));
fail_unless (tmp == gpad);
gst_object_unref (tmp);
gst_object_unref (ppad);
gst_object_unref (sinkpad);
/* need to ref as _add_pad takes ownership */
gst_object_ref (gpad);

View file

@ -168,6 +168,33 @@ GST_START_TEST (test_unref_threaded)
GST_END_TEST;
/* ======== weak ref test ======== */
static gboolean weak_ref_notify_succeeded = FALSE;
static void
on_weak_ref_notify (gpointer data, GstMiniObject * where_object_was)
{
weak_ref_notify_succeeded = TRUE;
}
GST_START_TEST (test_weak_ref)
{
GstBuffer *buffer;
buffer = gst_buffer_new_and_alloc (4);
gst_mini_object_weak_ref (GST_MINI_OBJECT (buffer), on_weak_ref_notify,
&buffer);
gst_buffer_unref (buffer);
fail_unless (weak_ref_notify_succeeded,
"No weak reference notification took place.");
}
GST_END_TEST;
#if 0
/* ======== recycle test ======== */
@ -434,6 +461,7 @@ gst_mini_object_suite (void)
tcase_add_test (tc_chain, test_make_writable);
tcase_add_test (tc_chain, test_ref_threaded);
tcase_add_test (tc_chain, test_unref_threaded);
tcase_add_test (tc_chain, test_weak_ref);
//tcase_add_test (tc_chain, test_recycle_threaded);
tcase_add_test (tc_chain, test_value_collection);
tcase_add_test (tc_chain, test_dup_null_mini_object);

View file

@ -59,13 +59,13 @@
#define GST_MAJORMINOR "0.10"
/* package name in plugins */
#define GST_PACKAGE_NAME "GStreamer prerelease"
#define GST_PACKAGE_NAME "GStreamer git"
/* package origin */
#define GST_PACKAGE_ORIGIN "Unknown package origin"
/* GStreamer package release date/time for plugins as YYYY-MM-DD */
#define GST_PACKAGE_RELEASE_DATETIME "2011-04-30T14:22Z"
#define GST_PACKAGE_RELEASE_DATETIME "2011-05-14T08:26Z"
/* location of the installed gst-plugin-scanner */
#define GST_PLUGIN_SCANNER_INSTALLED LIBDIR "\\gst-plugin-scanner"
@ -340,7 +340,7 @@
#define PACKAGE_NAME "GStreamer"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "GStreamer 0.10.32.4"
#define PACKAGE_STRING "GStreamer 0.10.34.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "gstreamer"
@ -349,7 +349,7 @@
#undef PACKAGE_URL
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.10.32.4"
#define PACKAGE_VERSION "0.10.34.1"
/* directory where plugins are located */
#ifdef _DEBUG
@ -380,7 +380,7 @@
#undef USE_POISONING
/* Version number of package */
#define VERSION "0.10.32.4"
#define VERSION "0.10.34.1"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */

View file

@ -57,14 +57,14 @@ G_BEGIN_DECLS
*
* The micro version of GStreamer at compile time:
*/
#define GST_VERSION_MICRO (32)
#define GST_VERSION_MICRO (34)
/**
* GST_VERSION_NANO:
*
* The nano version of GStreamer at compile time:
* Actual releases have 0, GIT versions have 1, prerelease versions have 2-...
*/
#define GST_VERSION_NANO (4)
#define GST_VERSION_NANO (1)
/**
* GST_CHECK_VERSION:

View file

@ -436,14 +436,21 @@ EXPORTS
gst_fraction_get_type
gst_fraction_range_get_type
gst_g_error_get_type
gst_ghost_pad_activate_pull_default
gst_ghost_pad_activate_push_default
gst_ghost_pad_construct
gst_ghost_pad_get_target
gst_ghost_pad_get_type
gst_ghost_pad_internal_activate_pull_default
gst_ghost_pad_internal_activate_push_default
gst_ghost_pad_link_default
gst_ghost_pad_new
gst_ghost_pad_new_from_template
gst_ghost_pad_new_no_target
gst_ghost_pad_new_no_target_from_template
gst_ghost_pad_set_target
gst_ghost_pad_setcaps_default
gst_ghost_pad_unlink_default
gst_implements_interface_cast
gst_implements_interface_check
gst_implements_interface_get_type
@ -613,6 +620,8 @@ EXPORTS
gst_mini_object_register
gst_mini_object_replace
gst_mini_object_unref
gst_mini_object_weak_ref
gst_mini_object_weak_unref
gst_object_check_uniqueness
gst_object_default_deep_notify
gst_object_default_error
@ -827,7 +836,22 @@ EXPORTS
gst_print_element_args
gst_print_pad_caps
gst_progress_type_get_type
gst_proxy_pad_acceptcaps_default
gst_proxy_pad_bufferalloc_default
gst_proxy_pad_chain_default
gst_proxy_pad_chain_list_default
gst_proxy_pad_checkgetrange_default
gst_proxy_pad_event_default
gst_proxy_pad_fixatecaps_default
gst_proxy_pad_get_internal
gst_proxy_pad_get_type
gst_proxy_pad_getcaps_default
gst_proxy_pad_getrange_default
gst_proxy_pad_iterate_internal_links_default
gst_proxy_pad_query_default
gst_proxy_pad_query_type_default
gst_proxy_pad_setcaps_default
gst_proxy_pad_unlink_default
gst_qos_type_get_type
gst_query_add_allocation_meta
gst_query_add_buffering_range