39#define XTIME_FMT "%u.%03u"
40#define XTIME(u) (int)(u/10000000), (int)((u / 10000)%1000)
44 QualityControlImpl *
This;
54 This->current_rstart =
This->current_rstop = -1;
72 return IBaseFilter_QueryInterface(
This->self,
riid,
ppv);
78 return IBaseFilter_AddRef(
This->self);
84 return IBaseFilter_Release(
This->self);
97 return IQualityControl_Notify(
This->tonotify,
This->self, qm);
101 IPin_ConnectedTo(
This->input, &to);
104 IPin_QueryInterface(to, &IID_IQualityControl, (
void**)&qc);
106 hr = IQualityControl_Notify(qc,
This->self, qm);
107 IQualityControl_Release(qc);
120 This->tonotify = tonotify;
125#define DO_RUNNING_AVG(avg,val,size) (((val) + ((size)-1) * (avg)) / (size))
128#define UPDATE_RUNNING_AVG(avg,val) DO_RUNNING_AVG(avg,val,8)
133#define UPDATE_RUNNING_AVG_P(avg,val) DO_RUNNING_AVG(avg,val,16)
134#define UPDATE_RUNNING_AVG_N(avg,val) DO_RUNNING_AVG(avg,val,4)
139 This->avg_render =
This->last_in_time =
This->last_left =
This->avg_duration =
This->avg_pt = -1;
140 This->clockstart = tStart;
141 This->avg_rate = -1.0;
164 max_lateness += stop;
166 max_lateness +=
start;
169 if (
start + jitter > max_lateness) {
170 WARN(
"buffer is too late %i > %i\n", (
int)((
start + jitter)/10000), (
int)(max_lateness/10000));
173 if (
This->last_in_time < 0 ||
176 FIXME(
"A lot of buffers are being dropped.\n");
177 FIXME(
"There may be a timestamping problem, or this computer is too slow.\n");
189 This->current_rstart =
This->current_rstop = -1;
190 This->current_jitter = 0;
196 IReferenceClock_GetTime(
This->clock, &
now);
200 if (jitter <= -10000) {
204 IReferenceClock_Unadvise(
This->clock,
cookie);
211 This->current_jitter = jitter;
213 TRACE(
"Dropped: %i %i %i %i\n",
This->is_dropped, (
int)(
start/10000), (
int)(stop/10000), (
int)(jitter / 10000));
214 if (
This->is_dropped) {
216 if (!
This->qos_handled)
230 if (!priv->clock || priv->current_rstart < 0)
233 start = priv->current_rstart;
234 stop = priv->current_rstop;
235 jitter = priv->current_jitter;
242 entered =
start + jitter;
246 entered =
start + jitter;
253 duration = stop -
start;
259 if (priv->last_left >= 0) {
260 if (entered > priv->last_left) {
261 pt = entered - priv->last_left;
274 XTIME(priv->avg_duration),
XTIME(priv->avg_pt), priv->avg_rate);
278 if (priv->avg_duration < 0)
279 priv->avg_duration = duration;
283 if (priv->avg_pt < 0)
288 if (priv->avg_duration != 0)
291 (
double)priv->avg_duration;
295 if (priv->last_left >= 0) {
296 if (priv->is_dropped || priv->avg_rate < 0.0) {
297 priv->avg_rate =
rate;
306 if (priv->avg_rate >= 0.0) {
310 if (priv->current_jitter < 0) {
313 if (priv->current_rstart < -priv->current_jitter)
314 priv->current_jitter = -priv->current_rstart;
317 priv->current_jitter += (priv->current_rstop - priv->current_rstart);
318 q.Type = (jitter > 0 ? Famine : Flood);
319 q.Proportion = (
LONG)(1000. / priv->avg_rate);
320 if (
q.Proportion < 200)
322 else if (
q.Proportion > 5000)
324 q.Late = priv->current_jitter;
325 q.TimeStamp = priv->current_rstart;
326 TRACE(
"Late: %i from %i, rate: %g\n", (
int)(
q.Late/10000), (
int)(
q.TimeStamp/10000), 1./priv->avg_rate);
327 hr = IQualityControl_Notify(&priv->IQualityControl_iface, priv->self,
q);
328 priv->qos_handled =
hr ==
S_OK;
332 priv->last_left =
left;
345 IReferenceClock_GetTime(
This->clock, &
This->start);
361 if (
This->avg_render < 0)
362 This->avg_render = elapsed;
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
#define HeapFree(x, y, z)
_ACRTIMP clock_t __cdecl clock(void)
GLdouble GLdouble GLdouble GLdouble q
GLenum GLenum GLenum input
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
void QualityControlRender_EndRender(QualityControlImpl *This)
void QualityControlRender_BeginRender(QualityControlImpl *This)
ULONG WINAPI QualityControlImpl_AddRef(IQualityControl *iface)
void QualityControlRender_Start(QualityControlImpl *This, REFERENCE_TIME tStart)
HRESULT WINAPI QualityControlImpl_Notify(IQualityControl *iface, IBaseFilter *sender, Quality qm)
void QualityControlImpl_Destroy(QualityControlImpl *This)
HRESULT WINAPI QualityControlImpl_QueryInterface(IQualityControl *iface, REFIID riid, void **ppv)
ULONG WINAPI QualityControlImpl_Release(IQualityControl *iface)
void QualityControlRender_DoQOS(QualityControlImpl *priv)
HRESULT QualityControlRender_WaitFor(QualityControlImpl *This, IMediaSample *sample, HANDLE ev)
HRESULT QualityControlImpl_Create(IPin *input, IBaseFilter *self, QualityControlImpl **ppv)
#define UPDATE_RUNNING_AVG_N(avg, val)
static BOOL QualityControlRender_IsLate(QualityControlImpl *This, REFERENCE_TIME jitter, REFERENCE_TIME start, REFERENCE_TIME stop)
static QualityControlImpl * impl_from_IQualityControl(IQualityControl *iface)
#define UPDATE_RUNNING_AVG(avg, val)
void QualityControlRender_SetClock(QualityControlImpl *This, IReferenceClock *clock)
HRESULT WINAPI QualityControlImpl_SetSink(IQualityControl *iface, IQualityControl *tonotify)
#define UPDATE_RUNNING_AVG_P(avg, val)
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
#define CONTAINING_RECORD(address, type, field)