Changed code that used pts=0 in demux packets to indicate "not known".
[mplayer.git] / loader / afl.c
blob7e1993657f913168a06795484eb04b22907671a4
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/
22 $Id$
24 ***************************************************************************/
25 #include "config.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 "driver.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;
195 HDRVR hdrv;
198 TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen);
200 if (!phad)
201 return MMSYSERR_INVALPARAM;
203 padid = MSACM_GetDriverID(hadid);
204 if (!padid)
205 return MMSYSERR_INVALHANDLE;
207 if (fdwOpen)
208 return MMSYSERR_INVALFLAG;
210 pad = (PWINE_ACMDRIVER) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
211 if (!pad)
212 return MMSYSERR_NOMEM;
214 pad->obj.pACMDriverID = padid;
215 icopen.fccType = mmioFOURCC('a', 'u', 'd', 'c');
216 icopen.fccHandler = (long)padid->pszFileName;
217 icopen.dwSize = sizeof(ICOPEN);
218 icopen.dwFlags = 0;
220 icopen.pV1Reserved = padid->pszFileName;
221 if (!padid->hInstModule)
222 pad->hDrvr = OpenDriverA((long)&icopen);
223 else
224 pad->hDrvr = padid->hInstModule;
226 if (!pad->hDrvr) {
227 HeapFree(MSACM_hHeap, 0, pad);
228 return MMSYSERR_ERROR;
231 pad->pfnDriverProc = GetProcAddress(pad->hDrvr, "DriverProc");
233 /* insert new pad at beg of list */
234 pad->pNextACMDriver = padid->pACMDriverList;
235 padid->pACMDriverList = pad;
237 /* FIXME: Create a WINE_ACMDRIVER32 */
238 *phad = (HACMDRIVER)pad;
240 return MMSYSERR_NOERROR;
243 /***********************************************************************
244 * acmDriverRemove (MSACM32.12)
246 MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
248 PWINE_ACMDRIVERID padid;
250 padid = MSACM_GetDriverID(hadid);
251 if (!padid)
252 return MMSYSERR_INVALHANDLE;
254 if (fdwRemove)
255 return MMSYSERR_INVALFLAG;
257 MSACM_UnregisterDriver(padid);
259 return MMSYSERR_NOERROR;
264 /**********************************************************************/
266 HANDLE MSACM_hHeap = (HANDLE) NULL;
267 PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL;
268 PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL;
270 /***********************************************************************
271 * MSACM_RegisterDriver32()
273 PWINE_ACMDRIVERID MSACM_RegisterDriver(const char* pszFileName,
274 WORD wFormatTag,
275 HINSTANCE hinstModule)
277 PWINE_ACMDRIVERID padid;
279 TRACE("('%s', '%x', 0x%08x)\n", pszFileName, wFormatTag, hinstModule);
281 #ifndef WIN32_LOADER
282 MSACM_hHeap = GetProcessHeap();
283 #endif
284 padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID));
285 padid->pszFileName = malloc(strlen(pszFileName)+1);
286 strcpy(padid->pszFileName, pszFileName);
287 // 1~strdup(pszDriverAlias);
288 padid->wFormatTag = wFormatTag;
289 padid->hInstModule = hinstModule;
290 padid->bEnabled = TRUE;
291 padid->pACMDriverList = NULL;
292 padid->pNextACMDriverID = NULL;
293 padid->pPrevACMDriverID = MSACM_pLastACMDriverID;
294 if (MSACM_pLastACMDriverID)
295 MSACM_pLastACMDriverID->pNextACMDriverID = padid;
296 MSACM_pLastACMDriverID = padid;
297 if (!MSACM_pFirstACMDriverID)
298 MSACM_pFirstACMDriverID = padid;
300 return padid;
304 /***********************************************************************
305 * MSACM_UnregisterDriver32()
307 PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p)
309 PWINE_ACMDRIVERID pNextACMDriverID;
311 while (p->pACMDriverList)
312 acmDriverClose((HACMDRIVER) p->pACMDriverList, 0);
314 if (p->pszFileName)
315 free(p->pszFileName);
317 if (p == MSACM_pFirstACMDriverID)
318 MSACM_pFirstACMDriverID = p->pNextACMDriverID;
319 if (p == MSACM_pLastACMDriverID)
320 MSACM_pLastACMDriverID = p->pPrevACMDriverID;
322 if (p->pPrevACMDriverID)
323 p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
324 if (p->pNextACMDriverID)
325 p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID;
327 pNextACMDriverID = p->pNextACMDriverID;
329 HeapFree(MSACM_hHeap, 0, p);
331 return pNextACMDriverID;
334 /***********************************************************************
335 * MSACM_UnregisterAllDrivers32()
336 * FIXME
337 * Where should this function be called?
339 void MSACM_UnregisterAllDrivers(void)
341 PWINE_ACMDRIVERID p;
343 for (p = MSACM_pFirstACMDriverID; p; p = MSACM_UnregisterDriver(p));
346 /***********************************************************************
347 * MSACM_GetDriverID32()
349 PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID)
351 return (PWINE_ACMDRIVERID)hDriverID;
354 /***********************************************************************
355 * MSACM_GetDriver32()
357 PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver)
359 return (PWINE_ACMDRIVER)hDriver;
362 /***********************************************************************
363 * MSACM_GetObj32()
365 PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj)
367 return (PWINE_ACMOBJ)hObj;
372 /***********************************************************************
373 * acmStreamOpen (MSACM32.40)
375 MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
376 PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback,
377 DWORD dwInstance, DWORD fdwOpen)
379 PWINE_ACMSTREAM was;
380 PWINE_ACMDRIVER wad;
381 MMRESULT ret;
382 int wfxSrcSize;
383 int wfxDstSize;
385 TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
386 phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen);
388 TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
389 pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec,
390 pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize);
392 TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
393 pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec,
394 pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize);
396 #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
397 wfxSrcSize = SIZEOF_WFX(pwfxSrc);
398 wfxDstSize = SIZEOF_WFX(pwfxDst);
399 #undef SIZEOF_WFX
401 was = (PWINE_ACMSTREAM) HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize + ((pwfltr) ? sizeof(WAVEFILTER) : 0));
402 if (was == NULL)
403 return MMSYSERR_NOMEM;
404 was->drvInst.cbStruct = sizeof(was->drvInst);
405 was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was));
406 memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize);
407 // LHACM is checking for 0x1
408 // but if this will not help
409 // was->drvInst.pwfxSrc->wFormatTag = 1;
410 was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was) + wfxSrcSize);
411 memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize);
412 if (pwfltr) {
413 was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)was + sizeof(*was) + wfxSrcSize + wfxDstSize);
414 memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER));
415 } else {
416 was->drvInst.pwfltr = NULL;
418 was->drvInst.dwCallback = dwCallback;
419 was->drvInst.dwInstance = dwInstance;
420 was->drvInst.fdwOpen = fdwOpen;
421 was->drvInst.fdwDriver = 0L;
422 was->drvInst.dwDriver = 0L;
423 was->drvInst.has = (HACMSTREAM)was;
425 if (had) {
426 if (!(wad = MSACM_GetDriver(had))) {
427 ret = MMSYSERR_INVALPARAM;
428 goto errCleanUp;
431 was->obj.pACMDriverID = wad->obj.pACMDriverID;
432 was->pDrv = wad;
433 was->hAcmDriver = 0; /* not to close it in acmStreamClose */
435 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
436 if (ret != MMSYSERR_NOERROR)
437 goto errCleanUp;
438 } else {
439 PWINE_ACMDRIVERID wadi;
440 short drv_tag;
441 ret = ACMERR_NOTPOSSIBLE;
442 /* if(pwfxSrc->wFormatTag==1)//compression
443 drv_tag=pwfxDst->wFormatTag;
444 else
445 if(pwfxDst->wFormatTag==1)//decompression
446 drv_tag=pwfxSrc->wFormatTag;
447 else
448 goto errCleanUp;
450 ret=acmDriverOpen2(drv_tag);
451 if (ret == MMSYSERR_NOERROR) {
452 if ((wad = MSACM_GetDriver(had)) != 0) {
453 was->obj.pACMDriverID = wad->obj.pACMDriverID;
454 was->pDrv = wad;
455 was->hAcmDriver = had;
457 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
458 if (ret == MMSYSERR_NOERROR) {
459 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
460 acmDriverClose(had, 0L);
462 break;
465 acmDriverClose(had, 0L);*/
466 //if(MSACM_pFirstACMDriverID==NULL)
467 // MSACM_RegisterAllDrivers();
469 for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID)
471 /* Check Format */
472 if ((int)wadi->wFormatTag != (int)pwfxSrc->wFormatTag) continue;
474 ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L);
475 if (ret == MMSYSERR_NOERROR) {
476 if ((wad = MSACM_GetDriver(had)) != 0) {
477 was->obj.pACMDriverID = wad->obj.pACMDriverID;
478 was->pDrv = wad;
479 was->hAcmDriver = had;
481 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
482 //lhacm - crash printf("RETOPEN %d\n", ret);
483 //ret = 0;
484 if (ret == MMSYSERR_NOERROR) {
485 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
486 acmDriverClose(had, 0L);
488 break;
491 // no match, close this acm driver and try next one
492 acmDriverClose(had, 0L);
495 if (ret != MMSYSERR_NOERROR) {
496 ret = ACMERR_NOTPOSSIBLE;
497 goto errCleanUp;
500 ret = MMSYSERR_NOERROR;
501 if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) {
502 if (phas)
503 *phas = (HACMSTREAM)was;
504 TRACE("=> (%d)\n", ret);
505 #ifdef WIN32_LOADER
506 CodecAlloc();
507 #endif
508 return ret;
510 errCleanUp:
511 if (phas)
512 *phas = (HACMSTREAM)0;
513 HeapFree(MSACM_hHeap, 0, was);
514 TRACE("=> (%d)\n", ret);
515 return ret;
519 MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose)
521 PWINE_ACMSTREAM was;
522 MMRESULT ret;
524 TRACE("(0x%08x, %ld)\n", has, fdwClose);
526 if ((was = ACM_GetStream(has)) == NULL) {
527 return MMSYSERR_INVALHANDLE;
529 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0);
530 if (ret == MMSYSERR_NOERROR) {
531 if (was->hAcmDriver)
532 acmDriverClose(was->hAcmDriver, 0L);
533 HeapFree(MSACM_hHeap, 0, was);
534 #ifdef WIN32_LOADER
535 CodecRelease();
536 #endif
538 TRACE("=> (%d)\n", ret);
539 return ret;
542 /***********************************************************************
543 * acmStreamConvert (MSACM32.38)
545 MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash,
546 DWORD fdwConvert)
548 PWINE_ACMSTREAM was;
549 MMRESULT ret = MMSYSERR_NOERROR;
550 PACMDRVSTREAMHEADER padsh;
552 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwConvert);
554 if ((was = ACM_GetStream(has)) == NULL)
555 return MMSYSERR_INVALHANDLE;
556 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
557 return MMSYSERR_INVALPARAM;
559 if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
560 return ACMERR_UNPREPARED;
562 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
563 * size. some fields are private to msacm internals, and are exposed
564 * in ACMSTREAMHEADER in the dwReservedDriver array
566 padsh = (PACMDRVSTREAMHEADER)pash;
568 /* check that pointers have not been modified */
569 if (padsh->pbPreparedSrc != padsh->pbSrc ||
570 padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
571 padsh->pbPreparedDst != padsh->pbDst ||
572 padsh->cbPreparedDstLength < padsh->cbDstLength) {
573 return MMSYSERR_INVALPARAM;
576 padsh->fdwConvert = fdwConvert;
578 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CONVERT, (DWORD)&was->drvInst, (DWORD)padsh);
579 if (ret == MMSYSERR_NOERROR) {
580 padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_DONE;
582 TRACE("=> (%d)\n", ret);
583 return ret;
587 /***********************************************************************
588 * acmStreamPrepareHeader (MSACM32.41)
590 MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
591 DWORD fdwPrepare)
593 PWINE_ACMSTREAM was;
594 MMRESULT ret = MMSYSERR_NOERROR;
595 PACMDRVSTREAMHEADER padsh;
597 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwPrepare);
599 if ((was = ACM_GetStream(has)) == NULL)
600 return MMSYSERR_INVALHANDLE;
601 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
602 return MMSYSERR_INVALPARAM;
603 if (fdwPrepare)
604 ret = MMSYSERR_INVALFLAG;
606 if (pash->fdwStatus & ACMSTREAMHEADER_STATUSF_DONE)
607 return MMSYSERR_NOERROR;
609 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
610 * size. some fields are private to msacm internals, and are exposed
611 * in ACMSTREAMHEADER in the dwReservedDriver array
613 padsh = (PACMDRVSTREAMHEADER)pash;
615 padsh->fdwConvert = fdwPrepare;
616 padsh->padshNext = NULL;
617 padsh->fdwDriver = padsh->dwDriver = 0L;
619 padsh->fdwPrepared = 0;
620 padsh->dwPrepared = 0;
621 padsh->pbPreparedSrc = 0;
622 padsh->cbPreparedSrcLength = 0;
623 padsh->pbPreparedDst = 0;
624 padsh->cbPreparedDstLength = 0;
626 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_PREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
627 if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
628 ret = MMSYSERR_NOERROR;
629 padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE);
630 padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_PREPARED;
631 padsh->fdwPrepared = padsh->fdwStatus;
632 padsh->dwPrepared = 0;
633 padsh->pbPreparedSrc = padsh->pbSrc;
634 padsh->cbPreparedSrcLength = padsh->cbSrcLength;
635 padsh->pbPreparedDst = padsh->pbDst;
636 padsh->cbPreparedDstLength = padsh->cbDstLength;
637 } else {
638 padsh->fdwPrepared = 0;
639 padsh->dwPrepared = 0;
640 padsh->pbPreparedSrc = 0;
641 padsh->cbPreparedSrcLength = 0;
642 padsh->pbPreparedDst = 0;
643 padsh->cbPreparedDstLength = 0;
645 TRACE("=> (%d)\n", ret);
646 return ret;
649 /***********************************************************************
650 * acmStreamReset (MSACM32.42)
652 MMRESULT WINAPI acmStreamReset(HACMSTREAM has, DWORD fdwReset)
654 PWINE_ACMSTREAM was;
655 MMRESULT ret = MMSYSERR_NOERROR;
657 TRACE("(0x%08x, %ld)\n", has, fdwReset);
659 if (fdwReset) {
660 ret = MMSYSERR_INVALFLAG;
661 } else if ((was = ACM_GetStream(has)) == NULL) {
662 return MMSYSERR_INVALHANDLE;
663 } else if (was->drvInst.fdwOpen & ACM_STREAMOPENF_ASYNC) {
664 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_RESET, (DWORD)&was->drvInst, 0);
666 TRACE("=> (%d)\n", ret);
667 return ret;
670 /***********************************************************************
671 * acmStreamSize (MSACM32.43)
673 MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput,
674 LPDWORD pdwOutputBytes, DWORD fdwSize)
676 PWINE_ACMSTREAM was;
677 ACMDRVSTREAMSIZE adss;
678 MMRESULT ret;
680 TRACE("(0x%08x, %ld, %p, %ld)\n", has, cbInput, pdwOutputBytes, fdwSize);
682 if ((was = ACM_GetStream(has)) == NULL) {
683 return MMSYSERR_INVALHANDLE;
685 if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) {
686 return MMSYSERR_INVALFLAG;
689 *pdwOutputBytes = 0L;
691 switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
692 case ACM_STREAMSIZEF_DESTINATION:
693 adss.cbDstLength = cbInput;
694 adss.cbSrcLength = 0;
695 break;
696 case ACM_STREAMSIZEF_SOURCE:
697 adss.cbSrcLength = cbInput;
698 adss.cbDstLength = 0;
699 break;
700 default:
701 return MMSYSERR_INVALFLAG;
704 adss.cbStruct = sizeof(adss);
705 adss.fdwSize = fdwSize;
706 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_SIZE,
707 (DWORD)&was->drvInst, (DWORD)&adss);
708 if (ret == MMSYSERR_NOERROR) {
709 switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
710 case ACM_STREAMSIZEF_DESTINATION:
711 *pdwOutputBytes = adss.cbSrcLength;
712 break;
713 case ACM_STREAMSIZEF_SOURCE:
714 *pdwOutputBytes = adss.cbDstLength;
715 break;
718 TRACE("=> (%d) [%lu]\n", ret, *pdwOutputBytes);
719 return ret;
722 /***********************************************************************
723 * acmStreamUnprepareHeader (MSACM32.44)
725 MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
726 DWORD fdwUnprepare)
728 PWINE_ACMSTREAM was;
729 MMRESULT ret = MMSYSERR_NOERROR;
730 PACMDRVSTREAMHEADER padsh;
732 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwUnprepare);
734 if ((was = ACM_GetStream(has)) == NULL)
735 return MMSYSERR_INVALHANDLE;
736 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
737 return MMSYSERR_INVALPARAM;
739 if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
740 return ACMERR_UNPREPARED;
742 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
743 * size. some fields are private to msacm internals, and are exposed
744 * in ACMSTREAMHEADER in the dwReservedDriver array
746 padsh = (PACMDRVSTREAMHEADER)pash;
748 /* check that pointers have not been modified */
749 if (padsh->pbPreparedSrc != padsh->pbSrc ||
750 padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
751 padsh->pbPreparedDst != padsh->pbDst ||
752 padsh->cbPreparedDstLength < padsh->cbDstLength) {
753 return MMSYSERR_INVALPARAM;
756 padsh->fdwConvert = fdwUnprepare;
758 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_UNPREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
759 if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
760 ret = MMSYSERR_NOERROR;
761 padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE|ACMSTREAMHEADER_STATUSF_PREPARED);
763 TRACE("=> (%d)\n", ret);
764 return ret;