Set sub_utf8 for mov subs.
[mplayer/glamo.git] / loader / afl.c
blob6284d5ce566430e6a67bf62d286205c50edddf40
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"
26 #include "debug.h"
28 #include "wine/winbase.h"
29 #include "wine/windef.h"
30 #include "wine/winuser.h"
31 #include "wine/vfw.h"
32 #include "wine/winestring.h"
33 #include "wine/driver.h"
34 #include "wine/winerror.h"
35 #include "wine/msacm.h"
36 #include "wine/msacmdrv.h"
37 #include "wineacm.h"
38 #ifndef __MINGW32__
39 #include "ext.h"
40 #endif
41 #include "driver.h"
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #pragma pack(1)
47 #define OpenDriverA DrvOpen
48 #define CloseDriver DrvClose
50 static inline PWINE_ACMSTREAM ACM_GetStream(HACMSTREAM has)
52 return (PWINE_ACMSTREAM)has;
55 /***********************************************************************
56 * acmDriverAddA (MSACM32.2)
58 MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule,
59 LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
61 if (!phadid)
62 return MMSYSERR_INVALPARAM;
64 /* Check if any unknown flags */
65 if (fdwAdd &
66 ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND|
67 ACM_DRIVERADDF_GLOBAL))
68 return MMSYSERR_INVALFLAG;
70 /* Check if any incompatible flags */
71 if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) &&
72 (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND))
73 return MMSYSERR_INVALFLAG;
75 /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a
76 * LoadDriver on it, to be sure we can call SendDriverMessage on the
77 * hDrvr handle.
79 *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, 0, hinstModule);
81 /* FIXME: lParam, dwPriority and fdwAdd ignored */
83 return MMSYSERR_NOERROR;
86 /***********************************************************************
87 * acmDriverClose (MSACM32.4)
89 MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
91 PWINE_ACMDRIVER p;
92 PWINE_ACMDRIVER* tp;
94 if (fdwClose)
95 return MMSYSERR_INVALFLAG;
97 p = MSACM_GetDriver(had);
98 if (!p)
99 return MMSYSERR_INVALHANDLE;
101 for (tp = &(p->obj.pACMDriverID->pACMDriverList); *tp; *tp = (*tp)->pNextACMDriver) {
102 if (*tp == p) {
103 *tp = (*tp)->pNextACMDriver;
104 break;
108 if (p->hDrvr && !p->obj.pACMDriverID->pACMDriverList)
109 CloseDriver(p->hDrvr);
111 HeapFree(MSACM_hHeap, 0, p);
113 return MMSYSERR_NOERROR;
116 /***********************************************************************
117 * acmDriverEnum (MSACM32.7)
119 MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)
121 PWINE_ACMDRIVERID p;
122 DWORD fdwSupport;
124 if (!fnCallback) {
125 return MMSYSERR_INVALPARAM;
128 if (fdwEnum && ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED)) {
129 return MMSYSERR_INVALFLAG;
132 for (p = MSACM_pFirstACMDriverID; p; p = p->pNextACMDriverID) {
133 fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
134 if (!p->bEnabled) {
135 if (fdwEnum & ACM_DRIVERENUMF_DISABLED)
136 fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
137 else
138 continue;
140 (*fnCallback)((HACMDRIVERID) p, dwInstance, fdwSupport);
143 return MMSYSERR_NOERROR;
146 /***********************************************************************
147 * acmDriverID (MSACM32.8)
149 MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID)
151 PWINE_ACMOBJ pao;
153 pao = MSACM_GetObj(hao);
154 if (!pao)
155 return MMSYSERR_INVALHANDLE;
157 if (!phadid)
158 return MMSYSERR_INVALPARAM;
160 if (fdwDriverID)
161 return MMSYSERR_INVALFLAG;
163 *phadid = (HACMDRIVERID) pao->pACMDriverID;
165 return MMSYSERR_NOERROR;
168 /***********************************************************************
169 * acmDriverMessage (MSACM32.9)
170 * FIXME
171 * Not implemented
173 LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
175 PWINE_ACMDRIVER pad = MSACM_GetDriver(had);
176 if (!pad)
177 return MMSYSERR_INVALPARAM;
179 /* FIXME: Check if uMsg legal */
181 if (!SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2))
182 return MMSYSERR_NOTSUPPORTED;
184 return MMSYSERR_NOERROR;
188 /***********************************************************************
189 * acmDriverOpen (MSACM32.10)
191 MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
193 PWINE_ACMDRIVERID padid;
194 PWINE_ACMDRIVER pad;
195 ICOPEN icopen;
196 HDRVR hdrv;
199 TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen);
201 if (!phad)
202 return MMSYSERR_INVALPARAM;
204 padid = MSACM_GetDriverID(hadid);
205 if (!padid)
206 return MMSYSERR_INVALHANDLE;
208 if (fdwOpen)
209 return MMSYSERR_INVALFLAG;
211 pad = (PWINE_ACMDRIVER) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
212 if (!pad)
213 return MMSYSERR_NOMEM;
215 pad->obj.pACMDriverID = padid;
216 icopen.fccType = mmioFOURCC('a', 'u', 'd', 'c');
217 icopen.fccHandler = (long)padid->pszFileName;
218 icopen.dwSize = sizeof(ICOPEN);
219 icopen.dwFlags = 0;
221 icopen.pV1Reserved = padid->pszFileName;
222 if (!padid->hInstModule)
223 pad->hDrvr = OpenDriverA((long)&icopen);
224 else
225 pad->hDrvr = padid->hInstModule;
227 if (!pad->hDrvr) {
228 HeapFree(MSACM_hHeap, 0, pad);
229 return MMSYSERR_ERROR;
232 pad->pfnDriverProc = GetProcAddress(pad->hDrvr, "DriverProc");
234 /* insert new pad at beg of list */
235 pad->pNextACMDriver = padid->pACMDriverList;
236 padid->pACMDriverList = pad;
238 /* FIXME: Create a WINE_ACMDRIVER32 */
239 *phad = (HACMDRIVER)pad;
241 return MMSYSERR_NOERROR;
244 /***********************************************************************
245 * acmDriverRemove (MSACM32.12)
247 MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
249 PWINE_ACMDRIVERID padid;
251 padid = MSACM_GetDriverID(hadid);
252 if (!padid)
253 return MMSYSERR_INVALHANDLE;
255 if (fdwRemove)
256 return MMSYSERR_INVALFLAG;
258 MSACM_UnregisterDriver(padid);
260 return MMSYSERR_NOERROR;
265 /**********************************************************************/
267 HANDLE MSACM_hHeap = (HANDLE) NULL;
268 PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL;
269 PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL;
271 /***********************************************************************
272 * MSACM_RegisterDriver32()
274 PWINE_ACMDRIVERID MSACM_RegisterDriver(const char* pszFileName,
275 WORD wFormatTag,
276 HINSTANCE hinstModule)
278 PWINE_ACMDRIVERID padid;
280 TRACE("('%s', '%x', 0x%08x)\n", pszFileName, wFormatTag, hinstModule);
282 #ifndef WIN32_LOADER
283 MSACM_hHeap = GetProcessHeap();
284 #endif
285 padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID));
286 padid->pszFileName = malloc(strlen(pszFileName)+1);
287 strcpy(padid->pszFileName, pszFileName);
288 // 1~strdup(pszDriverAlias);
289 padid->wFormatTag = wFormatTag;
290 padid->hInstModule = hinstModule;
291 padid->bEnabled = TRUE;
292 padid->pACMDriverList = NULL;
293 padid->pNextACMDriverID = NULL;
294 padid->pPrevACMDriverID = MSACM_pLastACMDriverID;
295 if (MSACM_pLastACMDriverID)
296 MSACM_pLastACMDriverID->pNextACMDriverID = padid;
297 MSACM_pLastACMDriverID = padid;
298 if (!MSACM_pFirstACMDriverID)
299 MSACM_pFirstACMDriverID = padid;
301 return padid;
305 /***********************************************************************
306 * MSACM_UnregisterDriver32()
308 PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p)
310 PWINE_ACMDRIVERID pNextACMDriverID;
312 while (p->pACMDriverList)
313 acmDriverClose((HACMDRIVER) p->pACMDriverList, 0);
315 if (p->pszFileName)
316 free(p->pszFileName);
318 if (p == MSACM_pFirstACMDriverID)
319 MSACM_pFirstACMDriverID = p->pNextACMDriverID;
320 if (p == MSACM_pLastACMDriverID)
321 MSACM_pLastACMDriverID = p->pPrevACMDriverID;
323 if (p->pPrevACMDriverID)
324 p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
325 if (p->pNextACMDriverID)
326 p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID;
328 pNextACMDriverID = p->pNextACMDriverID;
330 HeapFree(MSACM_hHeap, 0, p);
332 return pNextACMDriverID;
335 /***********************************************************************
336 * MSACM_UnregisterAllDrivers32()
337 * FIXME
338 * Where should this function be called?
340 void MSACM_UnregisterAllDrivers(void)
342 PWINE_ACMDRIVERID p;
344 for (p = MSACM_pFirstACMDriverID; p; p = MSACM_UnregisterDriver(p));
347 /***********************************************************************
348 * MSACM_GetDriverID32()
350 PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID)
352 return (PWINE_ACMDRIVERID)hDriverID;
355 /***********************************************************************
356 * MSACM_GetDriver32()
358 PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver)
360 return (PWINE_ACMDRIVER)hDriver;
363 /***********************************************************************
364 * MSACM_GetObj32()
366 PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj)
368 return (PWINE_ACMOBJ)hObj;
373 /***********************************************************************
374 * acmStreamOpen (MSACM32.40)
376 MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
377 PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback,
378 DWORD dwInstance, DWORD fdwOpen)
380 PWINE_ACMSTREAM was;
381 PWINE_ACMDRIVER wad;
382 MMRESULT ret;
383 int wfxSrcSize;
384 int wfxDstSize;
386 TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
387 phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen);
389 TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
390 pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec,
391 pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize);
393 TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
394 pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec,
395 pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize);
397 #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
398 wfxSrcSize = SIZEOF_WFX(pwfxSrc);
399 wfxDstSize = SIZEOF_WFX(pwfxDst);
400 #undef SIZEOF_WFX
402 was = (PWINE_ACMSTREAM) HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize + ((pwfltr) ? sizeof(WAVEFILTER) : 0));
403 if (was == NULL)
404 return MMSYSERR_NOMEM;
405 was->drvInst.cbStruct = sizeof(was->drvInst);
406 was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was));
407 memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize);
408 // LHACM is checking for 0x1
409 // but if this will not help
410 // was->drvInst.pwfxSrc->wFormatTag = 1;
411 was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was) + wfxSrcSize);
412 memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize);
413 if (pwfltr) {
414 was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)was + sizeof(*was) + wfxSrcSize + wfxDstSize);
415 memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER));
416 } else {
417 was->drvInst.pwfltr = NULL;
419 was->drvInst.dwCallback = dwCallback;
420 was->drvInst.dwInstance = dwInstance;
421 was->drvInst.fdwOpen = fdwOpen;
422 was->drvInst.fdwDriver = 0L;
423 was->drvInst.dwDriver = 0L;
424 was->drvInst.has = (HACMSTREAM)was;
426 if (had) {
427 if (!(wad = MSACM_GetDriver(had))) {
428 ret = MMSYSERR_INVALPARAM;
429 goto errCleanUp;
432 was->obj.pACMDriverID = wad->obj.pACMDriverID;
433 was->pDrv = wad;
434 was->hAcmDriver = 0; /* not to close it in acmStreamClose */
436 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
437 if (ret != MMSYSERR_NOERROR)
438 goto errCleanUp;
439 } else {
440 PWINE_ACMDRIVERID wadi;
441 short drv_tag;
442 ret = ACMERR_NOTPOSSIBLE;
443 /* if(pwfxSrc->wFormatTag==1)//compression
444 drv_tag=pwfxDst->wFormatTag;
445 else
446 if(pwfxDst->wFormatTag==1)//decompression
447 drv_tag=pwfxSrc->wFormatTag;
448 else
449 goto errCleanUp;
451 ret=acmDriverOpen2(drv_tag);
452 if (ret == MMSYSERR_NOERROR) {
453 if ((wad = MSACM_GetDriver(had)) != 0) {
454 was->obj.pACMDriverID = wad->obj.pACMDriverID;
455 was->pDrv = wad;
456 was->hAcmDriver = had;
458 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
459 if (ret == MMSYSERR_NOERROR) {
460 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
461 acmDriverClose(had, 0L);
463 break;
466 acmDriverClose(had, 0L);*/
467 //if(MSACM_pFirstACMDriverID==NULL)
468 // MSACM_RegisterAllDrivers();
470 for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID)
472 /* Check Format */
473 if ((int)wadi->wFormatTag != (int)pwfxSrc->wFormatTag) continue;
475 ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L);
476 if (ret == MMSYSERR_NOERROR) {
477 if ((wad = MSACM_GetDriver(had)) != 0) {
478 was->obj.pACMDriverID = wad->obj.pACMDriverID;
479 was->pDrv = wad;
480 was->hAcmDriver = had;
482 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
483 //lhacm - crash printf("RETOPEN %d\n", ret);
484 //ret = 0;
485 if (ret == MMSYSERR_NOERROR) {
486 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
487 acmDriverClose(had, 0L);
489 break;
492 // no match, close this acm driver and try next one
493 acmDriverClose(had, 0L);
496 if (ret != MMSYSERR_NOERROR) {
497 ret = ACMERR_NOTPOSSIBLE;
498 goto errCleanUp;
501 ret = MMSYSERR_NOERROR;
502 if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) {
503 if (phas)
504 *phas = (HACMSTREAM)was;
505 TRACE("=> (%d)\n", ret);
506 #ifdef WIN32_LOADER
507 CodecAlloc();
508 #endif
509 return ret;
511 errCleanUp:
512 if (phas)
513 *phas = (HACMSTREAM)0;
514 HeapFree(MSACM_hHeap, 0, was);
515 TRACE("=> (%d)\n", ret);
516 return ret;
520 MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose)
522 PWINE_ACMSTREAM was;
523 MMRESULT ret;
525 TRACE("(0x%08x, %ld)\n", has, fdwClose);
527 if ((was = ACM_GetStream(has)) == NULL) {
528 return MMSYSERR_INVALHANDLE;
530 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0);
531 if (ret == MMSYSERR_NOERROR) {
532 if (was->hAcmDriver)
533 acmDriverClose(was->hAcmDriver, 0L);
534 HeapFree(MSACM_hHeap, 0, was);
535 #ifdef WIN32_LOADER
536 CodecRelease();
537 #endif
539 TRACE("=> (%d)\n", ret);
540 return ret;
543 /***********************************************************************
544 * acmStreamConvert (MSACM32.38)
546 MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash,
547 DWORD fdwConvert)
549 PWINE_ACMSTREAM was;
550 MMRESULT ret = MMSYSERR_NOERROR;
551 PACMDRVSTREAMHEADER padsh;
553 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwConvert);
555 if ((was = ACM_GetStream(has)) == NULL)
556 return MMSYSERR_INVALHANDLE;
557 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
558 return MMSYSERR_INVALPARAM;
560 if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
561 return ACMERR_UNPREPARED;
563 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
564 * size. some fields are private to msacm internals, and are exposed
565 * in ACMSTREAMHEADER in the dwReservedDriver array
567 padsh = (PACMDRVSTREAMHEADER)pash;
569 /* check that pointers have not been modified */
570 if (padsh->pbPreparedSrc != padsh->pbSrc ||
571 padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
572 padsh->pbPreparedDst != padsh->pbDst ||
573 padsh->cbPreparedDstLength < padsh->cbDstLength) {
574 return MMSYSERR_INVALPARAM;
577 padsh->fdwConvert = fdwConvert;
579 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CONVERT, (DWORD)&was->drvInst, (DWORD)padsh);
580 if (ret == MMSYSERR_NOERROR) {
581 padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_DONE;
583 TRACE("=> (%d)\n", ret);
584 return ret;
588 /***********************************************************************
589 * acmStreamPrepareHeader (MSACM32.41)
591 MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
592 DWORD fdwPrepare)
594 PWINE_ACMSTREAM was;
595 MMRESULT ret = MMSYSERR_NOERROR;
596 PACMDRVSTREAMHEADER padsh;
598 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwPrepare);
600 if ((was = ACM_GetStream(has)) == NULL)
601 return MMSYSERR_INVALHANDLE;
602 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
603 return MMSYSERR_INVALPARAM;
604 if (fdwPrepare)
605 ret = MMSYSERR_INVALFLAG;
607 if (pash->fdwStatus & ACMSTREAMHEADER_STATUSF_DONE)
608 return MMSYSERR_NOERROR;
610 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
611 * size. some fields are private to msacm internals, and are exposed
612 * in ACMSTREAMHEADER in the dwReservedDriver array
614 padsh = (PACMDRVSTREAMHEADER)pash;
616 padsh->fdwConvert = fdwPrepare;
617 padsh->padshNext = NULL;
618 padsh->fdwDriver = padsh->dwDriver = 0L;
620 padsh->fdwPrepared = 0;
621 padsh->dwPrepared = 0;
622 padsh->pbPreparedSrc = 0;
623 padsh->cbPreparedSrcLength = 0;
624 padsh->pbPreparedDst = 0;
625 padsh->cbPreparedDstLength = 0;
627 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_PREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
628 if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
629 ret = MMSYSERR_NOERROR;
630 padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE);
631 padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_PREPARED;
632 padsh->fdwPrepared = padsh->fdwStatus;
633 padsh->dwPrepared = 0;
634 padsh->pbPreparedSrc = padsh->pbSrc;
635 padsh->cbPreparedSrcLength = padsh->cbSrcLength;
636 padsh->pbPreparedDst = padsh->pbDst;
637 padsh->cbPreparedDstLength = padsh->cbDstLength;
638 } else {
639 padsh->fdwPrepared = 0;
640 padsh->dwPrepared = 0;
641 padsh->pbPreparedSrc = 0;
642 padsh->cbPreparedSrcLength = 0;
643 padsh->pbPreparedDst = 0;
644 padsh->cbPreparedDstLength = 0;
646 TRACE("=> (%d)\n", ret);
647 return ret;
650 /***********************************************************************
651 * acmStreamReset (MSACM32.42)
653 MMRESULT WINAPI acmStreamReset(HACMSTREAM has, DWORD fdwReset)
655 PWINE_ACMSTREAM was;
656 MMRESULT ret = MMSYSERR_NOERROR;
658 TRACE("(0x%08x, %ld)\n", has, fdwReset);
660 if (fdwReset) {
661 ret = MMSYSERR_INVALFLAG;
662 } else if ((was = ACM_GetStream(has)) == NULL) {
663 return MMSYSERR_INVALHANDLE;
664 } else if (was->drvInst.fdwOpen & ACM_STREAMOPENF_ASYNC) {
665 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_RESET, (DWORD)&was->drvInst, 0);
667 TRACE("=> (%d)\n", ret);
668 return ret;
671 /***********************************************************************
672 * acmStreamSize (MSACM32.43)
674 MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput,
675 LPDWORD pdwOutputBytes, DWORD fdwSize)
677 PWINE_ACMSTREAM was;
678 ACMDRVSTREAMSIZE adss;
679 MMRESULT ret;
681 TRACE("(0x%08x, %ld, %p, %ld)\n", has, cbInput, pdwOutputBytes, fdwSize);
683 if ((was = ACM_GetStream(has)) == NULL) {
684 return MMSYSERR_INVALHANDLE;
686 if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) {
687 return MMSYSERR_INVALFLAG;
690 *pdwOutputBytes = 0L;
692 switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
693 case ACM_STREAMSIZEF_DESTINATION:
694 adss.cbDstLength = cbInput;
695 adss.cbSrcLength = 0;
696 break;
697 case ACM_STREAMSIZEF_SOURCE:
698 adss.cbSrcLength = cbInput;
699 adss.cbDstLength = 0;
700 break;
701 default:
702 return MMSYSERR_INVALFLAG;
705 adss.cbStruct = sizeof(adss);
706 adss.fdwSize = fdwSize;
707 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_SIZE,
708 (DWORD)&was->drvInst, (DWORD)&adss);
709 if (ret == MMSYSERR_NOERROR) {
710 switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
711 case ACM_STREAMSIZEF_DESTINATION:
712 *pdwOutputBytes = adss.cbSrcLength;
713 break;
714 case ACM_STREAMSIZEF_SOURCE:
715 *pdwOutputBytes = adss.cbDstLength;
716 break;
719 TRACE("=> (%d) [%lu]\n", ret, *pdwOutputBytes);
720 return ret;
723 /***********************************************************************
724 * acmStreamUnprepareHeader (MSACM32.44)
726 MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
727 DWORD fdwUnprepare)
729 PWINE_ACMSTREAM was;
730 MMRESULT ret = MMSYSERR_NOERROR;
731 PACMDRVSTREAMHEADER padsh;
733 TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwUnprepare);
735 if ((was = ACM_GetStream(has)) == NULL)
736 return MMSYSERR_INVALHANDLE;
737 if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
738 return MMSYSERR_INVALPARAM;
740 if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
741 return ACMERR_UNPREPARED;
743 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
744 * size. some fields are private to msacm internals, and are exposed
745 * in ACMSTREAMHEADER in the dwReservedDriver array
747 padsh = (PACMDRVSTREAMHEADER)pash;
749 /* check that pointers have not been modified */
750 if (padsh->pbPreparedSrc != padsh->pbSrc ||
751 padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
752 padsh->pbPreparedDst != padsh->pbDst ||
753 padsh->cbPreparedDstLength < padsh->cbDstLength) {
754 return MMSYSERR_INVALPARAM;
757 padsh->fdwConvert = fdwUnprepare;
759 ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_UNPREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
760 if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
761 ret = MMSYSERR_NOERROR;
762 padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE|ACMSTREAMHEADER_STATUSF_PREPARED);
764 TRACE("=> (%d)\n", ret);
765 return ret;