Beispiel #1
0
static void vfw_shutdown()
{
	int i;
	
	for(i=0; i<vfw_n_hicd; i++)
		ICDecompressEnd(vfw_hicd[i]);
}
Beispiel #2
0
// uninit driver
static void uninit(sh_video_t *sh){
    HRESULT ret;
    vd_vfw_ctx *priv = sh->context;

#ifdef BUILD_VFWEX
    ret = ICDecompressEndEx(priv->handle);
#else
    ret = ICDecompressEnd(priv->handle);
#endif
    if (ret)
    {
	mp_msg(MSGT_WIN32, MSGL_WARN, "ICDecompressEnd failed: %ld\n", ret);
	return;
    }

    ret = ICClose(priv->handle);
    if (ret)
    {
	mp_msg(MSGT_WIN32, MSGL_WARN, "ICClose failed: %ld\n", ret);
	return;
    }

    free(priv->o_bih);
    free(priv);
}
Beispiel #3
0
void CMainFrame::OnClose()
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	capCaptureAbort(m_hWndCap);
	capDriverDisconnect(m_hWndCap);
	Sleep(100);
	capSetCallbackOnError(m_hWndCap,NULL);
	capSetCallbackOnStatus(m_hWndCap,NULL);
	capSetCallbackOnVideoStream(m_hWndCap,NULL);
	delete lpbiIn;
	delete lpbiTmp;
	delete lpbiOut;
	if (m_vfwState==ENCDEC){
		ICDecompressEnd(hic2);
		ICClose(hic2);
		ICSeqCompressFrameEnd(&pc);
		ICCompressEnd(hic1);
		ICClose(hic1);
		AVIStreamClose(ps);
		if(m_pFile != NULL)
			AVIFileRelease(m_pFile);
	}

	enc_stop();
	dec_stop();

	Sleep(100);
	CFrameWnd::OnClose();
}
Beispiel #4
0
void CvCaptureCAM_VFW::closeHIC()
{
    if( hic )
    {
        ICDecompressEnd( hic );
        ICClose( hic );
        hic = 0;
    }
}
Beispiel #5
0
void cap_ic_finish(cap_cx *cx)
{
	if(cx->mode == CAP_USE_IC)
	{
		ICDecompressEnd(cx->ic);
		free(cx->poutfmt);
		ICClose(cx->ic);
	}
}
Beispiel #6
0
static ULONG WINAPI ICMStream_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->pg != NULL) {
      AVIStreamGetFrameClose(This->pg);
      This->pg = NULL;
    }
    if (This->pStream != NULL) {
      IAVIStream_Release(This->pStream);
      This->pStream = NULL;
    }
    if (This->hic != NULL) {
      if (This->lpbiPrev != NULL) {
	ICDecompressEnd(This->hic);
	HeapFree(GetProcessHeap(), 0, This->lpbiPrev);
	This->lpbiPrev = NULL;
	This->lpPrev   = NULL;
      }
      ICCompressEnd(This->hic);
      This->hic = NULL;
    }
    if (This->lpbiCur != NULL) {
      HeapFree(GetProcessHeap(), 0, This->lpbiCur);
      This->lpbiCur = NULL;
      This->lpCur   = NULL;
    }
    if (This->lpbiOutput != NULL) {
      HeapFree(GetProcessHeap(), 0, This->lpbiOutput);
      This->lpbiOutput = NULL;
      This->cbOutput   = 0;
    }
    if (This->lpbiInput != NULL) {
      HeapFree(GetProcessHeap(), 0, This->lpbiInput);
      This->lpbiInput = NULL;
      This->cbInput   = 0;
    }

    HeapFree(GetProcessHeap(), 0, This);

    return 0;
  }

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

  return ref;
}
Beispiel #7
0
static void AVIFILE_CloseCompressor(IGetFrameImpl *This)
{
  if (This->lpInFormat != This->lpOutFormat) {
    HeapFree(GetProcessHeap(), 0, This->lpOutFormat);
    This->lpOutFormat = NULL;
  }
  HeapFree(GetProcessHeap(), 0, This->lpInFormat);
  This->lpInFormat = NULL;
  if (This->hic != NULL) {
    if (This->bResize)
      ICDecompressExEnd(This->hic);
    else
      ICDecompressEnd(This->hic);
    ICClose(This->hic);
    This->hic = NULL;
  }
}
Beispiel #8
0
static HRESULT WINAPI AVIDec_StopStreaming(TransformFilter* pTransformFilter)
{
    AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
    DWORD result;

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

    if (!This->hvid)
        return S_OK;

    result = ICDecompressEnd(This->hvid);
    if (result != ICERR_OK)
    {
        ERR("Cannot stop processing (%d)\n", result);
        return E_FAIL;
    }
    return S_OK;
}
Beispiel #9
0
/***********************************************************************
 *		DrawDibEnd		[MSVFW32.@]
 */
BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd) 
{
    BOOL ret = TRUE;
    WINE_HDD *whdd = MSVIDEO_GetHddPtr(hdd);

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

    if (!whdd) return FALSE;

    whdd->hpal = 0; /* Do not free this */
    whdd->hdc = 0;
    HeapFree(GetProcessHeap(), 0, whdd->lpbi);
    whdd->lpbi = NULL;
    HeapFree(GetProcessHeap(), 0, whdd->lpbiOut);
    whdd->lpbiOut = NULL;

    whdd->begun = FALSE;

    /*if (whdd->lpvbits)
      HeapFree(GetProcessHeap(), 0, whdd->lpvbuf);*/

    if (whdd->hMemDC) 
    {
        SelectObject(whdd->hMemDC, whdd->hOldDib);
        DeleteDC(whdd->hMemDC);
        whdd->hMemDC = 0;
    }

    if (whdd->hDib) DeleteObject(whdd->hDib);
    whdd->hDib = 0;

    if (whdd->hic) 
    {
        ICDecompressEnd(whdd->hic);
        ICClose(whdd->hic);
        whdd->hic = 0;
    }

    whdd->lpvbits = NULL;

    return ret;
}
Beispiel #10
0
	~win_movie_Rec()
	{
		if(bAudio)
		{
			#ifdef SND_USE_FMOD
			if(fmod_stream)
				FSOUND_Stream_Close(fmod_stream);
			#endif

			acmStreamUnprepareHeader(acmStream,&audioStreamHeader,0);
			acmStreamClose(acmStream,0);

			delete[] audioDecoded;
			delete[] audioEncoded;

			AVIStreamRelease(audioStream);
		}

		if(bDecompStarted)
			ICDecompressEnd(hIC);
		if(hIC)
			ICClose(hIC);
		if(outdata) GlobalFreePtr(outdata);
		if(indata) GlobalFreePtr(indata);
		if(stream)
			AVIStreamRelease(stream);
		if(avi)
			AVIFileRelease(avi);
		if(img)
		{
			FreeImageHandle(imgHandle);
			delete img;
		}

		if(handle != 0)
			Handle::free(HANDLE_TYPE_MOVIE,handle);
	}
std::shared_ptr<WatermarkSearchResult> WatermarkSearchWorker::findWatermark(int width, int height)
{
    std::shared_ptr<WatermarkSearchResult> r = std::make_shared<WatermarkSearchResult>();
    r->size_.width_ = width;
    r->size_.height_ = height;

    int const bytesPerPixel = 4;
    int const scanlineSizeInBytes = width * bytesPerPixel;

    BITMAPINFOHEADER inputFormat;
    ZeroMemory(&inputFormat, sizeof(inputFormat));
    inputFormat.biSize = sizeof(inputFormat);
    inputFormat.biWidth = width;
    inputFormat.biHeight = height;
    inputFormat.biPlanes = 1;
    inputFormat.biBitCount = 8 * bytesPerPixel;
    inputFormat.biCompression = BI_RGB;
    inputFormat.biSizeImage = scanlineSizeInBytes * height;

    DWORD const size = ICCompressGetFormatSize(compressor_, &inputFormat);
    if (size == 0 || (size & 0xFFFF0000) == 0xFFFF0000) {
        return r;
    }
    std::vector<uint8_t> outputFormatStorage(size);
    LPBITMAPINFOHEADER outputFormat = (LPBITMAPINFOHEADER)(BITMAPINFO*)outputFormatStorage.data();
    if (ICCompressGetFormat(compressor_, &inputFormat, outputFormat) != ICERR_OK) {
        return r;
    }

    DWORD const outputSize = ICCompressGetSize(compressor_, &inputFormat, outputFormat);
    if (outputSize < 0) {
        return r;
    }

    if (outputBuffer_.size() < outputSize) {
        outputBuffer_.resize(outputSize);
    }
    if (inputBuffer_.size() < inputFormat.biSizeImage) {
        inputBuffer_.resize(inputFormat.biSizeImage);
    }
    std::fill(inputBuffer_.begin(), inputBuffer_.begin() + inputFormat.biSizeImage, (uint8_t)0xff);

    if (ICCompressBegin(compressor_, &inputFormat, outputFormat) != ICERR_OK) {
        return r;
    }

    DWORD flags = 0;
    DWORD dwckid = 0;

    DWORD result = ICCompress(compressor_,
                              0, // dwFlags
                              outputFormat,
                              outputBuffer_.data(),
                              &inputFormat,
                              inputBuffer_.data(),
                              &dwckid,
                              &flags,
                              0, // lpFrameNum
                              0, // dwFrameSize
                              0, // dwQuality
                              nullptr, // lpbiPrev
                              nullptr); // lpPrev
    if (result != ICERR_OK) {
        return r;
    }

    if (ICCompressEnd(compressor_) != ICERR_OK) {
        return r;
    }

    if (ICDecompressBegin(decompressor_, outputFormat, &inputFormat) != ICERR_OK) {
        return r;
    }

    std::fill(inputBuffer_.begin(), inputBuffer_.begin() + inputFormat.biSizeImage, (uint8_t)0xff);
    if (ICDecompress(decompressor_, 0, outputFormat, outputBuffer_.data(), &inputFormat, inputBuffer_.data()) != ICERR_OK) {
        return r;
    }

    if (ICDecompressEnd(decompressor_) != ICERR_OK) {
        return r;
    }

    // Search left edge of watermark
    int left = -1;
    for (int x = 0; x < width; ++x) {
        bool found = false;
        for (int y = 0; y < height; ++y) {
            for (int j = 0; j < bytesPerPixel; ++j) {
                int index = scanlineSizeInBytes * y + x * bytesPerPixel + j;
                if (inputBuffer_[index] != (uint8_t)0xff) {
                    found = true;
                    left = x;
                    break;
                }
            }
            if (found) {
                break;
            }
        }
        if (found) {
            break;
        }
    }
    if (left < 0) {
        return r;
    }

    // Search right edge of watermark
    int right = -1;
    for (int x = width - 1; x >= 0; --x) {
        bool found = false;
        for (int y = 0; y < height; ++y) {
            for (int j = 0; j < bytesPerPixel; ++j) {
                int index = scanlineSizeInBytes * y + x * bytesPerPixel + j;
                if (inputBuffer_[index] != (uint8_t)0xff) {
                    found = true;
                    right = x;
                    break;
                }
            }
            if (found) {
                break;
            }
        }
        if (found) {
            break;
        }
    }
    if (right < 0) {
        return r;
    }

    // Search top edge of watermark
    int top = -1;
    for (int y = 0; y < height; ++y) {
        bool found = false;
        for (int x = 0; x < width; ++x) {
            for (int j = 0; j < bytesPerPixel; ++j) {
                int index = scanlineSizeInBytes * y + x * bytesPerPixel + j;
                if (inputBuffer_[index] != (uint8_t)0xff) {
                    found = true;
                    top = y;
                    break;
                }
            }
            if (found) {
                break;
            }
        }
        if (found) {
            break;
        }
    }
    if (top < 0) {
        return r;
    }

    // Search bottom edge of watermark
    int bottom = -1;
    for (int y = height - 1; y >= 0; --y) {
        bool found = false;
        for (int x = 0; x < width; ++x) {
            for (int j = 0; j < bytesPerPixel; ++j) {
                int index = scanlineSizeInBytes * y + x * bytesPerPixel + j;
                if (inputBuffer_[index] != (uint8_t)0xff) {
                    found = true;
                    bottom = y;
                    break;
                }
            }
            if (found) {
                break;
            }
        }
        if (found) {
            break;
        }
    }
    if (top < 0) {
        return r;
    }

    r->x_ = left;
    r->y_ = top;

    int const watermarkWidth = right - left + 1;
    int const watermarkHeight = bottom - top + 1;
    r->width_ = watermarkWidth;
    r->height_ = watermarkHeight;

    r->watermark_ = std::make_shared<Bitmap>(watermarkWidth, watermarkHeight);
    for (int y = 0; y < watermarkHeight; ++y) {
        for (int x = 0; x < watermarkWidth; ++x) {
            int index = scanlineSizeInBytes * (y + top) + (x + left) * bytesPerPixel;
            uint8_t red = inputBuffer_[index];
            uint8_t green = inputBuffer_[index + 1];
            uint8_t blue = inputBuffer_[index + 2];
            r->watermark_->setPixel(x, watermarkHeight - y - 1, Color{ red, green, blue });
        }
    }
    return r;
}
Beispiel #12
0
HANDLE VFWAPI ICImageDecompress(
	HIC hic, UINT uiFlags, LPBITMAPINFO lpbiIn,
	LPVOID lpBits, LPBITMAPINFO lpbiOut)
{
	HGLOBAL	hMem = NULL;
	BYTE*	pMem = NULL;
	BOOL	bReleaseIC = FALSE;
	BYTE*	pHdr = NULL;
	ULONG	cbHdr = 0;
	BOOL	bSucceeded = FALSE;
	BOOL	bInDecompress = FALSE;
	DWORD	biSizeImage;

	TRACE("(%p,%08x,%p,%p,%p)\n",
		hic, uiFlags, lpbiIn, lpBits, lpbiOut);

	if ( hic == NULL )
	{
		hic = ICDecompressOpen( ICTYPE_VIDEO, 0, &lpbiIn->bmiHeader, (lpbiOut != NULL) ? &lpbiOut->bmiHeader : NULL );
		if ( hic == NULL )
		{
			WARN("no handler\n" );
			goto err;
		}
		bReleaseIC = TRUE;
	}
	if ( uiFlags != 0 )
	{
		FIXME( "unknown flag %08x\n", uiFlags );
		goto err;
	}
	if ( lpbiIn == NULL || lpBits == NULL )
	{
		WARN("invalid argument\n");
		goto err;
	}

	if ( lpbiOut != NULL )
	{
		if ( lpbiOut->bmiHeader.biSize != sizeof(BITMAPINFOHEADER) )
			goto err;
		cbHdr = sizeof(BITMAPINFOHEADER);
		if ( lpbiOut->bmiHeader.biCompression == 3 )
			cbHdr += sizeof(DWORD)*3;
		else
		if ( lpbiOut->bmiHeader.biBitCount <= 8 )
		{
			if ( lpbiOut->bmiHeader.biClrUsed == 0 )
				cbHdr += sizeof(RGBQUAD) * (1<<lpbiOut->bmiHeader.biBitCount);
			else
				cbHdr += sizeof(RGBQUAD) * lpbiOut->bmiHeader.biClrUsed;
		}
	}
	else
	{
		TRACE( "get format\n" );

		cbHdr = ICDecompressGetFormatSize(hic,lpbiIn);
		if ( cbHdr < sizeof(BITMAPINFOHEADER) )
			goto err;
		pHdr = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,cbHdr+sizeof(RGBQUAD)*256);
		if ( pHdr == NULL )
			goto err;
		if ( ICDecompressGetFormat( hic, lpbiIn, pHdr ) != ICERR_OK )
			goto err;
		lpbiOut = (BITMAPINFO*)pHdr;
		if ( lpbiOut->bmiHeader.biBitCount <= 8 &&
			 ICDecompressGetPalette( hic, lpbiIn, lpbiOut ) != ICERR_OK &&
			 lpbiIn->bmiHeader.biBitCount == lpbiOut->bmiHeader.biBitCount )
		{
			if ( lpbiIn->bmiHeader.biClrUsed == 0 )
				memcpy( lpbiOut->bmiColors, lpbiIn->bmiColors, sizeof(RGBQUAD)*(1<<lpbiOut->bmiHeader.biBitCount) );
			else
				memcpy( lpbiOut->bmiColors, lpbiIn->bmiColors, sizeof(RGBQUAD)*lpbiIn->bmiHeader.biClrUsed );
		}
		if ( lpbiOut->bmiHeader.biBitCount <= 8 &&
			 lpbiOut->bmiHeader.biClrUsed == 0 )
			lpbiOut->bmiHeader.biClrUsed = 1<<lpbiOut->bmiHeader.biBitCount;

		lpbiOut->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		cbHdr = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*lpbiOut->bmiHeader.biClrUsed;
	}

	biSizeImage = lpbiOut->bmiHeader.biSizeImage;
	if ( biSizeImage == 0 )
		biSizeImage = ((((lpbiOut->bmiHeader.biWidth * lpbiOut->bmiHeader.biBitCount + 7) >> 3) + 3) & (~3)) * abs(lpbiOut->bmiHeader.biHeight);

	TRACE( "call ICDecompressBegin\n" );

	if ( ICDecompressBegin( hic, lpbiIn, lpbiOut ) != ICERR_OK )
		goto err;
	bInDecompress = TRUE;

	TRACE( "cbHdr %d, biSizeImage %d\n", cbHdr, biSizeImage );

	hMem = GlobalAlloc( GMEM_MOVEABLE|GMEM_ZEROINIT, cbHdr + biSizeImage );
	if ( hMem == NULL )
	{
		WARN( "out of memory\n" );
		goto err;
	}
	pMem = GlobalLock( hMem );
	if ( pMem == NULL )
		goto err;
	memcpy( pMem, lpbiOut, cbHdr );

	TRACE( "call ICDecompress\n" );
	if ( ICDecompress( hic, 0, &lpbiIn->bmiHeader, lpBits, &lpbiOut->bmiHeader, pMem+cbHdr ) != ICERR_OK )
		goto err;

	bSucceeded = TRUE;
err:
	if ( bInDecompress )
		ICDecompressEnd( hic );
	if ( bReleaseIC )
		ICClose(hic);
        HeapFree(GetProcessHeap(),0,pHdr);
	if ( pMem != NULL )
		GlobalUnlock( hMem );
	if ( !bSucceeded && hMem != NULL )
	{
		GlobalFree(hMem); hMem = NULL;
	}

	return hMem;
}
BOOST_DATA_TEST_CASE(vcm_encdec, make_data_from_tuple_container(vecEncDecClips), src, dst, fmt, config, tolerance)
{
	VideoClip srcClip(src);
	VideoClip dstClip(dst);
	DWORD fccCodec = FCC(fmt);

	BOOST_REQUIRE(srcClip.GetWidth() == dstClip.GetWidth());
	BOOST_REQUIRE(srcClip.GetHeight() == dstClip.GetHeight());

	DWORD fccSrc = srcClip.GetFourCC();
	DWORD fccDst = dstClip.GetFourCC();
	unsigned int nWidth = srcClip.GetWidth();
	unsigned int nHeight = srcClip.GetHeight();

	size_t cbSrcData;
	size_t cbDstData;
	size_t cbCompressedData;

	HIC hicEncode, hicDecode;
	LRESULT lr;
	union
	{
		BITMAPINFOHEADER bihCompressed;
		char bihCompressedBuf[128];
	};
	BITMAPINFOHEADER bihSrc;
	BITMAPINFOHEADER bihDst;

	hicEncode = ICOpen(ICTYPE_VIDEO, fccCodec, ICMODE_COMPRESS);
	BOOST_REQUIRE(hicEncode != NULL);
	ICCloser iccloserEnc(hicEncode);

	lr = ICSetState(hicEncode, &config.front(), config.size());
	BOOST_REQUIRE(lr == config.size());

	hicDecode = ICOpen(ICTYPE_VIDEO, fccCodec, ICMODE_DECOMPRESS);
	BOOST_REQUIRE(hicDecode != NULL);
	ICCloser iccloserDec(hicDecode);

	memset(&bihSrc, 0, sizeof(BITMAPINFOHEADER));
	bihSrc.biSize = sizeof(BITMAPINFOHEADER);
	bihSrc.biWidth = nWidth;
	bihSrc.biHeight = nHeight;
	bihSrc.biPlanes = 1;
	bihSrc.biBitCount = FCC2BitCount(fccSrc);
	bihSrc.biCompression = FCC2Compression(fccSrc);
	bihSrc.biSizeImage = 10000000;

	memset(&bihDst, 0, sizeof(BITMAPINFOHEADER));
	bihDst.biSize = sizeof(BITMAPINFOHEADER);
	bihDst.biWidth = nWidth;
	bihDst.biHeight = nHeight;
	bihDst.biPlanes = 1;
	bihDst.biBitCount = FCC2BitCount(fccDst);
	bihDst.biCompression = FCC2Compression(fccDst);
	bihDst.biSizeImage = 10000000;

	lr = ICCompressGetFormat(hicEncode, &bihSrc, &bihCompressed);
	BOOST_REQUIRE_EQUAL(lr, ICERR_OK);
	cbCompressedData = ICCompressGetSize(hicEncode, &bihSrc, &bihCompressed);

	lr = ICCompressBegin(hicEncode, &bihSrc, &bihCompressed);
	BOOST_REQUIRE_EQUAL(lr, ICERR_OK);

	lr = ICDecompressBegin(hicDecode, &bihCompressed, &bihDst);
	BOOST_REQUIRE_EQUAL(lr, ICERR_OK);

	void *pSrcData;
	void *pDstData;
	void *pEncoderOut = malloc(cbCompressedData);
	void *pDecoderOut = NULL;
	int retSrc, retDst;
	LONG lFrameNum = 0;
	while ((retSrc = srcClip.GetNextFrame(&pSrcData, &cbSrcData, NULL)) == 0 &&
		(retDst = dstClip.GetNextFrame(&pDstData, &cbDstData, NULL) == 0))
	{
		DWORD dwFlags = 0;
		lr = ICCompress(hicEncode, 0, &bihCompressed, pEncoderOut, &bihSrc, pSrcData, NULL, &dwFlags, lFrameNum++, 0, 0, &bihSrc, NULL);
		BOOST_REQUIRE(lr == ICERR_OK);

		if (pDecoderOut == NULL)
			pDecoderOut = malloc(cbDstData);

		lr = ICDecompress(hicDecode, (dwFlags & AVIIF_KEYFRAME) ? 0 : ICDECOMPRESS_NOTKEYFRAME, &bihCompressed, pEncoderOut, &bihDst, pDecoderOut);
		BOOST_REQUIRE(lr == ICERR_OK);

		BOOST_CHECK(bihDst.biSizeImage == cbDstData);
		BOOST_CHECK(CompareFrame(pDstData, pDecoderOut, nWidth, cbDstData, fccDst, tolerance) == 0);
	}

	BOOST_CHECK(retSrc != 0 && retDst != 0);
	if (pDecoderOut != NULL)
		free(pDecoderOut);
	free(pEncoderOut);

	lr = ICDecompressEnd(hicDecode);
	BOOST_CHECK(lr == ICERR_OK);

	lr = ICCompressEnd(hicEncode);
	BOOST_CHECK(lr == ICERR_OK);
}
Beispiel #14
0
static HRESULT WINAPI ICMStream_fnSetFormat(IAVIStream *iface, LONG pos,
					     LPVOID format, LONG formatsize)
{
  IAVIStreamImpl *This = impl_from_IAVIStream(iface);

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

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

  /* We can only accept RGB data for writing */
  if (((LPBITMAPINFOHEADER)format)->biCompression != BI_RGB) {
    WARN(": need RGB data as input\n");
    return AVIERR_UNSUPPORTED;
  }

  /* Input format already known?
   * Changing of palette is supported, but be quiet if it's the same */
  if (This->lpbiInput != NULL) {
    if (This->cbInput != formatsize)
      return AVIERR_UNSUPPORTED;

    if (memcmp(format, This->lpbiInput, formatsize) == 0)
      return AVIERR_OK;
  }

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

  /* check if frame is already written */
  if (This->sInfo.dwLength + This->sInfo.dwStart > pos)
    return AVIERR_UNSUPPORTED;

  /* check if we should compress */
  if (This->sInfo.fccHandler == 0 ||
      This->sInfo.fccHandler == mmioFOURCC('N','O','N','E'))
    This->sInfo.fccHandler = comptypeDIB;

  /* only pass through? */
  if (This->sInfo.fccHandler == comptypeDIB)
    return IAVIStream_SetFormat(This->pStream, pos, format, formatsize);

  /* initial format setting? */
  if (This->lpbiInput == NULL) {
    ULONG size;

    assert(This->hic != NULL);

    /* get memory for input format */
    This->lpbiInput = HeapAlloc(GetProcessHeap(), 0, formatsize);
    if (This->lpbiInput == NULL)
      return AVIERR_MEMORY;
    This->cbInput = formatsize;
    memcpy(This->lpbiInput, format, formatsize);

    /* get output format */
    size = ICCompressGetFormatSize(This->hic, This->lpbiInput);
    if (size < sizeof(BITMAPINFOHEADER))
      return AVIERR_COMPRESSOR;
    This->lpbiOutput = HeapAlloc(GetProcessHeap(), 0, size);
    if (This->lpbiOutput == NULL)
      return AVIERR_MEMORY;
    This->cbOutput = size;
    if (ICCompressGetFormat(This->hic,This->lpbiInput,This->lpbiOutput) < S_OK)
      return AVIERR_COMPRESSOR;

    /* update AVISTREAMINFO structure */
    This->sInfo.rcFrame.right  =
      This->sInfo.rcFrame.left + This->lpbiOutput->biWidth;
    This->sInfo.rcFrame.bottom =
      This->sInfo.rcFrame.top  + This->lpbiOutput->biHeight;

    /* prepare codec for compression */
    if (ICCompressBegin(This->hic, This->lpbiInput, This->lpbiOutput) != S_OK)
      return AVIERR_COMPRESSOR;

    /* allocate memory for compressed frame */
    size = ICCompressGetSize(This->hic, This->lpbiInput, This->lpbiOutput);
    This->lpbiCur = HeapAlloc(GetProcessHeap(), 0, This->cbOutput + size);
    if (This->lpbiCur == NULL)
      return AVIERR_MEMORY;
    memcpy(This->lpbiCur, This->lpbiOutput, This->cbOutput);
    This->lpCur = DIBPTR(This->lpbiCur);

    /* allocate memory for last frame if needed */
    if (This->lKeyFrameEvery != 1 &&
	(This->dwICMFlags & VIDCF_FASTTEMPORALC) == 0) {
      size = ICDecompressGetFormatSize(This->hic, This->lpbiOutput);
      This->lpbiPrev = HeapAlloc(GetProcessHeap(), 0, size);
      if (This->lpbiPrev == NULL)
	return AVIERR_MEMORY;
      if (ICDecompressGetFormat(This->hic, This->lpbiOutput, This->lpbiPrev) < S_OK)
	return AVIERR_COMPRESSOR;

      if (This->lpbiPrev->biSizeImage == 0) {
	This->lpbiPrev->biSizeImage =
	  DIBWIDTHBYTES(*This->lpbiPrev) * This->lpbiPrev->biHeight;
      }

      /* get memory for format and picture */
      size += This->lpbiPrev->biSizeImage;
      This->lpbiPrev = HeapReAlloc(GetProcessHeap(), 0, This->lpbiPrev, size);
      if (This->lpbiPrev == NULL)
	return AVIERR_MEMORY;
      This->lpPrev = DIBPTR(This->lpbiPrev);

      /* prepare codec also for decompression */
      if (ICDecompressBegin(This->hic,This->lpbiOutput,This->lpbiPrev) != S_OK)
	return AVIERR_COMPRESSOR;
    }
  } else {
    /* format change -- check that's only the palette */
    LPBITMAPINFOHEADER lpbi = format;

    if (lpbi->biSize != This->lpbiInput->biSize ||
	lpbi->biWidth != This->lpbiInput->biWidth ||
	lpbi->biHeight != This->lpbiInput->biHeight ||
	lpbi->biBitCount != This->lpbiInput->biBitCount ||
	lpbi->biPlanes != This->lpbiInput->biPlanes ||
	lpbi->biCompression != This->lpbiInput->biCompression ||
	lpbi->biClrUsed != This->lpbiInput->biClrUsed)
      return AVIERR_UNSUPPORTED;

    /* get new output format */
    if (ICCompressGetFormat(This->hic, lpbi, This->lpbiOutput) < S_OK)
      return AVIERR_BADFORMAT;

    /* restart compression */
    ICCompressEnd(This->hic);
    if (ICCompressBegin(This->hic, lpbi, This->lpbiOutput) != S_OK)
      return AVIERR_COMPRESSOR;

    /* check if we need to restart decompression also */
    if (This->lKeyFrameEvery != 1 &&
	(This->dwICMFlags & VIDCF_FASTTEMPORALC) == 0) {
      ICDecompressEnd(This->hic);
      if (ICDecompressGetFormat(This->hic,This->lpbiOutput,This->lpbiPrev) < S_OK)
	return AVIERR_COMPRESSOR;
      if (ICDecompressBegin(This->hic,This->lpbiOutput,This->lpbiPrev) != S_OK)
	return AVIERR_COMPRESSOR;
    }
  }

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