VirtualBox

Changeset 88885 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 5, 2021 6:28:38 PM (4 years ago)
Author:
vboxsync
Message:

DrvAudioVRDE: Experimenting with alternative ways of signalling that we want to play/record stuff when a client connects. bugref:9890

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/DrvAudioVRDE.h

    r88382 r88885  
    7070    /** Pointer to the associated VRDE audio driver. */
    7171    struct DRVAUDIOVRDE *mpDrv;
     72    /** Protects accesses to mpDrv from racing driver destruction. */
     73    RTCRITSECT mCritSect;
    7274};
    7375
  • trunk/src/VBox/Main/src-client/DrvAudioVRDE.cpp

    r88819 r88885  
    7575    /** Pointer to the VRDP's console object. */
    7676    ConsoleVRDPServer   *pConsoleVRDPServer;
    77     /** Pointer to the DrvAudio port interface that is above us. */
    78     PPDMIAUDIOCONNECTOR  pDrvAudio;
    7977    /** Number of connected clients to this VRDE instance. */
    8078    uint32_t             cClients;
     79    /** Interface to the driver above us (DrvAudio).   */
     80    PDMIHOSTAUDIOPORT   *pIHostAudioPort;
    8181    /** Pointer to host audio interface. */
    8282    PDMIHOSTAUDIO        IHostAudio;
     
    9898    , mpDrv(NULL)
    9999{
     100    RTCritSectInit(&mCritSect);
    100101}
    101102
     
    103104AudioVRDE::~AudioVRDE(void)
    104105{
     106    RTCritSectEnter(&mCritSect);
    105107    if (mpDrv)
    106108    {
     
    108110        mpDrv = NULL;
    109111    }
     112    RTCritSectLeave(&mCritSect);
     113    RTCritSectDelete(&mCritSect);
    110114}
    111115
     
    129133    RT_NOREF(uClientID);
    130134
    131     LogRel2(("Audio: VRDE client connected\n"));
     135    RTCritSectEnter(&mCritSect);
    132136    if (mpDrv)
     137    {
    133138        mpDrv->cClients++;
     139        LogRel2(("Audio: VRDE client connected (#%u)\n", mpDrv->cClients));
     140
     141#if 0 /* later, maybe */
     142        /*
     143         * The first client triggers a device change event in both directions
     144         * so that can start talking to the audio device.
     145         *
     146         * Note! Should be okay to stay in the critical section here, as it's only
     147         *       used at construction and destruction time.
     148         */
     149        if (mpDrv->cClients == 1)
     150        {
     151            VMSTATE enmState = PDMDrvHlpVMState(mpDrv->pDrvIns);
     152            if (enmState <= VMSTATE_POWERING_OFF)
     153            {
     154                PDMIHOSTAUDIOPORT *pIHostAudioPort = mpDrv->pIHostAudioPort;
     155                AssertPtr(pIHostAudioPort);
     156                pIHostAudioPort->pfnNotifyDeviceChanged(pIHostAudioPort, PDMAUDIODIR_OUT, NULL /*pvUser*/);
     157                pIHostAudioPort->pfnNotifyDeviceChanged(pIHostAudioPort, PDMAUDIODIR_IN,  NULL /*pvUser*/);
     158            }
     159        }
     160#endif
     161    }
     162    RTCritSectLeave(&mCritSect);
    134163}
    135164
     
    139168    RT_NOREF(uClientID);
    140169
    141     LogRel2(("Audio: VRDE client disconnected\n"));
    142     Assert(mpDrv->cClients);
     170    RTCritSectEnter(&mCritSect);
    143171    if (mpDrv)
     172    {
     173        Assert(mpDrv->cClients > 0);
    144174        mpDrv->cClients--;
     175        LogRel2(("Audio: VRDE client disconnected (%u left)\n", mpDrv->cClients));
     176#if 0 /* later maybe */
     177        /*
     178         * The last client leaving triggers a device change event in both
     179         * directions so the audio devices can stop wasting time trying to
     180         * talk to us.  (There is an additional safeguard in
     181         * drvAudioVrdeHA_StreamGetStatus.)
     182         */
     183        if (mpDrv->cClients == 0)
     184        {
     185            VMSTATE enmState = PDMDrvHlpVMState(mpDrv->pDrvIns);
     186            if (enmState <= VMSTATE_POWERING_OFF)
     187            {
     188                PDMIHOSTAUDIOPORT *pIHostAudioPort = mpDrv->pIHostAudioPort;
     189                AssertPtr(pIHostAudioPort);
     190                pIHostAudioPort->pfnNotifyDeviceChanged(pIHostAudioPort, PDMAUDIODIR_OUT, NULL /*pvUser*/);
     191                pIHostAudioPort->pfnNotifyDeviceChanged(pIHostAudioPort, PDMAUDIODIR_IN,  NULL /*pvUser*/);
     192            }
     193        }
     194#endif
     195    }
     196    RTCritSectLeave(&mCritSect);
    145197}
    146198
     
    313365                                                     PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    314366{
    315     RT_NOREF(pInterface);
    316     PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pStream;
     367    PDRVAUDIOVRDE pThis       = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio);
     368    PVRDESTREAM   pStreamVRDE = (PVRDESTREAM)pStream;
    317369    AssertPtrReturn(pStreamVRDE, VERR_INVALID_POINTER);
    318370    AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER);
    319371    AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER);
    320372
     373    /*
     374     * Only create a stream if we have clients.
     375     */
    321376    int rc;
    322     if (pCfgReq->enmDir == PDMAUDIODIR_IN)
    323         rc = vrdeCreateStreamIn(pStreamVRDE, pCfgAcq);
     377    NOREF(pThis);
     378#if 0 /* later maybe */
     379    if (pThis->cClients == 0)
     380    {
     381        LogFunc(("No clients, failing with VERR_AUDIO_STREAM_COULD_NOT_CREATE.\n"));
     382        rc = VERR_AUDIO_STREAM_COULD_NOT_CREATE;
     383    }
    324384    else
    325         rc = vrdeCreateStreamOut(pCfgAcq);
    326     PDMAudioStrmCfgCopy(&pStreamVRDE->Cfg, pCfgAcq);
     385#endif
     386    {
     387        if (pCfgReq->enmDir == PDMAUDIODIR_IN)
     388            rc = vrdeCreateStreamIn(pStreamVRDE, pCfgAcq);
     389        else
     390            rc = vrdeCreateStreamOut(pCfgAcq);
     391        PDMAudioStrmCfgCopy(&pStreamVRDE->Cfg, pCfgAcq);
     392    }
    327393    return rc;
    328394}
     
    536602    RT_NOREF(pStream);
    537603
    538     uint32_t fStrmStatus = PDMAUDIOSTREAM_STS_INITIALIZED;
    539     if (pDrv->cClients) /* If any clients are connected, flag the stream as enabled. */
    540        fStrmStatus |= PDMAUDIOSTREAM_STS_ENABLED;
    541 
    542     return fStrmStatus;
     604    return pDrv->cClients > 0
     605         ? PDMAUDIOSTREAM_STS_INITIALIZED | PDMAUDIOSTREAM_STS_ENABLED
     606#if 0 /* later mabye */ /** @todo r=bird: Weird backend status mess. */
     607         : PDMAUDIOSTREAM_STS_NONE /* play possum if the clients all disappears. Re-init should be underways. */;
     608#else
     609         : PDMAUDIOSTREAM_STS_INITIALIZED /* If any clients are connected, flag the stream as enabled. */;
     610#endif
    543611}
    544612
     
    685753     * us since we'll be invalid when we return from this method.
    686754     */
    687     if (pThis->pAudioVRDE)
    688     {
    689         pThis->pAudioVRDE->mpDrv = NULL;
     755    AudioVRDE *pAudioVRDE = pThis->pAudioVRDE;
     756    if (pAudioVRDE)
     757    {
     758        RTCritSectEnter(&pAudioVRDE->mCritSect);
     759        pAudioVRDE->mpDrv = NULL;
    690760        pThis->pAudioVRDE = NULL;
     761        RTCritSectLeave(&pAudioVRDE->mCritSect);
    691762    }
    692763}
     
    740811
    741812    /*
     813     * Resolve the interface to the driver above us.
     814     */
     815    pThis->pIHostAudioPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIHOSTAUDIOPORT);
     816    AssertPtrReturn(pThis->pIHostAudioPort, VERR_PDM_MISSING_INTERFACE_ABOVE);
     817
     818    /*
    742819     * Get the ConsoleVRDPServer object pointer.
    743820     */
     
    761838    pThis->pAudioVRDE = (AudioVRDE *)pvUser;
    762839    AssertLogRelMsgReturn(RT_VALID_PTR(pThis->pAudioVRDE), ("pAudioVRDE=%p\n", pThis->pAudioVRDE), VERR_INVALID_POINTER);
     840    RTCritSectEnter(&pThis->pAudioVRDE->mCritSect);
    763841    pThis->pAudioVRDE->mpDrv = pThis;
    764 
    765     /*
    766      * Get the interface for the above driver (DrvAudio) to make mixer/conversion calls.
    767      * Described in CFGM tree.
    768      */
    769     pThis->pDrvAudio = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIAUDIOCONNECTOR);
    770     AssertMsgReturn(pThis->pDrvAudio, ("Configuration error: No upper interface specified!\n"), VERR_PDM_MISSING_INTERFACE_ABOVE);
     842    RTCritSectLeave(&pThis->pAudioVRDE->mCritSect);
    771843
    772844    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