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

📄 mciavi.c

📁 Wine-20031016
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- tab-width: 8; c-basic-offset: 4 -*- *//* * Digital video MCI Wine Driver * * Copyright 1999, 2000 Eric POUECH * * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//* TODO list : *	- handling of palettes *	- recording (which input devices ?), a cam recorder ? *	- lots of messages still need to be handled (cf FIXME) *	- synchronization between audio and video (especially for interleaved *	  files) *	- synchronization (as in all the Wine MCI drivers (MCI_WAIT) messages) *	- robustness when reading file can be enhanced *	- better move the AVI handling part to avifile DLL and make use of it *	- some files appear to have more than one audio stream (we only play the *	  first one) *	- some files contain an index of audio/video frame. Better use it, *	  instead of rebuilding it *	- mciWindow (for setting the hWnd) is broken with media player *	- stopping while playing a file with sound blocks until all buffered *        audio is played... still should be stopped ASAP */#include <string.h>#include "private_mciavi.h"#include "wine/debug.h"WINE_DEFAULT_DEBUG_CHANNEL(mciavi);/* =================================================================== * =================================================================== * FIXME: should be using the new mmThreadXXXX functions from WINMM * instead of those * it would require to add a wine internal flag to mmThreadCreate * in order to pass a 32 bit function instead of a 16 bit one * =================================================================== * =================================================================== */struct SCA {    UINT 	wDevID;    UINT 	wMsg;    DWORD 	dwParam1;    DWORD 	dwParam2;};/************************************************************************** * 				MCI_SCAStarter			[internal] */static DWORD CALLBACK	MCI_SCAStarter(LPVOID arg){    struct SCA*	sca = (struct SCA*)arg;    DWORD	ret;    TRACE("In thread before async command (%08x,%u,%08lx,%08lx)\n",	  sca->wDevID, sca->wMsg, sca->dwParam1, sca->dwParam2);    ret = mciSendCommandA(sca->wDevID, sca->wMsg, sca->dwParam1 | MCI_WAIT, sca->dwParam2);    TRACE("In thread after async command (%08x,%u,%08lx,%08lx)\n",	  sca->wDevID, sca->wMsg, sca->dwParam1, sca->dwParam2);    HeapFree(GetProcessHeap(), 0, sca);    ExitThread(ret);    WARN("Should not happen ? what's wrong \n");    /* should not go after this point */    return ret;}/************************************************************************** * 				MCI_SendCommandAsync		[internal] */static	DWORD MCI_SendCommandAsync(UINT wDevID, UINT wMsg, DWORD dwParam1,				   DWORD dwParam2, UINT size){    struct SCA*	sca = HeapAlloc(GetProcessHeap(), 0, sizeof(struct SCA) + size);    if (sca == 0)	return MCIERR_OUT_OF_MEMORY;    sca->wDevID   = wDevID;    sca->wMsg     = wMsg;    sca->dwParam1 = dwParam1;    if (size && dwParam2) {	sca->dwParam2 = (DWORD)sca + sizeof(struct SCA);	/* copy structure passed by program in dwParam2 to be sure	 * we can still use it whatever the program does	 */	memcpy((LPVOID)sca->dwParam2, (LPVOID)dwParam2, size);    } else {	sca->dwParam2 = dwParam2;    }    if (CreateThread(NULL, 0, MCI_SCAStarter, sca, 0, NULL) == 0) {	WARN("Couldn't allocate thread for async command handling, sending synchronously\n");	return MCI_SCAStarter(&sca);    }    return 0;}/*======================================================================* *                  	    MCI AVI implemantation			* *======================================================================*/HINSTANCE MCIAVI_hInstance = 0;BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad){    switch (fdwReason) {    case DLL_PROCESS_ATTACH:        DisableThreadLibraryCalls(hInstDLL);	MCIAVI_hInstance = hInstDLL;	break;    }    return TRUE;}/************************************************************************** * 				MCIAVI_drvOpen			[internal] */static	DWORD	MCIAVI_drvOpen(LPSTR str, LPMCI_OPEN_DRIVER_PARMSA modp){    WINE_MCIAVI*	wma;    static WCHAR	mciAviWStr[] = {'M','C','I','A','V','I',0};    if (!modp) return 0xFFFFFFFF;    wma = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MCIAVI));    if (!wma)	return 0;    wma->wDevID = modp->wDeviceID;    mciSetDriverData(wma->wDevID, (DWORD)wma);    wma->wCommandTable = mciLoadCommandResource(MCIAVI_hInstance, mciAviWStr, 0);    modp->wCustomCommandTable = wma->wCommandTable;    modp->wType = MCI_DEVTYPE_DIGITAL_VIDEO;    return modp->wDeviceID;}/************************************************************************** * 				MCIAVI_drvClose		[internal] */static	DWORD	MCIAVI_drvClose(DWORD dwDevID){    WINE_MCIAVI*  wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID);    if (wma) {	mciSetDriverData(dwDevID, 0);	mciFreeCommandResource(wma->wCommandTable);	HeapFree(GetProcessHeap(), 0, wma);	return 1;    }    return (dwDevID == 0xFFFFFFFF) ? 1 : 0;}/************************************************************************** * 				MCIAVI_drvConfigure		[internal] */static	DWORD	MCIAVI_drvConfigure(DWORD dwDevID){    WINE_MCIAVI*  wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID);    if (wma) {	MessageBoxA(0, "Sample AVI Wine Driver !", "MM-Wine Driver", MB_OK);	return 1;    }    return 0;}/************************************************************************** * 				MCIAVI_mciGetOpenDev		[internal] */WINE_MCIAVI*  MCIAVI_mciGetOpenDev(UINT wDevID){    WINE_MCIAVI*	wma = (WINE_MCIAVI*)mciGetDriverData(wDevID);    if (wma == NULL || wma->nUseCount == 0) {	WARN("Invalid wDevID=%u\n", wDevID);	return 0;    }    return wma;}static void MCIAVI_CleanUp(WINE_MCIAVI* wma){    /* to prevent handling in WindowProc */    wma->dwStatus = MCI_MODE_NOT_READY;    if (wma->hFile) {	mmioClose(wma->hFile, 0);	wma->hFile = 0;	if (wma->lpVideoIndex)	HeapFree(GetProcessHeap(), 0, wma->lpVideoIndex);	wma->lpVideoIndex = NULL;	if (wma->lpAudioIndex)	HeapFree(GetProcessHeap(), 0, wma->lpAudioIndex);	wma->lpAudioIndex = NULL;	if (wma->hic)		ICClose(wma->hic);	wma->hic = 0;	if (wma->inbih)		HeapFree(GetProcessHeap(), 0, wma->inbih);	wma->inbih = NULL;	if (wma->outbih)	HeapFree(GetProcessHeap(), 0, wma->outbih);	wma->outbih = NULL;        if (wma->indata)	HeapFree(GetProcessHeap(), 0, wma->indata);	wma->indata = NULL;    	if (wma->outdata)	HeapFree(GetProcessHeap(), 0, wma->outdata);	wma->outdata = NULL;    	if (wma->hbmFrame)	DeleteObject(wma->hbmFrame);	wma->hbmFrame = 0;	if (wma->hWnd)		DestroyWindow(wma->hWnd);	wma->hWnd = 0;	if (wma->lpWaveFormat)	HeapFree(GetProcessHeap(), 0, wma->lpWaveFormat);	wma->lpWaveFormat = 0;	memset(&wma->mah, 0, sizeof(wma->mah));	memset(&wma->ash_video, 0, sizeof(wma->ash_video));	memset(&wma->ash_audio, 0, sizeof(wma->ash_audio));	wma->dwCurrVideoFrame = wma->dwCurrAudioBlock = 0;    }}static	DWORD	MCIAVI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);/*************************************************************************** * 				MCIAVI_mciOpen			[internal] */static	DWORD	MCIAVI_mciOpen(UINT wDevID, DWORD dwFlags,			    LPMCI_DGV_OPEN_PARMSA lpOpenParms){    WINE_MCIAVI*	wma = (WINE_MCIAVI*)mciGetDriverData(wDevID);    LRESULT		dwRet = 0;    TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpOpenParms);    if (lpOpenParms == NULL) 		return MCIERR_NULL_PARAMETER_BLOCK;    if (wma == NULL)			return MCIERR_INVALID_DEVICE_ID;    if (wma->nUseCount > 0) {	/* The driver is already open on this channel */	/* If the driver was opened shareable before and this open specifies */	/* shareable then increment the use count */	if (wma->fShareable && (dwFlags & MCI_OPEN_SHAREABLE))	    ++wma->nUseCount;	else	    return MCIERR_MUST_USE_SHAREABLE;    } else {	wma->nUseCount = 1;	wma->fShareable = dwFlags & MCI_OPEN_SHAREABLE;    }    wma->dwStatus = MCI_MODE_NOT_READY;    InitializeCriticalSection(&wma->cs);    if (dwFlags & MCI_OPEN_ELEMENT) {	if (dwFlags & MCI_OPEN_ELEMENT_ID) {	    /* could it be that (DWORD)lpOpenParms->lpstrElementName	     * contains the hFile value ?	     */	    dwRet = MCIERR_UNRECOGNIZED_COMMAND;	} else if (strlen(lpOpenParms->lpstrElementName) > 0) {	    /* FIXME : what should be done id wma->hFile is already != 0, or the driver is playin' */	    TRACE("MCI_OPEN_ELEMENT '%s' !\n", lpOpenParms->lpstrElementName);	    if (lpOpenParms->lpstrElementName && (strlen(lpOpenParms->lpstrElementName) > 0)) {		wma->hFile = mmioOpenA(lpOpenParms->lpstrElementName, NULL,				       MMIO_ALLOCBUF | MMIO_DENYWRITE | MMIO_READWRITE);		if (wma->hFile == 0) {		    WARN("can't find file='%s' !\n", lpOpenParms->lpstrElementName);		    dwRet = MCIERR_FILE_NOT_FOUND;		} else {		    if (!MCIAVI_GetInfo(wma))			dwRet = MCIERR_INVALID_FILE;		    else if (!MCIAVI_OpenVideo(wma))			dwRet = MCIERR_CANNOT_LOAD_DRIVER;		    else if (!MCIAVI_CreateWindow(wma, dwFlags, lpOpenParms))			dwRet = MCIERR_CREATEWINDOW;		}	    }	} else {	    FIXME("Don't record yet\n");	    dwRet = MCIERR_UNSUPPORTED_FUNCTION;	}    }    memcpy(&wma->openParms, lpOpenParms, sizeof(MCI_WAVE_OPEN_PARMSA));    if (dwRet == 0) {	wma->dwStatus = MCI_MODE_STOP;	wma->dwMciTimeFormat = MCI_FORMAT_FRAMES;    } else {	MCIAVI_CleanUp(wma);    }    return dwRet;}/*************************************************************************** * 				MCIAVI_mciClose			[internal] */static	DWORD	MCIAVI_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms){    WINE_MCIAVI*	wma = MCIAVI_mciGetOpenDev(wDevID);    DWORD		dwRet = 0;    TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);    if (wma == NULL) 	return MCIERR_INVALID_DEVICE_ID;    if (wma->nUseCount == 1) {	if (wma->dwStatus != MCI_MODE_STOP)	    dwRet = MCIAVI_mciStop(wDevID, MCI_WAIT, lpParms);    	MCIAVI_CleanUp(wma);	if ((dwFlags & MCI_NOTIFY) && lpParms) {	    mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),			    wma->openParms.wDeviceID,			    MCI_NOTIFY_SUCCESSFUL);	}	HeapFree(GetProcessHeap(), 0, wma);	return dwRet;    }    wma->nUseCount--;    return dwRet;}

⌨️ 快捷键说明

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