Changeset 98456 in vbox
- Timestamp:
- Feb 2, 2023 8:23:19 PM (2 years ago)
- svn:sync-xref-src-repo-rev:
- 155706
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/VBox/Devices/Audio/AudioMixer.cpp ¶
r98453 r98456 113 113 static int audioMixerSinkRemoveStreamInternal(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream); 114 114 static void audioMixerSinkResetInternal(PAUDMIXSINK pSink); 115 static int audioMixerSinkWaitForDrainedLocked(PAUDMIXSINK pSink, RTMSINTERVAL msTimeout);116 115 117 116 static int audioMixerStreamCtlInternal(PAUDMIXSTREAM pMixStream, PDMAUDIOSTREAMCMD enmCmd); … … 415 414 /* AIO */ 416 415 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; 424 422 425 423 /* … … 580 578 * buffers that the update job has yet to transfer. This 581 579 * 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 */ 581 int AudioMixerSinkDrainAndStop(PAUDMIXSINK pSink, uint32_t cbComming) 586 582 { 587 583 AssertPtrReturn(pSink, VERR_INVALID_POINTER); … … 624 620 status. (The device's DMA timer won't kick it any more, so we must.) */ 625 621 AudioMixerSinkSignalUpdateJob(pSink); 626 #ifdef LOG_ENABLED627 uint64_t const msStart = RTTimeMilliTS();628 Log3Func(("Waiting for %RU32 update jobs (msTimeout=%RU32)\n", pSink->AIO.cUpdateJobs, msTimeout));629 #endif630 if ( msTimeout631 && pSink->AIO.cUpdateJobs)632 {633 rc = audioMixerSinkWaitForDrainedLocked(pSink, msTimeout);634 #ifdef LOG_ENABLED635 Log3Func(("Waiting for update jobs done (rc=%Rrc, took %RU64ms)\n", rc, RTTimeMilliTS() - msStart));636 #endif637 }638 622 } 639 623 else … … 678 662 679 663 /** 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 sense683 * to output stream in the VBox device context.684 *685 * @returns VBox status code. Generally always VINF_SUCCESS unless the input686 * 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 DMA689 * buffers that the update job has yet to transfer. This690 * 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 /**699 664 * Destroys and frees a mixer sink. 700 665 * … … 755 720 { 756 721 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);762 722 AssertRC(rc2); 763 723 } … … 774 734 AssertRC(rc2); 775 735 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;782 736 } 783 737 … … 1817 1771 * The run loop. 1818 1772 */ 1819 bool fDrainingFinished = false; /* Whether draining the stream is finished. */1820 #ifdef LOG_ENABLED1821 char szStatus[AUDIOMIXERSINK_STATUS_STR_MAX];1822 #endif1823 1824 1773 LogFlowFunc(("%s: Entering run loop...\n", pSink->pszName)); 1825 1774 while (!pSink->AIO.fShutdown) … … 1828 1777 1829 1778 RTCritSectEnter(&pSink->CritSect); 1830 1831 #ifdef LOG_ENABLED1832 Log3Func(("%s: Running async I/O (fStatus=%s) ...\n", pSink->pszName,1833 dbgAudioMixerSinkStatusToStr(pSink->fStatus, szStatus)));1834 #endif1835 1779 if (pSink->fStatus & (AUDMIXSINK_STS_RUNNING | AUDMIXSINK_STS_DRAINING)) 1836 1780 { 1837 uint32_t fStatusOld = pSink->fStatus;1838 1839 1781 /* 1840 1782 * Before doing jobs, always update input sinks. … … 1862 1804 */ 1863 1805 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 */ } 1872 1807 else 1873 1808 { … … 1877 1812 } 1878 1813 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));1883 1814 } 1884 1815 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 }1896 1816 1897 1817 /* … … 1902 1822 int rc = RTSemEventWait(pSink->AIO.hEvent, cMsSleep); 1903 1823 AssertLogRelMsgReturn(RT_SUCCESS(rc) || rc == VERR_TIMEOUT, ("%s: RTSemEventWait -> %Rrc\n", pSink->pszName, rc), rc); 1904 #ifdef LOG_ENABLED1905 Log3Func(("%s: Got signalled (fStatus=%s)\n", pSink->pszName, dbgAudioMixerSinkStatusToStr(pSink->fStatus, szStatus)));1906 #endif1907 1824 } 1908 1825 } … … 1970 1887 { 1971 1888 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);1977 1889 AssertRCReturnStmt(rc, RTCritSectLeave(&pSink->CritSect), rc); 1978 1890 } … … 2048 1960 2049 1961 /** 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 else2076 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 /**2107 1962 * Writes data to a mixer output sink. 2108 1963 * … … 2169 2024 idStream, cbSinkWritable, cbCircBufReadable, cbToTransfer, offStream)); 2170 2025 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)); 2173 2027 2174 2028 /* -
TabularUnified trunk/src/VBox/Devices/Audio/AudioMixer.h ¶
r98405 r98456 244 244 /** Event for letting the thread know there is some data to process. */ 245 245 RTSEMEVENT hEvent; 246 /** Event for letting the waiters know that draining the sink is done. */247 RTSEMEVENT hEventDrained;248 246 /** The device instance (same for all update jobs). */ 249 247 PPDMDEVINS pDevIns; … … 311 309 * @{ */ 312 310 int AudioMixerSinkStart(PAUDMIXSINK pSink); 313 int AudioMixerSinkDrainAndStopEx(PAUDMIXSINK pSink, uint32_t cbComming, RTMSINTERVAL msTimeout);314 311 int AudioMixerSinkDrainAndStop(PAUDMIXSINK pSink, uint32_t cbComming); 315 312 void AudioMixerSinkDestroy(PAUDMIXSINK pSink, PPDMDEVINS pDevIns); … … 327 324 int AudioMixerSinkRemoveUpdateJob(PAUDMIXSINK pSink, PFNAUDMIXSINKUPDATE pfnUpdate, void *pvUser); 328 325 int AudioMixerSinkSignalUpdateJob(PAUDMIXSINK pSink); 329 int AudioMixerSinkWaitForDrained(PAUDMIXSINK pSink, RTMSINTERVAL msTimeout);330 326 uint64_t AudioMixerSinkTransferFromCircBuf(PAUDMIXSINK pSink, PRTCIRCBUF pCircBuf, uint64_t offStream, 331 327 uint32_t idStream, PAUDIOHLPFILE pDbgFile); -
TabularUnified trunk/src/VBox/Devices/Audio/DevHdaStream.cpp ¶
r98405 r98456 1059 1059 } 1060 1060 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); 1064 1063 } 1065 1064 if ( RT_SUCCESS(rc) -
TabularUnified trunk/src/VBox/Devices/Audio/DevIchAc97.cpp ¶
r98405 r98456 2348 2348 else 2349 2349 { 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); 2353 2351 ichac97R3StreamTearDown(pStream); 2354 2352 } -
TabularUnified trunk/src/VBox/Devices/Audio/DevSB16.cpp ¶
r98405 r98456 2012 2012 else 2013 2013 { 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); 2016 2015 AssertRCReturn(rc, rc); 2017 2016 }
Note:
See TracChangeset
for help on using the changeset viewer.