1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
6 * Copyright 1998 Patrik Stridvall
16 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(msacm);
20 /***********************************************************************
21 * acmFilterChooseA (MSACM32.13)
23 MMRESULT WINAPI acmFilterChooseA(PACMFILTERCHOOSEA pafltrc)
25 FIXME("(%p): stub\n", pafltrc);
26 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
27 return MMSYSERR_ERROR;
30 /***********************************************************************
31 * acmFilterChooseW (MSACM32.14)
33 MMRESULT WINAPI acmFilterChooseW(PACMFILTERCHOOSEW pafltrc)
35 FIXME("(%p): stub\n", pafltrc);
36 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
37 return MMSYSERR_ERROR;
40 /***********************************************************************
41 * acmFilterDetailsA (MSACM32.15)
43 MMRESULT WINAPI acmFilterDetailsA(HACMDRIVER had, PACMFILTERDETAILSA pafd,
46 ACMFILTERDETAILSW afdw;
49 memset(&afdw, 0, sizeof(afdw));
50 afdw.cbStruct = sizeof(afdw);
51 afdw.dwFilterIndex = pafd->dwFilterIndex;
52 afdw.dwFilterTag = pafd->dwFilterTag;
53 afdw.pwfltr = pafd->pwfltr;
54 afdw.cbwfltr = pafd->cbwfltr;
56 mmr = acmFilterDetailsW(had, &afdw, fdwDetails);
57 if (mmr == MMSYSERR_NOERROR) {
58 pafd->dwFilterTag = afdw.dwFilterTag;
59 pafd->fdwSupport = afdw.fdwSupport;
60 WideCharToMultiByte( CP_ACP, 0, afdw.szFilter, -1, pafd->szFilter,
61 sizeof(pafd->szFilter), NULL, NULL );
66 /***********************************************************************
67 * acmFilterDetailsW (MSACM32.16)
69 MMRESULT WINAPI acmFilterDetailsW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
73 ACMFILTERTAGDETAILSA aftd;
75 TRACE("(0x%08x, %p, %ld)\n", had, pafd, fdwDetails);
77 memset(&aftd, 0, sizeof(aftd));
78 aftd.cbStruct = sizeof(aftd);
80 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
83 case ACM_FILTERDETAILSF_FILTER:
84 if (pafd->dwFilterTag != pafd->pwfltr->dwFilterTag) {
85 mmr = MMSYSERR_INVALPARAM;
88 if (had == (HACMDRIVER)NULL) {
89 PWINE_ACMDRIVERID padid;
91 mmr = ACMERR_NOTPOSSIBLE;
92 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
93 /* should check for codec only */
94 if (padid->bEnabled &&
95 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
96 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
97 (LPARAM)pafd, (LPARAM)fdwDetails);
98 acmDriverClose(had, 0);
99 if (mmr == MMSYSERR_NOERROR) break;
103 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
104 (LPARAM)pafd, (LPARAM)fdwDetails);
107 case ACM_FILTERDETAILSF_INDEX:
108 /* should check pafd->dwFilterIndex < aftd->cStandardFilters */
109 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
110 (LPARAM)pafd, (LPARAM)fdwDetails);
113 WARN("Unknown fdwDetails %08lx\n", fdwDetails);
114 mmr = MMSYSERR_INVALFLAG;
118 TRACE("=> %d\n", mmr);
122 struct MSACM_FilterEnumWtoA_Instance {
123 PACMFILTERDETAILSA pafda;
125 ACMFILTERENUMCBA fnCallback;
128 static BOOL CALLBACK MSACM_FilterEnumCallbackWtoA(HACMDRIVERID hadid,
129 PACMFILTERDETAILSW pafdw,
133 struct MSACM_FilterEnumWtoA_Instance* pafei;
135 pafei = (struct MSACM_FilterEnumWtoA_Instance*)dwInstance;
137 pafei->pafda->dwFilterIndex = pafdw->dwFilterIndex;
138 pafei->pafda->dwFilterTag = pafdw->dwFilterTag;
139 pafei->pafda->fdwSupport = pafdw->fdwSupport;
140 WideCharToMultiByte( CP_ACP, 0, pafdw->szFilter, -1, pafei->pafda->szFilter,
141 sizeof(pafei->pafda->szFilter), NULL, NULL );
143 return (pafei->fnCallback)(hadid, pafei->pafda,
144 pafei->dwInstance, fdwSupport);
147 /***********************************************************************
148 * acmFilterEnumA (MSACM32.17)
150 MMRESULT WINAPI acmFilterEnumA(HACMDRIVER had, PACMFILTERDETAILSA pafda,
151 ACMFILTERENUMCBA fnCallback, DWORD dwInstance,
154 ACMFILTERDETAILSW afdw;
155 struct MSACM_FilterEnumWtoA_Instance afei;
157 memset(&afdw, 0, sizeof(afdw));
158 afdw.cbStruct = sizeof(afdw);
159 afdw.dwFilterIndex = pafda->dwFilterIndex;
160 afdw.dwFilterTag = pafda->dwFilterTag;
161 afdw.pwfltr = pafda->pwfltr;
162 afdw.cbwfltr = pafda->cbwfltr;
165 afei.dwInstance = dwInstance;
166 afei.fnCallback = fnCallback;
168 return acmFilterEnumW(had, &afdw, MSACM_FilterEnumCallbackWtoA,
169 (DWORD)&afei, fdwEnum);
172 static BOOL MSACM_FilterEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had,
173 PACMFILTERDETAILSW pafd,
174 ACMFILTERENUMCBW fnCallback, DWORD dwInstance,
177 ACMDRIVERDETAILSW add;
178 ACMFILTERTAGDETAILSW aftd;
181 add.cbStruct = sizeof(add);
183 if (acmDriverDetailsW((HACMDRIVERID)padid, &add, 0) != MMSYSERR_NOERROR) return FALSE;
185 for (i = 0; i < add.cFilterTags; i++) {
186 memset(&aftd, 0, sizeof(aftd));
187 aftd.cbStruct = sizeof(aftd);
188 aftd.dwFilterTagIndex = i;
189 if (acmFilterTagDetailsW(had, &aftd, ACM_FILTERTAGDETAILSF_INDEX) != MMSYSERR_NOERROR)
192 if ((fdwEnum & ACM_FILTERENUMF_DWFILTERTAG) &&
193 aftd.dwFilterTag != pafd->pwfltr->dwFilterTag)
196 for (j = 0; j < aftd.cStandardFilters; j++) {
197 pafd->dwFilterIndex = j;
198 pafd->dwFilterTag = aftd.dwFilterTag;
199 if (acmFilterDetailsW(had, pafd, ACM_FILTERDETAILSF_INDEX) != MMSYSERR_NOERROR)
202 if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, add.fdwSupport))
209 /***********************************************************************
210 * acmFilterEnumW (MSACM32.18)
212 MMRESULT WINAPI acmFilterEnumW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
213 ACMFILTERENUMCBW fnCallback, DWORD dwInstance,
216 PWINE_ACMDRIVERID padid;
219 TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
220 had, pafd, fnCallback, dwInstance, fdwEnum);
222 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
224 if (fdwEnum & ~(ACM_FILTERENUMF_DWFILTERTAG))
225 FIXME("Unsupported fdwEnum values\n");
230 if (acmDriverID(had, &hadid, 0) != MMSYSERR_NOERROR)
231 return MMSYSERR_INVALHANDLE;
232 return MSACM_FilterEnumHelper(MSACM_GetDriverID(hadid), had, pafd,
233 fnCallback, dwInstance, fdwEnum);
235 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
236 /* should check for codec only */
237 if (!padid->bEnabled || acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
239 ret = MSACM_FilterEnumHelper(padid, had, pafd,
240 fnCallback, dwInstance, fdwEnum);
241 acmDriverClose(had, 0);
244 return MMSYSERR_NOERROR;
247 /***********************************************************************
248 * acmFilterTagDetailsA (MSACM32.19)
250 MMRESULT WINAPI acmFilterTagDetailsA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
253 ACMFILTERTAGDETAILSW aftdw;
256 memset(&aftdw, 0, sizeof(aftdw));
257 aftdw.cbStruct = sizeof(aftdw);
258 aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
259 aftdw.dwFilterTag = paftda->dwFilterTag;
261 mmr = acmFilterTagDetailsW(had, &aftdw, fdwDetails);
262 if (mmr == MMSYSERR_NOERROR) {
263 paftda->dwFilterTag = aftdw.dwFilterTag;
264 paftda->dwFilterTagIndex = aftdw.dwFilterTagIndex;
265 paftda->cbFilterSize = aftdw.cbFilterSize;
266 paftda->fdwSupport = aftdw.fdwSupport;
267 paftda->cStandardFilters = aftdw.cStandardFilters;
268 WideCharToMultiByte( CP_ACP, 0, aftdw.szFilterTag, -1, paftda->szFilterTag,
269 sizeof(paftda->szFilterTag), NULL, NULL );
274 /***********************************************************************
275 * acmFilterTagDetailsW (MSACM32.20)
277 MMRESULT WINAPI acmFilterTagDetailsW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
280 PWINE_ACMDRIVERID padid;
283 TRACE("(0x%08x, %p, %ld)\n", had, paftd, fdwDetails);
285 if (fdwDetails & ~(ACM_FILTERTAGDETAILSF_FILTERTAG|ACM_FILTERTAGDETAILSF_INDEX|
286 ACM_FILTERTAGDETAILSF_LARGESTSIZE))
287 return MMSYSERR_INVALFLAG;
289 switch (fdwDetails) {
290 case ACM_FILTERTAGDETAILSF_FILTERTAG:
291 if (had == (HACMDRIVER)NULL) {
292 mmr = ACMERR_NOTPOSSIBLE;
293 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
294 /* should check for codec only */
295 if (padid->bEnabled && acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
296 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
297 (LPARAM)paftd, (LPARAM)fdwDetails);
298 acmDriverClose(had, 0);
299 if (mmr == MMSYSERR_NOERROR) break;
303 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
304 (LPARAM)paftd, (LPARAM)fdwDetails);
308 case ACM_FILTERTAGDETAILSF_INDEX:
309 /* FIXME should check paftd->dwFilterTagIndex < add.cFilterTags */
310 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
311 (LPARAM)paftd, (LPARAM)fdwDetails);
314 case ACM_FILTERTAGDETAILSF_LARGESTSIZE:
315 if (had == (HACMDRIVER)NULL) {
316 ACMFILTERTAGDETAILSW tmp;
317 DWORD ft = paftd->dwFilterTag;
319 mmr = ACMERR_NOTPOSSIBLE;
320 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
321 /* should check for codec only */
322 if (padid->bEnabled &&
323 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
325 memset(&tmp, 0, sizeof(tmp));
326 tmp.cbStruct = sizeof(tmp);
327 tmp.dwFilterTag = ft;
329 if (MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
331 (LPARAM)fdwDetails) == MMSYSERR_NOERROR) {
332 if (mmr == ACMERR_NOTPOSSIBLE ||
333 paftd->cbFilterSize < tmp.cbFilterSize) {
335 mmr = MMSYSERR_NOERROR;
338 acmDriverClose(had, 0);
342 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
343 (LPARAM)paftd, (LPARAM)fdwDetails);
348 WARN("Unsupported fdwDetails=%08lx\n", fdwDetails);
349 mmr = MMSYSERR_ERROR;
352 if (mmr == MMSYSERR_NOERROR &&
353 paftd->dwFilterTag == WAVE_FORMAT_PCM && paftd->szFilterTag[0] == 0)
354 MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFilterTag,
355 sizeof(paftd->szFilterTag)/sizeof(WCHAR) );
360 struct MSACM_FilterTagEnumWtoA_Instance {
361 PACMFILTERTAGDETAILSA paftda;
363 ACMFILTERTAGENUMCBA fnCallback;
366 static BOOL CALLBACK MSACM_FilterTagEnumCallbackWtoA(HACMDRIVERID hadid,
367 PACMFILTERTAGDETAILSW paftdw,
371 struct MSACM_FilterTagEnumWtoA_Instance* paftei;
373 paftei = (struct MSACM_FilterTagEnumWtoA_Instance*)dwInstance;
375 paftei->paftda->dwFilterTagIndex = paftdw->dwFilterTagIndex;
376 paftei->paftda->dwFilterTag = paftdw->dwFilterTag;
377 paftei->paftda->cbFilterSize = paftdw->cbFilterSize;
378 paftei->paftda->fdwSupport = paftdw->fdwSupport;
379 paftei->paftda->cStandardFilters = paftdw->cStandardFilters;
380 WideCharToMultiByte( CP_ACP, 0, paftdw->szFilterTag, -1, paftei->paftda->szFilterTag,
381 sizeof(paftei->paftda->szFilterTag), NULL, NULL );
383 return (paftei->fnCallback)(hadid, paftei->paftda,
384 paftei->dwInstance, fdwSupport);
387 /***********************************************************************
388 * acmFilterTagEnumA (MSACM32.21)
390 MMRESULT WINAPI acmFilterTagEnumA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
391 ACMFILTERTAGENUMCBA fnCallback, DWORD dwInstance,
394 ACMFILTERTAGDETAILSW aftdw;
395 struct MSACM_FilterTagEnumWtoA_Instance aftei;
397 memset(&aftdw, 0, sizeof(aftdw));
398 aftdw.cbStruct = sizeof(aftdw);
399 aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
400 aftdw.dwFilterTag = paftda->dwFilterTag;
402 aftei.paftda = paftda;
403 aftei.dwInstance = dwInstance;
404 aftei.fnCallback = fnCallback;
406 return acmFilterTagEnumW(had, &aftdw, MSACM_FilterTagEnumCallbackWtoA,
407 (DWORD)&aftei, fdwEnum);
410 /***********************************************************************
411 * acmFilterTagEnumW (MSACM32.22)
413 MMRESULT WINAPI acmFilterTagEnumW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
414 ACMFILTERTAGENUMCBW fnCallback, DWORD dwInstance,
417 PWINE_ACMDRIVERID padid;
418 ACMDRIVERDETAILSW add;
421 TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
422 had, paftd, fnCallback, dwInstance, fdwEnum);
424 if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM;
426 if (had) FIXME("had != NULL, not supported\n");
428 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
429 /* should check for codec only */
430 if (padid->bEnabled && acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) {
431 add.cbStruct = sizeof(add);
433 if (acmDriverDetailsW((HACMDRIVERID)padid, &add, 0) == MMSYSERR_NOERROR) {
434 for (i = 0; i < add.cFilterTags; i++) {
435 paftd->dwFilterTagIndex = i;
436 if (acmFilterTagDetailsW(had, paftd, ACM_FILTERTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
437 if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance,
446 acmDriverClose(had, 0);
448 return MMSYSERR_NOERROR;