コード例 #1
0
ファイル: wnd.c プロジェクト: hoangduit/reactos
static LRESULT WINAPI MCIAVI_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    TRACE("hwnd=%p msg=%x wparam=%lx lparam=%lx\n", hWnd, uMsg, wParam, lParam);

    switch (uMsg) {
    case WM_CREATE:
        SetWindowLongW(hWnd, 0, (LPARAM)((CREATESTRUCTW *)lParam)->lpCreateParams);
        return DefWindowProcW(hWnd, uMsg, wParam, lParam);

    case WM_DESTROY:
        MCIAVI_mciClose(GetWindowLongW(hWnd, 0), MCI_WAIT, NULL);
        SetWindowLongW(hWnd, 0, 0);
        return DefWindowProcW(hWnd, uMsg, wParam, lParam);

    case WM_ERASEBKGND:
	{
	    RECT	rect;
	    GetClientRect(hWnd, &rect);
	    FillRect((HDC)wParam, &rect, GetStockObject(BLACK_BRUSH));
	}
       return 1;

    case WM_PAINT:
        {
            WINE_MCIAVI *wma = (WINE_MCIAVI *)mciGetDriverData(GetWindowLongW(hWnd, 0));

            if (!wma)
                return DefWindowProcW(hWnd, uMsg, wParam, lParam);
            
            EnterCriticalSection(&wma->cs);

            /* the animation isn't playing, don't paint */
	    if (wma->dwStatus == MCI_MODE_NOT_READY)
            {
                LeaveCriticalSection(&wma->cs);
		/* default paint handling */
                return DefWindowProcW(hWnd, uMsg, wParam, lParam);
            }

            if (wParam)
                MCIAVI_PaintFrame(wma, (HDC)wParam);
            else
            {
	        PAINTSTRUCT ps;
                BeginPaint(hWnd, &ps);
                MCIAVI_PaintFrame(wma, ps.hdc);
	        EndPaint(hWnd, &ps);
	    }

            LeaveCriticalSection(&wma->cs);
        }
       return 1;

    default:
        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
    }
}
コード例 #2
0
ファイル: mciavi.c プロジェクト: AlexSteel/wine
/******************************************************************************
 * 				MCIAVI_mciUpdate			[internal]
 */
static	DWORD	MCIAVI_mciUpdate(UINT wDevID, DWORD dwFlags, LPMCI_DGV_UPDATE_PARMS lpParms)
{
    WINE_MCIAVI *wma;

    TRACE("%04x, %08x, %p\n", wDevID, dwFlags, lpParms);

    if (lpParms == NULL)	return MCIERR_NULL_PARAMETER_BLOCK;

    wma = MCIAVI_mciGetOpenDev(wDevID);
    if (wma == NULL)		return MCIERR_INVALID_DEVICE_ID;
    /* Ignore MCI_TEST flag. */

    EnterCriticalSection(&wma->cs);

    if (dwFlags & MCI_DGV_UPDATE_HDC)
        MCIAVI_PaintFrame(wma, lpParms->hDC);

    LeaveCriticalSection(&wma->cs);

    return 0;
}
コード例 #3
0
ファイル: mmoutput.c プロジェクト: hoangduit/reactos
BOOL    MCIAVI_OpenVideo(WINE_MCIAVI* wma)
{
    HDC hDC;
    DWORD	outSize;
    FOURCC	fcc = wma->ash_video.fccHandler;

    TRACE("fcc %4.4s\n", (LPSTR)&fcc);

    wma->dwCachedFrame = -1;

    /* get the right handle */
    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) {
        /* check for builtin DIB compressions */
        fcc = wma->inbih->biCompression;
        if ((fcc == mmioFOURCC('D','I','B',' ')) ||
            (fcc == mmioFOURCC('R','L','E',' ')) ||
            (fcc == BI_RGB) || (fcc == BI_RLE8) ||
            (fcc == BI_RLE4) || (fcc == BI_BITFIELDS))
            goto paint_frame;

	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=%d\n", 		wma->outbih->biSize);
    TRACE("bih.biWidth=%d\n", 		wma->outbih->biWidth);
    TRACE("bih.biHeight=%d\n", 	wma->outbih->biHeight);
    TRACE("bih.biPlanes=%d\n", 		wma->outbih->biPlanes);
    TRACE("bih.biBitCount=%d\n", 	wma->outbih->biBitCount);
    TRACE("bih.biCompression=%x\n", 	wma->outbih->biCompression);
    TRACE("bih.biSizeImage=%d\n", 	wma->outbih->biSizeImage);
    TRACE("bih.biXPelsPerMeter=%d\n", 	wma->outbih->biXPelsPerMeter);
    TRACE("bih.biYPelsPerMeter=%d\n", 	wma->outbih->biYPelsPerMeter);
    TRACE("bih.biClrUsed=%d\n", 	wma->outbih->biClrUsed);
    TRACE("bih.biClrImportant=%d\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_PTR)wma->inbih, (DWORD_PTR)wma->outbih) != ICERR_OK) {
	WARN("Can't begin decompression\n");
	return FALSE;
    }

paint_frame:
    hDC = wma->hWndPaint ? GetDC(wma->hWndPaint) : 0;
    if (hDC)
    {
        MCIAVI_PaintFrame(wma, hDC);
        ReleaseDC(wma->hWndPaint, hDC);
    }
    return TRUE;
}
コード例 #4
0
ファイル: mciavi.c プロジェクト: AlexSteel/wine
/***************************************************************************
 * 				MCIAVI_player			[internal]
 */
static	DWORD	MCIAVI_player(WINE_MCIAVI *wma, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
{
    DWORD		dwRet;
    LPWAVEHDR		waveHdr = NULL;
    unsigned		i, nHdr = 0;
    DWORD		numEvents = 1;
    HANDLE		events[2];
    double next_frame_us;

    EnterCriticalSection(&wma->cs);

    if (wma->dwToVideoFrame <= wma->dwCurrVideoFrame)
    {
        dwRet = 0;
        goto mci_play_done;
    }

    events[0] = wma->hStopEvent;
    if (wma->lpWaveFormat) {
        if (MCIAVI_OpenAudio(wma, &nHdr, &waveHdr) != 0)
        {
            /* can't play audio */
            HeapFree(GetProcessHeap(), 0, wma->lpWaveFormat);
            wma->lpWaveFormat = NULL;
        }
        else
        {
            /* fill the queue with as many wave headers as possible */
            MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr);
            events[1] = wma->hEvent;
            numEvents = 2;
        }
    }

    next_frame_us = currenttime_us();
    while (wma->dwStatus == MCI_MODE_PLAY)
    {
        HDC hDC;
        double tc, delta;
        DWORD ret;

        tc = currenttime_us();

        hDC = wma->hWndPaint ? GetDC(wma->hWndPaint) : 0;
        if (hDC)
        {
            while(next_frame_us <= tc && wma->dwCurrVideoFrame < wma->dwToVideoFrame) {
                double dur;
                dur = MCIAVI_PaintFrame(wma, hDC);
                ++wma->dwCurrVideoFrame;
                if(!dur)
                    break;
                next_frame_us += dur;
                TRACE("next_frame: %f\n", next_frame_us);
            }
            ReleaseDC(wma->hWndPaint, hDC);
        }
        if (wma->dwCurrVideoFrame >= wma->dwToVideoFrame)
        {
            if (!(dwFlags & MCI_DGV_PLAY_REPEAT))
                break;
            TRACE("repeat media as requested\n");
            wma->dwCurrVideoFrame = wma->dwCurrAudioBlock = 0;
        }

        if (wma->lpWaveFormat)
            MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr);

        tc = currenttime_us();
        if (tc < next_frame_us)
            delta = next_frame_us - tc;
        else
            delta = 0;

        LeaveCriticalSection(&wma->cs);
        ret = WaitForMultipleObjects(numEvents, events, FALSE, delta / 1000);
        EnterCriticalSection(&wma->cs);
        if (ret == WAIT_OBJECT_0 || wma->dwStatus != MCI_MODE_PLAY) break;
    }

    if (wma->lpWaveFormat) {
        while (wma->dwEventCount != nHdr - 1)
        {
            LeaveCriticalSection(&wma->cs);
            Sleep(100);
            EnterCriticalSection(&wma->cs);
        }

        /* just to get rid of some race conditions between play, stop and pause */
        LeaveCriticalSection(&wma->cs);
        waveOutReset(wma->hWave);
        EnterCriticalSection(&wma->cs);

        for (i = 0; i < nHdr; i++)
            waveOutUnprepareHeader(wma->hWave, &waveHdr[i], sizeof(WAVEHDR));
    }

    dwRet = 0;

    if (wma->lpWaveFormat) {
        HeapFree(GetProcessHeap(), 0, waveHdr);

        if (wma->hWave) {
            LeaveCriticalSection(&wma->cs);
            waveOutClose(wma->hWave);
            EnterCriticalSection(&wma->cs);
            wma->hWave = 0;
        }
        CloseHandle(wma->hEvent);
    }

mci_play_done:
    wma->dwStatus = MCI_MODE_STOP;

    if (dwFlags & MCI_NOTIFY) {
        TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
        mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
                        wma->wDevID, MCI_NOTIFY_SUCCESSFUL);
    }
    LeaveCriticalSection(&wma->cs);
    return dwRet;
}
コード例 #5
0
ファイル: mciavi.c プロジェクト: bilboed/wine
/***************************************************************************
 * 				MCIAVI_mciPlay			[internal]
 */
static	DWORD	MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
{
    WINE_MCIAVI *wma;
    DWORD		frameTime;
    DWORD		dwRet;
    LPWAVEHDR		waveHdr = NULL;
    unsigned		i, nHdr = 0;
    DWORD		dwFromFrame, dwToFrame;
    DWORD		numEvents = 1;
    HANDLE		events[2];

    TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);

    if (lpParms == NULL)	return MCIERR_NULL_PARAMETER_BLOCK;

    wma = MCIAVI_mciGetOpenDev(wDevID);
    if (wma == NULL)		return MCIERR_INVALID_DEVICE_ID;
    if (dwFlags & MCI_DGV_PLAY_REVERSE) return MCIERR_UNSUPPORTED_FUNCTION;
    if (dwFlags & MCI_TEST)	return 0;

    EnterCriticalSection(&wma->cs);

    if (!wma->hFile)
    {
        LeaveCriticalSection(&wma->cs);
        return MCIERR_FILE_NOT_FOUND;
    }
    if (!wma->hWndPaint)
    {
        LeaveCriticalSection(&wma->cs);
        return MCIERR_NO_WINDOW;
    }

    LeaveCriticalSection(&wma->cs);

    if (!(dwFlags & MCI_WAIT))
        return MCIAVI_mciPlay_async(wma, dwFlags, lpParms);

    if (!(GetWindowLongW(wma->hWndPaint, GWL_STYLE) & WS_VISIBLE))
        ShowWindow(wma->hWndPaint, SW_SHOWNA);

    EnterCriticalSection(&wma->cs);

    dwFromFrame = wma->dwCurrVideoFrame;
    dwToFrame = wma->dwPlayableVideoFrames - 1;

    if (lpParms && (dwFlags & MCI_FROM)) {
	dwFromFrame = MCIAVI_ConvertTimeFormatToFrame(wma, lpParms->dwFrom);
    }
    if (lpParms && (dwFlags & MCI_TO)) {
	dwToFrame = MCIAVI_ConvertTimeFormatToFrame(wma, lpParms->dwTo);
    }
    if (dwToFrame >= wma->dwPlayableVideoFrames)
	dwToFrame = wma->dwPlayableVideoFrames - 1;

    TRACE("Playing from frame=%u to frame=%u\n", dwFromFrame, dwToFrame);

    wma->dwCurrVideoFrame = dwFromFrame;
    wma->dwToVideoFrame = dwToFrame;

    /* if already playing exit */
    if (wma->dwStatus == MCI_MODE_PLAY)
    {
        LeaveCriticalSection(&wma->cs);
        SetEvent(wma->ack_event);
        return 0;
    }

    if (wma->dwToVideoFrame <= wma->dwCurrVideoFrame)
    {
        dwRet = 0;
        SetEvent(wma->ack_event);
        goto mci_play_done;
    }

    wma->dwStatus = MCI_MODE_PLAY;
    /* signal the state change */
    SetEvent(wma->ack_event);

    if (dwFlags & (MCI_DGV_PLAY_REPEAT|MCI_MCIAVI_PLAY_WINDOW|MCI_MCIAVI_PLAY_FULLSCREEN))
	FIXME("Unsupported flag %08x\n", dwFlags);

    /* time is in microseconds, we should convert it to milliseconds */
    frameTime = (wma->mah.dwMicroSecPerFrame + 500) / 1000;

    events[0] = wma->hStopEvent;
    if (wma->lpWaveFormat) {
       if (MCIAVI_OpenAudio(wma, &nHdr, &waveHdr) != 0)
        {
            /* can't play audio */
            HeapFree(GetProcessHeap(), 0, wma->lpWaveFormat);
            wma->lpWaveFormat = NULL;
        }
       else
       {
            /* fill the queue with as many wave headers as possible */
            MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr);
            events[1] = wma->hEvent;
            numEvents = 2;
       }
    }

    while (wma->dwStatus == MCI_MODE_PLAY)
    {
        HDC hDC;
        DWORD tc, delta;
        DWORD ret;

	tc = GetTickCount();

        hDC = wma->hWndPaint ? GetDC(wma->hWndPaint) : 0;
        if (hDC)
        {
            MCIAVI_PaintFrame(wma, hDC);
            ReleaseDC(wma->hWndPaint, hDC);
        }

        if (wma->lpWaveFormat)
	    MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr);

	delta = GetTickCount() - tc;
	if (delta < frameTime)
            delta = frameTime - delta;
        else
            delta = 0;

        LeaveCriticalSection(&wma->cs);
        ret = WaitForMultipleObjects(numEvents, events, FALSE, delta);
        EnterCriticalSection(&wma->cs);
        if (ret == WAIT_OBJECT_0 || wma->dwStatus != MCI_MODE_PLAY) break;

       if (wma->dwCurrVideoFrame < dwToFrame)
           wma->dwCurrVideoFrame++;
        else
            break;
    }

    if (wma->lpWaveFormat) {
       while (wma->dwEventCount != nHdr - 1)
        {
            LeaveCriticalSection(&wma->cs);
            Sleep(100);
            EnterCriticalSection(&wma->cs);
        }

	/* just to get rid of some race conditions between play, stop and pause */
	LeaveCriticalSection(&wma->cs);
	waveOutReset(wma->hWave);
	EnterCriticalSection(&wma->cs);

	for (i = 0; i < nHdr; i++)
	    waveOutUnprepareHeader(wma->hWave, &waveHdr[i], sizeof(WAVEHDR));
    }

    dwRet = 0;

    if (wma->lpWaveFormat) {
	HeapFree(GetProcessHeap(), 0, waveHdr);

	if (wma->hWave) {
	    LeaveCriticalSection(&wma->cs);
	    waveOutClose(wma->hWave);
	    EnterCriticalSection(&wma->cs);
	    wma->hWave = 0;
	}
	CloseHandle(wma->hEvent);
    }

mci_play_done:
    wma->dwStatus = MCI_MODE_STOP;

    if (lpParms && (dwFlags & MCI_NOTIFY)) {
	TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
	mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
                       wDevID, MCI_NOTIFY_SUCCESSFUL);
    }
    LeaveCriticalSection(&wma->cs);
    return dwRet;
}