VirtualBox

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


Ignore:
Timestamp:
Jun 18, 2021 2:02:38 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
145232
Message:

Audio: Size the mixer buffer for sinks according to the scheulding hint. This should typically reduce the buffer size from the fixed size of 100ms we've used so far, helping to reduce latency build up. Also, 100ms might not have been enough for some configurations. bugref:9890

Location:
trunk/src/VBox/Devices/Audio
Files:
5 edited

Legend:

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

    r89768 r89779  
    945945 *
    946946 * @returns VBox status code.
    947  * @param   pSink   The sink to set audio format for.
    948  * @param   pProps  The properties of the new audio format (guest side).
    949  */
    950 int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PCPDMAUDIOPCMPROPS pProps)
     947 * @param   pSink               The sink to set audio format for.
     948 * @param   pProps              The properties of the new audio format (guest side).
     949 * @param   cMsSchedulingHint   Scheduling hint for mixer buffer sizing.
     950 */
     951int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PCPDMAUDIOPCMPROPS pProps, uint32_t cMsSchedulingHint)
    951952{
    952953    AssertPtrReturn(pSink, VERR_INVALID_POINTER);
     
    955956    AssertReturn(AudioHlpPcmPropsAreValid(pProps), VERR_INVALID_PARAMETER);
    956957
     958    /*
     959     * Calculate the mixer buffer size so we can force a recreation if it changes.
     960     *
     961     * This used to be fixed at 100ms, however that's usually too generous and can
     962     * in theory be too small.  Generally, we size the buffer at 3 DMA periods as
     963     * that seems reasonable.  Now, since the we don't quite trust the scheduling
     964     * hint we're getting, make sure we're got a minimum of 30ms buffer space, but
     965     * no more than 500ms.
     966     */
     967    if (cMsSchedulingHint <= 10)
     968        cMsSchedulingHint = 30;
     969    else
     970    {
     971        cMsSchedulingHint *= 3;
     972        if (cMsSchedulingHint > 500)
     973            cMsSchedulingHint = 500;
     974    }
     975    uint32_t const cBufferFrames = PDMAudioPropsMilliToFrames(pProps, cMsSchedulingHint);
     976     /** @todo configuration override on the buffer size? */
     977
    957978    int rc = RTCritSectEnter(&pSink->CritSect);
    958979    AssertRCReturn(rc, rc);
     
    960981    /*
    961982     * Do nothing unless the format actually changed.
    962      */
    963     if (!PDMAudioPropsAreEqual(&pSink->PCMProps, pProps))
     983     * The buffer size must not match exactly, within +/- 2% is okay.
     984     */
     985    uint32_t cOldBufferFrames;
     986    if (   !PDMAudioPropsAreEqual(&pSink->PCMProps, pProps)
     987        || (   cBufferFrames != (cOldBufferFrames = AudioMixBufSize(&pSink->MixBuf))
     988            && (uint32_t)RT_ABS((int32_t)(cBufferFrames - cOldBufferFrames)) > cBufferFrames / 50) )
    964989    {
    965990#ifdef LOG_ENABLED
     
    967992#endif
    968993        if (PDMAudioPropsHz(&pSink->PCMProps) != 0)
    969             LogFlowFunc(("[%s] Old format: %s\n", pSink->pszName, PDMAudioPropsToString(&pSink->PCMProps, szTmp, sizeof(szTmp)) ));
     994            LogFlowFunc(("[%s] Old format: %s; buffer: %u frames\n", pSink->pszName,
     995                         PDMAudioPropsToString(&pSink->PCMProps, szTmp, sizeof(szTmp)), AudioMixBufSize(&pSink->MixBuf) ));
    970996        pSink->PCMProps = *pProps;
    971         LogFlowFunc(("[%s] New format: %s\n", pSink->pszName, PDMAudioPropsToString(&pSink->PCMProps, szTmp, sizeof(szTmp)) ));
     997        LogFlowFunc(("[%s] New format: %s; buffer: %u frames\n", pSink->pszName,
     998                     PDMAudioPropsToString(&pSink->PCMProps, szTmp, sizeof(szTmp)), cBufferFrames ));
    972999
    9731000        /*
     
    9761003        AudioMixBufTerm(&pSink->MixBuf);
    9771004
    978         /** @todo r=bird: Make sure we've got more room here than what's expected to
    979          *        be moved in one guest DMA period. */
    980         rc = AudioMixBufInit(&pSink->MixBuf, pSink->pszName, &pSink->PCMProps,
    981                              PDMAudioPropsMilliToFrames(&pSink->PCMProps, 100 /*ms*/)); /** @todo Make this configurable? */
     1005        rc = AudioMixBufInit(&pSink->MixBuf, pSink->pszName, &pSink->PCMProps, cBufferFrames);
    9821006        if (RT_SUCCESS(rc))
    9831007        {
  • trunk/src/VBox/Devices/Audio/AudioMixer.h

    r89371 r89779  
    298298bool        AudioMixerSinkIsActive(PAUDMIXSINK pSink);
    299299void        AudioMixerSinkReset(PAUDMIXSINK pSink);
    300 int         AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PCPDMAUDIOPCMPROPS pPCMProps);
     300int         AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PCPDMAUDIOPCMPROPS pPCMProps, uint32_t cMsSchedulingHint);
    301301int         AudioMixerSinkSetVolume(PAUDMIXSINK pSink, PCPDMAUDIOVOLUME pVol);
    302302int         AudioMixerSinkUpdate(PAUDMIXSINK pSink, uint32_t cbDmaUsed, uint32_t cbDmaPeriod);
  • trunk/src/VBox/Devices/Audio/DevHda.cpp

    r89768 r89779  
    23482348    LogFunc(("Sink=%s, Stream=%s\n", pMixSink->pszName, pCfg->szName));
    23492349
    2350     if (!AudioHlpStreamCfgIsValid(pCfg))
    2351         return VERR_INVALID_PARAMETER;
    2352 
    2353     int rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props);
    2354     if (RT_SUCCESS(rc))
    2355     {
    2356         PHDADRIVER pDrv;
    2357         RTListForEach(&pThisCC->lstDrv, pDrv, HDADRIVER, Node)
    2358         {
    2359             /* We ignore failures here because one non-working driver shouldn't
    2360                be allowed to spoil it for everyone else. */
    2361             int rc2 = hdaR3MixerAddDrvStream(pDevIns, pMixSink, pCfg, pDrv);
    2362             if (RT_FAILURE(rc2))
    2363                 LogFunc(("Attaching stream failed with %Rrc (ignored)\n", rc2));
    2364         }
    2365     }
     2350    int rc;
     2351    if (AudioHlpStreamCfgIsValid(pCfg))
     2352    {
     2353        rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props, pCfg->Device.cMsSchedulingHint);
     2354        if (RT_SUCCESS(rc))
     2355        {
     2356            PHDADRIVER pDrv;
     2357            RTListForEach(&pThisCC->lstDrv, pDrv, HDADRIVER, Node)
     2358            {
     2359                /* We ignore failures here because one non-working driver shouldn't
     2360                   be allowed to spoil it for everyone else. */
     2361                int rc2 = hdaR3MixerAddDrvStream(pDevIns, pMixSink, pCfg, pDrv);
     2362                if (RT_FAILURE(rc2))
     2363                    LogFunc(("Attaching stream failed with %Rrc (ignored)\n", rc2));
     2364            }
     2365        }
     2366    }
     2367    else
     2368        rc = VERR_INVALID_PARAMETER;
    23662369    return rc;
    23672370}
  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r89778 r89779  
    18391839    if (AudioHlpStreamCfgIsValid(pCfg))
    18401840    {
    1841         rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props);
     1841        rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props, pCfg->Device.cMsSchedulingHint);
    18421842        if (RT_SUCCESS(rc))
    18431843        {
  • trunk/src/VBox/Devices/Audio/DevSB16.cpp

    r89768 r89779  
    17951795    AssertPtrReturn(pMixSink, VERR_INVALID_POINTER);
    17961796
    1797     if (!AudioHlpStreamCfgIsValid(pCfg))
    1798         return VERR_INVALID_PARAMETER;
    1799 
    1800     int rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props);
    1801     if (RT_FAILURE(rc))
    1802         return rc;
    1803 
    1804     PSB16DRIVER pDrv;
    1805     RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
    1806     {
    1807         int rc2 = sb16AddDrvStream(pDevIns, pMixSink, pCfg, pDrv);
    1808         if (RT_FAILURE(rc2))
    1809             LogFunc(("Attaching stream failed with %Rrc\n", rc2));
    1810 
    1811         /* Do not pass failure to rc here, as there might be drivers which aren't
    1812          * configured / ready yet. */
    1813     }
     1797    int rc;
     1798    if (AudioHlpStreamCfgIsValid(pCfg))
     1799    {
     1800        rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props, pCfg->Device.cMsSchedulingHint);
     1801        if (RT_SUCCESS(rc))
     1802        {
     1803            PSB16DRIVER pDrv;
     1804            RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
     1805            {
     1806                int rc2 = sb16AddDrvStream(pDevIns, pMixSink, pCfg, pDrv);
     1807                if (RT_FAILURE(rc2))
     1808                    LogFunc(("Attaching stream failed with %Rrc\n", rc2));
     1809
     1810                /* Do not pass failure to rc here, as there might be drivers which aren't
     1811                 * configured / ready yet. */
     1812            }
     1813        }
     1814    }
     1815    else
     1816        rc = VERR_INVALID_PARAMETER;
    18141817
    18151818    LogFlowFuncLeaveRC(rc);
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