VirtualBox

Changeset 89693 in vbox


Ignore:
Timestamp:
Jun 14, 2021 9:22:12 PM (4 years ago)
Author:
vboxsync
Message:

DevIchAc97: Added pushback and statistics to the output portion of ichac97R3StreamUpdateDma (similar to HDA). bugref:9890

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r89692 r89693  
    388388    /** Number of used bytes in the DMA buffer (pCircBuf). */
    389389    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;
    390396} AC97STREAMSTATE;
    391397AssertCompileSizeAlignment(AC97STREAMSTATE, 8);
     
    13251331    int rc2;
    13261332
     1333    /* The amount we're supposed to be transfering in this DMA period. */
     1334    uint32_t cbPeriod = pStreamCC->State.cbTransferChunk;
     1335
    13271336    /*
    13281337     * Output streams (SDO).
     
    13301339    if (pStreamCC->State.Cfg.enmDir == PDMAUDIODIR_OUT)
    13311340    {
     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         */
    13321345        uint32_t cbStreamFree = ichac97R3StreamGetFree(pStreamCC);
    1333         if (cbStreamFree)
     1346        if (cbStreamFree >= cbPeriod)
    13341347        { /* likely */ }
    13351348        else
    13361349        {
    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            }
    13381382        }
    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         */
    13551403        rc2 = AudioMixerSinkSignalUpdateJob(pSink);
    13561404        AssertRC(rc2);
     
    42724320        PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.StatDmaBufUsed, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_BYTES,
    42734321                               "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        }
    42744334    }
    42754335
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette