VirtualBox

Changeset 64568 in vbox for trunk


Ignore:
Timestamp:
Nov 4, 2016 12:38:20 PM (8 years ago)
Author:
vboxsync
Message:

Audio/DrvAudio: Added some more statistics to STAM about read, written, mixed and lost audio samples. Mix written samples immediately to the parent instead of postponing it for the next iteration. Logging tweaks.

Location:
trunk/src/VBox/Devices/Audio
Files:
2 edited

Legend:

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

    r64405 r64568  
    579579    LogFlowFunc(("[%s] cSamples=%RU32\n", pHstStream->szName, CfgHostAcq.cSampleBufferSize * 4));
    580580
    581     rc2 = AudioMixBufInit(&pHstStream->MixBuf, pHstStream->szName, &PCMProps, CfgHostAcq.cSampleBufferSize * 4);
     581    rc2 = AudioMixBufInit(&pHstStream->MixBuf, pHstStream->szName, &PCMProps, CfgHostAcq.cSampleBufferSize * 10);
    582582    AssertRC(rc2);
    583583
     
    598598    LogFlowFunc(("[%s] cSamples=%RU32\n", pGstStream->szName, CfgHostAcq.cSampleBufferSize * 2));
    599599
    600     rc2 = AudioMixBufInit(&pGstStream->MixBuf, pGstStream->szName, &PCMProps, CfgHostAcq.cSampleBufferSize * 2);
     600    rc2 = AudioMixBufInit(&pGstStream->MixBuf, pGstStream->szName, &PCMProps, CfgHostAcq.cSampleBufferSize * 20);
    601601    AssertRC(rc2);
    602602
     
    766766{
    767767    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     768    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
    768769    AssertPtrReturn(pvBuf,      VERR_INVALID_POINTER);
     770    AssertReturn(cbBuf,         VERR_INVALID_POINTER);
    769771    /* pcbWritten is optional. */
    770772
    771773    PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface);
    772 
    773     if (   !pStream
    774         || !cbBuf)
    775     {
    776         if (pcbWritten)
    777             *pcbWritten = 0;
    778         return VINF_SUCCESS;
    779     }
    780774
    781775    AssertMsg(pStream->enmDir == PDMAUDIODIR_OUT,
     
    789783        return rc;
    790784
     785#ifdef VBOX_WITH_STATISTICS
     786    STAM_PROFILE_ADV_START(&pThis->Stats.DelayOut, out);
     787#endif
     788
    791789    do
    792790    {
     
    816814        {
    817815            LogRel2(("Audio: Guest stream '%s' full, expect stuttering audio output\n", pGstStream->szName));
     816#ifdef DEBUG_andy
     817            AssertMsgFailed(("%s: Guest stream full\n", pGstStream->szName));
     818#endif
    818819            break;
    819820        }
    820821
    821         uint32_t cWritten = 0;
    822         rc = AudioMixBufWriteCirc(&pGstStream->MixBuf, pvBuf, cbBuf, &cWritten);
    823         if (rc == VINF_BUFFER_OVERFLOW)
    824         {
    825             LogRel2(("Audio: Lost audio samples from guest stream '%s', expect stuttering audio output\n", pGstStream->szName));
    826             rc = VINF_SUCCESS;
    827             break;
    828         }
     822        uint32_t csWritten = 0;
     823        rc = AudioMixBufWriteCirc(&pGstStream->MixBuf, pvBuf, cbBuf, &csWritten);
     824        if (RT_FAILURE(rc))
     825        {
     826            LogRel2(("Audio: Lost audio samples due to full guest stream '%s', expect stuttering audio output\n",
     827                     pGstStream->szName));
     828            rc = VINF_SUCCESS; /* Continue. */
     829        }
     830
     831#ifdef DEBUG_andy
     832        if (   RT_FAILURE(rc)
     833            || !csWritten)
     834        {
     835            AssertMsgFailed(("%s: Write failed: cbBuf=%RU32, csWritten=%RU32, rc=%Rrc\n",
     836                             pGstStream->szName, cbBuf, csWritten, rc));
     837        }
     838#endif
    829839
    830840#ifdef VBOX_WITH_STATISTICS
    831         STAM_COUNTER_ADD(&pThis->Stats.TotalBytesWritten, AUDIOMIXBUF_S2B(&pGstStream->MixBuf, cWritten));
    832         STAM_COUNTER_ADD(&pGstStream->Out.StatBytesTotalWritten, AUDIOMIXBUF_S2B(&pGstStream->MixBuf, cWritten));
     841        STAM_COUNTER_ADD(&pThis->Stats.TotalSamplesWritten, csWritten);
    833842#endif
    834         cbWritten = AUDIOMIXBUF_S2B(&pGstStream->MixBuf, cWritten);
    835 
    836         Log3Func(("[%s] cUsed=%RU32, cLive=%RU32\n",
    837                   pGstStream->szName, AudioMixBufUsed(&pGstStream->MixBuf), AudioMixBufLive(&pGstStream->MixBuf)));
     843        uint32_t csMixed = 0;
     844        if (csWritten)
     845        {
     846            int rc2 = AudioMixBufMixToParent(&pGstStream->MixBuf, csWritten, &csMixed);
     847            if (RT_FAILURE(rc2))
     848            {
     849                LogRel2(("Audio: Lost audio samples (%RU32) due to full host stream '%s', expect stuttering audio output\n",
     850                         csWritten - csMixed, pGstStream->szName));
     851            }
     852
     853#ifdef DEBUG_andy
     854            if (   RT_FAILURE(rc2)
     855                || csMixed < csWritten)
     856            {
     857                AssertMsgFailed(("%s: Mixing failed: cbBuf=%RU32, csWritten=%RU32, csMixed=%RU32, rc=%Rrc\n",
     858                                 pGstStream->szName, cbBuf, csWritten, csMixed, rc2));
     859            }
     860#endif
     861            if (RT_SUCCESS(rc))
     862                rc = rc2;
     863
     864            cbWritten = AUDIOMIXBUF_S2B(&pGstStream->MixBuf, csWritten);
     865
     866#ifdef VBOX_WITH_STATISTICS
     867            STAM_COUNTER_ADD(&pThis->Stats.TotalSamplesMixed,        csMixed);
     868            STAM_COUNTER_ADD(&pThis->Stats.TotalSamplesLost,         csWritten - csMixed);
     869            STAM_COUNTER_ADD(&pThis->Stats.TotalBytesWritten,        cbWritten);
     870            STAM_COUNTER_ADD(&pGstStream->Out.StatBytesTotalWritten, cbWritten);
     871#endif
     872        }
     873
     874        Log3Func(("[%s] cbBuf=%RU32, cUsed=%RU32, cLive=%RU32, cWritten=%RU32, cMixed=%RU32, rc=%Rrc\n",
     875                  pGstStream->szName,
     876                  cbBuf, AudioMixBufUsed(&pGstStream->MixBuf), AudioMixBufLive(&pGstStream->MixBuf), csWritten, csMixed, rc));
    838877
    839878    } while (0);
     
    9881027                    else
    9891028                        LogRel2(("Audio: Mixing to guest input stream '%s' failed: %Rrc\n", pGstStream->szName, rc));
     1029#ifdef DEBUG_andy
     1030                    AssertFailed();
     1031#endif
    9901032                }
    9911033
     
    9991041        else if (pHstStream->enmDir == PDMAUDIODIR_OUT)
    10001042        {
    1001             /* When playing samples, the host is the parent while the guest is the child.
    1002              * So try mixing not yet mixed guest-side samples to the host-side buffer. */
    1003             rc = AudioMixBufMixToParent(&pGstStream->MixBuf, AudioMixBufUsed(&pGstStream->MixBuf), &cSamplesMixed);
    1004             if (   RT_SUCCESS(rc)
    1005                 && cSamplesMixed)
    1006             {
    1007                 Log3Func(("[%s] %RU32 output samples mixed, guest has %RU32 samples left (%RU32 live)\n",
    1008                           pHstStream->szName, cSamplesMixed,
    1009                           AudioMixBufUsed(&pGstStream->MixBuf), AudioMixBufLive(&pGstStream->MixBuf)));
    1010             }
    1011             else if (RT_FAILURE(rc))
    1012             {
    1013                 if (rc == VERR_BUFFER_OVERFLOW)
    1014                     LogRel2(("Audio: Host output stream '%s' full, expect stuttering audio output\n", pHstStream->szName));
    1015                 else
    1016                     LogRel2(("Audio: Mixing to host output stream '%s' failed: %Rrc\n", pHstStream->szName, rc));
    1017             }
    1018 
    1019             uint32_t cSamplesLeft = AudioMixBufUsed(&pGstStream->MixBuf);
    1020             if (!cSamplesLeft) /* No samples (anymore)? */
    1021             {
    1022                 fTryClosePending = true;
    1023             }
     1043            /* Nothing to do here (yet). */
    10241044        }
    10251045        else
     
    10931113 */
    10941114static DECLCALLBACK(int) drvAudioStreamPlay(PPDMIAUDIOCONNECTOR pInterface,
    1095                                             PPDMAUDIOSTREAM pStream, uint32_t *pcSamplesPlayed)
     1115                                            PPDMAUDIOSTREAM pStream, uint32_t *pcsPlayed)
    10961116{
    10971117    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
     
    11091129               pStream->szName, pStream->enmDir));
    11101130
    1111     uint32_t cSamplesPlayed = 0;
     1131    uint32_t csPlayed = 0;
    11121132
    11131133    do
     
    11341154
    11351155        AssertPtr(pThis->pHostDrvAudio->pfnStreamGetStatus);
     1156
     1157        uint32_t csLive = AudioMixBufUsed(&pHstStream->MixBuf);
     1158
    11361159        PDMAUDIOSTRMSTS stsBackend = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream);
    11371160
    1138         uint32_t cSamplesLive = AudioMixBufLive(&pGstStream->MixBuf);
    1139         if (cSamplesLive)
    1140         {
    1141             if (   (stsBackend & PDMAUDIOSTRMSTS_FLAG_ENABLED)
    1142                 && (stsBackend & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE))
    1143             {
    1144                 AssertPtr(pThis->pHostDrvAudio->pfnStreamPlay);
    1145                 rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream, NULL /* pvBuf */, 0 /* cbBuf */,
    1146                                                          &cSamplesPlayed);
    1147                 if (RT_FAILURE(rc))
    1148                 {
    1149                     int rc2 = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE);
    1150                     AssertRC(rc2);
    1151                 }
    1152                 else
    1153                 {
     1161        Log3Func(("[%s] Start: stsBackend=0x%x, csLive=%RU32\n", pHstStream->szName, stsBackend, csLive));
     1162
     1163        if (   csLive
     1164            && (stsBackend & PDMAUDIOSTRMSTS_FLAG_ENABLED)
     1165            && (stsBackend & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE))
     1166        {
     1167            AssertPtr(pThis->pHostDrvAudio->pfnStreamPlay);
     1168            rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream, NULL /* pvBuf */, 0 /* cbBuf */,
     1169                                                     &csPlayed);
     1170            if (RT_SUCCESS(rc))
     1171            {
    11541172#ifdef VBOX_WITH_STATISTICS
    1155                     STAM_COUNTER_ADD(&pThis->Stats.TotalSamplesPlayed, cSamplesPlayed);
    1156                     STAM_COUNTER_ADD(&pHstStream->Out.StatSamplesPlayed, cSamplesPlayed);
     1173                STAM_COUNTER_ADD(&pThis->Stats.TotalSamplesPlayed, csPlayed);
     1174                STAM_PROFILE_ADV_STOP(&pThis->Stats.DelayOut, out);
     1175                STAM_COUNTER_ADD(&pHstStream->Out.StatSamplesPlayed, csPlayed);
    11571176#endif
    1158                     cSamplesLive = AudioMixBufLive(&pGstStream->MixBuf);
    1159                 }
    1160             }
    1161         }
    1162 
    1163         if (!cSamplesLive)
     1177                csLive = AudioMixBufUsed(&pHstStream->MixBuf);
     1178            }
     1179        }
     1180
     1181        Log3Func(("[%s] End: stsBackend=0x%x, csLive=%RU32, csPlayed=%RU32, rc=%Rrc\n",
     1182                  pHstStream->szName, stsBackend, csLive, csPlayed, rc));
     1183
     1184        if (!csLive)
    11641185        {
    11651186            /* Has the host stream marked as disabled but there still were guest streams relying
     
    11861207    if (RT_SUCCESS(rc))
    11871208    {
    1188         if (pcSamplesPlayed)
    1189             *pcSamplesPlayed = cSamplesPlayed;
     1209        if (pcsPlayed)
     1210            *pcsPlayed = csPlayed;
    11901211    }
    11911212
     
    17221743            if (cRead)
    17231744            {
     1745                cbRead = AUDIOMIXBUF_S2B(&pGstStream->MixBuf, cRead);
     1746
    17241747#ifdef VBOX_WITH_STATISTICS
    1725                 STAM_COUNTER_ADD(&pThis->Stats.TotalBytesRead, AUDIOMIXBUF_S2B(&pGstStream->MixBuf, cRead));
    1726                 STAM_COUNTER_ADD(&pGstStream->In.StatBytesTotalRead, AUDIOMIXBUF_S2B(&pGstStream->MixBuf, cRead));
     1748                STAM_COUNTER_ADD(&pThis->Stats.TotalBytesRead,       cbRead);
     1749                STAM_COUNTER_ADD(&pGstStream->In.StatBytesTotalRead, cbRead);
    17271750#endif
    17281751                AudioMixBufFinish(&pGstStream->MixBuf, cRead);
    1729 
    1730                 cbRead = AUDIOMIXBUF_S2B(&pGstStream->MixBuf, cRead);
    17311752            }
    17321753        }
     
    25372558        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->Stats.TotalStreamsCreated,  "TotalStreamsCreated",
    25382559                                  STAMUNIT_COUNT, "Total created audio streams.");
     2560        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->Stats.TotalSamplesRead,     "TotalSamplesRead",
     2561                                  STAMUNIT_COUNT, "Total samples read by device emulation.");
     2562        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->Stats.TotalSamplesWritten,  "TotalSamplesWritten",
     2563                                  STAMUNIT_COUNT, "Total samples written by device emulation ");
     2564        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->Stats.TotalSamplesMixed,    "TotalSamplesMixed",
     2565                                  STAMUNIT_COUNT, "Total samples mixed.");
     2566        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->Stats.TotalSamplesLost,     "TotalSamplesLost",
     2567                                  STAMUNIT_COUNT, "Total samples lost.");
    25392568        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->Stats.TotalSamplesPlayed,   "TotalSamplesPlayed",
    2540                                   STAMUNIT_COUNT, "Total samples played.");
     2569                                  STAMUNIT_COUNT, "Total samples played by backend.");
    25412570        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->Stats.TotalSamplesCaptured, "TotalSamplesCaptured",
    2542                                   STAMUNIT_COUNT, "Total samples captured.");
     2571                                  STAMUNIT_COUNT, "Total samples captured by backend.");
    25432572        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->Stats.TotalBytesRead,       "TotalBytesRead",
    25442573                                  STAMUNIT_BYTES, "Total bytes read.");
    25452574        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pThis->Stats.TotalBytesWritten,    "TotalBytesWritten",
    25462575                                  STAMUNIT_BYTES, "Total bytes written.");
     2576
     2577        PDMDrvHlpSTAMRegProfileAdvEx(pDrvIns, &pThis->Stats.DelayIn, "DelayIn",
     2578                                     STAMUNIT_NS_PER_CALL, "Profiling of input data processing.");
     2579        PDMDrvHlpSTAMRegProfileAdvEx(pDrvIns, &pThis->Stats.DelayOut, "DelayOut",
     2580                                     STAMUNIT_NS_PER_CALL, "Profiling of output data processing.");
    25472581#endif
    25482582    }
     
    26302664    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalStreamsActive);
    26312665    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalStreamsCreated);
     2666    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalSamplesRead);
     2667    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalSamplesWritten);
     2668    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalSamplesMixed);
     2669    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalSamplesLost);
    26322670    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalSamplesPlayed);
    26332671    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalSamplesCaptured);
    26342672    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalBytesRead);
    26352673    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.TotalBytesWritten);
     2674    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.DelayIn);
     2675    PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pThis->Stats.DelayOut);
    26362676#endif
    26372677
  • trunk/src/VBox/Devices/Audio/DrvAudio.h

    r64333 r64568  
    8282    STAMCOUNTER TotalStreamsActive;
    8383    STAMCOUNTER TotalStreamsCreated;
     84    STAMCOUNTER TotalSamplesRead;
     85    STAMCOUNTER TotalSamplesWritten;
     86    STAMCOUNTER TotalSamplesMixed;
     87    STAMCOUNTER TotalSamplesLost;
    8488    STAMCOUNTER TotalSamplesPlayed;
    8589    STAMCOUNTER TotalSamplesCaptured;
    8690    STAMCOUNTER TotalBytesRead;
    8791    STAMCOUNTER TotalBytesWritten;
     92    /** How much delay (in ms) for input processing. */
     93    STAMPROFILEADV DelayIn;
     94    /** How much delay (in ms) for output processing. */
     95    STAMPROFILEADV DelayOut;
    8896} DRVAUDIOSTATS, *PDRVAUDIOSTATS;
    8997#endif
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