Changeset 88094 in vbox
- Timestamp:
- Mar 11, 2021 3:00:17 PM (4 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r88077 r88094 5180 5180 5181 5181 for (uint8_t idxStream = 0; idxStream < RT_ELEMENTS(pThisCC->aStreams); idxStream++) 5182 { 5183 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.StatDmaFlowProblems, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, 5184 "Number of internal DMA buffer problems.", "Stream%u/DMABufferProblems", idxStream); 5182 5185 if (hdaGetDirFromSD(idxStream) == PDMAUDIODIR_OUT) 5183 5186 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.StatDmaFlowErrors, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, 5184 "Number of DMA overflows.", "Stream%u/DMAOverflows", idxStream);5187 "Number of internal DMA buffer overflows.", "Stream%u/DMABufferOverflows", idxStream); 5185 5188 else 5186 5189 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.StatDmaFlowErrors, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, 5187 "Number of DMA underflows.", "Stream%u/DMAUnderflows", idxStream); 5190 "Number of internal DMA buffer underuns.", "Stream%u/DMABufferUnderruns", idxStream); 5191 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.offRead, STAMTYPE_U64, STAMVISIBILITY_USED, STAMUNIT_BYTES, 5192 "Virtual internal buffer read position.", "Stream%u/offRead", idxStream); 5193 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.offWrite, STAMTYPE_U64, STAMVISIBILITY_USED, STAMUNIT_BYTES, 5194 "Virtual internal buffer write position.", "Stream%u/offWrite", idxStream); 5195 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStreams[idxStream].State.cbTransferSize, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_BYTES, 5196 "Bytes transfered per DMA timer callout.", "Stream%u/cbTransferSize", idxStream); 5197 PDMDevHlpSTAMRegisterF(pDevIns, (void*)&pThis->aStreams[idxStream].State.fRunning, STAMTYPE_BOOL, STAMVISIBILITY_USED, STAMUNIT_BYTES, 5198 "True if the stream is in RUN mode.", "Stream%u/fRunning", idxStream); 5199 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStreams[idxStream].State.Cfg.Props.uHz, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_BYTES, 5200 "The stream frequency.", "Stream%u/Cfg/Hz", idxStream); 5201 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStreams[idxStream].State.Cfg.Props.cChannels, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES, 5202 "The number of channels.", "Stream%u/Cfg/Channels", idxStream); 5203 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStreams[idxStream].State.Cfg.Props.cbSample, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES, 5204 "The size of a sample (per channel).", "Stream%u/Cfg/cbSample", idxStream); 5205 } 5188 5206 5189 5207 return VINF_SUCCESS; -
trunk/src/VBox/Devices/Audio/HDAStream.cpp
r88080 r88094 1178 1178 else 1179 1179 { 1180 Assert(hdaGetDirFromSD(uSD) != PDMAUDIODIR_OUT /* Handled by caller */); 1180 1181 /** @todo account for this or something so we can try get back in sync 1181 1182 * later... */ … … 1687 1688 1688 1689 /** 1690 * Output streams: Pushes data from to the mixer and host device. 1691 * 1692 * @param pStreamShared HDA stream to update (shared bits). 1693 * @param pStreamR3 HDA stream to update (ring-3 bits). 1694 * @param pSink The mixer sink to push to. 1695 * @param nsNow The current RTTimeNanoTS() value. 1696 */ 1697 static void hdaR3StreamPushToMixer(PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, PAUDMIXSINK pSink, uint64_t nsNow) 1698 { 1699 uint32_t const cbSinkWritable = AudioMixerSinkGetWritable(pSink); 1700 uint32_t const cbStreamReadable = hdaR3StreamGetUsed(pStreamR3); 1701 uint32_t cbToReadFromStream = RT_MIN(cbStreamReadable, cbSinkWritable); 1702 /* Make sure that we always align the number of bytes when reading to the stream's PCM properties. */ 1703 cbToReadFromStream = PDMAudioPropsFloorBytesToFrame(&pStreamR3->State.Mapping.PCMProps, cbToReadFromStream); 1704 1705 Assert(nsNow >= pStreamShared->State.tsLastReadNs); 1706 Log3Func(("[SD%RU8] msDeltaLastRead=%RI64\n", 1707 pStreamShared->u8SD, (nsNow - pStreamShared->State.tsLastReadNs) / RT_NS_1MS)); 1708 Log3Func(("[SD%RU8] cbSinkWritable=%RU32, cbStreamReadable=%RU32 -> cbToReadFromStream=%RU32\n", 1709 pStreamShared->u8SD, cbSinkWritable, cbStreamReadable, cbToReadFromStream)); 1710 1711 if (cbToReadFromStream) 1712 { 1713 /* Read (guest output) data and write it to the stream's sink. */ 1714 int rc2 = hdaR3StreamRead(pStreamR3, cbToReadFromStream, NULL /* pcbRead */); 1715 AssertRC(rc2); 1716 } 1717 1718 /* When running synchronously, update the associated sink here. 1719 * Otherwise this will be done in the async I/O thread. */ 1720 int rc2 = AudioMixerSinkUpdate(pSink); 1721 AssertRC(rc2); 1722 } 1723 1724 /** 1689 1725 * The stream's main function when called by the timer. 1690 1726 * … … 1770 1806 if (hdaGetDirFromSD(pStreamShared->u8SD) == PDMAUDIODIR_OUT) /* Output (SDO). */ 1771 1807 { 1772 /* 1773 * Do DMA work. 1774 */ 1775 bool fDoRead = false; /* Whether to push data down the driver stack or not. */ 1808 bool fDoRead; /* Whether to push data down the driver stack or not. */ 1776 1809 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 1777 1810 if (fInTimer) 1778 1811 # endif 1779 1812 { 1813 /* 1814 * Check how much room we have in our DMA buffer. There should be at 1815 * least one period worth of space there or we're in an overflow situation. 1816 */ 1780 1817 uint32_t cbStreamFree = hdaR3StreamGetFree(pStreamR3); 1781 if (cbStreamFree )1818 if (cbStreamFree >= pStreamShared->State.cbTransferSize) 1782 1819 { /* likely */ } 1783 1820 else 1784 1821 { 1785 LogRel2(("HDA: Warning: Hit stream #%RU8 overflow, dropping audio data\n", pStreamShared->u8SD)); 1822 STAM_REL_COUNTER_INC(&pStreamR3->State.StatDmaFlowProblems); 1823 Log(("hdaR3StreamUpdate: Warning! Stream #%u has insufficient space free: %u bytes, need %u. Will try move data out of the buffer...\n", 1824 pStreamShared->u8SD, cbStreamFree, pStreamShared->State.cbTransferSize)); 1825 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 1826 int rc = RTCritSectTryEnter(&pStreamR3->State.AIO.CritSect); 1827 if (RT_SUCCESS(rc)) 1828 { 1829 hdaR3StreamPushToMixer(pStreamShared, pStreamR3, pSink, tsNowNs); 1830 RTCritSectLeave(&pStreamR3->State.AIO.CritSect); 1831 } 1832 else 1833 RTThreadYield(); 1834 #else 1835 hdaR3StreamPushToMixer(pStreamShared, pStreamR3, pSink, tsNowNs); 1836 #endif 1837 Log(("hdaR3StreamUpdate: Gained %u bytes.\n", hdaR3StreamGetFree(pStreamR3) - cbStreamFree)); 1838 1839 cbStreamFree = hdaR3StreamGetFree(pStreamR3); 1840 if (cbStreamFree < pStreamShared->State.cbTransferSize) 1841 { 1842 /* Unable to make sufficient space. Drop the whole buffer content. 1843 * This is needed in order to keep the device emulation running at a constant rate, 1844 * at the cost of losing valid (but too much) data. */ 1845 STAM_REL_COUNTER_INC(&pStreamR3->State.StatDmaFlowErrors); 1846 LogRel2(("HDA: Warning: Hit stream #%RU8 overflow, dropping %u bytes of audio data\n", 1847 pStreamShared->u8SD, hdaR3StreamGetUsed(pStreamR3))); 1786 1848 # ifdef HDA_STRICT 1787 AssertMsgFailed(("Hit stream #%RU8 overflow -- timing bug?\n", pStreamShared->u8SD));1849 AssertMsgFailed(("Hit stream #%RU8 overflow -- timing bug?\n", pStreamShared->u8SD)); 1788 1850 # endif 1789 /* When hitting an overflow, drop all remaining data to make space for current data.1790 * This is needed in order to keep the device emulation running at a constant rate,1791 * at the cost of losing valid (but too much) data. */1792 RTCircBufReset(pStreamR3->State.pCircBuf);1793 pStreamR3->State.offWrite = 0;1794 pStreamR3->State.offRead = 0;1795 cbStreamFree = hdaR3StreamGetFree(pStreamR3); 1796 }1797 1798 /* Do the DMA transfer.*/1851 RTCircBufReset(pStreamR3->State.pCircBuf); 1852 pStreamR3->State.offWrite = 0; 1853 pStreamR3->State.offRead = 0; 1854 cbStreamFree = hdaR3StreamGetFree(pStreamR3); 1855 } 1856 } 1857 1858 /* 1859 * Do the DMA transfer. 1860 */ 1799 1861 uint64_t const offWriteBefore = pStreamR3->State.offWrite; 1800 1862 rc2 = hdaR3StreamTransfer(pDevIns, pThis, pThisCC, pStreamShared, pStreamR3, cbStreamFree); … … 1802 1864 1803 1865 /* 1804 * Push data to down thru the mixer to and to the host drivers?1866 * Should we push data to down thru the mixer to and to the host drivers? 1805 1867 * 1806 1868 * We initially delay this by pThis->msInitialDelay, but after than we'll … … 1852 1914 1853 1915 /* 1854 * <Missing Description> 1916 * Move data out of the pStreamR3->State.pCircBuf buffer and to 1917 * the mixer and in direction of the host audio devices. 1855 1918 */ 1856 1919 # ifdef VBOX_WITH_AUDIO_HDA_ASYNC_IO 1857 if (!fInTimer) /* In async I/O thread */1920 else 1858 1921 # else 1859 1922 if (fDoRead) 1860 1923 # endif 1861 { 1862 uint32_t const cbSinkWritable = AudioMixerSinkGetWritable(pSink); 1863 uint32_t const cbStreamReadable = hdaR3StreamGetUsed(pStreamR3); 1864 uint32_t cbToReadFromStream = RT_MIN(cbStreamReadable, cbSinkWritable); 1865 /* Make sure that we always align the number of bytes when reading to the stream's PCM properties. */ 1866 cbToReadFromStream = PDMAudioPropsFloorBytesToFrame(&pStreamR3->State.Mapping.PCMProps, cbToReadFromStream); 1867 1868 Assert(tsNowNs >= pStreamShared->State.tsLastReadNs); 1869 Log3Func(("[SD%RU8] msDeltaLastRead=%RI64\n", 1870 pStreamShared->u8SD, (tsNowNs - pStreamShared->State.tsLastReadNs) / RT_NS_1MS)); 1871 Log3Func(("[SD%RU8] cbSinkWritable=%RU32, cbStreamReadable=%RU32 -> cbToReadFromStream=%RU32\n", 1872 pStreamShared->u8SD, cbSinkWritable, cbStreamReadable, cbToReadFromStream)); 1873 1874 if (cbToReadFromStream) 1875 { 1876 /* Read (guest output) data and write it to the stream's sink. */ 1877 rc2 = hdaR3StreamRead(pStreamR3, cbToReadFromStream, NULL /* pcbRead */); 1878 AssertRC(rc2); 1879 } 1880 1881 /* When running synchronously, update the associated sink here. 1882 * Otherwise this will be done in the async I/O thread. */ 1883 rc2 = AudioMixerSinkUpdate(pSink); 1884 AssertRC(rc2); 1885 } 1924 hdaR3StreamPushToMixer(pStreamShared, pStreamR3, pSink, tsNowNs); 1886 1925 } 1887 1926 else /* Input (SDI). */ -
trunk/src/VBox/Devices/Audio/HDAStream.h
r88080 r88094 268 268 HDASTREAMSTATEAIO AIO; 269 269 #endif 270 /** Under/overflow statistics counter. */ 270 /** Counter for all under/overflows problems. */ 271 STAMCOUNTER StatDmaFlowProblems; 272 /** Counter for unresovled under/overflows problems. */ 271 273 STAMCOUNTER StatDmaFlowErrors; 272 274 } State;
Note:
See TracChangeset
for help on using the changeset viewer.