docs/libs/gstreamer-libs-sections.txt: Added basesink new methods.
authorWim Taymans <wim.taymans@gmail.com>
Tue, 7 Mar 2006 16:21:02 +0000 (16:21 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Tue, 7 Mar 2006 16:21:02 +0000 (16:21 +0000)
Original commit message from CVS:
* docs/libs/gstreamer-libs-sections.txt:
Added basesink new methods.
* gst/gstevent.c:
* gst/gstevent.h:
Docs updates. Flesh out the QoS docs.
* libs/gst/base/gstadapter.c:
Small doc clarification about ownership and flushing.
* libs/gst/base/gstbasesink.c: (gst_base_sink_set_sync),
(gst_base_sink_get_sync), (gst_base_sink_set_max_lateness),
(gst_base_sink_get_max_lateness), (gst_base_sink_set_property),
(gst_base_sink_get_property), (gst_base_sink_do_sync):
* libs/gst/base/gstbasesink.h:
Added new methods to allow subclass to control max-lateness
and sync.
Generate very basic QoS events based on last sync observation.
Updated docs, fix typo, added some QoS blurb.
* libs/gst/base/gstbasesrc.c:
Remove obsolete _get_state() calls from docs.

ChangeLog
docs/libs/gstreamer-libs-sections.txt
gst/gstevent.c
gst/gstevent.h
libs/gst/base/gstadapter.c
libs/gst/base/gstbasesink.c
libs/gst/base/gstbasesink.h
libs/gst/base/gstbasesrc.c

index f6ca69c1ff00e5a6022c9ee7b989ad3f656e4435..adbb12d675383a9da0129067556fc61c6880e28e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2006-03-07  Wim Taymans  <wim@fluendo.com>
+
+       * docs/libs/gstreamer-libs-sections.txt:
+       Added basesink new methods.
+
+       * gst/gstevent.c:
+       * gst/gstevent.h:
+       Docs updates. Flesh out the QoS docs.
+
+       * libs/gst/base/gstadapter.c:
+       Small doc clarification about ownership and flushing.
+
+       * libs/gst/base/gstbasesink.c: (gst_base_sink_set_sync),
+       (gst_base_sink_get_sync), (gst_base_sink_set_max_lateness),
+       (gst_base_sink_get_max_lateness), (gst_base_sink_set_property),
+       (gst_base_sink_get_property), (gst_base_sink_do_sync):
+       * libs/gst/base/gstbasesink.h:
+       Added new methods to allow subclass to control max-lateness 
+       and sync.
+       Generate very basic QoS events based on last sync observation.
+       Updated docs, fix typo, added some QoS blurb.
+
+       * libs/gst/base/gstbasesrc.c:
+       Remove obsolete _get_state() calls from docs.
+
 2006-03-07  Wim Taymans  <wim@fluendo.com>
 
        * docs/libs/gstreamer-libs-sections.txt:
index 0403cc8328ba6979795a654a804226e7dc4b6d86..4aa68b61554bcddd5854e1e38169b06cdf3f8e40 100644 (file)
@@ -159,6 +159,11 @@ GstBaseSink
 
 GST_BASE_SINK_PAD
 
+gst_base_sink_set_sync
+gst_base_sink_get_sync
+gst_base_sink_set_max_lateness
+gst_base_sink_get_max_lateness
+
 <SUBSECTION Standard>
 GstBaseSinkClass
 GST_BASE_SINK
index 0db8cee8894d09c2b9c113d88693a216a402692d..1df83f886fd219fca05727d70c21e74eaaa49923 100644 (file)
@@ -615,17 +615,28 @@ gst_event_parse_buffer_size (GstEvent * event, GstFormat * format,
  * Allocate a new qos event with the given values.
  * The QOS event is generated in an element that wants an upstream
  * element to either reduce or increase its rate because of
- * high/low CPU load.
+ * high/low CPU load or other resource usage such as network performance.
  *
- * proportion is the requested adjustment in datarate, 1.0 is the normal
+ * @proportion is the requested adjustment in datarate, 1.0 is the normal
  * datarate, 0.75 means increase datarate by 75%, 1.5 is 150%. Negative
  * values request a slow down, so -0.75 means a decrease by 75%.
  *
- * diff is the difference against the clock in stream time of the last
+ * @diff is the difference against the clock in stream time of the last
  * buffer that caused the element to generate the QOS event.
  *
- * timestamp is the timestamp of the last buffer that cause the element
- * to generate the QOS event.
+ * @timestamp is the timestamp of the last buffer that cause the element
+ * to generate the QOS event. 
+ *
+ * The upstream element can use the @diff and @timestamp values to decide
+ * whether to process more buffers. All buffers with timestamp <=
+ * @timestamp + @diff will certainly arrive late in the sink as well. 
+ *
+ * The @proportion value is generally computed based on more long
+ * term statistics about the stream quality and can be used in various ways
+ * such as lowering or increasing processing quality.
+ *
+ * The application can use general event probes to intercept the QoS
+ * event and implement custom application specific QoS handling.
  *
  * Returns: A new QOS event.
  */
index 0ec1d83d790a1c0409901b44f806c496809cae85..e12ab3367559c30de83115e0243977adddf7c2c9 100644 (file)
@@ -378,7 +378,6 @@ void                gst_event_parse_buffer_size     (GstEvent *event, GstFormat *format, gint64 *
                                                 gint64 *maxsize, gboolean *async);
 
 /* QOS events */
-/* FIXME: QOS events need to be fully specified and implemented */
 GstEvent*      gst_event_new_qos               (gdouble proportion, GstClockTimeDiff diff,
                                                 GstClockTime timestamp);
 void           gst_event_parse_qos             (GstEvent *event, gdouble *proportion, GstClockTimeDiff *diff,
index 6cd6cfef236291b0263cc05bd208d2db89713524..62cecf3cc05fa581ff706236373b5798da4c8fe6 100644 (file)
@@ -67,6 +67,9 @@
  * gst_adapter_clear(). Data should also be cleared or processed on EOS and
  * when changing state from #GST_STATE_PAUSED to #GST_STATE_READY.
  *
+ * Also check the GST_BUFFER_FLAG_DISCONT flag on the buffer. Some elements might
+ * need to clear the adapter after a discontinuity.
+ *
  * A last thing to note is that while GstAdapter is pretty optimized,
  * merging buffers still might be an operation that requires a memcpy()
  * operation, and this operation is not the fastest. Because of this, some
  * GstAdapter is not MT safe. All operations on an adapter must be serialized by
  * the caller. This is not normally a problem, however, as the normal use case
  * of GstAdapter is inside one pad's chain function, in which case access is
- * serialized via the pad's stream lock.
+ * serialized via the pad's STREAM_LOCK.
  *
- * Note that gst_adapter_push() takes ownership of the buffer passed.
+ * Note that gst_adapter_push() takes ownership of the buffer passed. Use 
+ * gst_buffer_ref() before pushing it into the adapter if you still want to
+ * access the buffer later. The adapter will never modify the data in the
+ * buffer pushed in it.
  *
- * Last reviewed on 2005-12-18 (0.10.0).
+ * Last reviewed on 2006-03-07 (0.10.4).
  */
 
 #include <string.h>
index 92127f043b27285311e8f0bc3ea526558c80ae30..8d1db0833b93357714c5f9eb955dbcae8c0a789b 100644 (file)
@@ -30,7 +30,7 @@
  * you, for example preroll, clock synchronization, state changes, activation in
  * push or pull mode, and queries. In most cases, when writing sink elements,
  * there is no need to implement class methods from #GstElement or to set
- * functions on pads, because the #GstBaseSink infrastructure is sufficient.
+ * functions on pads, because the #GstBaseSink infrastructure should be sufficient.
  *
  * There is only support in GstBaseSink for one sink pad, which should be named
  * "sink". A sink implementation (subclass of GstBaseSink) should install a pad
@@ -53,8 +53,8 @@
  * #GstBaseSink will handle the prerolling correctly. This means that it will
  * return GST_STATE_CHANGE_ASYNC from a state change to PAUSED until the first buffer
  * arrives in this element. The base class will call the GstBaseSink::preroll
- * vmethod with this preroll buffer and will then commit the state change to
- * PAUSED. 
+ * vmethod with this preroll buffer and will then commit the state change to the
+ * next asynchronously pending state.
  *
  * When the element is set to PLAYING, #GstBaseSink will synchronize on the clock
  * using the times returned from ::get_times. If this function returns
@@ -88,7 +88,7 @@
  * query will be forwarded upstream.
  *
  * The ::set_caps function will be called when the subclass should configure itself
- * to precess a specific media type.
+ * to process a specific media type.
  * 
  * The ::start and ::stop virtual methods will be called when resources should be
  * allocated. Any ::preroll, ::render  and ::set_caps function will be called
  * operations they perform in the ::render method. This is mostly usefull when
  * the ::render method performs a blocking write on a file descripter.
  *
- * Last reviewed on 2006-01-30 (0.10.3)
+ * The max-lateness property defines how the sink deals with buffers that arrive 
+ * too late in the sink. A buffer arrives too late in the sink when the presentation
+ * time (as a combination of the last segment, buffer timestamp and element
+ * base_time) is before the current time of the clock. If the frame is later than
+ * max-lateness, the sink will drop the buffer and will generate a QoS event upstream.
+ * This feature is disabled if sync is disabled, the ::get-times method does not
+ * return a valid start time or max-lateness is set to -1 (the default). 
+ * Subclasses can use gst_base_sink_set_max_lateness() to configure the max-lateness.
+ *
+ * Last reviewed on 2006-03-07 (0.10.4)
  */
 
 #ifdef HAVE_CONFIG_H
@@ -375,6 +384,95 @@ gst_base_sink_finalize (GObject * object)
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
+/**
+ * gst_base_sink_set_sync:
+ * @sink: the sink
+ * @sync: the new sync value.
+ *
+ * Configures @sink to synchronize on the clock or not. When
+ * @sync is FALSE, incomming samples will be played as fast as
+ * possible. If @sync is TRUE, the timestamps of the incomming
+ * buffers will be used to schedule the exact render time of its
+ * contents.
+ *
+ * Since: 0.10.4
+ */
+void
+gst_base_sink_set_sync (GstBaseSink * sink, gboolean sync)
+{
+  GST_OBJECT_LOCK (sink);
+  sink->sync = sync;
+  GST_OBJECT_UNLOCK (sink);
+}
+
+/**
+ * gst_base_sink_get_sync:
+ * @sink: the sink
+ *
+ * Checks if @sink is currently configured to synchronize against the
+ * clock.
+ *
+ * Returns: TRUE if the sink is configured to synchronize against the clock.
+ *
+ * Since: 0.10.4
+ */
+gboolean
+gst_base_sink_get_sync (GstBaseSink * sink)
+{
+  gboolean res;
+
+  GST_OBJECT_LOCK (sink);
+  res = sink->sync;
+  GST_OBJECT_UNLOCK (sink);
+
+  return res;
+}
+
+/**
+ * gst_base_sink_set_max_lateness:
+ * @sink: the sink
+ * @max_lateness: the new max lateness value.
+ *
+ * Sets the new max lateness value to @max_lateness. This value is
+ * used to decide if a buffer should be dropped or not based on the
+ * buffer timestamp and the current clock time. A value of -1 means
+ * an unlimited time.
+ *
+ * Since: 0.10.4
+ */
+void
+gst_base_sink_set_max_lateness (GstBaseSink * sink, gint64 max_lateness)
+{
+  GST_OBJECT_LOCK (sink);
+  sink->abidata.ABI.max_lateness = max_lateness;
+  GST_OBJECT_UNLOCK (sink);
+}
+
+/**
+ * gst_base_sink_get_max_lateness:
+ * @sink: the sink
+ *
+ * Gets the max lateness value. See gst_base_sink_set_max_lateness for
+ * more details.
+ *
+ * Returns: The maximum time in nanoseconds that a buffer can be late
+ * before it is dropped and not rendered. A value of -1 means an
+ * unlimited time.
+ *
+ * Since: 0.10.4
+ */
+gint64
+gst_base_sink_get_max_lateness (GstBaseSink * sink)
+{
+  gint64 res;
+
+  GST_OBJECT_LOCK (sink);
+  res = sink->abidata.ABI.max_lateness;
+  GST_OBJECT_UNLOCK (sink);
+
+  return res;
+}
+
 static void
 gst_base_sink_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
@@ -389,14 +487,10 @@ gst_base_sink_set_property (GObject * object, guint prop_id,
       GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
       break;
     case PROP_SYNC:
-      GST_OBJECT_LOCK (sink);
-      sink->sync = g_value_get_boolean (value);
-      GST_OBJECT_UNLOCK (sink);
+      gst_base_sink_set_sync (sink, g_value_get_boolean (value));
       break;
     case PROP_MAX_LATENESS:
-      GST_OBJECT_LOCK (sink);
-      sink->abidata.ABI.max_lateness = g_value_get_int64 (value);
-      GST_OBJECT_UNLOCK (sink);
+      gst_base_sink_set_max_lateness (sink, g_value_get_int64 (value));
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -417,14 +511,10 @@ gst_base_sink_get_property (GObject * object, guint prop_id, GValue * value,
       GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
       break;
     case PROP_SYNC:
-      GST_OBJECT_LOCK (sink);
-      g_value_set_boolean (value, sink->sync);
-      GST_OBJECT_UNLOCK (sink);
+      g_value_set_boolean (value, gst_base_sink_get_sync (sink));
       break;
     case PROP_MAX_LATENESS:
-      GST_OBJECT_LOCK (sink);
-      g_value_set_int64 (value, sink->abidata.ABI.max_lateness);
-      GST_OBJECT_UNLOCK (sink);
+      g_value_set_int64 (value, gst_base_sink_get_max_lateness (sink));
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -432,6 +522,7 @@ gst_base_sink_get_property (GObject * object, guint prop_id, GValue * value,
   }
 }
 
+
 static GstCaps *
 gst_base_sink_get_caps (GstBaseSink * sink)
 {
@@ -838,14 +929,23 @@ again:
 
   *late = FALSE;
 
-  if (basesink->abidata.ABI.max_lateness != -1) {
-    if (status == GST_CLOCK_EARLY
+  /* FIXME, update clock stats here and do some QoS */
+  if (status == GST_CLOCK_EARLY) {
+    if (basesink->abidata.ABI.max_lateness != -1
         && jitter > basesink->abidata.ABI.max_lateness) {
-      /* FIXME, update clock stats here and do some QoS */
+      GstEvent *event;
+
       GST_DEBUG_OBJECT (basesink, "late: jitter!! %" G_GINT64_FORMAT "\n",
           jitter);
       *late = TRUE;
+
+      /* generate QoS event, FIXME, calculate decent proportion. */
+      event = gst_event_new_qos (-1.0, jitter, start);
+
+      /* send upstream */
+      gst_pad_push_event (basesink->sinkpad, event);
     }
+  } else {
   }
 
   return GST_FLOW_OK;
index 7945d39d2c8d682d8005bb79fcf835c391039d1e..6bc093b95c7fb350366e185ff98f719835b0c115 100644 (file)
@@ -136,6 +136,12 @@ struct _GstBaseSinkClass {
 
 GType gst_base_sink_get_type(void);
 
+void           gst_base_sink_set_sync          (GstBaseSink *sink, gboolean sync);
+gboolean       gst_base_sink_get_sync          (GstBaseSink *sink);
+
+void           gst_base_sink_set_max_lateness  (GstBaseSink *sink, gint64 max_lateness);
+gint64         gst_base_sink_get_max_lateness  (GstBaseSink *sink);
+
 G_END_DECLS
 
 #endif /* __GST_BASE_SINK_H__ */
index 2302792e1b7093b9fc1f84093bbb1311fbe4fbca..e20f308a0e8c314f11663c3d01f4675025452e41 100644 (file)
  * ...
  * // stop recording
  * gst_element_set_state (audio_source, GST_STATE_NULL);
- * gst_element_get_state (audio_source, NULL, NULL, -1);
  * gst_element_set_locked_state (audio_source, TRUE);
  * ...
  * </programlisting>
  * ...
  * // everything done - shut down pipeline
  * gst_element_set_state (pipeline, GST_STATE_NULL);
- * gst_element_get_state (pipeline, NULL, NULL, -1);
  * gst_element_set_locked_state (audio_source, FALSE);
  * ...
  * </programlisting>
  * </para>
  * <para>
- * Last reviewed on 2005-12-18 (0.10.0)
+ * Last reviewed on 2006-03-07 (0.10.4)
  * </para>
  * </refsect2>
  */