Пример #1
0
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->lpVtbl = &iacmst;

  hr = IAVIStream_QueryInterface((IAVIStream*)pstream, riid, ppv);
  if (FAILED(hr))
    HeapFree(GetProcessHeap(), 0, pstream);

  return hr;
}
Пример #2
0
static HRESULT WINAPI IAVIEditStream_fnPaste(IAVIEditStream*iface,LONG*plStart,
                                             LONG*plLength,PAVISTREAM pSource,
                                             LONG lStart,LONG lLength)
{
  IAVIEditStreamImpl *This = impl_from_IAVIEditStream(iface);
  AVISTREAMINFOW      srcInfo;
  IAVIEditStreamImpl *pEdit = NULL;
  PAVISTREAM          pStream;
  DWORD               startPos, endPos, streamNr, nStreams;
  ULONG               n;

  TRACE("(%p,%p,%p,%p,%d,%d)\n",iface,plStart,plLength,
	pSource,lStart,lLength);

  if (pSource == NULL)
    return AVIERR_BADHANDLE;
  if (plStart == NULL || *plStart < 0)
    return AVIERR_BADPARAM;
  if (This->sInfo.dwStart + This->sInfo.dwLength < *plStart)
    return AVIERR_BADPARAM; /* Can't paste with holes */
  if (FAILED(IAVIStream_Info(pSource, &srcInfo, sizeof(srcInfo))))
    return AVIERR_ERROR;
  if (lStart < srcInfo.dwStart || lStart >= srcInfo.dwStart + srcInfo.dwLength)
    return AVIERR_BADPARAM;
  if (This->sInfo.fccType == 0) {
    /* This stream is empty */
    IAVIStream_Info(pSource, &This->sInfo, sizeof(This->sInfo));
    This->sInfo.dwStart  = *plStart;
    This->sInfo.dwLength = 0;
  }
  if (This->sInfo.fccType != srcInfo.fccType)
    return AVIERR_UNSUPPORTED; /* different stream types */
  if (lLength == -1) /* Copy the hole stream */
    lLength = srcInfo.dwLength;
  if (lStart + lLength > srcInfo.dwStart + srcInfo.dwLength)
    lLength = srcInfo.dwStart + srcInfo.dwLength - lStart;
  if (lLength + *plStart >= 0x80000000)
    return AVIERR_MEMORY;

  /* streamtype specific tests */
  if (srcInfo.fccType == streamtypeVIDEO) {
    LONG size;

    size = srcInfo.rcFrame.right - srcInfo.rcFrame.left;
    if (size != This->sInfo.rcFrame.right - This->sInfo.rcFrame.left)
      return AVIERR_UNSUPPORTED; /* FIXME: Can't GetFrame convert it? */
    size = srcInfo.rcFrame.bottom - srcInfo.rcFrame.top;
    if (size != This->sInfo.rcFrame.bottom - This->sInfo.rcFrame.top)
      return AVIERR_UNSUPPORTED; /* FIXME: Can't GetFrame convert it? */
  } else if (srcInfo.fccType == streamtypeAUDIO) {
    if (!AVIFILE_FormatsEqual(&This->IAVIStream_iface, pSource))
      return AVIERR_UNSUPPORTED;
  } else {
    /* FIXME: streamtypeMIDI and streamtypeTEXT */
    return AVIERR_UNSUPPORTED;
  }

  /* try to get an IEditStreamInternal interface */
  if (SUCCEEDED(IAVIStream_QueryInterface(pSource, &IID_IEditStreamInternal, (LPVOID*)&pEdit)))
      IAVIEditStream_Release(&pEdit->IAVIEditStream_iface);  /* pSource holds a reference */

  /* for video must check for change of format */
  if (This->sInfo.fccType == streamtypeVIDEO) {
    if (! This->bDecompress) {
      /* Need to decompress if any of the following conditions matches:
       *  - pSource is an editable stream which decompresses
       *  - the nearest keyframe of pSource isn't lStart
       *  - the nearest keyframe of this stream isn't *plStart
       *  - the format of pSource doesn't match this one
       */
      if ((pEdit != NULL && pEdit->bDecompress) ||
	  AVIStreamNearestKeyFrame(pSource, lStart) != lStart ||
          AVIStreamNearestKeyFrame(&This->IAVIStream_iface, *plStart) != *plStart ||
          (This->nStreams > 0 && !AVIFILE_FormatsEqual(&This->IAVIStream_iface, pSource))) {
	/* Use first stream part to get format to convert everything to */
	AVIFILE_ReadFrame(This, This->pStreams[0].pStream,
			  This->pStreams[0].dwStart);

	/* Check if we could convert the source streams to the desired format... */
	if (pEdit != NULL) {
	  if (FAILED(AVIFILE_FindStreamInTable(pEdit, lStart, &pStream,
					       &startPos, &streamNr, TRUE)))
	    return AVIERR_INTERNAL;
	  for (n = lStart; n < lStart + lLength; streamNr++) {
	    if (AVIFILE_ReadFrame(This, pEdit->pStreams[streamNr].pStream, startPos) == NULL)
	      return AVIERR_BADFORMAT;
	    startPos = pEdit->pStreams[streamNr].dwStart;
	    n += pEdit->pStreams[streamNr].dwLength;
	  }
	} else if (AVIFILE_ReadFrame(This, pSource, lStart) == NULL)
	  return AVIERR_BADFORMAT;

	This->bDecompress      = TRUE;
	This->sInfo.fccHandler = 0;
      }
    } else if (AVIFILE_ReadFrame(This, pSource, lStart) == NULL)
      return AVIERR_BADFORMAT; /* Can't convert source to own format */
  } /* FIXME: something special for the other formats? */

  /* Make sure we have enough memory for parts */
  if (pEdit != NULL) {
    DWORD nLastStream;

    AVIFILE_FindStreamInTable(pEdit, lStart + lLength, &pStream,
			      &endPos, &nLastStream, TRUE);
    AVIFILE_FindStreamInTable(pEdit, lStart, &pStream,
			      &startPos, &streamNr, FALSE);
    if (nLastStream == streamNr)
      nLastStream++;

    nStreams = nLastStream - streamNr;
  } else 
    nStreams = 1;
  if (This->nStreams + nStreams + 1 > This->nTableSize) {
    n = This->nStreams + nStreams + 33;

    This->pStreams = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pStreams, n * sizeof(EditStreamTable));
    if (This->pStreams == NULL)
      return AVIERR_MEMORY;
    This->nTableSize = n;
  }

  if (plLength != NULL)
    *plLength = lLength;

  /* now do the real work */
  if (This->sInfo.dwStart + This->sInfo.dwLength > *plStart) {
    AVIFILE_FindStreamInTable(This, *plStart, &pStream,
			      &startPos, &streamNr, FALSE);
    if (startPos != This->pStreams[streamNr].dwStart) {
      /* split stream streamNr at startPos */
      memmove(This->pStreams + streamNr + nStreams + 1,
	      This->pStreams + streamNr,
	      (This->nStreams + nStreams - streamNr + 1) * sizeof(EditStreamTable));

      This->pStreams[streamNr + 2].dwLength =
	EditStreamEnd(This, streamNr + 2) - startPos;
      This->pStreams[streamNr + 2].dwStart = startPos;
      This->pStreams[streamNr].dwLength =
	startPos - This->pStreams[streamNr].dwStart;
      IAVIStream_AddRef(This->pStreams[streamNr].pStream);
      streamNr++;
    } else {
      /* insert before stream at streamNr */
      memmove(This->pStreams + streamNr + nStreams, This->pStreams + streamNr,
	      (This->nStreams + nStreams - streamNr) * sizeof(EditStreamTable));
    }
  } else /* append the streams */
    streamNr = This->nStreams;

  if (pEdit != NULL) {
    /* insert the parts of the editable stream instead of itself */
    AVIFILE_FindStreamInTable(pEdit, lStart + lLength, &pStream,
			      &endPos, NULL, FALSE);
    AVIFILE_FindStreamInTable(pEdit, lStart, &pStream, &startPos, &n, FALSE);

    memcpy(This->pStreams + streamNr, pEdit->pStreams + n,
	   nStreams * sizeof(EditStreamTable));
    if (This->pStreams[streamNr].dwStart < startPos) {
      This->pStreams[streamNr].dwLength =
	EditStreamEnd(This, streamNr) - startPos;
      This->pStreams[streamNr].dwStart  = startPos;
    }
    if (endPos < EditStreamEnd(This, streamNr + nStreams))
      This->pStreams[streamNr + nStreams].dwLength =
	endPos - This->pStreams[streamNr + nStreams].dwStart;
  } else {
    /* a simple stream */
    This->pStreams[streamNr].pStream  = pSource;
    This->pStreams[streamNr].dwStart  = lStart;
    This->pStreams[streamNr].dwLength = lLength;
  }

  for (n = 0; n < nStreams; n++) {
    IAVIStream_AddRef(This->pStreams[streamNr + n].pStream);
    if (0 < streamNr + n &&
	This->pStreams[streamNr + n - 1].pStream != This->pStreams[streamNr + n].pStream) {
      This->sInfo.dwFlags |= AVISTREAMINFO_FORMATCHANGES;
      This->sInfo.dwFormatChangeCount++;
    }
  }
  This->sInfo.dwEditCount++;
  This->sInfo.dwLength += lLength;
  This->nStreams += nStreams;

  return AVIERR_OK;
}