VirtualBox

Changeset 73342 in vbox


Ignore:
Timestamp:
Jul 24, 2018 2:46:55 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
123956
Message:

Audio/AudioMixer: Added the option to also use a small ring buffer for the sink streams to buffer data between the device emulation and the audio connector (only output streams for now).

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

Legend:

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

    r73206 r73342  
    649649            pConn->pfnStreamRetain(pConn, pStream);
    650650        }
     651    }
     652
     653    if (RT_SUCCESS(rc))
     654    {
     655        rc = RTCircBufCreate(&pMixStream->pCircBuf, DrvAudioHlpMsToBytes(&pSink->PCMProps, 100 /* ms */)); /** @todo Make this configurable. */
     656        AssertRC(rc);
    651657    }
    652658
     
    16821688    Log3Func(("[%s] enmOp=%d, cbBuf=%RU32\n", pSink->pszName, enmOp, cbBuf));
    16831689
    1684     uint32_t cbWritten = UINT32_MAX;
    1685 
    16861690    PAUDMIXSTREAM pMixStream;
    16871691    RTListForEach(&pSink->lstStreams, pMixStream, AUDMIXSTREAM, Node)
    16881692    {
    1689         uint32_t cbProcessed = 0;
    1690         int rc2 = pMixStream->pConn->pfnStreamWrite(pMixStream->pConn, pMixStream->pStream, pvBuf, cbBuf, &cbProcessed);
    1691         if (RT_FAILURE(rc2))
    1692             LogFunc(("[%s] Failed writing to stream '%s': %Rrc\n", pSink->pszName, pMixStream->pszName, rc2));
    1693 
    1694         Log3Func(("[%s] Written %RU32 to '%s'\n", pSink->pszName, cbProcessed, pMixStream->pszName));
    1695 
    1696         if (cbProcessed)
     1693        PRTCIRCBUF pCircBuf = pMixStream->pCircBuf;
     1694        void *pvChunk;
     1695        size_t cbChunk;
     1696
     1697        uint32_t cbWritten = 0;
     1698        uint32_t cbToWrite = RT_MIN(cbBuf, (uint32_t)RTCircBufFree(pCircBuf));
     1699        while (cbToWrite)
     1700        {
     1701            RTCircBufAcquireWriteBlock(pCircBuf, cbToWrite, &pvChunk, &cbChunk);
     1702
     1703            if (cbChunk)
     1704                memcpy(pvChunk, (uint8_t *)pvBuf + cbWritten, cbChunk);
     1705
     1706            RTCircBufReleaseWriteBlock(pCircBuf, cbChunk);
     1707
     1708            cbWritten += (uint32_t)cbChunk;
     1709
     1710            Assert(cbToWrite >= cbChunk);
     1711            cbToWrite -= (uint32_t)cbChunk;
     1712        }
     1713
     1714        if (cbWritten < cbBuf)
     1715            LogFunc(("[%s] Warning: Only written %RU32/%RU32 bytes for stream '%s'\n",
     1716                     pSink->pszName, cbWritten, cbBuf, pMixStream->pszName));
     1717
     1718        if (!pMixStream->tsLastReadWrittenMs)
     1719            pMixStream->tsLastReadWrittenMs = RTTimeMilliTS();
     1720
     1721        pMixStream->tsLastReadWrittenMs = RTTimeMilliTS();
     1722
     1723        const uint32_t cbWritableStream = pMixStream->pConn->pfnStreamGetWritable(pMixStream->pConn, pMixStream->pStream);
     1724        cbToWrite = RT_MIN(cbWritableStream, (uint32_t)RTCircBufUsed(pCircBuf));
     1725
     1726        int rc2 = VINF_SUCCESS;
     1727
     1728        while (cbToWrite)
     1729        {
     1730            RTCircBufAcquireReadBlock(pCircBuf, cbToWrite, &pvChunk, &cbChunk);
     1731
     1732            if (cbChunk)
     1733            {
     1734                rc2 = pMixStream->pConn->pfnStreamWrite(pMixStream->pConn, pMixStream->pStream, pvChunk, (uint32_t)cbChunk,
     1735                                                        &cbWritten);
     1736                if (RT_FAILURE(rc2))
     1737                    LogFunc(("[%s] Failed writing to stream '%s': %Rrc\n", pSink->pszName, pMixStream->pszName, rc2));
     1738            }
     1739
     1740            RTCircBufReleaseReadBlock(pCircBuf, cbWritten);
     1741
     1742            if (   !cbWritten
     1743                || cbWritten < cbChunk)
     1744                break;
     1745
     1746            if (RT_FAILURE(rc2))
     1747                break;
     1748
     1749            Assert(cbToWrite >= cbChunk);
     1750            cbToWrite -= (uint32_t)cbChunk;
     1751        }
     1752
     1753        if (RTCircBufUsed(pCircBuf))
    16971754        {
    16981755            /* Set dirty bit. */
    16991756            pSink->fStatus |= AUDMIXSINK_STS_DIRTY;
    1700 
    1701             /*
    1702              * Return the minimum bytes processed by all connected streams.
    1703              * The host sets the pace, so all backends have to behave accordingly.
    1704              */
    1705             if (cbWritten > cbProcessed)
    1706                 cbWritten = cbProcessed;
    1707         }
    1708     }
    1709 
    1710     if (cbWritten == UINT32_MAX)
    1711         cbWritten = 0;
    1712 
    1713     Log3Func(("[%s] cbWritten=%RU32\n", pSink->pszName, cbWritten));
     1757        }
     1758    }
    17141759
    17151760    if (pcbWritten)
    1716         *pcbWritten = cbWritten;
     1761        *pcbWritten = cbBuf; /* Always report everything written, as the backends need to keep up themselves. */
    17171762
    17181763    int rc2 = RTCritSectLeave(&pSink->CritSect);
     
    18051850    }
    18061851
     1852    if (pMixStream->pCircBuf)
     1853    {
     1854        RTCircBufDestroy(pMixStream->pCircBuf);
     1855        pMixStream->pCircBuf = NULL;
     1856    }
     1857
    18071858    int rc2 = RTCritSectDelete(&pMixStream->CritSect);
    18081859    AssertRC(rc2);
  • trunk/src/VBox/Devices/Audio/AudioMixer.h

    r73039 r73342  
    77
    88/*
    9  * Copyright (C) 2014-2017 Oracle Corporation
     9 * Copyright (C) 2014-2018 Oracle Corporation
    1010 *
    1111 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    6868    /** Pointer to PDM audio stream this mixer stream handles. */
    6969    PPDMAUDIOSTREAM         pStream;
     70    /** Last read (recording) / written (playback) timestamp (in ms). */
     71    uint64_t                tsLastReadWrittenMs;
     72    /** The stream's circular buffer for temporarily
     73     *  holding (raw) device audio data. */
     74    PRTCIRCBUF              pCircBuf;
    7075} AUDMIXSTREAM, *PAUDMIXSTREAM;
    7176
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