docs/libs/gstreamer-libs-sections.txt: Added basesink new methods.

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.
This commit is contained in:
Wim Taymans 2006-03-07 16:21:02 +00:00
parent c45bd3fb9f
commit 7a88e2a762
8 changed files with 182 additions and 32 deletions

View file

@ -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:

View 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

View file

@ -615,18 +615,29 @@ 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
* @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.
*/
GstEvent *

View 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,

View 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
@ -76,11 +79,14 @@
* 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>

View 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
@ -106,7 +106,16 @@
* 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
&& jitter > basesink->abidata.ABI.max_lateness) {
/* 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) {
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;

View 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__ */

View file

@ -135,7 +135,6 @@
* ...
* // 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>
@ -146,13 +145,12 @@
* ...
* // 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>
*/