VirtualBox

Changeset 98456 in vbox


Ignore:
Timestamp:
Feb 2, 2023 8:23:19 PM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
155706
Message:

Audio: Backed out r155649 + r155650, as this needs another approach. The three device emulations are too different wrt locking and stream setup / teardown when it comes to if and when they reset their DMA buffers. Needs more testing first. bugref:10354

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

Legend:

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

    r98453 r98456  
    113113static int audioMixerSinkRemoveStreamInternal(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream);
    114114static void audioMixerSinkResetInternal(PAUDMIXSINK pSink);
    115 static int audioMixerSinkWaitForDrainedLocked(PAUDMIXSINK pSink, RTMSINTERVAL msTimeout);
    116115
    117116static int audioMixerStreamCtlInternal(PAUDMIXSTREAM pMixStream, PDMAUDIOSTREAMCMD enmCmd);
     
    415414            /* AIO */
    416415            AssertPtr(pDevIns);
    417             pSink->AIO.pDevIns       = pDevIns;
    418             pSink->AIO.hThread       = NIL_RTTHREAD;
    419             pSink->AIO.hEvent        = NIL_RTSEMEVENT;
    420             pSink->AIO.hEventDrained = NIL_RTSEMEVENT;
    421             pSink->AIO.fStarted      = false;
    422             pSink->AIO.fShutdown     = false;
    423             pSink->AIO.cUpdateJobs   = 0;
     416            pSink->AIO.pDevIns     = pDevIns;
     417            pSink->AIO.hThread     = NIL_RTTHREAD;
     418            pSink->AIO.hEvent      = NIL_RTSEMEVENT;
     419            pSink->AIO.fStarted    = false;
     420            pSink->AIO.fShutdown   = false;
     421            pSink->AIO.cUpdateJobs = 0;
    424422
    425423            /*
     
    580578 *                      buffers that the update job has yet to transfer.  This
    581579 *                      is ignored for input streams.
    582  * @param   msTimeout   Timeout to use for synchronously waiting for the draining / update jobs.
    583  *                      Set to 0 for running asynchronously.
    584  */
    585 int AudioMixerSinkDrainAndStopEx(PAUDMIXSINK pSink, uint32_t cbComming, RTMSINTERVAL msTimeout)
     580 */
     581int AudioMixerSinkDrainAndStop(PAUDMIXSINK pSink, uint32_t cbComming)
    586582{
    587583    AssertPtrReturn(pSink, VERR_INVALID_POINTER);
     
    624620                       status. (The device's DMA timer won't kick it any more, so we must.) */
    625621                    AudioMixerSinkSignalUpdateJob(pSink);
    626 #ifdef LOG_ENABLED
    627                     uint64_t const msStart = RTTimeMilliTS();
    628                     Log3Func(("Waiting for %RU32 update jobs (msTimeout=%RU32)\n", pSink->AIO.cUpdateJobs, msTimeout));
    629 #endif
    630                     if (   msTimeout
    631                         && pSink->AIO.cUpdateJobs)
    632                     {
    633                         rc = audioMixerSinkWaitForDrainedLocked(pSink, msTimeout);
    634 #ifdef LOG_ENABLED
    635                         Log3Func(("Waiting for update jobs done (rc=%Rrc, took %RU64ms)\n", rc, RTTimeMilliTS() - msStart));
    636 #endif
    637                     }
    638622                }
    639623                else
     
    678662
    679663/**
    680  * Kicks off the draining and stopping playback/capture on the mixer sink.
    681  *
    682  * For input streams this causes an immediate stop, as draining only makes sense
    683  * to output stream in the VBox device context.
    684  *
    685  * @returns VBox status code.  Generally always VINF_SUCCESS unless the input
    686  *          is invalid.  Individual driver errors are suppressed and ignored.
    687  * @param   pSink       Mixer sink to control.
    688  * @param   cbComming   The number of bytes still left in the device's DMA
    689  *                      buffers that the update job has yet to transfer.  This
    690  *                      is ignored for input streams.
    691  */
    692 int AudioMixerSinkDrainAndStop(PAUDMIXSINK pSink, uint32_t cbComming)
    693 {
    694     return AudioMixerSinkDrainAndStopEx(pSink, cbComming, 0 /* Don't wait */);
    695 }
    696 
    697 
    698 /**
    699664 * Destroys and frees a mixer sink.
    700665 *
     
    755720    {
    756721        int rc2 = RTSemEventSignal(pSink->AIO.hEvent);
    757         AssertRC(rc2);
    758     }
    759     if (pSink->AIO.hEventDrained != NIL_RTSEMEVENT)
    760     {
    761         int rc2 = RTSemEventSignal(pSink->AIO.hEventDrained);
    762722        AssertRC(rc2);
    763723    }
     
    774734        AssertRC(rc2);
    775735        pSink->AIO.hEvent = NIL_RTSEMEVENT;
    776     }
    777     if (pSink->AIO.hEventDrained != NIL_RTSEMEVENT)
    778     {
    779         int rc2 = RTSemEventDestroy(pSink->AIO.hEventDrained);
    780         AssertRC(rc2);
    781         pSink->AIO.hEventDrained = NIL_RTSEMEVENT;
    782736    }
    783737
     
    18171771     * The run loop.
    18181772     */
    1819     bool fDrainingFinished = false; /* Whether draining the stream is finished. */
    1820 #ifdef LOG_ENABLED
    1821     char szStatus[AUDIOMIXERSINK_STATUS_STR_MAX];
    1822 #endif
    1823 
    18241773    LogFlowFunc(("%s: Entering run loop...\n", pSink->pszName));
    18251774    while (!pSink->AIO.fShutdown)
     
    18281777
    18291778        RTCritSectEnter(&pSink->CritSect);
    1830 
    1831 #ifdef LOG_ENABLED
    1832         Log3Func(("%s: Running async I/O (fStatus=%s) ...\n", pSink->pszName,
    1833                   dbgAudioMixerSinkStatusToStr(pSink->fStatus, szStatus)));
    1834 #endif
    18351779        if (pSink->fStatus & (AUDMIXSINK_STS_RUNNING | AUDMIXSINK_STS_DRAINING))
    18361780        {
    1837             uint32_t fStatusOld = pSink->fStatus;
    1838 
    18391781            /*
    18401782             * Before doing jobs, always update input sinks.
     
    18621804             */
    18631805            if (!(pSink->fStatus & AUDMIXSINK_STS_DRAINING))
    1864             {
    1865                 /* likely */
    1866                 if (fStatusOld & AUDMIXSINK_STS_DRAINING)
    1867                 {
    1868                     Log3Func(("%s: Started draining\n", pSink->pszName));
    1869                     fDrainingFinished = true;
    1870                 }
    1871             }
     1806            { /* likely */ }
    18721807            else
    18731808            {
     
    18771812            }
    18781813
    1879             fStatusOld = pSink->fStatus;
    1880 
    1881             Log3Func(("%s: Running async I/O finished (fStatus=%s, cMsSleep=%RU32)\n",
    1882                       pSink->pszName, dbgAudioMixerSinkStatusToStr(pSink->fStatus, szStatus), cMsSleep));
    18831814        }
    18841815        RTCritSectLeave(&pSink->CritSect);
    1885 
    1886         /*
    1887          * Signal waiters.
    1888          */
    1889         if (fDrainingFinished)
    1890         {
    1891             Log3Func(("%s: Finished draining\n", pSink->pszName));
    1892             int rc = RTSemEventSignal(pSink->AIO.hEventDrained);
    1893             AssertLogRelMsgReturn(RT_SUCCESS(rc), ("%s: RTSemEventSignal(hEventDrained) -> %Rrc\n", pSink->pszName, rc), rc);
    1894             fDrainingFinished = false;
    1895         }
    18961816
    18971817        /*
     
    19021822            int rc = RTSemEventWait(pSink->AIO.hEvent, cMsSleep);
    19031823            AssertLogRelMsgReturn(RT_SUCCESS(rc) || rc == VERR_TIMEOUT, ("%s: RTSemEventWait -> %Rrc\n", pSink->pszName, rc), rc);
    1904 #ifdef LOG_ENABLED
    1905             Log3Func(("%s: Got signalled (fStatus=%s)\n", pSink->pszName, dbgAudioMixerSinkStatusToStr(pSink->fStatus, szStatus)));
    1906 #endif
    19071824        }
    19081825    }
     
    19701887        {
    19711888            rc = RTSemEventCreate(&pSink->AIO.hEvent);
    1972             AssertRCReturnStmt(rc, RTCritSectLeave(&pSink->CritSect), rc);
    1973         }
    1974         if (pSink->AIO.hEventDrained == NIL_RTSEMEVENT)
    1975         {
    1976             rc = RTSemEventCreate(&pSink->AIO.hEventDrained);
    19771889            AssertRCReturnStmt(rc, RTCritSectLeave(&pSink->CritSect), rc);
    19781890        }
     
    20481960
    20491961/**
    2050  * Waits for the sink's draining to complete, internal version.
    2051  *
    2052  * @returns VBox status code.
    2053  * @param   pSink       The mixer sink which AIO thread needs waiting on.
    2054  * @param   msTimeout   Timeout (in ms) to use for waiting on draining to be finished.
    2055  *
    2056  * @note    Caller holds the sink's lock.
    2057  */
    2058 static int audioMixerSinkWaitForDrainedLocked(PAUDMIXSINK pSink, RTMSINTERVAL msTimeout)
    2059 {
    2060     AssertReturn((pSink->fStatus & AUDMIXSINK_STS_DRAINING), VERR_WRONG_ORDER);
    2061 
    2062     int rc;
    2063 
    2064     if (pSink->AIO.cUpdateJobs)
    2065     {
    2066         rc = RTCritSectLeave(&pSink->CritSect);
    2067         AssertRCReturn(rc, rc);
    2068 
    2069         rc = RTSemEventWait(pSink->AIO.hEventDrained, msTimeout);
    2070 
    2071         int rc2 = RTCritSectEnter(&pSink->CritSect);
    2072         AssertRCReturn(rc2, rc2);
    2073 
    2074     }
    2075     else
    2076         rc = VINF_SUCCESS;
    2077 
    2078     return rc;
    2079 }
    2080 
    2081 
    2082 /**
    2083  * Waits for the sink's draining to complete.
    2084  *
    2085  * @returns VBox status code.
    2086  * @param   pSink       The mixer sink which AIO thread needs waiting on.
    2087  * @param   msTimeout   Timeout (in ms) to use for waiting on draining to be finished.
    2088  */
    2089 int AudioMixerSinkWaitForDrained(PAUDMIXSINK pSink, RTMSINTERVAL msTimeout)
    2090 {
    2091     AssertPtrReturn(pSink, VERR_INVALID_POINTER);
    2092     Assert(pSink->uMagic == AUDMIXSINK_MAGIC);
    2093 
    2094     int rc = RTCritSectEnter(&pSink->CritSect);
    2095     AssertRCReturn(rc, rc);
    2096 
    2097     rc = audioMixerSinkWaitForDrainedLocked(pSink, msTimeout);
    2098 
    2099     int rc2 = RTCritSectLeave(&pSink->CritSect);
    2100     AssertRCReturn(rc2, rc2);
    2101 
    2102     return rc;
    2103 }
    2104 
    2105 
    2106 /**
    21071962 * Writes data to a mixer output sink.
    21081963 *
     
    21692024              idStream, cbSinkWritable, cbCircBufReadable, cbToTransfer, offStream));
    21702025    AssertMsg(!(pSink->fStatus & AUDMIXSINK_STS_DRAINING) || cbCircBufReadable == pSink->cbDmaLeftToDrain,
    2171               ("idStream=%u: fStatus=%#x cbCircBufReadable=%#x cbDmaLeftToDrain=%#x\n",
    2172                idStream, pSink->fStatus, cbCircBufReadable, pSink->cbDmaLeftToDrain));
     2026              ("cbCircBufReadable=%#x cbDmaLeftToDrain=%#x\n", cbCircBufReadable, pSink->cbDmaLeftToDrain));
    21732027
    21742028    /*
  • TabularUnified trunk/src/VBox/Devices/Audio/AudioMixer.h

    r98405 r98456  
    244244        /** Event for letting the thread know there is some data to process. */
    245245        RTSEMEVENT              hEvent;
    246         /** Event for letting the waiters know that draining the sink is done. */
    247         RTSEMEVENT              hEventDrained;
    248246        /** The device instance (same for all update jobs). */
    249247        PPDMDEVINS              pDevIns;
     
    311309 * @{ */
    312310int         AudioMixerSinkStart(PAUDMIXSINK pSink);
    313 int         AudioMixerSinkDrainAndStopEx(PAUDMIXSINK pSink, uint32_t cbComming, RTMSINTERVAL msTimeout);
    314311int         AudioMixerSinkDrainAndStop(PAUDMIXSINK pSink, uint32_t cbComming);
    315312void        AudioMixerSinkDestroy(PAUDMIXSINK pSink, PPDMDEVINS pDevIns);
     
    327324int         AudioMixerSinkRemoveUpdateJob(PAUDMIXSINK pSink, PFNAUDMIXSINKUPDATE pfnUpdate, void *pvUser);
    328325int         AudioMixerSinkSignalUpdateJob(PAUDMIXSINK pSink);
    329 int         AudioMixerSinkWaitForDrained(PAUDMIXSINK pSink, RTMSINTERVAL msTimeout);
    330326uint64_t    AudioMixerSinkTransferFromCircBuf(PAUDMIXSINK pSink, PRTCIRCBUF pCircBuf, uint64_t offStream,
    331327                                              uint32_t idStream, PAUDIOHLPFILE pDbgFile);
  • TabularUnified trunk/src/VBox/Devices/Audio/DevHdaStream.cpp

    r98405 r98456  
    10591059        }
    10601060        else
    1061             rc = AudioMixerSinkDrainAndStopEx(pSink,
    1062                                               pStreamR3->State.pCircBuf ? (uint32_t)RTCircBufUsed(pStreamR3->State.pCircBuf) : 0,
    1063                                               RT_MS_5SEC);
     1061            rc = AudioMixerSinkDrainAndStop(pSink,
     1062                                            pStreamR3->State.pCircBuf ? (uint32_t)RTCircBufUsed(pStreamR3->State.pCircBuf) : 0);
    10641063    }
    10651064    if (   RT_SUCCESS(rc)
  • TabularUnified trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r98405 r98456  
    23482348    else
    23492349    {
    2350         rc = AudioMixerSinkDrainAndStopEx(pSink,
    2351                                           pStreamCC->State.pCircBuf ? (uint32_t)RTCircBufUsed(pStreamCC->State.pCircBuf) : 0,
    2352                                           RT_MS_5SEC);
     2350        rc = AudioMixerSinkDrainAndStop(pSink, pStreamCC->State.pCircBuf ? (uint32_t)RTCircBufUsed(pStreamCC->State.pCircBuf) : 0);
    23532351        ichac97R3StreamTearDown(pStream);
    23542352    }
  • TabularUnified trunk/src/VBox/Devices/Audio/DevSB16.cpp

    r98405 r98456  
    20122012    else
    20132013    {
    2014         rc = AudioMixerSinkDrainAndStopEx(pSink, pStream->State.pCircBuf ? (uint32_t)RTCircBufUsed(pStream->State.pCircBuf) : 0,
    2015                                           RT_MS_5SEC);
     2014        rc = AudioMixerSinkDrainAndStop(pSink, pStream->State.pCircBuf ? (uint32_t)RTCircBufUsed(pStream->State.pCircBuf) : 0);
    20162015        AssertRCReturn(rc, rc);
    20172016    }
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