mixer: support native audio driver mute
[mplayer.git] / loader / afl.c
blobb29471cdce103b5352806698f176223083240649
1 /**************************************************************************
4 This file will contain an interface to ACM drivers.
5 Its content will be based mainly on wine/dlls/msacm32
6 actually, for audio decompression only the following functions
7 are needed:
9 acmStreamOpen ( takes formats of src and dest, returns stream handle )
10 acmStreamPrepareHeader ( takes stream handler and info on data )
11 acmStreamConvert ( the same as PrepareHeader )
12 acmStreamUnprepareHeader
13 acmStreamClose
14 acmStreamSize
15 maybe acmStreamReset
17 In future I'll also add functions for format enumeration,
18 but not right now.
20 Modified for use with MPlayer, detailed changelog at
21 http://svn.mplayerhq.hu/mplayer/trunk/
23 ***************************************************************************/
24 #include "config.h"
25 #include "debug.h"
27 #include "wine/winbase.h"
28 #include "wine/windef.h"
29 #include "wine/winuser.h"
30 #include "wine/vfw.h"
31 #include "wine/winestring.h"
32 #include "wine/driver.h"
33 #include "wine/winerror.h"
34 #include "wine/msacm.h"
35 #include "wine/msacmdrv.h"
36 #include "wineacm.h"
37 #ifndef __MINGW32__
38 #include "ext.h"
39 #endif
40 #include "drv.h"
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #pragma pack(1)
46 #define OpenDriverA DrvOpen
47 #define CloseDriver DrvClose
49 static inline PWINE_ACMSTREAM ACM_GetStream(HACMSTREAM has)
51 return (PWINE_ACMSTREAM)has;
54 /***********************************************************************
55 * acmDriverAddA (MSACM32.2)
57 MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule,
58 LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
60 if (!phadid)
61 return MMSYSERR_INVALPARAM;
63 /* Check if any unknown flags */
64 if (fdwAdd &
65 ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND|
66 ACM_DRIVERADDF_GLOBAL))
67 return MMSYSERR_INVALFLAG;
69 /* Check if any incompatible flags */
70 if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) &&
71 (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND))
72 return MMSYSERR_INVALFLAG;
74 /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a
75 * LoadDriver on it, to be sure we can call SendDriverMessage on the
76 * hDrvr handle.
78 *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, 0, hinstModule);
80 /* FIXME: lParam, dwPriority and fdwAdd ignored */
82 return MMSYSERR_NOERROR;
85 /***********************************************************************
86 * acmDriverClose (MSACM32.4)
88 MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
90 PWINE_ACMDRIVER p;
91 PWINE_ACMDRIVER* tp;
93 if (fdwClose)
94 return MMSYSERR_INVALFLAG;
96 p = MSACM_GetDriver(had);
97 if (!p)
98 return MMSYSERR_INVALHANDLE;
100 for (tp = &(p->obj.pACMDriverID->pACMDriverList); *tp; *tp = (*tp)->pNextACMDriver) {
101 if (*tp == p) {
102 *tp = (*tp)->pNextACMDriver;
103 break;
107 if (p->hDrvr && !p->obj.pACMDriverID->pACMDriverList)
108 CloseDriver(p->hDrvr);
110 HeapFree(MSACM_hHeap, 0, p);
112 return MMSYSERR_NOERROR;
115 /***********************************************************************
116 * acmDriverEnum (MSACM32.7)
118 MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)
120 PWINE_ACMDRIVERID p;
121 DWORD fdwSupport;
123 if (!fnCallback) {
124 return MMSYSERR_INVALPARAM;
127 if (fdwEnum && ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED)) {
128 return MMSYSERR_INVALFLAG;
131 for (p = MSACM_pFirstACMDriverID; p; p = p->pNextACMDriverID) {
132 fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
133 if (!p->bEnabled) {
134 if (fdwEnum & ACM_DRIVERENUMF_DISABLED)
135 fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
136 else
137 continue;
139 (*fnCallback)((HACMDRIVERID) p, dwInstance, fdwSupport);
142 return MMSYSERR_NOERROR;
145 /***********************************************************************
146 * acmDriverID (MSACM32.8)
148 MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID)
150 PWINE_ACMOBJ pao;
152 pao = MSACM_GetObj(hao);
153 if (!pao)
154 return MMSYSERR_INVALHANDLE;
156 if (!phadid)
157 return MMSYSERR_INVALPARAM;
159 if (fdwDriverID)
160 return MMSYSERR_INVALFLAG;
162 *phadid = (HACMDRIVERID) pao->pACMDriverID;
164 return MMSYSERR_NOERROR;
167 /***********************************************************************
168 * acmDriverMessage (MSACM32.9)
169 * FIXME
170 * Not implemented
172 LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
174 PWINE_ACMDRIVER pad = MSACM_GetDriver(had);
175 if (!pad)
176 return MMSYSERR_INVALPARAM;
178 /* FIXME: Check if uMsg legal */
180 if (!SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2))
181 return MMSYSERR_NOTSUPPORTED;
183 return MMSYSERR_NOERROR;
187 /***********************************************************************
188 * acmDriverOpen (MSACM32.10)
190 MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
192 PWINE_ACMDRIVERID padid;
193 PWINE_ACMDRIVER pad;
194 ICOPEN icopen;
197 TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen);
199 if (!phad)
200 return MMSYSERR_INVALPARAM;
202 padid = MSACM_GetDriverID(hadid);
203 if (!padid)
204 return MMSYSERR_INVALHANDLE;
206 if (fdwOpen)
207 return MMSYSERR_INVALFLAG;
209 pad = (PWINE_ACMDRIVER) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
210 if (!pad)
211 return MMSYSERR_NOMEM;
213 pad->obj.pACMDriverID = padid;
214 icopen.fccType = mmioFOURCC('a', 'u', 'd', 'c');
215 icopen.fccHandler = (long)padid->pszFileName;
216 icopen.dwSize = sizeof(ICOPEN);
217 icopen.dwFlags = 0;
219 icopen.pV1Reserved = padid->pszFileName;
220 if (!padid->hInstModule)
221 pad->hDrvr = OpenDriverA((long)&icopen);
222 else
223 pad->hDrvr = padid->hInstModule;
225 if (!pad->hDrvr) {
226 HeapFree(MSACM_hHeap, 0, pad);
227 return MMSYSERR_ERROR;
230 pad->pfnDriverProc = (DRIVERPROC)GetProcAddress(pad->hDrvr, "DriverProc");
232 /* insert new pad at beg of list */
233 pad->pNextACMDriver = padid->pACMDriverList;
234 padid->pACMDriverList = pad;
236 /* FIXME: Create a WINE_ACMDRIVER32 */
237 *phad = (HACMDRIVER)pad;
239 return MMSYSERR_NOERROR;
242 /***********************************************************************
243 * acmDriverRemove (MSACM32.12)
245 MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
247 PWINE_ACMDRIVERID padid;
249 padid = MSACM_GetDriverID(hadid);
250 if (!padid)
251 return MMSYSERR_INVALHANDLE;
253 if (fdwRemove)
254 return MMSYSERR_INVALFLAG;
256 MSACM_UnregisterDriver(padid);
258 return MMSYSERR_NOERROR;
263 /**********************************************************************/
265 HANDLE MSACM_hHeap = (HANDLE) NULL;
266 PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL;
267 PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL;
269 /***********************************************************************
270 * MSACM_RegisterDriver32()
272 PWINE_ACMDRIVERID MSACM_RegisterDriver(const char* pszFileName,
273 WORD wFormatTag,
274 HINSTANCE hinstModule)
276 PWINE_ACMDRIVERID padid;
278 TRACE("('%s', '%x', 0x%08x)\n", pszFileName, wFormatTag, hinstModule);
280 #ifndef WIN32_LOADER
281 MSACM_hHeap = GetProcessHeap();
282 #endif
283 padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID));
284 padid->pszFileName = malloc(strlen(pszFileName)+1);
285 strcpy(padid->pszFileName, pszFileName);
286 // 1~strdup(pszDriverAlias);
287 padid->wFormatTag = wFormatTag;
288 padid->hInstModule = hinstModule;
289 padid->bEnabled = TRUE;
290 padid->pACMDriverList = NULL;
291 padid->pNextACMDriverID = NULL;
292 padid->pPrevACMDriverID = MSACM_pLastACMDriverID;
293 if (MSACM_pLastACMDriverID)
294 MSACM_pLastACMDriverID->pNextACMDriverID = padid;
295 MSACM_pLastACMDriverID = padid;
296 if (!MSACM_pFirstACMDriverID)
297 MSACM_pFirstACMDriverID = padid;
299 return padid;
303 /***********************************************************************
304 * MSACM_UnregisterDriver32()
306 PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p)
308 PWINE_ACMDRIVERID pNextACMDriverID;
310 while (p->pACMDriverList)
311 acmDriverClose((HACMDRIVER) p->pACMDriverList, 0);
313 free(p->pszFileName);
315 if (p == MSACM_pFirstACMDriverID)
316 MSACM_pFirstACMDriverID = p->pNextACMDriverID;
317 if (p == MSACM_pLastACMDriverID)
318 MSACM_pLastACMDriverID = p->pPrevACMDriverID;
320 if (p->pPrevACMDriverID)
321 p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
322 if (p->pNextACMDriverID)
323 p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID;
325 pNextACMDriverID = p->pNextACMDriverID;
327 HeapFree(MSACM_hHeap, 0, p);
329 return pNextACMDriverID;
332 /***********************************************************************
333 * MSACM_UnregisterAllDrivers32()
334 * FIXME
335 * Where should this function be called?
337 void MSACM_UnregisterAllDrivers(void)
339 PWINE_ACMDRIVERID p;
341 for (p = MSACM_pFirstACMDriverID; p; p = MSACM_UnregisterDriver(p));
344 /***********************************************************************
345 * MSACM_GetDriverID32()
347 PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID)
349 return (PWINE_ACMDRIVERID)hDriverID;
352 /***********************************************************************
353 * MSACM_GetDriver32()
355 PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver)
357 return (PWINE_ACMDRIVER)hDriver;
360 /***********************************************************************
361 * MSACM_GetObj32()
363 PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj)
365 return (PWINE_ACMOBJ)hObj;
370 /***********************************************************************
371 * acmStreamOpen (MSACM32.40)
373 MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
374 PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback,
375 DWORD dwInstance, DWORD fdwOpen)
377 PWINE_ACMSTREAM was;
378 PWINE_ACMDRIVER wad;
379 MMRESULT ret;
380 int wfxSrcSize;
381 int wfxDstSize;
383 TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
384 phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen);
386 TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
387 pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec,
388 pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize);
390 TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
391 pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec,
392 pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize);
394 #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
395 wfxSrcSize = SIZEOF_WFX(pwfxSrc);
396 wfxDstSize = SIZEOF_WFX(pwfxDst);
397 #undef SIZEOF_WFX
399 was = (PWINE_ACMSTREAM) HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize + ((pwfltr) ? sizeof(WAVEFILTER) : 0));
400 if (was == NULL)
401 return MMSYSERR_NOMEM;
402 was->drvInst.cbStruct = sizeof(was->drvInst);
403 was->drvInst.pwfxSrc = (PWAVEFORMATEX)(was + 1);
404 memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize);
405 // LHACM is checking for 0x1
406 // but if this will not help
407 // was->drvInst.pwfxSrc->wFormatTag = 1;
408 was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)(was + 1) + wfxSrcSize);
409 memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize);
410 if (pwfltr) {
411 was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)(was + 1) + wfxSrcSize + wfxDstSize);
412 memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER));
413 } else {
414 was->drvInst.pwfltr = NULL;
416 was->drvInst.dwCallback = dwCallback;
417 was->drvInst.dwInstance = dwInstance;
418 was->drvInst.fdwOpen = fdwOpen;
419 was->drvInst.fdwDriver = 0L;
420 was->drvInst.dwDriver = 0L;
421 was->drvInst.has = (HACMSTREAM)was;
423 if (had) {
424 if (!(wad = MSACM_GetDriver(had))) {
425 ret = MMSYSERR_INVALPARAM;
426 goto errCleanUp;
429 was->obj.pACMDriverID = wad->obj.pACMDriverID;
430 was->pDrv = wad;
431 was->hAcmDriver = 0; /* not to close it in acmStreamClose */
433 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
434 if (ret != MMSYSERR_NOERROR)
435 goto errCleanUp;
436 } else {
437 PWINE_ACMDRIVERID wadi;
438 //short drv_tag;
439 ret = ACMERR_NOTPOSSIBLE;
440 /* if(pwfxSrc->wFormatTag==1)//compression
441 drv_tag=pwfxDst->wFormatTag;
442 else
443 if(pwfxDst->wFormatTag==1)//decompression
444 drv_tag=pwfxSrc->wFormatTag;
445 else
446 goto errCleanUp;
448 ret=acmDriverOpen2(drv_tag);
449 if (ret == MMSYSERR_NOERROR) {
450 if ((wad = MSACM_GetDriver(had)) != 0) {
451 was->obj.pACMDriverID = wad->obj.pACMDriverID;
452 was->pDrv = wad;
453 was->hAcmDriver = had;
455 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
456 if (ret == MMSYSERR_NOERROR) {
457 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
458 acmDriverClose(had, 0L);
460 break;
463 acmDriverClose(had, 0L);*/
464 //if(MSACM_pFirstACMDriverID==NULL)
465 // MSACM_RegisterAllDrivers();
467 for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID)
469 /* Check Format */
470 if ((int)wadi->wFormatTag != (int)pwfxSrc->wFormatTag) continue;
472 ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L);
473 if (ret == MMSYSERR_NOERROR) {
474 if ((wad = MSACM_GetDriver(had)) != 0) {
475 was->obj.pACMDriverID = wad->obj.pACMDriverID;
476 was->pDrv = wad;
477 was->hAcmDriver = had;
479 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
480 //lhacm - crash printf("RETOPEN %d\n", ret);
481 //ret = 0;
482 if (ret == MMSYSERR_NOERROR) {
483 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
484 acmDriverClose(had, 0L);
486 break;
489 // no match, close this acm driver and try next one
490 acmDriverClose(had, 0L);
493 if (ret != MMSYSERR_NOERROR) {
494 ret = ACMERR_NOTPOSSIBLE;
495 goto errCleanUp;
498 ret = MMSYSERR_NOERROR;
499 if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) {
500 if (phas)
501 *phas = (HACMSTREAM)was;
502 TRACE("=> (%d)\n", ret);
503 #ifdef WIN32_LOADER
504 CodecAlloc();
505 #endif
506 return ret;
508 errCleanUp:
509 if (phas)
510 *phas = (HACMSTREAM)0;
511 HeapFree(MSACM_hHeap, 0, was);
512 TRACE("=> (%d)\n", ret);
513 return ret;
517 MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose)
519 PWINE_ACMSTREAM was;
520 MMRESULT ret;
522 TRACE("(0x%08x, %ld)\n", has, fdwClose);
524 if ((was = ACM_GetStream(has)) == NULL) {
525 return MMSYSERR_INVALHANDLE;
527 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0);
528 if (ret == MMSYSERR_NOERROR) {
529 if (was->hAcmDriver)
530 acmDriverClose(was->hAcmDriver, 0L);
531 HeapFree(MSACM_hHeap, 0, was);
532 #ifdef WIN32_LOADER
533 CodecRelease();
534 #endif
536 TRACE("=> (%d)\n", ret);
537 return ret;
540 /***********************************************************************
541 * acmStreamConvert (MSACM32.38)
543 MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash,
544 DWORD fdwConvert)
546 PWINE_ACMSTREAM was;
547 MMRESULT ret = MMSYSERR_NOERROR;
548 PACMDRVSTREAMHEADER padsh;
550 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwConvert);
552 if ((was = ACM_GetStream(has)) == NULL)
553 return MMSYSERR_INVALHANDLE;
554 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
555 return MMSYSERR_INVALPARAM;
557 if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
558 return ACMERR_UNPREPARED;
560 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
561 * size. some fields are private to msacm internals, and are exposed
562 * in ACMSTREAMHEADER in the dwReservedDriver array
564 padsh = (PACMDRVSTREAMHEADER)pash;
566 /* check that pointers have not been modified */
567 if (padsh->pbPreparedSrc != padsh->pbSrc ||
568 padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
569 padsh->pbPreparedDst != padsh->pbDst ||
570 padsh->cbPreparedDstLength < padsh->cbDstLength) {
571 return MMSYSERR_INVALPARAM;
574 padsh->fdwConvert = fdwConvert;
576 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CONVERT, (DWORD)&was->drvInst, (DWORD)padsh);
577 if (ret == MMSYSERR_NOERROR) {
578 padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_DONE;
580 TRACE("=> (%d)\n", ret);
581 return ret;
585 /***********************************************************************
586 * acmStreamPrepareHeader (MSACM32.41)
588 MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
589 DWORD fdwPrepare)
591 PWINE_ACMSTREAM was;
592 MMRESULT ret = MMSYSERR_NOERROR;
593 PACMDRVSTREAMHEADER padsh;
595 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwPrepare);
597 if ((was = ACM_GetStream(has)) == NULL)
598 return MMSYSERR_INVALHANDLE;
599 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
600 return MMSYSERR_INVALPARAM;
601 if (fdwPrepare)
602 ret = MMSYSERR_INVALFLAG;
604 if (pash->fdwStatus & ACMSTREAMHEADER_STATUSF_DONE)
605 return MMSYSERR_NOERROR;
607 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
608 * size. some fields are private to msacm internals, and are exposed
609 * in ACMSTREAMHEADER in the dwReservedDriver array
611 padsh = (PACMDRVSTREAMHEADER)pash;
613 padsh->fdwConvert = fdwPrepare;
614 padsh->padshNext = NULL;
615 padsh->fdwDriver = padsh->dwDriver = 0L;
617 padsh->fdwPrepared = 0;
618 padsh->dwPrepared = 0;
619 padsh->pbPreparedSrc = 0;
620 padsh->cbPreparedSrcLength = 0;
621 padsh->pbPreparedDst = 0;
622 padsh->cbPreparedDstLength = 0;
624 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_PREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
625 if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
626 ret = MMSYSERR_NOERROR;
627 padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE);
628 padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_PREPARED;
629 padsh->fdwPrepared = padsh->fdwStatus;
630 padsh->dwPrepared = 0;
631 padsh->pbPreparedSrc = padsh->pbSrc;
632 padsh->cbPreparedSrcLength = padsh->cbSrcLength;
633 padsh->pbPreparedDst = padsh->pbDst;
634 padsh->cbPreparedDstLength = padsh->cbDstLength;
635 } else {
636 padsh->fdwPrepared = 0;
637 padsh->dwPrepared = 0;
638 padsh->pbPreparedSrc = 0;
639 padsh->cbPreparedSrcLength = 0;
640 padsh->pbPreparedDst = 0;
641 padsh->cbPreparedDstLength = 0;
643 TRACE("=> (%d)\n", ret);
644 return ret;
647 /***********************************************************************
648 * acmStreamReset (MSACM32.42)
650 MMRESULT WINAPI acmStreamReset(HACMSTREAM has, DWORD fdwReset)
652 PWINE_ACMSTREAM was;
653 MMRESULT ret = MMSYSERR_NOERROR;
655 TRACE("(0x%08x, %ld)\n", has, fdwReset);
657 if (fdwReset) {
658 ret = MMSYSERR_INVALFLAG;
659 } else if ((was = ACM_GetStream(has)) == NULL) {
660 return MMSYSERR_INVALHANDLE;
661 } else if (was->drvInst.fdwOpen & ACM_STREAMOPENF_ASYNC) {
662 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_RESET, (DWORD)&was->drvInst, 0);
664 TRACE("=> (%d)\n", ret);
665 return ret;
668 /***********************************************************************
669 * acmStreamSize (MSACM32.43)
671 MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput,
672 LPDWORD pdwOutputBytes, DWORD fdwSize)
674 PWINE_ACMSTREAM was;
675 ACMDRVSTREAMSIZE adss;
676 MMRESULT ret;
678 TRACE("(0x%08x, %ld, %p, %ld)\n", has, cbInput, pdwOutputBytes, fdwSize);
680 if ((was = ACM_GetStream(has)) == NULL) {
681 return MMSYSERR_INVALHANDLE;
683 if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) {
684 return MMSYSERR_INVALFLAG;
687 *pdwOutputBytes = 0L;
689 switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
690 case ACM_STREAMSIZEF_DESTINATION:
691 adss.cbDstLength = cbInput;
692 adss.cbSrcLength = 0;
693 break;
694 case ACM_STREAMSIZEF_SOURCE:
695 adss.cbSrcLength = cbInput;
696 adss.cbDstLength = 0;
697 break;
698 default:
699 return MMSYSERR_INVALFLAG;
702 adss.cbStruct = sizeof(adss);
703 adss.fdwSize = fdwSize;
704 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_SIZE,
705 (DWORD)&was->drvInst, (DWORD)&adss);
706 if (ret == MMSYSERR_NOERROR) {
707 switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
708 case ACM_STREAMSIZEF_DESTINATION:
709 *pdwOutputBytes = adss.cbSrcLength;
710 break;
711 case ACM_STREAMSIZEF_SOURCE:
712 *pdwOutputBytes = adss.cbDstLength;
713 break;
716 TRACE("=> (%d) [%lu]\n", ret, *pdwOutputBytes);
717 return ret;
720 /***********************************************************************
721 * acmStreamUnprepareHeader (MSACM32.44)
723 MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
724 DWORD fdwUnprepare)
726 PWINE_ACMSTREAM was;
727 MMRESULT ret = MMSYSERR_NOERROR;
728 PACMDRVSTREAMHEADER padsh;
730 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwUnprepare);
732 if ((was = ACM_GetStream(has)) == NULL)
733 return MMSYSERR_INVALHANDLE;
734 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
735 return MMSYSERR_INVALPARAM;
737 if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
738 return ACMERR_UNPREPARED;
740 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
741 * size. some fields are private to msacm internals, and are exposed
742 * in ACMSTREAMHEADER in the dwReservedDriver array
744 padsh = (PACMDRVSTREAMHEADER)pash;
746 /* check that pointers have not been modified */
747 if (padsh->pbPreparedSrc != padsh->pbSrc ||
748 padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
749 padsh->pbPreparedDst != padsh->pbDst ||
750 padsh->cbPreparedDstLength < padsh->cbDstLength) {
751 return MMSYSERR_INVALPARAM;
754 padsh->fdwConvert = fdwUnprepare;
756 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_UNPREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
757 if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
758 ret = MMSYSERR_NOERROR;
759 padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE|ACMSTREAMHEADER_STATUSF_PREPARED);
761 TRACE("=> (%d)\n", ret);
762 return ret;