core: Clean up OSD seek info logic
[mplayer.git] / loader / afl.c
blob36b666bb0a9e155f1b24f1a35c6414b0ab6123ae
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 = 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 if (p->pszFileName)
314 free(p->pszFileName);
316 if (p == MSACM_pFirstACMDriverID)
317 MSACM_pFirstACMDriverID = p->pNextACMDriverID;
318 if (p == MSACM_pLastACMDriverID)
319 MSACM_pLastACMDriverID = p->pPrevACMDriverID;
321 if (p->pPrevACMDriverID)
322 p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
323 if (p->pNextACMDriverID)
324 p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID;
326 pNextACMDriverID = p->pNextACMDriverID;
328 HeapFree(MSACM_hHeap, 0, p);
330 return pNextACMDriverID;
333 /***********************************************************************
334 * MSACM_UnregisterAllDrivers32()
335 * FIXME
336 * Where should this function be called?
338 void MSACM_UnregisterAllDrivers(void)
340 PWINE_ACMDRIVERID p;
342 for (p = MSACM_pFirstACMDriverID; p; p = MSACM_UnregisterDriver(p));
345 /***********************************************************************
346 * MSACM_GetDriverID32()
348 PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID)
350 return (PWINE_ACMDRIVERID)hDriverID;
353 /***********************************************************************
354 * MSACM_GetDriver32()
356 PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver)
358 return (PWINE_ACMDRIVER)hDriver;
361 /***********************************************************************
362 * MSACM_GetObj32()
364 PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj)
366 return (PWINE_ACMOBJ)hObj;
371 /***********************************************************************
372 * acmStreamOpen (MSACM32.40)
374 MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
375 PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback,
376 DWORD dwInstance, DWORD fdwOpen)
378 PWINE_ACMSTREAM was;
379 PWINE_ACMDRIVER wad;
380 MMRESULT ret;
381 int wfxSrcSize;
382 int wfxDstSize;
384 TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
385 phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen);
387 TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
388 pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec,
389 pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize);
391 TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
392 pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec,
393 pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize);
395 #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
396 wfxSrcSize = SIZEOF_WFX(pwfxSrc);
397 wfxDstSize = SIZEOF_WFX(pwfxDst);
398 #undef SIZEOF_WFX
400 was = (PWINE_ACMSTREAM) HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize + ((pwfltr) ? sizeof(WAVEFILTER) : 0));
401 if (was == NULL)
402 return MMSYSERR_NOMEM;
403 was->drvInst.cbStruct = sizeof(was->drvInst);
404 was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was));
405 memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize);
406 // LHACM is checking for 0x1
407 // but if this will not help
408 // was->drvInst.pwfxSrc->wFormatTag = 1;
409 was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was) + wfxSrcSize);
410 memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize);
411 if (pwfltr) {
412 was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)was + sizeof(*was) + wfxSrcSize + wfxDstSize);
413 memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER));
414 } else {
415 was->drvInst.pwfltr = NULL;
417 was->drvInst.dwCallback = dwCallback;
418 was->drvInst.dwInstance = dwInstance;
419 was->drvInst.fdwOpen = fdwOpen;
420 was->drvInst.fdwDriver = 0L;
421 was->drvInst.dwDriver = 0L;
422 was->drvInst.has = (HACMSTREAM)was;
424 if (had) {
425 if (!(wad = MSACM_GetDriver(had))) {
426 ret = MMSYSERR_INVALPARAM;
427 goto errCleanUp;
430 was->obj.pACMDriverID = wad->obj.pACMDriverID;
431 was->pDrv = wad;
432 was->hAcmDriver = 0; /* not to close it in acmStreamClose */
434 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
435 if (ret != MMSYSERR_NOERROR)
436 goto errCleanUp;
437 } else {
438 PWINE_ACMDRIVERID wadi;
439 //short drv_tag;
440 ret = ACMERR_NOTPOSSIBLE;
441 /* if(pwfxSrc->wFormatTag==1)//compression
442 drv_tag=pwfxDst->wFormatTag;
443 else
444 if(pwfxDst->wFormatTag==1)//decompression
445 drv_tag=pwfxSrc->wFormatTag;
446 else
447 goto errCleanUp;
449 ret=acmDriverOpen2(drv_tag);
450 if (ret == MMSYSERR_NOERROR) {
451 if ((wad = MSACM_GetDriver(had)) != 0) {
452 was->obj.pACMDriverID = wad->obj.pACMDriverID;
453 was->pDrv = wad;
454 was->hAcmDriver = had;
456 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
457 if (ret == MMSYSERR_NOERROR) {
458 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
459 acmDriverClose(had, 0L);
461 break;
464 acmDriverClose(had, 0L);*/
465 //if(MSACM_pFirstACMDriverID==NULL)
466 // MSACM_RegisterAllDrivers();
468 for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID)
470 /* Check Format */
471 if ((int)wadi->wFormatTag != (int)pwfxSrc->wFormatTag) continue;
473 ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L);
474 if (ret == MMSYSERR_NOERROR) {
475 if ((wad = MSACM_GetDriver(had)) != 0) {
476 was->obj.pACMDriverID = wad->obj.pACMDriverID;
477 was->pDrv = wad;
478 was->hAcmDriver = had;
480 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
481 //lhacm - crash printf("RETOPEN %d\n", ret);
482 //ret = 0;
483 if (ret == MMSYSERR_NOERROR) {
484 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
485 acmDriverClose(had, 0L);
487 break;
490 // no match, close this acm driver and try next one
491 acmDriverClose(had, 0L);
494 if (ret != MMSYSERR_NOERROR) {
495 ret = ACMERR_NOTPOSSIBLE;
496 goto errCleanUp;
499 ret = MMSYSERR_NOERROR;
500 if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) {
501 if (phas)
502 *phas = (HACMSTREAM)was;
503 TRACE("=> (%d)\n", ret);
504 #ifdef WIN32_LOADER
505 CodecAlloc();
506 #endif
507 return ret;
509 errCleanUp:
510 if (phas)
511 *phas = (HACMSTREAM)0;
512 HeapFree(MSACM_hHeap, 0, was);
513 TRACE("=> (%d)\n", ret);
514 return ret;
518 MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose)
520 PWINE_ACMSTREAM was;
521 MMRESULT ret;
523 TRACE("(0x%08x, %ld)\n", has, fdwClose);
525 if ((was = ACM_GetStream(has)) == NULL) {
526 return MMSYSERR_INVALHANDLE;
528 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0);
529 if (ret == MMSYSERR_NOERROR) {
530 if (was->hAcmDriver)
531 acmDriverClose(was->hAcmDriver, 0L);
532 HeapFree(MSACM_hHeap, 0, was);
533 #ifdef WIN32_LOADER
534 CodecRelease();
535 #endif
537 TRACE("=> (%d)\n", ret);
538 return ret;
541 /***********************************************************************
542 * acmStreamConvert (MSACM32.38)
544 MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash,
545 DWORD fdwConvert)
547 PWINE_ACMSTREAM was;
548 MMRESULT ret = MMSYSERR_NOERROR;
549 PACMDRVSTREAMHEADER padsh;
551 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwConvert);
553 if ((was = ACM_GetStream(has)) == NULL)
554 return MMSYSERR_INVALHANDLE;
555 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
556 return MMSYSERR_INVALPARAM;
558 if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
559 return ACMERR_UNPREPARED;
561 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
562 * size. some fields are private to msacm internals, and are exposed
563 * in ACMSTREAMHEADER in the dwReservedDriver array
565 padsh = (PACMDRVSTREAMHEADER)pash;
567 /* check that pointers have not been modified */
568 if (padsh->pbPreparedSrc != padsh->pbSrc ||
569 padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
570 padsh->pbPreparedDst != padsh->pbDst ||
571 padsh->cbPreparedDstLength < padsh->cbDstLength) {
572 return MMSYSERR_INVALPARAM;
575 padsh->fdwConvert = fdwConvert;
577 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CONVERT, (DWORD)&was->drvInst, (DWORD)padsh);
578 if (ret == MMSYSERR_NOERROR) {
579 padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_DONE;
581 TRACE("=> (%d)\n", ret);
582 return ret;
586 /***********************************************************************
587 * acmStreamPrepareHeader (MSACM32.41)
589 MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
590 DWORD fdwPrepare)
592 PWINE_ACMSTREAM was;
593 MMRESULT ret = MMSYSERR_NOERROR;
594 PACMDRVSTREAMHEADER padsh;
596 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwPrepare);
598 if ((was = ACM_GetStream(has)) == NULL)
599 return MMSYSERR_INVALHANDLE;
600 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
601 return MMSYSERR_INVALPARAM;
602 if (fdwPrepare)
603 ret = MMSYSERR_INVALFLAG;
605 if (pash->fdwStatus & ACMSTREAMHEADER_STATUSF_DONE)
606 return MMSYSERR_NOERROR;
608 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
609 * size. some fields are private to msacm internals, and are exposed
610 * in ACMSTREAMHEADER in the dwReservedDriver array
612 padsh = (PACMDRVSTREAMHEADER)pash;
614 padsh->fdwConvert = fdwPrepare;
615 padsh->padshNext = NULL;
616 padsh->fdwDriver = padsh->dwDriver = 0L;
618 padsh->fdwPrepared = 0;
619 padsh->dwPrepared = 0;
620 padsh->pbPreparedSrc = 0;
621 padsh->cbPreparedSrcLength = 0;
622 padsh->pbPreparedDst = 0;
623 padsh->cbPreparedDstLength = 0;
625 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_PREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
626 if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
627 ret = MMSYSERR_NOERROR;
628 padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE);
629 padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_PREPARED;
630 padsh->fdwPrepared = padsh->fdwStatus;
631 padsh->dwPrepared = 0;
632 padsh->pbPreparedSrc = padsh->pbSrc;
633 padsh->cbPreparedSrcLength = padsh->cbSrcLength;
634 padsh->pbPreparedDst = padsh->pbDst;
635 padsh->cbPreparedDstLength = padsh->cbDstLength;
636 } else {
637 padsh->fdwPrepared = 0;
638 padsh->dwPrepared = 0;
639 padsh->pbPreparedSrc = 0;
640 padsh->cbPreparedSrcLength = 0;
641 padsh->pbPreparedDst = 0;
642 padsh->cbPreparedDstLength = 0;
644 TRACE("=> (%d)\n", ret);
645 return ret;
648 /***********************************************************************
649 * acmStreamReset (MSACM32.42)
651 MMRESULT WINAPI acmStreamReset(HACMSTREAM has, DWORD fdwReset)
653 PWINE_ACMSTREAM was;
654 MMRESULT ret = MMSYSERR_NOERROR;
656 TRACE("(0x%08x, %ld)\n", has, fdwReset);
658 if (fdwReset) {
659 ret = MMSYSERR_INVALFLAG;
660 } else if ((was = ACM_GetStream(has)) == NULL) {
661 return MMSYSERR_INVALHANDLE;
662 } else if (was->drvInst.fdwOpen & ACM_STREAMOPENF_ASYNC) {
663 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_RESET, (DWORD)&was->drvInst, 0);
665 TRACE("=> (%d)\n", ret);
666 return ret;
669 /***********************************************************************
670 * acmStreamSize (MSACM32.43)
672 MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput,
673 LPDWORD pdwOutputBytes, DWORD fdwSize)
675 PWINE_ACMSTREAM was;
676 ACMDRVSTREAMSIZE adss;
677 MMRESULT ret;
679 TRACE("(0x%08x, %ld, %p, %ld)\n", has, cbInput, pdwOutputBytes, fdwSize);
681 if ((was = ACM_GetStream(has)) == NULL) {
682 return MMSYSERR_INVALHANDLE;
684 if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) {
685 return MMSYSERR_INVALFLAG;
688 *pdwOutputBytes = 0L;
690 switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
691 case ACM_STREAMSIZEF_DESTINATION:
692 adss.cbDstLength = cbInput;
693 adss.cbSrcLength = 0;
694 break;
695 case ACM_STREAMSIZEF_SOURCE:
696 adss.cbSrcLength = cbInput;
697 adss.cbDstLength = 0;
698 break;
699 default:
700 return MMSYSERR_INVALFLAG;
703 adss.cbStruct = sizeof(adss);
704 adss.fdwSize = fdwSize;
705 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_SIZE,
706 (DWORD)&was->drvInst, (DWORD)&adss);
707 if (ret == MMSYSERR_NOERROR) {
708 switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
709 case ACM_STREAMSIZEF_DESTINATION:
710 *pdwOutputBytes = adss.cbSrcLength;
711 break;
712 case ACM_STREAMSIZEF_SOURCE:
713 *pdwOutputBytes = adss.cbDstLength;
714 break;
717 TRACE("=> (%d) [%lu]\n", ret, *pdwOutputBytes);
718 return ret;
721 /***********************************************************************
722 * acmStreamUnprepareHeader (MSACM32.44)
724 MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
725 DWORD fdwUnprepare)
727 PWINE_ACMSTREAM was;
728 MMRESULT ret = MMSYSERR_NOERROR;
729 PACMDRVSTREAMHEADER padsh;
731 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwUnprepare);
733 if ((was = ACM_GetStream(has)) == NULL)
734 return MMSYSERR_INVALHANDLE;
735 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
736 return MMSYSERR_INVALPARAM;
738 if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
739 return ACMERR_UNPREPARED;
741 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
742 * size. some fields are private to msacm internals, and are exposed
743 * in ACMSTREAMHEADER in the dwReservedDriver array
745 padsh = (PACMDRVSTREAMHEADER)pash;
747 /* check that pointers have not been modified */
748 if (padsh->pbPreparedSrc != padsh->pbSrc ||
749 padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
750 padsh->pbPreparedDst != padsh->pbDst ||
751 padsh->cbPreparedDstLength < padsh->cbDstLength) {
752 return MMSYSERR_INVALPARAM;
755 padsh->fdwConvert = fdwUnprepare;
757 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_UNPREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
758 if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
759 ret = MMSYSERR_NOERROR;
760 padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE|ACMSTREAMHEADER_STATUSF_PREPARED);
762 TRACE("=> (%d)\n", ret);
763 return ret;