VirtualBox

Ignore:
Timestamp:
May 12, 2021 12:46:35 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
144329
Message:

Audio: Worked over draining, starting with the internal DMA buffer (instead of just the pre-buffer and backend buffer) and using the async I/O thread to keep calling PDMIAUDIOCONNECTOR::pfnStreamIterate and PDMIHOSTAUDIO::pfnStreamPlay (NULL buffer) every so often till the draining is done. Also put a rough deadline on the draining. The PDMAUDIOSTREAMCMD_DISABLE is now defined to stop playback/capturing immediately, even when already draining (if possible). This gets rid of the timers in DrvAudio and windows backends. DrvAudio no longer issue an DISABLE command at the end of the drain, it assumes the backend does that internally itself. After issuing PDMAUDIOSTREAMCMD_DRAIN the client (be it mixer or drvaudio) will not provide any more data for the buffers via pfnStreamPlay. Only tested windows, needs to re-test all platforms. bugref:9890

File:
1 edited

Legend:

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

    r88966 r88991  
    5656#include <alsa/asoundlib.h>
    5757#include <alsa/control.h> /* For device enumeration. */
     58#include <alsa/version.h>
    5859#include "DrvHostAudioAlsaStubs.h"
    5960
     
    11251126{
    11261127    RT_NOREF(pInterface);
    1127     AssertPtrReturn(pStream, PDMHOSTAUDIOSTREAMSTATE_INVALID);
    1128 
    1129     return PDMHOSTAUDIOSTREAMSTATE_OKAY;
     1128    PALSAAUDIOSTREAM pStreamALSA = (PALSAAUDIOSTREAM)pStream;
     1129    AssertPtrReturn(pStreamALSA, PDMHOSTAUDIOSTREAMSTATE_INVALID);
     1130
     1131    PDMHOSTAUDIOSTREAMSTATE enmStreamState = PDMHOSTAUDIOSTREAMSTATE_OKAY;
     1132    snd_pcm_state_t         enmAlsaState   = snd_pcm_state(pStreamALSA->hPCM);
     1133    if (enmAlsaState == SND_PCM_STATE_DRAINING)
     1134        enmStreamState = PDMHOSTAUDIOSTREAMSTATE_DRAINING;
     1135#if (((SND_LIB_MAJOR) << 16) | ((SND_LIB_MAJOR) << 8) | (SND_LIB_SUBMINOR)) >= 0x10002 /* was added in 1.0.2 */
     1136    else if (enmAlsaState == SND_PCM_STATE_DISCONNECTED)
     1137        enmStreamState = PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING;
     1138#endif
     1139
     1140    Log5Func(("Stream '%s': ALSA state=%s -> %s\n",
     1141              pStreamALSA->Cfg.szName, snd_pcm_state_name(enmAlsaState), PDMHostAudioStreamStateGetName(enmStreamState) ));
     1142    return enmStreamState;
    11301143}
    11311144
     
    12741287    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    12751288    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    1276     AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
    1277     AssertReturn(cbBuf, VERR_INVALID_PARAMETER);
    12781289    AssertPtrReturn(pcbWritten, VERR_INVALID_POINTER);
    12791290    Log4Func(("@%#RX64: pvBuf=%p cbBuf=%#x (%u) state=%s - %s\n", pStreamALSA->offInternal, pvBuf, cbBuf, cbBuf,
    12801291              snd_pcm_state_name(snd_pcm_state(pStreamALSA->hPCM)), pStreamALSA->Cfg.szName));
     1292    if (cbBuf)
     1293        AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
     1294    else
     1295    {
     1296        /* Fend off draining calls. */
     1297        *pcbWritten = 0;
     1298        return VINF_SUCCESS;
     1299    }
    12811300
    12821301    /*
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