/*
 * 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@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
 */

#define COBJMACROS

#include "dshow.h"
#include "wine/strmbase.h"
#include "strmbase_private.h"

#include "uuids.h"
#include "wine/debug.h"

#include <assert.h>

WINE_DEFAULT_DEBUG_CHANNEL(strmbase_qc);

HRESULT QualityControlImpl_Create(IPin *input, IBaseFilter *self, QualityControlImpl **ppv) {
    QualityControlImpl *This;
    *ppv = HeapAlloc(GetProcessHeap(),0,sizeof(QualityControlImpl));
    if (!*ppv)
        return E_OUTOFMEMORY;
    This = *ppv;
    This->input = input;
    This->self = self;
    This->tonotify = NULL;
    This->clock = NULL;
    return S_OK;
}

HRESULT QualityControlImpl_Destroy(QualityControlImpl *This)
{
    return HeapFree(GetProcessHeap(),0,This);
}

HRESULT WINAPI QualityControlImpl_QueryInterface(IQualityControl *iface, REFIID riid, void **ppv) {
    QualityControlImpl *This = (QualityControlImpl*)iface;
    return IBaseFilter_QueryInterface(This->self, riid, ppv);
}

ULONG WINAPI QualityControlImpl_AddRef(IQualityControl *iface) {
    QualityControlImpl *This = (QualityControlImpl*)iface;
    return IBaseFilter_AddRef(This->self);
}

ULONG WINAPI QualityControlImpl_Release(IQualityControl *iface) {
    QualityControlImpl *This = (QualityControlImpl*)iface;
    return IBaseFilter_Release(This->self);
}

HRESULT WINAPI QualityControlImpl_Notify(IQualityControl *iface, IBaseFilter *sender, Quality qm) {
    HRESULT hr = S_FALSE;
    QualityControlImpl *This = (QualityControlImpl*)iface;
    if (This->tonotify)
        return IQualityControl_Notify(This->tonotify, This->self, qm);
    if (This->input) {
        IPin *to = NULL;
        IPin_ConnectedTo(This->input, &to);
        if (to) {
            IQualityControl *qc = NULL;
            IPin_QueryInterface(to, &IID_IQualityControl, (void**)&qc);
            if (qc) {
                hr = IQualityControl_Notify(qc, This->self, qm);
                IQualityControl_Release(qc);
            }
            IPin_Release(to);
        }
    }
    return hr;
}

HRESULT WINAPI QualityControlImpl_SetSink(IQualityControl *iface, IQualityControl *tonotify) {
    QualityControlImpl *This = (QualityControlImpl*)iface;
    This->tonotify = tonotify;
    return S_OK;
}

/* 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.
 * possitive 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(QualityControlImpl *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 = This->is_dropped = 0;
    This->qos_handled = 1; /* Lie that will be corrected on first adjustment */
}


void QualityControlRender_SetClock(QualityControlImpl *This, IReferenceClock *clock) {
    This->clock = clock;
}

static BOOL QualityControlRender_IsLate(QualityControlImpl *This, REFERENCE_TIME jitter,
                                        REFERENCE_TIME start, REFERENCE_TIME stop)
{
    REFERENCE_TIME max_lateness = 200000;

    /* 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;
}

HRESULT QualityControlRender_WaitFor(QualityControlImpl *This, IMediaSample *sample, HANDLE ev) {
    REFERENCE_TIME start = -1, stop = -1, jitter = 0;
    This->current_rstart = This->current_rstop = -1;
    This->current_jitter = 0;
    if (!This->clock || FAILED(IMediaSample_GetTime(sample, &start, &stop)))
        return S_OK;

    if (start >= 0) {
        REFERENCE_TIME now;
        IReferenceClock_GetTime(This->clock, &now);
        now -= This->clockstart;

        jitter = now - start;
        if (jitter <= -10000) {
            DWORD_PTR cookie;
            IReferenceClock_AdviseTime(This->clock, This->clockstart, start, (HEVENT)ev, &cookie);
            WaitForSingleObject(ev, INFINITE);
            IReferenceClock_Unadvise(This->clock, cookie);
        }
    }
    else
        start = stop = -1;
    This->current_rstart = start;
    This->current_rstop = stop > start ? stop : start;
    This->current_jitter = jitter;
    This->is_dropped = QualityControlRender_IsLate(This, jitter, start, stop);
    TRACE("Dropped: %i %i %i %i\n", This->is_dropped, (int)(start/10000), (int)(stop/10000), (int)(jitter / 10000));
    if (This->is_dropped) {
        This->dropped++;
        if (!This->qos_handled)
            return S_FALSE;
    } else
        This->rendered++;
    return S_OK;
}

void QualityControlRender_DoQOS(QualityControlImpl *priv)
{
    REFERENCE_TIME start, stop, jitter, pt, entered, left, duration;
    double rate;

    if (!priv->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;
    }

#define XTIME(u) (int)(u/10000000), (int)((u / 10000)%1000)
    TRACE("start: %u.%03u, entered %u.%03u, left %u.%03u, pt: %u.%03u, "
          "duration %u.%03u, jitter %u.%03u\n", XTIME(start), XTIME(entered),
          XTIME(left), XTIME(pt), XTIME(duration), XTIME(jitter));

    TRACE("avg_duration: %u.%03u, avg_pt: %u.%03u, avg_rate: %g\n",
      XTIME(priv->avg_duration), XTIME(priv->avg_pt), priv->avg_rate);
#undef XTIME

    /* 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: %i from %i, rate: %g\n", (int)(q.Late/10000), (int)(q.TimeStamp/10000), 1./priv->avg_rate);
        hr = IQualityControl_Notify((IQualityControl *)priv, priv->self, q);
        priv->qos_handled = hr == S_OK;
    }

    /* record when this buffer will leave us */
    priv->last_left = left;
}


void QualityControlRender_BeginRender(QualityControlImpl *This) {
    This->start = -1;
    if (!This->clock)
        return;
    IReferenceClock_GetTime(This->clock, &This->start);
}

void QualityControlRender_EndRender(QualityControlImpl *This) {
    REFERENCE_TIME elapsed;
    if (!This->clock || This->start < 0 || FAILED(IReferenceClock_GetTime(This->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);
}
