VirtualBox

Changeset 88432 in vbox for trunk/src


Ignore:
Timestamp:
Apr 9, 2021 12:50:14 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
143684
Message:

DrvHostAudioAlsa: Rewrote the pfnStreamGetPending implementation. Didn't take draining into account nor that the delay may always be non-zero due to fixed delays. bugref:9890

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

Legend:

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

    r88429 r88432  
    13761376{
    13771377    RT_NOREF(pInterface);
    1378     AssertPtrReturn(pStream, 0);
    1379 
    13801378    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
    1381 
    1382     snd_pcm_sframes_t cFramesDelay  = 0;
    1383     snd_pcm_state_t   enmState = snd_pcm_state(pStreamALSA->phPCM);
    1384 
    1385     int rc = VINF_SUCCESS;
    1386 
     1379    AssertPtrReturn(pStreamALSA, 0);
    13871380    AssertPtr(pStreamALSA->pCfg);
     1381
     1382    /*
     1383     * This is only relevant to output streams (input streams can't have
     1384     * any pending, unplayed data).
     1385     */
     1386    uint32_t cbPending = 0;
    13881387    if (pStreamALSA->pCfg->enmDir == PDMAUDIODIR_OUT)
    13891388    {
    1390         /* Getting the delay (in audio frames) reports the time it will take
    1391          * to hear a new sample after all queued samples have been played out. */
    1392         int rc2 = snd_pcm_delay(pStreamALSA->phPCM, &cFramesDelay);
    1393         if (RT_SUCCESS(rc))
    1394             rc = rc2;
    1395 
    1396         /* Make sure to check the stream's status.
    1397          * If it's anything but SND_PCM_STATE_RUNNING, the delay is meaningless and therefore 0. */
    1398         if (enmState != SND_PCM_STATE_RUNNING)
    1399             cFramesDelay = 0;
    1400     }
    1401 
    1402     /* Note: For input streams we never have pending data left. */
    1403 
    1404     Log2Func(("cFramesDelay=%RI32, enmState=%d, rc=%d\n", cFramesDelay, enmState, rc));
    1405 
    1406     return PDMAudioPropsFramesToBytes(&pStreamALSA->pCfg->Props, cFramesDelay);
     1389        /*
     1390         * Getting the delay (in audio frames) reports the time it will take
     1391         * to hear a new sample after all queued samples have been played out.
     1392         *
     1393         * We use snd_pcm_avail_delay instead of snd_pcm_delay here as it will
     1394         * update the buffer positions, and we can use the extra value against
     1395         * the buffer size to double check since the delay value may include
     1396         * fixed built-in delays in the processing chain and hardware.
     1397         */
     1398        snd_pcm_sframes_t cFramesAvail = 0;
     1399        snd_pcm_sframes_t cFramesDelay = 0;
     1400        int rc = snd_pcm_avail_delay(pStreamALSA->phPCM, &cFramesAvail, &cFramesDelay);
     1401
     1402        /*
     1403         * We now also get the state as the pending value should be zero when
     1404         * we're not in a playing state.
     1405         */
     1406        snd_pcm_state_t enmState = snd_pcm_state(pStreamALSA->phPCM);
     1407        switch (enmState)
     1408        {
     1409            case SND_PCM_STATE_RUNNING:
     1410            case SND_PCM_STATE_DRAINING:
     1411                if (rc >= 0)
     1412                {
     1413                    if (cFramesAvail >= pStreamALSA->pCfg->Backend.cFramesBufferSize)
     1414                        cbPending = 0;
     1415                    else
     1416                        cbPending = PDMAudioPropsFramesToBytes(&pStreamALSA->pCfg->Props, cFramesDelay);
     1417                }
     1418                break;
     1419
     1420            default:
     1421                break;
     1422        }
     1423        Log2Func(("returns %u (%#x) - cFramesBufferSize=%RU32 cFramesAvail=%ld cFramesDelay=%ld rc=%d; enmState=%s (%d) \n",
     1424                  cbPending, cbPending, pStreamALSA->pCfg->Backend.cFramesBufferSize, cFramesAvail, cFramesDelay, rc,
     1425                  snd_pcm_state_name(enmState), enmState));
     1426    }
     1427    return cbPending;
    14071428}
    14081429
  • trunk/src/VBox/Devices/Audio/DrvHostAudioAlsaStubs.cpp

    r88226 r88432  
    5858           (pcm))
    5959PROXY_STUB(snd_pcm_close, int, (snd_pcm_t *pcm), (pcm))
    60 PROXY_STUB(snd_pcm_delay, int, (snd_pcm_t *pcm, snd_pcm_sframes_t *frames),
    61            (pcm, frames))
     60PROXY_STUB(snd_pcm_avail_delay, int,
     61           (snd_pcm_t *pcm, snd_pcm_sframes_t *availp, snd_pcm_sframes_t *delayp),
     62           (pcm, availp, delayp))
    6263PROXY_STUB(snd_pcm_nonblock, int, (snd_pcm_t *pcm, int *onoff),
    6364           (pcm, onoff))
     
    166167
    167168    ELEMENT(snd_pcm_avail_update),
     169    ELEMENT(snd_pcm_avail_delay),
    168170    ELEMENT(snd_pcm_close),
    169     ELEMENT(snd_pcm_delay),
    170171    ELEMENT(snd_pcm_drain),
    171172    ELEMENT(snd_pcm_drop),
  • trunk/src/VBox/Devices/Audio/DrvHostAudioAlsaStubsMangling.h

    r88226 r88432  
    3535#define snd_pcm_avail_update                    ALSA_MANGLER(snd_pcm_avail_update)
    3636#define snd_pcm_close                           ALSA_MANGLER(snd_pcm_close)
    37 #define snd_pcm_delay                           ALSA_MANGLER(snd_pcm_delay)
     37#define snd_pcm_avail_delay                     ALSA_MANGLER(snd_pcm_avail_delay)
    3838#define snd_pcm_drain                           ALSA_MANGLER(snd_pcm_drain)
    3939#define snd_pcm_drop                            ALSA_MANGLER(snd_pcm_drop)
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette