[VFW] Add support for video compressor/decompressor dynamic installation
Christian Costa
titan.costa at wanadoo.fr
Sun Jun 29 04:53:30 CDT 2003
Hi,
This patch adds support for video compressor/decompressor dynamic
installation (through ICInstall).
This makes the game Schizm work and play mpeg video.
Bye,
Christian.
Changelog :
Add support for video compressor/decompressor dynamic installation.
Christian Costa titan.costa at wanadoo.fr
-------------- next part --------------
Index: msvfw32.spec
===================================================================
RCS file: /home/wine/wine/dlls/msvideo/msvfw32.spec,v
retrieving revision 1.17
diff -u -r1.17 msvfw32.spec
--- msvfw32.spec 23 Jun 2003 03:33:25 -0000 1.17
+++ msvfw32.spec 29 Jun 2003 09:23:57 -0000
@@ -34,12 +34,12 @@
@ stdcall ICImageCompress(long long ptr ptr ptr long ptr)
@ stdcall ICImageDecompress(long long ptr ptr ptr)
@ stdcall ICInfo(long long ptr)
-@ stub ICInstall
+@ stdcall ICInstall(long long ptr str long)
@ stdcall ICLocate(long long ptr ptr long)
@ stub ICMThunk
@ stdcall ICOpen(long long long)
@ stdcall ICOpenFunction(long long long ptr)
-@ stub ICRemove
+@ stdcall ICRemove(long long long)
@ stdcall ICSendMessage(long long long long)
@ stub ICSeqCompressFrame
@ stub ICSeqCompressFrameEnd
Index: msvideo_main.c
===================================================================
RCS file: /home/wine/wine/dlls/msvideo/msvideo_main.c,v
retrieving revision 1.49
diff -u -r1.49 msvideo_main.c
--- msvideo_main.c 23 Jun 2003 03:33:25 -0000 1.49
+++ msvideo_main.c 29 Jun 2003 09:24:01 -0000
@@ -47,6 +47,35 @@
static WINE_HIC* MSVIDEO_FirstHic /* = NULL */;
+typedef struct _reg_driver reg_driver;
+struct _reg_driver{
+ DWORD fccType;
+ DWORD fccHandler;
+ DRIVERPROC proc;
+ char* name;
+ reg_driver* next;
+};
+
+static reg_driver* reg_driver_list = NULL;
+
+static int compare_fourcc(DWORD fcc1, DWORD fcc2)
+{
+ char fcc_str1[5];
+ char fcc_str2[5];
+ fcc_str1[0] = LOBYTE(LOWORD(fcc1));
+ fcc_str1[1] = HIBYTE(LOWORD(fcc1));
+ fcc_str1[2] = LOBYTE(HIWORD(fcc1));
+ fcc_str1[3] = HIBYTE(HIWORD(fcc1));
+ fcc_str1[4] = 0;
+ fcc_str2[0] = LOBYTE(LOWORD(fcc2));
+ fcc_str2[1] = HIBYTE(LOWORD(fcc2));
+ fcc_str2[2] = LOBYTE(HIWORD(fcc2));
+ fcc_str2[3] = HIBYTE(HIWORD(fcc2));
+ fcc_str2[4] = 0;
+
+ return strcasecmp(fcc_str1,fcc_str2);
+}
+
/******************************************************************
* MSVIDEO_GetHicPtr
*
@@ -130,6 +159,88 @@
static DWORD IC_HandleRef = 1;
/***********************************************************************
+ * ICInstall [MSVFW32.@]
+ */
+BOOL VFWAPI ICInstall(DWORD fccType, DWORD fccHandler, LPARAM lParam, LPSTR szDesc, UINT wFlags)
+{
+ reg_driver* driver;
+
+ TRACE("(%s,%s,%p,%p,0x%08x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), (void*)lParam, szDesc, wFlags);
+
+ /* Check if a driver is already registered */
+ driver = reg_driver_list;
+ while(driver)
+ if (!compare_fourcc(fccType, driver->fccType) &&
+ !compare_fourcc(fccHandler, driver->fccHandler))
+ break;
+ else
+ driver = driver->next;
+ if (driver)
+ return FALSE;
+
+ /* Register the driver */
+ driver = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(reg_driver));
+ driver->fccType = fccType;
+ driver->fccHandler = fccHandler;
+
+ switch(wFlags) {
+ case ICINSTALL_FUNCTION:
+ driver->proc = (DRIVERPROC)lParam;
+ driver->name = NULL;
+ break;
+ case ICINSTALL_DRIVER:
+ driver->proc = NULL;
+ driver->name = HeapAlloc(GetProcessHeap(), 0, strlen((char*)lParam));
+ strcpy(driver->name, (char*) lParam);
+ break;
+ default:
+ ERR("Invalid flags!\n");
+ HeapFree(GetProcessHeap(), 0, driver);
+ return FALSE;
+ }
+
+ /* Insert our driver in the list*/
+ driver->next = reg_driver_list;
+ reg_driver_list = driver;
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * ICRemove [MSVFW32.@]
+ */
+BOOL VFWAPI ICRemove(DWORD fccType, DWORD fccHandler, UINT wFlags)
+{
+ reg_driver* driver;
+ reg_driver** previous;
+
+ TRACE("(%s,%s,0x%08x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wFlags);
+
+ /* Check if a driver is already registered */
+ driver = reg_driver_list;
+ previous = ®_driver_list;
+ while(driver)
+ if (!compare_fourcc(fccType, driver->fccType) &&
+ !compare_fourcc(fccHandler, driver->fccHandler))
+ break;
+ else {
+ previous = &(driver->next);
+ driver = driver->next;
+ }
+ if (!driver)
+ return FALSE;
+
+ /* Remove the driver from the list */
+ *previous = driver->next;
+ if (driver->name)
+ HeapFree(GetProcessHeap(), 0, driver->name);
+ HeapFree(GetProcessHeap(), 0, driver);
+
+ return TRUE;
+}
+
+
+/***********************************************************************
* ICOpen [MSVFW32.@]
* Opens an installable compressor. Return special handle.
*/
@@ -140,20 +251,23 @@
HDRVR hdrv;
WINE_HIC* whic;
BOOL bIs16;
+ reg_driver* driver;
TRACE("(%s,%s,0x%08x)\n", wine_dbgstr_fcc(fccType), wine_dbgstr_fcc(fccHandler), wMode);
- codecname[0] = LOBYTE(LOWORD(fccType));
- codecname[1] = HIBYTE(LOWORD(fccType));
- codecname[2] = LOBYTE(HIWORD(fccType));
- codecname[3] = HIBYTE(HIWORD(fccType));
- codecname[4] = '.';
- codecname[5] = LOBYTE(LOWORD(fccHandler));
- codecname[6] = HIBYTE(LOWORD(fccHandler));
- codecname[7] = LOBYTE(HIWORD(fccHandler));
- codecname[8] = HIBYTE(HIWORD(fccHandler));
- codecname[9] = '\0';
-
+ /* Check if there is a registered driver that matches */
+ driver = reg_driver_list;
+ while(driver)
+ if (!compare_fourcc(fccType, driver->fccType) &&
+ !compare_fourcc(fccHandler, driver->fccHandler))
+ break;
+ else
+ driver = driver->next;
+
+ if (driver && driver->proc)
+ /* The driver has been registered at runtime with its driverproc */
+ return MSVIDEO_OpenFunction(fccType, fccHandler, wMode, (DRIVERPROC)driver->proc, (DWORD)NULL);
+
/* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
* same layout as ICOPEN
*/
@@ -166,22 +280,41 @@
icopen.pV1Reserved = NULL;
icopen.pV2Reserved = NULL;
icopen.dnDevNode = 0; /* FIXME */
-
- hdrv = OpenDriverA(codecname, "drivers32", (LPARAM)&icopen);
- if (!hdrv)
- {
- if (fccType == streamtypeVIDEO)
- {
- codecname[0] = 'v';
- codecname[1] = 'i';
- codecname[2] = 'd';
- codecname[3] = 'c';
+
+ if (!driver) {
+ /* The driver is registered in the registry */
+ codecname[0] = LOBYTE(LOWORD(fccType));
+ codecname[1] = HIBYTE(LOWORD(fccType));
+ codecname[2] = LOBYTE(HIWORD(fccType));
+ codecname[3] = HIBYTE(HIWORD(fccType));
+ codecname[4] = '.';
+ codecname[5] = LOBYTE(LOWORD(fccHandler));
+ codecname[6] = HIBYTE(LOWORD(fccHandler));
+ codecname[7] = LOBYTE(HIWORD(fccHandler));
+ codecname[8] = HIBYTE(HIWORD(fccHandler));
+ codecname[9] = '\0';
- fccType = ICTYPE_VIDEO;
- hdrv = OpenDriverA(codecname, "drivers32", (LPARAM)&icopen);
- }
- if (!hdrv)
- return 0;
+ hdrv = OpenDriverA(codecname, "drivers32", (LPARAM)&icopen);
+ if (!hdrv)
+ {
+ if (fccType == streamtypeVIDEO)
+ {
+ codecname[0] = 'v';
+ codecname[1] = 'i';
+ codecname[2] = 'd';
+ codecname[3] = 'c';
+
+ fccType = ICTYPE_VIDEO;
+ hdrv = OpenDriverA(codecname, "drivers32", (LPARAM)&icopen);
+ }
+ if (!hdrv)
+ return 0;
+ }
+ } else {
+ /* The driver has been registered at runtime with its name */
+ hdrv = OpenDriverA(driver->name, NULL, (LPARAM)&icopen);
+ if (!hdrv)
+ return 0;
}
bIs16 = GetDriverFlags(hdrv) & WINE_GDF_16BIT;
@@ -256,9 +389,11 @@
/* return value is not checked */
MSVIDEO_SendMessage(whic, DRV_ENABLE, 0L, 0L);
- whic->hdrv = (HDRVR)MSVIDEO_SendMessage(whic, DRV_OPEN, 0, (DWORD)&icopen);
-
- if (whic->hdrv == 0)
+ whic->driverId = (DWORD)MSVIDEO_SendMessage(whic, DRV_OPEN, 0, (DWORD)&icopen);
+ /* FIXME: What should we put here? */
+ whic->hdrv = (HDRVR)0;
+
+ if (whic->driverId == 0)
{
WARN("DRV_OPEN failed for hic %p\n", whic->hic);
MSVIDEO_FirstHic = whic->next;
@@ -621,7 +756,8 @@
#undef XX
if (whic->driverproc) {
- ret = whic->driverproc((DWORD)whic->hic, whic->hdrv, msg, lParam1, lParam2);
+ /* dwDriverId parameter is the value returned by the DRV_OPEN */
+ ret = whic->driverproc(whic->driverId, whic->hdrv, msg, lParam1, lParam2);
} else {
ret = SendDriverMessage(whic->hdrv, msg, lParam1, lParam2);
}
Index: msvideo_private.h
===================================================================
RCS file: /home/wine/wine/dlls/msvideo/msvideo_private.h,v
retrieving revision 1.5
diff -u -r1.5 msvideo_private.h
--- msvideo_private.h 23 Jun 2003 03:33:25 -0000 1.5
+++ msvideo_private.h 29 Jun 2003 09:24:01 -0000
@@ -40,6 +40,7 @@
/* 26: */
DWORD driverproc16; /* Wine specific flags */
HIC hic;
+ DWORD driverId;
struct tagWINE_HIC* next;
} WINE_HIC;
More information about the wine-patches
mailing list