Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

afl.c

00001 /**************************************************************************
00002 
00003 
00004   This file will contain an interface to ACM drivers.
00005   Its content will be based mainly on wine/dlls/msacm32
00006   actually, for audio decompression only the following functions
00007   are needed:
00008   
00009   acmStreamOpen ( takes formats of src and dest, returns stream handle )
00010   acmStreamPrepareHeader ( takes stream handler and info on data )
00011   acmStreamConvert ( the same as PrepareHeader )
00012   acmStreamUnprepareHeader
00013   acmStreamClose
00014   acmStreamSize
00015   maybe acmStreamReset
00016   
00017   In future I'll also add functions for format enumeration, 
00018   but not right now.
00019 
00020   Modified for use with MPlayer, detailed CVS changelog at
00021   http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
00022   $Id: afl.c 11593 2005-06-28 18:02:01Z courmisch $
00023   
00024 ***************************************************************************/
00025 #include "config.h"
00026 
00027 #include "wine/winbase.h"
00028 #include "wine/windef.h"
00029 #include "wine/winuser.h"
00030 #include "wine/vfw.h"
00031 #include "wine/winestring.h"
00032 #include "wine/driver.h"
00033 #include "wine/winerror.h"
00034 #include "wine/msacm.h"
00035 #include "wine/msacmdrv.h"
00036 #include "wineacm.h"
00037 #ifndef __MINGW32__
00038 #include "ext.h"
00039 #endif
00040 #include "driver.h"
00041 
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <string.h>
00045 #pragma pack(1)
00046 #define OpenDriverA DrvOpen
00047 #define CloseDriver DrvClose
00048 
00049 static inline PWINE_ACMSTREAM ACM_GetStream(HACMSTREAM has)
00050 {
00051     return (PWINE_ACMSTREAM)has;
00052 }
00053 
00054 /***********************************************************************
00055  *           acmDriverAddA (MSACM32.2)
00056  */
00057 MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule,
00058                               LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
00059 {
00060     if (!phadid)
00061         return MMSYSERR_INVALPARAM;
00062     
00063     /* Check if any unknown flags */
00064     if (fdwAdd & 
00065         ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND|
00066           ACM_DRIVERADDF_GLOBAL))
00067         return MMSYSERR_INVALFLAG;
00068     
00069     /* Check if any incompatible flags */
00070     if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) && 
00071         (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND))
00072         return MMSYSERR_INVALFLAG;
00073     
00074     /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a 
00075      * LoadDriver on it, to be sure we can call SendDriverMessage on the
00076      * hDrvr handle.
00077      */
00078     *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, 0, hinstModule);
00079     
00080     /* FIXME: lParam, dwPriority and fdwAdd ignored */
00081     
00082     return MMSYSERR_NOERROR;
00083 }
00084 
00085 /***********************************************************************
00086  *           acmDriverClose (MSACM32.4)
00087  */
00088 MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
00089 {
00090     PWINE_ACMDRIVER  p;
00091     PWINE_ACMDRIVER* tp;
00092     
00093     if (fdwClose)
00094         return MMSYSERR_INVALFLAG;
00095     
00096     p = MSACM_GetDriver(had);
00097     if (!p)
00098         return MMSYSERR_INVALHANDLE;
00099 
00100     for (tp = &(p->obj.pACMDriverID->pACMDriverList); *tp; *tp = (*tp)->pNextACMDriver) {
00101         if (*tp == p) {
00102             *tp = (*tp)->pNextACMDriver;
00103             break;
00104         }
00105     }
00106     
00107     if (p->hDrvr && !p->obj.pACMDriverID->pACMDriverList)
00108         CloseDriver(p->hDrvr);
00109     
00110     HeapFree(MSACM_hHeap, 0, p);
00111     
00112     return MMSYSERR_NOERROR;
00113 }
00114 
00115 /***********************************************************************
00116  *           acmDriverEnum (MSACM32.7)
00117  */
00118 MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)
00119 {
00120     PWINE_ACMDRIVERID   p;
00121     DWORD               fdwSupport;
00122 
00123     if (!fnCallback) {
00124         return MMSYSERR_INVALPARAM;
00125     }
00126     
00127     if (fdwEnum && ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED)) {
00128         return MMSYSERR_INVALFLAG;
00129     }
00130     
00131     for (p = MSACM_pFirstACMDriverID; p; p = p->pNextACMDriverID) {
00132         fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
00133         if (!p->bEnabled) {
00134             if (fdwEnum & ACM_DRIVERENUMF_DISABLED)
00135                 fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
00136             else
00137                 continue;
00138         }
00139         (*fnCallback)((HACMDRIVERID) p, dwInstance, fdwSupport);
00140     }
00141     
00142     return MMSYSERR_NOERROR;
00143 }
00144 
00145 /***********************************************************************
00146  *           acmDriverID (MSACM32.8)
00147  */
00148 MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID)
00149 {
00150     PWINE_ACMOBJ pao;
00151     
00152     pao = MSACM_GetObj(hao);
00153     if (!pao)
00154         return MMSYSERR_INVALHANDLE;
00155     
00156     if (!phadid)
00157         return MMSYSERR_INVALPARAM;
00158     
00159     if (fdwDriverID)
00160         return MMSYSERR_INVALFLAG;
00161     
00162     *phadid = (HACMDRIVERID) pao->pACMDriverID;
00163     
00164     return MMSYSERR_NOERROR;
00165 }
00166 
00167 /***********************************************************************
00168  *           acmDriverMessage (MSACM32.9)
00169  * FIXME
00170  *   Not implemented
00171  */
00172 LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
00173 {
00174     PWINE_ACMDRIVER pad = MSACM_GetDriver(had);
00175     if (!pad)
00176         return MMSYSERR_INVALPARAM;
00177     
00178     /* FIXME: Check if uMsg legal */
00179     
00180     if (!SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2))
00181         return MMSYSERR_NOTSUPPORTED;
00182     
00183     return MMSYSERR_NOERROR;
00184 }
00185 
00186 
00187 /***********************************************************************
00188  *           acmDriverOpen (MSACM32.10)
00189  */
00190 MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
00191 {
00192     PWINE_ACMDRIVERID   padid;
00193     PWINE_ACMDRIVER     pad;
00194     ICOPEN              icopen;
00195     HDRVR               hdrv;
00196 
00197 
00198     TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen);
00199 
00200     if (!phad)
00201         return MMSYSERR_INVALPARAM;
00202     
00203     padid = MSACM_GetDriverID(hadid); 
00204     if (!padid)
00205         return MMSYSERR_INVALHANDLE;
00206     
00207     if (fdwOpen)
00208         return MMSYSERR_INVALFLAG;
00209     
00210     pad = (PWINE_ACMDRIVER) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
00211     if (!pad)
00212         return MMSYSERR_NOMEM;
00213 
00214     pad->obj.pACMDriverID = padid;
00215     icopen.fccType              = mmioFOURCC('a', 'u', 'd', 'c');
00216     icopen.fccHandler           = (long)padid->pszFileName;
00217     icopen.dwSize               = sizeof(ICOPEN);
00218     icopen.dwFlags              = 0;
00219 
00220     icopen.pV1Reserved = padid->pszFileName;
00221     if (!padid->hInstModule)
00222         pad->hDrvr = OpenDriverA((long)&icopen);
00223     else
00224         pad->hDrvr = padid->hInstModule;
00225     
00226     if (!pad->hDrvr) {
00227         HeapFree(MSACM_hHeap, 0, pad);
00228         return MMSYSERR_ERROR;
00229     }
00230 
00231     pad->pfnDriverProc = GetProcAddress(pad->hDrvr, "DriverProc");
00232 
00233     /* insert new pad at beg of list */
00234     pad->pNextACMDriver = padid->pACMDriverList;
00235     padid->pACMDriverList = pad;
00236 
00237     /* FIXME: Create a WINE_ACMDRIVER32 */
00238     *phad = (HACMDRIVER)pad;
00239 
00240     return MMSYSERR_NOERROR;
00241 }
00242 
00243 /***********************************************************************
00244  *           acmDriverRemove (MSACM32.12)
00245  */
00246 MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
00247 {
00248     PWINE_ACMDRIVERID padid;
00249     
00250     padid = MSACM_GetDriverID(hadid);
00251     if (!padid)
00252         return MMSYSERR_INVALHANDLE;
00253     
00254     if (fdwRemove)
00255         return MMSYSERR_INVALFLAG;
00256     
00257     MSACM_UnregisterDriver(padid);
00258     
00259     return MMSYSERR_NOERROR;
00260 }
00261 
00262 
00263 
00264 /**********************************************************************/
00265 
00266 HANDLE MSACM_hHeap = (HANDLE) NULL;
00267 PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL;
00268 PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL;
00269 
00270 /***********************************************************************
00271  *           MSACM_RegisterDriver32() 
00272  */
00273 PWINE_ACMDRIVERID MSACM_RegisterDriver(const char* pszFileName,
00274                                        WORD wFormatTag,
00275                                        HINSTANCE hinstModule)
00276 {
00277     PWINE_ACMDRIVERID padid;
00278 
00279     TRACE("('%s', '%x', 0x%08x)\n", pszFileName, wFormatTag, hinstModule);
00280 
00281 #ifndef WIN32_LOADER
00282         MSACM_hHeap = GetProcessHeap();
00283 #endif
00284     padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID));
00285     padid->pszFileName = (char*)malloc(strlen(pszFileName)+1);
00286     strcpy(padid->pszFileName, pszFileName);
00287 //    1~strdup(pszDriverAlias);
00288     padid->wFormatTag = wFormatTag;
00289     padid->hInstModule = hinstModule;
00290     padid->bEnabled = TRUE;
00291     padid->pACMDriverList = NULL;
00292     padid->pNextACMDriverID = NULL;
00293     padid->pPrevACMDriverID = MSACM_pLastACMDriverID;
00294     if (MSACM_pLastACMDriverID)
00295         MSACM_pLastACMDriverID->pNextACMDriverID = padid;
00296     MSACM_pLastACMDriverID = padid;
00297     if (!MSACM_pFirstACMDriverID)
00298         MSACM_pFirstACMDriverID = padid;
00299     
00300     return padid;
00301 }
00302 
00303 
00304 /***********************************************************************
00305  *           MSACM_UnregisterDriver32()
00306  */
00307 PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p)
00308 {
00309     PWINE_ACMDRIVERID pNextACMDriverID;
00310     
00311     while (p->pACMDriverList)
00312         acmDriverClose((HACMDRIVER) p->pACMDriverList, 0);
00313     
00314     if (p->pszFileName)
00315         free(p->pszFileName);
00316     
00317     if (p == MSACM_pFirstACMDriverID)
00318         MSACM_pFirstACMDriverID = p->pNextACMDriverID;
00319     if (p == MSACM_pLastACMDriverID)
00320         MSACM_pLastACMDriverID = p->pPrevACMDriverID;
00321 
00322     if (p->pPrevACMDriverID)
00323         p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
00324     if (p->pNextACMDriverID)
00325         p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID;
00326     
00327     pNextACMDriverID = p->pNextACMDriverID;
00328     
00329     HeapFree(MSACM_hHeap, 0, p);
00330     
00331     return pNextACMDriverID;
00332 }
00333 
00334 /***********************************************************************
00335  *           MSACM_UnregisterAllDrivers32()
00336  * FIXME
00337  *   Where should this function be called?
00338  */
00339 void MSACM_UnregisterAllDrivers(void)
00340 {
00341     PWINE_ACMDRIVERID p;
00342 
00343     for (p = MSACM_pFirstACMDriverID; p; p = MSACM_UnregisterDriver(p));
00344 }
00345 
00346 /***********************************************************************
00347  *           MSACM_GetDriverID32() 
00348  */
00349 PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID)
00350 {
00351     return (PWINE_ACMDRIVERID)hDriverID;
00352 }
00353 
00354 /***********************************************************************
00355  *           MSACM_GetDriver32()
00356  */
00357 PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver)
00358 {
00359     return (PWINE_ACMDRIVER)hDriver;
00360 }
00361 
00362 /***********************************************************************
00363  *           MSACM_GetObj32()
00364  */
00365 PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj)
00366 {
00367     return (PWINE_ACMOBJ)hObj;
00368 }
00369 
00370 
00371 
00372 /***********************************************************************
00373  *           acmStreamOpen (MSACM32.40)
00374  */
00375 MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
00376                               PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback,
00377                               DWORD dwInstance, DWORD fdwOpen)
00378 {
00379     PWINE_ACMSTREAM     was;
00380     PWINE_ACMDRIVER     wad;
00381     MMRESULT            ret;
00382     int                 wfxSrcSize;
00383     int                 wfxDstSize;
00384     
00385     TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
00386           phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen);
00387 
00388     TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n", 
00389           pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec, 
00390           pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize);
00391 
00392     TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n", 
00393           pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec, 
00394           pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize);
00395 
00396 #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
00397     wfxSrcSize = SIZEOF_WFX(pwfxSrc);
00398     wfxDstSize = SIZEOF_WFX(pwfxDst);
00399 #undef SIZEOF_WFX
00400 
00401     was = (PWINE_ACMSTREAM) HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize + ((pwfltr) ? sizeof(WAVEFILTER) : 0));
00402     if (was == NULL)
00403         return MMSYSERR_NOMEM;
00404     was->drvInst.cbStruct = sizeof(was->drvInst);
00405     was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was));
00406     memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize);
00407     // LHACM is checking for 0x1
00408     // but if this will not help
00409     // was->drvInst.pwfxSrc->wFormatTag = 1;
00410     was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was) + wfxSrcSize);
00411     memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize);
00412     if (pwfltr) {
00413         was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)was + sizeof(*was) + wfxSrcSize + wfxDstSize);
00414         memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER));
00415     } else {
00416         was->drvInst.pwfltr = NULL;
00417     }
00418     was->drvInst.dwCallback = dwCallback;    
00419     was->drvInst.dwInstance = dwInstance;
00420     was->drvInst.fdwOpen = fdwOpen;
00421     was->drvInst.fdwDriver = 0L;  
00422     was->drvInst.dwDriver = 0L;     
00423     was->drvInst.has = (HACMSTREAM)was;
00424     
00425     if (had) {
00426         if (!(wad = MSACM_GetDriver(had))) {
00427             ret = MMSYSERR_INVALPARAM;
00428             goto errCleanUp;
00429         }
00430         
00431         was->obj.pACMDriverID = wad->obj.pACMDriverID;
00432         was->pDrv = wad;
00433         was->hAcmDriver = 0; /* not to close it in acmStreamClose */
00434 
00435         ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
00436         if (ret != MMSYSERR_NOERROR)
00437             goto errCleanUp;
00438     } else {
00439         PWINE_ACMDRIVERID wadi;
00440         short drv_tag;
00441         ret = ACMERR_NOTPOSSIBLE;
00442 /*      if(pwfxSrc->wFormatTag==1)//compression
00443             drv_tag=pwfxDst->wFormatTag;
00444             else
00445             if(pwfxDst->wFormatTag==1)//decompression
00446                 drv_tag=pwfxSrc->wFormatTag;
00447                 else
00448                 goto errCleanUp;
00449 
00450             ret=acmDriverOpen2(drv_tag); 
00451             if (ret == MMSYSERR_NOERROR) {
00452                 if ((wad = MSACM_GetDriver(had)) != 0) {
00453                     was->obj.pACMDriverID = wad->obj.pACMDriverID;
00454                     was->pDrv = wad;
00455                     was->hAcmDriver = had;
00456                     
00457                     ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
00458                     if (ret == MMSYSERR_NOERROR) {
00459                         if (fdwOpen & ACM_STREAMOPENF_QUERY) {
00460                             acmDriverClose(had, 0L);
00461                         }
00462                         break;
00463                     }
00464                 }
00465                 acmDriverClose(had, 0L);*/
00466         //if(MSACM_pFirstACMDriverID==NULL)
00467         //    MSACM_RegisterAllDrivers();
00468         
00469         for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID)
00470         {
00471             /* Check Format */
00472             if ((int)wadi->wFormatTag != (int)pwfxSrc->wFormatTag) continue;
00473 
00474             ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L);
00475             if (ret == MMSYSERR_NOERROR) {
00476                 if ((wad = MSACM_GetDriver(had)) != 0) {
00477                     was->obj.pACMDriverID = wad->obj.pACMDriverID;
00478                     was->pDrv = wad;
00479                     was->hAcmDriver = had;
00480                     
00481                     ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
00482                     //lhacm - crash printf("RETOPEN %d\n", ret);
00483                     //ret = 0;
00484                     if (ret == MMSYSERR_NOERROR) {
00485                         if (fdwOpen & ACM_STREAMOPENF_QUERY) {
00486                             acmDriverClose(had, 0L);
00487                         }
00488                         break;
00489                     }
00490                 }
00491                 // no match, close this acm driver and try next one 
00492                 acmDriverClose(had, 0L);
00493             }
00494         }
00495         if (ret != MMSYSERR_NOERROR) {
00496             ret = ACMERR_NOTPOSSIBLE;
00497             goto errCleanUp;
00498         }
00499     }
00500     ret = MMSYSERR_NOERROR;
00501     if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) {
00502         if (phas)
00503             *phas = (HACMSTREAM)was;
00504         TRACE("=> (%d)\n", ret);
00505 #ifdef WIN32_LOADER
00506         CodecAlloc();
00507 #endif
00508         return ret;
00509     }
00510 errCleanUp:             
00511     if (phas)
00512         *phas = (HACMSTREAM)0;
00513     HeapFree(MSACM_hHeap, 0, was);
00514     TRACE("=> (%d)\n", ret);
00515     return ret;
00516 }
00517 
00518 
00519 MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose)
00520 {
00521     PWINE_ACMSTREAM     was;
00522     MMRESULT            ret;
00523                 
00524     TRACE("(0x%08x, %ld)\n", has, fdwClose);
00525     
00526     if ((was = ACM_GetStream(has)) == NULL) {
00527         return MMSYSERR_INVALHANDLE;
00528     }
00529     ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0);
00530     if (ret == MMSYSERR_NOERROR) {
00531         if (was->hAcmDriver)
00532             acmDriverClose(was->hAcmDriver, 0L);        
00533         HeapFree(MSACM_hHeap, 0, was);
00534 #ifdef WIN32_LOADER
00535         CodecRelease();
00536 #endif
00537     }
00538     TRACE("=> (%d)\n", ret);
00539     return ret;
00540 }
00541 
00542 /***********************************************************************
00543  *           acmStreamConvert (MSACM32.38)
00544  */
00545 MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash, 
00546                                  DWORD fdwConvert)
00547 {
00548     PWINE_ACMSTREAM     was;
00549     MMRESULT            ret = MMSYSERR_NOERROR;
00550     PACMDRVSTREAMHEADER padsh;
00551 
00552     TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwConvert);
00553 
00554     if ((was = ACM_GetStream(has)) == NULL)
00555         return MMSYSERR_INVALHANDLE;
00556     if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
00557         return MMSYSERR_INVALPARAM;
00558 
00559     if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
00560         return ACMERR_UNPREPARED;
00561 
00562     /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
00563      * size. some fields are private to msacm internals, and are exposed
00564      * in ACMSTREAMHEADER in the dwReservedDriver array
00565      */
00566     padsh = (PACMDRVSTREAMHEADER)pash;
00567 
00568     /* check that pointers have not been modified */
00569     if (padsh->pbPreparedSrc != padsh->pbSrc ||
00570         padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
00571         padsh->pbPreparedDst != padsh->pbDst ||
00572         padsh->cbPreparedDstLength < padsh->cbDstLength) {
00573         return MMSYSERR_INVALPARAM;
00574     }   
00575 
00576     padsh->fdwConvert = fdwConvert;
00577 
00578     ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CONVERT, (DWORD)&was->drvInst, (DWORD)padsh);
00579     if (ret == MMSYSERR_NOERROR) {
00580         padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_DONE;
00581     }
00582     TRACE("=> (%d)\n", ret);
00583     return ret;
00584 }
00585 
00586 
00587 /***********************************************************************
00588  *           acmStreamPrepareHeader (MSACM32.41)
00589  */
00590 MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash, 
00591                                        DWORD fdwPrepare)
00592 {
00593     PWINE_ACMSTREAM     was;
00594     MMRESULT            ret = MMSYSERR_NOERROR;
00595     PACMDRVSTREAMHEADER padsh;
00596 
00597     TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwPrepare);
00598     
00599     if ((was = ACM_GetStream(has)) == NULL)
00600         return MMSYSERR_INVALHANDLE;
00601     if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
00602         return MMSYSERR_INVALPARAM;
00603     if (fdwPrepare)
00604         ret = MMSYSERR_INVALFLAG;
00605 
00606     if (pash->fdwStatus & ACMSTREAMHEADER_STATUSF_DONE)
00607         return MMSYSERR_NOERROR;
00608 
00609     /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
00610      * size. some fields are private to msacm internals, and are exposed
00611      * in ACMSTREAMHEADER in the dwReservedDriver array
00612      */
00613     padsh = (PACMDRVSTREAMHEADER)pash;
00614 
00615     padsh->fdwConvert = fdwPrepare;
00616     padsh->padshNext = NULL;
00617     padsh->fdwDriver = padsh->dwDriver = 0L;
00618 
00619     padsh->fdwPrepared = 0;
00620     padsh->dwPrepared = 0;
00621     padsh->pbPreparedSrc = 0;
00622     padsh->cbPreparedSrcLength = 0;
00623     padsh->pbPreparedDst = 0;
00624     padsh->cbPreparedDstLength = 0;
00625 
00626     ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_PREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
00627     if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
00628         ret = MMSYSERR_NOERROR;
00629         padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE);
00630         padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_PREPARED;
00631         padsh->fdwPrepared = padsh->fdwStatus;
00632         padsh->dwPrepared = 0;
00633         padsh->pbPreparedSrc = padsh->pbSrc;
00634         padsh->cbPreparedSrcLength = padsh->cbSrcLength;
00635         padsh->pbPreparedDst = padsh->pbDst;
00636         padsh->cbPreparedDstLength = padsh->cbDstLength;
00637     } else {
00638         padsh->fdwPrepared = 0;
00639         padsh->dwPrepared = 0;
00640         padsh->pbPreparedSrc = 0;
00641         padsh->cbPreparedSrcLength = 0;
00642         padsh->pbPreparedDst = 0;
00643         padsh->cbPreparedDstLength = 0;
00644     }
00645     TRACE("=> (%d)\n", ret);
00646     return ret;
00647 }
00648 
00649 /***********************************************************************
00650  *           acmStreamReset (MSACM32.42)
00651  */
00652 MMRESULT WINAPI acmStreamReset(HACMSTREAM has, DWORD fdwReset)
00653 {
00654     PWINE_ACMSTREAM     was;
00655     MMRESULT            ret = MMSYSERR_NOERROR;
00656 
00657     TRACE("(0x%08x, %ld)\n", has, fdwReset);
00658 
00659     if (fdwReset) {
00660         ret = MMSYSERR_INVALFLAG;
00661     } else if ((was = ACM_GetStream(has)) == NULL) {
00662         return MMSYSERR_INVALHANDLE;
00663     } else if (was->drvInst.fdwOpen & ACM_STREAMOPENF_ASYNC) {
00664         ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_RESET, (DWORD)&was->drvInst, 0);
00665     }
00666     TRACE("=> (%d)\n", ret);
00667     return ret;
00668 }
00669 
00670 /***********************************************************************
00671  *           acmStreamSize (MSACM32.43)
00672  */
00673 MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput, 
00674                               LPDWORD pdwOutputBytes, DWORD fdwSize)
00675 {
00676     PWINE_ACMSTREAM     was;
00677     ACMDRVSTREAMSIZE    adss;
00678     MMRESULT            ret;
00679     
00680     TRACE("(0x%08x, %ld, %p, %ld)\n", has, cbInput, pdwOutputBytes, fdwSize);
00681     
00682     if ((was = ACM_GetStream(has)) == NULL) {
00683         return MMSYSERR_INVALHANDLE;
00684     }
00685     if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) {
00686         return MMSYSERR_INVALFLAG;
00687     }
00688 
00689     *pdwOutputBytes = 0L;
00690     
00691     switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
00692     case ACM_STREAMSIZEF_DESTINATION:
00693         adss.cbDstLength = cbInput;
00694         adss.cbSrcLength = 0;
00695         break;
00696     case ACM_STREAMSIZEF_SOURCE:
00697         adss.cbSrcLength = cbInput;
00698         adss.cbDstLength = 0;
00699         break;
00700     default:    
00701         return MMSYSERR_INVALFLAG;
00702     }
00703     
00704     adss.cbStruct = sizeof(adss);
00705     adss.fdwSize = fdwSize;
00706     ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_SIZE, 
00707                             (DWORD)&was->drvInst, (DWORD)&adss);
00708     if (ret == MMSYSERR_NOERROR) {
00709         switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
00710         case ACM_STREAMSIZEF_DESTINATION:
00711             *pdwOutputBytes = adss.cbSrcLength;
00712             break;
00713         case ACM_STREAMSIZEF_SOURCE:
00714             *pdwOutputBytes = adss.cbDstLength;
00715             break;
00716         }
00717     }
00718     TRACE("=> (%d) [%lu]\n", ret, *pdwOutputBytes);
00719     return ret;
00720 }
00721 
00722 /***********************************************************************
00723  *           acmStreamUnprepareHeader (MSACM32.44)
00724  */
00725 MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash, 
00726                                          DWORD fdwUnprepare)
00727 {
00728     PWINE_ACMSTREAM     was;
00729     MMRESULT            ret = MMSYSERR_NOERROR;
00730     PACMDRVSTREAMHEADER padsh;
00731 
00732     TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwUnprepare);
00733     
00734     if ((was = ACM_GetStream(has)) == NULL)
00735         return MMSYSERR_INVALHANDLE;
00736     if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
00737         return MMSYSERR_INVALPARAM;
00738 
00739     if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
00740         return ACMERR_UNPREPARED;
00741 
00742     /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
00743      * size. some fields are private to msacm internals, and are exposed
00744      * in ACMSTREAMHEADER in the dwReservedDriver array
00745      */
00746     padsh = (PACMDRVSTREAMHEADER)pash;
00747 
00748     /* check that pointers have not been modified */
00749     if (padsh->pbPreparedSrc != padsh->pbSrc ||
00750         padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
00751         padsh->pbPreparedDst != padsh->pbDst ||
00752         padsh->cbPreparedDstLength < padsh->cbDstLength) {
00753         return MMSYSERR_INVALPARAM;
00754     }   
00755 
00756     padsh->fdwConvert = fdwUnprepare;
00757 
00758     ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_UNPREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
00759     if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
00760         ret = MMSYSERR_NOERROR;
00761         padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE|ACMSTREAMHEADER_STATUSF_PREPARED);
00762     }
00763     TRACE("=> (%d)\n", ret);
00764     return ret;
00765 }

Generated on Tue Dec 20 10:14:20 2005 for vlc-0.8.4a by  doxygen 1.4.2