These are my patches to the multimedia system, now in the diff -u format. This should fix the following problems: (1) not finding the codecs at all, (2) mislisting the same codec multiple times. I now can run VirtualDub 1.4.10 almost perfectly (the speed still sucks).
Best,
Waldeck
Index: wine/dlls/msacm/format.c =================================================================== RCS file: /home/wine/wine/dlls/msacm/format.c,v retrieving revision 1.20 diff -u -r1.20 format.c --- wine/dlls/msacm/format.c 2 Dec 2002 18:10:59 -0000 1.20 +++ wine/dlls/msacm/format.c 19 Jan 2003 20:27:30 -0000 @@ -758,36 +758,69 @@ if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM; - if (had) FIXME("had != NULL, not supported\n"); + /* if (had) FIXME("had != NULL, not supported\n"); */ + + /* If had != 0, get tags for specific driver */ + if (had) { + + if (acmDriverID((HACMOBJ)had, (HACMDRIVERID *)&padid, 0) != MMSYSERR_NOERROR) + return MMSYSERR_INVALHANDLE; + + for (i = 0; i < padid->cFormatTags; i++) { + paftd->dwFormatTagIndex = i; + if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, + (LPARAM)paftd, ACM_FORMATTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) { + if (paftd->dwFormatTag == WAVE_FORMAT_PCM) { + if (paftd->szFormatTag[0] == 0) + MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag, + sizeof(paftd->szFormatTag)/sizeof(WCHAR) ); + /* FIXME (WS): I actually have no idea why one would + * have to do this. I just copied it from the block + * right below, where the EPP is not sure about it either. + * Oh, well... + */ + if (bPcmDone) continue; + bPcmDone = TRUE; + } + if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) + return MMSYSERR_NOERROR; + } + } - for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { - /* should check for codec only */ - if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && - acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) { - for (i = 0; i < padid->cFormatTags; i++) { - paftd->dwFormatTagIndex = i; - if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, - (LPARAM)paftd, ACM_FORMATTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) { - if (paftd->dwFormatTag == WAVE_FORMAT_PCM) { - if (paftd->szFormatTag[0] == 0) - MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag, - sizeof(paftd->szFormatTag)/sizeof(WCHAR) ); - /* FIXME (EPP): I'm not sure this is the correct - * algorithm (should make more sense to apply the same - * for all already loaded formats, but this will do - * for now - */ - if (bPcmDone) continue; - bPcmDone = TRUE; - } - if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) { - acmDriverClose(had, 0); - return MMSYSERR_NOERROR; - } - } - } - } - acmDriverClose(had, 0); + } + + /* if had==0 then search for the first suitable driver */ + else { + for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { + /* should check for codec only */ + if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && + acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) { + for (i = 0; i < padid->cFormatTags; i++) { + paftd->dwFormatTagIndex = i; + if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, + (LPARAM)paftd, ACM_FORMATTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) { + if (paftd->dwFormatTag == WAVE_FORMAT_PCM) { + if (paftd->szFormatTag[0] == 0) + MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag, + sizeof(paftd->szFormatTag)/sizeof(WCHAR) ); + /* FIXME (EPP): I'm not sure this is the correct + * algorithm (should make more sense to apply the same + * for all already loaded formats, but this will do + * for now + */ + if (bPcmDone) continue; + bPcmDone = TRUE; + } + if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) { + acmDriverClose(had, 0); + return MMSYSERR_NOERROR; + } + } + } + } + acmDriverClose(had, 0); + } } return MMSYSERR_NOERROR; } + Index: wine/dlls/msacm/stream.c =================================================================== RCS file: /home/wine/wine/dlls/msacm/stream.c,v retrieving revision 1.12 diff -u -r1.12 stream.c --- wine/dlls/msacm/stream.c 2 Dec 2002 18:10:59 -0000 1.12 +++ wine/dlls/msacm/stream.c 19 Jan 2003 20:27:30 -0000 @@ -147,7 +147,14 @@ pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec, pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize); + /* + * The docs say if ACM_STREAMOPENF_QUERY, phas should be NULL. It does + * not say it MUST BE NULL. This is breaking down some applications + * that happen to pass a non-null (probably garbage) phas. + if ((fdwOpen & ACM_STREAMOPENF_QUERY) && phas) return MMSYSERR_INVALPARAM; + */ + if (pwfltr && (pwfxSrc->wFormatTag != pwfxDst->wFormatTag)) return MMSYSERR_INVALPARAM; wfxSrcSize = wfxDstSize = sizeof(WAVEFORMATEX); @@ -230,14 +237,25 @@ ret = MMSYSERR_NOERROR; was->drvInst.has = (HACMSTREAM)was; if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) { - if (phas) - *phas = (HACMSTREAM)was; - TRACE("=> (%d)\n", ret); - return ret; + /* if this is not query, then return the pointer to heap */ + if (phas) + *phas = (HACMSTREAM)was; } + else + /* otherwise, we release memory to avoid leaks, hehe! */ + HeapFree(MSACM_hHeap, 0, was); + TRACE("=> (%d)\n", ret); + return ret; + errCleanUp: - if (phas) + if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) { + /* If it is not dirty, don't clean it up! + * The doc says that if ACM_STREAMOPENF_QUERY is set + * phas will not be set, even if there is an error. + */ + if (phas) *phas = NULL; + } HeapFree(MSACM_hHeap, 0, was); TRACE("=> (%d)\n", ret); return ret; Index: wine/dlls/msvideo/msvideo_main.c =================================================================== RCS file: /home/wine/wine/dlls/msvideo/msvideo_main.c,v retrieving revision 1.45 diff -u -r1.45 msvideo_main.c --- wine/dlls/msvideo/msvideo_main.c 14 Jan 2003 23:43:42 -0000 1.45 +++ wine/dlls/msvideo/msvideo_main.c 19 Jan 2003 20:27:30 -0000 @@ -79,13 +79,16 @@ char buf[2000]; TRACE("(%.4s,%.4s,%p)\n", (char*)&fccType, (char*)&fccHandler, lpicinfo); + // The "Case of the missing codecs" + // A fix proposed by Waldeck Schutzer <waldeck@dm.ufscar.br> if (GetPrivateProfileStringA("drivers32", NULL, NULL, buf, sizeof(buf), "system.ini")) { char *s = buf; while (*s) { - if (!strncasecmp((char*)&fccType, s, 4) && s[4] == '.' && s[9] == '=') + if (!strncasecmp((char*)&fccType, s, 4) && s[4] == '.' /* && s[9] == '=' */ ) + // buf is a list of keys, not keys followed by their values! { if (!fccHandler--) { @@ -95,11 +98,16 @@ hic = ICOpen(fccType, lpicinfo->fccHandler, ICMODE_QUERY); if (hic) { + // Some bad codecs can make wine crash right here. + // It would be nice to know why and to find ways + // to preventing it from happening. I can't do it. ICGetInfo(hic, lpicinfo, lpicinfo->dwSize); ICClose(hic); return TRUE; } - return FALSE; + // return FALSE; + // This one failed to open, but keep going down the list! + fccHandler++; } } s += strlen(s) + 1; /* either next char or \0 */