Changeset 57451 in vbox
- Timestamp:
- Aug 19, 2015 9:39:17 AM (10 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp
r57397 r57451 214 214 215 215 return rc; 216 } 217 218 /** 219 * Returns available number of samples for reading. 220 * 221 * @return uint32_t Number of samples available for reading. 222 * @param pMixBuf Mixing buffer to return value for. 223 */ 224 uint32_t AudioMixBufAvail(PPDMAUDIOMIXBUF pMixBuf) 225 { 226 AssertPtrReturn(pMixBuf, true); 227 228 uint32_t cAvail; 229 if (pMixBuf->pParent) /* Child */ 230 cAvail = pMixBuf->cMixed; 231 else 232 cAvail = pMixBuf->cProcessed; 233 234 Assert(cAvail <= pMixBuf->cSamples); 235 return cAvail; 216 236 } 217 237 … … 932 952 933 953 /** 934 * Returns the number of audio samples mixed (processed) from954 * Returns the number of audio samples mixed (processed) by 935 955 * the parent mixing buffer. 936 956 * … … 963 983 AssertPtrReturn(pDst, VERR_INVALID_POINTER); 964 984 AssertPtrReturn(pSrc, VERR_INVALID_POINTER); 985 AssertReturn(cSamples, VERR_INVALID_PARAMETER); 965 986 /* pcProcessed is optional. */ 966 987 … … 1264 1285 AssertPtrReturn(pMixBuf, VERR_INVALID_POINTER); 1265 1286 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); 1266 AssertReturn(cbBuf, VERR_INVALID_PARAMETER);1267 1287 /* pcbRead is optional. */ 1268 1288 -
trunk/src/VBox/Devices/Audio/AudioMixBuffer.h
r57397 r57451 51 51 52 52 int AudioMixBufAcquire(PPDMAUDIOMIXBUF pMixBuf, uint32_t cSamplesToRead, PPDMAUDIOSAMPLE *ppvSamples, uint32_t *pcSamplesRead); 53 uint32_t AudioMixBufAvail(PPDMAUDIOMIXBUF pMixBuf); 53 54 inline uint32_t AudioMixBufBytesToSamples(PPDMAUDIOMIXBUF pMixBuf); 54 55 void AudioMixBufClear(PPDMAUDIOMIXBUF pMixBuf); -
trunk/src/VBox/Devices/Audio/DrvAudio.cpp
r57442 r57451 444 444 if (RT_SUCCESS(rc)) 445 445 { 446 Assert(!pHstStrmOut->fPendingDisable); 446 447 pHstStrmOut->fEnabled = true; 448 LogFunc(("[%s] Enabled stream\n", pHstStrmOut->MixBuf.pszName)); 447 449 } 448 450 else 449 LogFlowFunc(("Backend reported an error when opening output stream, rc=%Rrc\n", rc)); 451 LogFlowFunc(("[%s] Backend reported an error when opening output stream, rc=%Rrc\n", 452 pHstStrmOut->MixBuf.pszName, rc)); 450 453 } 451 454 else … … 462 465 if (RT_SUCCESS(rc)) 463 466 { 464 pHstStrmOut->fEnabled = false; 467 pHstStrmOut->fEnabled = false; 468 pHstStrmOut->fPendingDisable = false; 465 469 AudioMixBufClear(&pHstStrmOut->MixBuf); 470 471 LogFunc(("[%s] Disabled stream\n", pHstStrmOut->MixBuf.pszName)); 466 472 } 467 473 else 468 LogFlowFunc((" Backend vetoed closing output stream, rc=%Rrc\n", rc));474 LogFlowFunc(("[%s] Backend vetoed closing output stream, rc=%Rrc\n", pHstStrmOut->MixBuf.pszName, rc)); 469 475 } 470 476 else … … 1015 1021 if (RT_SUCCESS(rc)) 1016 1022 { 1017 /* Return the number of samples which actually have been mixed 1023 /* 1024 * Return the number of samples which actually have been mixed 1018 1025 * down to the parent, regardless how much samples were written 1019 * into the children buffer. */ 1026 * into the children buffer. 1027 */ 1020 1028 if (pcbWritten) 1021 1029 *pcbWritten = AUDIOMIXBUF_S2B(&pGstStrmOut->MixBuf, cMixed); 1022 1030 } 1023 1031 1024 LogFlowFunc(("%s -> %s: Written pvBuf=%p, cbBuf=% zu, cWritten=%RU32 (%RU32 bytes), cMixed=%RU32, rc=%Rrc\n",1032 LogFlowFunc(("%s -> %s: Written pvBuf=%p, cbBuf=%RU32, cWritten=%RU32 (%RU32 bytes), cMixed=%RU32, rc=%Rrc\n", 1025 1033 pGstStrmOut->MixBuf.pszName, pHstStrmOut->MixBuf.pszName, pvBuf, cbBuf, cWritten, 1026 1034 AUDIOMIXBUF_S2B(&pGstStrmOut->MixBuf, cWritten), cMixed, rc)); … … 1147 1155 while ((pHstStrmOut = drvAudioHstFindAnyEnabledOut(pThis, pHstStrmOut))) 1148 1156 { 1149 uint32_t cStreamsLive; 1150 cSamplesLive = drvAudioHstOutSamplesLive(pHstStrmOut, &cStreamsLive); 1151 if (!cStreamsLive) 1152 cSamplesLive = 0; 1157 cSamplesLive = drvAudioHstOutSamplesLive(pHstStrmOut); 1153 1158 1154 1159 /* Has this stream marked as disabled but there still were guest streams relying 1155 1160 * on it? Check if this stream now can be closed and do so, if possible. */ 1156 1161 if ( pHstStrmOut->fPendingDisable 1157 && !cS treamsLive)1162 && !cSamplesLive) 1158 1163 { 1159 1164 /* Stop playing the current (pending) stream. */ … … 1191 1196 AudioMixBufFree(&pGstStrmOut->MixBuf))); 1192 1197 1193 LogFlowFunc(("\t[%s] cbFree=%RU32\n", pGstStrmOut->MixBuf.pszName, cbFree2));1198 //LogFlowFunc(("\t[%s] cbFree=%RU32\n", pGstStrmOut->MixBuf.pszName, cbFree2)); 1194 1199 } 1195 1200 } … … 1294 1299 cSamplesPlayedMax = RT_MAX(cSamplesPlayed, cSamplesPlayedMax); 1295 1300 1296 LogFlowFunc(("\t[%s] cSamplesPlayed=%RU32, rc=%Rrc\n", pHstStrmOut->MixBuf.pszName, cSamplesPlayed, rc2)); 1301 LogFlowFunc(("\t[%s] cSamplesPlayed=%RU32, cSamplesPlayedMax=%RU32, rc=%Rrc\n", 1302 pHstStrmOut->MixBuf.pszName, cSamplesPlayed, cSamplesPlayedMax, rc2)); 1297 1303 1298 1304 bool fNeedsCleanup = false; … … 1569 1575 AssertPtr(pHstStrmOut); 1570 1576 1571 if (pGstStrmOut->State.fActive != fEnable) 1577 if (pGstStrmOut->State.fActive != fEnable) /* Only process real state changes. */ 1572 1578 { 1573 1579 if (fEnable) … … 1577 1583 rc = drvAudioControlHstOut(pThis, pHstStrmOut, PDMAUDIOSTREAMCMD_ENABLE, 0 /* Flags */); 1578 1584 } 1579 else 1585 else /* Disable */ 1580 1586 { 1581 1587 if (pHstStrmOut->fEnabled) … … 1583 1589 uint32_t cGstStrmsActive = 0; 1584 1590 1591 /* 1592 * Check if there are any active guest streams assigned 1593 * to this host stream which still are being marked as active. 1594 * 1595 * In that case we have to defer closing the host stream and 1596 * wait until all guest streams have been finished. 1597 */ 1585 1598 PPDMAUDIOGSTSTRMOUT pIter; 1586 1599 RTListForEach(&pHstStrmOut->lstGstStrmOut, pIter, PDMAUDIOGSTSTRMOUT, Node) 1587 1600 { 1588 1601 if (pIter->State.fActive) 1602 { 1589 1603 cGstStrmsActive++; 1604 break; /* At least one assigned & active guest stream is enough. */ 1605 } 1590 1606 } 1591 1607 1608 /* Do we need to defer closing the host stream? */ 1592 1609 pHstStrmOut->fPendingDisable = cGstStrmsActive >= 1; 1610 1611 /* Can we close the host stream now instead of deferring it? */ 1612 if (!pHstStrmOut->fPendingDisable) 1613 rc = drvAudioControlHstOut(pThis, pHstStrmOut, PDMAUDIOSTREAMCMD_DISABLE, 0 /* Flags */); 1593 1614 } 1594 1615 } … … 1597 1618 pGstStrmOut->State.fActive = fEnable; 1598 1619 1599 LogFlowFunc(("%s: fEnable=%RTbool, rc=%Rrc\n", pGstStrmOut->MixBuf.pszName, fEnable, rc)); 1620 LogFlowFunc(("%s: fEnable=%RTbool, fPendingDisable=%RTbool, rc=%Rrc\n", 1621 pGstStrmOut->MixBuf.pszName, fEnable, pHstStrmOut->fPendingDisable, rc)); 1600 1622 } 1601 1623 } … … 1621 1643 LogFlowFunc(("%s: fEnable=%RTbool\n", pGstStrmIn->MixBuf.pszName, fEnable)); 1622 1644 1623 if (pGstStrmIn->State.fActive != fEnable) 1645 if (pGstStrmIn->State.fActive != fEnable) /* Only process real state changes. */ 1624 1646 { 1625 1647 rc = drvAudioControlHstIn(pThis, pHstStrmIn, -
trunk/src/VBox/Devices/Audio/DrvAudio.h
r57382 r57451 147 147 void drvAudioClearBuf(PPDMPCMPROPS pPCMInfo, void *pvBuf, size_t cbBuf); 148 148 void drvAudioDetachCapture(PPDMAUDIOHSTSTRMOUT pHstStrmOut); 149 uint32_t drvAudioHstOutSamplesLive(PPDMAUDIOHSTSTRMOUT pHstStrmOut , uint32_t *pcStreamsLive);149 uint32_t drvAudioHstOutSamplesLive(PPDMAUDIOHSTSTRMOUT pHstStrmOut); 150 150 151 151 -
trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp
r56648 r57451 409 409 410 410 /** 411 * Returns the minimum number of live samples already written to all associated 412 * guest output streams of a specific host output stream. 413 * 414 * @return uint32_t Minimum number of total live samples already written to all 415 * associated guest output streams, UINT32_MAX if none found. 416 * @param pHstStrmOut Host output stream to search in. 417 * @param pcStreamsLive Returns the number of live guest streams associated to 418 * this host output stream. Optional. 419 */ 420 static uint32_t drvAudioHstOutMinSamplesMixed(PPDMAUDIOHSTSTRMOUT pHstStrmOut, uint32_t *pcStreamsLive) 421 { 422 AssertPtrReturn(pHstStrmOut, 0); 423 /* pcStreamsLive is optional. */ 424 425 uint32_t cStreamsLive = 0; 426 uint32_t cMinSamplesMixed = UINT32_MAX; 427 uint32_t cSamples; 428 429 PPDMAUDIOGSTSTRMOUT pGstStrmOut; 430 RTListForEach(&pHstStrmOut->lstGstStrmOut, pGstStrmOut, PDMAUDIOGSTSTRMOUT, Node) 431 { 432 if ( pGstStrmOut->State.fActive 433 || !pGstStrmOut->State.fEmpty) 434 { 435 cSamples = AudioMixBufMixed(&pGstStrmOut->MixBuf); 436 cMinSamplesMixed = RT_MIN(cMinSamplesMixed, cSamples); 437 438 cStreamsLive++; 439 } 440 } 441 442 if (pcStreamsLive) 443 *pcStreamsLive = cStreamsLive; 444 445 return cMinSamplesMixed; 446 } 447 448 /** 449 * Finds the number of live (guest) samples of a specific host output stream. 411 * Finds the number of live samples for a specific output stream. 450 412 * 451 413 * @return uint32_t Minimum number of live host output samples processed 452 414 * by all connected guest output streams. 453 415 * @param pHstStrmOut Host output stream to search in. 454 * @param pcStreamsLive Number of associated guest live streams. Optional. 455 */ 456 uint32_t drvAudioHstOutSamplesLive(PPDMAUDIOHSTSTRMOUT pHstStrmOut, uint32_t *pcStreamsLive) 416 */ 417 uint32_t drvAudioHstOutSamplesLive(PPDMAUDIOHSTSTRMOUT pHstStrmOut) 457 418 { 458 419 AssertPtrReturn(pHstStrmOut, 0); 459 /* pcStreamsLive is optional. */ 460 461 uint32_t cStreamsLive; 462 uint32_t cSamplesMin = drvAudioHstOutMinSamplesMixed(pHstStrmOut, &cStreamsLive); 463 464 if (pcStreamsLive) 465 *pcStreamsLive = cStreamsLive; 466 467 if (cStreamsLive) /* Any live streams at all? */ 468 { 469 if ( cSamplesMin == UINT32_MAX 470 || cSamplesMin > AudioMixBufSize(&pHstStrmOut->MixBuf)) 471 { 472 LogFlowFunc(("Error: cSamplesMin=%RU32\n", cSamplesMin)); 473 return 0; 474 } 475 476 return cSamplesMin; 477 } 478 479 return 0; 480 } 481 420 421 uint32_t cSamplesLive = AudioMixBufAvail(&pHstStrmOut->MixBuf); 422 423 LogFlowFunc(("%s: cStreamsLive=%RU32, cSamplesLive=%RU32\n", pHstStrmOut->MixBuf.pszName, cSamplesLive)); 424 return cSamplesLive; 425 } 426 -
trunk/src/VBox/Devices/Audio/DrvHostALSAAudio.cpp
r57427 r57451 946 946 (uint32_t)cAvail), /* cAvail is always >= 0 */ 947 947 AUDIOMIXBUF_S2B(&pHstStrmOut->MixBuf, 948 drvAudioHstOutSamplesLive(pHstStrmOut , NULL /* pcStreamsLive */)));948 drvAudioHstOutSamplesLive(pHstStrmOut))); 949 949 LogFlowFunc(("cbToRead=%zu, cbAvail=%zu\n", 950 950 cbToRead, AUDIOMIXBUF_S2B(&pHstStrmOut->MixBuf, cAvail))); -
trunk/src/VBox/Devices/Audio/DrvHostCoreAudio.cpp
r56649 r57451 1494 1494 /* Not much else to do here. */ 1495 1495 1496 uint32_t cLive = drvAudioHstOutSamplesLive(pHstStrmOut , NULL /* pcStreamsLive */);1496 uint32_t cLive = drvAudioHstOutSamplesLive(pHstStrmOut); 1497 1497 if (!cLive) /* Not samples to play? Bail out. */ 1498 1498 { -
trunk/src/VBox/Devices/Audio/DrvHostDSound.cpp
r57398 r57451 1160 1160 } 1161 1161 1162 uint32_t csLive = drvAudioHstOutSamplesLive(pHstStrmOut , NULL /* pcStreamsLive */);1162 uint32_t csLive = drvAudioHstOutSamplesLive(pHstStrmOut); 1163 1163 uint32_t cbLive = csLive << cShift; 1164 1164 -
trunk/src/VBox/Devices/Audio/DrvHostNullAudio.cpp
r56648 r57451 153 153 154 154 /* Consume as many samples as would be played at the current frequency since last call. */ 155 uint32_t csLive = drvAudioHstOutSamplesLive(pHstStrmOut , NULL /* pcStreamsLive */);155 uint32_t csLive = drvAudioHstOutSamplesLive(pHstStrmOut); 156 156 uint64_t u64TicksNow = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns); 157 157 uint64_t u64TicksElapsed = u64TicksNow - pNullStrmOut->u64TicksLast; -
trunk/src/VBox/Devices/Audio/DrvHostOSSAudio.cpp
r57382 r57451 776 776 size_t cbBuf = AudioMixBufSizeBytes(&pHstStrmOut->MixBuf); 777 777 778 uint32_t cLive = drvAudioHstOutSamplesLive(pHstStrmOut, 779 NULL /* pcStreamsLive */); 778 uint32_t cLive = drvAudioHstOutSamplesLive(pHstStrmOut); 780 779 uint32_t cToRead; 781 780 -
trunk/src/VBox/Devices/Audio/DrvHostPulseAudio.cpp
r57358 r57451 833 833 uint32_t cbReadTotal = 0; 834 834 835 uint32_t cLive = drvAudioHstOutSamplesLive(pHstStrmOut , NULL /* pcStreamsLive */);835 uint32_t cLive = drvAudioHstOutSamplesLive(pHstStrmOut); 836 836 if (!cLive) 837 837 {
Note:
See TracChangeset
for help on using the changeset viewer.