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