Changeset 89693 in vbox
- Timestamp:
- Jun 14, 2021 9:22:12 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r89692 r89693 388 388 /** Number of used bytes in the DMA buffer (pCircBuf). */ 389 389 uint32_t StatDmaBufUsed; 390 /** Counter for all under/overflows problems. */ 391 STAMCOUNTER StatDmaFlowProblems; 392 /** Counter for unresovled under/overflows problems. */ 393 STAMCOUNTER StatDmaFlowErrors; 394 /** Number of bytes involved in unresolved flow errors. */ 395 STAMCOUNTER StatDmaFlowErrorBytes; 390 396 } AC97STREAMSTATE; 391 397 AssertCompileSizeAlignment(AC97STREAMSTATE, 8); … … 1325 1331 int rc2; 1326 1332 1333 /* The amount we're supposed to be transfering in this DMA period. */ 1334 uint32_t cbPeriod = pStreamCC->State.cbTransferChunk; 1335 1327 1336 /* 1328 1337 * Output streams (SDO). … … 1330 1339 if (pStreamCC->State.Cfg.enmDir == PDMAUDIODIR_OUT) 1331 1340 { 1341 /* 1342 * Check how much room we have in our DMA buffer. There should be at 1343 * least one period worth of space there or we're in an overflow situation. 1344 */ 1332 1345 uint32_t cbStreamFree = ichac97R3StreamGetFree(pStreamCC); 1333 if (cbStreamFree )1346 if (cbStreamFree >= cbPeriod) 1334 1347 { /* likely */ } 1335 1348 else 1336 1349 { 1337 /** @todo Record this as a statistic. Try make some space available. */ 1350 STAM_REL_COUNTER_INC(&pStreamCC->State.StatDmaFlowProblems); 1351 Log(("ichac97R3StreamUpdateDma: Warning! Stream #%u has insufficient space free: %u bytes, need %u. Will try move data out of the buffer...\n", 1352 pStreamCC->u8SD, cbStreamFree, cbPeriod)); 1353 int rc = AudioMixerSinkTryLock(pSink); 1354 if (RT_SUCCESS(rc)) 1355 { 1356 ichac97R3StreamPushToMixer(pStreamCC, pSink); 1357 AudioMixerSinkUpdate(pSink, 0, 0); 1358 AudioMixerSinkUnlock(pSink); 1359 } 1360 else 1361 RTThreadYield(); 1362 Log(("ichac97R3StreamUpdateDma: Gained %u bytes.\n", ichac97R3StreamGetFree(pStreamCC) - cbStreamFree)); 1363 1364 cbStreamFree = ichac97R3StreamGetFree(pStreamCC); 1365 if (cbStreamFree < cbPeriod) 1366 { 1367 /* Unable to make sufficient space. Drop the whole buffer content. 1368 * This is needed in order to keep the device emulation running at a constant rate, 1369 * at the cost of losing valid (but too much) data. */ 1370 STAM_REL_COUNTER_INC(&pStreamCC->State.StatDmaFlowErrors); 1371 LogRel2(("AC97: Warning: Hit stream #%RU8 overflow, dropping %u bytes of audio data\n", 1372 pStreamCC->u8SD, ichac97R3StreamGetUsed(pStreamCC))); 1373 # ifdef HDA_STRICT 1374 AssertMsgFailed(("Hit stream #%RU8 overflow -- timing bug?\n", pStreamCC->u8SD)); 1375 # endif 1376 RTCircBufReset(pStreamCC->State.pCircBuf); 1377 pStreamCC->State.offWrite = 0; 1378 pStreamCC->State.offRead = 0; 1379 cbStreamFree = ichac97R3StreamGetFree(pStreamCC); 1380 Assert(cbStreamFree >= cbPeriod); 1381 } 1338 1382 } 1339 if (cbStreamFree) 1340 { 1341 Log3Func(("[SD%RU8] PICB=%zu (%RU64ms), cbFree=%zu (%RU64ms), cbTransferChunk=%zu (%RU64ms)\n", 1342 pStream->u8SD, 1343 (pStream->Regs.picb << 1), PDMAudioPropsBytesToMilli(&pStreamCC->State.Cfg.Props, pStream->Regs.picb << 1), 1344 cbStreamFree, PDMAudioPropsBytesToMilli(&pStreamCC->State.Cfg.Props, cbStreamFree), 1345 pStreamCC->State.cbTransferChunk, PDMAudioPropsBytesToMilli(&pStreamCC->State.Cfg.Props, pStreamCC->State.cbTransferChunk))); 1346 1347 /* Do the DMA transfer. */ 1348 rc2 = ichac97R3StreamTransfer(pDevIns, pThis, pStream, pStreamCC, 1349 RT_MIN(pStreamCC->State.cbTransferChunk, cbStreamFree)); 1350 AssertRC(rc2); 1351 1352 pStreamCC->State.tsLastUpdateNs = RTTimeNanoTS(); 1353 } 1354 1383 1384 /* 1385 * Do the DMA transfer. 1386 */ 1387 Log3Func(("[SD%RU8] PICB=%#x samples / %RU64 ms, cbFree=%#x / %RU64 ms, cbTransferChunk=%#x / %RU64 ms\n", pStream->u8SD, 1388 pStream->Regs.picb, PDMAudioPropsBytesToMilli(&pStreamCC->State.Cfg.Props, 1389 PDMAudioPropsSampleSize(&pStreamCC->State.Cfg.Props) 1390 * pStream->Regs.picb), 1391 cbStreamFree, PDMAudioPropsBytesToMilli(&pStreamCC->State.Cfg.Props, cbStreamFree), 1392 cbPeriod, PDMAudioPropsBytesToMilli(&pStreamCC->State.Cfg.Props, cbPeriod))); 1393 1394 rc2 = ichac97R3StreamTransfer(pDevIns, pThis, pStream, pStreamCC, RT_MIN(cbStreamFree, cbPeriod)); 1395 AssertRC(rc2); 1396 1397 pStreamCC->State.tsLastUpdateNs = RTTimeNanoTS(); 1398 1399 1400 /* 1401 * Notify the AIO thread. 1402 */ 1355 1403 rc2 = AudioMixerSinkSignalUpdateJob(pSink); 1356 1404 AssertRC(rc2); … … 4272 4320 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.StatDmaBufUsed, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_BYTES, 4273 4321 "Number of bytes used in the internal DMA buffer.", "Stream%u/DMABufUsed", idxStream); 4322 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.StatDmaFlowProblems, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, 4323 "Number of internal DMA buffer problems.", "Stream%u/DMABufferProblems", idxStream); 4324 if (ichac97GetDirFromSD(idxStream) == PDMAUDIODIR_OUT) 4325 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.StatDmaFlowErrors, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, 4326 "Number of internal DMA buffer overflows.", "Stream%u/DMABufferOverflows", idxStream); 4327 else 4328 { 4329 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.StatDmaFlowErrors, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES, 4330 "Number of internal DMA buffer underuns.", "Stream%u/DMABufferUnderruns", idxStream); 4331 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.StatDmaFlowErrorBytes, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_BYTES, 4332 "Number of bytes of silence added to cope with underruns.", "Stream%u/DMABufferSilence", idxStream); 4333 } 4274 4334 } 4275 4335
Note:
See TracChangeset
for help on using the changeset viewer.