* Sync up to trunk head (r65147).
[reactos.git] / dll / win32 / msacm32 / filter.c
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
2
3 /*
4 * MSACM32 library
5 *
6 * Copyright 1998 Patrik Stridvall
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23 #include "wineacm.h"
24
25 /***********************************************************************
26 * acmFilterChooseA (MSACM32.@)
27 */
28 MMRESULT WINAPI acmFilterChooseA(PACMFILTERCHOOSEA pafltrc)
29 {
30 FIXME("(%p): stub\n", pafltrc);
31 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
32 return MMSYSERR_ERROR;
33 }
34
35 /***********************************************************************
36 * acmFilterChooseW (MSACM32.@)
37 */
38 MMRESULT WINAPI acmFilterChooseW(PACMFILTERCHOOSEW pafltrc)
39 {
40 FIXME("(%p): stub\n", pafltrc);
41 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
42 return MMSYSERR_ERROR;
43 }
44
45 /***********************************************************************
46 * acmFilterDetailsA (MSACM32.@)
47 */
48 MMRESULT WINAPI acmFilterDetailsA(HACMDRIVER had, PACMFILTERDETAILSA pafd,
49 DWORD fdwDetails)
50 {
51 ACMFILTERDETAILSW afdw;
52 MMRESULT mmr;
53
54 memset(&afdw, 0, sizeof(afdw));
55 afdw.cbStruct = sizeof(afdw);
56 afdw.dwFilterIndex = pafd->dwFilterIndex;
57 afdw.dwFilterTag = pafd->dwFilterTag;
58 afdw.pwfltr = pafd->pwfltr;
59 afdw.cbwfltr = pafd->cbwfltr;
60
61 mmr = acmFilterDetailsW(had, &afdw, fdwDetails);
62 if (mmr == MMSYSERR_NOERROR) {
63 pafd->dwFilterTag = afdw.dwFilterTag;
64 pafd->fdwSupport = afdw.fdwSupport;
65 WideCharToMultiByte( CP_ACP, 0, afdw.szFilter, -1, pafd->szFilter,
66 sizeof(pafd->szFilter), NULL, NULL );
67 }
68 return mmr;
69 }
70
71 /***********************************************************************
72 * acmFilterDetailsW (MSACM32.@)
73 */
74 MMRESULT WINAPI acmFilterDetailsW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
75 DWORD fdwDetails)
76 {
77 MMRESULT mmr;
78 ACMFILTERTAGDETAILSA aftd;
79
80 TRACE("(%p, %p, %d)\n", had, pafd, fdwDetails);
81
82 memset(&aftd, 0, sizeof(aftd));
83 aftd.cbStruct = sizeof(aftd);
84
85 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
86
87 switch (fdwDetails) {
88 case ACM_FILTERDETAILSF_FILTER:
89 if (pafd->dwFilterTag != pafd->pwfltr->dwFilterTag) {
90 mmr = MMSYSERR_INVALPARAM;
91 break;
92 }
93 if (had == NULL) {
94 PWINE_ACMDRIVERID padid;
95
96 mmr = ACMERR_NOTPOSSIBLE;
97 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
98 /* should check for codec only */
99 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
100 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
101 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
102 (LPARAM)pafd, (LPARAM)fdwDetails);
103 acmDriverClose(had, 0);
104 if (mmr == MMSYSERR_NOERROR) break;
105 }
106 }
107 } else {
108 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, (LPARAM)pafd, fdwDetails);
109 }
110 break;
111 case ACM_FILTERDETAILSF_INDEX:
112 /* should check pafd->dwFilterIndex < aftd->cStandardFilters */
113 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, (LPARAM)pafd, fdwDetails);
114 break;
115 default:
116 WARN("Unknown fdwDetails %08x\n", fdwDetails);
117 mmr = MMSYSERR_INVALFLAG;
118 break;
119 }
120
121 TRACE("=> %d\n", mmr);
122 return mmr;
123 }
124
125 struct MSACM_FilterEnumWtoA_Instance {
126 PACMFILTERDETAILSA pafda;
127 DWORD_PTR dwInstance;
128 ACMFILTERENUMCBA fnCallback;
129 };
130
131 static BOOL CALLBACK MSACM_FilterEnumCallbackWtoA(HACMDRIVERID hadid,
132 PACMFILTERDETAILSW pafdw,
133 DWORD_PTR dwInstance,
134 DWORD fdwSupport)
135 {
136 struct MSACM_FilterEnumWtoA_Instance* pafei;
137
138 pafei = (struct MSACM_FilterEnumWtoA_Instance*)dwInstance;
139
140 pafei->pafda->dwFilterIndex = pafdw->dwFilterIndex;
141 pafei->pafda->dwFilterTag = pafdw->dwFilterTag;
142 pafei->pafda->fdwSupport = pafdw->fdwSupport;
143 WideCharToMultiByte( CP_ACP, 0, pafdw->szFilter, -1, pafei->pafda->szFilter,
144 sizeof(pafei->pafda->szFilter), NULL, NULL );
145
146 return (pafei->fnCallback)(hadid, pafei->pafda,
147 pafei->dwInstance, fdwSupport);
148 }
149
150 /***********************************************************************
151 * acmFilterEnumA (MSACM32.@)
152 */
153 MMRESULT WINAPI acmFilterEnumA(HACMDRIVER had, PACMFILTERDETAILSA pafda,
154 ACMFILTERENUMCBA fnCallback,
155 DWORD_PTR dwInstance, DWORD fdwEnum)
156 {
157 ACMFILTERDETAILSW afdw;
158 struct MSACM_FilterEnumWtoA_Instance afei;
159
160 memset(&afdw, 0, sizeof(afdw));
161 afdw.cbStruct = sizeof(afdw);
162 afdw.dwFilterIndex = pafda->dwFilterIndex;
163 afdw.dwFilterTag = pafda->dwFilterTag;
164 afdw.pwfltr = pafda->pwfltr;
165 afdw.cbwfltr = pafda->cbwfltr;
166
167 afei.pafda = pafda;
168 afei.dwInstance = dwInstance;
169 afei.fnCallback = fnCallback;
170
171 return acmFilterEnumW(had, &afdw, MSACM_FilterEnumCallbackWtoA,
172 (DWORD_PTR)&afei, fdwEnum);
173 }
174
175 static BOOL MSACM_FilterEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had,
176 PACMFILTERDETAILSW pafd,
177 ACMFILTERENUMCBW fnCallback,
178 DWORD_PTR dwInstance, DWORD fdwEnum)
179 {
180 ACMFILTERTAGDETAILSW aftd;
181 unsigned int i, j;
182
183 for (i = 0; i < padid->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)
188 continue;
189
190 if ((fdwEnum & ACM_FILTERENUMF_DWFILTERTAG) &&
191 aftd.dwFilterTag != pafd->pwfltr->dwFilterTag)
192 continue;
193
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)
198 continue;
199
200 if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, padid->fdwSupport))
201 return FALSE;
202 }
203 }
204 return TRUE;
205 }
206
207 /***********************************************************************
208 * acmFilterEnumW (MSACM32.@)
209 */
210 MMRESULT WINAPI acmFilterEnumW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
211 ACMFILTERENUMCBW fnCallback,
212 DWORD_PTR dwInstance, DWORD fdwEnum)
213 {
214 PWINE_ACMDRIVERID padid;
215 BOOL ret;
216
217 TRACE("(%p, %p, %p, %ld, %d)\n",
218 had, pafd, fnCallback, dwInstance, fdwEnum);
219
220 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
221
222 if (fdwEnum & ~(ACM_FILTERENUMF_DWFILTERTAG))
223 FIXME("Unsupported fdwEnum values\n");
224
225 if (had) {
226 HACMDRIVERID hadid;
227
228 if (acmDriverID((HACMOBJ)had, &hadid, 0) != MMSYSERR_NOERROR)
229 return MMSYSERR_INVALHANDLE;
230 MSACM_FilterEnumHelper(MSACM_GetDriverID(hadid), had, pafd,
231 fnCallback, dwInstance, fdwEnum);
232 return MMSYSERR_NOERROR;
233 }
234 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
235 /* should check for codec only */
236 if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) ||
237 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
238 continue;
239 ret = MSACM_FilterEnumHelper(padid, had, pafd,
240 fnCallback, dwInstance, fdwEnum);
241 acmDriverClose(had, 0);
242 if (!ret) break;
243 }
244 return MMSYSERR_NOERROR;
245 }
246
247 /***********************************************************************
248 * acmFilterTagDetailsA (MSACM32.@)
249 */
250 MMRESULT WINAPI acmFilterTagDetailsA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
251 DWORD fdwDetails)
252 {
253 ACMFILTERTAGDETAILSW aftdw;
254 MMRESULT mmr;
255
256 memset(&aftdw, 0, sizeof(aftdw));
257 aftdw.cbStruct = sizeof(aftdw);
258 aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
259 aftdw.dwFilterTag = paftda->dwFilterTag;
260
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 );
270 }
271 return mmr;
272 }
273
274 /***********************************************************************
275 * acmFilterTagDetailsW (MSACM32.@)
276 */
277 MMRESULT WINAPI acmFilterTagDetailsW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
278 DWORD fdwDetails)
279 {
280 PWINE_ACMDRIVERID padid;
281 MMRESULT mmr;
282
283 TRACE("(%p, %p, %d)\n", had, paftd, fdwDetails);
284
285 if (fdwDetails & ~(ACM_FILTERTAGDETAILSF_FILTERTAG|ACM_FILTERTAGDETAILSF_INDEX|
286 ACM_FILTERTAGDETAILSF_LARGESTSIZE))
287 return MMSYSERR_INVALFLAG;
288
289 switch (fdwDetails) {
290 case ACM_FILTERTAGDETAILSF_FILTERTAG:
291 if (had == NULL) {
292 mmr = ACMERR_NOTPOSSIBLE;
293 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
294 /* should check for codec only */
295 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
296 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
297 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
298 acmDriverClose(had, 0);
299 if (mmr == MMSYSERR_NOERROR) break;
300 }
301 }
302 } else {
303 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
304 }
305 break;
306
307 case ACM_FILTERTAGDETAILSF_INDEX:
308 /* FIXME should check paftd->dwFilterTagIndex < add.cFilterTags */
309 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
310 break;
311
312 case ACM_FILTERTAGDETAILSF_LARGESTSIZE:
313 if (had == NULL) {
314 ACMFILTERTAGDETAILSW tmp;
315 DWORD ft = paftd->dwFilterTag;
316
317 mmr = ACMERR_NOTPOSSIBLE;
318 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
319 /* should check for codec only */
320 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
321 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
322
323 memset(&tmp, 0, sizeof(tmp));
324 tmp.cbStruct = sizeof(tmp);
325 tmp.dwFilterTag = ft;
326
327 if (MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
328 (LPARAM)&tmp, fdwDetails) == MMSYSERR_NOERROR) {
329 if (mmr == ACMERR_NOTPOSSIBLE ||
330 paftd->cbFilterSize < tmp.cbFilterSize) {
331 *paftd = tmp;
332 mmr = MMSYSERR_NOERROR;
333 }
334 }
335 acmDriverClose(had, 0);
336 }
337 }
338 } else {
339 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
340 }
341 break;
342
343 default:
344 WARN("Unsupported fdwDetails=%08x\n", fdwDetails);
345 mmr = MMSYSERR_ERROR;
346 }
347
348 if (mmr == MMSYSERR_NOERROR &&
349 paftd->dwFilterTag == WAVE_FORMAT_PCM && paftd->szFilterTag[0] == 0)
350 MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFilterTag,
351 sizeof(paftd->szFilterTag)/sizeof(WCHAR) );
352
353 return mmr;
354 }
355
356 struct MSACM_FilterTagEnumWtoA_Instance {
357 PACMFILTERTAGDETAILSA paftda;
358 DWORD_PTR dwInstance;
359 ACMFILTERTAGENUMCBA fnCallback;
360 };
361
362 static BOOL CALLBACK MSACM_FilterTagEnumCallbackWtoA(HACMDRIVERID hadid,
363 PACMFILTERTAGDETAILSW paftdw,
364 DWORD_PTR dwInstance,
365 DWORD fdwSupport)
366 {
367 struct MSACM_FilterTagEnumWtoA_Instance* paftei;
368
369 paftei = (struct MSACM_FilterTagEnumWtoA_Instance*)dwInstance;
370
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 WideCharToMultiByte( CP_ACP, 0, paftdw->szFilterTag, -1, paftei->paftda->szFilterTag,
377 sizeof(paftei->paftda->szFilterTag), NULL, NULL );
378
379 return (paftei->fnCallback)(hadid, paftei->paftda,
380 paftei->dwInstance, fdwSupport);
381 }
382
383 /***********************************************************************
384 * acmFilterTagEnumA (MSACM32.@)
385 */
386 MMRESULT WINAPI acmFilterTagEnumA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
387 ACMFILTERTAGENUMCBA fnCallback,
388 DWORD_PTR dwInstance, DWORD fdwEnum)
389 {
390 ACMFILTERTAGDETAILSW aftdw;
391 struct MSACM_FilterTagEnumWtoA_Instance aftei;
392
393 memset(&aftdw, 0, sizeof(aftdw));
394 aftdw.cbStruct = sizeof(aftdw);
395 aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
396 aftdw.dwFilterTag = paftda->dwFilterTag;
397
398 aftei.paftda = paftda;
399 aftei.dwInstance = dwInstance;
400 aftei.fnCallback = fnCallback;
401
402 return acmFilterTagEnumW(had, &aftdw, MSACM_FilterTagEnumCallbackWtoA,
403 (DWORD_PTR)&aftei, fdwEnum);
404 }
405
406 /***********************************************************************
407 * acmFilterTagEnumW (MSACM32.@)
408 */
409 MMRESULT WINAPI acmFilterTagEnumW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
410 ACMFILTERTAGENUMCBW fnCallback,
411 DWORD_PTR dwInstance, DWORD fdwEnum)
412 {
413 PWINE_ACMDRIVERID padid;
414 unsigned int i;
415
416 TRACE("(%p, %p, %p, %ld, %d)\n",
417 had, paftd, fnCallback, dwInstance, fdwEnum);
418
419 if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM;
420
421 if (had) FIXME("had != NULL, not supported\n");
422
423 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
424 /* should check for codec only */
425 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
426 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) {
427
428 for (i = 0; i < padid->cFilterTags; i++) {
429 paftd->dwFilterTagIndex = i;
430 if (acmFilterTagDetailsW(had, paftd, ACM_FILTERTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
431 if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) {
432 padid = NULL;
433 break;
434 }
435 }
436 }
437 acmDriverClose(had, 0);
438 }
439 }
440 return MMSYSERR_NOERROR;
441 }