VirtualBox

Changeset 61386 in vbox


Ignore:
Timestamp:
Jun 1, 2016 6:51:16 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
107697
Message:

Audio: Update.

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/pdmaudioifs.h

    r61352 r61386  
    702702
    703703    /**
     704     * Sets the audio volume of a specific audio stream.
     705     *
     706     * @returns VBox status code.
     707     * @param   pInterface      Pointer to the interface structure containing the called function pointer.
     708     * @param   pStream         Pointer to audio stream.
     709     * @param   pVol            Pointer to audio volume structure to set the stream's audio volume to.
     710     */
     711    DECLR3CALLBACKMEMBER(int, pfnStreamSetVolume, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOVOLUME pVol));
     712
     713    /**
    704714     * Plays (transfers) all available audio samples of a an output stream via the connected host backend.
    705715     *
     
    718728
    719729/** PDMIAUDIOCONNECTOR interface ID. */
    720 #define PDMIAUDIOCONNECTOR_IID                  "9E03C980-64E9-42EC-9C70-316995990BE3"
     730#define PDMIAUDIOCONNECTOR_IID                  "9C097435-3276-4D88-A49A-A4FE671D86F8"
    721731
    722732
  • trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp

    r61352 r61386  
    10461046
    10471047    /* Note: Always count in parent samples, as the rate can differ! */
    1048     pSrc->cMixed      = cDstMixed;
    1049     Assert(pSrc->cMixed <= pDst->cSamples);
     1048    pSrc->cMixed      = RT_MIN(cDstMixed, pDst->cSamples);
    10501049
    10511050    pDst->offWrite    = offDstWrite;
     
    15421541    }
    15431542
    1544     PPDMAUDIOMIXBUF pIter;
    1545     while (!RTListIsEmpty(&pMixBuf->lstChildren))
    1546     {
    1547         pIter = RTListGetFirst(&pMixBuf->lstChildren, PDMAUDIOMIXBUF, Node);
    1548 
    1549         AUDMIXBUF_LOG(("\tUnlinking \"%s\"\n", pIter->pszName));
    1550 
    1551         AudioMixBufReset(pIter->pParent);
    1552         pIter->pParent = NULL;
    1553 
    1554         RTListNodeRemove(&pIter->Node);
    1555     }
     1543    PPDMAUDIOMIXBUF pChild, pChildNext;
     1544    RTListForEachSafe(&pMixBuf->lstChildren, pChild, pChildNext, PDMAUDIOMIXBUF, Node)
     1545    {
     1546        AUDMIXBUF_LOG(("\tUnlinking \"%s\"\n", pChild->pszName));
     1547
     1548        AudioMixBufReset(pChild);
     1549
     1550        Assert(pChild->pParent == pMixBuf);
     1551        pChild->pParent = NULL;
     1552
     1553        RTListNodeRemove(&pChild->Node);
     1554    }
     1555
     1556    Assert(RTListIsEmpty(&pMixBuf->lstChildren));
     1557
     1558    AudioMixBufReset(pMixBuf);
    15561559
    15571560    if (pMixBuf->pRate)
  • trunk/src/VBox/Devices/Audio/AudioMixer.cpp

    r61325 r61386  
    867867    RTListForEach(&pSink->lstStreams, pMixStream, AUDMIXSTREAM, Node)
    868868    {
    869         if (fOut)
    870             AudioMixBufSetVolume(&pMixStream->pStream->MixBuf, &volSink);
    871         else
    872             AudioMixBufSetVolume(&pMixStream->pStream->MixBuf, &volSink);
     869        int rc2 = pMixStream->pConn->pfnStreamSetVolume(pMixStream->pConn, pMixStream->pStream, &volSink);
     870        AssertRC(rc2);
    873871    }
    874872
     
    900898    {
    901899        if (!(pMixStream->pConn->pfnStreamGetStatus(pMixStream->pConn, pMixStream->pStream) & PDMAUDIOSTRMSTS_FLAG_ENABLED))
     900        {
     901            LogFlowFunc(("%s: Disabled, skipping ...\n", pSink->pszName));
    902902            continue;
     903        }
    903904
    904905        int rc2 = pMixStream->pConn->pfnStreamWrite(pMixStream->pConn, pMixStream->pStream, pvBuf, cbBuf, &cbProcessed);
  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r61320 r61386  
    13761376    pThis->uTimerTS = cTicksNow;
    13771377
     1378    LogFlowFuncEnter();
     1379
    13781380    uint32_t cbLineIn;
    13791381    AudioMixerSinkTimerUpdate(pThis->pSinkLineIn, pThis->cTimerTicks, cTicksPerSec, &cbLineIn);
  • trunk/src/VBox/Devices/Audio/DevIchHda.cpp

    r61167 r61386  
    34653465        Assert(cbRead <= cbBuf);
    34663466        Assert(cbRead <= pBDLE->u32BufSize - pBDLE->State.u32BufOff);
    3467         //Assert(cbRead <= pStream->u16FIFOS);
    34683467
    34693468        /*
     
    34773476        if (pBDLE->State.cbBelowFIFOW + cbRead > hdaStreamGetFIFOW(pThis, pStream))
    34783477        {
     3478            Assert(pBDLE->State.u32BufOff + cbRead <= pBDLE->u32BufSize);
    34793479            pBDLE->State.u32BufOff    += cbRead;
    34803480            pBDLE->State.cbBelowFIFOW  = 0;
     
    34833483        else
    34843484        {
     3485            Assert(pBDLE->State.u32BufOff + cbRead <= pBDLE->u32BufSize);
    34853486            pBDLE->State.u32BufOff    += cbRead;
    34863487            pBDLE->State.cbBelowFIFOW += cbRead;
     
    36283629        else
    36293630        {
    3630             pBDLE->State.u32BufOff += cbWritten;
     3631            Assert(pBDLE->State.u32BufOff + cbWritten <= pBDLE->u32BufSize);
     3632            pBDLE->State.u32BufOff    += cbWritten;
    36313633            pBDLE->State.cbBelowFIFOW += cbWritten;
    36323634            Assert(pBDLE->State.cbBelowFIFOW <= hdaStreamGetFIFOW(pThis, pStream));
  • trunk/src/VBox/Devices/Audio/DevSB16.cpp

    r61334 r61386  
    434434    if (hold)
    435435    {
     436#ifndef VBOX_WITH_AUDIO_CALLBACKS
    436437        pThis->cStreamsActive++;
    437 #ifndef VBOX_WITH_AUDIO_CALLBACKS
    438438        sb16TimerMaybeStart(pThis);
    439439#endif
     
    10391039            else
    10401040                TMTimerSet(pThis->pTimerIRQ, TMTimerGet(pThis->pTimerIRQ) + ticks);
    1041             LogFlowFunc(("mix silence %d %d % %RU64\n", samples, bytes, ticks));
     1041            LogFlowFunc(("mix silence: %d samples, %d bytes, %RU64 ticks\n", samples, bytes, ticks));
    10421042            break;
    10431043        }
     
    11081108    uint8_t lvol = sb16MixRegToVol(pThis, 0x30);
    11091109    uint8_t rvol = sb16MixRegToVol(pThis, 0x31);
    1110     PDMAUDIOVOLUME vol = { false, lvol, rvol };
    1111 
    1112 //    AudioMixerSetMasterVolume(pThis->pMixer, &vol);
     1110
     1111    PDMAUDIOVOLUME Vol = { false /* fMute */, lvol, rvol };
     1112
     1113    PSB16DRIVER pDrv;
     1114    RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
     1115    {
     1116        int rc2 = pDrv->pConnector->pfnStreamSetVolume(pDrv->pConnector, pDrv->Out.pStream, &Vol);
     1117        AssertRC(rc2);
     1118    }
    11131119}
    11141120
     
    11181124    uint8_t lvol = sb16MixRegToVol(pThis, 0x32);
    11191125    uint8_t rvol = sb16MixRegToVol(pThis, 0x33);
    1120     PDMAUDIOVOLUME vol = { false, lvol, rvol };
    1121 
    1122   //  AudioMixerSinkSetVolume(pThis->pSinkOutput, &vol);
     1126
     1127    PDMAUDIOVOLUME Vol = { false /* fMute */, lvol, rvol };
     1128
     1129    PSB16DRIVER pDrv;
     1130    RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
     1131    {
     1132        int rc2 = pDrv->pConnector->pfnStreamSetVolume(pDrv->pConnector, pDrv->Out.pStream, &Vol);
     1133        AssertRC(rc2);
     1134    }
    11231135}
    11241136
    11251137static void sb16ResetLegacy(PSB16STATE pThis)
    11261138{
     1139    LogFlowFuncEnter();
     1140
    11271141    sb16CloseOut(pThis);
    11281142
     
    11681182    dsp_out_data(pThis, 0xaa);
    11691183    sb16SpeakerControl(pThis, 0);
     1184
    11701185    sb16Control(pThis, 0);
    11711186    sb16ResetLegacy(pThis);
     
    17811796            continue;
    17821797
    1783         PDMAUDIOSTRMSTS strmSts = pDrv->pConnector->pfnStreamGetStatus(pDrv->pConnector, pStream);
    1784         fIsPlaying |= (   (strmSts & PDMAUDIOSTRMSTS_FLAG_ENABLED)
    1785                        || (strmSts & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE));
    1786 
    1787         LogFlowFunc(("%s: strmSts=0x%x -> fIsPlaying=%RTbool\n", pStream->szName, strmSts, fIsPlaying));
    1788 
    17891798        int rc2 = pDrv->pConnector->pfnStreamIterate(pDrv->pConnector, pStream);
    17901799        if (RT_SUCCESS(rc2))
     
    18011810            }
    18021811        }
     1812
     1813        PDMAUDIOSTRMSTS strmSts = pDrv->pConnector->pfnStreamGetStatus(pDrv->pConnector, pStream);
     1814        fIsPlaying |= (   (strmSts & PDMAUDIOSTRMSTS_FLAG_ENABLED)
     1815                       || (strmSts & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE));
     1816
     1817        LogFlowFunc(("%s: strmSts=0x%x -> fIsPlaying=%RTbool\n", pStream->szName, strmSts, fIsPlaying));
    18031818    }
    18041819
     
    18141829        TMTimerSet(pThis->pTimerIO, cTicksNow + cTicks);
    18151830    }
     1831
     1832    LogFlowFuncLeave();
    18161833}
    18171834
     
    20352052    AssertPtrReturn(pCfg,  VERR_INVALID_POINTER);
    20362053
     2054    LogFlowFuncEnter();
     2055
    20372056    AssertReturn(pCfg->enmDir == PDMAUDIODIR_OUT, VERR_INVALID_PARAMETER);
    2038 
    2039     int rc = VINF_SUCCESS;
    20402057
    20412058    /* Set a default audio format for the host. */
     
    20522069    uint8_t uLUN = 0;
    20532070
     2071    int rc = VINF_SUCCESS;
     2072
    20542073    PSB16DRIVER pDrv;
    20552074    RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
     
    20622081        }
    20632082
     2083        int rc2;
     2084
    20642085        if (pDrv->Out.pStream)
    20652086        {
    20662087            pDrv->pConnector->pfnStreamRelease(pDrv->pConnector, pDrv->Out.pStream);
    20672088
    2068             int rc3 = pDrv->pConnector->pfnStreamDestroy(pDrv->pConnector, pDrv->Out.pStream);
    2069             AssertRC(rc3);
    2070 
    2071             pDrv->Out.pStream = NULL;
     2089            rc2 = pDrv->pConnector->pfnStreamDestroy(pDrv->pConnector, pDrv->Out.pStream);
     2090            if (RT_SUCCESS(rc2))
     2091                pDrv->Out.pStream = NULL;
    20722092        }
    2073 
    2074         int rc2 = pDrv->pConnector->pfnStreamCreate(pDrv->pConnector, &CfgHost, pCfg, &pDrv->Out.pStream);
     2093        else
     2094            rc2 = VINF_SUCCESS;
     2095
    20752096        if (RT_SUCCESS(rc2))
    2076             pDrv->pConnector->pfnStreamAddRef(pDrv->pConnector, pDrv->Out.pStream);
     2097        {
     2098            rc2 = pDrv->pConnector->pfnStreamCreate(pDrv->pConnector, &CfgHost, pCfg, &pDrv->Out.pStream);
     2099            if (RT_SUCCESS(rc2))
     2100                pDrv->pConnector->pfnStreamAddRef(pDrv->pConnector, pDrv->Out.pStream);
     2101        }
    20772102
    20782103        LogFlowFunc(("LUN#%RU8: Created output \"%s\", rc=%Rrc\n", pDrv->uLUN, pCfg->szName, rc2));
     
    20812106    }
    20822107
     2108    LogFlowFuncLeaveRC(rc);
    20832109    return rc;
    20842110}
     
    20972123            pDrv->pConnector->pfnStreamRelease(pDrv->pConnector, pDrv->Out.pStream);
    20982124
    2099             pDrv->pConnector->pfnStreamDestroy(pDrv->pConnector, pDrv->Out.pStream);
    2100             pDrv->Out.pStream = NULL;
     2125            int rc2 = pDrv->pConnector->pfnStreamDestroy(pDrv->pConnector, pDrv->Out.pStream);
     2126            if (RT_SUCCESS(rc2))
     2127                pDrv->Out.pStream = NULL;
    21012128        }
    21022129    }
     2130
     2131    LogFlowFuncLeave();
    21032132}
    21042133
  • trunk/src/VBox/Devices/Audio/DrvAudio.cpp

    r61337 r61386  
    6666
    6767static DECLCALLBACK(int) drvAudioStreamDestroy(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream);
     68static int drvAudioStreamControlInternalBackend(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd);
    6869static int drvAudioStreamControlInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd);
    69 static int drvAudioStreamControlInternalBackend(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd);
    7070static int drvAudioStreamDestroyInternalBackend(PDRVAUDIO pThis, PPDMAUDIOSTREAM pHstStream);
    7171static int drvAudioStreamDestroyInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream);
     72static int drvAudioStreamIterateInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream);
    7273
    7374#ifndef VBOX_AUDIO_TESTCASE
     
    154155                               ? pStream
    155156                               : pStream->pPair;
     157    if (pStreamHst)
     158    {
     159        Assert(pStreamHst->enmCtx == PDMAUDIOSTREAMCTX_HOST);
     160    }
     161    else
     162        LogFlowFunc(("%s: Warning: Does not have a host stream (anymore)\n", pStream->szName));
     163
    156164    return pStreamHst;
    157165}
     
    263271        return rc;
    264272
    265     LogFlowFunc(("%s\n", pStream->szName));
     273    LogFlowFunc(("%s: enmStreamCmd=%ld\n", pStream->szName, enmStreamCmd));
     274
     275    rc = drvAudioStreamControlInternal(pThis, pStream, enmStreamCmd);
     276
     277    int rc2 = RTCritSectLeave(&pThis->CritSect);
     278    if (RT_SUCCESS(rc))
     279        rc = rc2;
     280
     281    return rc;
     282}
     283
     284static int drvAudioStreamControlInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
     285{
     286    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
     287    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
     288
     289    LogFlowFunc(("%s: enmStreamCmd=%ld\n", pStream->szName, enmStreamCmd));
    266290
    267291    PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream);
    268     PPDMAUDIOSTREAM pGstStream = pHstStream->pPair;
    269 
    270     /* Note: Call the host (backend) first to see if there is any pending disable
    271      *       actions in progress. */
    272     rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, enmStreamCmd);
    273     if (   RT_SUCCESS(rc)
    274         || rc == VERR_AUDIO_STREAM_PENDING_DISABLE)
    275     {
    276         int rc3 = drvAudioStreamControlInternal(pThis, pStream, enmStreamCmd);
    277         if (RT_SUCCESS(rc))
    278             rc = rc3;
    279     }
    280 
    281     int rc2 = RTCritSectLeave(&pThis->CritSect);
    282     if (RT_SUCCESS(rc))
    283         rc = rc2;
    284 
    285     return rc;
    286 }
    287 
    288 static int drvAudioStreamControlInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pGstStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    289 {
    290     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
    291 
    292     if (!pGstStream)
    293         return VINF_SUCCESS;
     292    PPDMAUDIOSTREAM pGstStream = pHstStream ? pHstStream->pPair : pStream;
     293    AssertPtr(pGstStream);
    294294
    295295    int rc = VINF_SUCCESS;
     
    299299        case PDMAUDIOSTREAMCMD_ENABLE:
    300300        {
    301             pGstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_ENABLED;
     301            if (!(pGstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED))
     302            {
     303                if (pHstStream)
     304                {
     305                    /* Is a pending disable outstanding? Then disable first. */
     306                    if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE)
     307                        rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE);
     308
     309                    if (RT_SUCCESS(rc))
     310                        rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_ENABLE);
     311                }
     312
     313                pGstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_ENABLED;
     314            }
    302315            break;
    303316        }
    304317
    305318        case PDMAUDIOSTREAMCMD_DISABLE:
    306         {
    307             pGstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_ENABLED;
     319        case PDMAUDIOSTREAMCMD_PAUSE:
     320        {
     321            if (pGstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED)
     322            {
     323                /* Is the guest side stream still active?
     324                 * Mark the host stream as pending disable and bail out. */
     325                if (pHstStream)
     326                {
     327                    LogFlowFunc(("%s: Pending disable/pause\n", pHstStream->szName));
     328                    pHstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE;
     329                }
     330
     331                if (enmStreamCmd == PDMAUDIOSTREAMCMD_DISABLE)
     332                {
     333                    pGstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_ENABLED;
     334                }
     335                else if (enmStreamCmd == PDMAUDIOSTREAMCMD_PAUSE)
     336                    pGstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_PAUSED;
     337                else
     338                    AssertFailedBreakStmt(rc = VERR_NOT_IMPLEMENTED);
     339            }
     340
     341            if (   pHstStream
     342                && !(pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE))
     343            {
     344                rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, enmStreamCmd);
     345                if (RT_SUCCESS(rc))
     346                    pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE;
     347            }
    308348            break;
    309349        }
    310350
    311         case PDMAUDIOSTREAMCMD_PAUSE:
    312         {
    313             pGstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_PAUSED;
    314             break;
    315         }
    316 
    317351        case PDMAUDIOSTREAMCMD_RESUME:
    318352        {
    319             pGstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PAUSED;
     353            if (pGstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PAUSED)
     354            {
     355                if (pHstStream)
     356                    rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_RESUME);
     357
     358                pGstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PAUSED;
     359            }
    320360            break;
    321361        }
     
    327367    }
    328368
    329     LogFlowFunc(("%s: enmStreamCmd=%ld, rc=%Rrc\n", pGstStream->szName, enmStreamCmd, rc));
     369    if (RT_FAILURE(rc))
     370        LogFunc(("%s: Failed with %Rrc\n", pStream->szName, rc));
     371
    330372    return rc;
    331373}
    332374
    333 static int drvAudioStreamControlInternalBackend(PDRVAUDIO pThis, PPDMAUDIOSTREAM pHstStream, PDMAUDIOSTREAMCMD enmStreamCmd)
    334 {
    335     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
    336 
    337     if (!pHstStream)
    338         return VINF_SUCCESS;
    339 
    340     AssertMsg(pHstStream->enmCtx == PDMAUDIOSTREAMCTX_HOST,
    341               ("Stream '%s' is not a host stream and therefore has no backend\n", pHstStream->szName));
    342 
    343     LogFlowFunc(("%s: enmStreamCmd=%ld\n", pHstStream->szName, enmStreamCmd));
     375static int drvAudioStreamControlInternalBackend(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
     376{
     377    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
     378    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
     379
     380    LogFlowFunc(("%s: enmStreamCmd=%ld\n", pStream->szName, enmStreamCmd));
     381
     382    PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream);
     383    AssertPtr(pHstStream);
     384
     385    AssertPtr(pThis->pHostDrvAudio);
    344386
    345387    int rc = VINF_SUCCESS;
    346388
    347     PPDMAUDIOSTREAM pGstStream = pHstStream->pPair; /* Can be NULL. */
    348 
    349389    switch (enmStreamCmd)
    350390    {
     
    353393            if (!(pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED))
    354394            {
    355                 if (pThis->pHostDrvAudio)
    356                     rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_ENABLE);
     395                rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_ENABLE);
    357396                if (RT_SUCCESS(rc))
    358397                    pHstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_ENABLED;
     
    363402        case PDMAUDIOSTREAMCMD_DISABLE:
    364403        {
    365             /* Is the guest side stream still active?
    366              * Mark the host stream as pending disable and bail out. */
    367             if (   pGstStream
    368                 && (pGstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED))
    369             {
    370                 LogFlowFunc(("%s: Pending disable\n", pHstStream->szName));
    371                 pHstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE;
    372                 rc = VERR_AUDIO_STREAM_PENDING_DISABLE;
    373                 break;
    374             }
    375 
    376             /* Clear pending disable bit. */
    377             pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE;
    378 
    379404            if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED)
    380405            {
    381                 if (pThis->pHostDrvAudio)
    382                     rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_DISABLE);
     406                rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_DISABLE);
    383407                if (RT_SUCCESS(rc))
    384408                {
     
    392416        case PDMAUDIOSTREAMCMD_PAUSE:
    393417        {
    394             /* Is the guest side stream still active?
    395              * Mark the host stream as pending disable and bail out. */
    396             if (   pGstStream
    397                 && (pGstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED))
    398             {
    399                 LogFlowFunc(("%s: Pending pause\n", pHstStream->szName));
    400                 pHstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE;
    401                 rc = VERR_AUDIO_STREAM_PENDING_DISABLE;
    402                 break;
    403             }
    404 
    405418            if (!(pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PAUSED))
    406419            {
    407                 if (pThis->pHostDrvAudio)
    408                     rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_PAUSE);
     420                rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_PAUSE);
    409421                if (RT_SUCCESS(rc))
    410422                    pHstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_PAUSED;
     
    417429            if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PAUSED)
    418430            {
    419                 if (pThis->pHostDrvAudio)
    420                     rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_RESUME);
     431                rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_RESUME);
    421432                if (RT_SUCCESS(rc))
    422433                    pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PAUSED;
     
    432443
    433444    if (RT_FAILURE(rc))
    434         LogFunc(("%s: Failed with %Rrc\n", pHstStream->szName, rc));
     445        LogFunc(("%s: Failed with %Rrc\n", pStream->szName, rc));
    435446
    436447    return rc;
     
    671682   NOREF(pInterface);
    672683
    673    Assert(pStream->cRefs);
    674    if (pStream->cRefs)
     684   if (pStream->cRefs > 1) /* 1 reference always is kept by this audio driver. */
    675685       pStream->cRefs--;
    676686
     
    682692{
    683693    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     694    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    684695    /* pcData is optional. */
     696
     697    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
     698
     699    int rc = RTCritSectEnter(&pThis->CritSect);
     700    if (RT_FAILURE(rc))
     701        return rc;
     702
     703    LogFlowFunc(("%s\n", pStream->szName));
     704
     705    rc = drvAudioStreamIterateInternal(pThis, pStream);
     706
     707    int rc2 = RTCritSectLeave(&pThis->CritSect);
     708    if (RT_SUCCESS(rc))
     709        rc = rc2;
     710
     711    if (RT_FAILURE(rc))
     712        LogFlowFuncLeaveRC(rc);
     713
     714    return rc;
     715}
     716
     717static int drvAudioStreamIterateInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream)
     718{
     719    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
    685720
    686721    if (!pStream)
    687722        return VINF_SUCCESS;
    688723
    689     PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
    690 
    691     int rc = RTCritSectEnter(&pThis->CritSect);
    692     if (RT_FAILURE(rc))
    693         return rc;
    694 
    695     LogFlowFunc(("[%s]\n", pStream->szName));
     724    LogFlowFunc(("%s\n", pStream->szName));
    696725
    697726    PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream);
    698727    PPDMAUDIOSTREAM pGstStream = pHstStream->pPair;
     728
     729    int rc = VINF_SUCCESS;
    699730
    700731    do
     
    721752            uint32_t cSamplesToMix = AudioMixBufUsed(&pGstStream->MixBuf);
    722753
    723             /* Has this stream marked as disabled but there still were guest streams relying
    724              * on it? CheckpHstStreamif this stream now can be closed and do so, if possible. */
    725             if (   (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE)
    726                 && !cSamplesToMix)
    727             {
    728                 rc = drvAudioStreamControlInternal(pThis, pGstStream, PDMAUDIOSTREAMCMD_DISABLE);
    729                 if (RT_SUCCESS(rc))
    730                     rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE);
    731 
    732                 if (RT_FAILURE(rc))
    733                     LogFunc(("%s: Backend vetoed against closing output stream, rc=%Rrc\n", pHstStream->szName, rc));
    734 
    735                 break;
    736             }
    737 
    738             uint32_t cSamplesPlayed = 0;
    739             if (hstStrmSts & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE)
    740             {
     754            if (cSamplesToMix)
     755            {
     756                uint32_t cSamplesPlayed = 0;
     757                if (hstStrmSts & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE)
     758                {
    741759            /*    int rc2 = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream, &cSamplesPlayed);
    742760                if (RT_SUCCESS(rc))
     
    744762            }*/
    745763
    746                 if (cSamplesToMix)
    747764                    rc = AudioMixBufMixToParent(&pGstStream->MixBuf, cSamplesToMix, &cSamplesMixed);
    748             }
    749 
    750             LogFlowFunc(("%s: %RU32/%RU32 samples mixed, %RU32 played\n",
    751                          pHstStream->szName, cSamplesMixed, cSamplesToMix, cSamplesPlayed));
     765
     766                    LogFlowFunc(("%s: %RU32/%RU32 samples mixed, rc=%Rrc\n",
     767                                 pHstStream->szName, cSamplesMixed, cSamplesToMix, rc));
     768                }
     769            }
    752770        }
    753771
     
    756774
    757775    } while (0);
    758 
    759     int rc2 = RTCritSectLeave(&pThis->CritSect);
    760     if (RT_SUCCESS(rc))
    761         rc = rc2;
    762 
    763     if (RT_FAILURE(rc))
    764         LogFlowFuncLeaveRC(rc);
    765776
    766777    return rc;
     
    973984        AssertPtr(pGstStream);
    974985
    975         PDMAUDIOSTRMSTS strmSts = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream);
    976 
    977         if (strmSts & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE)
    978         {
    979             rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream, &cSamplesPlayed);
    980             if (RT_FAILURE(rc))
    981             {
    982                 int rc3 = drvAudioStreamControlInternalBackend(pThis, pStream, PDMAUDIOSTREAMCMD_DISABLE);
    983                 AssertRC(rc3);
    984             }
    985         }
    986 
    987         LogFlowFunc(("[%s] strmSts=0x%x, cSamplesPlayed=%RU32, rc=%Rrc\n", pStream->szName, strmSts, cSamplesPlayed, rc));
    988 
     986        uint32_t cSamplesLive = AudioMixBufUsed(&pHstStream->MixBuf);
     987        if (cSamplesLive)
     988        {
     989            PDMAUDIOSTRMSTS strmSts = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream);
     990            if (strmSts & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE)
     991            {
     992                rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream, &cSamplesPlayed);
     993                if (RT_FAILURE(rc))
     994                    drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE);
     995            }
     996
     997            LogFlowFunc(("[%s] strmSts=0x%x, cSamplesPlayed=%RU32, rc=%Rrc\n", pStream->szName, strmSts, cSamplesPlayed, rc));
     998
     999            if (RT_SUCCESS(rc))
     1000            {
     1001                rc = drvAudioStreamIterateInternal(pThis, pStream);
     1002                if (RT_SUCCESS(rc))
     1003                    cSamplesLive = AudioMixBufUsed(&pHstStream->MixBuf);
     1004            }
     1005        }
     1006
     1007        if (!cSamplesLive)
     1008        {
     1009            /* Has the host stream marked as disabled but there still were guest streams relying
     1010             * on it? Check if the stream now can be closed and do so, if possible. */
     1011            if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE)
     1012            {
     1013                LogFunc(("%s: Closing pending stream\n", pHstStream->szName));
     1014                rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE);
     1015                if (RT_SUCCESS(rc))
     1016                {
     1017                    pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE;
     1018                }
     1019                else
     1020                    LogFunc(("%s: Backend vetoed against closing output stream, rc=%Rrc\n", pHstStream->szName, rc));
     1021            }
     1022        }
    9891023    #if 0
    9901024            if (pStream->pPair)
     
    13321366        return;
    13331367
    1334     PPDMAUDIOSTREAM pStream;
    1335     RTListForEach(&pThis->lstStreams, pStream, PDMAUDIOSTREAM, Node)
    1336         drvAudioStreamControlInternal(pThis, pStream, enmCmd);
     1368    PPDMAUDIOSTREAM pHstStream;
     1369    RTListForEach(&pThis->lstHstStreams, pHstStream, PDMAUDIOSTREAM, Node)
     1370        drvAudioStreamControlInternalBackend(pThis, pHstStream, enmCmd);
    13371371}
    13381372
     
    13451379    LogFlowFunc(("pThis=%p, pDrvIns=%p\n", pThis, pDrvIns));
    13461380
    1347     RTListInit(&pThis->lstStreams);
     1381    RTListInit(&pThis->lstHstStreams);
     1382    RTListInit(&pThis->lstGstStreams);
    13481383#ifdef VBOX_WITH_AUDIO_CALLBACKS
    13491384    RTListInit(&pThis->lstCBIn);
     
    16471682        AssertPtrBreakStmt(pHstStrm, rc = VERR_NO_MEMORY);
    16481683
    1649         RTListAppend(&pThis->lstStreams, &pHstStrm->Node);
     1684        pHstStrm->enmCtx = PDMAUDIOSTREAMCTX_HOST;
     1685        pHstStrm->enmDir = pCfgHost->enmDir;
     1686
     1687        RTListAppend(&pThis->lstHstStreams, &pHstStrm->Node);
    16501688
    16511689        pGstStrm = (PPDMAUDIOSTREAM)RTMemAllocZ(sizeof(PDMAUDIOSTREAM));
    16521690        AssertPtrBreakStmt(pGstStrm, rc = VERR_NO_MEMORY);
    16531691
    1654         RTListAppend(&pThis->lstStreams, &pGstStrm->Node);
     1692        pGstStrm->enmCtx = PDMAUDIOSTREAMCTX_GUEST;
     1693        pGstStrm->enmDir = pCfgGuest->enmDir;
     1694
     1695        RTListAppend(&pThis->lstGstStreams, &pGstStrm->Node);
    16551696
    16561697        /*
     
    16701711        }
    16711712
    1672         pHstStrm->enmCtx   = PDMAUDIOSTREAMCTX_HOST;
    1673         pHstStrm->enmDir   = pCfgHost->enmDir;
    16741713        pHstStrm->fStatus |= PDMAUDIOSTRMSTS_FLAG_INITIALIZED;
    16751714        pHstStrm->pPair    = pGstStrm;
     
    17061745        }
    17071746
    1708         pGstStrm->enmCtx   = PDMAUDIOSTREAMCTX_GUEST;
    1709         pGstStrm->enmDir   = pCfgGuest->enmDir;
    17101747        pGstStrm->fStatus |= PDMAUDIOSTRMSTS_FLAG_INITIALIZED;
    17111748        pGstStrm->pPair    = pHstStrm;
     
    17191756    if (RT_FAILURE(rc))
    17201757    {
    1721         if (   pHstStrm
    1722             && pHstStrm->enmCtx == PDMAUDIOSTREAMCTX_HOST)
    1723         {
    1724             if (pHstStrm->fStatus & PDMAUDIOSTRMSTS_FLAG_INITIALIZED)
    1725             {
    1726                 rc = drvAudioStreamControlInternalBackend(pThis, pHstStrm, PDMAUDIOSTREAMCMD_DISABLE);
    1727                 if (RT_SUCCESS(rc))
    1728                 {
    1729                     rc = pThis->pHostDrvAudio->pfnStreamDestroy(pThis->pHostDrvAudio, pHstStrm);
    1730                     if (RT_SUCCESS(rc))
    1731                         pHstStrm->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_INITIALIZED;
    1732                 }
    1733             }
    1734 
    1735             AssertMsgRC(rc, ("Host stream '%s' failed to uninit in backend: %Rrc\n",  pHstStrm->szName, rc));
    1736         }
    1737 
    17381758        drvAudioStreamDestroyInternal(pThis, pGstStrm);
    17391759        pGstStrm = NULL;
     
    17591779        }
    17601780
     1781        /* Always return the guest-side part to the device emulation. */
    17611782        *ppStream = pGstStrm;
    17621783    }
     
    18151836{
    18161837    AssertPtrReturn(pInterface, false);
    1817     /* pStream is optional. */
    1818 
    1819     if (!pStream)
    1820         return PDMAUDIOSTRMSTS_FLAG_NONE;
     1838    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    18211839
    18221840    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
     
    18341852    return strmSts;
    18351853}
     1854
     1855static DECLCALLBACK(int) drvAudioStreamSetVolume(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOVOLUME pVol)
     1856{
     1857    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     1858    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
     1859    AssertPtrReturn(pVol,       VERR_INVALID_POINTER);
     1860
     1861    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
     1862
     1863    LogFlowFunc(("%s: volL=%RU32, volR=%RU32, fMute=%RTbool\n", pStream->szName, pVol->uLeft, pVol->uRight, pVol->fMuted));
     1864
     1865    AudioMixBufSetVolume(&pStream->MixBuf, pVol);
     1866
     1867    return VINF_SUCCESS;
     1868}
    18361869#endif
    18371870
    18381871static DECLCALLBACK(int) drvAudioStreamDestroy(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream)
    18391872{
     1873    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     1874    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
     1875
    18401876    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
    18411877
     
    18511887    if (RT_SUCCESS(rc))
    18521888    {
    1853         rc = drvAudioStreamDestroyInternal(pThis, pStream);
    1854         if (RT_SUCCESS(rc))
    1855             pStream = NULL;
     1889        PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream);
     1890        PPDMAUDIOSTREAM pGstStream = pHstStream ? pHstStream->pPair : pStream;
     1891
     1892        LogFlowFunc(("\tHost : %s\n", pHstStream ? pHstStream->szName : "<None>"));
     1893        LogFlowFunc(("\tGuest: %s\n", pGstStream ? pGstStream->szName : "<None>"));
     1894
     1895        /* Should prevent double frees. */
     1896        Assert(pHstStream != pGstStream);
     1897
     1898        if (pHstStream)
     1899        {
     1900            pHstStream->pPair = NULL;
     1901            RTListNodeRemove(&pHstStream->Node);
     1902        }
     1903
     1904        if (pGstStream)
     1905        {
     1906            pGstStream->pPair = NULL;
     1907            RTListNodeRemove(&pGstStream->Node);
     1908        }
     1909
     1910        if (pHstStream)
     1911        {
     1912            rc = drvAudioStreamDestroyInternal(pThis, pHstStream);
     1913            AssertRC(rc);
     1914
     1915            pHstStream = NULL;
     1916        }
     1917
     1918        if (pGstStream)
     1919        {
     1920            rc = drvAudioStreamDestroyInternal(pThis, pGstStream);
     1921            AssertRC(rc);
     1922
     1923            pGstStream = NULL;
     1924        }
    18561925    }
    18571926
     
    18721941        rc = rc2;
    18731942
    1874     if (RT_FAILURE(rc))
    1875         LogFlowFunc(("Failed with %Rrc\n", rc));
    1876 
     1943    LogFlowFuncLeaveRC(rc);
    18771944    return rc;
    18781945}
     
    18801947static int drvAudioStreamDestroyInternalBackend(PDRVAUDIO pThis, PPDMAUDIOSTREAM pHstStream)
    18811948{
    1882     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
    1883 
    1884     if (!pHstStream)
    1885         return VINF_SUCCESS;
    1886 
    1887     AssertPtr(pThis->pHostDrvAudio);
     1949    AssertPtrReturn(pThis,      VERR_INVALID_POINTER);
     1950    AssertPtrReturn(pHstStream, VERR_INVALID_POINTER);
     1951
    18881952    AssertMsg(pHstStream->enmCtx == PDMAUDIOSTREAMCTX_HOST,
    18891953              ("Stream '%s' is not a host stream and therefore has no backend\n", pHstStream->szName));
     
    18951959    if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_INITIALIZED)
    18961960    {
    1897         rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE);
     1961        if (pThis->pHostDrvAudio)
     1962            rc = pThis->pHostDrvAudio->pfnStreamDestroy(pThis->pHostDrvAudio, pHstStream);
    18981963        if (RT_SUCCESS(rc))
    1899         {
    1900             rc = pThis->pHostDrvAudio->pfnStreamDestroy(pThis->pHostDrvAudio, pHstStream);
    1901             if (RT_SUCCESS(rc))
    1902                 pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_INITIALIZED;
    1903         }
    1904     }
    1905     else
    1906         rc = VINF_SUCCESS;
     1964            pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_INITIALIZED;
     1965    }
    19071966
    19081967    LogFlowFunc(("%s: Returning %Rrc\n", pHstStream->szName, rc));
     
    19121971static int drvAudioStreamDestroyInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream)
    19131972{
    1914     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
    1915     /* pStream is optional. */
    1916 
    1917     if (!pStream)
    1918         return VINF_SUCCESS;
     1973    AssertPtrReturn(pThis,   VERR_INVALID_POINTER);
     1974    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    19191975
    19201976    LogFlowFunc(("%s: cRefs=%RU32\n", pStream->szName, pStream->cRefs));
    19211977
    1922     /* Try to find out which stream is which -- both streams could be destroyed (NULL)
    1923      * already, so do some additional checking here. */
    1924     PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream);
    1925     PPDMAUDIOSTREAM pGstStream = pHstStream ? pHstStream->pPair : pStream;
    1926 
    1927     if (   (   pHstStream
    1928             && pHstStream->cRefs > 1)
    1929         || (   pGstStream
    1930             && pGstStream->cRefs > 1)
    1931        )
    1932     {
     1978    if (pStream->cRefs > 1)
    19331979        return VERR_WRONG_ORDER;
    1934     }
    19351980
    19361981    int rc = VINF_SUCCESS;
    19371982
    1938     if (pGstStream)
    1939     {
    1940         AssertMsg(pGstStream->enmCtx == PDMAUDIOSTREAMCTX_GUEST,
    1941                   ("Stream '%s' is not a guest stream\n", pGstStream->szName));
    1942 
    1943         rc = drvAudioStreamControlInternal(pThis, pGstStream, PDMAUDIOSTREAMCMD_DISABLE);
    1944     }
    1945 
    1946     if (RT_SUCCESS(rc))
    1947         rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE);
    1948 
    1949     if (RT_SUCCESS(rc))
    1950     {
    1951         /* Unlink from pair. */
    1952         if (pStream->pPair)
    1953         {
    1954             pStream->pPair->pPair = NULL;
    1955             pStream->pPair = NULL;
    1956         }
    1957 
     1983    if (pStream->enmCtx == PDMAUDIOSTREAMCTX_GUEST)
     1984    {
     1985        if (pStream->fStatus & PDMAUDIOSTRMSTS_FLAG_INITIALIZED)
     1986        {
     1987            rc = drvAudioStreamControlInternal(pThis, pStream, PDMAUDIOSTREAMCMD_DISABLE);
     1988            if (RT_SUCCESS(rc))
     1989                pStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_INITIALIZED;
     1990        }
     1991    }
     1992    else if (pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST)
     1993    {
     1994        rc = drvAudioStreamDestroyInternalBackend(pThis, pStream);
     1995    }
     1996    else
     1997        AssertFailedReturn(VERR_NOT_IMPLEMENTED);
     1998
     1999    if (RT_SUCCESS(rc))
     2000    {
    19582001        /* Destroy mixing buffer. */
    19592002        AudioMixBufDestroy(&pStream->MixBuf);
    19602003
    1961         /* Remove from list. */
    1962         RTListNodeRemove(&pStream->Node);
    1963 
    1964         RTMemFree(pStream);
    1965         pStream = NULL;
    1966     }
    1967 
    1968     if (RT_FAILURE(rc))
    1969         LogFunc(("Failed with %Rrc\n", rc));
    1970 
     2004        if (pStream)
     2005        {
     2006            RTMemFree(pStream);
     2007            pStream = NULL;
     2008        }
     2009    }
     2010
     2011    LogFlowFunc(("Returning %Rrc\n", rc));
    19712012    return rc;
    19722013}
     
    20012042    LogFlowFuncEnter();
    20022043
    2003     PPDMAUDIOSTREAM pStream, pStreamNext;
    2004     RTListForEachSafe(&pThis->lstStreams, pStream, pStreamNext, PDMAUDIOSTREAM, Node)
    2005         drvAudioStreamDestroyInternal(pThis, pStream);
     2044    /* Just destroy the host stream on the backend side.
     2045     * The rest will either be destructed by the device emulation or
     2046     * in drvAudioDestruct(). */
     2047    PPDMAUDIOSTREAM pStream;
     2048    RTListForEach(&pThis->lstHstStreams, pStream, PDMAUDIOSTREAM, Node)
     2049        drvAudioStreamDestroyInternalBackend(pThis, pStream);
    20062050
    20072051    /*
     
    20472091    pThis->IAudioConnector.pfnStreamIterate     = drvAudioStreamIterate;
    20482092    pThis->IAudioConnector.pfnStreamGetStatus   = drvAudioStreamGetStatus;
     2093    pThis->IAudioConnector.pfnStreamSetVolume   = drvAudioStreamSetVolume;
    20492094    pThis->IAudioConnector.pfnStreamPlay        = drvAudioStreamPlay;
    20502095#ifdef VBOX_WITH_AUDIO_CALLBACKS
     
    21052150     *       do this in drvAudioPowerOff() instead.
    21062151     */
    2107     PPDMAUDIOSTREAM pStream, pStreamNext;
    2108     RTListForEachSafe(&pThis->lstStreams, pStream, pStreamNext, PDMAUDIOSTREAM, Node)
    2109         drvAudioStreamDestroyInternal(pThis, pStream);
    21102152
    21112153    /* Sanity. */
    2112     Assert(RTListIsEmpty(&pThis->lstStreams));
     2154    Assert(RTListIsEmpty(&pThis->lstHstStreams));
     2155    Assert(RTListIsEmpty(&pThis->lstGstStreams));
    21132156
    21142157#ifdef VBOX_WITH_AUDIO_CALLBACKS
  • trunk/src/VBox/Devices/Audio/DrvAudio.h

    r61168 r61386  
    9090    /** Pointer to audio driver below us. */
    9191    PPDMIHOSTAUDIO          pHostDrvAudio;
    92     /** List of input/output audio streams. */
    93     RTLISTANCHOR            lstStreams;
     92    /** List of host input/output audio streams. */
     93    RTLISTANCHOR            lstHstStreams;
     94    /** List of guest input/output audio streams. */
     95    RTLISTANCHOR            lstGstStreams;
    9496    /** Max. number of free input streams.
    9597     *  UINT32_MAX for unlimited streams. */
  • trunk/src/VBox/Devices/Audio/DrvHostPulseAudio.cpp

    r61320 r61386  
    169169static void paSignalWaiter(PDRVHOSTPULSEAUDIO pThis)
    170170{
     171    if (!pThis)
     172        return;
     173
    171174    pThis->fLoopWait = true;
    172175    pa_threaded_mainloop_signal(pThis->pMainLoop, 0);
     
    11431146        pa_stream_unref(pStrm->pPAStream);
    11441147
     1148        pStrm->pPAStream = NULL;
     1149
    11451150        pa_threaded_mainloop_unlock(pThis->pMainLoop);
    1146 
    1147         pStrm->pPAStream = NULL;
    11481151    }
    11491152
     
    11751178        pa_stream_unref(pStrm->pPAStream);
    11761179
     1180        pStrm->pPAStream = NULL;
     1181
    11771182        pa_threaded_mainloop_unlock(pThis->pMainLoop);
    1178 
    1179         pStrm->pPAStream = NULL;
    11801183    }
    11811184
     
    12361239            {
    12371240                rc = paWaitFor(pThis, pa_stream_trigger(pStrm->pPAStream, paStreamCbSuccess, pStrm));
    1238                 if (RT_LIKELY(RT_SUCCESS(rc)))
     1241                if (RT_SUCCESS(rc))
    12391242                    pStrm->pDrainOp = pa_stream_drain(pStrm->pPAStream, paStreamCbDrain, pStrm);
    12401243            }
     
    13551358    if (pCfg->enmDir == PDMAUDIODIR_IN)
    13561359        rc = paCreateStreamIn(pInterface,  pStream, pCfg, pcSamples);
     1360    else if (pStream->enmDir == PDMAUDIODIR_OUT)
     1361        rc = paCreateStreamOut(pInterface, pStream, pCfg, pcSamples);
    13571362    else
    1358         rc = paCreateStreamOut(pInterface, pStream, pCfg, pcSamples);
     1363        AssertFailedReturn(VERR_NOT_IMPLEMENTED);
    13591364
    13601365    LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc));
     
    13661371    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    13671372    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
     1373
     1374    LogFlowFunc(("%s\n", pStream->szName));
    13681375
    13691376    int rc;
    13701377    if (pStream->enmDir == PDMAUDIODIR_IN)
    13711378        rc = paDestroyStreamIn(pInterface,  pStream);
     1379    else if (pStream->enmDir == PDMAUDIODIR_OUT)
     1380        rc = paDestroyStreamOut(pInterface, pStream);
    13721381    else
    1373         rc = paDestroyStreamOut(pInterface, pStream);
    1374 
     1382        AssertFailedReturn(VERR_NOT_IMPLEMENTED);
     1383
     1384    LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc));
    13751385    return rc;
    13761386}
     
    13871397    if (pStream->enmDir == PDMAUDIODIR_IN)
    13881398        rc = paControlStreamIn(pInterface,  pStream, enmStreamCmd);
     1399    else if (pStream->enmDir == PDMAUDIODIR_OUT)
     1400        rc = paControlStreamOut(pInterface, pStream, enmStreamCmd);
    13891401    else
    1390         rc = paControlStreamOut(pInterface, pStream, enmStreamCmd);
    1391 
     1402        AssertFailedReturn(VERR_NOT_IMPLEMENTED);
     1403
     1404    LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc));
    13921405    return rc;
    13931406}
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