VirtualBox

Changeset 70925 in vbox for trunk/src/VBox/Devices/Audio


Ignore:
Timestamp:
Feb 9, 2018 9:51:46 AM (7 years ago)
Author:
vboxsync
Message:

Audio/DrvHostDSound.cpp: Also use the notification thread for capturing audio.

File:
1 edited

Legend:

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

    r70921 r70925  
    121121    bool               fEnabled;
    122122    RTCRITSECT         CritSect;
     123    PRTCIRCBUF         pCircBuf;
    123124    union
    124125    {
     
    132133            /** Size (in bytes) of the DirectSound buffer. */
    133134            DWORD                       cbBufSize;
    134             HRESULT                     hrLastCapture;
    135135        } In;
    136136        struct
     
    154154            bool fPendingPlayback;
    155155            bool fPendingClose;
    156             PRTCIRCBUF                  pCircBuf;
    157156        } Out;
    158157    };
     
    236235static HRESULT  directSoundPlayRestore(PDRVHOSTDSOUND pThis, LPDIRECTSOUNDBUFFER8 pDSB);
    237236static HRESULT  directSoundPlayStop(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, bool fFlush);
    238 static HRESULT  directSoundCaptureStop(PDSOUNDSTREAM pStreamDS);
     237static HRESULT  directSoundCaptureStop(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, bool fFlush);
    239238
    240239static void     dsoundDeviceRemove(PDSOUNDDEV pDev);
     
    586585    DSLOG(("DSound: Closing playback stream\n"));
    587586
    588     if (pStreamDS->Out.pCircBuf)
    589         Assert(RTCircBufUsed(pStreamDS->Out.pCircBuf) == 0);
     587    if (pStreamDS->pCircBuf)
     588        Assert(RTCircBufUsed(pStreamDS->pCircBuf) == 0);
    590589
    591590    if (SUCCEEDED(hr))
     
    593592        RTCritSectEnter(&pThis->CritSect);
    594593
    595         if (pStreamDS->Out.pCircBuf)
    596         {
    597             RTCircBufDestroy(pStreamDS->Out.pCircBuf);
    598             pStreamDS->Out.pCircBuf = NULL;
     594        if (pStreamDS->pCircBuf)
     595        {
     596            RTCircBufDestroy(pStreamDS->pCircBuf);
     597            pStreamDS->pCircBuf = NULL;
    599598        }
    600599
     
    766765        RTCritSectEnter(&pThis->CritSect);
    767766
    768         rc = RTCircBufCreate(&pStreamDS->Out.pCircBuf, pStreamDS->Out.cbBufSize);
     767        rc = RTCircBufCreate(&pStreamDS->pCircBuf, pStreamDS->Out.cbBufSize);
    769768        AssertRC(rc);
    770769
     
    906905    {
    907906        if (fFlush)
    908             RTCircBufReset(pStreamDS->Out.pCircBuf);
     907            RTCircBufReset(pStreamDS->pCircBuf);
    909908    }
    910909
     
    10691068
    10701069
    1071 static HRESULT directSoundCaptureClose(PDSOUNDSTREAM pStreamDS)
    1072 {
     1070static HRESULT directSoundCaptureClose(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS)
     1071{
     1072    AssertPtrReturn(pThis,     E_POINTER);
    10731073    AssertPtrReturn(pStreamDS, E_POINTER);
    10741074
    10751075    LogFlowFuncEnter();
    10761076
    1077     HRESULT hr = S_OK;
     1077    HRESULT hr = directSoundCaptureStop(pThis, pStreamDS, true /* fFlush */);
     1078    if (FAILED(hr))
     1079        return hr;
    10781080
    10791081    if (   pStreamDS
     
    10821084        DSLOG(("DSound: Closing capturing stream\n"));
    10831085
    1084         hr = directSoundCaptureStop(pStreamDS);
    1085         if (SUCCEEDED(hr))
    1086         {
    1087             IDirectSoundCaptureBuffer8_Release(pStreamDS->In.pDSCB);
    1088             pStreamDS->In.pDSCB = NULL;
    1089         }
    1090         else
    1091             DSLOGREL(("DSound: Stopping capture buffer failed with %Rhrc\n", hr));
     1086        IDirectSoundCaptureBuffer8_Release(pStreamDS->In.pDSCB);
     1087        pStreamDS->In.pDSCB = NULL;
    10921088    }
    10931089
     
    12121208
    12131209        /* Initial state: reading at the initial capture position, no error. */
    1214         pStreamDS->In.offReadPos    = offByteReadPos;
     1210        pStreamDS->In.offReadPos    = 0;
    12151211        pStreamDS->In.cbBufSize     = bc.dwBufferBytes;
    1216         pStreamDS->In.hrLastCapture = S_OK;
    1217 
    1218         pCfgAcq->cFrameBufferHint = PDMAUDIOSTREAMCFG_B2F(pCfgAcq, bc.dwBufferBytes);
     1212
     1213        rc = RTCircBufCreate(&pStreamDS->pCircBuf, pStreamDS->In.cbBufSize);
     1214        AssertRC(rc);
     1215
     1216        /*
     1217         * Install notification.
     1218         */
     1219        LPDIRECTSOUNDNOTIFY8 pNotify;
     1220        hr = IDirectSoundNotify_QueryInterface(pStreamDS->In.pDSCB, IID_IDirectSoundNotify8, (PVOID *)&pNotify);
     1221        if (SUCCEEDED(hr))
     1222        {
     1223            DSBPOSITIONNOTIFY dsPosNotify[3];
     1224            RT_ZERO(dsPosNotify);
     1225
     1226            dsPosNotify[0].dwOffset     = 0;
     1227            dsPosNotify[0].hEventNotify = pThis->aEvents[DSOUNDEVENT_INPUT];
     1228
     1229            dsPosNotify[1].dwOffset     = float(pStreamDS->In.cbBufSize * 0.3);
     1230            dsPosNotify[1].hEventNotify = pThis->aEvents[DSOUNDEVENT_INPUT];
     1231
     1232            dsPosNotify[2].dwOffset     = float(pStreamDS->In.cbBufSize * 0.6);
     1233            dsPosNotify[2].hEventNotify = pThis->aEvents[DSOUNDEVENT_INPUT];
     1234
     1235            hr = IDirectSoundNotify_SetNotificationPositions(pNotify, 3 /* Count */, dsPosNotify);
     1236            if (FAILED(hr))
     1237                DSLOGREL(("DSound: Setting capture position notification failed with %Rhrc\n", hr));
     1238
     1239            IDirectSoundNotify_Release(pNotify);
     1240
     1241            pThis->pDSStrmIn = pStreamDS;
     1242        }
     1243
     1244        pCfgAcq->cFrameBufferHint = PDMAUDIOSTREAMCFG_B2F(pCfgAcq, pStreamDS->In.cbBufSize);
    12191245
    12201246    } while (0);
    12211247
    12221248    if (FAILED(hr))
    1223         directSoundCaptureClose(pStreamDS);
     1249        directSoundCaptureClose(pThis, pStreamDS);
    12241250
    12251251    LogFlowFunc(("Returning %Rhrc\n", hr));
     
    12281254
    12291255
    1230 static HRESULT directSoundCaptureStop(PDSOUNDSTREAM pStreamDS)
    1231 {
     1256static HRESULT directSoundCaptureStop(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, bool fFlush)
     1257{
     1258    AssertPtrReturn(pThis,     E_POINTER);
    12321259    AssertPtrReturn(pStreamDS, E_POINTER);
     1260
     1261    RT_NOREF(pThis);
    12331262
    12341263    HRESULT hr = S_OK;
     
    12441273                pStreamDS->fEnabled = false;
    12451274        }
     1275    }
     1276
     1277    if (SUCCEEDED(hr))
     1278    {
     1279        if (fFlush)
     1280            RTCircBufReset(pStreamDS->pCircBuf);
    12461281    }
    12471282
     
    16091644
    16101645    uint8_t   *pbBuf    = (uint8_t *)pvBuf;
    1611     PRTCIRCBUF pCircBuf = pStreamDS->Out.pCircBuf;
     1646    PRTCIRCBUF pCircBuf = pStreamDS->pCircBuf;
    16121647
    16131648    uint32_t cbToPlay = RT_MIN(cxBuf, (uint32_t)RTCircBufFree(pCircBuf));
     
    16831718    pStreamDS->In.cbBufSize     = 0;
    16841719    pStreamDS->In.pDSCB         = NULL;
    1685     pStreamDS->In.hrLastCapture = S_OK;
    16861720
    16871721    int rc = VINF_SUCCESS;
     
    17111745            if (FAILED(hr))
    17121746            {
    1713                 hr = directSoundCaptureClose(pStreamDS);
     1747                hr = directSoundCaptureClose(pThis, pStreamDS);
    17141748                if (SUCCEEDED(hr))
    17151749                {
     
    17401774            AssertPtr(pThis->pDSC);
    17411775
    1742             directSoundCaptureStop(pStreamDS);
     1776            directSoundCaptureStop(pThis, pStreamDS,
     1777                                   enmStreamCmd == PDMAUDIOSTREAMCMD_DISABLE /* fFlush */);
    17431778
    17441779            /* Return success in any case, as stopping the capture can fail if
     
    17611796}
    17621797
    1763 
    17641798/**
    17651799 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
     
    17771811    PDSOUNDSTREAM  pStreamDS = (PDSOUNDSTREAM)pStream;
    17781812
    1779     LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB = pStreamDS->In.pDSCB;
    1780     AssertPtr(pDSCB);
    1781 
    17821813    int rc = VINF_SUCCESS;
    17831814
    17841815    uint32_t cbReadTotal = 0;
    17851816
    1786     do
    1787     {
    1788         if (pDSCB == NULL)
    1789         {
    1790             rc = VERR_NOT_AVAILABLE;
    1791             break;
    1792         }
    1793 
    1794         /* Get DirectSound capture position in bytes. */
    1795         DWORD offCurPos;
    1796         HRESULT hr = IDirectSoundCaptureBuffer_GetCurrentPosition(pDSCB, NULL, &offCurPos);
    1797         if (FAILED(hr))
    1798         {
    1799             if (hr != pStreamDS->In.hrLastCapture)
    1800             {
    1801                 DSLOGREL(("DSound: Getting capture position failed with %Rhrc\n", hr));
    1802                 pStreamDS->In.hrLastCapture = hr;
    1803             }
    1804 
    1805             rc = VERR_NOT_AVAILABLE;
    1806             break;
    1807         }
    1808 
    1809         pStreamDS->In.hrLastCapture = hr;
    1810 
    1811         if (offCurPos & pStreamDS->uAlign)
    1812             DSLOGF(("DSound: Misaligned capture read position %ld (alignment: %RU32)\n",
    1813                     offCurPos, pStreamDS->uAlign + 1));
    1814 
    1815         /* Number of samples available in the DirectSound capture buffer. */
    1816         DWORD cbToCapture = dsoundRingDistance(offCurPos, pStreamDS->In.offReadPos, pStreamDS->In.cbBufSize);
    1817         if (cbToCapture == 0)
    1818             break;
    1819 
    1820         if (cxBuf == 0)
    1821         {
    1822             DSLOGF(("DSound: Capture buffer full\n"));
    1823             break;
    1824         }
    1825 
    1826         DSLOGF(("DSound: Capture cxBuf=%RU32, offCurPos=%ld, offReadPos=%ld, cbToCapture=%ld\n",
    1827                 cxBuf, offCurPos, pStreamDS->In.offReadPos, cbToCapture));
    1828 
    1829         /* No need to fetch more samples than mix buffer can receive. */
    1830         cbToCapture = RT_MIN(cbToCapture, cxBuf);
    1831 
    1832         /* Lock relevant range in the DirectSound capture buffer. */
    1833         PVOID pv1, pv2;
    1834         DWORD cb1, cb2;
    1835         hr = directSoundCaptureLock(pStreamDS,
    1836                                     pStreamDS->In.offReadPos,  /* dwOffset */
    1837                                     cbToCapture,               /* dwBytes */
    1838                                     &pv1, &pv2, &cb1, &cb2,
    1839                                     0                          /* dwFlags */);
    1840         if (FAILED(hr))
    1841         {
    1842             rc = VERR_ACCESS_DENIED;
    1843             break;
    1844         }
    1845 
    1846         if (pv1 && cb1)
    1847         {
    1848             memcpy((uint8_t *)pvBuf + cbReadTotal, pv1, cb1);
    1849             cbReadTotal += cb1;
    1850         }
    1851 
    1852         if (pv2 && cb2)
    1853         {
    1854             memcpy((uint8_t *)pvBuf + cbReadTotal, pv2, cb2);
    1855             cbReadTotal += cb2;
    1856         }
    1857 
    1858         directSoundCaptureUnlock(pDSCB, pv1, pv2, cb1, cb2);
    1859 
    1860         if (RT_SUCCESS(rc))
    1861         {
    1862             pStreamDS->In.offReadPos = (pStreamDS->In.offReadPos + cbReadTotal)
    1863                                      % pStreamDS->In.cbBufSize;
    1864             DSLOGF(("DSound: Captured %ld bytes (%RU32 total)\n", cbToCapture, cbReadTotal));
    1865         }
    1866 
    1867     } while (0);
     1817    uint32_t cbToRead = RT_MIN((uint32_t)RTCircBufUsed(pStreamDS->pCircBuf), cxBuf);
     1818    while (cbToRead)
     1819    {
     1820        void   *pvChunk;
     1821        size_t  cbChunk;
     1822        RTCircBufAcquireReadBlock(pStreamDS->pCircBuf, cbToRead, &pvChunk, &cbChunk);
     1823
     1824        if (cbChunk)
     1825        {
     1826            memcpy((uint8_t *)pvBuf + cbReadTotal, pvChunk, cbChunk);
     1827            cbReadTotal += (uint32_t)cbChunk;
     1828            Assert(cbToRead >= cbChunk);
     1829            cbToRead    -= (uint32_t)cbChunk;
     1830        }
     1831
     1832        RTCircBufReleaseReadBlock(pStreamDS->pCircBuf, cbChunk);
     1833    }
    18681834
    18691835    if (RT_SUCCESS(rc))
     
    18781844}
    18791845
    1880 static int dsoundDestroyStreamIn(PDSOUNDSTREAM pStreamDS)
     1846static int dsoundDestroyStreamIn(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS)
    18811847{
    18821848    LogFlowFuncEnter();
    18831849
    1884     directSoundCaptureClose(pStreamDS);
     1850    directSoundCaptureClose(pThis, pStreamDS);
    18851851
    18861852    return VINF_SUCCESS;
     
    19741940                dwObj -= WAIT_OBJECT_0;
    19751941
    1976                 Log3Func(("Event %ld\n",  dwObj));
    1977 
    1978                 PDSOUNDSTREAM pStreamDS = pThis->pDSStrmOut;
    1979 
    1980                 if (!    pStreamDS
    1981                     ||  !pStreamDS->fEnabled)
    1982                     break;
    1983 
    19841942                if (dwObj == DSOUNDEVENT_NOTIFY)
    19851943                {
     1944                    Log3Func(("Notify\n"));
    19861945                }
    19871946                else if (dwObj == DSOUNDEVENT_INPUT)
    19881947                {
     1948                    PDSOUNDSTREAM pStreamDS = pThis->pDSStrmIn;
     1949
     1950                    if (   !pStreamDS
     1951                        || !pStreamDS->fEnabled)
     1952                    {
     1953                        Log3Func(("Skipping capture\n"));
     1954                        break;
     1955                    }
     1956
     1957                    LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB = pStreamDS->In.pDSCB;
     1958                    AssertPtr(pDSCB);
     1959
     1960                    DWORD offCaptureCursor;
     1961                    HRESULT hr = IDirectSoundCaptureBuffer_GetCurrentPosition(pDSCB, NULL, &offCaptureCursor);
     1962                    if (FAILED(hr))
     1963                        break;
     1964
     1965                    DWORD cbUsed = dsoundRingDistance(offCaptureCursor, pStreamDS->In.offReadPos, pStreamDS->In.cbBufSize);
     1966
     1967                    PRTCIRCBUF pCircBuf = pStreamDS->pCircBuf;
     1968                    AssertPtr(pCircBuf);
     1969
     1970                    uint32_t cbFree = (uint32_t)RTCircBufFree(pCircBuf);
     1971                    if (!cbFree)
     1972                        DSLOG(("DSound: Warning: Capture buffer full, skipping to record data (%RU32 bytes)\n", cbUsed));
     1973
     1974                    DWORD cbToCapture = RT_MIN(cbUsed, cbFree);
     1975
     1976                    Log3Func(("cbUsed=%ld, cbToCapture=%ld\n", cbUsed, cbToCapture));
     1977
     1978                    while (cbToCapture)
     1979                    {
     1980                        void  *pvBuf;
     1981                        size_t cbBuf;
     1982                        RTCircBufAcquireWriteBlock(pCircBuf, cbToCapture, &pvBuf, &cbBuf);
     1983
     1984                        if (cbBuf)
     1985                        {
     1986                            PVOID pv1, pv2;
     1987                            DWORD cb1, cb2;
     1988                            hr = directSoundCaptureLock(pStreamDS, pStreamDS->In.offReadPos, (DWORD)cbBuf,
     1989                                                        &pv1, &pv2, &cb1, &cb2, 0 /* dwFlags */);
     1990                            if (FAILED(hr))
     1991                                break;
     1992
     1993                            AssertPtr(pv1);
     1994                            Assert(cb1);
     1995
     1996                            memcpy(pvBuf, pv1, cb1);
     1997
     1998                            if (pv2 && cb2) /* Buffer wrap-around? Write second part. */
     1999                                memcpy((uint8_t *)pvBuf + cb1, pv2, cb2);
     2000
     2001                            directSoundCaptureUnlock(pDSCB, pv1, pv2, cb1, cb2);
     2002
     2003                            pStreamDS->In.offReadPos = (pStreamDS->In.offReadPos + cb1 + cb2) % pStreamDS->In.cbBufSize;
     2004
     2005                            Assert(cbToCapture >= cbBuf);
     2006                            cbToCapture -= (uint32_t)cbBuf;
     2007                        }
     2008
     2009#ifdef VBOX_AUDIO_DEBUG_DUMP_PCM_DATA
     2010                        if (cbBuf)
     2011                        {
     2012                            RTFILE fh;
     2013                            int rc2 = RTFileOpen(&fh, VBOX_AUDIO_DEBUG_DUMP_PCM_DATA_PATH "dsoundCapture.pcm",
     2014                                                 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);
     2015                            if (RT_SUCCESS(rc2))
     2016                            {
     2017                                RTFileWrite(fh, pvBuf, cbBuf, NULL);
     2018                                RTFileClose(fh);
     2019                            }
     2020                        }
     2021#endif
     2022                        RTCircBufReleaseWriteBlock(pCircBuf, cbBuf);
     2023                    }
    19892024                }
    19902025                else if (dwObj == DSOUNDEVENT_OUTPUT)
    19912026                {
     2027                    PDSOUNDSTREAM pStreamDS = pThis->pDSStrmOut;
     2028
     2029                    if (   !pStreamDS
     2030                        || !pStreamDS->fEnabled)
     2031                    {
     2032                        Log3Func(("Skipping playback\n"));
     2033                        break;
     2034                    }
     2035
    19922036                    LPDIRECTSOUNDBUFFER8 pDSB = pStreamDS->Out.pDSB;
    1993                     if (!pDSB)
    1994                         break;
     2037                    AssertPtr(pDSB);
    19952038
    19962039                    HRESULT hr;
    1997 
    1998                     DWORD offPlayCursor; DWORD offWriteCursor2;
    1999                     hr = IDirectSoundBuffer8_GetCurrentPosition(pStreamDS->Out.pDSB, &offPlayCursor, &offWriteCursor2);
    2000 
    2001                     //Log3Func(("p=%ld, w=%ld\n", offPlayCursor, offWriteCursor2));
    20022040
    20032041                    DWORD cbFree, cbRemaining;
     
    20052043                    {
    20062044                        DWORD offWriteCursor;
    2007                         hr = IDirectSoundBuffer8_GetCurrentPosition(pStreamDS->Out.pDSB, NULL, &offWriteCursor);
     2045                        hr = IDirectSoundBuffer8_GetCurrentPosition(pDSB, NULL, &offWriteCursor);
    20082046                        if (FAILED(hr))
    20092047                            break;
     
    20172055                    {
    20182056                        DWORD offPlayCursor;
    2019                         hr = IDirectSoundBuffer8_GetCurrentPosition(pStreamDS->Out.pDSB, &offPlayCursor, NULL);
     2057                        hr = IDirectSoundBuffer8_GetCurrentPosition(pDSB, &offPlayCursor, NULL);
    20202058                        if (FAILED(hr))
    20212059                            break;
     
    20252063                    }
    20262064
    2027                     PRTCIRCBUF pCircBuf = pStreamDS->Out.pCircBuf;
     2065                    PRTCIRCBUF pCircBuf = pStreamDS->pCircBuf;
    20282066                    AssertPtr(pCircBuf);
    20292067
    20302068                    DWORD cbUsed   = (uint32_t)RTCircBufUsed(pCircBuf);
     2069                    if (!cbUsed)
     2070                        DSLOG(("DSound: Warning: No more playback data available within time (%RU32 bytes free)\n", cbFree));
     2071
    20312072                    DWORD cbToPlay = RT_MIN(cbFree, cbUsed);
    20322073
    2033                     //Log3Func(("cbUsed=%ld, cbToPlay=%ld\n", cbUsed, cbToPlay));
     2074                    Log3Func(("cbUsed=%ld, cbToPlay=%ld\n", cbUsed, cbToPlay));
    20342075
    20352076                    while (cbToPlay)
     
    20752116                        for (unsigned i = 0; i < DRV_DSOUND_RESTORE_ATTEMPTS_MAX; i++)
    20762117                        {
    2077                             hr = IDirectSoundBuffer8_Play(pStreamDS->Out.pDSB, 0, 0, fFlags);
     2118                            hr = IDirectSoundBuffer8_Play(pDSB, 0, 0, fFlags);
    20782119                            if (   SUCCEEDED(hr)
    20792120                                || hr != DSERR_BUFFERLOST)
     
    20822123                            {
    20832124                                LogFunc(("Restarting playback failed due to lost buffer, restoring ...\n"));
    2084                                 directSoundPlayRestore(pThis, pStreamDS->Out.pDSB);
     2125                                directSoundPlayRestore(pThis, pDSB);
    20852126                            }
    20862127                        }
     
    20992140                        {
    21002141                            DSLOG(("DSound: Stopping playing output\n"));
    2101                             hr = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB);
     2142                            hr = IDirectSoundBuffer8_Stop(pDSB);
    21022143                        }
    21032144                    }
     
    23032344    int rc;
    23042345    if (pStreamDS->pCfg->enmDir == PDMAUDIODIR_IN)
    2305         rc = dsoundDestroyStreamIn(pStreamDS);
     2346        rc = dsoundDestroyStreamIn(pThis, pStreamDS);
    23062347    else
    23072348        rc = dsoundDestroyStreamOut(pThis, pStreamDS);
     
    23522393    PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream;
    23532394
    2354     if (pStreamDS->fEnabled)
    2355         return UINT32_MAX;
     2395    if (   pStreamDS->fEnabled
     2396        && pStreamDS->pCircBuf)
     2397    {
     2398        return (uint32_t)RTCircBufUsed(pStreamDS->pCircBuf);
     2399    }
    23562400
    23572401    return 0;
     
    23702414
    23712415    if (pStreamDS->fEnabled)
    2372         return (uint32_t)RTCircBufFree(pStreamDS->Out.pCircBuf);
     2416        return (uint32_t)RTCircBufFree(pStreamDS->pCircBuf);
    23732417
    23742418    return 0;
     
    23912435
    23922436        /* Any uncommitted data left? */
    2393         if (pStreamDS->Out.pCircBuf)
    2394             cbPending = (uint32_t)RTCircBufUsed(pStreamDS->Out.pCircBuf);
     2437        if (pStreamDS->pCircBuf)
     2438            cbPending = (uint32_t)RTCircBufUsed(pStreamDS->pCircBuf);
    23952439
    23962440        /* Check if we have committed data which still needs to be played by
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