VirtualBox

Changeset 73563 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Aug 8, 2018 1:39:53 PM (6 years ago)
Author:
vboxsync
Message:

Audio/DrvHostDSound.cpp: Cleaned up internal state handling by having a dedicated reset and enable/disable function.

File:
1 edited

Legend:

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

    r73550 r73563  
    168168        } Out;
    169169    };
     170#ifdef LOG_ENABLED
    170171    struct
    171172    {
    172173        uint64_t tsLastTransferredMs;
    173174    } Dbg;
     175#endif
    174176} DSOUNDSTREAM, *PDSOUNDSTREAM;
    175177
     
    249251static int      dsoundDevicesEnumerate(PDRVHOSTDSOUND pThis, PPDMAUDIOBACKENDCFG pCfg);
    250252
     253static int      dsoundStreamEnable(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, bool fEnable);
     254static void     dsoundStreamReset(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS);
    251255static void     dsoundUpdateStatusInternal(PDRVHOSTDSOUND pThis);
    252256static void     dsoundUpdateStatusInternalEx(PDRVHOSTDSOUND pThis, PPDMAUDIOBACKENDCFG pCfg, uint32_t fEnum);
     
    808812 * @return  IPRT status code.
    809813 * @param   pThis               Host audio driver instance.
    810  */
    811 static int dsoundPlayTransfer(PDRVHOSTDSOUND pThis)
    812 {
    813     PDSOUNDSTREAM pStreamDS = pThis->pDSStrmOut;
    814 
    815     if (   !pStreamDS
    816         || !pStreamDS->fEnabled)
    817     {
     814 * @param   pStreamDS           Stream to transfer playback data for.
     815 */
     816static int dsoundPlayTransfer(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS)
     817{
     818    if (!pStreamDS->fEnabled)
     819    {
     820        Log2Func(("Stream disabled, skipping\n"));
    818821        return VINF_SUCCESS;
    819822    }
     
    855858    if (!pStreamDS->Dbg.tsLastTransferredMs)
    856859        pStreamDS->Dbg.tsLastTransferredMs = RTTimeMilliTS();
    857     Log3Func(("tsLastTransferredMs=%RU64ms, cbAvail=%RU32, cbFree=%RU32 -> cbToTransfer=%RU32 (fDrain=%RTbool)\n",
    858               RTTimeMilliTS() - pStreamDS->Dbg.tsLastTransferredMs, cbAvail, cbFree, cbToTransfer, pStreamDS->Out.fDrain));
     860    Log3Func(("offPlay=%RU32, offWrite=%RU32, tsLastTransferredMs=%RU64ms, cbAvail=%RU32, cbFree=%RU32 -> cbToTransfer=%RU32 "
     861              "(fFirst=%RTbool, fDrain=%RTbool)\n",
     862              offPlayCursor, offWriteCursor, RTTimeMilliTS() - pStreamDS->Dbg.tsLastTransferredMs, cbAvail, cbFree, cbToTransfer,
     863              pStreamDS->Out.fFirstTransfer, pStreamDS->Out.fDrain));
    859864    pStreamDS->Dbg.tsLastTransferredMs = RTTimeMilliTS();
    860865#endif
     
    915920        if (SUCCEEDED(hr))
    916921        {
    917             DSLOG(("DSound: Started playing output\n"));
    918922            pStreamDS->Out.fFirstTransfer = false;
    919923        }
     
    977981    if (pStreamDS->Out.pDSB)
    978982    {
    979         if (pStreamDS->fEnabled)
    980         {
    981             DSLOG(("DSound: %s playback\n", fFlush ? "Stopping" : "Pausing"));
    982 
    983             hr = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB);
     983        DSLOG(("DSound: Stopping playback\n"));
     984        hr = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB);
     985        if (FAILED(hr))
     986        {
     987            hr = directSoundPlayRestore(pThis, pStreamDS->Out.pDSB);
    984988            if (FAILED(hr))
    985             {
    986                 hr = directSoundPlayRestore(pThis, pStreamDS->Out.pDSB);
    987                 if (FAILED(hr))
    988                     hr = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB);
    989             }
    990 
    991             pStreamDS->fEnabled = false;
     989                hr = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB);
    992990        }
    993991    }
     
    995993    if (SUCCEEDED(hr))
    996994    {
    997         if (   fFlush
    998             && pStreamDS->pCircBuf)
    999         {
    1000             RTCircBufReset(pStreamDS->pCircBuf);
    1001         }
     995        if (fFlush)
     996            dsoundStreamReset(pThis, pStreamDS);
    1002997    }
    1003998
     
    10081003}
    10091004
     1005/**
     1006 * Enables or disables a stream.
     1007 *
     1008 * @return  IPRT status code.
     1009 * @param   pThis               Host audio driver instance.
     1010 * @param   pStreamDS           Stream to enable / disable.
     1011 * @param   fEnable             Whether to enable or disable the stream.
     1012 */
     1013static int dsoundStreamEnable(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, bool fEnable)
     1014{
     1015    RT_NOREF(pThis);
     1016
     1017    LogFunc(("%s %s\n",
     1018             fEnable ? "Enabling" : "Disabling",
     1019             pStreamDS->Cfg.enmDir == PDMAUDIODIR_IN ? "capture" : "playback"));
     1020
     1021    pStreamDS->fEnabled = fEnable;
     1022
     1023    return VINF_SUCCESS;
     1024}
     1025
    10101026
    10111027/**
    10121028 * Resets the state of a DirectSound stream.
    10131029 *
    1014  * @return  HRESULT
    10151030 * @param   pThis               Host audio driver instance.
    10161031 * @param   pStreamDS           Stream to reset state for.
    10171032 */
    1018 static HRESULT directSoundPlayReset(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS)
    1019 {
    1020     AssertPtrReturn(pThis,     E_POINTER);
    1021     AssertPtrReturn(pStreamDS, E_POINTER);
    1022 
    1023     Assert(pStreamDS->fEnabled == false);
    1024 
    1025     pStreamDS->fEnabled           = true;
    1026     /* Note: Playing back via DirectSound starts in the notification thread
    1027      *       once enough audio output data is available. */
    1028 
    1029     if (pStreamDS->Cfg.enmDir == PDMAUDIODIR_OUT)
     1033static void dsoundStreamReset(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS)
     1034{
     1035    RT_NOREF(pThis);
     1036
     1037    LogFunc(("Resetting %s\n",
     1038             pStreamDS->Cfg.enmDir == PDMAUDIODIR_IN ? "capture" : "playback"));
     1039
     1040    if (pStreamDS->pCircBuf)
     1041        RTCircBufReset(pStreamDS->pCircBuf);
     1042
     1043    if (pStreamDS->Cfg.enmDir == PDMAUDIODIR_IN)
     1044    {
     1045        pStreamDS->In.offReadPos = 0;
     1046        pStreamDS->In.cOverruns  = 0;
     1047    }
     1048    else if (pStreamDS->Cfg.enmDir == PDMAUDIODIR_OUT)
    10301049    {
    10311050        pStreamDS->Out.fFirstTransfer = true;
     1051        pStreamDS->Out.fDrain         = false;
    10321052        pStreamDS->Out.cUnderruns     = 0;
    10331053
     
    10381058        pStreamDS->Out.cbWritten = 0;
    10391059
     1060        pStreamDS->Out.offWritePos = 0;
    10401061        pStreamDS->Out.offPlayCursorLastPending = 0;
    10411062        pStreamDS->Out.offPlayCursorLastPlayed = 0;
    10421063    }
    1043 
    1044     return S_OK;
     1064    else
     1065        AssertFailed();
     1066
     1067#ifdef LOG_ENABLED
     1068    pStreamDS->Dbg.tsLastTransferredMs = 0;
     1069#endif
    10451070}
    10461071
     
    10611086    for (unsigned i = 0; i < DRV_DSOUND_RESTORE_ATTEMPTS_MAX; i++)
    10621087    {
     1088        DSLOG(("DSound: Starting playback\n"));
    10631089        hr = IDirectSoundBuffer8_Play(pStreamDS->Out.pDSB, 0, 0, fFlags);
    10641090        if (   SUCCEEDED(hr)
     
    11581184 * @return  IPRT status code.
    11591185 * @param   pThis               Host audio driver instance.
    1160  */
    1161 static int dsoundCaptureTransfer(PDRVHOSTDSOUND pThis)
    1162 {
    1163     PDSOUNDSTREAM pStreamDS = pThis->pDSStrmIn;
    1164     AssertPtr(pStreamDS);
     1186 * @param   pStreamDS           Stream to capture audio data for.
     1187 */
     1188static int dsoundCaptureTransfer(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS)
     1189{
     1190    RT_NOREF(pThis);
    11651191
    11661192    LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB = pStreamDS->In.pDSCB;
     
    11701196    HRESULT hr = IDirectSoundCaptureBuffer_GetCurrentPosition(pDSCB, NULL, &offCaptureCursor);
    11711197    if (FAILED(hr))
     1198    {
     1199        AssertFailed();
    11721200        return VERR_ACCESS_DENIED; /** @todo Find a better rc. */
     1201    }
    11731202
    11741203    DWORD cbUsed = dsoundRingDistance(offCaptureCursor, pStreamDS->In.offReadPos, pStreamDS->cbBufSize);
     
    14731502    if (pStreamDS->In.pDSCB)
    14741503    {
    1475         if (pStreamDS->fEnabled)
    1476         {
    1477             DSLOG(("DSound: Stopping capture\n"));
    1478 
    1479             hr = IDirectSoundCaptureBuffer_Stop(pStreamDS->In.pDSCB);
    1480             if (SUCCEEDED(hr))
    1481                 pStreamDS->fEnabled = false;
    1482         }
     1504        DSLOG(("DSound: Stopping capture\n"));
     1505        hr = IDirectSoundCaptureBuffer_Stop(pStreamDS->In.pDSCB);
    14831506    }
    14841507
    14851508    if (SUCCEEDED(hr))
    14861509    {
    1487         if (   fFlush
    1488             && pStreamDS->pCircBuf)
    1489         {
    1490             RTCircBufReset(pStreamDS->pCircBuf);
    1491         }
     1510        if (fFlush)
     1511             dsoundStreamReset(pThis, pStreamDS);
    14921512    }
    14931513
     
    15031523    AssertPtrReturn(pStreamDS, E_POINTER);
    15041524
    1505     Assert(pStreamDS->fEnabled == false);
    1506 
    15071525    HRESULT hr;
    1508     if (pStreamDS->In.pDSCB != NULL)
     1526    if (pStreamDS->In.pDSCB)
    15091527    {
    15101528        DWORD dwStatus;
     
    15261544                DSLOG(("DSound: Starting to capture\n"));
    15271545                hr = IDirectSoundCaptureBuffer8_Start(pStreamDS->In.pDSCB, fFlags);
    1528                 if (SUCCEEDED(hr))
    1529                 {
    1530                     pStreamDS->fEnabled = true;
    1531 
    1532                     pStreamDS->In.offReadPos = 0;
    1533                     pStreamDS->In.cOverruns  = 0;
    1534                 }
    1535                 else
     1546                if (FAILED(hr))
    15361547                    DSLOGREL(("DSound: Starting to capture failed with %Rhrc\n", hr));
    15371548            }
     
    17531764    LogFlowFunc(("pStreamDS=%p, pCfgReq=%p\n", pStreamDS, pCfgReq));
    17541765
    1755     pStreamDS->cbBufSize = 0;
    1756 
    1757     pStreamDS->Out.pDSB = NULL;
    1758     pStreamDS->Out.offWritePos = 0;
    1759     pStreamDS->Out.offPlayCursorLastPlayed = 0;
    1760     pStreamDS->Out.offPlayCursorLastPending = 0;
    1761     pStreamDS->Out.cbWritten = 0;
    1762     pStreamDS->Out.cbTransferred = 0;
    1763     pStreamDS->Out.fFirstTransfer = true;
    1764     pStreamDS->Out.fDrain = false;
    1765     pStreamDS->Out.cbLastTransferred = 0;
    1766     pStreamDS->Out.tsLastTransferred = 0;
    1767 
    17681766    int rc = VINF_SUCCESS;
    17691767
    17701768    /* Try to open playback in case the device is already there. */
    17711769    HRESULT hr = directSoundPlayOpen(pThis, pStreamDS, pCfgReq, pCfgAcq);
    1772     if (FAILED(hr))
     1770    if (SUCCEEDED(hr))
     1771    {
     1772        rc = DrvAudioHlpStreamCfgCopy(&pStreamDS->Cfg, pCfgAcq);
     1773        if (RT_SUCCESS(rc))
     1774            dsoundStreamReset(pThis, pStreamDS);
     1775    }
     1776    else
    17731777        rc = VERR_GENERAL_FAILURE; /** @todo Fudge! */
    17741778
     
    17881792        case PDMAUDIOSTREAMCMD_ENABLE:
    17891793        {
    1790             hr = directSoundPlayReset(pThis, pStreamDS);
    1791             if (FAILED(hr))
    1792                 rc = VERR_NOT_SUPPORTED; /** @todo Fix this. */
     1794            dsoundStreamEnable(pThis, pStreamDS, true /* fEnable */);
    17931795            break;
    17941796        }
     
    18031805
    18041806        case PDMAUDIOSTREAMCMD_DISABLE:
    1805         case PDMAUDIOSTREAMCMD_PAUSE:
    1806         {
    1807             hr = directSoundPlayStop(pThis, pStreamDS, enmStreamCmd == PDMAUDIOSTREAMCMD_DISABLE /* fFlush */);
     1807        {
     1808            dsoundStreamEnable(pThis, pStreamDS, false /* fEnable */);
     1809            hr = directSoundPlayStop(pThis, pStreamDS, true /* fFlush */);
    18081810            if (FAILED(hr))
    18091811                rc = VERR_NOT_SUPPORTED;
     
    18111813        }
    18121814
     1815        case PDMAUDIOSTREAMCMD_PAUSE:
     1816        {
     1817            hr = directSoundPlayStop(pThis, pStreamDS, false /* fFlush */);
     1818            if (FAILED(hr))
     1819                rc = VERR_NOT_SUPPORTED;
     1820            break;
     1821        }
     1822
    18131823        case PDMAUDIOSTREAMCMD_DRAIN:
    18141824        {
    18151825            /* Make sure we transferred everything. */
     1826            pStreamDS->fEnabled = true;
    18161827            pStreamDS->Out.fDrain = true;
    1817             rc = dsoundPlayTransfer(pThis);
     1828            rc = dsoundPlayTransfer(pThis, pStreamDS);
    18181829            if (   RT_SUCCESS(rc)
    18191830                && pStreamDS->Out.fFirstTransfer)
     
    18901901    pStreamDS->Out.cbWritten += cbWrittenTotal;
    18911902
    1892     rc = dsoundPlayTransfer(pThis);
     1903    rc = dsoundPlayTransfer(pThis, pStreamDS);
    18931904    AssertRC(rc);
    18941905
     
    19271938             pStreamDS, pCfgReq, DrvAudioHlpRecSrcToStr(pCfgReq->DestSource.Source)));
    19281939
    1929     /* Init the stream structure and save relevant information to it. */
    1930     pStreamDS->cbBufSize     = 0;
    1931 
    1932     pStreamDS->In.pDSCB      = NULL;
    1933     pStreamDS->In.offReadPos = 0;
    1934     pStreamDS->In.cOverruns  = 0;
    1935 
    19361940    int rc = VINF_SUCCESS;
    19371941
    19381942    /* Try to open capture in case the device is already there. */
    19391943    HRESULT hr = directSoundCaptureOpen(pThis, pStreamDS, pCfgReq, pCfgAcq);
    1940     if (FAILED(hr))
     1944    if (SUCCEEDED(hr))
     1945    {
     1946        rc = DrvAudioHlpStreamCfgCopy(&pStreamDS->Cfg, pCfgAcq);
     1947        if (RT_SUCCESS(rc))
     1948            dsoundStreamReset(pThis, pStreamDS);
     1949    }
     1950    else
    19411951        rc = VERR_GENERAL_FAILURE; /** @todo Fudge! */
    19421952
     
    19541964    {
    19551965        case PDMAUDIOSTREAMCMD_ENABLE:
     1966            dsoundStreamEnable(pThis, pStreamDS, true /* fEnable */);
     1967            RT_FALL_THROUGH();
    19561968        case PDMAUDIOSTREAMCMD_RESUME:
    19571969        {
     
    19841996
    19851997        case PDMAUDIOSTREAMCMD_DISABLE:
     1998            dsoundStreamEnable(pThis, pStreamDS, false /* fEnable */);
     1999            RT_FALL_THROUGH();
    19862000        case PDMAUDIOSTREAMCMD_PAUSE:
    19872001        {
    1988             AssertPtr(pThis->pDSC);
    1989 
    19902002            directSoundCaptureStop(pThis, pStreamDS,
    19912003                                   enmStreamCmd == PDMAUDIOSTREAMCMD_DISABLE /* fFlush */);
     
    23312343
    23322344    PDMAUDIOSTREAMSTS strmSts = PDMAUDIOSTREAMSTS_FLAG_INITIALIZED;
    2333     if (pStreamDS->Cfg.enmDir == PDMAUDIODIR_IN)
    2334     {
    2335         if (pStreamDS->fEnabled)
    2336             strmSts |= PDMAUDIOSTREAMSTS_FLAG_ENABLED;
    2337     }
    2338     else
    2339     {
    2340         if (pStreamDS->fEnabled)
    2341             strmSts |= PDMAUDIOSTREAMSTS_FLAG_ENABLED;
    2342     }
     2345
     2346    if (pStreamDS->fEnabled)
     2347        strmSts |= PDMAUDIOSTREAMSTS_FLAG_ENABLED;
    23432348
    23442349    return strmSts;
     
    23572362
    23582363    if (pStreamDS->Cfg.enmDir == PDMAUDIODIR_IN)
    2359         return dsoundCaptureTransfer(pThis);
     2364        return dsoundCaptureTransfer(pThis, pStreamDS);
    23602365
    23612366    return VINF_SUCCESS;
Note: See TracChangeset for help on using the changeset viewer.

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