1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
6 * Copyright 1998 Patrik Stridvall
11 #include "wine/winestring.h"
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 lstrcpyWtoA(pafd->szFilter, afdw.szFilter);
65 /***********************************************************************
66 * acmFilterDetailsW (MSACM32.16)
68 MMRESULT WINAPI acmFilterDetailsW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
72 ACMFILTERTAGDETAILSA aftd;
74 TRACE("(0x%08x, %p, %ld)\n", had, pafd, fdwDetails);
76 memset(&aftd, 0, sizeof(aftd));
77 aftd.cbStruct = sizeof(aftd);
79 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
82 case ACM_FILTERDETAILSF_FILTER:
83 if (pafd->dwFilterTag != pafd->pwfltr->dwFilterTag) {
84 mmr = MMSYSERR_INVALPARAM;
87 if (had == (HACMDRIVER)NULL) {
88 PWINE_ACMDRIVERID padid;
90 mmr = ACMERR_NOTPOSSIBLE;
91 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
92 /* should check for codec only */
93 if (padid->bEnabled &&
94 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
95 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
96 (LPARAM)pafd, (LPARAM)fdwDetails);
97 acmDriverClose(had, 0);
98 if (mmr == MMSYSERR_NOERROR) break;
102 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
103 (LPARAM)pafd, (LPARAM)fdwDetails);
106 case ACM_FILTERDETAILSF_INDEX:
107 /* should check pafd->dwFilterIndex < aftd->cStandardFilters */
108 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
109 (LPARAM)pafd, (LPARAM)fdwDetails);
112 WARN("Unknown fdwDetails %08lx\n", fdwDetails);
113 mmr = MMSYSERR_INVALFLAG;
117 TRACE("=> %d\n", mmr);
121 struct MSACM_FilterEnumWtoA_Instance {
122 PACMFILTERDETAILSA pafda;
124 ACMFILTERENUMCBA fnCallback;
127 static BOOL CALLBACK MSACM_FilterEnumCallbackWtoA(HACMDRIVERID hadid,
128 PACMFILTERDETAILSW pafdw,
132 struct MSACM_FilterEnumWtoA_Instance* pafei;
134 pafei = (struct MSACM_FilterEnumWtoA_Instance*)dwInstance;
136 pafei->pafda->dwFilterIndex = pafdw->dwFilterIndex;
137 pafei->pafda->dwFilterTag = pafdw->dwFilterTag;
138 pafei->pafda->fdwSupport = pafdw->fdwSupport;
139 lstrcpyWtoA(pafei->pafda->szFilter, pafdw->szFilter);
141 return (pafei->fnCallback)(hadid, pafei->pafda,
142 pafei->dwInstance, fdwSupport);
145 /***********************************************************************
146 * acmFilterEnumA (MSACM32.17)
148 MMRESULT WINAPI acmFilterEnumA(HACMDRIVER had, PACMFILTERDETAILSA pafda,
149 ACMFILTERENUMCBA fnCallback, DWORD dwInstance,
152 ACMFILTERDETAILSW afdw;
153 struct MSACM_FilterEnumWtoA_Instance afei;
155 memset(&afdw, 0, sizeof(afdw));
156 afdw.cbStruct = sizeof(afdw);
157 afdw.dwFilterIndex = pafda->dwFilterIndex;
158 afdw.dwFilterTag = pafda->dwFilterTag;
159 afdw.pwfltr = pafda->pwfltr;
160 afdw.cbwfltr = pafda->cbwfltr;
163 afei.dwInstance = dwInstance;
164 afei.fnCallback = fnCallback;
166 return acmFilterEnumW(had, &afdw, MSACM_FilterEnumCallbackWtoA,
167 (DWORD)&afei, fdwEnum);
170 static BOOL MSACM_FilterEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had,
171 PACMFILTERDETAILSW pafd,
172 ACMFILTERENUMCBW fnCallback, DWORD dwInstance,
175 ACMDRIVERDETAILSW add;
176 ACMFILTERTAGDETAILSW aftd;
179 add.cbStruct = sizeof(add);
181 if (acmDriverDetailsW((HACMDRIVERID)padid, &add, 0) != MMSYSERR_NOERROR) return FALSE;
183 for (i = 0; i < add.cFilterTags; i++) {
184 memset(&aftd, 0, sizeof(aftd));
185 aftd.cbStruct = sizeof(aftd);
186 aftd.dwFilterTagIndex = i;
187 if (acmFilterTagDetailsW(had, &aftd, ACM_FILTERTAGDETAILSF_INDEX) != MMSYSERR_NOERROR)
190 if ((fdwEnum & ACM_FILTERENUMF_DWFILTERTAG) &&
191 aftd.dwFilterTag != pafd->pwfltr->dwFilterTag)
194 for (j = 0; j < aftd.cStandardFilters; j++) {
195 pafd->dwFilterIndex = j;
196 pafd->dwFilterTag = aftd.dwFilterTag;
197 if (acmFilterDetailsW(had, pafd, ACM_FILTERDETAILSF_INDEX) != MMSYSERR_NOERROR)
200 if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, add.fdwSupport))
207 /***********************************************************************
208 * acmFilterEnumW (MSACM32.18)
210 MMRESULT WINAPI acmFilterEnumW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
211 ACMFILTERENUMCBW fnCallback, DWORD dwInstance,
214 PWINE_ACMDRIVERID padid;
217 TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
218 had, pafd, fnCallback, dwInstance, fdwEnum);
220 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
222 if (fdwEnum & ~(ACM_FILTERENUMF_DWFILTERTAG))
223 FIXME("Unsupported fdwEnum values\n");
228 if (acmDriverID(had, &hadid, 0) != MMSYSERR_NOERROR)
229 return MMSYSERR_INVALHANDLE;
230 return MSACM_FilterEnumHelper(MSACM_GetDriverID(hadid), had, pafd,
231 fnCallback, dwInstance, fdwEnum);
233 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
234 /* should check for codec only */
235 if (!padid->bEnabled || acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
237 ret = MSACM_FilterEnumHelper(padid, had, pafd,
238 fnCallback, dwInstance, fdwEnum);
239 acmDriverClose(had, 0);
242 return MMSYSERR_NOERROR;
245 /***********************************************************************
246 * acmFilterTagDetailsA (MSACM32.19)
248 MMRESULT WINAPI acmFilterTagDetailsA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
251 ACMFILTERTAGDETAILSW aftdw;
254 memset(&aftdw, 0, sizeof(aftdw));
255 aftdw.cbStruct = sizeof(aftdw);
256 aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
257 aftdw.dwFilterTag = paftda->dwFilterTag;
259 mmr = acmFilterTagDetailsW(had, &aftdw, fdwDetails);
260 if (mmr == MMSYSERR_NOERROR) {
261 paftda->dwFilterTag = aftdw.dwFilterTag;
262 paftda->dwFilterTagIndex = aftdw.dwFilterTagIndex;
263 paftda->cbFilterSize = aftdw.cbFilterSize;
264 paftda->fdwSupport = aftdw.fdwSupport;
265 paftda->cStandardFilters = aftdw.cStandardFilters;
266 lstrcpyWtoA(paftda->szFilterTag, aftdw.szFilterTag);
271 /***********************************************************************
272 * acmFilterTagDetailsW (MSACM32.20)
274 MMRESULT WINAPI acmFilterTagDetailsW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
277 PWINE_ACMDRIVERID padid;
280 TRACE("(0x%08x, %p, %ld)\n", had, paftd, fdwDetails);
282 if (fdwDetails & ~(ACM_FILTERTAGDETAILSF_FILTERTAG|ACM_FILTERTAGDETAILSF_INDEX|
283 ACM_FILTERTAGDETAILSF_LARGESTSIZE))
284 return MMSYSERR_INVALFLAG;
286 switch (fdwDetails) {
287 case ACM_FILTERTAGDETAILSF_FILTERTAG:
288 if (had == (HACMDRIVER)NULL) {
289 mmr = ACMERR_NOTPOSSIBLE;
290 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
291 /* should check for codec only */
292 if (padid->bEnabled && acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
293 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
294 (LPARAM)paftd, (LPARAM)fdwDetails);
295 acmDriverClose(had, 0);
296 if (mmr == MMSYSERR_NOERROR) break;
300 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
301 (LPARAM)paftd, (LPARAM)fdwDetails);
305 case ACM_FILTERTAGDETAILSF_INDEX:
306 /* FIXME should check paftd->dwFilterTagIndex < add.cFilterTags */
307 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
308 (LPARAM)paftd, (LPARAM)fdwDetails);
311 case ACM_FILTERTAGDETAILSF_LARGESTSIZE:
312 if (had == (HACMDRIVER)NULL) {
313 ACMFILTERTAGDETAILSW tmp;
314 DWORD ft = paftd->dwFilterTag;
316 mmr = ACMERR_NOTPOSSIBLE;
317 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
318 /* should check for codec only */
319 if (padid->bEnabled &&
320 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
322 memset(&tmp, 0, sizeof(tmp));
323 tmp.cbStruct = sizeof(tmp);
324 tmp.dwFilterTag = ft;
326 if (MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
328 (LPARAM)fdwDetails) == MMSYSERR_NOERROR) {
329 if (mmr == ACMERR_NOTPOSSIBLE ||
330 paftd->cbFilterSize < tmp.cbFilterSize) {
332 mmr = MMSYSERR_NOERROR;
335 acmDriverClose(had, 0);
339 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
340 (LPARAM)paftd, (LPARAM)fdwDetails);
345 WARN("Unsupported fdwDetails=%08lx\n", fdwDetails);
346 mmr = MMSYSERR_ERROR;
349 if (mmr == MMSYSERR_NOERROR &&
350 paftd->dwFilterTag == WAVE_FORMAT_PCM && paftd->szFilterTag[0] == 0)
351 lstrcpyAtoW(paftd->szFilterTag, "PCM");
356 struct MSACM_FilterTagEnumWtoA_Instance {
357 PACMFILTERTAGDETAILSA paftda;
359 ACMFILTERTAGENUMCBA fnCallback;
362 static BOOL CALLBACK MSACM_FilterTagEnumCallbackWtoA(HACMDRIVERID hadid,
363 PACMFILTERTAGDETAILSW paftdw,
367 struct MSACM_FilterTagEnumWtoA_Instance* paftei;
369 paftei = (struct MSACM_FilterTagEnumWtoA_Instance*)dwInstance;
371 paftei->paftda->dwFilterTagIndex = paftdw->dwFilterTagIndex;
372 paftei->paftda->dwFilterTag = paftdw->dwFilterTag;
373 paftei->paftda->cbFilterSize = paftdw->cbFilterSize;
374 paftei->paftda->fdwSupport = paftdw->fdwSupport;
375 paftei->paftda->cStandardFilters = paftdw->cStandardFilters;
376 lstrcpyWtoA(paftei->paftda->szFilterTag, paftdw->szFilterTag);
378 return (paftei->fnCallback)(hadid, paftei->paftda,
379 paftei->dwInstance, fdwSupport);
382 /***********************************************************************
383 * acmFilterTagEnumA (MSACM32.21)
385 MMRESULT WINAPI acmFilterTagEnumA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
386 ACMFILTERTAGENUMCBA fnCallback, DWORD dwInstance,
389 ACMFILTERTAGDETAILSW aftdw;
390 struct MSACM_FilterTagEnumWtoA_Instance aftei;
392 memset(&aftdw, 0, sizeof(aftdw));
393 aftdw.cbStruct = sizeof(aftdw);
394 aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
395 aftdw.dwFilterTag = paftda->dwFilterTag;
397 aftei.paftda = paftda;
398 aftei.dwInstance = dwInstance;
399 aftei.fnCallback = fnCallback;
401 return acmFilterTagEnumW(had, &aftdw, MSACM_FilterTagEnumCallbackWtoA,
402 (DWORD)&aftei, fdwEnum);
405 /***********************************************************************
406 * acmFilterTagEnumW (MSACM32.22)
408 MMRESULT WINAPI acmFilterTagEnumW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
409 ACMFILTERTAGENUMCBW fnCallback, DWORD dwInstance,
412 PWINE_ACMDRIVERID padid;
413 ACMDRIVERDETAILSW add;
416 TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
417 had, paftd, fnCallback, dwInstance, fdwEnum);
419 if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM;
421 if (had) FIXME("had != NULL, not supported\n");
423 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
424 /* should check for codec only */
425 if (padid->bEnabled && acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) {
426 add.cbStruct = sizeof(add);
428 if (acmDriverDetailsW((HACMDRIVERID)padid, &add, 0) == MMSYSERR_NOERROR) {
429 for (i = 0; i < add.cFilterTags; i++) {
430 paftd->dwFilterTagIndex = i;
431 if (acmFilterTagDetailsW(had, paftd, ACM_FILTERTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
432 if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance,
441 acmDriverClose(had, 0);
443 return MMSYSERR_NOERROR;