mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-25 16:48:11 +00:00
libs/gst/base/gstbasesink.c: More QoS measurements as described in the design doc.
Original commit message from CVS: * libs/gst/base/gstbasesink.c: (gst_base_sink_init), (gst_base_sink_finalize), (gst_base_sink_set_qos_enabled), (gst_base_sink_is_qos_enabled), (gst_base_sink_do_sync), (gst_base_sink_record_qos_observation), (gst_base_sink_perform_qos), (gst_base_sink_reset_qos), (gst_base_sink_is_too_late), (gst_base_sink_render_object), (gst_base_sink_change_state): More QoS measurements as described in the design doc. Get rid of ringbuffer with observations, running average is more simple and equally good. Calculates valid proportion now. Added beginning of flood measurement.
This commit is contained in:
parent
9c9290f52f
commit
0a4ba6610f
2 changed files with 191 additions and 72 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
||||||
|
2006-03-30 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* libs/gst/base/gstbasesink.c: (gst_base_sink_init),
|
||||||
|
(gst_base_sink_finalize), (gst_base_sink_set_qos_enabled),
|
||||||
|
(gst_base_sink_is_qos_enabled), (gst_base_sink_do_sync),
|
||||||
|
(gst_base_sink_record_qos_observation),
|
||||||
|
(gst_base_sink_perform_qos), (gst_base_sink_reset_qos),
|
||||||
|
(gst_base_sink_is_too_late), (gst_base_sink_render_object),
|
||||||
|
(gst_base_sink_change_state):
|
||||||
|
More QoS measurements as described in the design doc.
|
||||||
|
Get rid of ringbuffer with observations, running average is
|
||||||
|
more simple and equally good.
|
||||||
|
Calculates valid proportion now.
|
||||||
|
Added beginning of flood measurement.
|
||||||
|
|
||||||
2006-03-29 Wim Taymans <wim@fluendo.com>
|
2006-03-29 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* docs/design/part-qos.txt:
|
* docs/design/part-qos.txt:
|
||||||
|
|
|
@ -142,22 +142,39 @@ GST_DEBUG_CATEGORY_STATIC (gst_base_sink_debug);
|
||||||
*/
|
*/
|
||||||
struct _GstBaseSinkPrivate
|
struct _GstBaseSinkPrivate
|
||||||
{
|
{
|
||||||
gboolean qos_enabled;
|
gint qos_enabled; /* ATOMIC */
|
||||||
|
|
||||||
/* last position */
|
/* last position */
|
||||||
GstClockTime last_cstart;
|
GstClockTime last_cstart;
|
||||||
GstClockTime last_cstop;
|
GstClockTime last_cstop;
|
||||||
|
|
||||||
/* for the linear regression when doing QoS */
|
/* start, stop and jitter of current buffer, stream time */
|
||||||
gboolean filling;
|
GstClockTime current_start;
|
||||||
gint window_size;
|
GstClockTime current_stop;
|
||||||
gint window_threshold;
|
GstClockTimeDiff current_jitter;
|
||||||
gint time_index;
|
|
||||||
gint64 *times;
|
|
||||||
|
|
||||||
/* stats go here. */
|
/* last buffer that arrived in time, stream time */
|
||||||
|
GstClockTime last_in_time;
|
||||||
|
/* when the last buffer left the sink, stream time */
|
||||||
|
GstClockTime last_left;
|
||||||
|
|
||||||
|
/* running averages go here these are done on stream time */
|
||||||
|
GstClockTime avg_pt;
|
||||||
|
GstClockTime avg_duration;
|
||||||
|
gdouble avg_rate;
|
||||||
|
|
||||||
|
/* these are done on system time. avg_jitter and avg_render are
|
||||||
|
* compared to eachother to see if the rendering time takes a
|
||||||
|
* huge amount of the processing, If so we are flooded with
|
||||||
|
* buffers. */
|
||||||
|
GstClockTime last_left_systime;
|
||||||
|
GstClockTime avg_jitter;
|
||||||
|
GstClockTime avg_render;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define RUNNING_AVG_WINDOW 8
|
||||||
|
#define UPDATE_RUNNING_AVG(avg,val) ((val) + (RUNNING_AVG_WINDOW-1) * (avg)) / RUNNING_AVG_WINDOW
|
||||||
|
|
||||||
/* BaseSink signals and properties */
|
/* BaseSink signals and properties */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -175,10 +192,6 @@ enum
|
||||||
#define DEFAULT_MAX_LATENESS -1
|
#define DEFAULT_MAX_LATENESS -1
|
||||||
#define DEFAULT_QOS FALSE
|
#define DEFAULT_QOS FALSE
|
||||||
|
|
||||||
/* for QoS, no properties yet */
|
|
||||||
#define DEFAULT_WINDOW_SIZE 32
|
|
||||||
#define DEFAULT_WINDOW_THRESHOLD 4
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
|
@ -253,8 +266,8 @@ static gboolean gst_base_sink_is_too_late (GstBaseSink * basesink,
|
||||||
GstClockReturn status, GstClockTimeDiff jitter);
|
GstClockReturn status, GstClockTimeDiff jitter);
|
||||||
|
|
||||||
/* QoS */
|
/* QoS */
|
||||||
static void gst_base_sink_add_qos_observation (GstBaseSink * sink,
|
static void gst_base_sink_record_qos_observation (GstBaseSink * sink,
|
||||||
GstClockTime time, GstClockTimeDiff jitter);
|
GstClockTime start, GstClockTime stop, GstClockTimeDiff jitter);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_base_sink_base_init (gpointer g_class)
|
gst_base_sink_base_init (gpointer g_class)
|
||||||
|
@ -420,13 +433,7 @@ gst_base_sink_init (GstBaseSink * basesink, gpointer g_class)
|
||||||
|
|
||||||
basesink->sync = DEFAULT_SYNC;
|
basesink->sync = DEFAULT_SYNC;
|
||||||
basesink->abidata.ABI.max_lateness = DEFAULT_MAX_LATENESS;
|
basesink->abidata.ABI.max_lateness = DEFAULT_MAX_LATENESS;
|
||||||
priv->qos_enabled = DEFAULT_QOS;
|
gst_atomic_int_set (&priv->qos_enabled, DEFAULT_QOS);
|
||||||
|
|
||||||
priv->window_size = DEFAULT_WINDOW_SIZE;
|
|
||||||
priv->window_threshold = DEFAULT_WINDOW_THRESHOLD;
|
|
||||||
priv->filling = TRUE;
|
|
||||||
priv->time_index = 0;
|
|
||||||
priv->times = g_new0 (gint64, 4 * priv->window_size);
|
|
||||||
|
|
||||||
GST_OBJECT_FLAG_SET (basesink, GST_ELEMENT_IS_SINK);
|
GST_OBJECT_FLAG_SET (basesink, GST_ELEMENT_IS_SINK);
|
||||||
}
|
}
|
||||||
|
@ -440,7 +447,6 @@ gst_base_sink_finalize (GObject * object)
|
||||||
|
|
||||||
g_queue_free (basesink->preroll_queue);
|
g_queue_free (basesink->preroll_queue);
|
||||||
gst_segment_free (basesink->abidata.ABI.clip_segment);
|
gst_segment_free (basesink->abidata.ABI.clip_segment);
|
||||||
g_free (basesink->priv->times);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
@ -546,9 +552,7 @@ gst_base_sink_get_max_lateness (GstBaseSink * sink)
|
||||||
void
|
void
|
||||||
gst_base_sink_set_qos_enabled (GstBaseSink * sink, gboolean enabled)
|
gst_base_sink_set_qos_enabled (GstBaseSink * sink, gboolean enabled)
|
||||||
{
|
{
|
||||||
GST_OBJECT_LOCK (sink);
|
gst_atomic_int_set (&sink->priv->qos_enabled, enabled);
|
||||||
sink->priv->qos_enabled = enabled;
|
|
||||||
GST_OBJECT_UNLOCK (sink);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -567,9 +571,7 @@ gst_base_sink_is_qos_enabled (GstBaseSink * sink)
|
||||||
{
|
{
|
||||||
gboolean res;
|
gboolean res;
|
||||||
|
|
||||||
GST_OBJECT_LOCK (sink);
|
res = g_atomic_int_get (&sink->priv->qos_enabled);
|
||||||
res = sink->priv->qos_enabled;
|
|
||||||
GST_OBJECT_UNLOCK (sink);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -1032,6 +1034,8 @@ gst_base_sink_do_sync (GstBaseSink * basesink, GstPad * pad,
|
||||||
|
|
||||||
start = stop = cstart = cstop = -1;
|
start = stop = cstart = cstop = -1;
|
||||||
|
|
||||||
|
basesink->priv->current_start = -1;
|
||||||
|
|
||||||
/* update timing information for this object */
|
/* update timing information for this object */
|
||||||
syncable = gst_base_sink_get_sync_times (basesink, obj,
|
syncable = gst_base_sink_get_sync_times (basesink, obj,
|
||||||
&start, &stop, &cstart, &cstop, &do_sync);
|
&start, &stop, &cstart, &cstop, &do_sync);
|
||||||
|
@ -1109,8 +1113,8 @@ again:
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* successful syncing done, add observation */
|
/* successful syncing done, record observation */
|
||||||
gst_base_sink_add_qos_observation (basesink, cstart, jitter);
|
gst_base_sink_record_qos_observation (basesink, cstart, cstop, jitter);
|
||||||
|
|
||||||
/* check if the object should be dropped */
|
/* check if the object should be dropped */
|
||||||
*late = gst_base_sink_is_too_late (basesink, obj, start, stop,
|
*late = gst_base_sink_is_too_late (basesink, obj, start, stop,
|
||||||
|
@ -1137,27 +1141,26 @@ stopping:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add a qos observation to the ringbuffer of observations */
|
/* record a qos observation for later processing */
|
||||||
static void
|
static void
|
||||||
gst_base_sink_add_qos_observation (GstBaseSink * sink, GstClockTime time,
|
gst_base_sink_record_qos_observation (GstBaseSink * sink, GstClockTime start,
|
||||||
GstClockTimeDiff jitter)
|
GstClockTime stop, GstClockTimeDiff jitter)
|
||||||
{
|
{
|
||||||
GstBaseSinkPrivate *priv;
|
GstBaseSinkPrivate *priv;
|
||||||
gint index;
|
|
||||||
|
|
||||||
priv = sink->priv;
|
priv = sink->priv;
|
||||||
|
|
||||||
if (!priv->qos_enabled || time == -1)
|
if (!g_atomic_int_get (&priv->qos_enabled))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, sink,
|
GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, sink,
|
||||||
"adding QoS observation time: %" G_GUINT64_FORMAT ", jitter %"
|
"recording QoS observation start: %" GST_TIME_FORMAT ", stop %"
|
||||||
G_GINT64_FORMAT, time, jitter);
|
GST_TIME_FORMAT ", jitter %" G_GINT64_FORMAT,
|
||||||
|
GST_TIME_ARGS (start), GST_TIME_ARGS (stop), jitter);
|
||||||
|
|
||||||
index = priv->time_index << 2;
|
priv->current_start = start;
|
||||||
|
priv->current_stop = stop;
|
||||||
priv->times[index] = time;
|
priv->current_jitter = jitter;
|
||||||
priv->times[index + 2] = jitter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -1184,38 +1187,89 @@ static void
|
||||||
gst_base_sink_perform_qos (GstBaseSink * sink, gboolean dropped)
|
gst_base_sink_perform_qos (GstBaseSink * sink, gboolean dropped)
|
||||||
{
|
{
|
||||||
GstBaseSinkPrivate *priv;
|
GstBaseSinkPrivate *priv;
|
||||||
gdouble proportion;
|
GstClockTime start, stop;
|
||||||
|
GstClockTimeDiff jitter;
|
||||||
|
GstClockTime pt, entered, left;
|
||||||
|
GstClockTime duration;
|
||||||
|
gdouble rate;
|
||||||
|
|
||||||
priv = sink->priv;
|
priv = sink->priv;
|
||||||
|
|
||||||
|
start = priv->current_start;
|
||||||
|
|
||||||
/* if QoS disabled, do nothing */
|
/* if QoS disabled, do nothing */
|
||||||
if (!priv->qos_enabled)
|
if (!g_atomic_int_get (&priv->qos_enabled) || start == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* no proportion yet */
|
stop = priv->current_stop;
|
||||||
proportion = 0.0;
|
jitter = priv->current_jitter;
|
||||||
|
|
||||||
/* last observation caused a drop, send Qos */
|
/* this is the time the buffer entered the sink */
|
||||||
if (dropped) {
|
entered = start + jitter;
|
||||||
GstClockTime time;
|
/* this is the time the buffer left the sink */
|
||||||
GstClockTimeDiff diff;
|
left = start + (jitter < 0 ? 0 : jitter);
|
||||||
gint index;
|
|
||||||
|
|
||||||
index = priv->time_index << 2;
|
/* calculate duration of the buffer */
|
||||||
|
if (stop != -1)
|
||||||
|
duration = stop - start;
|
||||||
|
else
|
||||||
|
duration = -1;
|
||||||
|
|
||||||
time = priv->times[index];
|
/* if we have the time when the last buffer left us, calculate
|
||||||
diff = priv->times[index + 2];
|
* processing time */
|
||||||
|
if (priv->last_left != -1 && entered > priv->last_left) {
|
||||||
gst_base_sink_send_qos (sink, proportion, time, diff);
|
pt = entered - priv->last_left;
|
||||||
|
} else {
|
||||||
|
pt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* move to next observation */
|
GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, sink, "start: %" GST_TIME_FORMAT
|
||||||
priv->time_index++;
|
", entered %" GST_TIME_FORMAT ", left %" GST_TIME_FORMAT ", pt: %"
|
||||||
if (G_UNLIKELY (priv->time_index == priv->window_size)) {
|
GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT ",jitter %"
|
||||||
priv->filling = FALSE;
|
G_GINT64_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (entered),
|
||||||
priv->time_index = 0;
|
GST_TIME_ARGS (left), GST_TIME_ARGS (pt), GST_TIME_ARGS (duration),
|
||||||
}
|
jitter);
|
||||||
|
|
||||||
|
GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, sink, "avg_duration: %" GST_TIME_FORMAT
|
||||||
|
", avg_pt: %" GST_TIME_FORMAT ", avg_rate: %g",
|
||||||
|
GST_TIME_ARGS (priv->avg_duration), GST_TIME_ARGS (priv->avg_pt),
|
||||||
|
priv->avg_rate);
|
||||||
|
|
||||||
|
/* record when this buffer will leave us */
|
||||||
|
priv->last_left = left;
|
||||||
|
|
||||||
|
/* collect running averages. for first observations, we copy the
|
||||||
|
* values */
|
||||||
|
if (priv->avg_duration == -1)
|
||||||
|
priv->avg_duration = duration;
|
||||||
|
else
|
||||||
|
priv->avg_duration = UPDATE_RUNNING_AVG (priv->avg_duration, duration);
|
||||||
|
|
||||||
|
if (priv->avg_pt == -1)
|
||||||
|
priv->avg_pt = pt;
|
||||||
|
else
|
||||||
|
priv->avg_pt = UPDATE_RUNNING_AVG (priv->avg_pt, pt);
|
||||||
|
|
||||||
|
if (priv->avg_duration != 0)
|
||||||
|
rate = ((gdouble) priv->avg_pt) / priv->avg_duration;
|
||||||
|
else
|
||||||
|
rate = 1.0;
|
||||||
|
|
||||||
|
priv->avg_rate = UPDATE_RUNNING_AVG (priv->avg_rate, rate);
|
||||||
|
|
||||||
|
GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, sink,
|
||||||
|
"updated: avg_duration: %" GST_TIME_FORMAT ", avg_pt: %" GST_TIME_FORMAT
|
||||||
|
", avg_rate: %g", GST_TIME_ARGS (priv->avg_duration),
|
||||||
|
GST_TIME_ARGS (priv->avg_pt), priv->avg_rate);
|
||||||
|
|
||||||
|
|
||||||
|
/* last observation did not cause a drop, no need to send
|
||||||
|
* a QoS event */
|
||||||
|
if (G_LIKELY (!dropped))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
gst_base_sink_send_qos (sink, priv->avg_rate, priv->current_start,
|
||||||
|
priv->current_jitter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset all qos measuring */
|
/* reset all qos measuring */
|
||||||
|
@ -1225,8 +1279,13 @@ gst_base_sink_reset_qos (GstBaseSink * sink)
|
||||||
GstBaseSinkPrivate *priv;
|
GstBaseSinkPrivate *priv;
|
||||||
|
|
||||||
priv = sink->priv;
|
priv = sink->priv;
|
||||||
priv->filling = TRUE;
|
|
||||||
priv->time_index = 0;
|
priv->last_in_time = -1;
|
||||||
|
priv->last_left = -1;
|
||||||
|
priv->avg_duration = -1;
|
||||||
|
priv->avg_pt = -1;
|
||||||
|
priv->avg_rate = 1.0;
|
||||||
|
priv->avg_render = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Checks if the object was scheduled too late.
|
/* Checks if the object was scheduled too late.
|
||||||
|
@ -1245,6 +1304,11 @@ gst_base_sink_is_too_late (GstBaseSink * basesink, GstMiniObject * obj,
|
||||||
{
|
{
|
||||||
gboolean late;
|
gboolean late;
|
||||||
gint64 max_lateness;
|
gint64 max_lateness;
|
||||||
|
GstBaseSinkPrivate *priv;
|
||||||
|
|
||||||
|
priv = basesink->priv;
|
||||||
|
|
||||||
|
late = FALSE;
|
||||||
|
|
||||||
/* only for objects that were too late */
|
/* only for objects that were too late */
|
||||||
if (G_LIKELY (status != GST_CLOCK_EARLY))
|
if (G_LIKELY (status != GST_CLOCK_EARLY))
|
||||||
|
@ -1265,23 +1329,30 @@ gst_base_sink_is_too_late (GstBaseSink * basesink, GstMiniObject * obj,
|
||||||
goto no_timestamp;
|
goto no_timestamp;
|
||||||
|
|
||||||
/* if the jitter bigger than duration and lateness we are too late */
|
/* if the jitter bigger than duration and lateness we are too late */
|
||||||
if (G_LIKELY (stop != -1))
|
if (G_LIKELY (stop != -1)) {
|
||||||
late = start + jitter > stop + max_lateness;
|
if ((late = start + jitter > stop + max_lateness)) {
|
||||||
else
|
if (priv->last_in_time && start - priv->last_in_time > GST_SECOND) {
|
||||||
late = FALSE;
|
late = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (!late) {
|
||||||
|
priv->last_in_time = start;
|
||||||
|
}
|
||||||
return late;
|
return late;
|
||||||
|
|
||||||
/* all is fine */
|
/* all is fine */
|
||||||
in_time:
|
in_time:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (basesink, "object was scheduled in time");
|
GST_DEBUG_OBJECT (basesink, "object was scheduled in time");
|
||||||
return FALSE;
|
goto done;
|
||||||
}
|
}
|
||||||
no_drop:
|
no_drop:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (basesink, "frame dropping disabled");
|
GST_DEBUG_OBJECT (basesink, "frame dropping disabled");
|
||||||
return FALSE;
|
goto done;
|
||||||
}
|
}
|
||||||
not_buffer:
|
not_buffer:
|
||||||
{
|
{
|
||||||
|
@ -1317,16 +1388,48 @@ gst_base_sink_render_object (GstBaseSink * basesink, GstPad * pad,
|
||||||
|
|
||||||
/* and now render, event or buffer. */
|
/* and now render, event or buffer. */
|
||||||
if (G_LIKELY (GST_IS_BUFFER (obj))) {
|
if (G_LIKELY (GST_IS_BUFFER (obj))) {
|
||||||
|
GTimeVal start, stop;
|
||||||
|
|
||||||
/* drop late buffers unconditionally, let's hope it's unlikely */
|
/* drop late buffers unconditionally, let's hope it's unlikely */
|
||||||
if (G_UNLIKELY (late))
|
if (G_UNLIKELY (late))
|
||||||
goto dropped;
|
goto dropped;
|
||||||
|
|
||||||
bclass = GST_BASE_SINK_GET_CLASS (basesink);
|
bclass = GST_BASE_SINK_GET_CLASS (basesink);
|
||||||
|
|
||||||
|
if (G_LIKELY (bclass->render)) {
|
||||||
|
gint do_qos;
|
||||||
|
GstBaseSinkPrivate *priv;
|
||||||
|
|
||||||
|
priv = basesink->priv;
|
||||||
|
|
||||||
|
/* read once, to get same value before and after */
|
||||||
|
do_qos = g_atomic_int_get (&priv->qos_enabled);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (basesink, "rendering buffer %p", obj);
|
GST_DEBUG_OBJECT (basesink, "rendering buffer %p", obj);
|
||||||
if (G_LIKELY (bclass->render))
|
|
||||||
|
/* record rendering time for QoS and stats */
|
||||||
|
if (do_qos)
|
||||||
|
g_get_current_time (&start);
|
||||||
|
|
||||||
ret = bclass->render (basesink, GST_BUFFER_CAST (obj));
|
ret = bclass->render (basesink, GST_BUFFER_CAST (obj));
|
||||||
|
|
||||||
|
if (do_qos) {
|
||||||
|
GstClockTime elapsed;
|
||||||
|
|
||||||
|
g_get_current_time (&stop);
|
||||||
|
|
||||||
|
elapsed = GST_TIMEVAL_TO_TIME (stop) - GST_TIMEVAL_TO_TIME (start);
|
||||||
|
|
||||||
|
if (priv->avg_render == -1)
|
||||||
|
priv->avg_render = elapsed;
|
||||||
|
else
|
||||||
|
priv->avg_render = UPDATE_RUNNING_AVG (priv->avg_render, elapsed);
|
||||||
|
|
||||||
|
GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, basesink,
|
||||||
|
"avg_render: %" GST_TIME_FORMAT, GST_TIME_ARGS (priv->avg_render));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
GstEvent *event = GST_EVENT_CAST (obj);
|
GstEvent *event = GST_EVENT_CAST (obj);
|
||||||
gboolean event_res = TRUE;
|
gboolean event_res = TRUE;
|
||||||
|
@ -2347,6 +2450,7 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
|
||||||
basesink->playing_async = TRUE;
|
basesink->playing_async = TRUE;
|
||||||
ret = GST_STATE_CHANGE_ASYNC;
|
ret = GST_STATE_CHANGE_ASYNC;
|
||||||
}
|
}
|
||||||
|
gst_base_sink_reset_qos (basesink);
|
||||||
GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
|
GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
|
|
Loading…
Reference in a new issue