1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
6 * Copyright 1998 Patrik Stridvall
17 #include "debugtools.h"
19 DEFAULT_DEBUG_CHANNEL(msacm);
21 /***********************************************************************
22 * acmFilterChooseA (MSACM32.13)
24 MMRESULT WINAPI acmFilterChooseA(PACMFILTERCHOOSEA pafltrc)
26 FIXME("(%p): stub\n", pafltrc);
27 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
28 return MMSYSERR_ERROR;
31 /***********************************************************************
32 * acmFilterChooseW (MSACM32.14)
34 MMRESULT WINAPI acmFilterChooseW(PACMFILTERCHOOSEW pafltrc)
36 FIXME("(%p): stub\n", pafltrc);
37 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
38 return MMSYSERR_ERROR;
41 /***********************************************************************
42 * acmFilterDetailsA (MSACM32.15)
44 MMRESULT WINAPI acmFilterDetailsA(HACMDRIVER had, PACMFILTERDETAILSA pafd,
47 ACMFILTERDETAILSW afdw;
50 memset(&afdw, 0, sizeof(afdw));
51 afdw.cbStruct = sizeof(afdw);
52 afdw.dwFilterIndex = pafd->dwFilterIndex;
53 afdw.dwFilterTag = pafd->dwFilterTag;
54 afdw.pwfltr = pafd->pwfltr;
55 afdw.cbwfltr = pafd->cbwfltr;
57 mmr = acmFilterDetailsW(had, &afdw, fdwDetails);
58 if (mmr == MMSYSERR_NOERROR) {
59 pafd->dwFilterTag = afdw.dwFilterTag;
60 pafd->fdwSupport = afdw.fdwSupport;
61 WideCharToMultiByte( CP_ACP, 0, afdw.szFilter, -1, pafd->szFilter,
62 sizeof(pafd->szFilter), NULL, NULL );
67 /***********************************************************************
68 * acmFilterDetailsW (MSACM32.16)
70 MMRESULT WINAPI acmFilterDetailsW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
74 ACMFILTERTAGDETAILSA aftd;
76 TRACE("(0x%08x, %p, %ld)\n", had, pafd, fdwDetails);
78 memset(&aftd, 0, sizeof(aftd));
79 aftd.cbStruct = sizeof(aftd);
81 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
84 case ACM_FILTERDETAILSF_FILTER:
85 if (pafd->dwFilterTag != pafd->pwfltr->dwFilterTag) {
86 mmr = MMSYSERR_INVALPARAM;
89 if (had == (HACMDRIVER)NULL) {
90 PWINE_ACMDRIVERID padid;
92 mmr = ACMERR_NOTPOSSIBLE;
93 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
94 /* should check for codec only */
95 if (padid->bEnabled &&
96 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
97 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
98 (LPARAM)pafd, (LPARAM)fdwDetails);
99 acmDriverClose(had, 0);
100 if (mmr == MMSYSERR_NOERROR) break;
104 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
105 (LPARAM)pafd, (LPARAM)fdwDetails);
108 case ACM_FILTERDETAILSF_INDEX:
109 /* should check pafd->dwFilterIndex < aftd->cStandardFilters */
110 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
111 (LPARAM)pafd, (LPARAM)fdwDetails);
114 WARN("Unknown fdwDetails %08lx\n", fdwDetails);
115 mmr = MMSYSERR_INVALFLAG;
119 TRACE("=> %d\n", mmr);
123 struct MSACM_FilterEnumWtoA_Instance {
124 PACMFILTERDETAILSA pafda;
126 ACMFILTERENUMCBA fnCallback;
129 static BOOL CALLBACK MSACM_FilterEnumCallbackWtoA(HACMDRIVERID hadid,
130 PACMFILTERDETAILSW pafdw,
134 struct MSACM_FilterEnumWtoA_Instance* pafei;
136 pafei = (struct MSACM_FilterEnumWtoA_Instance*)dwInstance;
138 pafei->pafda->dwFilterIndex = pafdw->dwFilterIndex;
139 pafei->pafda->dwFilterTag = pafdw->dwFilterTag;
140 pafei->pafda->fdwSupport = pafdw->fdwSupport;
141 WideCharToMultiByte( CP_ACP, 0, pafdw->szFilter, -1, pafei->pafda->szFilter,
142 sizeof(pafei->pafda->szFilter), NULL, NULL );
144 return (pafei->fnCallback)(hadid, pafei->pafda,
145 pafei->dwInstance, fdwSupport);
148 /***********************************************************************
149 * acmFilterEnumA (MSACM32.17)
151 MMRESULT WINAPI acmFilterEnumA(HACMDRIVER had, PACMFILTERDETAILSA pafda,
152 ACMFILTERENUMCBA fnCallback, DWORD dwInstance,
155 ACMFILTERDETAILSW afdw;
156 struct MSACM_FilterEnumWtoA_Instance afei;
158 memset(&afdw, 0, sizeof(afdw));
159 afdw.cbStruct = sizeof(afdw);
160 afdw.dwFilterIndex = pafda->dwFilterIndex;
161 afdw.dwFilterTag = pafda->dwFilterTag;
162 afdw.pwfltr = pafda->pwfltr;
163 afdw.cbwfltr = pafda->cbwfltr;
166 afei.dwInstance = dwInstance;
167 afei.fnCallback = fnCallback;
169 return acmFilterEnumW(had, &afdw, MSACM_FilterEnumCallbackWtoA,
170 (DWORD)&afei, fdwEnum);
173 static BOOL MSACM_FilterEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had,
174 PACMFILTERDETAILSW pafd,
175 ACMFILTERENUMCBW fnCallback, DWORD dwInstance,
178 ACMDRIVERDETAILSW add;
179 ACMFILTERTAGDETAILSW aftd;
182 add.cbStruct = sizeof(add);
184 if (acmDriverDetailsW((HACMDRIVERID)padid, &add, 0) != MMSYSERR_NOERROR) return FALSE;
186 for (i = 0; i < add.cFilterTags; i++) {
187 memset(&aftd, 0, sizeof(aftd));
188 aftd.cbStruct = sizeof(aftd);
189 aftd.dwFilterTagIndex = i;
190 if (acmFilterTagDetailsW(had, &aftd, ACM_FILTERTAGDETAILSF_INDEX) != MMSYSERR_NOERROR)
193 if ((fdwEnum & ACM_FILTERENUMF_DWFILTERTAG) &&
194 aftd.dwFilterTag != pafd->pwfltr->dwFilterTag)
197 for (j = 0; j < aftd.cStandardFilters; j++) {
198 pafd->dwFilterIndex = j;
199 pafd->dwFilterTag = aftd.dwFilterTag;
200 if (acmFilterDetailsW(had, pafd, ACM_FILTERDETAILSF_INDEX) != MMSYSERR_NOERROR)
203 if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, add.fdwSupport))
210 /***********************************************************************
211 * acmFilterEnumW (MSACM32.18)
213 MMRESULT WINAPI acmFilterEnumW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
214 ACMFILTERENUMCBW fnCallback, DWORD dwInstance,
217 PWINE_ACMDRIVERID padid;
220 TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
221 had, pafd, fnCallback, dwInstance, fdwEnum);
223 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
225 if (fdwEnum & ~(ACM_FILTERENUMF_DWFILTERTAG))
226 FIXME("Unsupported fdwEnum values\n");
231 if (acmDriverID(had, &hadid, 0) != MMSYSERR_NOERROR)
232 return MMSYSERR_INVALHANDLE;
233 MSACM_FilterEnumHelper(MSACM_GetDriverID(hadid), had, pafd,
234 fnCallback, dwInstance, fdwEnum);
235 return MMSYSERR_NOERROR;
237 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
238 /* should check for codec only */
239 if (!padid->bEnabled || acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
241 ret = MSACM_FilterEnumHelper(padid, had, pafd,
242 fnCallback, dwInstance, fdwEnum);
243 acmDriverClose(had, 0);
246 return MMSYSERR_NOERROR;
249 /***********************************************************************
250 * acmFilterTagDetailsA (MSACM32.19)
252 MMRESULT WINAPI acmFilterTagDetailsA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
255 ACMFILTERTAGDETAILSW aftdw;
258 memset(&aftdw, 0, sizeof(aftdw));
259 aftdw.cbStruct = sizeof(aftdw);
260 aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
261 aftdw.dwFilterTag = paftda->dwFilterTag;
263 mmr = acmFilterTagDetailsW(had, &aftdw, fdwDetails);
264 if (mmr == MMSYSERR_NOERROR) {
265 paftda->dwFilterTag = aftdw.dwFilterTag;
266 paftda->dwFilterTagIndex = aftdw.dwFilterTagIndex;
267 paftda->cbFilterSize = aftdw.cbFilterSize;
268 paftda->fdwSupport = aftdw.fdwSupport;
269 paftda->cStandardFilters = aftdw.cStandardFilters;
270 WideCharToMultiByte( CP_ACP, 0, aftdw.szFilterTag, -1, paftda->szFilterTag,
271 sizeof(paftda->szFilterTag), NULL, NULL );
276 /***********************************************************************
277 * acmFilterTagDetailsW (MSACM32.20)
279 MMRESULT WINAPI acmFilterTagDetailsW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
282 PWINE_ACMDRIVERID padid;
285 TRACE("(0x%08x, %p, %ld)\n", had, paftd, fdwDetails);
287 if (fdwDetails & ~(ACM_FILTERTAGDETAILSF_FILTERTAG|ACM_FILTERTAGDETAILSF_INDEX|
288 ACM_FILTERTAGDETAILSF_LARGESTSIZE))
289 return MMSYSERR_INVALFLAG;
291 switch (fdwDetails) {
292 case ACM_FILTERTAGDETAILSF_FILTERTAG:
293 if (had == (HACMDRIVER)NULL) {
294 mmr = ACMERR_NOTPOSSIBLE;
295 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
296 /* should check for codec only */
297 if (padid->bEnabled && acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
298 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
299 (LPARAM)paftd, (LPARAM)fdwDetails);
300 acmDriverClose(had, 0);
301 if (mmr == MMSYSERR_NOERROR) break;
305 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
306 (LPARAM)paftd, (LPARAM)fdwDetails);
310 case ACM_FILTERTAGDETAILSF_INDEX:
311 /* FIXME should check paftd->dwFilterTagIndex < add.cFilterTags */
312 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
313 (LPARAM)paftd, (LPARAM)fdwDetails);
316 case ACM_FILTERTAGDETAILSF_LARGESTSIZE:
317 if (had == (HACMDRIVER)NULL) {
318 ACMFILTERTAGDETAILSW tmp;
319 DWORD ft = paftd->dwFilterTag;
321 mmr = ACMERR_NOTPOSSIBLE;
322 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
323 /* should check for codec only */
324 if (padid->bEnabled &&
325 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
327 memset(&tmp, 0, sizeof(tmp));
328 tmp.cbStruct = sizeof(tmp);
329 tmp.dwFilterTag = ft;
331 if (MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
333 (LPARAM)fdwDetails) == MMSYSERR_NOERROR) {
334 if (mmr == ACMERR_NOTPOSSIBLE ||
335 paftd->cbFilterSize < tmp.cbFilterSize) {
337 mmr = MMSYSERR_NOERROR;
340 acmDriverClose(had, 0);
344 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
345 (LPARAM)paftd, (LPARAM)fdwDetails);
350 WARN("Unsupported fdwDetails=%08lx\n", fdwDetails);
351 mmr = MMSYSERR_ERROR;
354 if (mmr == MMSYSERR_NOERROR &&
355 paftd->dwFilterTag == WAVE_FORMAT_PCM && paftd->szFilterTag[0] == 0)
356 MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFilterTag,
357 sizeof(paftd->szFilterTag)/sizeof(WCHAR) );
362 struct MSACM_FilterTagEnumWtoA_Instance {
363 PACMFILTERTAGDETAILSA paftda;
365 ACMFILTERTAGENUMCBA fnCallback;
368 static BOOL CALLBACK MSACM_FilterTagEnumCallbackWtoA(HACMDRIVERID hadid,
369 PACMFILTERTAGDETAILSW paftdw,
373 struct MSACM_FilterTagEnumWtoA_Instance* paftei;
375 paftei = (struct MSACM_FilterTagEnumWtoA_Instance*)dwInstance;
377 paftei->paftda->dwFilterTagIndex = paftdw->dwFilterTagIndex;
378 paftei->paftda->dwFilterTag = paftdw->dwFilterTag;
379 paftei->paftda->cbFilterSize = paftdw->cbFilterSize;
380 paftei->paftda->fdwSupport = paftdw->fdwSupport;
381 paftei->paftda->cStandardFilters = paftdw->cStandardFilters;
382 WideCharToMultiByte( CP_ACP, 0, paftdw->szFilterTag, -1, paftei->paftda->szFilterTag,
383 sizeof(paftei->paftda->szFilterTag), NULL, NULL );
385 return (paftei->fnCallback)(hadid, paftei->paftda,
386 paftei->dwInstance, fdwSupport);
389 /***********************************************************************
390 * acmFilterTagEnumA (MSACM32.21)
392 MMRESULT WINAPI acmFilterTagEnumA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
393 ACMFILTERTAGENUMCBA fnCallback, DWORD dwInstance,
396 ACMFILTERTAGDETAILSW aftdw;
397 struct MSACM_FilterTagEnumWtoA_Instance aftei;
399 memset(&aftdw, 0, sizeof(aftdw));
400 aftdw.cbStruct = sizeof(aftdw);
401 aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
402 aftdw.dwFilterTag = paftda->dwFilterTag;
404 aftei.paftda = paftda;
405 aftei.dwInstance = dwInstance;
406 aftei.fnCallback = fnCallback;
408 return acmFilterTagEnumW(had, &aftdw, MSACM_FilterTagEnumCallbackWtoA,
409 (DWORD)&aftei, fdwEnum);
412 /***********************************************************************
413 * acmFilterTagEnumW (MSACM32.22)
415 MMRESULT WINAPI acmFilterTagEnumW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
416 ACMFILTERTAGENUMCBW fnCallback, DWORD dwInstance,
419 PWINE_ACMDRIVERID padid;
420 ACMDRIVERDETAILSW add;
423 TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
424 had, paftd, fnCallback, dwInstance, fdwEnum);
426 if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM;
428 if (had) FIXME("had != NULL, not supported\n");
430 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
431 /* should check for codec only */
432 if (padid->bEnabled && acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) {
433 add.cbStruct = sizeof(add);
435 if (acmDriverDetailsW((HACMDRIVERID)padid, &add, 0) == MMSYSERR_NOERROR) {
436 for (i = 0; i < add.cFilterTags; i++) {
437 paftd->dwFilterTagIndex = i;
438 if (acmFilterTagDetailsW(had, paftd, ACM_FILTERTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
439 if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance,
448 acmDriverClose(had, 0);
450 return MMSYSERR_NOERROR;