VirtualBox

Changeset 68597 in vbox


Ignore:
Timestamp:
Sep 1, 2017 11:40:56 AM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
117820
Message:

Audio/DrvHostDSound.cpp: Integrated r117818 from 5.1 into trunk.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DrvHostDSound.cpp

    r68272 r68597  
    8282typedef HRESULT WINAPI FNDIRECTSOUNDCAPTUREENUMERATEW(LPDSENUMCALLBACKW pDSEnumCallback, PVOID pContext);
    8383typedef FNDIRECTSOUNDCAPTUREENUMERATEW *PFNDIRECTSOUNDCAPTUREENUMERATEW;
     84typedef HRESULT WINAPI FNDIRECTSOUNDCAPTURECREATE8(LPCGUID lpcGUID, LPDIRECTSOUNDCAPTURE8 *lplpDSC, LPUNKNOWN pUnkOuter);
     85typedef FNDIRECTSOUNDCAPTURECREATE8 *PFNDIRECTSOUNDCAPTURECREATE8;
    8486
    8587#ifdef VBOX_WITH_AUDIO_DEVICE_CALLBACKS
     
    110112    /** Buffer alignment. */
    111113    uint8_t            uAlign;
     114    /** Whether this stream is in an enable state on the DirectSound side. */
     115    bool               fEnabled;
    112116    union
    113117    {
    114118        struct
    115119        {
    116             LPDIRECTSOUNDCAPTURE8       pDSC;
    117120            LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB;
    118121            DWORD                       offCaptureBufRead;
    119122            DWORD                       cbCaptureBuf;
    120123            HRESULT                     hrLastCapture;
    121             bool                        fEnabled;
    122124        } In;
    123125        struct
    124126        {
    125             LPDIRECTSOUND8              pDS;     /** @todo Move this out of this structure! Not required per-stream (e.g. for multi-channel). */
    126127            LPDIRECTSOUNDBUFFER8        pDSB;
    127128            DWORD                       offPlayWritePos;
    128129            DWORD                       cbPlayBuf;
    129             bool                        fEnabled;
    130130            bool                        fRestartPlayback;
    131131        } Out;
     
    136136{
    137137    /** Pointer to the driver instance structure. */
    138     PPDMDRVINS          pDrvIns;
     138    PPDMDRVINS              pDrvIns;
    139139    /** Our audio host audio interface. */
    140     PDMIHOSTAUDIO       IHostAudio;
     140    PDMIHOSTAUDIO           IHostAudio;
    141141    /** List of found host input devices. */
    142     RTLISTANCHOR        lstDevInput;
     142    RTLISTANCHOR            lstDevInput;
    143143    /** List of found host output devices. */
    144     RTLISTANCHOR        lstDevOutput;
     144    RTLISTANCHOR            lstDevOutput;
    145145    /** DirectSound configuration options. */
    146     DSOUNDHOSTCFG       cfg;
     146    DSOUNDHOSTCFG           cfg;
    147147    /** Whether this backend supports any audio input. */
    148     bool                fEnabledIn;
     148    bool                    fEnabledIn;
    149149    /** Whether this backend supports any audio output. */
    150     bool                fEnabledOut;
     150    bool                    fEnabledOut;
     151    /** The Direct Sound playback interface. */
     152    LPDIRECTSOUND8          pDS;
     153    /** The Direct Sound capturing interface. */
     154    LPDIRECTSOUNDCAPTURE8   pDSC;
    151155#ifdef VBOX_WITH_AUDIO_DEVICE_CALLBACKS
    152156    /** Pointer to the audio connector interface of the driver/device above us. */
    153     PPDMIAUDIOCONNECTOR pUpIAudioConnector;
     157    PPDMIAUDIOCONNECTOR     pUpIAudioConnector;
    154158    /** Stopped indicator. */
    155     bool                fStopped;
     159    bool                    fStopped;
    156160    /** Shutdown indicator. */
    157     bool                fShutdown;
     161    bool                    fShutdown;
    158162    /** Notification thread. */
    159     RTTHREAD            Thread;
     163    RTTHREAD                Thread;
    160164    /** Array of events to wait for in notification thread. */
    161     HANDLE              aEvents[VBOX_DSOUND_MAX_EVENTS];
     165    HANDLE                  aEvents[VBOX_DSOUND_MAX_EVENTS];
    162166    /** Number of events to wait for in notification thread.
    163167     *  Must not exceed VBOX_DSOUND_MAX_EVENTS. */
    164     uint8_t             cEvents;
     168    uint8_t                 cEvents;
    165169    /** Pointer to the input stream. */
    166     PDSOUNDSTREAM       pDSStrmIn;
     170    PDSOUNDSTREAM           pDSStrmIn;
    167171    /** Pointer to the output stream. */
    168     PDSOUNDSTREAM       pDSStrmOut;
     172    PDSOUNDSTREAM           pDSStrmOut;
    169173#endif
    170174} DRVHOSTDSOUND, *PDRVHOSTDSOUND;
     
    207211static int      dsoundNotifyThread(PDRVHOSTDSOUND pThis, bool fShutdown);
    208212#endif
    209 
     213static void     dsoundUpdateStatusInternal(PDRVHOSTDSOUND pThis);
     214static void     dsoundUpdateStatusInternalEx(PDRVHOSTDSOUND pThis, PPDMAUDIOBACKENDCFG pCfg, uint32_t fEnum);
    210215
    211216
     
    332337    AssertPtrReturnVoid(pThis);
    333338
    334     PDSOUNDDEV pDev;
    335     while (!RTListIsEmpty(&pThis->lstDevInput))
    336     {
    337         pDev = RTListGetFirst(&pThis->lstDevInput, DSOUNDDEV, Node);
     339    PDSOUNDDEV pDev, pDevNext;
     340    RTListForEachSafe(&pThis->lstDevInput, pDev, pDevNext, DSOUNDDEV, Node)
    338341        dsoundDeviceRemove(pDev);
    339     }
    340 
    341     while (!RTListIsEmpty(&pThis->lstDevOutput))
    342     {
    343         pDev = RTListGetFirst(&pThis->lstDevOutput, DSOUNDDEV, Node);
     342
     343    Assert(RTListIsEmpty(&pThis->lstDevInput));
     344
     345    RTListForEachSafe(&pThis->lstDevOutput, pDev, pDevNext, DSOUNDDEV, Node)
    344346        dsoundDeviceRemove(pDev);
    345     }
     347
     348    Assert(RTListIsEmpty(&pThis->lstDevOutput));
    346349}
    347350
     
    457460 */
    458461
    459 static void directSoundPlayInterfaceRelease(PDSOUNDSTREAM pStreamDS)
    460 {
    461     if (pStreamDS->Out.pDS)
    462     {
    463         IDirectSound8_Release(pStreamDS->Out.pDS);
    464         pStreamDS->Out.pDS = NULL;
    465     }
    466 }
    467 
    468 
    469 static HRESULT directSoundPlayInterfaceCreate(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS)
    470 {
    471     AssertPtrReturn(pThis,     E_POINTER);
    472     AssertPtrReturn(pStreamDS, E_POINTER);
    473 
    474     if (pStreamDS->Out.pDS != NULL)
    475     {
    476         DSLOG(("DSound: DirectSound instance already exists\n"));
     462static void directSoundPlayInterfaceDestroy(PDRVHOSTDSOUND pThis)
     463{
     464    if (pThis->pDS)
     465    {
     466        LogFlowFuncEnter();
     467
     468        IDirectSound8_Release(pThis->pDS);
     469        pThis->pDS = NULL;
     470    }
     471}
     472
     473
     474static HRESULT directSoundPlayInterfaceCreate(PDRVHOSTDSOUND pThis)
     475{
     476    if (pThis->pDS != NULL)
    477477        return S_OK;
    478     }
     478
     479    LogFlowFuncEnter();
    479480
    480481    HRESULT hr = CoCreateInstance(CLSID_DirectSound8, NULL, CLSCTX_ALL,
    481                                   IID_IDirectSound8, (void **)&pStreamDS->Out.pDS);
     482                                  IID_IDirectSound8, (void **)&pThis->pDS);
    482483    if (FAILED(hr))
    483484    {
     
    486487    else
    487488    {
    488         hr = IDirectSound8_Initialize(pStreamDS->Out.pDS, pThis->cfg.pGuidPlay);
     489        hr = IDirectSound8_Initialize(pThis->pDS, pThis->cfg.pGuidPlay);
    489490        if (SUCCEEDED(hr))
    490491        {
    491492            HWND hWnd = GetDesktopWindow();
    492             hr = IDirectSound8_SetCooperativeLevel(pStreamDS->Out.pDS, hWnd, DSSCL_PRIORITY);
     493            hr = IDirectSound8_SetCooperativeLevel(pThis->pDS, hWnd, DSSCL_PRIORITY);
    493494            if (FAILED(hr))
    494495                DSLOGREL(("DSound: Setting cooperative level for window %p failed with %Rhrc\n", hWnd, hr));
     
    502503                DSLOGREL(("DSound: DirectSound playback initialization failed with %Rhrc\n", hr));
    503504
    504             directSoundPlayInterfaceRelease(pStreamDS);
    505         }
    506     }
    507 
     505            directSoundPlayInterfaceDestroy(pThis);
     506        }
     507    }
     508
     509    LogFlowFunc(("Returning %Rhrc\n", hr));
    508510    return hr;
    509511}
     
    542544            pStreamDS->Out.pDSB = NULL;
    543545        }
    544         else
    545             DSLOGREL(("DSound: Stop playback stream %p when closing %Rhrc\n", pStreamDS, hr));
    546     }
    547 
    548     if (SUCCEEDED(hr))
    549         directSoundPlayInterfaceRelease(pStreamDS);
     546    }
     547
     548    if (FAILED(hr))
     549        DSLOGREL(("DSound: Stopping playback stream %p failed with %Rhrc\n", pStreamDS, hr));
    550550
    551551    return hr;
     
    580580        return E_INVALIDARG;
    581581
    582     HRESULT hr = directSoundPlayInterfaceCreate(pThis, pStreamDS);
     582    directSoundPlayInterfaceDestroy(pThis);
     583
     584    dsoundUpdateStatusInternal(pThis);
     585
     586    HRESULT hr = directSoundPlayInterfaceCreate(pThis);
    583587    if (FAILED(hr))
    584588        return hr;
     
    610614        bd.dwBufferBytes = pThis->cfg.cbBufferOut;
    611615
    612         hr = IDirectSound8_CreateSoundBuffer(pStreamDS->Out.pDS, &bd, &pDSB, NULL);
     616        hr = IDirectSound8_CreateSoundBuffer(pThis->pDS, &bd, &pDSB, NULL);
    613617        if (FAILED(hr))
    614618        {
     
    812816    AssertPtrReturn(pStreamDS, E_POINTER);
    813817
    814     HRESULT hr;
    815 
    816     if (pStreamDS->Out.pDSB != NULL)
    817     {
    818         DSLOG(("DSound: Stopping playback\n"));
    819 
    820         HRESULT hr2 = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB);
    821         if (FAILED(hr2))
    822         {
    823             hr2 = directSoundPlayRestore(pThis, pStreamDS->Out.pDSB);
    824             if (FAILED(hr2))
    825                 hr2 = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB);
    826         }
    827 
    828         if (FAILED(hr2))
    829             DSLOG(("DSound: Stopping playback failed with %Rhrc\n", hr2));
    830 
    831         hr = S_OK; /* Always report success here. */
    832     }
    833     else
    834         hr = E_UNEXPECTED;
    835 
    836     if (SUCCEEDED(hr))
    837     {
    838         pStreamDS->Out.fEnabled = false;
    839     }
    840     else
     818    HRESULT hr = S_OK;
     819
     820    if (pStreamDS->Out.pDSB)
     821    {
     822        if (pStreamDS->fEnabled)
     823        {
     824            DSLOG(("DSound: Stopping playback\n"));
     825
     826            hr = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB);
     827            if (FAILED(hr))
     828            {
     829                hr = directSoundPlayRestore(pThis, pStreamDS->Out.pDSB);
     830                if (FAILED(hr))
     831                    hr = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB);
     832            }
     833
     834            if (SUCCEEDED(hr))
     835                pStreamDS->fEnabled = false;
     836        }
     837    }
     838
     839    if (FAILED(hr))
    841840        DSLOGREL(("DSound: Stopping playback failed with %Rhrc\n", hr));
    842841
     
    866865
    867866                pStreamDS->Out.fRestartPlayback = true;
    868                 pStreamDS->Out.fEnabled         = true;
     867                pStreamDS->fEnabled             = true;
    869868
    870869                DSLOG(("DSound: Playback started\n"));
     
    962961}
    963962
    964 
    965 static void directSoundCaptureInterfaceRelease(PDSOUNDSTREAM pStreamDS)
    966 {
    967     if (pStreamDS->In.pDSC)
     963/**
     964 * Destroys the DirectSound capturing interface.
     965 *
     966 * @return  IPRT status code.
     967 * @param   pThis               Driver instance to destroy capturing interface for.
     968 */
     969static void directSoundCaptureInterfaceDestroy(PDRVHOSTDSOUND pThis)
     970{
     971    if (pThis->pDSC)
    968972    {
    969973        LogFlowFuncEnter();
    970         IDirectSoundCapture_Release(pStreamDS->In.pDSC);
    971         pStreamDS->In.pDSC = NULL;
    972     }
    973 }
    974 
    975 
    976 static HRESULT directSoundCaptureInterfaceCreate(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, PPDMAUDIOSTREAMCFG pCfg)
     974
     975        IDirectSoundCapture_Release(pThis->pDSC);
     976        pThis->pDSC = NULL;
     977    }
     978}
     979
     980/**
     981 * Creates the DirectSound capturing interface.
     982 *
     983 * @return  IPRT status code.
     984 * @param   pThis               Driver instance to create the capturing interface for.
     985 * @param   pCfg                Audio stream to use for creating the capturing interface.
     986 */
     987static HRESULT directSoundCaptureInterfaceCreate(PDRVHOSTDSOUND pThis, PPDMAUDIOSTREAMCFG pCfg)
    977988{
    978989    AssertPtrReturn(pThis,     E_POINTER);
    979     AssertPtrReturn(pStreamDS, E_POINTER);
    980990    AssertPtrReturn(pCfg,      E_POINTER);
    981991
    982     if (pStreamDS->In.pDSC != NULL)
    983     {
    984         DSLOG(("DSound: DirectSoundCapture instance already exists\n"));
     992    if (pThis->pDSC)
    985993        return S_OK;
    986     }
     994
     995    LogFlowFuncEnter();
    987996
    988997    HRESULT hr = CoCreateInstance(CLSID_DirectSoundCapture8, NULL, CLSCTX_ALL,
    989                                   IID_IDirectSoundCapture8, (void **)&pStreamDS->In.pDSC);
     998                                  IID_IDirectSoundCapture8, (void **)&pThis->pDSC);
    990999    if (FAILED(hr))
    9911000    {
     
    9951004    {
    9961005        LPCGUID pGUID = dsoundCaptureSelectDevice(pThis, pCfg);
    997         hr = IDirectSoundCapture_Initialize(pStreamDS->In.pDSC, pGUID);
     1006        /* pGUID can be NULL when using the default device. */
     1007
     1008        hr = IDirectSoundCapture_Initialize(pThis->pDSC, pGUID);
    9981009        if (FAILED(hr))
    9991010        {
     
    10031014                DSLOGREL(("DSound: Initializing capturing device failed with %Rhrc\n", hr));
    10041015
    1005             directSoundCaptureInterfaceRelease(pStreamDS);
     1016            directSoundCaptureInterfaceDestroy(pThis);
    10061017        }
    10071018    }
     
    10311042            DSLOGREL(("DSound: Stopping capture buffer failed with %Rhrc\n", hr));
    10321043    }
    1033 
    1034     if (SUCCEEDED(hr))
    1035         directSoundCaptureInterfaceRelease(pStreamDS);
    10361044
    10371045    LogFlowFunc(("Returning %Rhrc\n", hr));
     
    10681076        return E_INVALIDARG;
    10691077
    1070     HRESULT hr = directSoundCaptureInterfaceCreate(pThis, pStreamDS, pCfgReq);
     1078    directSoundCaptureInterfaceDestroy(pThis);
     1079
     1080    dsoundUpdateStatusInternalEx(pThis, NULL /* Cfg */, DSOUNDENUMCBFLAGS_LOG /* fEnum */);
     1081
     1082    HRESULT hr = directSoundCaptureInterfaceCreate(pThis, pCfgReq);
    10711083    if (FAILED(hr))
    10721084        return hr;
     
    10831095        bd.dwBufferBytes = pThis->cfg.cbBufferIn;
    10841096
    1085         hr = IDirectSoundCapture_CreateCaptureBuffer(pStreamDS->In.pDSC, &bd, &pDSCB, NULL);
     1097        hr = IDirectSoundCapture_CreateCaptureBuffer(pThis->pDSC, &bd, &pDSCB, NULL);
    10861098        if (FAILED(hr))
    10871099        {
     
    11881200    RT_NOREF(pThis);
    11891201
    1190     HRESULT hr;
     1202    HRESULT hr = S_OK;
    11911203
    11921204    if (pStreamDS->In.pDSCB)
    11931205    {
    1194         DSLOG(("DSound: Stopping capture\n"));
    1195 
    1196         hr = IDirectSoundCaptureBuffer_Stop(pStreamDS->In.pDSCB);
    1197         if (FAILED(hr))
    1198             DSLOGREL(("DSound: Stopping capture buffer failed with %Rhrc\n", hr));
    1199     }
    1200     else
    1201         hr = E_UNEXPECTED;
    1202 
    1203     if (SUCCEEDED(hr))
    1204         pStreamDS->In.fEnabled = false;
     1206        if (pStreamDS->fEnabled)
     1207        {
     1208            DSLOG(("DSound: Stopping capture\n"));
     1209
     1210            hr = IDirectSoundCaptureBuffer_Stop(pStreamDS->In.pDSCB);
     1211            if (FAILED(hr))
     1212                DSLOGREL(("DSound: Stopping capture buffer failed with %Rhrc\n", hr));
     1213
     1214            pStreamDS->fEnabled = false;
     1215        }
     1216    }
    12051217
    12061218    LogFlowFunc(("Returning %Rhrc\n", hr));
     
    12371249                DSLOG(("DSound: Starting to capture\n"));
    12381250                hr = IDirectSoundCaptureBuffer8_Start(pStreamDS->In.pDSCB, fFlags);
    1239                 if (FAILED(hr))
     1251                if (SUCCEEDED(hr))
     1252                {
     1253                    pStreamDS->fEnabled = true;
     1254                }
     1255                else
    12401256                    DSLOGREL(("DSound: Starting to capture failed with %Rhrc\n", hr));
    12411257            }
     
    12461262
    12471263    if (SUCCEEDED(hr))
    1248         pStreamDS->In.fEnabled = true;
     1264
    12491265
    12501266    LogFlowFunc(("Returning %Rhrc\n", hr));
     
    12641280
    12651281    int rc = RTUtf16ToUtf8(pwszDescription, &pDev->pszName);
    1266     if (RT_SUCCESS(rc))
     1282    if (   RT_SUCCESS(rc)
     1283        && pGUID)
     1284    {
    12671285        memcpy(&pDev->Guid, pGUID, sizeof(GUID));
     1286    }
    12681287
    12691288    if (RT_SUCCESS(rc))
     
    12811300    if (pDev)
    12821301    {
    1283         RTStrFree(pDev->pszName);
    1284         pDev->pszName = NULL;
     1302        if (pDev->pszName)
     1303        {
     1304            RTStrFree(pDev->pszName);
     1305            pDev->pszName = NULL;
     1306        }
    12851307
    12861308        RTListNodeRemove(&pDev->Node);
     
    14631485    LogFlowFunc(("pStreamDS=%p, pCfgReq=%p\n", pStreamDS, pCfgReq));
    14641486
    1465     pStreamDS->Out.pDS = NULL;
    14661487    pStreamDS->Out.pDSB = NULL;
    14671488    pStreamDS->Out.offPlayWritePos = 0;
     
    17021723    pStreamDS->In.offCaptureBufRead = 0;
    17031724    pStreamDS->In.cbCaptureBuf      = 0;
    1704     pStreamDS->In.pDSC              = NULL;
    17051725    pStreamDS->In.pDSCB             = NULL;
    17061726    pStreamDS->In.hrLastCapture     = S_OK;
     
    22662286    PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream;
    22672287
    2268     if (pStreamDS->In.fEnabled)
     2288    if (pStreamDS->fEnabled)
    22692289        return UINT32_MAX;
    22702290
     
    22862306    PDSOUNDSTREAM  pStreamDS = (PDSOUNDSTREAM)pStream;
    22872307
    2288     if (pStreamDS->Out.fEnabled)
     2308    if (pStreamDS->fEnabled)
    22892309    {
    22902310        DWORD cbFree;
     
    23182338    if (pStreamDS->pCfg->enmDir == PDMAUDIODIR_IN)
    23192339    {
    2320         if (pStreamDS->In.fEnabled)
     2340        if (pStreamDS->fEnabled)
    23212341            strmSts |= PDMAUDIOSTREAMSTS_FLAG_ENABLED;
    23222342    }
    23232343    else
    23242344    {
    2325         if (pStreamDS->Out.fEnabled)
     2345        if (pStreamDS->fEnabled)
    23262346            strmSts |= PDMAUDIOSTREAMSTS_FLAG_ENABLED;
    23272347    }
     
    23972417    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    23982418
    2399     HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
     2419    HRESULT hr = CoInitializeEx(NULL, 0);
    24002420    if (FAILED(hr))
    24012421    {
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette