Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/strmbase/Makefile.in | 1 -
dlls/strmbase/qualitycontrol.c | 317 ------------------------------
dlls/strmbase/renderer.c | 326 +++++++++++++++++++++++++++++++
dlls/strmbase/strmbase_private.h | 5 -
dlls/wineqtdecoder/Makefile.in | 1 -
include/wine/strmbase.h | 2 -
6 files changed, 326 insertions(+), 326 deletions(-)
delete mode 100644 dlls/strmbase/qualitycontrol.c
diff --git a/dlls/strmbase/Makefile.in b/dlls/strmbase/Makefile.in
index ec13acccf40..0fef7b6ff03 100644
--- a/dlls/strmbase/Makefile.in
+++ b/dlls/strmbase/Makefile.in
@@ -7,6 +7,5 @@ C_SRCS = \
outputqueue.c \
pin.c \
pospass.c \
- qualitycontrol.c \
renderer.c \
seeking.c
diff --git a/dlls/strmbase/qualitycontrol.c b/dlls/strmbase/qualitycontrol.c
deleted file mode 100644
index d0bd070d447..00000000000
--- a/dlls/strmbase/qualitycontrol.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Quality Control Interfaces
- *
- * Copyright 2010 Maarten Lankhorst for CodeWeavers
- *
- * rendering qos functions based on, the original can be found at
- * gstreamer/libs/gst/base/gstbasesink.c which has copyright notice:
- *
- * Copyright (C) 2005-2007 Wim Taymans <wim.taymans(a)gmail.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "strmbase_private.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(strmbase_qc);
-
-static inline struct strmbase_qc *impl_from_IQualityControl(IQualityControl *iface)
-{
- return CONTAINING_RECORD(iface, struct strmbase_qc, IQualityControl_iface);
-}
-
-static HRESULT WINAPI quality_control_QueryInterface(IQualityControl *iface, REFIID riid, void **ppv)
-{
- struct strmbase_qc *This = impl_from_IQualityControl(iface);
- return IBaseFilter_QueryInterface(&This->pin->filter->IBaseFilter_iface, riid, ppv);
-}
-
-static ULONG WINAPI quality_control_AddRef(IQualityControl *iface)
-{
- struct strmbase_qc *This = impl_from_IQualityControl(iface);
- return IBaseFilter_AddRef(&This->pin->filter->IBaseFilter_iface);
-}
-
-static ULONG WINAPI quality_control_Release(IQualityControl *iface)
-{
- struct strmbase_qc *This = impl_from_IQualityControl(iface);
- return IBaseFilter_Release(&This->pin->filter->IBaseFilter_iface);
-}
-
-static HRESULT WINAPI quality_control_Notify(IQualityControl *iface, IBaseFilter *sender, Quality qm)
-{
- struct strmbase_qc *This = impl_from_IQualityControl(iface);
- HRESULT hr = S_FALSE;
-
- TRACE("iface %p, sender %p, type %#x, proportion %u, late %s, timestamp %s.\n",
- iface, sender, qm.Type, qm.Proportion, debugstr_time(qm.Late), debugstr_time(qm.TimeStamp));
-
- if (This->tonotify)
- return IQualityControl_Notify(This->tonotify, &This->pin->filter->IBaseFilter_iface, qm);
-
- if (This->pin->peer)
- {
- IQualityControl *qc = NULL;
- IPin_QueryInterface(This->pin->peer, &IID_IQualityControl, (void **)&qc);
- if (qc)
- {
- hr = IQualityControl_Notify(qc, &This->pin->filter->IBaseFilter_iface, qm);
- IQualityControl_Release(qc);
- }
- }
-
- return hr;
-}
-
-static HRESULT WINAPI quality_control_SetSink(IQualityControl *iface, IQualityControl *tonotify)
-{
- struct strmbase_qc *This = impl_from_IQualityControl(iface);
- TRACE("%p %p\n", This, tonotify);
- This->tonotify = tonotify;
- return S_OK;
-}
-
-static const IQualityControlVtbl quality_control_vtbl =
-{
- quality_control_QueryInterface,
- quality_control_AddRef,
- quality_control_Release,
- quality_control_Notify,
- quality_control_SetSink,
-};
-
-/* Macros copied from gstreamer, weighted average between old average and new ones */
-#define DO_RUNNING_AVG(avg,val,size) (((val) + ((size)-1) * (avg)) / (size))
-
-/* generic running average, this has a neutral window size */
-#define UPDATE_RUNNING_AVG(avg,val) DO_RUNNING_AVG(avg,val,8)
-
-/* the windows for these running averages are experimentally obtained.
- * positive values get averaged more while negative values use a small
- * window so we can react faster to badness. */
-#define UPDATE_RUNNING_AVG_P(avg,val) DO_RUNNING_AVG(avg,val,16)
-#define UPDATE_RUNNING_AVG_N(avg,val) DO_RUNNING_AVG(avg,val,4)
-
-void QualityControlRender_Start(struct strmbase_qc *This, REFERENCE_TIME tStart)
-{
- This->avg_render = This->last_in_time = This->last_left = This->avg_duration = This->avg_pt = -1;
- This->clockstart = tStart;
- This->avg_rate = -1.0;
- This->rendered = This->dropped = 0;
- This->is_dropped = FALSE;
- This->qos_handled = TRUE; /* Lie that will be corrected on first adjustment */
-}
-
-static BOOL QualityControlRender_IsLate(struct strmbase_qc *This, REFERENCE_TIME jitter,
- REFERENCE_TIME start, REFERENCE_TIME stop)
-{
- REFERENCE_TIME max_lateness = 200000;
-
- TRACE("jitter %s, start %s, stop %s.\n", debugstr_time(jitter),
- debugstr_time(start), debugstr_time(stop));
-
- /* we can add a valid stop time */
- if (stop >= start)
- max_lateness += stop;
- else
- max_lateness += start;
-
- /* if the jitter bigger than duration and lateness we are too late */
- if (start + jitter > max_lateness) {
- WARN("buffer is too late %i > %i\n", (int)((start + jitter)/10000), (int)(max_lateness/10000));
- /* !!emergency!!, if we did not receive anything valid for more than a
- * second, render it anyway so the user sees something */
- if (This->last_in_time < 0 ||
- start - This->last_in_time < 10000000)
- return TRUE;
- FIXME("A lot of buffers are being dropped.\n");
- FIXME("There may be a timestamping problem, or this computer is too slow.\n");
- }
- This->last_in_time = start;
- return FALSE;
-}
-
-void QualityControlRender_DoQOS(struct strmbase_qc *priv)
-{
- REFERENCE_TIME start, stop, jitter, pt, entered, left, duration;
- double rate;
-
- TRACE("%p\n", priv);
-
- if (!priv->pin->filter->clock || priv->current_rstart < 0)
- return;
-
- start = priv->current_rstart;
- stop = priv->current_rstop;
- jitter = priv->current_jitter;
-
- if (jitter < 0) {
- /* this is the time the buffer entered the sink */
- if (start < -jitter)
- entered = 0;
- else
- entered = start + jitter;
- left = start;
- } else {
- /* this is the time the buffer entered the sink */
- entered = start + jitter;
- /* this is the time the buffer left the sink */
- left = start + jitter;
- }
-
- /* calculate duration of the buffer */
- if (stop >= start)
- duration = stop - start;
- else
- duration = 0;
-
- /* if we have the time when the last buffer left us, calculate
- * processing time */
- if (priv->last_left >= 0) {
- if (entered > priv->last_left) {
- pt = entered - priv->last_left;
- } else {
- pt = 0;
- }
- } else {
- pt = priv->avg_pt;
- }
-
- TRACE("start %s, entered %s, left %s, pt %s, duration %s, jitter %s.\n",
- debugstr_time(start), debugstr_time(entered), debugstr_time(left),
- debugstr_time(pt), debugstr_time(duration), debugstr_time(jitter));
-
- TRACE("average duration %s, average pt %s, average rate %.16e.\n",
- debugstr_time(priv->avg_duration), debugstr_time(priv->avg_pt), priv->avg_rate);
-
- /* collect running averages. for first observations, we copy the
- * values */
- if (priv->avg_duration < 0)
- priv->avg_duration = duration;
- else
- priv->avg_duration = UPDATE_RUNNING_AVG (priv->avg_duration, duration);
-
- if (priv->avg_pt < 0)
- priv->avg_pt = pt;
- else
- priv->avg_pt = UPDATE_RUNNING_AVG (priv->avg_pt, pt);
-
- if (priv->avg_duration != 0)
- rate =
- (double)priv->avg_pt /
- (double)priv->avg_duration;
- else
- rate = 0.0;
-
- if (priv->last_left >= 0) {
- if (priv->is_dropped || priv->avg_rate < 0.0) {
- priv->avg_rate = rate;
- } else {
- if (rate > 1.0)
- priv->avg_rate = UPDATE_RUNNING_AVG_N (priv->avg_rate, rate);
- else
- priv->avg_rate = UPDATE_RUNNING_AVG_P (priv->avg_rate, rate);
- }
- }
-
- if (priv->avg_rate >= 0.0) {
- HRESULT hr;
- Quality q;
- /* if we have a valid rate, start sending QoS messages */
- if (priv->current_jitter < 0) {
- /* make sure we never go below 0 when adding the jitter to the
- * timestamp. */
- if (priv->current_rstart < -priv->current_jitter)
- priv->current_jitter = -priv->current_rstart;
- }
- else
- priv->current_jitter += (priv->current_rstop - priv->current_rstart);
- q.Type = (jitter > 0 ? Famine : Flood);
- q.Proportion = (LONG)(1000. / priv->avg_rate);
- if (q.Proportion < 200)
- q.Proportion = 200;
- else if (q.Proportion > 5000)
- q.Proportion = 5000;
- q.Late = priv->current_jitter;
- q.TimeStamp = priv->current_rstart;
- TRACE("Late: %s from %s, rate: %g\n", debugstr_time(q.Late), debugstr_time(q.TimeStamp), 1./priv->avg_rate);
- hr = IQualityControl_Notify(&priv->IQualityControl_iface, &priv->pin->filter->IBaseFilter_iface, q);
- priv->qos_handled = hr == S_OK;
- }
-
- /* record when this buffer will leave us */
- priv->last_left = left;
-}
-
-
-void QualityControlRender_BeginRender(struct strmbase_qc *This, REFERENCE_TIME start, REFERENCE_TIME stop)
-{
- This->start = -1;
-
- This->current_rstart = start;
- This->current_rstop = max(stop, start);
-
- if (start >= 0)
- {
- REFERENCE_TIME now;
- IReferenceClock_GetTime(This->pin->filter->clock, &now);
- This->current_jitter = (now - This->clockstart) - start;
- }
- else
- This->current_jitter = 0;
-
- /* FIXME: This isn't correct; we don't drop samples, nor should. */
- This->is_dropped = QualityControlRender_IsLate(This, This->current_jitter, start, stop);
- TRACE("dropped %d, start %s, stop %s, jitter %s.\n", This->is_dropped,
- debugstr_time(start), debugstr_time(stop), debugstr_time(This->current_jitter));
- if (This->is_dropped)
- This->dropped++;
- else
- This->rendered++;
-
- if (!This->pin->filter->clock)
- return;
-
- IReferenceClock_GetTime(This->pin->filter->clock, &This->start);
-
- TRACE("Starting at %s.\n", debugstr_time(This->start));
-}
-
-void QualityControlRender_EndRender(struct strmbase_qc *This)
-{
- REFERENCE_TIME elapsed;
-
- TRACE("%p\n", This);
-
- if (!This->pin->filter->clock || This->start < 0
- || FAILED(IReferenceClock_GetTime(This->pin->filter->clock, &This->stop)))
- return;
-
- elapsed = This->start - This->stop;
- if (elapsed < 0)
- return;
- if (This->avg_render < 0)
- This->avg_render = elapsed;
- else
- This->avg_render = UPDATE_RUNNING_AVG (This->avg_render, elapsed);
-}
-
-void strmbase_qc_init(struct strmbase_qc *qc, struct strmbase_pin *pin)
-{
- memset(qc, 0, sizeof(*qc));
- qc->pin = pin;
- qc->current_rstart = qc->current_rstop = -1;
- qc->IQualityControl_iface.lpVtbl = &quality_control_vtbl;
-}
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c
index 8da3d81de61..f3869c868dc 100644
--- a/dlls/strmbase/renderer.c
+++ b/dlls/strmbase/renderer.c
@@ -22,6 +22,257 @@
WINE_DEFAULT_DEBUG_CHANNEL(strmbase);
+/* The following quality-of-service code is based on GstBaseSink QoS code, which
+ * is covered by the following copyright information:
+ *
+ * GStreamer
+ * Copyright (C) 2005-2007 Wim Taymans <wim.taymans(a)gmail.com>
+ *
+ * gstbasesink.c: Base class for sink elements
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#define DO_RUNNING_AVG(avg,val,size) (((val) + ((size)-1) * (avg)) / (size))
+
+/* Generic running average; this has a neutral window size. */
+#define UPDATE_RUNNING_AVG(avg,val) DO_RUNNING_AVG(avg,val,8)
+
+/* The windows for these running averages are experimentally obtained.
+ * Positive values get averaged more, while negative values use a small
+ * window so we can react faster to badness. */
+#define UPDATE_RUNNING_AVG_P(avg,val) DO_RUNNING_AVG(avg,val,16)
+#define UPDATE_RUNNING_AVG_N(avg,val) DO_RUNNING_AVG(avg,val,4)
+
+static void QualityControlRender_Start(struct strmbase_qc *This, REFERENCE_TIME tStart)
+{
+ This->avg_render = This->last_in_time = This->last_left = This->avg_duration = This->avg_pt = -1;
+ This->clockstart = tStart;
+ This->avg_rate = -1.0;
+ This->rendered = This->dropped = 0;
+ This->is_dropped = FALSE;
+ This->qos_handled = TRUE; /* Lie that will be corrected on first adjustment */
+}
+
+static BOOL QualityControlRender_IsLate(struct strmbase_qc *This, REFERENCE_TIME jitter,
+ REFERENCE_TIME start, REFERENCE_TIME stop)
+{
+ REFERENCE_TIME max_lateness = 200000;
+
+ TRACE("jitter %s, start %s, stop %s.\n", debugstr_time(jitter),
+ debugstr_time(start), debugstr_time(stop));
+
+ /* we can add a valid stop time */
+ if (stop >= start)
+ max_lateness += stop;
+ else
+ max_lateness += start;
+
+ /* if the jitter bigger than duration and lateness we are too late */
+ if (start + jitter > max_lateness) {
+ WARN("buffer is too late %i > %i\n", (int)((start + jitter)/10000), (int)(max_lateness/10000));
+ /* !!emergency!!, if we did not receive anything valid for more than a
+ * second, render it anyway so the user sees something */
+ if (This->last_in_time < 0 ||
+ start - This->last_in_time < 10000000)
+ return TRUE;
+ FIXME("A lot of buffers are being dropped.\n");
+ FIXME("There may be a timestamping problem, or this computer is too slow.\n");
+ }
+ This->last_in_time = start;
+ return FALSE;
+}
+
+static void QualityControlRender_DoQOS(struct strmbase_qc *priv)
+{
+ REFERENCE_TIME start, stop, jitter, pt, entered, left, duration;
+ double rate;
+
+ TRACE("%p\n", priv);
+
+ if (!priv->pin->filter->clock || priv->current_rstart < 0)
+ return;
+
+ start = priv->current_rstart;
+ stop = priv->current_rstop;
+ jitter = priv->current_jitter;
+
+ if (jitter < 0)
+ {
+ /* This is the time the buffer entered the sink. */
+ if (start < -jitter)
+ entered = 0;
+ else
+ entered = start + jitter;
+ left = start;
+ }
+ else
+ {
+ /* This is the time the buffer entered the sink. */
+ entered = start + jitter;
+ /* This is the time the buffer left the sink. */
+ left = start + jitter;
+ }
+
+ /* Calculate the duration of the buffer. */
+ if (stop >= start)
+ duration = stop - start;
+ else
+ duration = 0;
+
+ /* If we have the time when the last buffer left us, calculate processing
+ * time. */
+ if (priv->last_left >= 0)
+ {
+ if (entered > priv->last_left)
+ pt = entered - priv->last_left;
+ else
+ pt = 0;
+ }
+ else
+ {
+ pt = priv->avg_pt;
+ }
+
+ TRACE("start %s, entered %s, left %s, pt %s, duration %s, jitter %s.\n",
+ debugstr_time(start), debugstr_time(entered), debugstr_time(left),
+ debugstr_time(pt), debugstr_time(duration), debugstr_time(jitter));
+
+ TRACE("average duration %s, average pt %s, average rate %.16e.\n",
+ debugstr_time(priv->avg_duration), debugstr_time(priv->avg_pt), priv->avg_rate);
+
+ /* Collect running averages. For first observations, we copy the values. */
+ if (priv->avg_duration < 0)
+ priv->avg_duration = duration;
+ else
+ priv->avg_duration = UPDATE_RUNNING_AVG(priv->avg_duration, duration);
+
+ if (priv->avg_pt < 0)
+ priv->avg_pt = pt;
+ else
+ priv->avg_pt = UPDATE_RUNNING_AVG(priv->avg_pt, pt);
+
+ if (priv->avg_duration != 0)
+ rate = (double)priv->avg_pt / (double)priv->avg_duration;
+ else
+ rate = 0.0;
+
+ if (priv->last_left >= 0)
+ {
+ if (priv->is_dropped || priv->avg_rate < 0.0)
+ {
+ priv->avg_rate = rate;
+ }
+ else
+ {
+ if (rate > 1.0)
+ priv->avg_rate = UPDATE_RUNNING_AVG_N(priv->avg_rate, rate);
+ else
+ priv->avg_rate = UPDATE_RUNNING_AVG_P(priv->avg_rate, rate);
+ }
+ }
+
+ if (priv->avg_rate >= 0.0)
+ {
+ HRESULT hr;
+ Quality q;
+
+ /* If we have a valid rate, start sending QoS messages. */
+ if (priv->current_jitter < 0)
+ {
+ /* Make sure we never go below 0 when adding the jitter to the
+ * timestamp. */
+ if (priv->current_rstart < -priv->current_jitter)
+ priv->current_jitter = -priv->current_rstart;
+ }
+ else
+ {
+ priv->current_jitter += (priv->current_rstop - priv->current_rstart);
+ }
+
+ q.Type = (jitter > 0 ? Famine : Flood);
+ q.Proportion = 1000.0 / priv->avg_rate;
+ if (q.Proportion < 200)
+ q.Proportion = 200;
+ else if (q.Proportion > 5000)
+ q.Proportion = 5000;
+ q.Late = priv->current_jitter;
+ q.TimeStamp = priv->current_rstart;
+ hr = IQualityControl_Notify(&priv->IQualityControl_iface, &priv->pin->filter->IBaseFilter_iface, q);
+ priv->qos_handled = hr == S_OK;
+ }
+
+ /* Record when this buffer will leave us. */
+ priv->last_left = left;
+}
+
+static void QualityControlRender_BeginRender(struct strmbase_qc *This, REFERENCE_TIME start, REFERENCE_TIME stop)
+{
+ This->start = -1;
+
+ This->current_rstart = start;
+ This->current_rstop = max(stop, start);
+
+ if (start >= 0)
+ {
+ REFERENCE_TIME now;
+ IReferenceClock_GetTime(This->pin->filter->clock, &now);
+ This->current_jitter = (now - This->clockstart) - start;
+ }
+ else
+ {
+ This->current_jitter = 0;
+ }
+
+ /* FIXME: This isn't correct; we don't drop samples, nor should. */
+ This->is_dropped = QualityControlRender_IsLate(This, This->current_jitter, start, stop);
+ TRACE("dropped %d, start %s, stop %s, jitter %s.\n", This->is_dropped,
+ debugstr_time(start), debugstr_time(stop), debugstr_time(This->current_jitter));
+ if (This->is_dropped)
+ This->dropped++;
+ else
+ This->rendered++;
+
+ if (!This->pin->filter->clock)
+ return;
+
+ IReferenceClock_GetTime(This->pin->filter->clock, &This->start);
+
+ TRACE("Starting at %s.\n", debugstr_time(This->start));
+}
+
+static void QualityControlRender_EndRender(struct strmbase_qc *This)
+{
+ REFERENCE_TIME elapsed;
+
+ TRACE("%p\n", This);
+
+ if (!This->pin->filter->clock || This->start < 0
+ || FAILED(IReferenceClock_GetTime(This->pin->filter->clock, &This->stop)))
+ return;
+
+ elapsed = This->start - This->stop;
+ if (elapsed < 0)
+ return;
+ if (This->avg_render < 0)
+ This->avg_render = elapsed;
+ else
+ This->avg_render = UPDATE_RUNNING_AVG(This->avg_render, elapsed);
+}
+
static inline struct strmbase_renderer *impl_from_strmbase_filter(struct strmbase_filter *iface)
{
return CONTAINING_RECORD(iface, struct strmbase_renderer, filter);
@@ -319,6 +570,73 @@ static const struct strmbase_sink_ops sink_ops =
.sink_end_flush = sink_end_flush,
};
+static struct strmbase_qc *impl_from_IQualityControl(IQualityControl *iface)
+{
+ return CONTAINING_RECORD(iface, struct strmbase_qc, IQualityControl_iface);
+}
+
+static HRESULT WINAPI quality_control_QueryInterface(IQualityControl *iface, REFIID iid, void **out)
+{
+ struct strmbase_qc *qc = impl_from_IQualityControl(iface);
+ return IBaseFilter_QueryInterface(&qc->pin->filter->IBaseFilter_iface, iid, out);
+}
+
+static ULONG WINAPI quality_control_AddRef(IQualityControl *iface)
+{
+ struct strmbase_qc *qc = impl_from_IQualityControl(iface);
+ return IBaseFilter_AddRef(&qc->pin->filter->IBaseFilter_iface);
+}
+
+static ULONG WINAPI quality_control_Release(IQualityControl *iface)
+{
+ struct strmbase_qc *qc = impl_from_IQualityControl(iface);
+ return IBaseFilter_Release(&qc->pin->filter->IBaseFilter_iface);
+}
+
+static HRESULT WINAPI quality_control_Notify(IQualityControl *iface, IBaseFilter *sender, Quality q)
+{
+ struct strmbase_qc *qc = impl_from_IQualityControl(iface);
+ HRESULT hr = S_FALSE;
+
+ TRACE("iface %p, sender %p, type %#x, proportion %u, late %s, timestamp %s.\n",
+ iface, sender, q.Type, q.Proportion, debugstr_time(q.Late), debugstr_time(q.TimeStamp));
+
+ if (qc->tonotify)
+ return IQualityControl_Notify(qc->tonotify, &qc->pin->filter->IBaseFilter_iface, q);
+
+ if (qc->pin->peer)
+ {
+ IQualityControl *peer_qc = NULL;
+ IPin_QueryInterface(qc->pin->peer, &IID_IQualityControl, (void **)&peer_qc);
+ if (peer_qc)
+ {
+ hr = IQualityControl_Notify(peer_qc, &qc->pin->filter->IBaseFilter_iface, q);
+ IQualityControl_Release(peer_qc);
+ }
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI quality_control_SetSink(IQualityControl *iface, IQualityControl *sink)
+{
+ struct strmbase_qc *qc = impl_from_IQualityControl(iface);
+
+ TRACE("iface %p, sink %p.\n", iface, sink);
+
+ qc->tonotify = sink;
+ return S_OK;
+}
+
+static const IQualityControlVtbl quality_control_vtbl =
+{
+ quality_control_QueryInterface,
+ quality_control_AddRef,
+ quality_control_Release,
+ quality_control_Notify,
+ quality_control_SetSink,
+};
+
void strmbase_renderer_cleanup(struct strmbase_renderer *filter)
{
if (filter->sink.pin.peer)
@@ -334,6 +652,14 @@ void strmbase_renderer_cleanup(struct strmbase_renderer *filter)
strmbase_filter_cleanup(&filter->filter);
}
+static void strmbase_qc_init(struct strmbase_qc *qc, struct strmbase_pin *pin)
+{
+ memset(qc, 0, sizeof(*qc));
+ qc->pin = pin;
+ qc->current_rstart = qc->current_rstop = -1;
+ qc->IQualityControl_iface.lpVtbl = &quality_control_vtbl;
+}
+
void strmbase_renderer_init(struct strmbase_renderer *filter, IUnknown *outer,
const CLSID *clsid, const WCHAR *sink_name, const struct strmbase_renderer_ops *ops)
{
diff --git a/dlls/strmbase/strmbase_private.h b/dlls/strmbase/strmbase_private.h
index ff82d942813..9ac0b24bb1a 100644
--- a/dlls/strmbase/strmbase_private.h
+++ b/dlls/strmbase/strmbase_private.h
@@ -53,9 +53,4 @@ static inline const char *debugstr_time(REFERENCE_TIME time)
return wine_dbg_sprintf("%s", rev);
}
-void QualityControlRender_Start(struct strmbase_qc *This, REFERENCE_TIME tStart);
-void QualityControlRender_DoQOS(struct strmbase_qc *priv);
-void QualityControlRender_BeginRender(struct strmbase_qc *This, REFERENCE_TIME start, REFERENCE_TIME stop);
-void QualityControlRender_EndRender(struct strmbase_qc *This);
-
#endif /* __WINE_STRMBASE_PRIVATE_H */
diff --git a/dlls/wineqtdecoder/Makefile.in b/dlls/wineqtdecoder/Makefile.in
index 2b7179f2316..41a96709beb 100644
--- a/dlls/wineqtdecoder/Makefile.in
+++ b/dlls/wineqtdecoder/Makefile.in
@@ -13,7 +13,6 @@ C_SRCS = \
qtsplitter.c \
qtutils.c \
qtvdecoder.c \
- qualitycontrol.c \
seeking.c
RC_SRCS = \
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index 4bb9d898a1a..51dcb3a8c55 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -286,8 +286,6 @@ struct strmbase_qc
BOOL qos_handled, is_dropped;
};
-void strmbase_qc_init(struct strmbase_qc *qc, struct strmbase_pin *pin);
-
struct strmbase_renderer
{
struct strmbase_filter filter;
--
2.20.1