/*
 * Copyright (C) 2013 Piotr Caban for CodeWeavers
 *
 * 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 <stdarg.h>
#include <stdio.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "wtypes.h"
#include "dshow.h"
#include "vfw.h"
#include "aviriff.h"

#include "qcap_main.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(qcap);

#define MAX_PIN_NO 128
#define AVISUPERINDEX_ENTRIES 2000
#define AVISTDINDEX_ENTRIES 4000
#define ALIGN(x) ((x+1)/2*2)

typedef struct {
    BaseOutputPin pin;
    IQualityControl IQualityControl_iface;

    int cur_stream;
    LONGLONG cur_time;

    int buf_pos;
    BYTE buf[65536];

    int movi_off;
    int out_pos;
    int size;
    IStream *stream;
} AviMuxOut;

typedef struct {
    BaseInputPin pin;
    IAMStreamControl IAMStreamControl_iface;
    IPropertyBag IPropertyBag_iface;
    IQualityControl IQualityControl_iface;

    REFERENCE_TIME avg_time_per_frame;
    REFERENCE_TIME stop;
    int stream_id;
    LONGLONG stream_time;

    /* strl chunk */
    AVISTREAMHEADER strh;
    struct {
        FOURCC fcc;
        DWORD cb;
        BYTE data[1];
    } *strf;
    AVISUPERINDEX *indx;
    BYTE indx_data[FIELD_OFFSET(AVISUPERINDEX, aIndex[AVISUPERINDEX_ENTRIES])];

    /* movi chunk */
    int ix_off;
    AVISTDINDEX *ix;
    BYTE ix_data[FIELD_OFFSET(AVISTDINDEX, aIndex[AVISTDINDEX_ENTRIES])];

    IMediaSample *samples_head;
    IMemAllocator *samples_allocator;
} AviMuxIn;

typedef struct {
    BaseFilter filter;
    IConfigAviMux IConfigAviMux_iface;
    IConfigInterleaving IConfigInterleaving_iface;
    IMediaSeeking IMediaSeeking_iface;
    IPersistMediaPropertyBag IPersistMediaPropertyBag_iface;
    ISpecifyPropertyPages ISpecifyPropertyPages_iface;

    InterleavingMode mode;
    REFERENCE_TIME interleave;
    REFERENCE_TIME preroll;

    AviMuxOut *out;
    int input_pin_no;
    AviMuxIn *in[MAX_PIN_NO-1];

    REFERENCE_TIME start, stop;
    AVIMAINHEADER avih;

    int idx1_entries;
    int idx1_size;
    AVIINDEXENTRY *idx1;
} AviMux;

static HRESULT create_input_pin(AviMux*);

static inline AviMux* impl_from_BaseFilter(BaseFilter *filter)
{
    return CONTAINING_RECORD(filter, AviMux, filter);
}

static IPin* WINAPI AviMux_GetPin(BaseFilter *iface, int pos)
{
    AviMux *This = impl_from_BaseFilter(iface);

    TRACE("(%p)->(%d)\n", This, pos);

    if(pos == 0) {
        IPin_AddRef(&This->out->pin.pin.IPin_iface);
        return &This->out->pin.pin.IPin_iface;
    }else if(pos>0 && pos<=This->input_pin_no) {
        IPin_AddRef(&This->in[pos-1]->pin.pin.IPin_iface);
        return &This->in[pos-1]->pin.pin.IPin_iface;
    }

    return NULL;
}

static LONG WINAPI AviMux_GetPinCount(BaseFilter *iface)
{
    AviMux *This = impl_from_BaseFilter(iface);
    TRACE("(%p)\n", This);
    return This->input_pin_no+1;
}

static const BaseFilterFuncTable filter_func_table = {
    AviMux_GetPin,
    AviMux_GetPinCount
};

static inline AviMux* impl_from_IBaseFilter(IBaseFilter *iface)
{
    BaseFilter *filter = CONTAINING_RECORD(iface, BaseFilter, IBaseFilter_iface);
    return impl_from_BaseFilter(filter);
}

static HRESULT WINAPI AviMux_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppv)
{
    AviMux *This = impl_from_IBaseFilter(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);

    if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPersist) ||
            IsEqualIID(riid, &IID_IMediaFilter) || IsEqualIID(riid, &IID_IBaseFilter))
        *ppv = &This->filter.IBaseFilter_iface;
    else if(IsEqualIID(riid, &IID_IConfigAviMux))
        *ppv = &This->IConfigAviMux_iface;
    else if(IsEqualIID(riid, &IID_IConfigInterleaving))
        *ppv = &This->IConfigInterleaving_iface;
    else if(IsEqualIID(riid, &IID_IMediaSeeking))
        *ppv = &This->IMediaSeeking_iface;
    else if(IsEqualIID(riid, &IID_IPersistMediaPropertyBag))
        *ppv = &This->IPersistMediaPropertyBag_iface;
    else if(IsEqualIID(riid, &IID_ISpecifyPropertyPages))
        *ppv = &This->ISpecifyPropertyPages_iface;
    else {
        FIXME("no interface for %s\n", debugstr_guid(riid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI AviMux_Release(IBaseFilter *iface)
{
    AviMux *This = impl_from_IBaseFilter(iface);
    ULONG ref = BaseFilterImpl_Release(iface);

    TRACE("(%p) new refcount: %u\n", This, ref);

    if(!ref) {
        int i;

        BaseOutputPinImpl_Release(&This->out->pin.pin.IPin_iface);

        for(i=0; i<This->input_pin_no; i++) {
            IPin_Disconnect(&This->in[i]->pin.pin.IPin_iface);
            IMemAllocator_Release(This->in[i]->samples_allocator);
            This->in[i]->samples_allocator = NULL;
            BaseInputPinImpl_Release(&This->in[i]->pin.pin.IPin_iface);
        }

        HeapFree(GetProcessHeap(), 0, This->idx1);
        HeapFree(GetProcessHeap(), 0, This);
        ObjectRefCount(FALSE);
    }
    return ref;
}

static HRESULT out_flush(AviMux *This)
{
    ULONG written;
    HRESULT hr;

    if(!This->out->buf_pos)
        return S_OK;

    hr = IStream_Write(This->out->stream, This->out->buf, This->out->buf_pos, &written);
    if(FAILED(hr))
        return hr;
    if(written != This->out->buf_pos)
        return E_FAIL;

    This->out->buf_pos = 0;
    return S_OK;
}

static HRESULT out_seek(AviMux *This, int pos)
{
    LARGE_INTEGER li;
    HRESULT hr;

    hr = out_flush(This);
    if(FAILED(hr))
        return hr;

    li.QuadPart = pos;
    hr = IStream_Seek(This->out->stream, li, STREAM_SEEK_SET, NULL);
    if(FAILED(hr))
        return hr;

    This->out->out_pos = pos;
    if(This->out->out_pos > This->out->size)
        This->out->size = This->out->out_pos;
    return hr;
}

static HRESULT out_write(AviMux *This, const void *data, int size)
{
    int chunk_size;
    HRESULT hr;

    while(1) {
        if(size > sizeof(This->out->buf)-This->out->buf_pos)
            chunk_size = sizeof(This->out->buf)-This->out->buf_pos;
        else
            chunk_size = size;

        memcpy(This->out->buf + This->out->buf_pos, data, chunk_size);
        size -= chunk_size;
        data = (const BYTE*)data + chunk_size;
        This->out->buf_pos += chunk_size;
        This->out->out_pos += chunk_size;
        if(This->out->out_pos > This->out->size)
            This->out->size = This->out->out_pos;

        if(!size)
            break;
        hr = out_flush(This);
        if(FAILED(hr))
            return hr;
    }

    return S_OK;
}

static inline HRESULT idx1_add_entry(AviMux *avimux, DWORD ckid, DWORD flags, DWORD off, DWORD len)
{
    if(avimux->idx1_entries == avimux->idx1_size) {
        AVIINDEXENTRY *new_idx = HeapReAlloc(GetProcessHeap(), 0, avimux->idx1,
                sizeof(*avimux->idx1)*2*avimux->idx1_size);
        if(!new_idx)
            return E_OUTOFMEMORY;

        avimux->idx1_size *= 2;
        avimux->idx1 = new_idx;
    }

    avimux->idx1[avimux->idx1_entries].ckid = ckid;
    avimux->idx1[avimux->idx1_entries].dwFlags = flags;
    avimux->idx1[avimux->idx1_entries].dwChunkOffset = off;
    avimux->idx1[avimux->idx1_entries].dwChunkLength = len;
    avimux->idx1_entries++;
    return S_OK;
}

static HRESULT flush_queue(AviMux *avimux, AviMuxIn *avimuxin, BOOL closing)
{
    IMediaSample *sample, **prev, **head_prev;
    BYTE *data;
    RIFFCHUNK rf;
    DWORD size;
    DWORD flags;
    HRESULT hr;

    if(avimux->out->cur_stream != avimuxin->stream_id)
        return S_OK;

    while(avimuxin->samples_head) {
        hr = IMediaSample_GetPointer(avimuxin->samples_head, (BYTE**)&head_prev);
        if(FAILED(hr))
            return hr;
        head_prev--;

        hr = IMediaSample_GetPointer(*head_prev, (BYTE**)&prev);
        if(FAILED(hr))
            return hr;
        prev--;

        sample = *head_prev;
        size = IMediaSample_GetActualDataLength(sample);
        hr = IMediaSample_GetPointer(sample, &data);
        if(FAILED(hr))
            return hr;
        flags = IMediaSample_IsDiscontinuity(sample)==S_OK ? AM_SAMPLE_TIMEDISCONTINUITY : 0;
        if(IMediaSample_IsSyncPoint(sample) == S_OK)
            flags |= AM_SAMPLE_SPLICEPOINT;

        if(avimuxin->stream_time + (closing ? 0 : avimuxin->strh.dwScale) > avimux->out->cur_time &&
                !(flags & AM_SAMPLE_TIMEDISCONTINUITY)) {
            if(closing)
                break;

            avimux->out->cur_stream++;
            if(avimux->out->cur_stream >= avimux->input_pin_no-1) {
                avimux->out->cur_time += avimux->interleave;
                avimux->out->cur_stream = 0;
            }
            avimuxin = avimux->in[avimux->out->cur_stream];
            continue;
        }

        if(avimuxin->ix->nEntriesInUse == AVISTDINDEX_ENTRIES) {
            /* TODO: use output pins Deliver/Receive method */
            hr = out_seek(avimux, avimuxin->ix_off);
            if(FAILED(hr))
                return hr;
            hr = out_write(avimux, avimuxin->ix, sizeof(avimuxin->ix_data));
            if(FAILED(hr))
                return hr;

            avimuxin->indx->aIndex[avimuxin->indx->nEntriesInUse].qwOffset = avimuxin->ix_off;
            avimuxin->indx->aIndex[avimuxin->indx->nEntriesInUse].dwSize = sizeof(avimuxin->ix_data);
            avimuxin->indx->aIndex[avimuxin->indx->nEntriesInUse].dwDuration = AVISTDINDEX_ENTRIES;
            avimuxin->indx->nEntriesInUse++;

            memset(avimuxin->ix->aIndex, 0, sizeof(avimuxin->ix->aIndex)*avimuxin->ix->nEntriesInUse);
            avimuxin->ix->nEntriesInUse = 0;
            avimuxin->ix->qwBaseOffset = 0;

            avimuxin->ix_off = avimux->out->size;
            avimux->out->size += sizeof(avimuxin->ix_data);
        }

        if(*head_prev == avimuxin->samples_head)
            avimuxin->samples_head = NULL;
        else
            *head_prev = *prev;

        avimuxin->stream_time += avimuxin->strh.dwScale;
        avimuxin->strh.dwLength++;
        if(!(flags & AM_SAMPLE_TIMEDISCONTINUITY)) {
            if(!avimuxin->ix->qwBaseOffset)
                avimuxin->ix->qwBaseOffset = avimux->out->size;
            avimuxin->ix->aIndex[avimuxin->ix->nEntriesInUse].dwOffset = avimux->out->size
                + sizeof(RIFFCHUNK) - avimuxin->ix->qwBaseOffset;

            hr = out_seek(avimux, avimux->out->size);
            if(FAILED(hr)) {
                IMediaSample_Release(sample);
                return hr;
            }
        }
        avimuxin->ix->aIndex[avimuxin->ix->nEntriesInUse].dwSize = size |
            (flags & AM_SAMPLE_SPLICEPOINT ? 0 : AVISTDINDEX_DELTAFRAME);
        avimuxin->ix->nEntriesInUse++;

        rf.fcc = FCC('0'+avimuxin->stream_id/10, '0'+avimuxin->stream_id%10,
                'd', flags & AM_SAMPLE_SPLICEPOINT ? 'b' : 'c');
        rf.cb = size;
        hr = idx1_add_entry(avimux, rf.fcc, flags & AM_SAMPLE_SPLICEPOINT ? AVIIF_KEYFRAME : 0,
                flags & AM_SAMPLE_TIMEDISCONTINUITY ?
                avimux->idx1[avimux->idx1_entries-1].dwChunkOffset : avimux->out->size, size);
        if(FAILED(hr)) {
            IMediaSample_Release(sample);
            return hr;
        }

        if(!(flags & AM_SAMPLE_TIMEDISCONTINUITY)) {
            hr = out_write(avimux, &rf, sizeof(rf));
            if(FAILED(hr)) {
                IMediaSample_Release(sample);
                return hr;
            }
            hr = out_write(avimux, data, size);
            if(FAILED(hr)) {
                IMediaSample_Release(sample);
                return hr;
            }
            flags = 0;
            hr = out_write(avimux, &flags, ALIGN(rf.cb)-rf.cb);
            if(FAILED(hr)) {
                IMediaSample_Release(sample);
                return hr;
            }
        }
        IMediaSample_Release(sample);
    }
    return S_OK;
}

static HRESULT queue_sample(AviMux *avimux, AviMuxIn *avimuxin, IMediaSample *sample)
{
    IMediaSample **prev, **head_prev;
    HRESULT hr;

    hr = IMediaSample_GetPointer(sample, (BYTE**)&prev);
    if(FAILED(hr))
        return hr;
    prev--;

    if(avimuxin->samples_head) {
        hr = IMediaSample_GetPointer(avimuxin->samples_head, (BYTE**)&head_prev);
        if(FAILED(hr))
            return hr;
        head_prev--;

        *prev = *head_prev;
        *head_prev = sample;
    }else {
        *prev = sample;
    }
    avimuxin->samples_head = sample;
    IMediaSample_AddRef(sample);

    return flush_queue(avimux, avimuxin, FALSE);
}

static HRESULT WINAPI AviMux_Stop(IBaseFilter *iface)
{
    AviMux *This = impl_from_IBaseFilter(iface);
    HRESULT hr;
    int i;

    TRACE("(%p)\n", This);

    if(This->filter.state == State_Stopped)
        return S_OK;

    if(This->out->stream) {
        AVIEXTHEADER dmlh;
        RIFFCHUNK rc;
        RIFFLIST rl;
        int idx1_off, empty_stream;

        empty_stream = This->out->cur_stream;
        for(i=empty_stream+1; ; i++) {
            if(i >= This->input_pin_no-1)
                i = 0;
            if(i == empty_stream)
                break;

            This->out->cur_stream = i;
            hr = flush_queue(This, This->in[This->out->cur_stream], TRUE);
            if(FAILED(hr))
                return hr;
        }

        idx1_off = This->out->size;
        rc.fcc = ckidAVIOLDINDEX;
        rc.cb = This->idx1_entries * sizeof(*This->idx1);
        hr = out_write(This, &rc, sizeof(rc));
        if(FAILED(hr))
            return hr;
        hr = out_write(This, This->idx1, This->idx1_entries * sizeof(*This->idx1));
        if(FAILED(hr))
            return hr;
        /* native writes 8 '\0' characters after the end of RIFF data */
        i = 0;
        hr = out_write(This, &i, sizeof(i));
        if(FAILED(hr))
            return hr;
        hr = out_write(This, &i, sizeof(i));
        if(FAILED(hr))
            return hr;

        for(i=0; i<This->input_pin_no; i++) {
            if(!This->in[i]->pin.pin.pConnectedTo)
                continue;

            hr = out_seek(This, This->in[i]->ix_off);
            if(FAILED(hr))
                return hr;

            This->in[i]->indx->aIndex[This->in[i]->indx->nEntriesInUse].qwOffset = This->in[i]->ix_off;
            This->in[i]->indx->aIndex[This->in[i]->indx->nEntriesInUse].dwSize = sizeof(This->in[i]->ix_data);
            This->in[i]->indx->aIndex[This->in[i]->indx->nEntriesInUse].dwDuration = This->in[i]->strh.dwLength;
            if(This->in[i]->indx->nEntriesInUse) {
                This->in[i]->indx->aIndex[This->in[i]->indx->nEntriesInUse].dwDuration -=
                    This->in[i]->indx->aIndex[This->in[i]->indx->nEntriesInUse-1].dwDuration;
            }
            This->in[i]->indx->nEntriesInUse++;
            hr = out_write(This, This->in[i]->ix, sizeof(This->in[i]->ix_data));
            if(FAILED(hr))
                return hr;
        }

        hr = out_seek(This, 0);
        if(FAILED(hr))
            return hr;

        rl.fcc = FCC('R','I','F','F');
        rl.cb = This->out->size-sizeof(RIFFCHUNK)-2*sizeof(int);
        rl.fccListType = FCC('A','V','I',' ');
        hr = out_write(This, &rl, sizeof(rl));
        if(FAILED(hr))
            return hr;

        rl.fcc = FCC('L','I','S','T');
        rl.cb = This->out->movi_off - sizeof(RIFFLIST) - sizeof(RIFFCHUNK);
        rl.fccListType = FCC('h','d','r','l');
        hr = out_write(This, &rl, sizeof(rl));
        if(FAILED(hr))
            return hr;

        /* FIXME: set This->avih.dwMaxBytesPerSec value */
        This->avih.dwTotalFrames = (This->stop-This->start) / 10 / This->avih.dwMicroSecPerFrame;
        hr = out_write(This, &This->avih, sizeof(This->avih));
        if(FAILED(hr))
            return hr;

        for(i=0; i<This->input_pin_no; i++) {
            if(!This->in[i]->pin.pin.pConnectedTo)
                continue;

            rl.cb = sizeof(FOURCC) + sizeof(AVISTREAMHEADER) + sizeof(RIFFCHUNK) +
                This->in[i]->strf->cb + sizeof(This->in[i]->indx_data);
            rl.fccListType = ckidSTREAMLIST;
            hr = out_write(This, &rl, sizeof(rl));
            if(FAILED(hr))
                return hr;

            hr = out_write(This, &This->in[i]->strh, sizeof(AVISTREAMHEADER));
            if(FAILED(hr))
                return hr;

            hr = out_write(This, This->in[i]->strf, sizeof(RIFFCHUNK) + This->in[i]->strf->cb);
            if(FAILED(hr))
                return hr;

            hr = out_write(This, This->in[i]->indx, sizeof(This->in[i]->indx_data));
            if(FAILED(hr))
                return hr;
        }

        rl.cb = sizeof(dmlh) + sizeof(FOURCC);
        rl.fccListType = ckidODML;
        hr = out_write(This, &rl, sizeof(rl));
        if(FAILED(hr))
            return hr;

        memset(&dmlh, 0, sizeof(dmlh));
        dmlh.fcc = ckidAVIEXTHEADER;
        dmlh.cb = sizeof(dmlh) - sizeof(RIFFCHUNK);
        dmlh.dwGrandFrames = This->in[0]->strh.dwLength;
        hr = out_write(This, &dmlh, sizeof(dmlh));

        rl.cb = idx1_off - This->out->movi_off - sizeof(RIFFCHUNK);
        rl.fccListType = FCC('m','o','v','i');
        out_write(This, &rl, sizeof(rl));
        out_flush(This);

        IStream_Release(This->out->stream);
        This->out->stream = NULL;
    }

    This->filter.state = State_Stopped;
    return S_OK;
}

static HRESULT WINAPI AviMux_Pause(IBaseFilter *iface)
{
    AviMux *This = impl_from_IBaseFilter(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI AviMux_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
{
    AviMux *This = impl_from_IBaseFilter(iface);
    HRESULT hr;
    int i, stream_id;

    TRACE("(%p)->(0x%x%08x)\n", This, (ULONG)(tStart >> 32), (ULONG)tStart);

    if(This->filter.state == State_Running)
        return S_OK;

    if(This->mode != INTERLEAVE_FULL) {
        FIXME("mode not supported (%d)\n", This->mode);
        return E_NOTIMPL;
    }

    if(tStart)
        FIXME("tStart parameter ignored\n");

    for(i=0; i<This->input_pin_no; i++) {
        IMediaSeeking *ms;
        LONGLONG cur, stop;

        if(!This->in[i]->pin.pin.pConnectedTo)
            continue;

        hr = IPin_QueryInterface(This->in[i]->pin.pin.pConnectedTo,
                &IID_IMediaSeeking, (void**)&ms);
        if(FAILED(hr))
            continue;

        hr = IMediaSeeking_GetPositions(ms, &cur, &stop);
        if(FAILED(hr)) {
            IMediaSeeking_Release(ms);
            continue;
        }

        FIXME("Use IMediaSeeking to fill stream header\n");
        IMediaSeeking_Release(ms);
    }

    if(This->out->pin.pMemInputPin) {
        hr = IMemInputPin_QueryInterface(This->out->pin.pMemInputPin,
                &IID_IStream, (void**)&This->out->stream);
        if(FAILED(hr))
            return hr;
    }

    This->idx1_entries = 0;
    if(!This->idx1_size) {
        This->idx1_size = 1024;
        This->idx1 = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->idx1)*This->idx1_size);
        if(!This->idx1)
            return E_OUTOFMEMORY;
    }

    This->out->size = 3*sizeof(RIFFLIST) + sizeof(AVIMAINHEADER) + sizeof(AVIEXTHEADER);
    This->start = -1;
    This->stop = -1;
    memset(&This->avih, 0, sizeof(This->avih));
    for(i=0; i<This->input_pin_no; i++) {
        if(!This->in[i]->pin.pin.pConnectedTo)
            continue;

        This->avih.dwStreams++;
        This->out->size += sizeof(RIFFLIST) + sizeof(AVISTREAMHEADER) + sizeof(RIFFCHUNK)
            + This->in[i]->strf->cb + sizeof(This->in[i]->indx_data);

        This->in[i]->strh.dwScale = MulDiv(This->in[i]->avg_time_per_frame, This->interleave, 10000000);
        This->in[i]->strh.dwRate = This->interleave;

        hr = IMemAllocator_Commit(This->in[i]->pin.pAllocator);
        if(FAILED(hr)) {
            if(This->out->stream) {
                IStream_Release(This->out->stream);
                This->out->stream = NULL;
            }
            return hr;
        }
    }

    This->out->movi_off = This->out->size;
    This->out->size += sizeof(RIFFLIST);

    idx1_add_entry(This, FCC('7','F','x','x'), 0, This->out->movi_off+sizeof(RIFFLIST), 0);

    stream_id = 0;
    for(i=0; i<This->input_pin_no; i++) {
        if(!This->in[i]->pin.pin.pConnectedTo)
            continue;

        This->in[i]->ix_off = This->out->size;
        This->out->size += sizeof(This->in[i]->ix_data);
        This->in[i]->ix->fcc = FCC('i','x','0'+stream_id/10,'0'+stream_id%10);
        This->in[i]->ix->cb = sizeof(This->in[i]->ix_data) - sizeof(RIFFCHUNK);
        This->in[i]->ix->wLongsPerEntry = 2;
        This->in[i]->ix->bIndexSubType = 0;
        This->in[i]->ix->bIndexType = AVI_INDEX_OF_CHUNKS;
        This->in[i]->ix->dwChunkId = FCC('0'+stream_id/10,'0'+stream_id%10,'d','b');
        This->in[i]->ix->qwBaseOffset = 0;

        This->in[i]->indx->fcc = ckidAVISUPERINDEX;
        This->in[i]->indx->cb = sizeof(This->in[i]->indx_data) - sizeof(RIFFCHUNK);
        This->in[i]->indx->wLongsPerEntry = 4;
        This->in[i]->indx->bIndexSubType = 0;
        This->in[i]->indx->bIndexType = AVI_INDEX_OF_INDEXES;
        This->in[i]->indx->dwChunkId = This->in[i]->ix->dwChunkId;
        This->in[i]->stream_id = stream_id++;
    }

    This->out->buf_pos = 0;
    This->out->out_pos = 0;

    This->avih.fcc = ckidMAINAVIHEADER;
    This->avih.cb = sizeof(AVIMAINHEADER) - sizeof(RIFFCHUNK);
    /* TODO: Use first video stream */
    This->avih.dwMicroSecPerFrame = This->in[0]->avg_time_per_frame/10;
    This->avih.dwPaddingGranularity = 1;
    This->avih.dwFlags = AVIF_TRUSTCKTYPE | AVIF_HASINDEX;
    This->avih.dwWidth = ((BITMAPINFOHEADER*)This->in[0]->strf->data)->biWidth;
    This->avih.dwHeight = ((BITMAPINFOHEADER*)This->in[0]->strf->data)->biHeight;

    This->filter.state = State_Running;
    return S_OK;
}

static HRESULT WINAPI AviMux_EnumPins(IBaseFilter *iface, IEnumPins **ppEnum)
{
    AviMux *This = impl_from_IBaseFilter(iface);
    TRACE("(%p)->(%p)\n", This, ppEnum);
    return BaseFilterImpl_EnumPins(iface, ppEnum);
}

static HRESULT WINAPI AviMux_FindPin(IBaseFilter *iface, LPCWSTR Id, IPin **ppPin)
{
    AviMux *This = impl_from_IBaseFilter(iface);
    int i;

    TRACE("(%p)->(%s %p)\n", This, debugstr_w(Id), ppPin);

    if(!Id || !ppPin)
        return E_POINTER;

    if(!lstrcmpiW(Id, This->out->pin.pin.pinInfo.achName)) {
        IPin_AddRef(&This->out->pin.pin.IPin_iface);
        *ppPin = &This->out->pin.pin.IPin_iface;
        return S_OK;
    }

    for(i=0; i<This->input_pin_no; i++) {
        if(lstrcmpiW(Id, This->in[i]->pin.pin.pinInfo.achName))
            continue;

        IPin_AddRef(&This->in[i]->pin.pin.IPin_iface);
        *ppPin = &This->in[i]->pin.pin.IPin_iface;
        return S_OK;
    }

    return VFW_E_NOT_FOUND;
}

static HRESULT WINAPI AviMux_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *pInfo)
{
    AviMux *This = impl_from_IBaseFilter(iface);
    FIXME("(%p)->(%p)\n", This, pInfo);
    return E_NOTIMPL;
}

static HRESULT WINAPI AviMux_QueryVendorInfo(IBaseFilter *iface, LPWSTR *pVendorInfo)
{
    AviMux *This = impl_from_IBaseFilter(iface);
    FIXME("(%p)->(%p)\n", This, pVendorInfo);
    return E_NOTIMPL;
}

static const IBaseFilterVtbl AviMuxVtbl = {
    AviMux_QueryInterface,
    BaseFilterImpl_AddRef,
    AviMux_Release,
    BaseFilterImpl_GetClassID,
    AviMux_Stop,
    AviMux_Pause,
    AviMux_Run,
    BaseFilterImpl_GetState,
    BaseFilterImpl_SetSyncSource,
    BaseFilterImpl_GetSyncSource,
    AviMux_EnumPins,
    AviMux_FindPin,
    AviMux_QueryFilterInfo,
    BaseFilterImpl_JoinFilterGraph,
    AviMux_QueryVendorInfo
};

static inline AviMux* impl_from_IConfigAviMux(IConfigAviMux *iface)
{
    return CONTAINING_RECORD(iface, AviMux, IConfigAviMux_iface);
}

static HRESULT WINAPI ConfigAviMux_QueryInterface(
        IConfigAviMux *iface, REFIID riid, void **ppv)
{
    AviMux *This = impl_from_IConfigAviMux(iface);
    return IBaseFilter_QueryInterface(&This->filter.IBaseFilter_iface, riid, ppv);
}

static ULONG WINAPI ConfigAviMux_AddRef(IConfigAviMux *iface)
{
    AviMux *This = impl_from_IConfigAviMux(iface);
    return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
}

static ULONG WINAPI ConfigAviMux_Release(IConfigAviMux *iface)
{
    AviMux *This = impl_from_IConfigAviMux(iface);
    return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
}

static HRESULT WINAPI ConfigAviMux_SetMasterStream(IConfigAviMux *iface, LONG iStream)
{
    AviMux *This = impl_from_IConfigAviMux(iface);
    FIXME("(%p)->(%d)\n", This, iStream);
    return E_NOTIMPL;
}

static HRESULT WINAPI ConfigAviMux_GetMasterStream(IConfigAviMux *iface, LONG *pStream)
{
    AviMux *This = impl_from_IConfigAviMux(iface);
    FIXME("(%p)->(%p)\n", This, pStream);
    return E_NOTIMPL;
}

static HRESULT WINAPI ConfigAviMux_SetOutputCompatibilityIndex(
        IConfigAviMux *iface, BOOL fOldIndex)
{
    AviMux *This = impl_from_IConfigAviMux(iface);
    FIXME("(%p)->(%x)\n", This, fOldIndex);
    return E_NOTIMPL;
}

static HRESULT WINAPI ConfigAviMux_GetOutputCompatibilityIndex(
        IConfigAviMux *iface, BOOL *pfOldIndex)
{
    AviMux *This = impl_from_IConfigAviMux(iface);
    FIXME("(%p)->(%p)\n", This, pfOldIndex);
    return E_NOTIMPL;
}

static const IConfigAviMuxVtbl ConfigAviMuxVtbl = {
    ConfigAviMux_QueryInterface,
    ConfigAviMux_AddRef,
    ConfigAviMux_Release,
    ConfigAviMux_SetMasterStream,
    ConfigAviMux_GetMasterStream,
    ConfigAviMux_SetOutputCompatibilityIndex,
    ConfigAviMux_GetOutputCompatibilityIndex
};

static inline AviMux* impl_from_IConfigInterleaving(IConfigInterleaving *iface)
{
    return CONTAINING_RECORD(iface, AviMux, IConfigInterleaving_iface);
}

static HRESULT WINAPI ConfigInterleaving_QueryInterface(
        IConfigInterleaving *iface, REFIID riid, void **ppv)
{
    AviMux *This = impl_from_IConfigInterleaving(iface);
    return IBaseFilter_QueryInterface(&This->filter.IBaseFilter_iface, riid, ppv);
}

static ULONG WINAPI ConfigInterleaving_AddRef(IConfigInterleaving *iface)
{
    AviMux *This = impl_from_IConfigInterleaving(iface);
    return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
}

static ULONG WINAPI ConfigInterleaving_Release(IConfigInterleaving *iface)
{
    AviMux *This = impl_from_IConfigInterleaving(iface);
    return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
}

static HRESULT WINAPI ConfigInterleaving_put_Mode(
        IConfigInterleaving *iface, InterleavingMode mode)
{
    AviMux *This = impl_from_IConfigInterleaving(iface);

    TRACE("(%p)->(%d)\n", This, mode);

    if(mode>INTERLEAVE_NONE_BUFFERED)
        return E_INVALIDARG;

    if(This->mode != mode) {
        if(This->out->pin.pin.pConnectedTo) {
            HRESULT hr = IFilterGraph_Reconnect(This->filter.filterInfo.pGraph,
                    &This->out->pin.pin.IPin_iface);
            if(FAILED(hr))
                return hr;
        }

        This->mode = mode;
    }

    return S_OK;
}

static HRESULT WINAPI ConfigInterleaving_get_Mode(
        IConfigInterleaving *iface, InterleavingMode *pMode)
{
    AviMux *This = impl_from_IConfigInterleaving(iface);
    FIXME("(%p)->(%p)\n", This, pMode);
    return E_NOTIMPL;
}

static HRESULT WINAPI ConfigInterleaving_put_Interleaving(IConfigInterleaving *iface,
        const REFERENCE_TIME *prtInterleave, const REFERENCE_TIME *prtPreroll)
{
    AviMux *This = impl_from_IConfigInterleaving(iface);

    TRACE("(%p)->(%p %p)\n", This, prtInterleave, prtPreroll);

    if(prtInterleave)
        This->interleave = *prtInterleave;
    if(prtPreroll)
        This->preroll = *prtPreroll;
    return S_OK;
}

static HRESULT WINAPI ConfigInterleaving_get_Interleaving(IConfigInterleaving *iface,
        REFERENCE_TIME *prtInterleave, REFERENCE_TIME *prtPreroll)
{
    AviMux *This = impl_from_IConfigInterleaving(iface);
    FIXME("(%p)->(%p %p)\n", This, prtInterleave, prtPreroll);
    return E_NOTIMPL;
}

static const IConfigInterleavingVtbl ConfigInterleavingVtbl = {
    ConfigInterleaving_QueryInterface,
    ConfigInterleaving_AddRef,
    ConfigInterleaving_Release,
    ConfigInterleaving_put_Mode,
    ConfigInterleaving_get_Mode,
    ConfigInterleaving_put_Interleaving,
    ConfigInterleaving_get_Interleaving
};

static inline AviMux* impl_from_IMediaSeeking(IMediaSeeking *iface)
{
    return CONTAINING_RECORD(iface, AviMux, IMediaSeeking_iface);
}

static HRESULT WINAPI MediaSeeking_QueryInterface(
        IMediaSeeking *iface, REFIID riid, void **ppv)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    return IBaseFilter_QueryInterface(&This->filter.IBaseFilter_iface, riid, ppv);
}

static ULONG WINAPI MediaSeeking_AddRef(IMediaSeeking *iface)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
}

static ULONG WINAPI MediaSeeking_Release(IMediaSeeking *iface)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
}

static HRESULT WINAPI MediaSeeking_GetCapabilities(
        IMediaSeeking *iface, DWORD *pCapabilities)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%p)\n", This, pCapabilities);
    return E_NOTIMPL;
}

static HRESULT WINAPI MediaSeeking_CheckCapabilities(
        IMediaSeeking *iface, DWORD *pCapabilities)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%p)\n", This, pCapabilities);
    return E_NOTIMPL;
}

static HRESULT WINAPI MediaSeeking_IsFormatSupported(
        IMediaSeeking *iface, const GUID *pFormat)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_guid(pFormat));
    return E_NOTIMPL;
}

static HRESULT WINAPI MediaSeeking_QueryPreferredFormat(
        IMediaSeeking *iface, GUID *pFormat)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%p)\n", This, pFormat);
    return E_NOTIMPL;
}

static HRESULT WINAPI MediaSeeking_GetTimeFormat(
        IMediaSeeking *iface, GUID *pFormat)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%p)\n", This, pFormat);
    return E_NOTIMPL;
}

static HRESULT WINAPI MediaSeeking_IsUsingTimeFormat(
        IMediaSeeking *iface, const GUID *pFormat)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_guid(pFormat));
    return E_NOTIMPL;
}

static HRESULT WINAPI MediaSeeking_SetTimeFormat(
        IMediaSeeking *iface, const GUID *pFormat)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_guid(pFormat));
    return E_NOTIMPL;
}

static HRESULT WINAPI MediaSeeking_GetDuration(
        IMediaSeeking *iface, LONGLONG *pDuration)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%p)\n", This, pDuration);
    return E_NOTIMPL;
}

static HRESULT WINAPI MediaSeeking_GetStopPosition(
        IMediaSeeking *iface, LONGLONG *pStop)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%p)\n", This, pStop);
    return E_NOTIMPL;
}

static HRESULT WINAPI MediaSeeking_GetCurrentPosition(
        IMediaSeeking *iface, LONGLONG *pCurrent)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%p)\n", This, pCurrent);
    return E_NOTIMPL;
}

static HRESULT WINAPI MediaSeeking_ConvertTimeFormat(IMediaSeeking *iface, LONGLONG *pTarget,
        const GUID *pTargetFormat, LONGLONG Source, const GUID *pSourceFormat)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%p %s %s %s)\n", This, pTarget, debugstr_guid(pTargetFormat),
            wine_dbgstr_longlong(Source), debugstr_guid(pSourceFormat));
    return E_NOTIMPL;
}

static HRESULT WINAPI MediaSeeking_SetPositions(IMediaSeeking *iface, LONGLONG *pCurrent,
        DWORD dwCurrentFlags, LONGLONG *pStop, DWORD dwStopFlags)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%p %x %p %x)\n", This, pCurrent, dwCurrentFlags, pStop, dwStopFlags);
    return E_NOTIMPL;
}

static HRESULT WINAPI MediaSeeking_GetPositions(IMediaSeeking *iface,
        LONGLONG *pCurrent, LONGLONG *pStop)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%p %p)\n", This, pCurrent, pStop);
    return E_NOTIMPL;
}

static HRESULT WINAPI MediaSeeking_GetAvailable(IMediaSeeking *iface,
        LONGLONG *pEarliest, LONGLONG *pLatest)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%p %p)\n", This, pEarliest, pLatest);
    return E_NOTIMPL;
}

static HRESULT WINAPI MediaSeeking_SetRate(IMediaSeeking *iface, double dRate)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%lf)\n", This, dRate);
    return E_NOTIMPL;
}

static HRESULT WINAPI MediaSeeking_GetRate(IMediaSeeking *iface, double *pdRate)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%p)\n", This, pdRate);
    return E_NOTIMPL;
}

static HRESULT WINAPI MediaSeeking_GetPreroll(IMediaSeeking *iface, LONGLONG *pllPreroll)
{
    AviMux *This = impl_from_IMediaSeeking(iface);
    FIXME("(%p)->(%p)\n", This, pllPreroll);
    return E_NOTIMPL;
}

static const IMediaSeekingVtbl MediaSeekingVtbl = {
    MediaSeeking_QueryInterface,
    MediaSeeking_AddRef,
    MediaSeeking_Release,
    MediaSeeking_GetCapabilities,
    MediaSeeking_CheckCapabilities,
    MediaSeeking_IsFormatSupported,
    MediaSeeking_QueryPreferredFormat,
    MediaSeeking_GetTimeFormat,
    MediaSeeking_IsUsingTimeFormat,
    MediaSeeking_SetTimeFormat,
    MediaSeeking_GetDuration,
    MediaSeeking_GetStopPosition,
    MediaSeeking_GetCurrentPosition,
    MediaSeeking_ConvertTimeFormat,
    MediaSeeking_SetPositions,
    MediaSeeking_GetPositions,
    MediaSeeking_GetAvailable,
    MediaSeeking_SetRate,
    MediaSeeking_GetRate,
    MediaSeeking_GetPreroll
};

static inline AviMux* impl_from_IPersistMediaPropertyBag(IPersistMediaPropertyBag *iface)
{
    return CONTAINING_RECORD(iface, AviMux, IPersistMediaPropertyBag_iface);
}

static HRESULT WINAPI PersistMediaPropertyBag_QueryInterface(
        IPersistMediaPropertyBag *iface, REFIID riid, void **ppv)
{
    AviMux *This = impl_from_IPersistMediaPropertyBag(iface);
    return IBaseFilter_QueryInterface(&This->filter.IBaseFilter_iface, riid, ppv);
}

static ULONG WINAPI PersistMediaPropertyBag_AddRef(IPersistMediaPropertyBag *iface)
{
    AviMux *This = impl_from_IPersistMediaPropertyBag(iface);
    return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
}

static ULONG WINAPI PersistMediaPropertyBag_Release(IPersistMediaPropertyBag *iface)
{
    AviMux *This = impl_from_IPersistMediaPropertyBag(iface);
    return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
}

static HRESULT WINAPI PersistMediaPropertyBag_GetClassID(
        IPersistMediaPropertyBag *iface, CLSID *pClassID)
{
    AviMux *This = impl_from_IPersistMediaPropertyBag(iface);
    return IBaseFilter_GetClassID(&This->filter.IBaseFilter_iface, pClassID);
}

static HRESULT WINAPI PersistMediaPropertyBag_InitNew(IPersistMediaPropertyBag *iface)
{
    AviMux *This = impl_from_IPersistMediaPropertyBag(iface);
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI PersistMediaPropertyBag_Load(IPersistMediaPropertyBag *iface,
        IMediaPropertyBag *pPropBag, IErrorLog *pErrorLog)
{
    AviMux *This = impl_from_IPersistMediaPropertyBag(iface);
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI PersistMediaPropertyBag_Save(IPersistMediaPropertyBag *iface,
        IMediaPropertyBag *pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties)
{
    AviMux *This = impl_from_IPersistMediaPropertyBag(iface);
    FIXME("(%p)->()\n", This);
    return E_NOTIMPL;
}

static const IPersistMediaPropertyBagVtbl PersistMediaPropertyBagVtbl = {
    PersistMediaPropertyBag_QueryInterface,
    PersistMediaPropertyBag_AddRef,
    PersistMediaPropertyBag_Release,
    PersistMediaPropertyBag_GetClassID,
    PersistMediaPropertyBag_InitNew,
    PersistMediaPropertyBag_Load,
    PersistMediaPropertyBag_Save
};

static inline AviMux* impl_from_ISpecifyPropertyPages(ISpecifyPropertyPages *iface)
{
    return CONTAINING_RECORD(iface, AviMux, ISpecifyPropertyPages_iface);
}

static HRESULT WINAPI SpecifyPropertyPages_QueryInterface(
        ISpecifyPropertyPages *iface, REFIID riid, void **ppv)
{
    AviMux *This = impl_from_ISpecifyPropertyPages(iface);
    return IBaseFilter_QueryInterface(&This->filter.IBaseFilter_iface, riid, ppv);
}

static ULONG WINAPI SpecifyPropertyPages_AddRef(ISpecifyPropertyPages *iface)
{
    AviMux *This = impl_from_ISpecifyPropertyPages(iface);
    return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
}

static ULONG WINAPI SpecifyPropertyPages_Release(ISpecifyPropertyPages *iface)
{
    AviMux *This = impl_from_ISpecifyPropertyPages(iface);
    return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
}

static HRESULT WINAPI SpecifyPropertyPages_GetPages(
        ISpecifyPropertyPages *iface, CAUUID *pPages)
{
    AviMux *This = impl_from_ISpecifyPropertyPages(iface);
    FIXME("(%p)->(%p)\n", This, pPages);
    return E_NOTIMPL;
}

static const ISpecifyPropertyPagesVtbl SpecifyPropertyPagesVtbl = {
    SpecifyPropertyPages_QueryInterface,
    SpecifyPropertyPages_AddRef,
    SpecifyPropertyPages_Release,
    SpecifyPropertyPages_GetPages
};

static HRESULT WINAPI AviMuxOut_AttemptConnection(BasePin *base,
        IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
{
    PIN_DIRECTION dir;
    HRESULT hr;

    TRACE("(%p)->(%p AM_MEDIA_TYPE(%p))\n", base, pReceivePin, pmt);
    dump_AM_MEDIA_TYPE(pmt);

    hr = IPin_QueryDirection(pReceivePin, &dir);
    if(hr==S_OK && dir!=PINDIR_INPUT)
        return VFW_E_INVALID_DIRECTION;

    return BaseOutputPinImpl_AttemptConnection(base, pReceivePin, pmt);
}

static LONG WINAPI AviMuxOut_GetMediaTypeVersion(BasePin *base)
{
    return 0;
}

static HRESULT WINAPI AviMuxOut_GetMediaType(BasePin *base, int iPosition, AM_MEDIA_TYPE *amt)
{
    TRACE("(%p)->(%d %p)\n", base, iPosition, amt);

    if(iPosition < 0)
        return E_INVALIDARG;
    if(iPosition > 0)
        return VFW_S_NO_MORE_ITEMS;

    amt->majortype = MEDIATYPE_Stream;
    amt->subtype = MEDIASUBTYPE_Avi;
    amt->bFixedSizeSamples = TRUE;
    amt->bTemporalCompression = FALSE;
    amt->lSampleSize = 1;
    amt->formattype = GUID_NULL;
    amt->pUnk = NULL;
    amt->cbFormat = 0;
    amt->pbFormat = NULL;
    return S_OK;
}

static HRESULT WINAPI AviMuxOut_DecideAllocator(BaseOutputPin *base,
        IMemInputPin *pPin, IMemAllocator **pAlloc)
{
    ALLOCATOR_PROPERTIES req, actual;
    HRESULT hr;

    TRACE("(%p)->(%p %p)\n", base, pPin, pAlloc);

    hr = BaseOutputPinImpl_InitAllocator(base, pAlloc);
    if(FAILED(hr))
        return hr;

    hr = IMemInputPin_GetAllocatorRequirements(pPin, &req);
    if(FAILED(hr))
        req.cbAlign = 1;
    req.cBuffers = 32;
    req.cbBuffer = 0;
    req.cbPrefix = 0;

    hr = IMemAllocator_SetProperties(*pAlloc, &req, &actual);
    if(FAILED(hr))
        return hr;

    return IMemInputPin_NotifyAllocator(pPin, *pAlloc, TRUE);
}

static HRESULT WINAPI AviMuxOut_BreakConnect(BaseOutputPin *base)
{
    FIXME("(%p)\n", base);
    return E_NOTIMPL;
}

static const BaseOutputPinFuncTable AviMuxOut_BaseOutputFuncTable = {
    {
        NULL,
        AviMuxOut_AttemptConnection,
        AviMuxOut_GetMediaTypeVersion,
        AviMuxOut_GetMediaType
    },
    NULL,
    AviMuxOut_DecideAllocator,
    AviMuxOut_BreakConnect
};

static inline AviMux* impl_from_out_IPin(IPin *iface)
{
    BasePin *bp = CONTAINING_RECORD(iface, BasePin, IPin_iface);
    IBaseFilter *bf = bp->pinInfo.pFilter;

    return impl_from_IBaseFilter(bf);
}

static HRESULT WINAPI AviMuxOut_QueryInterface(IPin *iface, REFIID riid, void **ppv)
{
    AviMux *This = impl_from_out_IPin(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);

    if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPin))
        *ppv = iface;
    else if(IsEqualIID(riid, &IID_IQualityControl))
        *ppv = &This->out->IQualityControl_iface;
    else {
        FIXME("no interface for %s\n", debugstr_guid(riid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI AviMuxOut_AddRef(IPin *iface)
{
    AviMux *This = impl_from_out_IPin(iface);
    return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
}

static ULONG WINAPI AviMuxOut_Release(IPin *iface)
{
    AviMux *This = impl_from_out_IPin(iface);
    return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
}

static HRESULT WINAPI AviMuxOut_Connect(IPin *iface,
        IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
{
    AviMux *This = impl_from_out_IPin(iface);
    HRESULT hr;
    int i;

    TRACE("(%p)->(%p AM_MEDIA_TYPE(%p))\n", This, pReceivePin, pmt);
    dump_AM_MEDIA_TYPE(pmt);

    hr = BaseOutputPinImpl_Connect(iface, pReceivePin, pmt);
    if(FAILED(hr))
        return hr;

    for(i=0; i<This->input_pin_no; i++) {
        if(!This->in[i]->pin.pin.pConnectedTo)
            continue;

        hr = IFilterGraph_Reconnect(This->filter.filterInfo.pGraph, &This->in[i]->pin.pin.IPin_iface);
        if(FAILED(hr)) {
            BaseOutputPinImpl_Disconnect(iface);
            break;
        }
    }

    if(hr == S_OK)
        IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
    return hr;
}

static HRESULT WINAPI AviMuxOut_ReceiveConnection(IPin *iface,
        IPin *pConnector, const AM_MEDIA_TYPE *pmt)
{
    AviMux *This = impl_from_out_IPin(iface);
    TRACE("(%p)->(%p AM_MEDIA_TYPE(%p)\n", This, pConnector, pmt);
    dump_AM_MEDIA_TYPE(pmt);
    return BaseOutputPinImpl_ReceiveConnection(iface, pConnector, pmt);
}

static HRESULT WINAPI AviMuxOut_Disconnect(IPin *iface)
{
    AviMux *This = impl_from_out_IPin(iface);
    HRESULT hr;

    TRACE("(%p)\n", This);

    hr = BaseOutputPinImpl_Disconnect(iface);
    if(hr == S_OK)
        IBaseFilter_Release(&This->filter.IBaseFilter_iface);
    return hr;
}

static HRESULT WINAPI AviMuxOut_ConnectedTo(IPin *iface, IPin **pPin)
{
    AviMux *This = impl_from_out_IPin(iface);
    TRACE("(%p)->(%p)\n", This, pPin);
    return BasePinImpl_ConnectedTo(iface, pPin);
}

static HRESULT WINAPI AviMuxOut_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *pmt)
{
    AviMux *This = impl_from_out_IPin(iface);
    TRACE("(%p)->(%p)\n", This, pmt);
    return BasePinImpl_ConnectionMediaType(iface, pmt);
}

static HRESULT WINAPI AviMuxOut_QueryPinInfo(IPin *iface, PIN_INFO *pInfo)
{
    AviMux *This = impl_from_out_IPin(iface);
    TRACE("(%p)->(%p)\n", This, pInfo);
    return BasePinImpl_QueryPinInfo(iface, pInfo);
}

static HRESULT WINAPI AviMuxOut_QueryDirection(IPin *iface, PIN_DIRECTION *pPinDir)
{
    AviMux *This = impl_from_out_IPin(iface);
    TRACE("(%p)->(%p)\n", This, pPinDir);
    return BasePinImpl_QueryDirection(iface, pPinDir);
}

static HRESULT WINAPI AviMuxOut_QueryId(IPin *iface, LPWSTR *Id)
{
    AviMux *This = impl_from_out_IPin(iface);
    TRACE("(%p)->(%p)\n", This, Id);
    return BasePinImpl_QueryId(iface, Id);
}

static HRESULT WINAPI AviMuxOut_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt)
{
    AviMux *This = impl_from_out_IPin(iface);
    TRACE("(%p)->(AM_MEDIA_TYPE(%p))\n", This, pmt);
    dump_AM_MEDIA_TYPE(pmt);
    return BasePinImpl_QueryAccept(iface, pmt);
}

static HRESULT WINAPI AviMuxOut_EnumMediaTypes(IPin *iface, IEnumMediaTypes **ppEnum)
{
    AviMux *This = impl_from_out_IPin(iface);
    TRACE("(%p)->(%p)\n", This, ppEnum);
    return BasePinImpl_EnumMediaTypes(iface, ppEnum);
}

static HRESULT WINAPI AviMuxOut_QueryInternalConnections(
        IPin *iface, IPin **apPin, ULONG *nPin)
{
    AviMux *This = impl_from_out_IPin(iface);
    FIXME("(%p)->(%p %p)\n", This, apPin, nPin);
    return E_NOTIMPL;
}

static HRESULT WINAPI AviMuxOut_EndOfStream(IPin *iface)
{
    AviMux *This = impl_from_out_IPin(iface);
    TRACE("(%p)\n", This);
    return BaseOutputPinImpl_EndOfStream(iface);
}

static HRESULT WINAPI AviMuxOut_BeginFlush(IPin *iface)
{
    AviMux *This = impl_from_out_IPin(iface);
    TRACE("(%p)\n", This);
    return BaseOutputPinImpl_BeginFlush(iface);
}

static HRESULT WINAPI AviMuxOut_EndFlush(IPin *iface)
{
    AviMux *This = impl_from_out_IPin(iface);
    TRACE("(%p)\n", This);
    return BaseOutputPinImpl_EndFlush(iface);
}

static HRESULT WINAPI AviMuxOut_NewSegment(IPin *iface, REFERENCE_TIME tStart,
        REFERENCE_TIME tStop, double dRate)
{
    AviMux *This = impl_from_out_IPin(iface);
    TRACE("(%p)->(0x%x%08x 0x%x%08x %lf)\n", This, (ULONG)(tStart >> 32),
            (ULONG)tStart, (ULONG)(tStop >> 32), (ULONG)tStop, dRate);
    return BasePinImpl_NewSegment(iface, tStart, tStop, dRate);
}

static const IPinVtbl AviMuxOut_PinVtbl = {
    AviMuxOut_QueryInterface,
    AviMuxOut_AddRef,
    AviMuxOut_Release,
    AviMuxOut_Connect,
    AviMuxOut_ReceiveConnection,
    AviMuxOut_Disconnect,
    AviMuxOut_ConnectedTo,
    AviMuxOut_ConnectionMediaType,
    AviMuxOut_QueryPinInfo,
    AviMuxOut_QueryDirection,
    AviMuxOut_QueryId,
    AviMuxOut_QueryAccept,
    AviMuxOut_EnumMediaTypes,
    AviMuxOut_QueryInternalConnections,
    AviMuxOut_EndOfStream,
    AviMuxOut_BeginFlush,
    AviMuxOut_EndFlush,
    AviMuxOut_NewSegment
};

static inline AviMux* impl_from_out_IQualityControl(IQualityControl *iface)
{
    AviMuxOut *amo = CONTAINING_RECORD(iface, AviMuxOut, IQualityControl_iface);
    return impl_from_IBaseFilter(amo->pin.pin.pinInfo.pFilter);
}

static HRESULT WINAPI AviMuxOut_QualityControl_QueryInterface(
        IQualityControl *iface, REFIID riid, void **ppv)
{
    AviMux *This = impl_from_out_IQualityControl(iface);
    return IPin_QueryInterface(&This->out->pin.pin.IPin_iface, riid, ppv);
}

static ULONG WINAPI AviMuxOut_QualityControl_AddRef(IQualityControl *iface)
{
    AviMux *This = impl_from_out_IQualityControl(iface);
    return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
}

static ULONG WINAPI AviMuxOut_QualityControl_Release(IQualityControl *iface)
{
    AviMux *This = impl_from_out_IQualityControl(iface);
    return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
}

static HRESULT WINAPI AviMuxOut_QualityControl_Notify(IQualityControl *iface,
        IBaseFilter *pSelf, Quality q)
{
    AviMux *This = impl_from_out_IQualityControl(iface);
    FIXME("(%p)->(%p { 0x%x %u %s %s })\n", This, pSelf,
            q.Type, q.Proportion,
            wine_dbgstr_longlong(q.Late),
            wine_dbgstr_longlong(q.TimeStamp));
    return E_NOTIMPL;
}

static HRESULT WINAPI AviMuxOut_QualityControl_SetSink(
        IQualityControl *iface, IQualityControl *piqc)
{
    AviMux *This = impl_from_out_IQualityControl(iface);
    FIXME("(%p)->(%p)\n", This, piqc);
    return E_NOTIMPL;
}

static const IQualityControlVtbl AviMuxOut_QualityControlVtbl = {
    AviMuxOut_QualityControl_QueryInterface,
    AviMuxOut_QualityControl_AddRef,
    AviMuxOut_QualityControl_Release,
    AviMuxOut_QualityControl_Notify,
    AviMuxOut_QualityControl_SetSink
};

static HRESULT WINAPI AviMuxIn_CheckMediaType(BasePin *base, const AM_MEDIA_TYPE *pmt)
{
    TRACE("(%p:%s)->(AM_MEDIA_TYPE(%p))\n", base, debugstr_w(base->pinInfo.achName), pmt);
    dump_AM_MEDIA_TYPE(pmt);

    if(IsEqualIID(&pmt->majortype, &MEDIATYPE_Audio) &&
            IsEqualIID(&pmt->formattype, &FORMAT_WaveFormatEx))
        return S_OK;
    if(IsEqualIID(&pmt->majortype, &MEDIATYPE_Interleaved) &&
            IsEqualIID(&pmt->formattype, &FORMAT_DvInfo))
        return S_OK;
    if(IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) &&
            (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo) ||
             IsEqualIID(&pmt->formattype, &FORMAT_DvInfo)))
        return S_OK;
    return S_FALSE;
}

static LONG WINAPI AviMuxIn_GetMediaTypeVersion(BasePin *base)
{
    return 0;
}

static HRESULT WINAPI AviMuxIn_GetMediaType(BasePin *base, int iPosition, AM_MEDIA_TYPE *amt)
{
    return S_FALSE;
}

static HRESULT WINAPI AviMuxIn_Receive(BaseInputPin *base, IMediaSample *pSample)
{
    AviMuxIn *avimuxin = CONTAINING_RECORD(base, AviMuxIn, pin);
    AviMux *avimux = impl_from_IBaseFilter(base->pin.pinInfo.pFilter);
    REFERENCE_TIME start, stop;
    IMediaSample *sample;
    int frames_no;
    IMediaSample2 *ms2;
    BYTE *frame, *buf;
    DWORD max_size, size;
    DWORD flags;
    HRESULT hr;

    TRACE("(%p:%s)->(%p)\n", base, debugstr_w(base->pin.pinInfo.achName), pSample);

    hr = IMediaSample_QueryInterface(pSample, &IID_IMediaSample2, (void**)&ms2);
    if(SUCCEEDED(hr)) {
        AM_SAMPLE2_PROPERTIES props;

        memset(&props, 0, sizeof(props));
        hr = IMediaSample2_GetProperties(ms2, sizeof(props), (BYTE*)&props);
        IMediaSample2_Release(ms2);
        if(FAILED(hr))
            return hr;

        flags = props.dwSampleFlags;
        frame = props.pbBuffer;
        size = props.lActual;
    }else {
        flags = IMediaSample_IsSyncPoint(pSample) == S_OK ? AM_SAMPLE_SPLICEPOINT : 0;
        hr = IMediaSample_GetPointer(pSample, &frame);
        if(FAILED(hr))
            return hr;
        size = IMediaSample_GetActualDataLength(pSample);
    }

    if(!avimuxin->pin.pin.mtCurrent.bTemporalCompression)
        flags |= AM_SAMPLE_SPLICEPOINT;

    hr = IMediaSample_GetTime(pSample, &start, &stop);
    if(FAILED(hr))
        return hr;

    if(avimuxin->stop>stop)
        return VFW_E_START_TIME_AFTER_END;

    if(avimux->start == -1)
        avimux->start = start;
    if(avimux->stop < stop)
        avimux->stop = stop;

    if(avimux->avih.dwSuggestedBufferSize < ALIGN(size)+sizeof(RIFFCHUNK))
        avimux->avih.dwSuggestedBufferSize = ALIGN(size) + sizeof(RIFFCHUNK);
    if(avimuxin->strh.dwSuggestedBufferSize < ALIGN(size)+sizeof(RIFFCHUNK))
        avimuxin->strh.dwSuggestedBufferSize = ALIGN(size) + sizeof(RIFFCHUNK);

    frames_no = 1;
    if(avimuxin->stop!=-1 && start > avimuxin->stop) {
        frames_no += (double)(start - avimuxin->stop) / 10000000
                * avimuxin->strh.dwRate / avimuxin->strh.dwScale + 0.5;
    }
    avimuxin->stop = stop;

    while(--frames_no) {
        /* TODO: store all control frames in one buffer */
        hr = IMemAllocator_GetBuffer(avimuxin->samples_allocator, &sample, NULL, NULL, 0);
        if(FAILED(hr))
            return hr;
        hr = IMediaSample_SetActualDataLength(sample, 0);
        if(SUCCEEDED(hr))
            hr = IMediaSample_SetDiscontinuity(sample, TRUE);
        if(SUCCEEDED(hr))
            hr = IMediaSample_SetSyncPoint(sample, FALSE);
        if(SUCCEEDED(hr))
            hr = queue_sample(avimux, avimuxin, sample);
        IMediaSample_Release(sample);
        if(FAILED(hr))
            return hr;
    }

    hr = IMemAllocator_GetBuffer(avimuxin->samples_allocator, &sample, NULL, NULL, 0);
    if(FAILED(hr))
        return hr;
    max_size = IMediaSample_GetSize(sample);
    if(size > max_size)
        size = max_size;
    hr = IMediaSample_SetActualDataLength(sample, size);
    if(SUCCEEDED(hr))
        hr = IMediaSample_SetDiscontinuity(sample, FALSE);
    if(SUCCEEDED(hr))
        hr = IMediaSample_SetSyncPoint(sample, flags & AM_SAMPLE_SPLICEPOINT);
    /* TODO: avoid unnecessary copying */
    if(SUCCEEDED(hr))
        hr = IMediaSample_GetPointer(sample, &buf);
    if(SUCCEEDED(hr)) {
        memcpy(buf, frame, size);
        hr = queue_sample(avimux, avimuxin, sample);
    }
    IMediaSample_Release(sample);

    return hr;
}

static const BaseInputPinFuncTable AviMuxIn_BaseInputFuncTable = {
    {
        AviMuxIn_CheckMediaType,
        NULL,
        AviMuxIn_GetMediaTypeVersion,
        AviMuxIn_GetMediaType
    },
    AviMuxIn_Receive
};

static inline AviMux* impl_from_in_IPin(IPin *iface)
{
    BasePin *bp = CONTAINING_RECORD(iface, BasePin, IPin_iface);
    IBaseFilter *bf = bp->pinInfo.pFilter;

    return impl_from_IBaseFilter(bf);
}

static inline AviMuxIn* AviMuxIn_from_IPin(IPin *iface)
{
    BasePin *bp = CONTAINING_RECORD(iface, BasePin, IPin_iface);
    BaseInputPin *bip = CONTAINING_RECORD(bp, BaseInputPin, pin);
    return CONTAINING_RECORD(bip, AviMuxIn, pin);
}

static HRESULT WINAPI AviMuxIn_QueryInterface(IPin *iface, REFIID riid, void **ppv)
{
    AviMux *This = impl_from_in_IPin(iface);
    AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);

    TRACE("(%p:%s)->(%s %p)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName),
            debugstr_guid(riid), ppv);

    if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPin))
        *ppv = &avimuxin->pin.pin.IPin_iface;
    else if(IsEqualIID(riid, &IID_IAMStreamControl))
        *ppv = &avimuxin->IAMStreamControl_iface;
    else if(IsEqualIID(riid, &IID_IMemInputPin))
        *ppv = &avimuxin->pin.IMemInputPin_iface;
    else if(IsEqualIID(riid, &IID_IPropertyBag))
        *ppv = &avimuxin->IPropertyBag_iface;
    else if(IsEqualIID(riid, &IID_IQualityControl))
        *ppv = &avimuxin->IQualityControl_iface;
    else {
        FIXME("no interface for %s\n", debugstr_guid(riid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI AviMuxIn_AddRef(IPin *iface)
{
    AviMux *This = impl_from_in_IPin(iface);
    return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
}

static ULONG WINAPI AviMuxIn_Release(IPin *iface)
{
    AviMux *This = impl_from_in_IPin(iface);
    return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
}

static HRESULT WINAPI AviMuxIn_Connect(IPin *iface,
        IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
{
    AviMux *This = impl_from_in_IPin(iface);
    AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
    TRACE("(%p:%s)->(%p AM_MEDIA_TYPE(%p))\n", This,
            debugstr_w(avimuxin->pin.pin.pinInfo.achName), pReceivePin, pmt);
    dump_AM_MEDIA_TYPE(pmt);
    return BaseInputPinImpl_Connect(iface, pReceivePin, pmt);
}

static HRESULT WINAPI AviMuxIn_ReceiveConnection(IPin *iface,
        IPin *pConnector, const AM_MEDIA_TYPE *pmt)
{
    AviMux *This = impl_from_in_IPin(iface);
    AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
    HRESULT hr;

    TRACE("(%p:%s)->(%p AM_MEDIA_TYPE(%p))\n", This,
            debugstr_w(avimuxin->pin.pin.pinInfo.achName), pConnector, pmt);
    dump_AM_MEDIA_TYPE(pmt);

    if(!pmt)
        return E_POINTER;

    hr = BaseInputPinImpl_ReceiveConnection(iface, pConnector, pmt);
    if(FAILED(hr))
        return hr;

    if(IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) &&
            IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) {
        ALLOCATOR_PROPERTIES req, act;
        VIDEOINFOHEADER *vih;
        int size;

        vih = (VIDEOINFOHEADER*)pmt->pbFormat;
        avimuxin->strh.fcc = ckidSTREAMHEADER;
        avimuxin->strh.cb = sizeof(AVISTREAMHEADER) - FIELD_OFFSET(AVISTREAMHEADER, fccType);
        avimuxin->strh.fccType = streamtypeVIDEO;
        /* FIXME: fccHandler should be set differently */
        avimuxin->strh.fccHandler = vih->bmiHeader.biCompression ?
            vih->bmiHeader.biCompression : FCC('D','I','B',' ');
        avimuxin->avg_time_per_frame = vih->AvgTimePerFrame;
        avimuxin->stop = -1;

        req.cBuffers = 32;
        req.cbBuffer = vih->bmiHeader.biSizeImage;
        req.cbAlign = 1;
        req.cbPrefix = sizeof(void*);
        hr = IMemAllocator_SetProperties(avimuxin->samples_allocator, &req, &act);
        if(SUCCEEDED(hr))
            hr = IMemAllocator_Commit(avimuxin->samples_allocator);
        if(FAILED(hr)) {
            BasePinImpl_Disconnect(iface);
            return hr;
        }

        size = pmt->cbFormat - FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader);
        avimuxin->strf = CoTaskMemAlloc(sizeof(RIFFCHUNK) + ALIGN(FIELD_OFFSET(BITMAPINFO, bmiColors[vih->bmiHeader.biClrUsed])));
        avimuxin->strf->fcc = ckidSTREAMFORMAT;
        avimuxin->strf->cb = FIELD_OFFSET(BITMAPINFO, bmiColors[vih->bmiHeader.biClrUsed]);
        if(size > avimuxin->strf->cb)
            size = avimuxin->strf->cb;
        memcpy(avimuxin->strf->data, &vih->bmiHeader, size);
    }else {
        FIXME("format not supported: %s %s\n", debugstr_guid(&pmt->majortype),
                debugstr_guid(&pmt->formattype));
        return E_NOTIMPL;
    }

    return create_input_pin(This);
}

static HRESULT WINAPI AviMuxIn_Disconnect(IPin *iface)
{
    AviMux *This = impl_from_in_IPin(iface);
    AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
    IMediaSample **prev, *cur;
    HRESULT hr;

    TRACE("(%p:%s)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName));

    hr = BasePinImpl_Disconnect(iface);
    if(FAILED(hr))
        return hr;

    IMemAllocator_Decommit(avimuxin->samples_allocator);
    while(avimuxin->samples_head) {
        cur = avimuxin->samples_head;
        hr = IMediaSample_GetPointer(cur, (BYTE**)&prev);
        if(FAILED(hr))
            break;
        prev--;

        cur = avimuxin->samples_head;
        avimuxin->samples_head = *prev;
        IMediaSample_Release(cur);

        if(cur == avimuxin->samples_head)
            avimuxin->samples_head = NULL;
    }
    CoTaskMemFree(avimuxin->strf);
    avimuxin->strf = NULL;
    return hr;
}

static HRESULT WINAPI AviMuxIn_ConnectedTo(IPin *iface, IPin **pPin)
{
    AviMux *This = impl_from_in_IPin(iface);
    AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
    TRACE("(%p:%s)->(%p)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName), pPin);
    return BasePinImpl_ConnectedTo(iface, pPin);
}

static HRESULT WINAPI AviMuxIn_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *pmt)
{
    AviMux *This = impl_from_in_IPin(iface);
    AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
    TRACE("(%p:%s)->(%p)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName), pmt);
    return BasePinImpl_ConnectionMediaType(iface, pmt);
}

static HRESULT WINAPI AviMuxIn_QueryPinInfo(IPin *iface, PIN_INFO *pInfo)
{
    AviMux *This = impl_from_in_IPin(iface);
    AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
    TRACE("(%p:%s)->(%p)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName), pInfo);
    return BasePinImpl_QueryPinInfo(iface, pInfo);
}

static HRESULT WINAPI AviMuxIn_QueryDirection(IPin *iface, PIN_DIRECTION *pPinDir)
{
    AviMux *This = impl_from_in_IPin(iface);
    AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
    TRACE("(%p:%s)->(%p)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName), pPinDir);
    return BasePinImpl_QueryDirection(iface, pPinDir);
}

static HRESULT WINAPI AviMuxIn_QueryId(IPin *iface, LPWSTR *Id)
{
    AviMux *This = impl_from_in_IPin(iface);
    AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
    TRACE("(%p:%s)->(%p)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName), Id);
    return BasePinImpl_QueryId(iface, Id);
}

static HRESULT WINAPI AviMuxIn_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt)
{
    AviMux *This = impl_from_in_IPin(iface);
    AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
    TRACE("(%p:%s)->(AM_MEDIA_TYPE(%p))\n", This,
            debugstr_w(avimuxin->pin.pin.pinInfo.achName), pmt);
    dump_AM_MEDIA_TYPE(pmt);
    return BasePinImpl_QueryAccept(iface, pmt);
}

static HRESULT WINAPI AviMuxIn_EnumMediaTypes(IPin *iface, IEnumMediaTypes **ppEnum)
{
    AviMux *This = impl_from_in_IPin(iface);
    AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
    TRACE("(%p:%s)->(%p)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName), ppEnum);
    return BasePinImpl_EnumMediaTypes(iface, ppEnum);
}

static HRESULT WINAPI AviMuxIn_QueryInternalConnections(
        IPin *iface, IPin **apPin, ULONG *nPin)
{
    AviMux *This = impl_from_in_IPin(iface);
    AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
    TRACE("(%p:%s)->(%p %p)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName), apPin, nPin);
    return BasePinImpl_QueryInternalConnections(iface, apPin, nPin);
}

static HRESULT WINAPI AviMuxIn_EndOfStream(IPin *iface)
{
    AviMux *This = impl_from_in_IPin(iface);
    AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
    TRACE("(%p:%s)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName));
    return BaseInputPinImpl_EndOfStream(iface);
}

static HRESULT WINAPI AviMuxIn_BeginFlush(IPin *iface)
{
    AviMux *This = impl_from_in_IPin(iface);
    AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
    TRACE("(%p:%s)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName));
    return BaseInputPinImpl_BeginFlush(iface);
}

static HRESULT WINAPI AviMuxIn_EndFlush(IPin *iface)
{
    AviMux *This = impl_from_in_IPin(iface);
    AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
    TRACE("(%p:%s)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName));
    return BaseInputPinImpl_EndFlush(iface);
}

static HRESULT WINAPI AviMuxIn_NewSegment(IPin *iface, REFERENCE_TIME tStart,
        REFERENCE_TIME tStop, double dRate)
{
    AviMux *This = impl_from_in_IPin(iface);
    AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
    TRACE("(%p:%s)->(0x%x%08x 0x%x%08x %lf)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName),
         (ULONG)(tStart >> 32), (ULONG)tStart, (ULONG)(tStop >> 32), (ULONG)tStop, dRate);
    return BasePinImpl_NewSegment(iface, tStart, tStop, dRate);
}

static const IPinVtbl AviMuxIn_PinVtbl = {
    AviMuxIn_QueryInterface,
    AviMuxIn_AddRef,
    AviMuxIn_Release,
    AviMuxIn_Connect,
    AviMuxIn_ReceiveConnection,
    AviMuxIn_Disconnect,
    AviMuxIn_ConnectedTo,
    AviMuxIn_ConnectionMediaType,
    AviMuxIn_QueryPinInfo,
    AviMuxIn_QueryDirection,
    AviMuxIn_QueryId,
    AviMuxIn_QueryAccept,
    AviMuxIn_EnumMediaTypes,
    AviMuxIn_QueryInternalConnections,
    AviMuxIn_EndOfStream,
    AviMuxIn_BeginFlush,
    AviMuxIn_EndFlush,
    AviMuxIn_NewSegment
};

static inline AviMuxIn* AviMuxIn_from_IAMStreamControl(IAMStreamControl *iface)
{
    return CONTAINING_RECORD(iface, AviMuxIn, IAMStreamControl_iface);
}

static HRESULT WINAPI AviMuxIn_AMStreamControl_QueryInterface(
        IAMStreamControl *iface, REFIID riid, void **ppv)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IAMStreamControl(iface);
    return IPin_QueryInterface(&avimuxin->pin.pin.IPin_iface, riid, ppv);
}

static ULONG WINAPI AviMuxIn_AMStreamControl_AddRef(IAMStreamControl *iface)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IAMStreamControl(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
}

static ULONG WINAPI AviMuxIn_AMStreamControl_Release(IAMStreamControl *iface)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IAMStreamControl(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
}

static HRESULT WINAPI AviMuxIn_AMStreamControl_StartAt(IAMStreamControl *iface,
        const REFERENCE_TIME *ptStart, DWORD dwCookie)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IAMStreamControl(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    FIXME("(%p:%s)->(%p %x)\n", This,
            debugstr_w(avimuxin->pin.pin.pinInfo.achName), ptStart, dwCookie);
    return E_NOTIMPL;
}

static HRESULT WINAPI AviMuxIn_AMStreamControl_StopAt(IAMStreamControl *iface,
        const REFERENCE_TIME *ptStop, BOOL bSendExtra, DWORD dwCookie)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IAMStreamControl(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    FIXME("(%p:%s)->(%p %x %x)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName),
            ptStop, bSendExtra, dwCookie);
    return E_NOTIMPL;
}

static HRESULT WINAPI AviMuxIn_AMStreamControl_GetInfo(
        IAMStreamControl *iface, AM_STREAM_INFO *pInfo)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IAMStreamControl(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    FIXME("(%p:%s)->(%p)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName), pInfo);
    return E_NOTIMPL;
}

static const IAMStreamControlVtbl AviMuxIn_AMStreamControlVtbl = {
    AviMuxIn_AMStreamControl_QueryInterface,
    AviMuxIn_AMStreamControl_AddRef,
    AviMuxIn_AMStreamControl_Release,
    AviMuxIn_AMStreamControl_StartAt,
    AviMuxIn_AMStreamControl_StopAt,
    AviMuxIn_AMStreamControl_GetInfo
};

static inline AviMuxIn* AviMuxIn_from_IMemInputPin(IMemInputPin *iface)
{
    BaseInputPin *bip = CONTAINING_RECORD(iface, BaseInputPin, IMemInputPin_iface);
    return CONTAINING_RECORD(bip, AviMuxIn, pin);
}

static HRESULT WINAPI AviMuxIn_MemInputPin_QueryInterface(
        IMemInputPin *iface, REFIID riid, void **ppv)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IMemInputPin(iface);
    return IPin_QueryInterface(&avimuxin->pin.pin.IPin_iface, riid, ppv);
}

static ULONG WINAPI AviMuxIn_MemInputPin_AddRef(IMemInputPin *iface)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IMemInputPin(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
}

static ULONG WINAPI AviMuxIn_MemInputPin_Release(IMemInputPin *iface)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IMemInputPin(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
}

static HRESULT WINAPI AviMuxIn_MemInputPin_GetAllocator(
        IMemInputPin *iface, IMemAllocator **ppAllocator)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IMemInputPin(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);

    TRACE("(%p:%s)->(%p)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName), ppAllocator);

    if(!ppAllocator)
        return E_POINTER;

    IMemAllocator_AddRef(avimuxin->pin.pAllocator);
    *ppAllocator = avimuxin->pin.pAllocator;
    return S_OK;
}

static HRESULT WINAPI AviMuxIn_MemInputPin_NotifyAllocator(
        IMemInputPin *iface, IMemAllocator *pAllocator, BOOL bReadOnly)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IMemInputPin(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    ALLOCATOR_PROPERTIES props;
    HRESULT hr;

    TRACE("(%p:%s)->(%p %x)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName),
            pAllocator, bReadOnly);

    if(!pAllocator)
        return E_POINTER;

    memset(&props, 0, sizeof(props));
    hr = IMemAllocator_GetProperties(pAllocator, &props);
    if(FAILED(hr))
        return hr;

    props.cbAlign = 1;
    props.cbPrefix = 8;
    return IMemAllocator_SetProperties(avimuxin->pin.pAllocator, &props, &props);
}

static HRESULT WINAPI AviMuxIn_MemInputPin_GetAllocatorRequirements(
        IMemInputPin *iface, ALLOCATOR_PROPERTIES *pProps)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IMemInputPin(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);

    TRACE("(%p:%s)->(%p)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName), pProps);

    if(!pProps)
        return E_POINTER;

    pProps->cbAlign = 1;
    pProps->cbPrefix = 8;
    return S_OK;
}

static HRESULT WINAPI AviMuxIn_MemInputPin_Receive(
        IMemInputPin *iface, IMediaSample *pSample)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IMemInputPin(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);

    TRACE("(%p:%s)->(%p)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName), pSample);

    return avimuxin->pin.pFuncsTable->pfnReceive(&avimuxin->pin, pSample);
}

static HRESULT WINAPI AviMuxIn_MemInputPin_ReceiveMultiple(IMemInputPin *iface,
        IMediaSample **pSamples, LONG nSamples, LONG *nSamplesProcessed)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IMemInputPin(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    HRESULT hr = S_OK;

    TRACE("(%p:%s)->(%p %d %p)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName),
            pSamples, nSamples, nSamplesProcessed);

    for(*nSamplesProcessed=0; *nSamplesProcessed<nSamples; (*nSamplesProcessed)++)
    {
        hr = avimuxin->pin.pFuncsTable->pfnReceive(&avimuxin->pin, pSamples[*nSamplesProcessed]);
        if(hr != S_OK)
            break;
    }

    return hr;
}

static HRESULT WINAPI AviMuxIn_MemInputPin_ReceiveCanBlock(IMemInputPin *iface)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IMemInputPin(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    HRESULT hr;

    TRACE("(%p:%s)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName));

    if(!This->out->pin.pMemInputPin)
        return S_FALSE;

    hr = IMemInputPin_ReceiveCanBlock(This->out->pin.pMemInputPin);
    return hr != S_FALSE ? S_OK : S_FALSE;
}

static const IMemInputPinVtbl AviMuxIn_MemInputPinVtbl = {
    AviMuxIn_MemInputPin_QueryInterface,
    AviMuxIn_MemInputPin_AddRef,
    AviMuxIn_MemInputPin_Release,
    AviMuxIn_MemInputPin_GetAllocator,
    AviMuxIn_MemInputPin_NotifyAllocator,
    AviMuxIn_MemInputPin_GetAllocatorRequirements,
    AviMuxIn_MemInputPin_Receive,
    AviMuxIn_MemInputPin_ReceiveMultiple,
    AviMuxIn_MemInputPin_ReceiveCanBlock
};

static inline AviMuxIn* AviMuxIn_from_IPropertyBag(IPropertyBag *iface)
{
    return CONTAINING_RECORD(iface, AviMuxIn, IPropertyBag_iface);
}

static HRESULT WINAPI AviMuxIn_PropertyBag_QueryInterface(
        IPropertyBag *iface, REFIID riid, void **ppv)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IPropertyBag(iface);
    return IPin_QueryInterface(&avimuxin->pin.pin.IPin_iface, riid, ppv);
}

static ULONG WINAPI AviMuxIn_PropertyBag_AddRef(IPropertyBag *iface)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IPropertyBag(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
}

static ULONG WINAPI AviMuxIn_PropertyBag_Release(IPropertyBag *iface)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IPropertyBag(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
}

static HRESULT WINAPI AviMuxIn_PropertyBag_Read(IPropertyBag *iface,
        LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog *pErrorLog)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IPropertyBag(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    FIXME("(%p:%s)->(%s %p %p)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName),
            debugstr_w(pszPropName), pVar, pErrorLog);
    return E_NOTIMPL;
}

static HRESULT WINAPI AviMuxIn_PropertyBag_Write(IPropertyBag *iface,
        LPCOLESTR pszPropName, VARIANT *pVar)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IPropertyBag(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    FIXME("(%p:%s)->(%s %p)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName),
            debugstr_w(pszPropName), pVar);
    return E_NOTIMPL;
}

static const IPropertyBagVtbl AviMuxIn_PropertyBagVtbl = {
    AviMuxIn_PropertyBag_QueryInterface,
    AviMuxIn_PropertyBag_AddRef,
    AviMuxIn_PropertyBag_Release,
    AviMuxIn_PropertyBag_Read,
    AviMuxIn_PropertyBag_Write
};

static inline AviMuxIn* AviMuxIn_from_IQualityControl(IQualityControl *iface)
{
    return CONTAINING_RECORD(iface, AviMuxIn, IQualityControl_iface);
}

static HRESULT WINAPI AviMuxIn_QualityControl_QueryInterface(
        IQualityControl *iface, REFIID riid, void **ppv)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IQualityControl(iface);
    return IPin_QueryInterface(&avimuxin->pin.pin.IPin_iface, riid, ppv);
}

static ULONG WINAPI AviMuxIn_QualityControl_AddRef(IQualityControl *iface)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IQualityControl(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
}

static ULONG WINAPI AviMuxIn_QualityControl_Release(IQualityControl *iface)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IQualityControl(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
}

static HRESULT WINAPI AviMuxIn_QualityControl_Notify(IQualityControl *iface,
        IBaseFilter *pSelf, Quality q)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IQualityControl(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    FIXME("(%p:%s)->(%p { 0x%x %u %s %s })\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName), pSelf,
            q.Type, q.Proportion,
            wine_dbgstr_longlong(q.Late),
            wine_dbgstr_longlong(q.TimeStamp));
    return E_NOTIMPL;
}

static HRESULT WINAPI AviMuxIn_QualityControl_SetSink(
        IQualityControl *iface, IQualityControl *piqc)
{
    AviMuxIn *avimuxin = AviMuxIn_from_IQualityControl(iface);
    AviMux *This = impl_from_in_IPin(&avimuxin->pin.pin.IPin_iface);
    FIXME("(%p:%s)->(%p)\n", This, debugstr_w(avimuxin->pin.pin.pinInfo.achName), piqc);
    return E_NOTIMPL;
}

static const IQualityControlVtbl AviMuxIn_QualityControlVtbl = {
    AviMuxIn_QualityControl_QueryInterface,
    AviMuxIn_QualityControl_AddRef,
    AviMuxIn_QualityControl_Release,
    AviMuxIn_QualityControl_Notify,
    AviMuxIn_QualityControl_SetSink
};

static HRESULT create_input_pin(AviMux *avimux)
{
    static const WCHAR name[] = {'I','n','p','u','t',' ','0','0',0};
    PIN_INFO info;
    HRESULT hr;

    if(avimux->input_pin_no >= MAX_PIN_NO-1)
        return E_FAIL;

    info.dir = PINDIR_INPUT;
    info.pFilter = &avimux->filter.IBaseFilter_iface;
    memcpy(info.achName, name, sizeof(name));
    info.achName[7] = '0' + (avimux->input_pin_no+1) % 10;
    info.achName[6] = '0' + (avimux->input_pin_no+1) / 10;

    hr = BaseInputPin_Construct(&AviMuxIn_PinVtbl, sizeof(AviMuxIn), &info,
            &AviMuxIn_BaseInputFuncTable, &avimux->filter.csFilter, NULL, (IPin**)&avimux->in[avimux->input_pin_no]);
    if(FAILED(hr))
        return hr;
    avimux->in[avimux->input_pin_no]->pin.IMemInputPin_iface.lpVtbl = &AviMuxIn_MemInputPinVtbl;
    avimux->in[avimux->input_pin_no]->IAMStreamControl_iface.lpVtbl = &AviMuxIn_AMStreamControlVtbl;
    avimux->in[avimux->input_pin_no]->IPropertyBag_iface.lpVtbl = &AviMuxIn_PropertyBagVtbl;
    avimux->in[avimux->input_pin_no]->IQualityControl_iface.lpVtbl = &AviMuxIn_QualityControlVtbl;

    avimux->in[avimux->input_pin_no]->samples_head = NULL;
    hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
            &IID_IMemAllocator, (void**)&avimux->in[avimux->input_pin_no]->samples_allocator);
    if(FAILED(hr)) {
        BaseInputPinImpl_Release(&avimux->in[avimux->input_pin_no]->pin.pin.IPin_iface);
        return hr;
    }

    hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
            &IID_IMemAllocator, (void**)&avimux->in[avimux->input_pin_no]->pin.pAllocator);
    if(FAILED(hr)) {
        IMemAllocator_Release(avimux->in[avimux->input_pin_no]->samples_allocator);
        BaseInputPinImpl_Release(&avimux->in[avimux->input_pin_no]->pin.pin.IPin_iface);
        return hr;
    }

    avimux->in[avimux->input_pin_no]->stream_time = 0;
    memset(&avimux->in[avimux->input_pin_no]->strh, 0, sizeof(avimux->in[avimux->input_pin_no]->strh));
    avimux->in[avimux->input_pin_no]->strf = NULL;
    memset(&avimux->in[avimux->input_pin_no]->indx_data, 0, sizeof(avimux->in[avimux->input_pin_no]->indx_data));
    memset(&avimux->in[avimux->input_pin_no]->ix_data, 0, sizeof(avimux->in[avimux->input_pin_no]->ix_data));
    avimux->in[avimux->input_pin_no]->indx = (AVISUPERINDEX*)&avimux->in[avimux->input_pin_no]->indx_data;
    avimux->in[avimux->input_pin_no]->ix = (AVISTDINDEX*)avimux->in[avimux->input_pin_no]->ix_data;

    avimux->input_pin_no++;
    return S_OK;
}

IUnknown* WINAPI QCAP_createAVIMux(IUnknown *pUnkOuter, HRESULT *phr)
{
    static const WCHAR output_name[] = {'A','V','I',' ','O','u','t',0};

    AviMux *avimux;
    PIN_INFO info;
    HRESULT hr;

    TRACE("(%p)\n", pUnkOuter);

    if(pUnkOuter) {
        *phr = CLASS_E_NOAGGREGATION;
        return NULL;
    }

    avimux = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(AviMux));
    if(!avimux) {
        *phr = E_OUTOFMEMORY;
        return NULL;
    }

    BaseFilter_Init(&avimux->filter, &AviMuxVtbl, &CLSID_AviDest,
            (DWORD_PTR)(__FILE__ ": AviMux.csFilter"), &filter_func_table);
    avimux->IConfigAviMux_iface.lpVtbl = &ConfigAviMuxVtbl;
    avimux->IConfigInterleaving_iface.lpVtbl = &ConfigInterleavingVtbl;
    avimux->IMediaSeeking_iface.lpVtbl = &MediaSeekingVtbl;
    avimux->IPersistMediaPropertyBag_iface.lpVtbl = &PersistMediaPropertyBagVtbl;
    avimux->ISpecifyPropertyPages_iface.lpVtbl = &SpecifyPropertyPagesVtbl;

    info.dir = PINDIR_OUTPUT;
    info.pFilter = &avimux->filter.IBaseFilter_iface;
    lstrcpyW(info.achName, output_name);
    hr = BaseOutputPin_Construct(&AviMuxOut_PinVtbl, sizeof(AviMuxOut), &info,
            &AviMuxOut_BaseOutputFuncTable, &avimux->filter.csFilter, (IPin**)&avimux->out);
    if(FAILED(hr)) {
        BaseFilterImpl_Release(&avimux->filter.IBaseFilter_iface);
        HeapFree(GetProcessHeap(), 0, avimux);
        *phr = hr;
        return NULL;
    }
    avimux->out->IQualityControl_iface.lpVtbl = &AviMuxOut_QualityControlVtbl;
    avimux->out->cur_stream = 0;
    avimux->out->cur_time = 0;
    avimux->out->stream = NULL;

    hr = create_input_pin(avimux);
    if(FAILED(hr)) {
        BaseOutputPinImpl_Release(&avimux->out->pin.pin.IPin_iface);
        BaseFilterImpl_Release(&avimux->filter.IBaseFilter_iface);
        HeapFree(GetProcessHeap(), 0, avimux);
        *phr = hr;
        return NULL;
    }

    avimux->interleave = 10000000;

    ObjectRefCount(TRUE);
    *phr = S_OK;
    return (IUnknown*)&avimux->filter.IBaseFilter_iface;
}
