VirtualBox

Changeset 89543 in vbox


Ignore:
Timestamp:
Jun 7, 2021 9:57:06 AM (3 years ago)
Author:
vboxsync
Message:

DrvAudioVRDE: Some fixes and cleanups. bugref:9890

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/DrvAudioVRDE.cpp

    r89510 r89543  
    237237    PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pvContext;
    238238    AssertPtrReturn(pStreamVRDE, VERR_INVALID_POINTER);
     239    LogFlowFunc(("cbData=%#x\n", cbData));
    239240
    240241    void  *pvBuf = NULL;
     
    298299    RT_NOREF(pInterface, enmDir);
    299300    return PDMAUDIOBACKENDSTS_RUNNING;
    300 }
    301 
    302 
    303 static int vrdeCreateStreamIn(PVRDESTREAM pStreamVRDE, PPDMAUDIOSTREAMCFG pCfgAcq)
    304 {
    305     /*
    306      * The VRDP server does its own mixing and resampling as it may server
    307      * multiple clients all with different sound formats.  So, it feeds us
    308      * raw mixer frames (somewhat akind to stereo signed 64-bit, see
    309      * st_sample_t and PDMAUDIOFRAME).
    310      */
    311     PDMAudioPropsInitEx(&pCfgAcq->Props, 8 /*64-bit*/, true /*fSigned*/, 2 /*stereo*/, 22050 /*Hz*/,
    312                         true /*fLittleEndian*/, true /*fRaw*/);
    313 
    314     /* According to the VRDP docs, the VRDP server stores audio in 200ms chunks. */
    315     const uint32_t cFramesVrdpServer = PDMAudioPropsMilliToFrames(&pCfgAcq->Props, 200 /*ms*/);
    316 
    317     int rc = RTCircBufCreate(&pStreamVRDE->In.pCircBuf, PDMAudioPropsFramesToBytes(&pCfgAcq->Props, cFramesVrdpServer));
    318     if (RT_SUCCESS(rc))
    319     {
    320         pCfgAcq->Backend.cFramesPeriod          = cFramesVrdpServer;
    321 /** @todo r=bird: This is inconsistent with the above buffer allocation and I
    322  * think also ALSA and Pulse backends way of setting cFramesBufferSize. */
    323         pCfgAcq->Backend.cFramesBufferSize      = cFramesVrdpServer * 2; /* Use "double buffering". */
    324         pCfgAcq->Backend.cFramesPreBuffering    = cFramesVrdpServer;
    325     }
    326 
    327     return rc;
    328 }
    329 
    330 
    331 static int vrdeCreateStreamOut(PPDMAUDIOSTREAMCFG pCfgAcq)
    332 {
    333     /*
    334      * The VRDP server does its own mixing and resampling because it may be
    335      * sending the audio to any number of different clients all with different
    336      * formats (including clients which hasn't yet connected).  So, it desires
    337      * the raw data from the mixer (somewhat akind to stereo signed 64-bit,
    338      * see st_sample_t and PDMAUDIOFRAME).
    339      */
    340     PDMAudioPropsInitEx(&pCfgAcq->Props, 8 /*64-bit*/, true /*fSigned*/, 2 /*stereo*/, 22050 /*Hz*/,
    341                         true /*fLittleEndian*/, true /*fRaw*/);
    342 
    343     /* According to the VRDP docs, the VRDP server stores audio in 200ms chunks. */
    344     /** @todo r=bird: So, if VRDP does 200ms chunks, why do we report 100ms
    345      *        buffer and 20ms period?  How does these parameters at all correlate
    346      *        with the above comment?!? */
    347     pCfgAcq->Backend.cFramesPeriod       = PDMAudioPropsMilliToFrames(&pCfgAcq->Props, 20  /*ms*/);
    348     pCfgAcq->Backend.cFramesBufferSize   = PDMAudioPropsMilliToFrames(&pCfgAcq->Props, 100 /*ms*/);
    349     pCfgAcq->Backend.cFramesPreBuffering = pCfgAcq->Backend.cFramesPeriod * 2;
    350 
    351     return VINF_SUCCESS;
    352301}
    353302
     
    379328#endif
    380329    {
     330        /*
     331         * The VRDP server does its own mixing and resampling because it may be
     332         * sending the audio to any number of different clients all with different
     333         * formats (including clients which hasn't yet connected).  So, it desires
     334         * the raw data from the mixer (somewhat akind to stereo signed 64-bit,
     335         * see st_sample_t and PDMAUDIOFRAME).
     336         */
     337        PDMAudioPropsInitEx(&pCfgAcq->Props, 8 /*64-bit*/, true /*fSigned*/, 2 /*stereo*/,
     338                            22050 /*Hz - VRDP_AUDIO_CHUNK_INTERNAL_FREQ_HZ*/,
     339                            true /*fLittleEndian*/, true /*fRaw*/);
     340
     341        /* According to the VRDP docs (VRDP_AUDIO_CHUNK_TIME_MS), the VRDP server
     342           stores audio in 200ms chunks. */
     343        const uint32_t cFramesVrdpServer = PDMAudioPropsMilliToFrames(&pCfgAcq->Props, 200 /*ms*/);
     344
    381345        if (pCfgReq->enmDir == PDMAUDIODIR_IN)
    382             rc = vrdeCreateStreamIn(pStreamVRDE, pCfgAcq);
     346        {
     347            pCfgAcq->Backend.cFramesBufferSize      = cFramesVrdpServer;
     348            pCfgAcq->Backend.cFramesPeriod          = cFramesVrdpServer / 4; /* This is utter non-sense, but whatever. */
     349            pCfgAcq->Backend.cFramesPreBuffering    = pCfgReq->Backend.cFramesPreBuffering * cFramesVrdpServer
     350                                                    / RT_MAX(pCfgReq->Backend.cFramesBufferSize, 1);
     351
     352            rc = RTCircBufCreate(&pStreamVRDE->In.pCircBuf, PDMAudioPropsFramesToBytes(&pCfgAcq->Props, cFramesVrdpServer));
     353        }
    383354        else
    384             rc = vrdeCreateStreamOut(pCfgAcq);
     355        {
     356            /** @todo r=bird: So, if VRDP does 200ms chunks, why do we report 100ms
     357             *        buffer and 20ms period?  How does these parameters at all correlate
     358             *        with the above comment?!? */
     359            pCfgAcq->Backend.cFramesPeriod       = PDMAudioPropsMilliToFrames(&pCfgAcq->Props, 20  /*ms*/);
     360            pCfgAcq->Backend.cFramesBufferSize   = PDMAudioPropsMilliToFrames(&pCfgAcq->Props, 100 /*ms*/);
     361            pCfgAcq->Backend.cFramesPreBuffering = pCfgAcq->Backend.cFramesPeriod * 2;
     362            rc = VINF_SUCCESS;
     363        }
     364
    385365        PDMAudioStrmCfgCopy(&pStreamVRDE->Cfg, pCfgAcq);
    386366    }
     
    400380    RT_NOREF(fImmediate);
    401381
    402     if (pStreamVRDE->Cfg.enmDir == PDMAUDIODIR_OUT)
    403     {
     382    if (pStreamVRDE->Cfg.enmDir == PDMAUDIODIR_IN)
     383    {
     384        LogFlowFunc(("Calling SendAudioInputEnd\n"));
    404385        if (pDrv->pConsoleVRDPServer)
    405386            pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL);
     
    437418                                                           PDMAudioPropsChannels(&pStreamVRDE->Cfg.Props),
    438419                                                           PDMAudioPropsSampleBits(&pStreamVRDE->Cfg.Props));
     420        LogFlowFunc(("SendAudioInputBegin returns %Rrc\n", rc));
    439421        if (rc == VERR_NOT_SUPPORTED)
    440422        {
     
    466448    else if (pStreamVRDE->Cfg.enmDir == PDMAUDIODIR_IN)
    467449    {
     450        LogFlowFunc(("Calling SendAudioInputEnd\n"));
    468451        pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL /* pvUserCtx */);
    469452        rc = VINF_SUCCESS;
     
    541524static DECLCALLBACK(uint32_t) drvAudioVrdeHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    542525{
    543     PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio);
    544     RT_NOREF(pStream);
     526    PDRVAUDIOVRDE pDrv        = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudio);
     527    PVRDESTREAM   pStreamVRDE = (PVRDESTREAM)pStream;
    545528
    546529    /** @todo Find some sane value here. We probably need a VRDE API VRDE to specify this. */
    547530    if (pDrv->cClients)
    548         return _16K * sizeof(int64_t) * 2;
     531        return PDMAudioPropsFramesToBytes(&pStreamVRDE->Cfg.Props, pStreamVRDE->Cfg.Backend.cFramesBufferSize);
    549532    return 0;
    550533}
     
    601584    PVRDESTREAM pStreamVRDE = (PVRDESTREAM)pStream;
    602585
    603     if (pStreamVRDE->Cfg.enmDir == PDMAUDIODIR_IN)
    604     {
    605         /* Return frames instead of bytes here
    606          * (since we specified PDMAUDIOSTREAMLAYOUT_RAW as the audio data layout). */
    607         return PDMAudioPropsBytesToFrames(&pStreamVRDE->Cfg.Props, (uint32_t)RTCircBufUsed(pStreamVRDE->In.pCircBuf));
    608     }
    609     return 0;
     586    AssertReturn(pStreamVRDE->Cfg.enmDir == PDMAUDIODIR_IN, 0);
     587    uint32_t cbRet = (uint32_t)RTCircBufUsed(pStreamVRDE->In.pCircBuf);
     588    Log4Func(("returns %#x\n", cbRet));
     589    return cbRet;
    610590}
    611591
     
    624604    AssertPtrReturn(pcbRead, VERR_INVALID_PARAMETER);
    625605
    626     size_t cbData = 0;
    627     if (RTCircBufUsed(pStreamVRDE->In.pCircBuf))
    628     {
    629         void *pvData = NULL;
     606    *pcbRead = 0;
     607    while (cbBuf > 0 && RTCircBufUsed(pStreamVRDE->In.pCircBuf) > 0)
     608    {
     609        size_t cbData = 0;
     610        void  *pvData = NULL;
    630611        RTCircBufAcquireReadBlock(pStreamVRDE->In.pCircBuf, cbBuf, &pvData, &cbData);
    631612
    632         if (cbData)
    633             memcpy(pvBuf, pvData, cbData);
     613        memcpy(pvBuf, pvData, cbData);
    634614
    635615        RTCircBufReleaseReadBlock(pStreamVRDE->In.pCircBuf, cbData);
    636     }
    637 
    638     *pcbRead = (uint32_t)cbData;
     616
     617        *pcbRead += (uint32_t)cbData;
     618        cbBuf    -= (uint32_t)cbData;
     619        pvData    = (uint8_t *)pvData + cbData;
     620    }
     621
     622    LogFlowFunc(("returns %#x bytes\n", *pcbRead));
    639623    return VINF_SUCCESS;
    640624}
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