Changeset 88080 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Mar 10, 2021 9:22:36 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 143221
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDACommon.cpp
r87863 r88080 742 742 } 743 743 744 /**745 * Sets the virtual device timer to a new expiration time.746 *747 * @returns Whether the new expiration time was set or not.748 * @param pDevIns The device instance.749 * @param pStreamShared HDA stream to set timer for (shared).750 * @param tsExpire New (virtual) expiration time to set.751 * @param fForce Whether to force setting the expiration time or not.752 * @param tsNow The current clock timestamp if available, 0 if not.753 *754 * @remark This function takes all active HDA streams and their755 * current timing into account. This is needed to make sure756 * that all streams can match their needed timing.757 *758 * To achieve this, the earliest (lowest) timestamp of all759 * active streams found will be used for the next scheduling slot.760 *761 * Forcing a new expiration time will override the above mechanism.762 */763 bool hdaR3TimerSet(PPDMDEVINS pDevIns, PHDASTREAM pStreamShared, uint64_t tsExpire, bool fForce, uint64_t tsNow)764 {765 AssertPtr(pStreamShared);766 767 if (!tsNow)768 tsNow = PDMDevHlpTimerGet(pDevIns, pStreamShared->hTimer);769 770 if (!fForce)771 {772 /** @todo r=bird: hdaR3StreamTransferIsScheduled() also does a773 * PDMDevHlpTimerGet(), so, some callers does one, this does, and then we do774 * right afterwards == very inefficient! */775 if (hdaR3StreamTransferIsScheduled(pStreamShared, tsNow))776 {777 uint64_t const tsNext = hdaR3StreamTransferGetNext(pStreamShared);778 if (tsExpire > tsNext)779 tsExpire = tsNext;780 }781 }782 783 /*784 * Make sure to not go backwards in time, as this will assert in TMTimerSet().785 * This in theory could happen in hdaR3StreamTransferGetNext() from above.786 */787 if (tsExpire < tsNow)788 tsExpire = tsNow;789 790 int rc = PDMDevHlpTimerSet(pDevIns, pStreamShared->hTimer, tsExpire);791 AssertRCReturn(rc, false);792 793 return true;794 }795 796 744 #endif /* IN_RING3 */ -
trunk/src/VBox/Devices/Audio/DevHDACommon.h
r87863 r88080 671 671 /** @} */ 672 672 673 /** @name Device timer functions.674 * @{675 */676 #ifdef IN_RING3677 bool hdaR3TimerSet(PPDMDEVINS pDevIns, PHDASTREAM pStreamShared, uint64_t u64Expire, bool fForce, uint64_t tsNow);678 #endif679 /** @} */680 681 673 #endif /* !VBOX_INCLUDED_SRC_Audio_DevHDACommon_h */ 682 674 -
trunk/src/VBox/Devices/Audio/HDAStream.cpp
r88063 r88080 1021 1021 1022 1022 /** 1023 * Returns whether a next transfer for a given stream is scheduled or not.1024 *1025 * This takes pending stream interrupts into account as well as the next scheduled1026 * transfer timestamp.1027 *1028 * @returns True if a next transfer is scheduled, false if not.1029 * @param pStreamShared HDA stream to retrieve schedule status for (shared).1030 * @param tsNow The current time.1031 */1032 bool hdaR3StreamTransferIsScheduled(PHDASTREAM pStreamShared, uint64_t tsNow)1033 {1034 if (pStreamShared)1035 {1036 if (pStreamShared->State.fRunning)1037 {1038 if (pStreamShared->State.cTransferPendingInterrupts)1039 {1040 Log3Func(("[SD%RU8] Scheduled (%RU8 IRQs pending)\n", pStreamShared->u8SD, pStreamShared->State.cTransferPendingInterrupts));1041 return true;1042 }1043 1044 /** @todo r=bird: how can this be right? */1045 if (pStreamShared->State.tsTransferNext > tsNow)1046 {1047 Log3Func(("[SD%RU8] Scheduled in %RU64\n", pStreamShared->u8SD, pStreamShared->State.tsTransferNext - tsNow));1048 return true;1049 }1050 }1051 }1052 return false;1053 }1054 1055 /**1056 * Returns the (virtual) clock timestamp of the next transfer, if any.1057 * Will return 0 if no new transfer is scheduled.1058 *1059 * @returns The (virtual) clock timestamp of the next transfer.1060 * @param pStreamShared HDA stream to retrieve timestamp for (shared).1061 */1062 uint64_t hdaR3StreamTransferGetNext(PHDASTREAM pStreamShared)1063 {1064 return pStreamShared->State.tsTransferNext;1065 }1066 1067 /**1068 1023 * Writes audio data from a mixer sink into an HDA stream's DMA buffer. 1069 1024 * … … 1750 1705 Assert(PDMDevHlpTimerIsLockOwner(pDevIns, pStreamShared->hTimer)); 1751 1706 1707 /* Do the work: */ 1752 1708 hdaR3StreamUpdate(pDevIns, pThis, pThisCC, pStreamShared, pStreamR3, true /* fInTimer */); 1753 1709 1754 /* Flag indicating whether to kick the timer again for a new data processing round. */ 1755 bool fSinkActive = false; 1756 if (pStreamR3->pMixSink) 1757 fSinkActive = AudioMixerSinkIsActive(pStreamR3->pMixSink->pMixSink); 1758 1759 #ifdef LOG_ENABLED 1760 const uint8_t uSD = pStreamShared->u8SD; 1761 #endif 1762 1763 if (fSinkActive) 1764 { 1765 const uint64_t tsNow = PDMDevHlpTimerGet(pDevIns, pStreamShared->hTimer); /* (For virtual sync this remains the same for the whole callout IIRC) */ 1766 const bool fTimerScheduled = hdaR3StreamTransferIsScheduled(pStreamShared, tsNow); 1767 1768 /** @todo r=bird: This is a waste of time if the timer is called at a 1769 * constant rate. We can just calculate it here. */ 1770 uint64_t tsTransferNext; 1771 if (fTimerScheduled) 1772 { 1773 Assert(pStreamShared->State.tsTransferNext); /* Make sure that a new transfer timestamp is set. */ 1774 tsTransferNext = pStreamShared->State.tsTransferNext; 1775 } 1776 else /* Schedule at the precalculated rate. */ 1777 tsTransferNext = tsNow + pStreamShared->State.cTransferTicks; 1778 1779 Log3Func(("[SD%RU8] fSinksActive=%RTbool, fTimerScheduled=%RTbool, tsTransferNext=%RU64 (in %RU64)\n", 1780 uSD, fSinkActive, fTimerScheduled, tsTransferNext, tsTransferNext - tsNow)); 1781 1782 hdaR3TimerSet(pDevIns, pStreamShared, tsTransferNext, 1783 true /*fForce*/, tsNow); 1710 /* Re-arm the timer if the sink is still active: */ 1711 if ( pStreamR3->pMixSink 1712 && AudioMixerSinkIsActive(pStreamR3->pMixSink->pMixSink)) 1713 { 1714 uint64_t const tsNow = PDMDevHlpTimerGet(pDevIns, pStreamShared->hTimer); /* (For virtual sync this remains the same for the whole callout IIRC) */ 1715 uint64_t const tsTransferNext = tsNow + pStreamShared->State.cTransferTicks; 1716 Log3Func(("[SD%RU8] fSinkActive=true, tsTransferNext=%RU64 (in %RU64)\n", 1717 pStreamShared->u8SD, tsTransferNext, tsTransferNext - tsNow)); 1718 pStreamShared->State.tsTransferNext = tsTransferNext; /* legacy */ 1719 int rc = PDMDevHlpTimerSet(pDevIns, pStreamShared->hTimer, tsTransferNext); 1720 AssertRC(rc); 1721 1784 1722 return tsNow; 1785 1723 } 1786 1724 1787 Log3Func(("[SD%RU8] fSink sActive=%RTbool\n", uSD, fSinkActive));1725 Log3Func(("[SD%RU8] fSinkActive=false\n", pStreamShared->u8SD)); 1788 1726 return 0; 1789 1727 } -
trunk/src/VBox/Devices/Audio/HDAStream.h
r88063 r88080 303 303 uint64_t hdaR3StreamTimerMain(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC, 304 304 PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3); 305 bool hdaR3StreamTransferIsScheduled(PHDASTREAM pStreamShared, uint64_t tsNow);306 uint64_t hdaR3StreamTransferGetNext(PHDASTREAM pStreamShared);307 305 void hdaR3StreamUpdate(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTATER3 pThisCC, 308 306 PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3, bool fInTimer);
Note:
See TracChangeset
for help on using the changeset viewer.