PATCH: fixes problems with multply listed audio codecs
Waldeck Schutzer
schutzer at math.rutgers.edu
Mon Jan 20 14:26:06 CST 2003
This patch adresses the following issues:
1. Audio codecs were being incorrectly listed several times.
2. An ideosyncrasy of acmStreamOpen would occasioanally cause some
applications to crash.
Waldeck
-------------- next part --------------
Index: wine/dlls/msacm/format.c
===================================================================
RCS file: /home/wine/wine/dlls/msacm/format.c,v
retrieving revision 1.20
diff -u -p -r1.20 format.c
--- wine/dlls/msacm/format.c 2 Dec 2002 18:10:59 -0000 1.20
+++ wine/dlls/msacm/format.c 20 Jan 2003 20:02:45 -0000
@@ -758,36 +758,74 @@ MMRESULT WINAPI acmFormatTagEnumW(HACMDR
if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM;
- if (had) FIXME("had != NULL, not supported\n");
+ /* (WS) MSDN info page says that if had != 0, then we should find
+ * the specific driver to get its tags from. Therefore I'm removing
+ * the FIXME call and adding a search block below. It also seems
+ * that the lack of this functionality was the responsible for
+ * codecs to be multiply and incorrectly listed.
+ */
+
+ /* if (had) FIXME("had != NULL, not supported\n"); */
+
+ 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) );
+ /* (WS) I'm preserving this PCM hack since it seems to be
+ * correct. Please notice this block was borrowed from
+ * below.
+ */
+ 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 -p -r1.12 stream.c
--- wine/dlls/msacm/stream.c 2 Dec 2002 18:10:59 -0000 1.12
+++ wine/dlls/msacm/stream.c 20 Jan 2003 20:02:45 -0000
@@ -147,7 +147,14 @@ MMRESULT WINAPI acmStreamOpen(PHACMSTREA
pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec,
pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize);
+ /* (WS) I'm removing the following test and making some other changes
+ * herein because the info page on MSDN says that in query mode the
+ * parameter phas should (and not must) be NULL. Otherwise some
+ * applications will crash because phas is garbage.
+
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 @@ MMRESULT WINAPI acmStreamOpen(PHACMSTREA
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 not in query mode, return pointer to allocated heap */
+ if (phas)
+ *phas = (HACMSTREAM)was;
}
+ else
+ /* otherwise, release memory to avoid leaks */
+ HeapFree(MSACM_hHeap, 0, was);
+ TRACE("=> (%d)\n", ret);
+ return ret;
+
errCleanUp:
- if (phas)
+ if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) {
+ /* (WS) As I explained above, this is supposed to be closer to what
+ * is expected from this function. In query mode phas is not needed
+ * and hence will not be used at all.
+ */
+ if (phas)
*phas = NULL;
+ }
HeapFree(MSACM_hHeap, 0, was);
TRACE("=> (%d)\n", ret);
return ret;
More information about the wine-patches
mailing list