VirtualBox

Changeset 88564 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Apr 16, 2021 1:16:47 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
143859
Message:

DrvHostAudioDSound: Added a status formatter and some other logging changes and cleanups. bugref:9890

File:
1 edited

Legend:

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

    r88556 r88564  
    117117    /** Size (in bytes) of the DirectSound buffer. */
    118118    DWORD               cbBufSize;
    119     /** The stream's critical section for synchronizing access. */
    120     RTCRITSECT          CritSect;
    121119    union
    122120    {
     
    157155             *  to the DirectSound buffer was. */
    158156            uint32_t                    cbLastTransferred;
    159             /** Timestamp (in ms) of the last transfer from the internal buffer
    160              *  to the DirectSound buffer. */
    161             uint64_t                    tsLastTransferredMs;
    162             /** Number of buffer underruns happened. Used for logging. */
    163             uint8_t                     cUnderruns;
    164157        } Out;
    165158    };
    166 #ifdef LOG_ENABLED
    167     struct
    168     {
    169         uint64_t tsLastTransferredMs;
    170     } Dbg;
    171 #endif
     159    /** Timestamp (in ms) of the last transfer from the internal buffer to/from the
     160     *  DirectSound buffer. */
     161    uint64_t            msLastTransfer;
     162    /** The stream's critical section for synchronizing access. */
     163    RTCRITSECT          CritSect;
     164    /** Used for formatting the current DSound status. */
     165    char                szStatus[127];
     166    /** Fixed zero terminator. */
     167    char const         chStateZero;
    172168} DSOUNDSTREAM, *PDSOUNDSTREAM;
    173169
     
    232228
    233229static void     dsoundUpdateStatusInternal(PDRVHOSTDSOUND pThis);
     230
     231
     232#if defined(LOG_ENABLED) // || defined(RTLOG_REL_ENABLED)
     233/**
     234 * Gets the stream status as a string for logging purposes.
     235 *
     236 * @returns Status string (pStreamDS->szStatus).
     237 * @param   pStreamDS   The stream to get the status for.
     238 */
     239static const char *drvHostDSoundStreamStatusString(PDSOUNDSTREAM pStreamDS)
     240{
     241    /*
     242     * Out internal stream status first.
     243     */
     244    size_t off;
     245    if (pStreamDS->fEnabled)
     246    {
     247        memcpy(pStreamDS->szStatus, RT_STR_TUPLE("ENABLED "));
     248        off = sizeof("ENABLED ") - 1;
     249    }
     250    else
     251    {
     252        memcpy(pStreamDS->szStatus, RT_STR_TUPLE("DISABLED"));
     253        off = sizeof("DISABLED") - 1;
     254    }
     255
     256    /*
     257     * Direction specific stuff, returning with a status DWORD and string mappings for it.
     258     */
     259    typedef struct DRVHOSTDSOUNDSFLAGS2STR
     260    {
     261        const char *pszMnemonic;
     262        uint32_t    cchMnemonic;
     263        uint32_t    fFlag;
     264    } DRVHOSTDSOUNDSFLAGS2STR;
     265    static const DRVHOSTDSOUNDSFLAGS2STR s_aCaptureFlags[] =
     266    {
     267        { RT_STR_TUPLE(" CAPTURING"),    DSCBSTATUS_CAPTURING  },
     268        { RT_STR_TUPLE(" LOOPING"),      DSCBSTATUS_LOOPING    },
     269    };
     270    static const DRVHOSTDSOUNDSFLAGS2STR s_aPlaybackFlags[] =
     271    {
     272        { RT_STR_TUPLE(" PLAYING"),      DSBSTATUS_PLAYING     },
     273        { RT_STR_TUPLE(" BUFFERLOST"),   DSBSTATUS_BUFFERLOST  },
     274        { RT_STR_TUPLE(" LOOPING"),      DSBSTATUS_LOOPING     },
     275        { RT_STR_TUPLE(" LOCHARDWARE"),  DSBSTATUS_LOCHARDWARE },
     276        { RT_STR_TUPLE(" LOCSOFTWARE"),  DSBSTATUS_LOCSOFTWARE },
     277        { RT_STR_TUPLE(" TERMINATED"),   DSBSTATUS_TERMINATED  },
     278    };
     279    DRVHOSTDSOUNDSFLAGS2STR const  *paMappings = NULL;
     280    size_t                          cMappings  = 0;
     281    DWORD                           fStatus    = 0;
     282    if (pStreamDS->Cfg.enmDir == PDMAUDIODIR_IN)
     283    {
     284        if (pStreamDS->In.pDSCB)
     285        {
     286            HRESULT hrc = pStreamDS->In.pDSCB->GetStatus(&fStatus);
     287            if (SUCCEEDED(hrc))
     288            {
     289                paMappings = s_aCaptureFlags;
     290                cMappings  = RT_ELEMENTS(s_aCaptureFlags);
     291            }
     292            else
     293                RTStrPrintf(&pStreamDS->szStatus[off], sizeof(pStreamDS->szStatus) - off, "GetStatus->%Rhrc", hrc);
     294        }
     295        else
     296            RTStrCopy(&pStreamDS->szStatus[off], sizeof(pStreamDS->szStatus) - off, "NO-DSCB");
     297    }
     298    else if (pStreamDS->Cfg.enmDir == PDMAUDIODIR_OUT)
     299    {
     300        if (pStreamDS->Out.fDrain)
     301        {
     302            memcpy(&pStreamDS->szStatus[off], RT_STR_TUPLE(" DRAINING"));
     303            off += sizeof(" DRAINING") - 1;
     304        }
     305
     306        if (pStreamDS->Out.fFirstTransfer)
     307        {
     308            memcpy(&pStreamDS->szStatus[off], RT_STR_TUPLE(" NOXFER"));
     309            off += sizeof(" NOXFER") - 1;
     310        }
     311
     312        if (pStreamDS->Out.pDSB)
     313        {
     314            HRESULT hrc = pStreamDS->Out.pDSB->GetStatus(&fStatus);
     315            if (SUCCEEDED(hrc))
     316            {
     317                paMappings = s_aPlaybackFlags;
     318                cMappings  = RT_ELEMENTS(s_aPlaybackFlags);
     319            }
     320            else
     321                RTStrPrintf(&pStreamDS->szStatus[off], sizeof(pStreamDS->szStatus) - off, "GetStatus->%Rhrc", hrc);
     322        }
     323        else
     324            RTStrCopy(&pStreamDS->szStatus[off], sizeof(pStreamDS->szStatus) - off, "NO-DSB");
     325    }
     326    else
     327        RTStrCopy(&pStreamDS->szStatus[off], sizeof(pStreamDS->szStatus) - off, "BAD-DIR");
     328
     329    /* Format flags. */
     330    if (paMappings)
     331    {
     332        if (fStatus == 0)
     333            RTStrCopy(&pStreamDS->szStatus[off], sizeof(pStreamDS->szStatus) - off, " 0");
     334        else
     335        {
     336            for (size_t i = 0; i < cMappings; i++)
     337                if (fStatus & paMappings[i].fFlag)
     338                {
     339                    memcpy(&pStreamDS->szStatus[off], paMappings[i].pszMnemonic, paMappings[i].cchMnemonic);
     340                    off += paMappings[i].cchMnemonic;
     341
     342                    fStatus &= ~paMappings[i].fFlag;
     343                    if (!fStatus)
     344                        break;
     345                }
     346            if (fStatus != 0)
     347                off += RTStrPrintf(&pStreamDS->szStatus[off], sizeof(pStreamDS->szStatus) - off, " %#x", fStatus);
     348        }
     349    }
     350
     351    /*
     352     * Finally, terminate the string.  By postponing it this long, it won't be
     353     * a big deal if two threads go thru here at the same time as long as the
     354     * status is the same.
     355     */
     356    Assert(off < sizeof(pStreamDS->szStatus));
     357    pStreamDS->szStatus[off] = '\0';
     358
     359    return pStreamDS->szStatus;
     360}
     361#endif /* LOG_ENABLED || RTLOG_REL_ENABLED */
    234362
    235363
     
    11611289
    11621290        /* Reset the state: */
     1291        pStreamDS->msLastTransfer   = 0;
    11631292/** @todo r=bird: We set the read position to zero here, but shouldn't we query it
    11641293 * from the buffer instead given that there isn't any interface for repositioning
    11651294 * to the start of the buffer as with playback buffers? */
    1166         pStreamDS->In.offReadPos = 0;
    1167         pStreamDS->In.cOverruns  = 0;
     1295        pStreamDS->In.offReadPos    = 0;
     1296        pStreamDS->In.cOverruns     = 0;
    11681297
    11691298        /* Clear the buffer content: */
     
    12051334
    12061335        /* Reset the internal state: */
     1336        pStreamDS->msLastTransfer               = 0;
    12071337        pStreamDS->Out.fFirstTransfer           = true;
    12081338        pStreamDS->Out.fDrain                   = false;
    1209         pStreamDS->Out.cUnderruns               = 0;
    12101339        pStreamDS->Out.cbLastTransferred        = 0;
    1211         pStreamDS->Out.tsLastTransferredMs      = 0;
    12121340        pStreamDS->Out.cbTransferred            = 0;
    12131341        pStreamDS->Out.cbWritten                = 0;
     
    12491377        }
    12501378    }
    1251 
    1252 #ifdef LOG_ENABLED
    1253     pStreamDS->Dbg.tsLastTransferredMs = 0;
    1254 #endif
    12551379}
    12561380
     
    15871711    PDSOUNDSTREAM  pStreamDS = (PDSOUNDSTREAM)pStream;
    15881712    AssertPtrReturn(pStreamDS, VERR_INVALID_POINTER);
     1713    LogFlowFunc(("Stream '%s' {%s}\n", pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS)));
    15891714
    15901715    if (pStreamDS->Cfg.enmDir == PDMAUDIODIR_IN)
     
    17121837    PDRVHOSTDSOUND  pThis     = RT_FROM_MEMBER(pInterface, DRVHOSTDSOUND, IHostAudio);
    17131838    PDSOUNDSTREAM   pStreamDS = (PDSOUNDSTREAM)pStream;
    1714     LogFlowFunc(("fEnabled=%d '%s'\n", pStreamDS->fEnabled, pStreamDS->Cfg.szName));
     1839    LogFlowFunc(("Stream '%s' {%s}\n", pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS)));
    17151840
    17161841    /*
     
    17751900    PDRVHOSTDSOUND  pThis     = RT_FROM_MEMBER(pInterface, DRVHOSTDSOUND, IHostAudio);
    17761901    PDSOUNDSTREAM   pStreamDS = (PDSOUNDSTREAM)pStream;
    1777     LogFlowFunc(("fEnabled=%d '%s'\n", pStreamDS->fEnabled, pStreamDS->Cfg.szName));
     1902    LogFlowFunc(("cMsLastTransfer=%RI64 ms, stream '%s' {%s} \n",
     1903                 pStreamDS->msLastTransfer ? RTTimeMilliTS() - pStreamDS->msLastTransfer : -1,
     1904                 pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS) ));
    17781905
    17791906    /*
     
    18201947    }
    18211948
    1822     LogFlowFunc(("returns %Rrc\n", rc));
     1949    LogFlowFunc(("returns %Rrc {%s}\n", rc, drvHostDSoundStreamStatusString(pStreamDS)));
    18231950    return rc;
    18241951}
     
    18351962    PDRVHOSTDSOUND  pThis     = RT_FROM_MEMBER(pInterface, DRVHOSTDSOUND, IHostAudio);
    18361963    PDSOUNDSTREAM   pStreamDS = (PDSOUNDSTREAM)pStream;
    1837     LogFlowFunc(("fEnabled=%d '%s'\n", pStreamDS->fEnabled, pStreamDS->Cfg.szName));
     1964    LogFlowFunc(("cMsLastTransfer=%RI64 ms, stream '%s' {%s} \n",
     1965                 pStreamDS->msLastTransfer ? RTTimeMilliTS() - pStreamDS->msLastTransfer : -1,
     1966                 pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS) ));
    18381967
    18391968    /*
     
    18732002    }
    18742003
    1875     LogFlowFunc(("returns %Rrc\n", rc));
     2004    LogFlowFunc(("returns %Rrc {%s}\n", rc, drvHostDSoundStreamStatusString(pStreamDS)));
    18762005    return rc;
    18772006}
     
    19182047    PDRVHOSTDSOUND  pThis     = RT_FROM_MEMBER(pInterface, DRVHOSTDSOUND, IHostAudio);
    19192048    PDSOUNDSTREAM   pStreamDS = (PDSOUNDSTREAM)pStream;
    1920     LogFlowFunc(("fEnabled=%d '%s'\n", pStreamDS->fEnabled, pStreamDS->Cfg.szName));
     2049    LogFlowFunc(("Stream '%s' {%s}\n", pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS)));
    19212050
    19222051    /*
     
    19342063    }
    19352064
    1936     LogFlowFunc(("returns %Rrc\n", rc));
     2065    LogFlowFunc(("returns %Rrc {%s}\n", rc, drvHostDSoundStreamStatusString(pStreamDS)));
    19372066    return rc;
    19382067}
     
    19472076    PDSOUNDSTREAM   pStreamDS = (PDSOUNDSTREAM)pStream;
    19482077    AssertReturn(pStreamDS->Cfg.enmDir == PDMAUDIODIR_OUT, VERR_INVALID_PARAMETER);
    1949     LogFlowFunc(("fEnabled=%d fDrain=%d '%s'\n", pStreamDS->fEnabled, pStreamDS->Out.fDrain, pStreamDS->Cfg.szName));
     2078    LogFlowFunc(("cMsLastTransfer=%RI64 ms, stream '%s' {%s} \n",
     2079                 pStreamDS->msLastTransfer ? RTTimeMilliTS() - pStreamDS->msLastTransfer : -1,
     2080                 pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS) ));
    19502081
    19512082    /*
     
    19812112        }
    19822113    }
    1983     LogFlowFunc(("returns %Rrc\n", rc));
     2114    LogFlowFunc(("returns %Rrc {%s}\n", rc, drvHostDSoundStreamStatusString(pStreamDS)));
    19842115    return rc;
    19852116}
     
    20682199
    20692200    LPDIRECTSOUNDBUFFER8 pDSB = pStreamDS->Out.pDSB;
    2070     if (!pDSB)
    2071     {
    2072         AssertPtr(pDSB);
    2073         return VERR_INVALID_POINTER;
    2074     }
     2201    AssertPtrReturn(pDSB, VERR_INVALID_POINTER);
    20752202
    20762203    HRESULT hr = S_OK;
     
    21412268    PDSOUNDSTREAM   pStreamDS = (PDSOUNDSTREAM)pStream;
    21422269    AssertPtrReturn(pStreamDS, 0);
     2270    LogFlowFunc(("Stream '%s' {%s}\n", pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS)));
    21432271
    21442272    DWORD           cbFree    = 0;
     
    21602288    PDSOUNDSTREAM   pStreamDS = (PDSOUNDSTREAM)pStream;
    21612289    AssertPtrReturn(pStreamDS, 0);
     2290    LogFlowFunc(("Stream '%s' {%s}\n", pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS)));
    21622291
    21632292    if (pStreamDS->Cfg.enmDir == PDMAUDIODIR_OUT)
     
    21882317{
    21892318    RT_NOREF(pInterface);
    2190     AssertPtrReturn(pStream, PDMAUDIOSTREAMSTS_FLAGS_NONE);
    2191 
    21922319    PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream;
     2320    AssertPtrReturn(pStreamDS, PDMAUDIOSTREAMSTS_FLAGS_NONE);
    21932321
    21942322    PDMAUDIOSTREAMSTS fStrmStatus = PDMAUDIOSTREAMSTS_FLAGS_INITIALIZED;
    2195 
    21962323    if (pStreamDS->fEnabled)
    21972324        fStrmStatus |= PDMAUDIOSTREAMSTS_FLAGS_ENABLED;
    21982325
     2326    LogFlowFunc(("returns %#x for '%s' {%s}\n", fStrmStatus, pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS)));
    21992327    return fStrmStatus;
    22002328}
     
    22182346    else
    22192347    {
    2220         Log2Func(("Stream disabled, skipping\n"));
     2348        Log2Func(("Skipping disabled stream {%s}\n", drvHostDSoundStreamStatusString(pStreamDS)));
    22212349        return VINF_SUCCESS;
    22222350    }
     2351    Log4Func(("cbBuf=%#x stream '%s' {%s}\n", cbBuf, pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS) ));
    22232352
    22242353/** @todo Any condition under which we should call dsoundUpdateStatusInternal(pThis) here?
     
    22422371
    22432372        uint32_t const cbToWrite = RT_MIN(cbWritable, cbBuf);
    2244         Log3Func(("offPlay=%#x offWritePos=%#x -> cbWritable=%#x cbToWrite=%#x%s%s\n", offPlayCursor, pStreamDS->Out.offWritePos,
    2245                   cbWritable, cbToWrite, pStreamDS->Out.fFirstTransfer ? " first" : "", pStreamDS->Out.fDrain ? " drain" : ""));
     2373        Log3Func(("offPlay=%#x offWritePos=%#x -> cbWritable=%#x cbToWrite=%#x {%s}\n", offPlayCursor, pStreamDS->Out.offWritePos,
     2374                  cbWritable, cbToWrite, drvHostDSoundStreamStatusString(pStreamDS) ));
    22462375
    22472376        /*
     
    23012430    if (cbWritten)
    23022431    {
    2303         uint64_t const msPrev = pStreamDS->Out.tsLastTransferredMs;
    2304         pStreamDS->Out.cbLastTransferred   = cbWritten;
    2305         pStreamDS->Out.tsLastTransferredMs = RTTimeMilliTS();
    2306         LogFlowFunc(("cbLastTransferred=%RU32, tsLastTransferredMs=%RU64 cMsDelta=%RU64\n",
    2307                      cbWritten, pStreamDS->Out.tsLastTransferredMs, msPrev ? pStreamDS->Out.tsLastTransferredMs - msPrev : 0));
     2432        uint64_t const msPrev = pStreamDS->msLastTransfer;
     2433        pStreamDS->Out.cbLastTransferred = cbWritten;
     2434        pStreamDS->msLastTransfer        = RTTimeMilliTS();
     2435        LogFlowFunc(("cbLastTransferred=%RU32, msLastTransfer=%RU64 msNow=%RU64 cMsDelta=%RU64 {%s}\n",
     2436                     cbWritten, msPrev, pStreamDS->msLastTransfer, msPrev ? pStreamDS->msLastTransfer - msPrev : 0,
     2437                     drvHostDSoundStreamStatusString(pStreamDS) ));
    23082438    }
    23092439    return VINF_SUCCESS;
     
    23332463    }
    23342464#endif
     2465    Log4Func(("cbBuf=%#x stream '%s' {%s}\n", cbBuf, pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS) ));
    23352466
    23362467    /*
     
    23672498
    23682499        uint32_t const cbToRead = RT_MIN(cbReadable, cbBuf);
    2369         Log3Func(("offCapture=%#x offRead=%#x/%#x -> cbWritable=%#x cbToWrite=%#x\n",
    2370                   offCaptureCursor, offReadCursor, pStreamDS->In.offReadPos, cbReadable, cbToRead));
     2500        Log3Func(("offCapture=%#x offRead=%#x/%#x -> cbWritable=%#x cbToWrite=%#x {%s}\n", offCaptureCursor, offReadCursor,
     2501                  pStreamDS->In.offReadPos, cbReadable, cbToRead, drvHostDSoundStreamStatusString(pStreamDS)));
    23712502
    23722503        /*
     
    24072538     * Done.
    24082539     */
    2409     if (pcbRead)
    2410         *pcbRead = cbRead;
     2540    *pcbRead = cbRead;
     2541    if (cbRead)
     2542    {
     2543        uint64_t const msPrev = pStreamDS->msLastTransfer;
     2544        pStreamDS->msLastTransfer = RTTimeMilliTS();
     2545        LogFlowFunc(("cbRead=%RU32, msLastTransfer=%RU64 msNow=%RU64 cMsDelta=%RU64 {%s}\n",
     2546                     cbRead, msPrev, pStreamDS->msLastTransfer, msPrev ? pStreamDS->msLastTransfer - msPrev : 0,
     2547                     drvHostDSoundStreamStatusString(pStreamDS) ));
     2548    }
    24112549
    24122550#ifdef VBOX_AUDIO_DEBUG_DUMP_PCM_DATA
Note: See TracChangeset for help on using the changeset viewer.

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