diff options
author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-08-08 18:10:27 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-08-08 18:10:27 +0200 |
commit | d1f921cf62a353aff4ea4bbb953cd08d6bdc8fc1 (patch) | |
tree | c2324e9b7a86a3aba410f36c914f23263a3f022f /plugins | |
parent | bed72dff4210fac83b878ac3b0f3ecb78d30d1d2 (diff) |
Imported Upstream version 0.11.93upstream/0.11.93
Diffstat (limited to 'plugins')
42 files changed, 586 insertions, 444 deletions
diff --git a/plugins/Makefile.in b/plugins/Makefile.in index 099c0e4..b666215 100644 --- a/plugins/Makefile.in +++ b/plugins/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11.5 from Makefile.am. +# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -206,7 +206,9 @@ GIO_LDFLAGS = @GIO_LDFLAGS@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_EXTRA_CFLAGS = @GLIB_EXTRA_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GLIB_PREFIX = @GLIB_PREFIX@ GLIB_REQ = @GLIB_REQ@ GMP_LIBS = @GMP_LIBS@ diff --git a/plugins/elements/Makefile.am b/plugins/elements/Makefile.am index d451a1f..5e0230c 100644 --- a/plugins/elements/Makefile.am +++ b/plugins/elements/Makefile.am @@ -17,6 +17,7 @@ libgstcoreelements_la_SOURCES = \ gstoutputselector.c \ gstdataqueue.c \ gstmultiqueue.c \ + gstqueuearray.c \ gstqueue.c \ gstqueue2.c \ gsttee.c \ @@ -44,6 +45,7 @@ noinst_HEADERS = \ gstoutputselector.h \ gstdataqueue.h \ gstmultiqueue.h \ + gstqueuearray.h \ gstqueue.h \ gstqueue2.h \ gsttee.h \ diff --git a/plugins/elements/Makefile.in b/plugins/elements/Makefile.in index 56a2e0c..3bb168f 100644 --- a/plugins/elements/Makefile.in +++ b/plugins/elements/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11.5 from Makefile.am. +# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -143,6 +143,7 @@ am_libgstcoreelements_la_OBJECTS = \ libgstcoreelements_la-gstoutputselector.lo \ libgstcoreelements_la-gstdataqueue.lo \ libgstcoreelements_la-gstmultiqueue.lo \ + libgstcoreelements_la-gstqueuearray.lo \ libgstcoreelements_la-gstqueue.lo \ libgstcoreelements_la-gstqueue2.lo \ libgstcoreelements_la-gsttee.lo \ @@ -251,7 +252,9 @@ GIO_LDFLAGS = @GIO_LDFLAGS@ GIO_LIBS = @GIO_LIBS@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_EXTRA_CFLAGS = @GLIB_EXTRA_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GLIB_PREFIX = @GLIB_PREFIX@ GLIB_REQ = @GLIB_REQ@ GMP_LIBS = @GMP_LIBS@ @@ -483,6 +486,7 @@ libgstcoreelements_la_SOURCES = \ gstoutputselector.c \ gstdataqueue.c \ gstmultiqueue.c \ + gstqueuearray.c \ gstqueue.c \ gstqueue2.c \ gsttee.c \ @@ -510,6 +514,7 @@ noinst_HEADERS = \ gstoutputselector.h \ gstdataqueue.h \ gstmultiqueue.h \ + gstqueuearray.h \ gstqueue.h \ gstqueue2.h \ gsttee.h \ @@ -611,6 +616,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstcoreelements_la-gstoutputselector.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstcoreelements_la-gstqueue.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstcoreelements_la-gstqueue2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstcoreelements_la-gstqueuearray.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstcoreelements_la-gsttee.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstcoreelements_la-gsttypefindelement.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstcoreelements_la-gstvalve.Plo@am__quote@ @@ -734,6 +740,13 @@ libgstcoreelements_la-gstmultiqueue.lo: gstmultiqueue.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstcoreelements_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstcoreelements_la_CFLAGS) $(CFLAGS) -c -o libgstcoreelements_la-gstmultiqueue.lo `test -f 'gstmultiqueue.c' || echo '$(srcdir)/'`gstmultiqueue.c +libgstcoreelements_la-gstqueuearray.lo: gstqueuearray.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstcoreelements_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstcoreelements_la_CFLAGS) $(CFLAGS) -MT libgstcoreelements_la-gstqueuearray.lo -MD -MP -MF $(DEPDIR)/libgstcoreelements_la-gstqueuearray.Tpo -c -o libgstcoreelements_la-gstqueuearray.lo `test -f 'gstqueuearray.c' || echo '$(srcdir)/'`gstqueuearray.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstcoreelements_la-gstqueuearray.Tpo $(DEPDIR)/libgstcoreelements_la-gstqueuearray.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstqueuearray.c' object='libgstcoreelements_la-gstqueuearray.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstcoreelements_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstcoreelements_la_CFLAGS) $(CFLAGS) -c -o libgstcoreelements_la-gstqueuearray.lo `test -f 'gstqueuearray.c' || echo '$(srcdir)/'`gstqueuearray.c + libgstcoreelements_la-gstqueue.lo: gstqueue.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstcoreelements_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstcoreelements_la_CFLAGS) $(CFLAGS) -MT libgstcoreelements_la-gstqueue.lo -MD -MP -MF $(DEPDIR)/libgstcoreelements_la-gstqueue.Tpo -c -o libgstcoreelements_la-gstqueue.lo `test -f 'gstqueue.c' || echo '$(srcdir)/'`gstqueue.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstcoreelements_la-gstqueue.Tpo $(DEPDIR)/libgstcoreelements_la-gstqueue.Plo diff --git a/plugins/elements/gstcapsfilter.c b/plugins/elements/gstcapsfilter.c index 971cb7f..1c585d9 100644 --- a/plugins/elements/gstcapsfilter.c +++ b/plugins/elements/gstcapsfilter.c @@ -305,7 +305,8 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input, GST_PTR_FORMAT " to apply to srcpad", out_caps); if (!gst_pad_has_current_caps (trans->srcpad)) - gst_pad_push_event (trans->srcpad, gst_event_new_caps (out_caps)); + if (!gst_pad_set_caps (trans->srcpad, out_caps)) + ret = GST_FLOW_NOT_NEGOTIATED; gst_caps_unref (out_caps); } else { gchar *caps_str = gst_caps_to_string (out_caps); diff --git a/plugins/elements/gstcapsfilter.h b/plugins/elements/gstcapsfilter.h index d132e66..9db6ebc 100644 --- a/plugins/elements/gstcapsfilter.h +++ b/plugins/elements/gstcapsfilter.h @@ -59,7 +59,7 @@ struct _GstCapsFilterClass { GstBaseTransformClass trans_class; }; -GType gst_capsfilter_get_type (void); +G_GNUC_INTERNAL GType gst_capsfilter_get_type (void); G_END_DECLS diff --git a/plugins/elements/gstdataqueue.c b/plugins/elements/gstdataqueue.c index c1b8820..dff49c6 100644 --- a/plugins/elements/gstdataqueue.c +++ b/plugins/elements/gstdataqueue.c @@ -26,8 +26,6 @@ * #GstDataQueue is an object that handles threadsafe queueing of objects. It * also provides size-related functionality. This object should be used for * any #GstElement that wishes to provide some sort of queueing functionality. - * - * Since: 0.10.11 */ #include <gst/gst.h> @@ -89,7 +87,7 @@ enum q->cur_level.visible, \ q->cur_level.bytes, \ q->cur_level.time, \ - q->queue->length) + q->queue.length) static void gst_data_queue_finalize (GObject * object); @@ -181,7 +179,7 @@ gst_data_queue_init (GstDataQueue * queue) g_mutex_init (&queue->qlock); g_cond_init (&queue->item_add); g_cond_init (&queue->item_del); - queue->queue = g_queue_new (); + gst_queue_array_init (&queue->queue, 50); GST_DEBUG ("initialized queue's not_empty & not_full conditions"); } @@ -199,8 +197,6 @@ gst_data_queue_init (GstDataQueue * queue) * or @emptycallback. * * Returns: a new #GstDataQueue. - * - * Since: 0.10.26 */ GstDataQueue * @@ -239,8 +235,8 @@ gst_data_queue_new (GstDataQueueCheckFullFunction checkfull, gpointer checkdata) static void gst_data_queue_cleanup (GstDataQueue * queue) { - while (!g_queue_is_empty (queue->queue)) { - GstDataQueueItem *item = g_queue_pop_head (queue->queue); + while (!gst_queue_array_is_empty (&queue->queue)) { + GstDataQueueItem *item = gst_queue_array_pop_head (&queue->queue); /* Just call the destroy notify on the item */ item->destroy (item); @@ -259,7 +255,7 @@ gst_data_queue_finalize (GObject * object) GST_DEBUG ("finalizing queue"); gst_data_queue_cleanup (queue); - g_queue_free (queue->queue); + gst_queue_array_clear (&queue->queue); GST_DEBUG ("free mutex"); g_mutex_clear (&queue->qlock); @@ -285,7 +281,7 @@ gst_data_queue_locked_flush (GstDataQueue * queue) static inline gboolean gst_data_queue_locked_is_empty (GstDataQueue * queue) { - return (queue->queue->length == 0); + return (queue->queue.length == 0); } static inline gboolean @@ -302,8 +298,6 @@ gst_data_queue_locked_is_full (GstDataQueue * queue) * Flushes all the contents of the @queue. Any call to #gst_data_queue_push and * #gst_data_queue_pop will be released. * MT safe. - * - * Since: 0.10.11 */ void gst_data_queue_flush (GstDataQueue * queue) @@ -322,8 +316,6 @@ gst_data_queue_flush (GstDataQueue * queue) * MT safe. * * Returns: #TRUE if @queue is empty. - * - * Since: 0.10.11 */ gboolean gst_data_queue_is_empty (GstDataQueue * queue) @@ -346,8 +338,6 @@ gst_data_queue_is_empty (GstDataQueue * queue) * MT safe. * * Returns: #TRUE if @queue is full. - * - * Since: 0.10.11 */ gboolean gst_data_queue_is_full (GstDataQueue * queue) @@ -373,8 +363,6 @@ gst_data_queue_is_full (GstDataQueue * queue) * all calls to those two functions will return #FALSE. * * MT Safe. - * - * Since: 0.10.11 */ void gst_data_queue_set_flushing (GstDataQueue * queue, gboolean flushing) @@ -409,8 +397,6 @@ gst_data_queue_set_flushing (GstDataQueue * queue, gboolean flushing) * is returned, the caller is responsible for freeing @item and its contents. * * Returns: #TRUE if the @item was successfully pushed on the @queue. - * - * Since: 0.10.11 */ gboolean gst_data_queue_push (GstDataQueue * queue, GstDataQueueItem * item) @@ -441,7 +427,7 @@ gst_data_queue_push (GstDataQueue * queue, GstDataQueueItem * item) } } - g_queue_push_tail (queue->queue, item); + gst_queue_array_push_tail (&queue->queue, item); if (item->visible) queue->cur_level.visible++; @@ -476,8 +462,6 @@ flushing: * MT safe. * * Returns: #TRUE if an @item was successfully retrieved from the @queue. - * - * Since: 0.10.11 */ gboolean gst_data_queue_pop (GstDataQueue * queue, GstDataQueueItem ** item) @@ -507,7 +491,7 @@ gst_data_queue_pop (GstDataQueue * queue, GstDataQueueItem ** item) } /* Get the item from the GQueue */ - *item = g_queue_pop_head (queue->queue); + *item = gst_queue_array_pop_head (&queue->queue); /* update current level counter */ if ((*item)->visible) @@ -532,6 +516,12 @@ flushing: } } +static gint +is_of_type (gconstpointer a, gconstpointer b) +{ + return !G_TYPE_CHECK_INSTANCE_TYPE (a, GPOINTER_TO_INT (b)); +} + /** * gst_data_queue_drop_head: * @queue: The #GstDataQueue to drop an item from. @@ -540,34 +530,27 @@ flushing: * Pop and unref the head-most #GstMiniObject with the given #GType. * * Returns: TRUE if an element was removed. - * - * Since: 0.10.11 */ gboolean gst_data_queue_drop_head (GstDataQueue * queue, GType type) { gboolean res = FALSE; - GList *item; GstDataQueueItem *leak = NULL; + guint idx; g_return_val_if_fail (GST_IS_DATA_QUEUE (queue), FALSE); GST_DEBUG ("queue:%p", queue); GST_DATA_QUEUE_MUTEX_LOCK (queue); - for (item = g_queue_peek_head_link (queue->queue); item; item = item->next) { - GstDataQueueItem *tmp = (GstDataQueueItem *) item->data; + idx = + gst_queue_array_find (&queue->queue, is_of_type, GINT_TO_POINTER (type)); - if (G_TYPE_CHECK_INSTANCE_TYPE (tmp->object, type)) { - leak = tmp; - break; - } - } - - if (!leak) + if (idx == -1) goto done; - g_queue_delete_link (queue->queue, item); + leak = queue->queue.array[idx]; + gst_queue_array_drop_element (&queue->queue, idx); if (leak->visible) queue->cur_level.visible--; @@ -592,8 +575,6 @@ done: * * Inform the queue that the limits for the fullness check have changed and that * any blocking gst_data_queue_push() should be unblocked to recheck the limts. - * - * Since: 0.10.11 */ void gst_data_queue_limits_changed (GstDataQueue * queue) @@ -614,8 +595,6 @@ gst_data_queue_limits_changed (GstDataQueue * queue) * @level: the location to store the result * * Get the current level of the queue. - * - * Since: 0.10.11 */ void gst_data_queue_get_level (GstDataQueue * queue, GstDataQueueSize * level) diff --git a/plugins/elements/gstdataqueue.h b/plugins/elements/gstdataqueue.h index 36f4be7..52fdeaf 100644 --- a/plugins/elements/gstdataqueue.h +++ b/plugins/elements/gstdataqueue.h @@ -24,6 +24,7 @@ #define __GST_DATA_QUEUE_H__ #include <gst/gst.h> +#include "gstqueuearray.h" G_BEGIN_DECLS #define GST_TYPE_DATA_QUEUE \ @@ -54,8 +55,6 @@ typedef struct _GstDataQueueItem GstDataQueueItem; * * Structure used by #GstDataQueue. You can supply a different structure, as * long as the top of the structure is identical to this structure. - * - * Since: 0.10.11 */ struct _GstDataQueueItem @@ -76,8 +75,6 @@ struct _GstDataQueueItem * @time: amount of time * * Structure describing the size of a queue. - * - * Since: 0.10.11 */ struct _GstDataQueueSize { @@ -98,8 +95,6 @@ struct _GstDataQueueSize * considered as full. * * Returns: #TRUE if the queue should be considered full. - * - * Since: 0.10.11 */ typedef gboolean (*GstDataQueueCheckFullFunction) (GstDataQueue * queue, guint visible, guint bytes, guint64 time, gpointer checkdata); @@ -112,16 +107,14 @@ typedef void (*GstDataQueueEmptyCallback) (GstDataQueue * queue, gpointer checkd * @object: the parent structure * * Opaque #GstDataQueue structure. - * - * Since: 0.10.11 */ struct _GstDataQueue { GObject object; /*< private >*/ - /* the queue of data we're keeping our grubby hands on */ - GQueue *queue; + /* the array of data we're keeping our grubby hands on */ + GstQueueArray queue; GstDataQueueSize cur_level; /* size of the queue */ GstDataQueueCheckFullFunction checkfull; /* Callback to check if the queue is full */ @@ -137,7 +130,7 @@ struct _GstDataQueue GstDataQueueFullCallback fullcallback; GstDataQueueEmptyCallback emptycallback; - gpointer _gst_reserved[GST_PADDING]; + /* gpointer _gst_reserved[GST_PADDING]; */ }; struct _GstDataQueueClass @@ -148,31 +141,47 @@ struct _GstDataQueueClass void (*empty) (GstDataQueue * queue); void (*full) (GstDataQueue * queue); - gpointer _gst_reserved[GST_PADDING]; + /* gpointer _gst_reserved[GST_PADDING]; */ }; +G_GNUC_INTERNAL GType gst_data_queue_get_type (void); +G_GNUC_INTERNAL GstDataQueue * gst_data_queue_new (GstDataQueueCheckFullFunction checkfull, gpointer checkdata) G_GNUC_MALLOC; +G_GNUC_INTERNAL GstDataQueue * gst_data_queue_new_full (GstDataQueueCheckFullFunction checkfull, GstDataQueueFullCallback fullcallback, GstDataQueueEmptyCallback emptycallback, gpointer checkdata) G_GNUC_MALLOC; +G_GNUC_INTERNAL gboolean gst_data_queue_push (GstDataQueue * queue, GstDataQueueItem * item); + +G_GNUC_INTERNAL gboolean gst_data_queue_pop (GstDataQueue * queue, GstDataQueueItem ** item); +G_GNUC_INTERNAL void gst_data_queue_flush (GstDataQueue * queue); + +G_GNUC_INTERNAL void gst_data_queue_set_flushing (GstDataQueue * queue, gboolean flushing); +G_GNUC_INTERNAL gboolean gst_data_queue_drop_head (GstDataQueue * queue, GType type); +G_GNUC_INTERNAL gboolean gst_data_queue_is_full (GstDataQueue * queue); + +G_GNUC_INTERNAL gboolean gst_data_queue_is_empty (GstDataQueue * queue); +G_GNUC_INTERNAL void gst_data_queue_get_level (GstDataQueue * queue, GstDataQueueSize *level); + +G_GNUC_INTERNAL void gst_data_queue_limits_changed (GstDataQueue * queue); G_END_DECLS diff --git a/plugins/elements/gstelements.c b/plugins/elements/gstelements.c index 00594b5..6ba95d0 100644 --- a/plugins/elements/gstelements.c +++ b/plugins/elements/gstelements.c @@ -45,54 +45,65 @@ #include "gsttypefindelement.h" #include "gstvalve.h" -struct _elements_entry -{ - const gchar *name; - guint rank; - GType (*type) (void); -}; - - -static struct _elements_entry _elements[] = { - {"capsfilter", GST_RANK_NONE, gst_capsfilter_get_type}, - {"fakesrc", GST_RANK_NONE, gst_fake_src_get_type}, - {"fakesink", GST_RANK_NONE, gst_fake_sink_get_type}, -#if defined(HAVE_SYS_SOCKET_H) || defined(_MSC_VER) - {"fdsrc", GST_RANK_NONE, gst_fd_src_get_type}, - {"fdsink", GST_RANK_NONE, gst_fd_sink_get_type}, -#endif - {"filesrc", GST_RANK_PRIMARY, gst_file_src_get_type}, - {"funnel", GST_RANK_NONE, gst_funnel_get_type}, - {"identity", GST_RANK_NONE, gst_identity_get_type}, - {"input-selector", GST_RANK_NONE, gst_input_selector_get_type}, - {"output-selector", GST_RANK_NONE, gst_output_selector_get_type}, - {"queue", GST_RANK_NONE, gst_queue_get_type}, - {"queue2", GST_RANK_NONE, gst_queue2_get_type}, - {"filesink", GST_RANK_PRIMARY, gst_file_sink_get_type}, - {"tee", GST_RANK_NONE, gst_tee_get_type}, - {"typefind", GST_RANK_NONE, gst_type_find_element_get_type}, - {"multiqueue", GST_RANK_NONE, gst_multi_queue_get_type}, - {"valve", GST_RANK_NONE, gst_valve_get_type}, - {NULL, 0}, -}; - static gboolean plugin_init (GstPlugin * plugin) { - struct _elements_entry *my_elements = _elements; - - while ((*my_elements).name) { - if (!gst_element_register (plugin, (*my_elements).name, (*my_elements).rank, - ((*my_elements).type) ())) - return FALSE; - my_elements++; - } + if (!gst_element_register (plugin, "capsfilter", GST_RANK_NONE, + gst_capsfilter_get_type ())) + return FALSE; + if (!gst_element_register (plugin, "fakesrc", GST_RANK_NONE, + gst_fake_src_get_type ())) + return FALSE; + if (!gst_element_register (plugin, "fakesink", GST_RANK_NONE, + gst_fake_sink_get_type ())) + return FALSE; +#if defined(HAVE_SYS_SOCKET_H) || defined(_MSC_VER) + if (!gst_element_register (plugin, "fdsrc", GST_RANK_NONE, + gst_fd_src_get_type ())) + return FALSE; + if (!gst_element_register (plugin, "fdsink", GST_RANK_NONE, + gst_fd_sink_get_type ())) + return FALSE; +#endif + if (!gst_element_register (plugin, "filesrc", GST_RANK_PRIMARY, + gst_file_src_get_type ())) + return FALSE; + if (!gst_element_register (plugin, "funnel", GST_RANK_NONE, + gst_funnel_get_type ())) + return FALSE; + if (!gst_element_register (plugin, "identity", GST_RANK_NONE, + gst_identity_get_type ())) + return FALSE; + if (!gst_element_register (plugin, "input-selector", GST_RANK_NONE, + gst_input_selector_get_type ())) + return FALSE; + if (!gst_element_register (plugin, "output-selector", GST_RANK_NONE, + gst_output_selector_get_type ())) + return FALSE; + if (!gst_element_register (plugin, "queue", GST_RANK_NONE, + gst_queue_get_type ())) + return FALSE; + if (!gst_element_register (plugin, "queue2", GST_RANK_NONE, + gst_queue2_get_type ())) + return FALSE; + if (!gst_element_register (plugin, "filesink", GST_RANK_PRIMARY, + gst_file_sink_get_type ())) + return FALSE; + if (!gst_element_register (plugin, "tee", GST_RANK_NONE, gst_tee_get_type ())) + return FALSE; + if (!gst_element_register (plugin, "typefind", GST_RANK_NONE, + gst_type_find_element_get_type ())) + return FALSE; + if (!gst_element_register (plugin, "multiqueue", GST_RANK_NONE, + gst_multi_queue_get_type ())) + return FALSE; + if (!gst_element_register (plugin, "valve", GST_RANK_NONE, + gst_valve_get_type ())) + return FALSE; return TRUE; } -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - coreelements, - "standard GStreamer elements", - plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN); +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, coreelements, + " GStreamer core elements", plugin_init, VERSION, GST_LICENSE, + GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN); diff --git a/plugins/elements/gstfakesink.c b/plugins/elements/gstfakesink.c index 363fde9..c328f37 100644 --- a/plugins/elements/gstfakesink.c +++ b/plugins/elements/gstfakesink.c @@ -207,8 +207,6 @@ gst_fake_sink_class_init (GstFakeSinkClass * klass) * @pad: the pad that received it * * This signal gets emitted before unreffing the buffer. - * - * Since: 0.10.7 */ gst_fake_sink_signals[SIGNAL_PREROLL_HANDOFF] = g_signal_new ("preroll-handoff", G_TYPE_FROM_CLASS (klass), @@ -478,7 +476,7 @@ gst_fake_sink_render (GstBaseSink * bsink, GstBuffer * buf) sink->last_message = g_strdup_printf ("chain ******* (%s:%s) (%u bytes, dts: %s, pts: %s" ", duration: %s, offset: %" G_GINT64_FORMAT ", offset_end: %" - G_GINT64_FORMAT ", flags: %d %s) %p", + G_GINT64_FORMAT ", flags: %08x %s) %p", GST_DEBUG_PAD_NAME (GST_BASE_SINK_CAST (sink)->sinkpad), (guint) gst_buffer_get_size (buf), dts_str, pts_str, dur_str, GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf), diff --git a/plugins/elements/gstfakesink.h b/plugins/elements/gstfakesink.h index 2db98b9..274b45a 100644 --- a/plugins/elements/gstfakesink.h +++ b/plugins/elements/gstfakesink.h @@ -92,7 +92,7 @@ struct _GstFakeSinkClass { void (*preroll_handoff) (GstElement *element, GstBuffer *buf, GstPad *pad); }; -GType gst_fake_sink_get_type (void); +G_GNUC_INTERNAL GType gst_fake_sink_get_type (void); G_END_DECLS diff --git a/plugins/elements/gstfakesrc.c b/plugins/elements/gstfakesrc.c index 89eb17b..bbdff16 100644 --- a/plugins/elements/gstfakesrc.c +++ b/plugins/elements/gstfakesrc.c @@ -315,8 +315,6 @@ gst_fake_src_class_init (GstFakeSrcClass * klass) * GstFakeSrc:format * * Set the format of the newsegment events to produce. - * - * Since: 0.10.20 */ g_object_class_install_property (gobject_class, PROP_FORMAT, g_param_spec_enum ("format", "Format", @@ -854,7 +852,7 @@ gst_fake_src_create (GstBaseSrc * basesrc, guint64 offset, guint length, src->last_message = g_strdup_printf ("create ******* (%s:%s) (%u bytes, dts: %s, pts:%s" ", duration: %s, offset: %" G_GINT64_FORMAT ", offset_end: %" - G_GINT64_FORMAT ", flags: %d %s) %p", + G_GINT64_FORMAT ", flags: %08x %s) %p", GST_DEBUG_PAD_NAME (GST_BASE_SRC_CAST (src)->srcpad), (guint) size, dts_str, pts_str, dur_str, GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf), GST_MINI_OBJECT_CAST (buf)->flags, diff --git a/plugins/elements/gstfakesrc.h b/plugins/elements/gstfakesrc.h index 965fcb0..3ed0e60 100644 --- a/plugins/elements/gstfakesrc.h +++ b/plugins/elements/gstfakesrc.h @@ -159,7 +159,7 @@ struct _GstFakeSrcClass { void (*handoff) (GstElement *element, GstBuffer *buf, GstPad *pad); }; -GType gst_fake_src_get_type (void); +G_GNUC_INTERNAL GType gst_fake_src_get_type (void); G_END_DECLS diff --git a/plugins/elements/gstfdsink.c b/plugins/elements/gstfdsink.c index 7852561..74d30ca 100644 --- a/plugins/elements/gstfdsink.c +++ b/plugins/elements/gstfdsink.c @@ -41,14 +41,6 @@ #include <sys/types.h> -#ifdef G_OS_WIN32 -#include <io.h> /* lseek, open, close, read */ -#undef lseek -#define lseek _lseeki64 -#undef off_t -#define off_t guint64 -#endif - #include <sys/stat.h> #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> @@ -69,6 +61,14 @@ #include "gstfdsink.h" +#ifdef G_OS_WIN32 +#include <io.h> /* lseek, open, close, read */ +#undef lseek +#define lseek _lseeki64 +#undef off_t +#define off_t guint64 +#endif + static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, diff --git a/plugins/elements/gstfdsink.h b/plugins/elements/gstfdsink.h index 59393d0..643453d 100644 --- a/plugins/elements/gstfdsink.h +++ b/plugins/elements/gstfdsink.h @@ -67,7 +67,7 @@ struct _GstFdSinkClass { GstBaseSinkClass parent_class; }; -GType gst_fd_sink_get_type(void); +G_GNUC_INTERNAL GType gst_fd_sink_get_type (void); G_END_DECLS diff --git a/plugins/elements/gstfdsrc.c b/plugins/elements/gstfdsrc.c index 13c70bd..a29d84c 100644 --- a/plugins/elements/gstfdsrc.c +++ b/plugins/elements/gstfdsrc.c @@ -160,8 +160,6 @@ gst_fd_src_class_init (GstFdSrcClass * klass) * GstFdSrc:timeout * * Post a message after timeout microseconds - * - * Since: 0.10.21 */ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_TIMEOUT, g_param_spec_uint64 ("timeout", "Timeout", diff --git a/plugins/elements/gstfdsrc.h b/plugins/elements/gstfdsrc.h index aac1d52..16e696f 100644 --- a/plugins/elements/gstfdsrc.h +++ b/plugins/elements/gstfdsrc.h @@ -80,7 +80,7 @@ struct _GstFdSrcClass { void (*timeout) (GstElement *element); }; -GType gst_fd_src_get_type(void); +G_GNUC_INTERNAL GType gst_fd_src_get_type(void); G_END_DECLS diff --git a/plugins/elements/gstfilesink.c b/plugins/elements/gstfilesink.c index 7b5218b..c434a56 100644 --- a/plugins/elements/gstfilesink.c +++ b/plugins/elements/gstfilesink.c @@ -212,8 +212,6 @@ gst_file_sink_class_init (GstFileSinkClass * klass) * GstFileSink:append * * Append to an already existing file. - * - * Since: 0.10.25 */ g_object_class_install_property (gobject_class, PROP_APPEND, g_param_spec_boolean ("append", "Append", diff --git a/plugins/elements/gstfilesink.h b/plugins/elements/gstfilesink.h index 3f0d6ce..9776550 100644 --- a/plugins/elements/gstfilesink.h +++ b/plugins/elements/gstfilesink.h @@ -72,7 +72,7 @@ struct _GstFileSinkClass { GstBaseSinkClass parent_class; }; -GType gst_file_sink_get_type(void); +G_GNUC_INTERNAL GType gst_file_sink_get_type (void); G_END_DECLS diff --git a/plugins/elements/gstfilesrc.c b/plugins/elements/gstfilesrc.c index a0672d1..911223b 100644 --- a/plugins/elements/gstfilesrc.c +++ b/plugins/elements/gstfilesrc.c @@ -149,7 +149,6 @@ static gboolean gst_file_src_is_seekable (GstBaseSrc * src); static gboolean gst_file_src_get_size (GstBaseSrc * src, guint64 * size); static GstFlowReturn gst_file_src_fill (GstBaseSrc * src, guint64 offset, guint length, GstBuffer * buf); -static gboolean gst_file_src_query (GstBaseSrc * src, GstQuery * query); static void gst_file_src_uri_handler_init (gpointer g_iface, gpointer iface_data); @@ -195,7 +194,6 @@ gst_file_src_class_init (GstFileSrcClass * klass) gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_file_src_is_seekable); gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_file_src_get_size); gstbasesrc_class->fill = GST_DEBUG_FUNCPTR (gst_file_src_fill); - gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_file_src_query); if (sizeof (off_t) < 8) { GST_LOG ("No large file support, sizeof (off_t) = %" G_GSIZE_FORMAT "!", @@ -404,28 +402,6 @@ eos: } static gboolean -gst_file_src_query (GstBaseSrc * basesrc, GstQuery * query) -{ - gboolean ret = FALSE; - GstFileSrc *src = GST_FILE_SRC (basesrc); - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_URI: - gst_query_set_uri (query, src->uri); - ret = TRUE; - break; - default: - ret = FALSE; - break; - } - - if (!ret) - ret = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query); - - return ret; -} - -static gboolean gst_file_src_is_seekable (GstBaseSrc * basesrc) { GstFileSrc *src = GST_FILE_SRC (basesrc); diff --git a/plugins/elements/gstfilesrc.h b/plugins/elements/gstfilesrc.h index 5aa9f87..18c3c41 100644 --- a/plugins/elements/gstfilesrc.h +++ b/plugins/elements/gstfilesrc.h @@ -69,7 +69,7 @@ struct _GstFileSrcClass { GstBaseSrcClass parent_class; }; -GType gst_file_src_get_type (void); +G_GNUC_INTERNAL GType gst_file_src_get_type (void); G_END_DECLS diff --git a/plugins/elements/gstfunnel.c b/plugins/elements/gstfunnel.c index a15a9e6..fb4fafe 100644 --- a/plugins/elements/gstfunnel.c +++ b/plugins/elements/gstfunnel.c @@ -229,16 +229,19 @@ gst_funnel_release_pad (GstElement * element, GstPad * pad) { GstFunnel *funnel = GST_FUNNEL (element); GstFunnelPad *fpad = GST_FUNNEL_PAD_CAST (pad); + gboolean got_eos; gboolean send_eos = FALSE; GST_DEBUG_OBJECT (funnel, "releasing pad"); gst_pad_set_active (pad, FALSE); + got_eos = fpad->got_eos; + gst_element_remove_pad (GST_ELEMENT_CAST (funnel), pad); GST_OBJECT_LOCK (funnel); - if (!fpad->got_eos && gst_funnel_all_sinkpads_eos_unlocked (funnel)) { + if (!got_eos && gst_funnel_all_sinkpads_eos_unlocked (funnel)) { GST_DEBUG_OBJECT (funnel, "Pad removed. All others are EOS. Sending EOS"); send_eos = TRUE; } diff --git a/plugins/elements/gstfunnel.h b/plugins/elements/gstfunnel.h index 588a651..c968fca 100644 --- a/plugins/elements/gstfunnel.h +++ b/plugins/elements/gstfunnel.h @@ -62,7 +62,7 @@ struct _GstFunnelClass { GstElementClass parent_class; }; -GType gst_funnel_get_type (void); +G_GNUC_INTERNAL GType gst_funnel_get_type (void); G_END_DECLS diff --git a/plugins/elements/gstidentity.c b/plugins/elements/gstidentity.c index 50afaec..8361a7a 100644 --- a/plugins/elements/gstidentity.c +++ b/plugins/elements/gstidentity.c @@ -67,7 +67,6 @@ enum #define DEFAULT_SINGLE_SEGMENT FALSE #define DEFAULT_DUMP FALSE #define DEFAULT_SYNC FALSE -#define DEFAULT_CHECK_PERFECT FALSE #define DEFAULT_CHECK_IMPERFECT_TIMESTAMP FALSE #define DEFAULT_CHECK_IMPERFECT_OFFSET FALSE #define DEFAULT_SIGNAL_HANDOFFS TRUE @@ -84,7 +83,6 @@ enum PROP_LAST_MESSAGE, PROP_DUMP, PROP_SYNC, - PROP_CHECK_PERFECT, PROP_CHECK_IMPERFECT_TIMESTAMP, PROP_CHECK_IMPERFECT_OFFSET, PROP_SIGNAL_HANDOFFS @@ -178,12 +176,6 @@ gst_identity_class_init (GstIdentityClass * klass) g_param_spec_boolean ("sync", "Synchronize", "Synchronize to pipeline clock", DEFAULT_SYNC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_CHECK_PERFECT, - g_param_spec_boolean ("check-perfect", "Check For Perfect Stream", - "Verify that the stream is time- and data-contiguous. " - "This only logs in the debug log. This will be deprecated in favor " - "of the check-imperfect-timestamp/offset properties.", - DEFAULT_CHECK_PERFECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_CHECK_IMPERFECT_TIMESTAMP, g_param_spec_boolean ("check-imperfect-timestamp", @@ -203,8 +195,6 @@ gst_identity_class_init (GstIdentityClass * klass) * * If set to #TRUE, the identity will emit a handoff signal when handling a buffer. * When set to #FALSE, no signal will be emited, which might improve performance. - * - * Since: 0.10.16 */ g_object_class_install_property (gobject_class, PROP_SIGNAL_HANDOFFS, g_param_spec_boolean ("signal-handoffs", @@ -256,7 +246,6 @@ gst_identity_init (GstIdentity * identity) identity->silent = DEFAULT_SILENT; identity->single_segment = DEFAULT_SINGLE_SEGMENT; identity->sync = DEFAULT_SYNC; - identity->check_perfect = DEFAULT_CHECK_PERFECT; identity->check_imperfect_timestamp = DEFAULT_CHECK_IMPERFECT_TIMESTAMP; identity->check_imperfect_offset = DEFAULT_CHECK_IMPERFECT_OFFSET; identity->dump = DEFAULT_DUMP; @@ -351,51 +340,6 @@ gst_identity_sink_event (GstBaseTransform * trans, GstEvent * event) } static void -gst_identity_check_perfect (GstIdentity * identity, GstBuffer * buf) -{ - GstClockTime timestamp; - - timestamp = GST_BUFFER_TIMESTAMP (buf); - - /* see if we need to do perfect stream checking */ - /* invalid timestamp drops us out of check. FIXME: maybe warn ? */ - if (timestamp != GST_CLOCK_TIME_NONE) { - /* check if we had a previous buffer to compare to */ - if (identity->prev_timestamp != GST_CLOCK_TIME_NONE && - identity->prev_duration != GST_CLOCK_TIME_NONE) { - guint64 offset, t_expected; - gint64 dt; - - t_expected = identity->prev_timestamp + identity->prev_duration; - dt = timestamp - t_expected; - if (dt != 0) { - GST_WARNING_OBJECT (identity, - "Buffer not time-contiguous with previous one: " "prev ts %" - GST_TIME_FORMAT ", prev dur %" GST_TIME_FORMAT ", new ts %" - GST_TIME_FORMAT " (expected ts %" GST_TIME_FORMAT ", delta=%c%" - GST_TIME_FORMAT ")", GST_TIME_ARGS (identity->prev_timestamp), - GST_TIME_ARGS (identity->prev_duration), GST_TIME_ARGS (timestamp), - GST_TIME_ARGS (t_expected), (dt < 0) ? '-' : '+', - GST_TIME_ARGS ((dt < 0) ? (GstClockTime) (-dt) : dt)); - } - - offset = GST_BUFFER_OFFSET (buf); - if (identity->prev_offset_end != offset && - identity->prev_offset_end != GST_BUFFER_OFFSET_NONE && - offset != GST_BUFFER_OFFSET_NONE) { - GST_WARNING_OBJECT (identity, - "Buffer not data-contiguous with previous one: " - "prev offset_end %" G_GINT64_FORMAT ", new offset %" - G_GINT64_FORMAT, identity->prev_offset_end, offset); - } - } else { - GST_DEBUG_OBJECT (identity, "can't check time-contiguity, no timestamp " - "and/or duration were set on previous buffer"); - } - } -} - -static void gst_identity_check_imperfect_timestamp (GstIdentity * identity, GstBuffer * buf) { GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buf); @@ -532,7 +476,7 @@ gst_identity_update_last_message_for_buffer (GstIdentity * identity, identity->last_message = g_strdup_printf ("%s ******* (%s:%s) " "(%" G_GSIZE_FORMAT " bytes, dts: %s, pts:%s, duration: %s, offset: %" G_GINT64_FORMAT ", " "offset_end: % " G_GINT64_FORMAT - ", flags: %d %s) %p", action, + ", flags: %08x %s) %p", action, GST_DEBUG_PAD_NAME (GST_BASE_TRANSFORM_CAST (identity)->sinkpad), size, print_pretty_time (dts_str, sizeof (dts_str), GST_BUFFER_DTS (buf)), print_pretty_time (pts_str, sizeof (pts_str), GST_BUFFER_PTS (buf)), @@ -555,8 +499,6 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf) size = gst_buffer_get_size (buf); - if (identity->check_perfect) - gst_identity_check_perfect (identity, buf); if (identity->check_imperfect_timestamp) gst_identity_check_imperfect_timestamp (identity, buf); if (identity->check_imperfect_offset) @@ -698,9 +640,6 @@ gst_identity_set_property (GObject * object, guint prop_id, case PROP_SYNC: identity->sync = g_value_get_boolean (value); break; - case PROP_CHECK_PERFECT: - identity->check_perfect = g_value_get_boolean (value); - break; case PROP_CHECK_IMPERFECT_TIMESTAMP: identity->check_imperfect_timestamp = g_value_get_boolean (value); break; @@ -758,9 +697,6 @@ gst_identity_get_property (GObject * object, guint prop_id, GValue * value, case PROP_SYNC: g_value_set_boolean (value, identity->sync); break; - case PROP_CHECK_PERFECT: - g_value_set_boolean (value, identity->check_perfect); - break; case PROP_CHECK_IMPERFECT_TIMESTAMP: g_value_set_boolean (value, identity->check_imperfect_timestamp); break; diff --git a/plugins/elements/gstidentity.h b/plugins/elements/gstidentity.h index fabc667..835cf94 100644 --- a/plugins/elements/gstidentity.h +++ b/plugins/elements/gstidentity.h @@ -62,7 +62,6 @@ struct _GstIdentity { gboolean silent; gboolean dump; gboolean sync; - gboolean check_perfect; gboolean check_imperfect_timestamp; gboolean check_imperfect_offset; gboolean single_segment; @@ -82,7 +81,7 @@ struct _GstIdentityClass { void (*handoff) (GstElement *element, GstBuffer *buf); }; -GType gst_identity_get_type(void); +G_GNUC_INTERNAL GType gst_identity_get_type (void); G_END_DECLS diff --git a/plugins/elements/gstinputselector.c b/plugins/elements/gstinputselector.c index 9133a8c..7d63fb0 100644 --- a/plugins/elements/gstinputselector.c +++ b/plugins/elements/gstinputselector.c @@ -47,8 +47,6 @@ * #GST_FLOW_NOT_LINKED * </listitem> * </itemizedlist> - * - * Since: 0.10.32 */ #ifdef HAVE_CONFIG_H @@ -85,15 +83,6 @@ gst_input_selector_sync_mode_get_type (void) return type; } -#if GLIB_CHECK_VERSION(2, 26, 0) -#define NOTIFY_MUTEX_LOCK() -#define NOTIFY_MUTEX_UNLOCK() -#else -static GStaticRecMutex notify_mutex = G_STATIC_REC_MUTEX_INIT; -#define NOTIFY_MUTEX_LOCK() g_static_rec_mutex_lock (¬ify_mutex) -#define NOTIFY_MUTEX_UNLOCK() g_static_rec_mutex_unlock (¬ify_mutex) -#endif - #define GST_INPUT_SELECTOR_GET_LOCK(sel) (&((GstInputSelector*)(sel))->lock) #define GST_INPUT_SELECTOR_GET_COND(sel) (&((GstInputSelector*)(sel))->cond) #define GST_INPUT_SELECTOR_LOCK(sel) (g_mutex_lock (GST_INPUT_SELECTOR_GET_LOCK(sel))) @@ -454,6 +443,7 @@ gst_selector_pad_event (GstPad * pad, GstObject * parent, GstEvent * event) { gboolean res = TRUE; gboolean forward; + gboolean new_tags = FALSE; GstInputSelector *sel; GstSelectorPad *selpad; GstPad *prev_active_sinkpad; @@ -524,7 +514,7 @@ gst_selector_pad_event (GstPad * pad, GstObject * parent, GstEvent * event) gst_tag_list_unref (oldtags); GST_DEBUG_OBJECT (pad, "received tags %" GST_PTR_FORMAT, newtags); - g_object_notify (G_OBJECT (selpad), "tags"); + new_tags = TRUE; break; } case GST_EVENT_EOS: @@ -551,6 +541,8 @@ gst_selector_pad_event (GstPad * pad, GstObject * parent, GstEvent * event) break; } GST_INPUT_SELECTOR_UNLOCK (sel); + if (new_tags) + g_object_notify (G_OBJECT (selpad), "tags"); if (forward) { GST_DEBUG_OBJECT (pad, "forwarding event"); res = gst_pad_push_event (sel->srcpad, event); @@ -575,11 +567,32 @@ gst_selector_pad_query (GstPad * pad, GstObject * parent, GstQuery * query) gboolean res = FALSE; switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_ALLOCATION:{ + GstPad *active_sinkpad; + GstInputSelector *sel = GST_INPUT_SELECTOR (parent); + + /* Only do the allocation query for the active sinkpad, + * after switching a reconfigure event is sent and upstream + * should reconfigure and do a new allocation query + */ + if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) { + GST_INPUT_SELECTOR_LOCK (sel); + active_sinkpad = gst_input_selector_activate_sinkpad (sel, pad); + GST_INPUT_SELECTOR_UNLOCK (sel); + + if (pad != active_sinkpad) { + res = FALSE; + goto done; + } + } + } + /* fall through */ default: res = gst_pad_query_default (pad, parent, query); break; } +done: return res; } @@ -1098,38 +1111,6 @@ static gboolean gst_input_selector_query (GstPad * pad, GstObject * parent, GstQuery * query); static gint64 gst_input_selector_block (GstInputSelector * self); -/* FIXME: create these marshallers using glib-genmarshal */ -static void -gst_input_selector_marshal_INT64__VOID (GClosure * closure, - GValue * return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue * param_values, - gpointer invocation_hint G_GNUC_UNUSED, gpointer marshal_data) -{ - typedef gint64 (*GMarshalFunc_INT64__VOID) (gpointer data1, gpointer data2); - register GMarshalFunc_INT64__VOID callback; - register GCClosure *cc = (GCClosure *) closure; - register gpointer data1, data2; - gint64 v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 1); - - if (G_CCLOSURE_SWAP_DATA (closure)) { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } else { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = - (GMarshalFunc_INT64__VOID) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, data2); - - g_value_set_int64 (return_value, v_return); -} - #define _do_init \ GST_DEBUG_CATEGORY_INIT (input_selector_debug, \ "input-selector", 0, "An input stream selector element"); @@ -1168,8 +1149,6 @@ gst_input_selector_class_init (GstInputSelectorClass * klass) * To make sure no buffers are dropped by input-selector * that might be needed when switching the active pad, * sync-mode should be set to "clock" and cache-buffers to TRUE. - * - * Since: 0.10.36 */ g_object_class_install_property (gobject_class, PROP_SYNC_STREAMS, g_param_spec_boolean ("sync-streams", "Sync Streams", @@ -1188,8 +1167,6 @@ gst_input_selector_class_init (GstInputSelectorClass * klass) * be ahead of current clock time when switching the active pad, as the current * active pad may have pushed more buffers than what was displayed/consumed, * which may cause delays and some missing buffers. - * - * Since: 0.10.36 */ g_object_class_install_property (gobject_class, PROP_SYNC_MODE, g_param_spec_enum ("sync-mode", "Sync mode", @@ -1229,7 +1206,7 @@ gst_input_selector_class_init (GstInputSelectorClass * klass) g_signal_new ("block", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstInputSelectorClass, block), NULL, NULL, - gst_input_selector_marshal_INT64__VOID, G_TYPE_INT64, 0); + g_cclosure_marshal_generic, G_TYPE_INT64, 0); gst_element_class_set_static_metadata (gstelement_class, "Input selector", "Generic", "N-to-1 input stream selector", @@ -1328,6 +1305,11 @@ gst_input_selector_set_active_pad (GstInputSelector * self, GstPad * pad) active_pad_p = &self->active_sinkpad; gst_object_replace ((GstObject **) active_pad_p, GST_OBJECT_CAST (pad)); + if (old && old != new) + gst_pad_push_event (GST_PAD_CAST (old), gst_event_new_reconfigure ()); + if (new) + gst_pad_push_event (GST_PAD_CAST (new), gst_event_new_reconfigure ()); + GST_DEBUG_OBJECT (self, "New active pad is %" GST_PTR_FORMAT, self->active_sinkpad); @@ -1604,12 +1586,24 @@ gst_input_selector_activate_sinkpad (GstInputSelector * sel, GstPad * pad) selpad->active = TRUE; active_sinkpad = sel->active_sinkpad; - if (active_sinkpad == NULL) { - /* first pad we get activity on becomes the activated pad by default */ - if (sel->active_sinkpad) - gst_object_unref (sel->active_sinkpad); - active_sinkpad = sel->active_sinkpad = gst_object_ref (pad); - GST_DEBUG_OBJECT (sel, "Activating pad %s:%s", GST_DEBUG_PAD_NAME (pad)); + if (sel->active_sinkpad == NULL) { + GValue item = G_VALUE_INIT; + GstIterator *iter = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (sel)); + GstIteratorResult ires; + + while ((ires = gst_iterator_next (iter, &item)) == GST_ITERATOR_RESYNC) + gst_iterator_resync (iter); + if (ires == GST_ITERATOR_OK) { + /* If no pad is currently selected, we return the first usable pad to + * guarantee consistency */ + + active_sinkpad = sel->active_sinkpad = g_value_dup_object (&item); + g_value_reset (&item); + GST_DEBUG_OBJECT (sel, "Activating pad %s:%s", + GST_DEBUG_PAD_NAME (active_sinkpad)); + } else + GST_WARNING_OBJECT (sel, "Couldn't find a default sink pad"); + gst_iterator_free (iter); } return active_sinkpad; diff --git a/plugins/elements/gstinputselector.h b/plugins/elements/gstinputselector.h index dd48a51..2bfcd3e 100644 --- a/plugins/elements/gstinputselector.h +++ b/plugins/elements/gstinputselector.h @@ -84,7 +84,7 @@ struct _GstInputSelectorClass { gint64 (*block) (GstInputSelector *self); }; -GType gst_input_selector_get_type (void); +G_GNUC_INTERNAL GType gst_input_selector_get_type (void); G_END_DECLS diff --git a/plugins/elements/gstmultiqueue.c b/plugins/elements/gstmultiqueue.c index bd3b69c..cfa8a24 100644 --- a/plugins/elements/gstmultiqueue.c +++ b/plugins/elements/gstmultiqueue.c @@ -368,8 +368,6 @@ gst_multi_queue_class_init (GstMultiQueueClass * klass) * * Enable the buffering option in multiqueue so that BUFFERING messages are * emited based on low-/high-percent thresholds. - * - * Since: 0.10.26 */ g_object_class_install_property (gobject_class, PROP_USE_BUFFERING, g_param_spec_boolean ("use-buffering", "Use buffering", @@ -379,8 +377,6 @@ gst_multi_queue_class_init (GstMultiQueueClass * klass) * GstMultiQueue:low-percent * * Low threshold percent for buffering to start. - * - * Since: 0.10.26 */ g_object_class_install_property (gobject_class, PROP_LOW_PERCENT, g_param_spec_int ("low-percent", "Low percent", @@ -390,8 +386,6 @@ gst_multi_queue_class_init (GstMultiQueueClass * klass) * GstMultiQueue:high-percent * * High threshold percent for buffering to finish. - * - * Since: 0.10.26 */ g_object_class_install_property (gobject_class, PROP_HIGH_PERCENT, g_param_spec_int ("high-percent", "High percent", @@ -406,8 +400,6 @@ gst_multi_queue_class_init (GstMultiQueueClass * klass) * 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.36 */ g_object_class_install_property (gobject_class, PROP_SYNC_BY_RUNNING_TIME, g_param_spec_boolean ("sync-by-running-time", "Sync By Running Time", @@ -794,7 +786,7 @@ gst_single_queue_flush (GstMultiQueue * mq, GstSingleQueue * sq, gboolean flush) GST_LOG_OBJECT (mq, "SingleQueue %d : starting task", sq->id); result = gst_pad_start_task (sq->srcpad, (GstTaskFunction) gst_multi_queue_loop, - sq->srcpad); + sq->srcpad, NULL); } return result; } diff --git a/plugins/elements/gstmultiqueue.h b/plugins/elements/gstmultiqueue.h index 04c7501..986dc22 100644 --- a/plugins/elements/gstmultiqueue.h +++ b/plugins/elements/gstmultiqueue.h @@ -84,7 +84,7 @@ struct _GstMultiQueueClass { void (*overrun) (GstMultiQueue *queue); }; -GType gst_multi_queue_get_type (void); +G_GNUC_INTERNAL GType gst_multi_queue_get_type (void); G_END_DECLS diff --git a/plugins/elements/gstoutputselector.c b/plugins/elements/gstoutputselector.c index 04422ad..294c2bc 100644 --- a/plugins/elements/gstoutputselector.c +++ b/plugins/elements/gstoutputselector.c @@ -22,8 +22,6 @@ * @see_also: #GstOutputSelector, #GstInputSelector * * Direct input stream to one out of N output pads. - * - * Since: 0.10.32 */ #ifdef HAVE_CONFIG_H diff --git a/plugins/elements/gstoutputselector.h b/plugins/elements/gstoutputselector.h index 8c55b44..b2a4728 100644 --- a/plugins/elements/gstoutputselector.h +++ b/plugins/elements/gstoutputselector.h @@ -61,7 +61,7 @@ struct _GstOutputSelectorClass { GstElementClass parent_class; }; -GType gst_output_selector_get_type (void); +G_GNUC_INTERNAL GType gst_output_selector_get_type (void); G_END_DECLS diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c index aa494be..2989823 100644 --- a/plugins/elements/gstqueue.c +++ b/plugins/elements/gstqueue.c @@ -353,8 +353,6 @@ gst_queue_class_init (GstQueueClass * klass) * * Don't emit queue signals. Makes queues more lightweight if no signals are * needed. - * - * Since: 0.10.31 */ g_object_class_install_property (gobject_class, PROP_SILENT, g_param_spec_boolean ("silent", "Silent", @@ -419,7 +417,7 @@ gst_queue_init (GstQueue * queue) g_cond_init (&queue->item_add); g_cond_init (&queue->item_del); - g_queue_init (&queue->queue); + gst_queue_array_init (&queue->queue, DEFAULT_MAX_SIZE_BUFFERS * 3 / 2); queue->sinktime = GST_CLOCK_TIME_NONE; queue->srctime = GST_CLOCK_TIME_NONE; @@ -442,12 +440,14 @@ gst_queue_finalize (GObject * object) GST_DEBUG_OBJECT (queue, "finalizing queue"); - while ((data = g_queue_pop_head (&queue->queue))) { + while (!gst_queue_array_is_empty (&queue->queue)) { + data = gst_queue_array_pop_head (&queue->queue); + /* FIXME: if it's a query, shouldn't we unref that too? */ if (!GST_IS_QUERY (data)) gst_mini_object_unref (data); } + gst_queue_array_clear (&queue->queue); - g_queue_clear (&queue->queue); g_mutex_clear (&queue->qlock); g_cond_clear (&queue->item_add); g_cond_clear (&queue->item_del); @@ -556,7 +556,8 @@ gst_queue_locked_flush (GstQueue * queue) { GstMiniObject *data; - while ((data = g_queue_pop_head (&queue->queue))) { + while (!gst_queue_array_is_empty (&queue->queue)) { + data = gst_queue_array_pop_head (&queue->queue); /* Then lose another reference because we are supposed to destroy that data when flushing */ if (!GST_IS_QUERY (data)) @@ -588,7 +589,8 @@ gst_queue_locked_enqueue_buffer (GstQueue * queue, gpointer item) queue->cur_level.bytes += gst_buffer_get_size (buffer); apply_buffer (queue, buffer, &queue->sink_segment, TRUE, TRUE); - g_queue_push_tail (&queue->queue, item); + if (item) + gst_queue_array_push_tail (&queue->queue, item); GST_QUEUE_SIGNAL_ADD (queue); } @@ -622,7 +624,8 @@ gst_queue_locked_enqueue_event (GstQueue * queue, gpointer item) break; } - g_queue_push_tail (&queue->queue, item); + if (item) + gst_queue_array_push_tail (&queue->queue, item); GST_QUEUE_SIGNAL_ADD (queue); } @@ -632,7 +635,7 @@ gst_queue_locked_dequeue (GstQueue * queue) { GstMiniObject *item; - item = g_queue_pop_head (&queue->queue); + item = gst_queue_array_pop_head (&queue->queue); if (item == NULL) goto no_item; @@ -735,7 +738,7 @@ gst_queue_handle_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) queue->eos = FALSE; queue->unexpected = FALSE; gst_pad_start_task (queue->srcpad, (GstTaskFunction) gst_queue_loop, - queue->srcpad); + queue->srcpad, NULL); GST_QUEUE_MUTEX_UNLOCK (queue); STATUS (queue, pad, "after flush"); @@ -789,7 +792,7 @@ gst_queue_handle_sink_query (GstPad * pad, GstObject * parent, GstQuery * query) GST_QUEUE_MUTEX_LOCK_CHECK (queue, out_flushing); GST_LOG_OBJECT (queue, "queuing query %p (%s)", query, GST_QUERY_TYPE_NAME (query)); - g_queue_push_tail (&queue->queue, query); + gst_queue_array_push_tail (&queue->queue, query); GST_QUEUE_SIGNAL_ADD (queue); while (queue->queue.length != 0) { /* for as long as the queue has items, we know the query is @@ -817,9 +820,19 @@ out_flushing: static gboolean gst_queue_is_empty (GstQueue * queue) { + GstMiniObject *head; + if (queue->queue.length == 0) return TRUE; + /* Only consider the queue empty if the minimum thresholds + * are not reached and data is at the queue head. Otherwise + * we would block forever on serialized queries. + */ + head = queue->queue.array[queue->queue.head]; + if (!GST_IS_BUFFER (head) && !GST_IS_BUFFER_LIST (head)) + return FALSE; + /* It is possible that a max size is reached before all min thresholds are. * Therefore, only consider it empty if it is not filled. */ return ((queue->min_threshold.buffers > 0 && @@ -1203,10 +1216,21 @@ gst_queue_handle_src_query (GstPad * pad, GstObject * parent, GstQuery * query) GstQueue *queue = GST_QUEUE (parent); gboolean res; - res = gst_pad_query_default (pad, parent, query); + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_SCHEDULING:{ + gst_query_add_scheduling_mode (query, GST_PAD_MODE_PUSH); + res = TRUE; + break; + } + default: + res = gst_pad_query_default (pad, parent, query); + break; + } + if (!res) return FALSE; + /* Adjust peer response for data contained in queue */ switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { @@ -1314,7 +1338,8 @@ gst_queue_src_activate_mode (GstPad * pad, GstObject * parent, GstPadMode mode, queue->eos = FALSE; queue->unexpected = FALSE; result = - gst_pad_start_task (pad, (GstTaskFunction) gst_queue_loop, pad); + gst_pad_start_task (pad, (GstTaskFunction) gst_queue_loop, pad, + NULL); GST_QUEUE_MUTEX_UNLOCK (queue); } else { /* step 1, unblock loop function */ diff --git a/plugins/elements/gstqueue.h b/plugins/elements/gstqueue.h index 57ccc2a..1ed123e 100644 --- a/plugins/elements/gstqueue.h +++ b/plugins/elements/gstqueue.h @@ -25,6 +25,7 @@ #define __GST_QUEUE_H__ #include <gst/gst.h> +#include "gstqueuearray.h" G_BEGIN_DECLS @@ -107,7 +108,7 @@ struct _GstQueue { gboolean eos; /* the queue of data we're keeping our grubby hands on */ - GQueue queue; + GstQueueArray queue; GstQueueSize cur_level, /* currently in the queue */ @@ -147,7 +148,7 @@ struct _GstQueueClass { void (*pushing) (GstQueue *queue); }; -GType gst_queue_get_type (void); +G_GNUC_INTERNAL GType gst_queue_get_type (void); G_END_DECLS diff --git a/plugins/elements/gstqueue2.c b/plugins/elements/gstqueue2.c index 158da10..13e9d22 100644 --- a/plugins/elements/gstqueue2.c +++ b/plugins/elements/gstqueue2.c @@ -46,10 +46,8 @@ * By using this, it will buffer the entire stream data on the file independently * of the queue size limits, they will only be used for buffering statistics. * - * Since 0.10.24, setting the temp-location property with a filename is deprecated - * because it's impossible to securely open a temporary file in this way. The - * property will still be used to notify the application of the allocated - * filename, though. + * The temp-location property will be used to notify the application of the + * allocated filename. * * Last reviewed on 2009-07-10 (0.10.24) */ @@ -98,7 +96,7 @@ enum /* other defines */ #define DEFAULT_BUFFER_SIZE 4096 -#define QUEUE_IS_USING_TEMP_FILE(queue) ((queue)->temp_location_set || (queue)->temp_template != NULL) +#define QUEUE_IS_USING_TEMP_FILE(queue) ((queue)->temp_template != NULL) #define QUEUE_IS_USING_RING_BUFFER(queue) ((queue)->ring_buffer_max_size != 0) /* for consistency with the above macro */ #define QUEUE_IS_USING_QUEUE(queue) (!QUEUE_IS_USING_TEMP_FILE(queue) && !QUEUE_IS_USING_RING_BUFFER (queue)) @@ -334,16 +332,14 @@ gst_queue2_class_init (GstQueue2Class * klass) g_object_class_install_property (gobject_class, PROP_TEMP_LOCATION, g_param_spec_string ("temp-location", "Temporary File Location", - "Location to store temporary files in (Deprecated: Only read this " - "property, use temp-template to configure the name template)", - NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + "Location to store temporary files in (Only read this property, " + "use temp-template to configure the name template)", + NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); /** * GstQueue2:temp-remove * * When temp-template is set, remove the temporary file when going to READY. - * - * Since: 0.10.26 */ g_object_class_install_property (gobject_class, PROP_TEMP_REMOVE, g_param_spec_boolean ("temp-remove", "Remove the Temporary File", @@ -355,8 +351,6 @@ gst_queue2_class_init (GstQueue2Class * klass) * * The maximum size of the ring buffer in bytes. If set to 0, the ring * buffer is disabled. Default 0. - * - * Since: 0.10.31 */ g_object_class_install_property (gobject_class, PROP_RING_BUFFER_MAX_SIZE, g_param_spec_uint64 ("ring-buffer-max-size", @@ -451,7 +445,6 @@ gst_queue2_init (GstQueue2 * queue) /* tempfile related */ queue->temp_template = NULL; queue->temp_location = NULL; - queue->temp_location_set = FALSE; queue->temp_remove = DEFAULT_TEMP_REMOVE; queue->ring_buffer = NULL; @@ -786,7 +779,6 @@ update_buffering (GstQueue2 * queue) GST_LOG_OBJECT (queue, "we are EOS"); } else { /* figure out the percent we are filled, we take the max of all formats. */ - if (!QUEUE_IS_USING_RING_BUFFER (queue)) { percent = GET_PERCENT (bytes, 0); } else { @@ -817,8 +809,6 @@ update_buffering (GstQueue2 * queue) } if (post) { GstMessage *message; - GstBufferingMode mode; - gint64 buffering_left = -1; /* scale to high percent so that it becomes the 100% mark */ percent = percent * 100 / queue->high_percent; @@ -826,31 +816,34 @@ update_buffering (GstQueue2 * queue) if (percent > 100) percent = 100; + if (percent != queue->buffering_percent) { + GstBufferingMode mode; + gint64 buffering_left; + + buffering_left = (percent == 100 ? 0 : -1); + queue->buffering_percent = percent; if (!QUEUE_IS_USING_QUEUE (queue)) { - gint64 duration; - if (QUEUE_IS_USING_RING_BUFFER (queue)) mode = GST_BUFFERING_TIMESHIFT; else mode = GST_BUFFERING_DOWNLOAD; - - if (queue->byte_in_rate > 0) { - if (gst_pad_peer_query_duration (queue->sinkpad, GST_FORMAT_BYTES, - &duration)) { - buffering_left = - (gdouble) ((duration - - queue->current->writing_pos) * 1000) / queue->byte_in_rate; - } - } else { - buffering_left = G_MAXINT64; - } } else { mode = GST_BUFFERING_STREAM; } + if (queue->use_rate_estimate) { + guint64 max, cur; + + max = queue->max_level.rate_time; + cur = queue->cur_level.rate_time; + + if (percent != 100 && max > cur) + buffering_left = (max - cur) / 1000000; + } + GST_DEBUG_OBJECT (queue, "buffering %d percent", (gint) percent); message = gst_message_new_buffering (GST_OBJECT_CAST (queue), (gint) percent); @@ -1374,45 +1367,34 @@ gst_queue2_open_temp_location_file (GstQueue2 * queue) GST_DEBUG_OBJECT (queue, "opening temp file %s", queue->temp_template); - /* we have two cases: - * - temp_location was set to something !NULL (Deprecated). in this case we - * open the specified filename. - * - temp_template was set, allocate a filename and open that filename - */ - if (!queue->temp_location_set) { - /* nothing to do */ - if (queue->temp_template == NULL) - goto no_directory; - - /* make copy of the template, we don't want to change this */ - name = g_strdup (queue->temp_template); - fd = g_mkstemp (name); - if (fd == -1) - goto mkstemp_failed; - - /* open the file for update/writing */ - queue->temp_file = fdopen (fd, "wb+"); - /* error creating file */ - if (queue->temp_file == NULL) - goto open_failed; - - g_free (queue->temp_location); - queue->temp_location = name; + /* If temp_template was set, allocate a filename and open that filen */ - GST_QUEUE2_MUTEX_UNLOCK (queue); + /* nothing to do */ + if (queue->temp_template == NULL) + goto no_directory; + + /* make copy of the template, we don't want to change this */ + name = g_strdup (queue->temp_template); + fd = g_mkstemp (name); + if (fd == -1) + goto mkstemp_failed; + + /* open the file for update/writing */ + queue->temp_file = fdopen (fd, "wb+"); + /* error creating file */ + if (queue->temp_file == NULL) + goto open_failed; - /* we can't emit the notify with the lock */ - g_object_notify (G_OBJECT (queue), "temp-location"); + g_free (queue->temp_location); + queue->temp_location = name; + + GST_QUEUE2_MUTEX_UNLOCK (queue); + + /* we can't emit the notify with the lock */ + g_object_notify (G_OBJECT (queue), "temp-location"); + + GST_QUEUE2_MUTEX_LOCK (queue); - GST_QUEUE2_MUTEX_LOCK (queue); - } else { - /* open the file for update/writing, this is deprecated but we still need to - * support it for API/ABI compatibility */ - queue->temp_file = g_fopen (queue->temp_location, "wb+"); - /* error creating file */ - if (queue->temp_file == NULL) - goto open_failed; - } GST_DEBUG_OBJECT (queue, "opened temp file %s", queue->temp_template); return TRUE; @@ -1941,6 +1923,19 @@ gst_queue2_locked_enqueue (GstQueue2 * queue, gpointer item, item = NULL; } break; + case GST_EVENT_CAPS:{ + GstCaps *caps; + + gst_event_parse_caps (event, &caps); + GST_INFO ("got caps: %" GST_PTR_FORMAT, caps); + + if (!QUEUE_IS_USING_QUEUE (queue)) { + GST_LOG ("Dropping caps event, not using queue"); + gst_event_unref (event); + item = NULL; + } + break; + } default: if (!QUEUE_IS_USING_QUEUE (queue)) goto unexpected_event; @@ -2139,7 +2134,7 @@ gst_queue2_handle_sink_event (GstPad * pad, GstObject * parent, /* reset rate counters */ reset_rate_timer (queue); gst_pad_start_task (queue->srcpad, (GstTaskFunction) gst_queue2_loop, - queue->srcpad); + queue->srcpad, NULL); GST_QUEUE2_MUTEX_UNLOCK (queue); } else { GST_QUEUE2_MUTEX_LOCK (queue); @@ -2697,16 +2692,31 @@ gst_queue2_handle_src_query (GstPad * pad, GstObject * parent, GstQuery * query) GST_FORMAT_BYTES, &duration); } + GST_DEBUG_OBJECT (queue, "percent %d, duration %" G_GINT64_FORMAT + ", writing %" G_GINT64_FORMAT, percent, duration, writing_pos); + /* calculate remaining and total download time */ - if (peer_res && byte_in_rate > 0.0) { - estimated_total = (duration * 1000) / byte_in_rate; - buffering_left = ((duration - writing_pos) * 1000) / byte_in_rate; - } else { + if (peer_res && byte_in_rate > 0.0) + estimated_total = ((duration - writing_pos) * 1000) / byte_in_rate; + else estimated_total = -1; - buffering_left = -1; + + /* calculate estimated remaining buffer time */ + buffering_left = (percent == 100 ? 0 : -1); + + if (queue->use_rate_estimate) { + guint64 max, cur; + + max = queue->max_level.rate_time; + cur = queue->cur_level.rate_time; + + if (percent != 100 && max > cur) + buffering_left = (max - cur) / 1000000; } - GST_DEBUG_OBJECT (queue, "estimated %" G_GINT64_FORMAT ", left %" - G_GINT64_FORMAT, estimated_total, buffering_left); + + GST_DEBUG_OBJECT (queue, "estimated-total %" G_GINT64_FORMAT + ", buffering-left %" G_GINT64_FORMAT, estimated_total, + buffering_left); gst_query_parse_buffering_range (query, &format, NULL, NULL, NULL); @@ -2716,14 +2726,12 @@ gst_queue2_handle_src_query (GstPad * pad, GstObject * parent, GstQuery * query) if (!peer_res) goto peer_failed; - GST_DEBUG_OBJECT (queue, - "duration %" G_GINT64_FORMAT ", writing %" G_GINT64_FORMAT, - duration, writing_pos); - start = 0; /* get our available data relative to the duration */ if (duration != -1) - stop = GST_FORMAT_PERCENT_MAX * writing_pos / duration; + stop = + gst_util_uint64_scale (GST_FORMAT_PERCENT_MAX, writing_pos, + duration); else stop = -1; break; @@ -2747,8 +2755,12 @@ gst_queue2_handle_src_query (GstPad * pad, GstObject * parent, GstQuery * query) range_stop = 0; break; } - range_start = 100 * queued_ranges->offset / duration; - range_stop = 100 * queued_ranges->writing_pos / duration; + range_start = + gst_util_uint64_scale (GST_FORMAT_PERCENT_MAX, + queued_ranges->offset, duration); + range_stop = + gst_util_uint64_scale (GST_FORMAT_PERCENT_MAX, + queued_ranges->writing_pos, duration); break; case GST_FORMAT_BYTES: range_start = queued_ranges->offset; @@ -2768,10 +2780,10 @@ gst_queue2_handle_src_query (GstPad * pad, GstObject * parent, GstQuery * query) } gst_query_set_buffering_percent (query, is_buffering, percent); - gst_query_set_buffering_range (query, format, start, stop, - estimated_total); gst_query_set_buffering_stats (query, GST_BUFFERING_DOWNLOAD, byte_in_rate, byte_out_rate, buffering_left); + gst_query_set_buffering_range (query, format, start, stop, + estimated_total); } break; } @@ -2944,7 +2956,8 @@ gst_queue2_src_activate_push (GstPad * pad, GstObject * parent, gboolean active) queue->sinkresult = GST_FLOW_OK; queue->is_eos = FALSE; queue->unexpected = FALSE; - result = gst_pad_start_task (pad, (GstTaskFunction) gst_queue2_loop, pad); + result = + gst_pad_start_task (pad, (GstTaskFunction) gst_queue2_loop, pad, NULL); GST_QUEUE2_MUTEX_UNLOCK (queue); } else { /* unblock loop function */ @@ -3192,13 +3205,6 @@ gst_queue2_set_property (GObject * object, case PROP_TEMP_TEMPLATE: gst_queue2_set_temp_template (queue, g_value_get_string (value)); break; - case PROP_TEMP_LOCATION: - g_free (queue->temp_location); - queue->temp_location = g_value_dup_string (value); - /* you can set the property back to NULL to make it use the temp-template - * property. */ - queue->temp_location_set = queue->temp_location != NULL; - break; case PROP_TEMP_REMOVE: queue->temp_remove = g_value_get_boolean (value); break; diff --git a/plugins/elements/gstqueue2.h b/plugins/elements/gstqueue2.h index 25beef4..b69f46b 100644 --- a/plugins/elements/gstqueue2.h +++ b/plugins/elements/gstqueue2.h @@ -156,7 +156,7 @@ struct _GstQueue2Class GstElementClass parent_class; }; -GType gst_queue2_get_type (void); +G_GNUC_INTERNAL GType gst_queue2_get_type (void); G_END_DECLS diff --git a/plugins/elements/gstqueuearray.c b/plugins/elements/gstqueuearray.c new file mode 100644 index 0000000..f16f7ae --- /dev/null +++ b/plugins/elements/gstqueuearray.c @@ -0,0 +1,175 @@ +/* GStreamer + * Copyright (C) 2009 Edward Hervey <bilboed@bilboed.com> + * + * gstqueuearray.c: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <string.h> +#include <gst/gst.h> +#include "gstqueuearray.h" + +void +gst_queue_array_init (GstQueueArray * array, guint initial_size) +{ + array->size = initial_size; + array->array = g_new0 (gpointer, initial_size); + array->head = 0; + array->tail = 0; + array->length = 0; + +} + +GstQueueArray * +gst_queue_array_new (guint initial_size) +{ + GstQueueArray *array; + + array = g_new (GstQueueArray, 1); + gst_queue_array_init (array, initial_size); + return array; +} + +gpointer +gst_queue_array_pop_head (GstQueueArray * array) +{ + gpointer ret; + + /* empty array */ + if (G_UNLIKELY (array->length == 0)) + return NULL; + ret = array->array[array->head]; + array->head++; + array->head %= array->size; + array->length--; + return ret; +} + +void +gst_queue_array_push_tail (GstQueueArray * array, gpointer data) +{ + /* Check if we need to make room */ + if (G_UNLIKELY (array->length == array->size)) { + /* newsize is 50% bigger */ + guint newsize = (3 * array->size) / 2; + + /* copy over data */ + if (array->tail != 0) { + gpointer *array2 = g_new0 (gpointer, newsize); + guint t1 = array->head; + guint t2 = array->size - array->head; + + /* [0-----TAIL][HEAD------SIZE] + * + * We want to end up with + * [HEAD------------------TAIL][----FREEDATA------NEWSIZE] + * + * 1) move [HEAD-----SIZE] part to beginning of new array + * 2) move [0-------TAIL] part new array, after previous part + */ + + memcpy (array2, &array->array[array->head], t2 * sizeof (gpointer)); + memcpy (&array2[t2], array->array, t1 * sizeof (gpointer)); + + g_free (array->array); + array->array = array2; + array->head = 0; + } else { + /* Fast path, we just need to grow the array */ + array->array = g_renew (gpointer, array->array, newsize); + } + array->tail = array->size; + array->size = newsize; + } + + array->array[array->tail] = data; + array->tail++; + array->tail %= array->size; + array->length++; +} + +gboolean +gst_queue_array_is_empty (GstQueueArray * array) +{ + return (array->length == 0); +} + +void +gst_queue_array_clear (GstQueueArray * array) +{ + g_free (array->array); +} + +void +gst_queue_array_free (GstQueueArray * array) +{ + gst_queue_array_clear (array); + g_free (array); +} + +void +gst_queue_array_drop_element (GstQueueArray * array, guint idx) +{ + if (idx == array->head) { + /* just move the head */ + array->head++; + array->head %= array->size; + return; + } + if (idx == array->tail - 1) { + /* just move the tail */ + array->tail = (array->tail - 1 + array->size) % array->size; + return; + } + /* drop the element #idx... and readjust the array */ + if (array->head < array->tail) { + /* Make sure it's within the boundaries */ + g_assert (array->head < idx && idx <= array->tail); + /* ends not wrapped */ + /* move head-idx to head+1 */ + memcpy (&array->array[array->head + 1], + &array->array[array->head], (idx - array->head) * sizeof (gpointer)); + array->tail--; + } else { + /* ends are wrapped */ + if (idx < array->tail) { + /* move idx-tail backwards one */ + memcpy (&array->array[idx - 1], + &array->array[idx], (array->tail - idx) * sizeof (gpointer)); + array->tail--; + } else if (idx >= array->head) { + /* move head-idx forwards one */ + memcpy (&array->array[array->head], + &array->array[array->head + 1], + (idx - array->head) * sizeof (gpointer)); + array->head++; + } else + g_assert_not_reached (); + } +} + +guint +gst_queue_array_find (GstQueueArray * array, GCompareFunc func, gpointer data) +{ + guint i; + + /* Scan from head to tail */ + for (i = array->head; i < array->length; i = (i + 1) % array->size) + if (func (array->array[i], data) == 0) + return i; + return -1; +} diff --git a/plugins/elements/gstqueuearray.h b/plugins/elements/gstqueuearray.h new file mode 100644 index 0000000..510cbf4 --- /dev/null +++ b/plugins/elements/gstqueuearray.h @@ -0,0 +1,61 @@ +/* GStreamer + * Copyright (C) 2009-2010 Edward Hervey <bilboed@bilboed.com> + * + * gstqueuearray.h: + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <glib.h> + +#ifndef __GST_QUEUE_ARRAY_H__ +#define __GST_QUEUE_ARRAY_H__ + +typedef struct _GstQueueArray GstQueueArray; + +struct _GstQueueArray +{ + gpointer *array; + guint size; + guint head; + guint tail; + guint length; +}; + +G_GNUC_INTERNAL void gst_queue_array_init (GstQueueArray * array, + guint initial_size); + +G_GNUC_INTERNAL void gst_queue_array_clear (GstQueueArray * array); + +G_GNUC_INTERNAL GstQueueArray * gst_queue_array_new (guint initial_size); + +G_GNUC_INTERNAL gpointer gst_queue_array_pop_head (GstQueueArray * array); + +G_GNUC_INTERNAL void gst_queue_array_push_tail (GstQueueArray * array, + gpointer data); + +G_GNUC_INTERNAL gboolean gst_queue_array_is_empty (GstQueueArray * array); + +G_GNUC_INTERNAL void gst_queue_array_free (GstQueueArray * array); + +G_GNUC_INTERNAL void gst_queue_array_drop_element (GstQueueArray * array, + guint idx); + +G_GNUC_INTERNAL guint gst_queue_array_find (GstQueueArray * array, + GCompareFunc func, + gpointer data); + +#endif diff --git a/plugins/elements/gsttee.c b/plugins/elements/gsttee.c index 33f2d8d..3c7f019 100644 --- a/plugins/elements/gsttee.c +++ b/plugins/elements/gsttee.c @@ -83,7 +83,6 @@ gst_tee_pull_mode_get_type (void) #define GST_TEE_DYN_UNLOCK(tee) g_mutex_unlock (&(tee)->dyn_lock) #define DEFAULT_PROP_NUM_SRC_PADS 0 -#define DEFAULT_PROP_HAS_SINK_LOOP FALSE #define DEFAULT_PROP_HAS_CHAIN TRUE #define DEFAULT_PROP_SILENT TRUE #define DEFAULT_PROP_LAST_MESSAGE NULL @@ -93,7 +92,6 @@ enum { PROP_0, PROP_NUM_SRC_PADS, - PROP_HAS_SINK_LOOP, PROP_HAS_CHAIN, PROP_SILENT, PROP_LAST_MESSAGE, @@ -245,11 +243,6 @@ gst_tee_class_init (GstTeeClass * klass) g_param_spec_int ("num-src-pads", "Num Src Pads", "The number of source pads", 0, G_MAXINT, DEFAULT_PROP_NUM_SRC_PADS, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_HAS_SINK_LOOP, - g_param_spec_boolean ("has-sink-loop", "Has Sink Loop", - "If the element should spawn a thread (unimplemented and deprecated)", - DEFAULT_PROP_HAS_SINK_LOOP, - G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_HAS_CHAIN, g_param_spec_boolean ("has-chain", "Has Chain", "If the element can operate in push mode", DEFAULT_PROP_HAS_CHAIN, @@ -443,12 +436,6 @@ gst_tee_set_property (GObject * object, guint prop_id, const GValue * value, GST_OBJECT_LOCK (tee); switch (prop_id) { - case PROP_HAS_SINK_LOOP: - tee->has_sink_loop = g_value_get_boolean (value); - if (tee->has_sink_loop) { - g_warning ("tee will never implement has-sink-loop==TRUE"); - } - break; case PROP_HAS_CHAIN: tee->has_chain = g_value_get_boolean (value); break; @@ -488,9 +475,6 @@ gst_tee_get_property (GObject * object, guint prop_id, GValue * value, case PROP_NUM_SRC_PADS: g_value_set_int (value, GST_ELEMENT (tee)->numsrcpads); break; - case PROP_HAS_SINK_LOOP: - g_value_set_boolean (value, tee->has_sink_loop); - break; case PROP_HAS_CHAIN: g_value_set_boolean (value, tee->has_chain); break; diff --git a/plugins/elements/gsttee.h b/plugins/elements/gsttee.h index 5d6cc51..5d00947 100644 --- a/plugins/elements/gsttee.h +++ b/plugins/elements/gsttee.h @@ -74,7 +74,6 @@ struct _GstTee { guint pad_counter; gboolean has_chain; - gboolean has_sink_loop; gboolean silent; gchar *last_message; @@ -87,7 +86,7 @@ struct _GstTeeClass { GstElementClass parent_class; }; -GType gst_tee_get_type (void); +G_GNUC_INTERNAL GType gst_tee_get_type (void); G_END_DECLS diff --git a/plugins/elements/gsttypefindelement.c b/plugins/elements/gsttypefindelement.c index e6c4de2..d299026 100644 --- a/plugins/elements/gsttypefindelement.c +++ b/plugins/elements/gsttypefindelement.c @@ -39,7 +39,7 @@ * 1) get a list of all typefind functions sorted best to worst * 2) if all elements have been called with all requested data goto 8 * 3) call all functions once with all available data - * 4) if a function returns a value >= PROP_MAXIMUM goto 8 + * 4) if a function returns a value >= PROP_MAXIMUM goto 8 (never implemented)) * 5) all functions with a result > PROP_MINIMUM or functions that did not get * all requested data (where peek returned NULL) stay in list * 6) seek to requested offset of best function that still has open data @@ -111,7 +111,6 @@ enum PROP_0, PROP_CAPS, PROP_MINIMUM, - PROP_MAXIMUM, PROP_FORCE_CAPS, PROP_LAST }; @@ -188,7 +187,7 @@ gst_type_find_element_have_type (GstTypeFindElement * typefind, typefind->caps = gst_caps_ref (caps); GST_OBJECT_UNLOCK (typefind); - gst_pad_push_event (typefind->src, gst_event_new_caps (caps)); + gst_pad_set_caps (typefind->src, caps); } static void @@ -210,11 +209,6 @@ gst_type_find_element_class_init (GstTypeFindElementClass * typefind_class) "minimum probability required to accept caps", GST_TYPE_FIND_MINIMUM, GST_TYPE_FIND_MAXIMUM, GST_TYPE_FIND_MINIMUM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (gobject_class, PROP_MAXIMUM, - g_param_spec_uint ("maximum", _("maximum"), - "probability to stop typefinding (deprecated; non-functional)", - GST_TYPE_FIND_MINIMUM, GST_TYPE_FIND_MAXIMUM, GST_TYPE_FIND_MAXIMUM, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_FORCE_CAPS, g_param_spec_boxed ("force-caps", _("force caps"), _("force caps without doing a typefind"), GST_TYPE_CAPS, @@ -288,7 +282,6 @@ gst_type_find_element_init (GstTypeFindElement * typefind) typefind->mode = MODE_TYPEFIND; typefind->caps = NULL; typefind->min_probability = 1; - typefind->max_probability = GST_TYPE_FIND_MAXIMUM; typefind->adapter = gst_adapter_new (); } @@ -323,9 +316,6 @@ gst_type_find_element_set_property (GObject * object, guint prop_id, case PROP_MINIMUM: typefind->min_probability = g_value_get_uint (value); break; - case PROP_MAXIMUM: - typefind->max_probability = g_value_get_uint (value); - break; case PROP_FORCE_CAPS: GST_OBJECT_LOCK (typefind); if (typefind->force_caps) @@ -356,9 +346,6 @@ gst_type_find_element_get_property (GObject * object, guint prop_id, case PROP_MINIMUM: g_value_set_uint (value, typefind->min_probability); break; - case PROP_MAXIMUM: - g_value_set_uint (value, typefind->max_probability); - break; case PROP_FORCE_CAPS: GST_OBJECT_LOCK (typefind); g_value_set_boxed (value, typefind->force_caps); @@ -436,14 +423,14 @@ static gboolean gst_type_find_element_seek (GstTypeFindElement * typefind, GstEvent * event) { GstSeekFlags flags; - GstSeekType cur_type, stop_type; + GstSeekType start_type, stop_type; GstFormat format; gboolean flush; gdouble rate; - gint64 cur, stop; + gint64 start, stop; GstSegment seeksegment = { 0, }; - gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur, + gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start, &stop_type, &stop); /* we can only seek on bytes */ @@ -458,7 +445,7 @@ gst_type_find_element_seek (GstTypeFindElement * typefind, GstEvent * event) GST_DEBUG_OBJECT (typefind, "configuring seek"); gst_segment_do_seek (&seeksegment, rate, format, flags, - cur_type, cur, stop_type, stop, NULL); + start_type, start, stop_type, stop, NULL); flush = ! !(flags & GST_SEEK_FLAG_FLUSH); @@ -491,7 +478,7 @@ gst_type_find_element_seek (GstTypeFindElement * typefind, GstEvent * event) typefind->offset = typefind->segment.start; /* notify start of new segment */ - if (typefind->segment.flags & GST_SEEK_FLAG_SEGMENT) { + if (typefind->segment.flags & GST_SEGMENT_FLAG_SEGMENT) { GstMessage *msg; msg = gst_message_new_segment_start (GST_OBJECT (typefind), @@ -504,7 +491,7 @@ gst_type_find_element_seek (GstTypeFindElement * typefind, GstEvent * event) /* restart our task since it might have been stopped when we did the * flush. */ gst_pad_start_task (typefind->sink, - (GstTaskFunction) gst_type_find_element_loop, typefind->sink); + (GstTaskFunction) gst_type_find_element_loop, typefind->sink, NULL); /* streaming can continue now */ GST_PAD_STREAM_UNLOCK (typefind->sink); @@ -877,7 +864,7 @@ gst_type_find_element_chain_do_typefinding (GstTypeFindElement * typefind, have_min = avail >= TYPE_FIND_MIN_SIZE; have_max = avail >= TYPE_FIND_MAX_SIZE; } else { - have_min = TRUE; + have_min = avail > 0; have_max = TRUE; } @@ -979,12 +966,12 @@ gst_type_find_element_activate_src_mode (GstPad * pad, GstObject * parent, * activation might happen from the streaming thread. */ gst_pad_pause_task (typefind->sink); res = gst_pad_activate_mode (typefind->sink, mode, active); - if (typefind->caps) { + if (active && res && typefind->caps) { GstCaps *caps; GST_OBJECT_LOCK (typefind); caps = gst_caps_ref (typefind->caps); GST_OBJECT_UNLOCK (typefind); - gst_pad_push_event (typefind->src, gst_event_new_caps (caps)); + res = gst_pad_set_caps (typefind->src, caps); gst_caps_unref (caps); } break; @@ -1103,7 +1090,7 @@ pause: if (ret == GST_FLOW_EOS) { /* perform EOS logic */ - if (typefind->segment.flags & GST_SEEK_FLAG_SEGMENT) { + if (typefind->segment.flags & GST_SEGMENT_FLAG_SEGMENT) { gint64 stop; /* for segment playback we need to post when (in stream time) @@ -1115,6 +1102,8 @@ pause: gst_element_post_message (GST_ELEMENT (typefind), gst_message_new_segment_done (GST_OBJECT (typefind), GST_FORMAT_BYTES, stop)); + gst_pad_push_event (typefind->src, + gst_event_new_segment_done (GST_FORMAT_BYTES, stop)); } else { push_eos = TRUE; } @@ -1218,7 +1207,7 @@ gst_type_find_element_activate_sink (GstPad * pad, GstObject * parent) /* only start our task if we ourselves decide to start in pull mode */ return gst_pad_start_task (pad, (GstTaskFunction) gst_type_find_element_loop, - pad); + pad, NULL); typefind_push: { diff --git a/plugins/elements/gsttypefindelement.h b/plugins/elements/gsttypefindelement.h index 0242ec2..2ee3325 100644 --- a/plugins/elements/gsttypefindelement.h +++ b/plugins/elements/gsttypefindelement.h @@ -51,7 +51,6 @@ struct _GstTypeFindElement { GstPad * src; guint min_probability; - guint max_probability; GstCaps * caps; guint mode; @@ -75,7 +74,7 @@ struct _GstTypeFindElementClass { GstCaps *caps); }; -GType gst_type_find_element_get_type (void); +G_GNUC_INTERNAL GType gst_type_find_element_get_type (void); G_END_DECLS diff --git a/plugins/elements/gstvalve.c b/plugins/elements/gstvalve.c index a69b785..c5fb151 100644 --- a/plugins/elements/gstvalve.c +++ b/plugins/elements/gstvalve.c @@ -34,8 +34,6 @@ * gst-plugins-bad. * * Documentation last reviewed on 2010-12-30 (0.10.31) - * - * Since: 0.10.32 */ #ifdef HAVE_CONFIG_H diff --git a/plugins/elements/gstvalve.h b/plugins/elements/gstvalve.h index 7318af7..c12c7c7 100644 --- a/plugins/elements/gstvalve.h +++ b/plugins/elements/gstvalve.h @@ -48,8 +48,6 @@ typedef struct _GstValveClass GstValveClass; * GstValve: * * The private valve structure - * - * Since: 0.10.32 */ struct _GstValve { @@ -72,7 +70,7 @@ struct _GstValveClass GstElementClass parent_class; }; -GType gst_valve_get_type (void); +G_GNUC_INTERNAL GType gst_valve_get_type (void); G_END_DECLS |