/*
 * Copyright 2002 Michael Günnewig
 *
 * 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 <assert.h>
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "mmsystem.h"
#include "vfw.h"
#include "msacm.h"

#include "avifile_private.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(avifile);

/***********************************************************************/

typedef struct _IAVIStreamImpl {
  /* IUnknown stuff */
  IAVIStream      IAVIStream_iface;
  LONG		  ref;

  /* IAVIStream stuff */
  PAVISTREAM      pStream;
  AVISTREAMINFOW  sInfo;

  HACMSTREAM      has;

  LPWAVEFORMATEX  lpInFormat;
  LONG            cbInFormat;

  LPWAVEFORMATEX  lpOutFormat;
  LONG            cbOutFormat;

  ACMSTREAMHEADER acmStreamHdr;
} IAVIStreamImpl;

/***********************************************************************/

#define CONVERT_STREAM_to_THIS(a) do { \
           DWORD __bytes; \
           acmStreamSize(This->has,*(a) * This->lpInFormat->nBlockAlign,\
                         &__bytes, ACM_STREAMSIZEF_SOURCE); \
           *(a) = __bytes / This->lpOutFormat->nBlockAlign; } while(0)

#define CONVERT_THIS_to_STREAM(a) do { \
           DWORD __bytes; \
           acmStreamSize(This->has,*(a) * This->lpOutFormat->nBlockAlign,\
                         &__bytes, ACM_STREAMSIZEF_DESTINATION); \
           *(a) = __bytes / This->lpInFormat->nBlockAlign; } while(0)

static HRESULT AVIFILE_OpenCompressor(IAVIStreamImpl *This)
{
  HRESULT hr;

  /* pre-conditions */
  assert(This != NULL);
  assert(This->pStream != NULL);

  if (This->has != NULL)
    return AVIERR_OK;

  if (This->lpInFormat == NULL) {
    /* decode or encode the data from pStream */
    hr = AVIStreamFormatSize(This->pStream, This->sInfo.dwStart, &This->cbInFormat);
    if (FAILED(hr))
      return hr;
    This->lpInFormat = HeapAlloc(GetProcessHeap(), 0, This->cbInFormat);
    if (This->lpInFormat == NULL)
      return AVIERR_MEMORY;

    hr = IAVIStream_ReadFormat(This->pStream, This->sInfo.dwStart,
                               This->lpInFormat, &This->cbInFormat);
    if (FAILED(hr))
      return hr;

    if (This->lpOutFormat == NULL) {
      /* we must decode to default format */
      This->cbOutFormat = sizeof(PCMWAVEFORMAT);
      This->lpOutFormat = HeapAlloc(GetProcessHeap(), 0, This->cbOutFormat);
      if (This->lpOutFormat == NULL)
        return AVIERR_MEMORY;

      This->lpOutFormat->wFormatTag = WAVE_FORMAT_PCM;
      if (acmFormatSuggest(NULL, This->lpInFormat, This->lpOutFormat,
                           This->cbOutFormat, ACM_FORMATSUGGESTF_WFORMATTAG) != S_OK)
        return AVIERR_NOCOMPRESSOR;
    }
  } else if (This->lpOutFormat == NULL)
    return AVIERR_ERROR; /* To what should I encode? */

  if (acmStreamOpen(&This->has, NULL, This->lpInFormat, This->lpOutFormat,
                    NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME) != S_OK)
    return AVIERR_NOCOMPRESSOR;

  /* update AVISTREAMINFO structure */
  This->sInfo.dwSampleSize = This->lpOutFormat->nBlockAlign;
  This->sInfo.dwScale      = This->lpOutFormat->nBlockAlign;
  This->sInfo.dwRate       = This->lpOutFormat->nAvgBytesPerSec;
  This->sInfo.dwQuality    = (DWORD)ICQUALITY_DEFAULT;
  SetRectEmpty(&This->sInfo.rcFrame);

  /* convert positions and sizes to output format */
  CONVERT_STREAM_to_THIS(&This->sInfo.dwStart);
  CONVERT_STREAM_to_THIS(&This->sInfo.dwLength);
  CONVERT_STREAM_to_THIS(&This->sInfo.dwSuggestedBufferSize);

  return AVIERR_OK;
}

static inline IAVIStreamImpl *impl_from_IAVIStream(IAVIStream *iface)
{
  return CONTAINING_RECORD(iface, IAVIStreamImpl, IAVIStream_iface);
}

static HRESULT WINAPI ACMStream_fnQueryInterface(IAVIStream *iface,
						  REFIID refiid, LPVOID *obj)
{
  IAVIStreamImpl *This = impl_from_IAVIStream(iface);

  TRACE("(%p,%s,%p)\n", iface, debugstr_guid(refiid), obj);

  if (IsEqualGUID(&IID_IUnknown, refiid) ||
      IsEqualGUID(&IID_IAVIStream, refiid)) {
    *obj = This;
    IAVIStream_AddRef(iface);

    return S_OK;
  }

  return OLE_E_ENUM_NOMORE;
}

static ULONG WINAPI ACMStream_fnAddRef(IAVIStream *iface)
{
  IAVIStreamImpl *This = impl_from_IAVIStream(iface);
  ULONG ref = InterlockedIncrement(&This->ref);

  TRACE("(%p) -> %d\n", iface, ref);

  /* also add reference to the nested stream */
  if (This->pStream != NULL)
    IAVIStream_AddRef(This->pStream);

  return ref;
}

static ULONG WINAPI ACMStream_fnRelease(IAVIStream* iface)
{
  IAVIStreamImpl *This = impl_from_IAVIStream(iface);
  ULONG ref = InterlockedDecrement(&This->ref);

  TRACE("(%p) -> %d\n", iface, ref);

  if (ref == 0) {
    /* destruct */
    if (This->has != NULL) {
      if (This->acmStreamHdr.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED)
	acmStreamUnprepareHeader(This->has, &This->acmStreamHdr, 0);
      acmStreamClose(This->has, 0);
      This->has = NULL;
    }
    HeapFree(GetProcessHeap(), 0, This->acmStreamHdr.pbSrc);
    This->acmStreamHdr.pbSrc = NULL;
    HeapFree(GetProcessHeap(), 0, This->acmStreamHdr.pbDst);
    This->acmStreamHdr.pbDst = NULL;
    if (This->lpInFormat != NULL) {
      HeapFree(GetProcessHeap(), 0, This->lpInFormat);
      This->lpInFormat = NULL;
      This->cbInFormat = 0;
    }
    if (This->lpOutFormat != NULL) {
      HeapFree(GetProcessHeap(), 0, This->lpOutFormat);
      This->lpOutFormat = NULL;
      This->cbOutFormat = 0;
    }
    if (This->pStream != NULL) {
      IAVIStream_Release(This->pStream);
      This->pStream = NULL;
    }
    HeapFree(GetProcessHeap(), 0, This);

    return 0;
  }

  /* also release reference to the nested stream */
  if (This->pStream != NULL)
    IAVIStream_Release(This->pStream);

  return ref;
}

/* lParam1: PAVISTREAM
 * lParam2: LPAVICOMPRESSOPTIONS -- even if doc's say LPWAVEFORMAT
 */
static HRESULT WINAPI ACMStream_fnCreate(IAVIStream *iface, LPARAM lParam1,
					  LPARAM lParam2)
{
  IAVIStreamImpl *This = impl_from_IAVIStream(iface);

  TRACE("(%p,0x%08lX,0x%08lX)\n", iface, lParam1, lParam2);

  /* check for swapped parameters */
  if ((LPVOID)lParam1 != NULL &&
      ((LPAVICOMPRESSOPTIONS)lParam1)->fccType == streamtypeAUDIO) {
    LPARAM tmp = lParam1;

    lParam1 = lParam2;
    lParam2 = tmp;
  }

  if ((LPVOID)lParam1 == NULL)
    return AVIERR_BADPARAM;

  IAVIStream_Info((PAVISTREAM)lParam1, &This->sInfo, sizeof(This->sInfo));
  if (This->sInfo.fccType != streamtypeAUDIO)
    return AVIERR_ERROR; /* error in registry or AVIMakeCompressedStream */

  This->sInfo.fccHandler = 0; /* be paranoid */

  /* FIXME: check ACM version? Which version does we need? */

  if ((LPVOID)lParam2 != NULL) {
    /* We only need the format from the compress-options */
    if (((LPAVICOMPRESSOPTIONS)lParam2)->fccType == streamtypeAUDIO)
      lParam2 = (LPARAM)((LPAVICOMPRESSOPTIONS)lParam2)->lpFormat;

    if (((LPWAVEFORMATEX)lParam2)->wFormatTag != WAVE_FORMAT_PCM)
      This->cbOutFormat = sizeof(WAVEFORMATEX) + ((LPWAVEFORMATEX)lParam2)->cbSize;
    else
      This->cbOutFormat = sizeof(PCMWAVEFORMAT);

    This->lpOutFormat = HeapAlloc(GetProcessHeap(), 0, This->cbOutFormat);
    if (This->lpOutFormat == NULL)
      return AVIERR_MEMORY;

    memcpy(This->lpOutFormat, (LPVOID)lParam2, This->cbOutFormat);
  } else {
    This->lpOutFormat = NULL;
    This->cbOutFormat = 0;
  }

  This->pStream = (PAVISTREAM)lParam1;
  IAVIStream_AddRef(This->pStream);

  return AVIERR_OK;
}

static HRESULT WINAPI ACMStream_fnInfo(IAVIStream *iface,LPAVISTREAMINFOW psi,
					LONG size)
{
  IAVIStreamImpl *This = impl_from_IAVIStream(iface);

  TRACE("(%p,%p,%d)\n", iface, psi, size);

  if (psi == NULL)
    return AVIERR_BADPARAM;
  if (size < 0)
    return AVIERR_BADSIZE;

  /* Need codec to correct some values in structure */
  if (This->has == NULL) {
    HRESULT hr = AVIFILE_OpenCompressor(This);

    if (FAILED(hr))
      return hr;
  }

  memcpy(psi, &This->sInfo, min(size, (LONG)sizeof(This->sInfo)));

  if (size < (LONG)sizeof(This->sInfo))
    return AVIERR_BUFFERTOOSMALL;
  return AVIERR_OK;
}

static LONG WINAPI ACMStream_fnFindSample(IAVIStream *iface, LONG pos,
					   LONG flags)
{
  IAVIStreamImpl *This = impl_from_IAVIStream(iface);

  TRACE("(%p,%d,0x%08X)\n",iface,pos,flags);

  if (flags & FIND_FROM_START) {
    pos = This->sInfo.dwStart;
    flags &= ~(FIND_FROM_START|FIND_PREV);
    flags |= FIND_NEXT;
  }

  /* convert pos from our 'space' to This->pStream's one */
  CONVERT_THIS_to_STREAM(&pos);

  /* ask stream */
  pos = IAVIStream_FindSample(This->pStream, pos, flags);

  if (pos != -1) {
    /* convert pos back to our 'space' if it's no size or physical pos */
    if ((flags & FIND_RET) == 0)
      CONVERT_STREAM_to_THIS(&pos);
  }

  return pos;
}

static HRESULT WINAPI ACMStream_fnReadFormat(IAVIStream *iface, LONG pos,
					      LPVOID format, LONG *formatsize)
{
  IAVIStreamImpl *This = impl_from_IAVIStream(iface);

  TRACE("(%p,%d,%p,%p)\n", iface, pos, format, formatsize);

  if (formatsize == NULL)
    return AVIERR_BADPARAM;

  if (This->has == NULL) {
    HRESULT hr = AVIFILE_OpenCompressor(This);

    if (FAILED(hr))
      return hr;
  }

  /* only interested in needed buffersize? */
  if (format == NULL || *formatsize <= 0) {
    *formatsize = This->cbOutFormat;

    return AVIERR_OK;
  }

  /* copy initial format (only as much as will fit) */
  memcpy(format, This->lpOutFormat, min(*formatsize, This->cbOutFormat));
  if (*formatsize < This->cbOutFormat) {
    *formatsize = This->cbOutFormat;
    return AVIERR_BUFFERTOOSMALL;
  }

  *formatsize = This->cbOutFormat;
  return AVIERR_OK;
}

static HRESULT WINAPI ACMStream_fnSetFormat(IAVIStream *iface, LONG pos,
					     LPVOID format, LONG formatsize)
{
  IAVIStreamImpl *This = impl_from_IAVIStream(iface);

  HRESULT hr;

  TRACE("(%p,%d,%p,%d)\n", iface, pos, format, formatsize);

  /* check parameters */
  if (format == NULL || formatsize <= 0)
    return AVIERR_BADPARAM;

  /* Input format already known?
   * Changing is unsupported, but be quiet if it's the same */
  if (This->lpInFormat != NULL) {
    if (This->cbInFormat != formatsize ||
	memcmp(format, This->lpInFormat, formatsize) != 0)
      return AVIERR_UNSUPPORTED;

    return AVIERR_OK;
  }

  /* Does the nested stream support writing? */
  if ((This->sInfo.dwCaps & AVIFILECAPS_CANWRITE) == 0)
    return AVIERR_READONLY;

  This->lpInFormat = HeapAlloc(GetProcessHeap(), 0, formatsize);
  if (This->lpInFormat == NULL)
    return AVIERR_MEMORY;
  This->cbInFormat = formatsize;
  memcpy(This->lpInFormat, format, formatsize);

  /* initialize formats and get compressor */
  hr = AVIFILE_OpenCompressor(This);
  if (FAILED(hr))
    return hr;

  CONVERT_THIS_to_STREAM(&pos);

  /* tell the nested stream the new format */
  return IAVIStream_SetFormat(This->pStream, pos, This->lpOutFormat,
			      This->cbOutFormat);
}

static HRESULT WINAPI ACMStream_fnRead(IAVIStream *iface, LONG start,
					LONG samples, LPVOID buffer,
					LONG buffersize, LPLONG bytesread,
					LPLONG samplesread)
{
  IAVIStreamImpl *This = impl_from_IAVIStream(iface);

  HRESULT hr;
  DWORD   size;

  TRACE("(%p,%d,%d,%p,%d,%p,%p)\n", iface, start, samples, buffer,
 	buffersize, bytesread, samplesread);

  /* clear return parameters if given */
  if (bytesread != NULL)
    *bytesread = 0;
  if (samplesread != NULL)
    *samplesread = 0;

  /* Do we have our compressor? */
  if (This->has == NULL) {
    hr = AVIFILE_OpenCompressor(This);

    if (FAILED(hr))
      return hr;
  }

  /* only need to pass through? */
  if (This->cbInFormat == This->cbOutFormat &&
      memcmp(This->lpInFormat, This->lpOutFormat, This->cbInFormat) == 0) {
    return IAVIStream_Read(This->pStream, start, samples, buffer, buffersize,
			   bytesread, samplesread);
  }

  /* read as much as fit? */
  if (samples == -1)
    samples = buffersize / This->lpOutFormat->nBlockAlign;
  /* limit to buffersize */
  if (samples * This->lpOutFormat->nBlockAlign > buffersize)
    samples = buffersize / This->lpOutFormat->nBlockAlign;

  /* only return needed size? */
  if (buffer == NULL || buffersize <= 0 || samples == 0) {
    if (bytesread == NULL && samplesread == NULL)
      return AVIERR_BADPARAM;

    if (bytesread != NULL)
      *bytesread = samples * This->lpOutFormat->nBlockAlign;
    if (samplesread != NULL)
      *samplesread = samples;

    return AVIERR_OK;
  }

  /* map our positions to pStream positions */
  CONVERT_THIS_to_STREAM(&start);

  /* our needed internal buffersize */
  size = samples * This->lpInFormat->nBlockAlign;

  /* Need to free destination buffer used for writing? */
  if (This->acmStreamHdr.pbDst != NULL) {
    HeapFree(GetProcessHeap(), 0, This->acmStreamHdr.pbDst);
    This->acmStreamHdr.pbDst     = NULL;
    This->acmStreamHdr.dwDstUser = 0;
  }

  /* need bigger source buffer? */
  if (This->acmStreamHdr.pbSrc == NULL ||
      This->acmStreamHdr.dwSrcUser < size) {
    if (This->acmStreamHdr.pbSrc == NULL)
      This->acmStreamHdr.pbSrc = HeapAlloc(GetProcessHeap(), 0, size);
    else
      This->acmStreamHdr.pbSrc = HeapReAlloc(GetProcessHeap(), 0, This->acmStreamHdr.pbSrc, size);
    if (This->acmStreamHdr.pbSrc == NULL)
      return AVIERR_MEMORY;
    This->acmStreamHdr.dwSrcUser = size;
  }

  This->acmStreamHdr.cbStruct = sizeof(This->acmStreamHdr);
  This->acmStreamHdr.cbSrcLengthUsed = 0;
  This->acmStreamHdr.cbDstLengthUsed = 0;
  This->acmStreamHdr.cbSrcLength     = size;

  /* read source data */
  hr = IAVIStream_Read(This->pStream, start, -1, This->acmStreamHdr.pbSrc,
		       This->acmStreamHdr.cbSrcLength,
		       (LONG *)&This->acmStreamHdr.cbSrcLength, NULL);
  if (FAILED(hr) || This->acmStreamHdr.cbSrcLength == 0)
    return hr;

  /* need to prepare stream? */
  This->acmStreamHdr.pbDst       = buffer;
  This->acmStreamHdr.cbDstLength = buffersize;
  if ((This->acmStreamHdr.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED) == 0) {
    if (acmStreamPrepareHeader(This->has, &This->acmStreamHdr, 0) != S_OK) {
      This->acmStreamHdr.pbDst       = NULL;
      This->acmStreamHdr.cbDstLength = 0;
      return AVIERR_COMPRESSOR;
    }
  }

  /* now do the conversion */
  /* FIXME: use ACM_CONVERTF_* flags */
  if (acmStreamConvert(This->has, &This->acmStreamHdr, 0) != S_OK)
    hr = AVIERR_COMPRESSOR;

  This->acmStreamHdr.pbDst       = NULL;
  This->acmStreamHdr.cbDstLength = 0;

  /* fill out return parameters if given */
  if (bytesread != NULL)
    *bytesread = This->acmStreamHdr.cbDstLengthUsed;
  if (samplesread != NULL)
    *samplesread =
      This->acmStreamHdr.cbDstLengthUsed / This->lpOutFormat->nBlockAlign;

  return hr;
}

static HRESULT WINAPI ACMStream_fnWrite(IAVIStream *iface, LONG start,
					 LONG samples, LPVOID buffer,
					 LONG buffersize, DWORD flags,
					 LPLONG sampwritten,
					 LPLONG byteswritten)
{
  IAVIStreamImpl *This = impl_from_IAVIStream(iface);

  HRESULT hr;
  ULONG   size;

  TRACE("(%p,%d,%d,%p,%d,0x%08X,%p,%p)\n", iface, start, samples,
	buffer, buffersize, flags, sampwritten, byteswritten);

  /* clear return parameters if given */
  if (sampwritten != NULL)
    *sampwritten = 0;
  if (byteswritten != NULL)
    *byteswritten = 0;

  /* check parameters */
  if (buffer == NULL && (buffersize > 0 || samples > 0))
    return AVIERR_BADPARAM;

  /* Have we write capability? */
  if ((This->sInfo.dwCaps & AVIFILECAPS_CANWRITE) == 0)
    return AVIERR_READONLY;

  /* also need a compressor */
  if (This->has == NULL)
    return AVIERR_NOCOMPRESSOR;

  /* map our sizes to pStream sizes */
  size = buffersize;
  CONVERT_THIS_to_STREAM(&size);
  CONVERT_THIS_to_STREAM(&start);

  /* no bytes to write? -- short circuit */
  if (size == 0) {
    return IAVIStream_Write(This->pStream, -1, samples, buffer, size,
			    flags, sampwritten, byteswritten);
  }

  /* Need to free source buffer used for reading? */
  if (This->acmStreamHdr.pbSrc != NULL) {
    HeapFree(GetProcessHeap(), 0, This->acmStreamHdr.pbSrc);
    This->acmStreamHdr.pbSrc     = NULL;
    This->acmStreamHdr.dwSrcUser = 0;
  }

  /* Need bigger destination buffer? */
  if (This->acmStreamHdr.pbDst == NULL ||
      This->acmStreamHdr.dwDstUser < size) {
    if (This->acmStreamHdr.pbDst == NULL)
      This->acmStreamHdr.pbDst = HeapAlloc(GetProcessHeap(), 0, size);
    else
      This->acmStreamHdr.pbDst = HeapReAlloc(GetProcessHeap(), 0, This->acmStreamHdr.pbDst, size);
    if (This->acmStreamHdr.pbDst == NULL)
      return AVIERR_MEMORY;
    This->acmStreamHdr.dwDstUser = size;
  }
  This->acmStreamHdr.cbStruct        = sizeof(This->acmStreamHdr);
  This->acmStreamHdr.cbSrcLengthUsed = 0;
  This->acmStreamHdr.cbDstLengthUsed = 0;
  This->acmStreamHdr.cbDstLength     = This->acmStreamHdr.dwDstUser;

  /* need to prepare stream? */
  This->acmStreamHdr.pbSrc       = buffer;
  This->acmStreamHdr.cbSrcLength = buffersize;
  if ((This->acmStreamHdr.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED) == 0) {
    if (acmStreamPrepareHeader(This->has, &This->acmStreamHdr, 0) != S_OK) {
      This->acmStreamHdr.pbSrc       = NULL;
      This->acmStreamHdr.cbSrcLength = 0;
      return AVIERR_COMPRESSOR;
    }
  }

  /* now do the conversion */
  /* FIXME: use ACM_CONVERTF_* flags */
  if (acmStreamConvert(This->has, &This->acmStreamHdr, 0) != S_OK)
    hr = AVIERR_COMPRESSOR;
  else
    hr = AVIERR_OK;

  This->acmStreamHdr.pbSrc       = NULL;
  This->acmStreamHdr.cbSrcLength = 0;

  if (FAILED(hr))
    return hr;

  return IAVIStream_Write(This->pStream,-1,This->acmStreamHdr.cbDstLengthUsed /
			  This->lpOutFormat->nBlockAlign,This->acmStreamHdr.pbDst,
			  This->acmStreamHdr.cbDstLengthUsed,flags,sampwritten,
			  byteswritten);
}

static HRESULT WINAPI ACMStream_fnDelete(IAVIStream *iface, LONG start,
					  LONG samples)
{
  IAVIStreamImpl *This = impl_from_IAVIStream(iface);

  TRACE("(%p,%d,%d)\n", iface, start, samples);

  /* check parameters */
  if (start < 0 || samples < 0)
    return AVIERR_BADPARAM;

  /* Delete before start of stream? */
  if ((DWORD)(start + samples) < This->sInfo.dwStart)
    return AVIERR_OK;

  /* Delete after end of stream? */
  if ((DWORD)start > This->sInfo.dwLength)
    return AVIERR_OK;

  /* For the rest we need write capability */
  if ((This->sInfo.dwCaps & AVIFILECAPS_CANWRITE) == 0)
    return AVIERR_READONLY;

  /* A compressor is also necessary */
  if (This->has == NULL)
    return AVIERR_NOCOMPRESSOR;

  /* map our positions to pStream positions */
  CONVERT_THIS_to_STREAM(&start);
  CONVERT_THIS_to_STREAM(&samples);

  return IAVIStream_Delete(This->pStream, start, samples);
}

static HRESULT WINAPI ACMStream_fnReadData(IAVIStream *iface, DWORD fcc,
					    LPVOID lp, LPLONG lpread)
{
  IAVIStreamImpl *This = impl_from_IAVIStream(iface);

  TRACE("(%p,0x%08X,%p,%p)\n", iface, fcc, lp, lpread);

  assert(This->pStream != NULL);

  return IAVIStream_ReadData(This->pStream, fcc, lp, lpread);
}

static HRESULT WINAPI ACMStream_fnWriteData(IAVIStream *iface, DWORD fcc,
					     LPVOID lp, LONG size)
{
  IAVIStreamImpl *This = impl_from_IAVIStream(iface);

  TRACE("(%p,0x%08x,%p,%d)\n", iface, fcc, lp, size);

  assert(This->pStream != NULL);

  return IAVIStream_WriteData(This->pStream, fcc, lp, size);
}

static HRESULT WINAPI ACMStream_fnSetInfo(IAVIStream *iface,
					   LPAVISTREAMINFOW info, LONG infolen)
{
  FIXME("(%p,%p,%d): stub\n", iface, info, infolen);

  return E_FAIL;
}

static const struct IAVIStreamVtbl iacmst = {
  ACMStream_fnQueryInterface,
  ACMStream_fnAddRef,
  ACMStream_fnRelease,
  ACMStream_fnCreate,
  ACMStream_fnInfo,
  ACMStream_fnFindSample,
  ACMStream_fnReadFormat,
  ACMStream_fnSetFormat,
  ACMStream_fnRead,
  ACMStream_fnWrite,
  ACMStream_fnDelete,
  ACMStream_fnReadData,
  ACMStream_fnWriteData,
  ACMStream_fnSetInfo
};

HRESULT AVIFILE_CreateACMStream(REFIID riid, LPVOID *ppv)
{
  IAVIStreamImpl *pstream;
  HRESULT         hr;

  assert(riid != NULL && ppv != NULL);

  *ppv = NULL;

  pstream = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAVIStreamImpl));
  if (pstream == NULL)
    return AVIERR_MEMORY;

  pstream->IAVIStream_iface.lpVtbl = &iacmst;

  hr = IAVIStream_QueryInterface(&pstream->IAVIStream_iface, riid, ppv);
  if (FAILED(hr))
    HeapFree(GetProcessHeap(), 0, pstream);

  return hr;
}
