⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmoutput.c

📁 Wine-20031016
💻 C
📖 第 1 页 / 共 2 页
字号:
				  wma->dwPlayableVideoFrames * sizeof(struct MMIOPos));    if (!wma->lpVideoIndex) {	WARN("Can't alloc video index array\n");	return FALSE;    }    wma->dwPlayableAudioBlocks = 0;    wma->lpAudioIndex = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,				  wma->dwPlayableVideoFrames * sizeof(struct MMIOPos));    if (!wma->lpAudioIndex) {	WARN("Can't alloc audio index array\n");	return FALSE;    }    alb.numAudioBlocks = alb.numVideoFrames = 0;    alb.inVideoSize = alb.inAudioSize = 0;    alb.numAudioAllocated = 0;    while (mmioDescend(wma->hFile, &mmckInfo, &mmckList, 0) == 0) {	if (mmckInfo.fccType == listtypeAVIRECORD) {	    MMCKINFO	tmp;	    while (mmioDescend(wma->hFile, &tmp, &mmckInfo, 0) == 0) {		MCIAVI_AddFrame(wma, &tmp, &alb);		mmioAscend(wma->hFile, &tmp, 0);	    }	} else {	    MCIAVI_AddFrame(wma, &mmckInfo, &alb);	}	mmioAscend(wma->hFile, &mmckInfo, 0);    }    if (alb.numVideoFrames != wma->dwPlayableVideoFrames) {	WARN("Found %ld video frames (/%ld), reducing playable frames\n",	     alb.numVideoFrames, wma->dwPlayableVideoFrames);	wma->dwPlayableVideoFrames = alb.numVideoFrames;    }    wma->dwPlayableAudioBlocks = alb.numAudioBlocks;    if (alb.inVideoSize > wma->ash_video.dwSuggestedBufferSize) {	WARN("inVideoSize=%ld suggestedSize=%ld\n", alb.inVideoSize, wma->ash_video.dwSuggestedBufferSize);	wma->ash_video.dwSuggestedBufferSize = alb.inVideoSize;    }    if (alb.inAudioSize > wma->ash_audio.dwSuggestedBufferSize) {	WARN("inAudioSize=%ld suggestedSize=%ld\n", alb.inAudioSize, wma->ash_audio.dwSuggestedBufferSize);	wma->ash_audio.dwSuggestedBufferSize = alb.inAudioSize;    }    wma->indata = HeapAlloc(GetProcessHeap(), 0, wma->ash_video.dwSuggestedBufferSize);    if (!wma->indata) {	WARN("Can't alloc input buffer\n");	return FALSE;    }    return TRUE;}BOOL    MCIAVI_OpenVideo(WINE_MCIAVI* wma){    DWORD	outSize;    FOURCC	fcc = wma->ash_video.fccHandler;    /* check uncompressed AVI */    if ((fcc == mmioFOURCC('D','I','B',' ')) ||	(fcc == mmioFOURCC('R','L','E',' '))) {	wma->hic = 0;	MCIAVI_DrawFrame(wma);	return TRUE;    }    /* get the right handle */    if (fcc == 0) fcc = wma->inbih->biCompression;    if (fcc == mmioFOURCC('C','R','A','M')) fcc = mmioFOURCC('M','S','V','C');    /* try to get a decompressor for that type */    wma->hic = ICLocate(ICTYPE_VIDEO, fcc, wma->inbih, NULL, ICMODE_DECOMPRESS);    if (!wma->hic) {	WARN("Can't locate codec for the file\n");	return FALSE;    }    outSize = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);    wma->outbih = HeapAlloc(GetProcessHeap(), 0, outSize);    if (!wma->outbih) {	WARN("Can't alloc output BIH\n");	return FALSE;    }    if (!ICGetDisplayFormat(wma->hic, wma->inbih, wma->outbih, 0, 0, 0)) {	WARN("Can't open decompressor\n");	return FALSE;    }    TRACE("bih.biSize=%ld\n", 		wma->outbih->biSize);    TRACE("bih.biWidth=%ld\n", 		wma->outbih->biWidth);    TRACE("bih.biHeight=%ld\n", 	wma->outbih->biHeight);    TRACE("bih.biPlanes=%d\n", 		wma->outbih->biPlanes);    TRACE("bih.biBitCount=%d\n", 	wma->outbih->biBitCount);    TRACE("bih.biCompression=%lx\n", 	wma->outbih->biCompression);    TRACE("bih.biSizeImage=%ld\n", 	wma->outbih->biSizeImage);    TRACE("bih.biXPelsPerMeter=%ld\n", 	wma->outbih->biXPelsPerMeter);    TRACE("bih.biYPelsPerMeter=%ld\n", 	wma->outbih->biYPelsPerMeter);    TRACE("bih.biClrUsed=%ld\n", 	wma->outbih->biClrUsed);    TRACE("bih.biClrImportant=%ld\n", 	wma->outbih->biClrImportant);    wma->outdata = HeapAlloc(GetProcessHeap(), 0, wma->outbih->biSizeImage);    if (!wma->outdata) {	WARN("Can't alloc output buffer\n");	return FALSE;    }    if (ICSendMessage(wma->hic, ICM_DECOMPRESS_BEGIN,		      (DWORD)wma->inbih, (DWORD)wma->outbih) != ICERR_OK) {	WARN("Can't begin decompression\n");	return FALSE;    }    MCIAVI_DrawFrame(wma);    return TRUE;}static void CALLBACK MCIAVI_waveCallback(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance,					 DWORD dwParam1, DWORD dwParam2){    WINE_MCIAVI*	wma = (WINE_MCIAVI*)dwInstance;    switch (uMsg) {    case WOM_OPEN:    case WOM_CLOSE:	break;    case WOM_DONE:	InterlockedIncrement(&wma->dwEventCount);	TRACE("Returning waveHdr=%lx\n", dwParam1);	SetEvent(wma->hEvent);	break;    default:	ERR("Unknown uMsg=%d\n", uMsg);    }}DWORD MCIAVI_OpenAudio(WINE_MCIAVI* wma, unsigned* nHdr, LPWAVEHDR* pWaveHdr){    DWORD	dwRet;    LPWAVEHDR	waveHdr;    unsigned	i;    dwRet = waveOutOpen((HWAVEOUT *)&wma->hWave, WAVE_MAPPER, wma->lpWaveFormat,			(DWORD)MCIAVI_waveCallback, (DWORD)wma, CALLBACK_FUNCTION);    if (dwRet != 0) {	TRACE("Can't open low level audio device %ld\n", dwRet);	dwRet = MCIERR_DEVICE_OPEN;	wma->hWave = 0;	goto cleanUp;    }    /* FIXME: should set up a heuristic to compute the number of wave headers     * to be used...     */    *nHdr = 7;    waveHdr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,			*nHdr * (sizeof(WAVEHDR) + wma->ash_audio.dwSuggestedBufferSize));    if (!waveHdr) {	TRACE("Can't alloc wave headers\n");	dwRet = MCIERR_DEVICE_OPEN;	goto cleanUp;    }    for (i = 0; i < *nHdr; i++) {	/* other fields are zero:ed on allocation */	waveHdr[i].lpData = (char*)waveHdr +	    *nHdr * sizeof(WAVEHDR) + i * wma->ash_audio.dwSuggestedBufferSize;	waveHdr[i].dwBufferLength = wma->ash_audio.dwSuggestedBufferSize;	if (waveOutPrepareHeader(wma->hWave, &waveHdr[i], sizeof(WAVEHDR))) {	    dwRet = MCIERR_INTERNAL;	    goto cleanUp;	}    }    if (wma->dwCurrVideoFrame != 0 && wma->lpWaveFormat) {	FIXME("Should recompute dwCurrAudioBlock, except unsynchronized sound & video\n");    }    wma->dwCurrAudioBlock = 0;    wma->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);    wma->dwEventCount = *nHdr - 1;    *pWaveHdr = waveHdr; cleanUp:    return dwRet;}void MCIAVI_PlayAudioBlocks(WINE_MCIAVI* wma, unsigned nHdr, LPWAVEHDR waveHdr){    TRACE("%ld (ec=%lu)\n", wma->lpAudioIndex[wma->dwCurrAudioBlock].dwOffset, wma->dwEventCount);    /* push as many blocks as possible => audio gets priority */    while (wma->dwStatus != MCI_MODE_STOP && wma->dwStatus != MCI_MODE_NOT_READY &&	   wma->dwCurrAudioBlock < wma->dwPlayableAudioBlocks) {	unsigned	whidx = wma->dwCurrAudioBlock % nHdr;	ResetEvent(wma->hEvent);	if (InterlockedDecrement(&wma->dwEventCount) < 0 ||	    !wma->lpAudioIndex[wma->dwCurrAudioBlock].dwOffset)	    break;	mmioSeek(wma->hFile, wma->lpAudioIndex[wma->dwCurrAudioBlock].dwOffset, SEEK_SET);	mmioRead(wma->hFile, waveHdr[whidx].lpData, wma->lpAudioIndex[wma->dwCurrAudioBlock].dwSize);	waveHdr[whidx].dwFlags &= ~WHDR_DONE;	waveHdr[whidx].dwBufferLength = wma->lpAudioIndex[wma->dwCurrAudioBlock].dwSize;	waveOutWrite(wma->hWave, &waveHdr[whidx], sizeof(WAVEHDR));	wma->dwCurrAudioBlock++;    }    InterlockedIncrement(&wma->dwEventCount);}LRESULT MCIAVI_PaintFrame(WINE_MCIAVI* wma, HDC hDC){    void* 		pBitmapData = NULL;    LPBITMAPINFO	pBitmapInfo = NULL;    HDC 		hdcMem;    HBITMAP		hbmOld;    int 		nWidth;    int 		nHeight;    if (!hDC || !wma->inbih)	return TRUE;    TRACE("Painting frame %lu\n", wma->dwCurrVideoFrame);    if (wma->hic) {        pBitmapData = wma->outdata;        pBitmapInfo = (LPBITMAPINFO)wma->outbih;        nWidth = wma->outbih->biWidth;        nHeight = wma->outbih->biHeight;    } else {        pBitmapData = wma->indata;        pBitmapInfo = (LPBITMAPINFO)wma->inbih;        nWidth = wma->inbih->biWidth;        nHeight = wma->inbih->biHeight;    }    if (!wma->hbmFrame)        wma->hbmFrame = CreateCompatibleBitmap(hDC, nWidth, nHeight);    SetDIBits(hDC, wma->hbmFrame, 0, nHeight, pBitmapData, pBitmapInfo, DIB_RGB_COLORS);    hdcMem = CreateCompatibleDC(hDC);    hbmOld = SelectObject(hdcMem, wma->hbmFrame);    BitBlt(hDC, 0, 0, nWidth, nHeight, hdcMem, 0, 0, SRCCOPY);    SelectObject(hdcMem, hbmOld);    DeleteDC(hdcMem);    return TRUE;}LRESULT MCIAVI_DrawFrame(WINE_MCIAVI* wma){    HDC		hDC;    TRACE("Drawing frame %lu\n", wma->dwCurrVideoFrame);    if (!wma->lpVideoIndex[wma->dwCurrVideoFrame].dwOffset)	return FALSE;    EnterCriticalSection(&wma->cs);    mmioSeek(wma->hFile, wma->lpVideoIndex[wma->dwCurrVideoFrame].dwOffset, SEEK_SET);    mmioRead(wma->hFile, wma->indata, wma->lpVideoIndex[wma->dwCurrVideoFrame].dwSize);    /* FIXME ? */    wma->inbih->biSizeImage = wma->lpVideoIndex[wma->dwCurrVideoFrame].dwSize;    if (wma->hic &&	ICDecompress(wma->hic, 0, wma->inbih, wma->indata,		     wma->outbih, wma->outdata) != ICERR_OK) {	LeaveCriticalSection(&wma->cs);	WARN("Decompression error\n");	return FALSE;    }    if (IsWindowVisible(wma->hWnd) && (hDC = GetDC(wma->hWnd)) != 0) {	MCIAVI_PaintFrame(wma, hDC);	ReleaseDC(wma->hWnd, hDC);    }    LeaveCriticalSection(&wma->cs);    return TRUE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -