Changeset 88564 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Apr 16, 2021 1:16:47 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 143859
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvHostAudioDSound.cpp
r88556 r88564 117 117 /** Size (in bytes) of the DirectSound buffer. */ 118 118 DWORD cbBufSize; 119 /** The stream's critical section for synchronizing access. */120 RTCRITSECT CritSect;121 119 union 122 120 { … … 157 155 * to the DirectSound buffer was. */ 158 156 uint32_t cbLastTransferred; 159 /** Timestamp (in ms) of the last transfer from the internal buffer160 * to the DirectSound buffer. */161 uint64_t tsLastTransferredMs;162 /** Number of buffer underruns happened. Used for logging. */163 uint8_t cUnderruns;164 157 } Out; 165 158 }; 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; 172 168 } DSOUNDSTREAM, *PDSOUNDSTREAM; 173 169 … … 232 228 233 229 static 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 */ 239 static 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 */ 234 362 235 363 … … 1161 1289 1162 1290 /* Reset the state: */ 1291 pStreamDS->msLastTransfer = 0; 1163 1292 /** @todo r=bird: We set the read position to zero here, but shouldn't we query it 1164 1293 * from the buffer instead given that there isn't any interface for repositioning 1165 1294 * 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; 1168 1297 1169 1298 /* Clear the buffer content: */ … … 1205 1334 1206 1335 /* Reset the internal state: */ 1336 pStreamDS->msLastTransfer = 0; 1207 1337 pStreamDS->Out.fFirstTransfer = true; 1208 1338 pStreamDS->Out.fDrain = false; 1209 pStreamDS->Out.cUnderruns = 0;1210 1339 pStreamDS->Out.cbLastTransferred = 0; 1211 pStreamDS->Out.tsLastTransferredMs = 0;1212 1340 pStreamDS->Out.cbTransferred = 0; 1213 1341 pStreamDS->Out.cbWritten = 0; … … 1249 1377 } 1250 1378 } 1251 1252 #ifdef LOG_ENABLED1253 pStreamDS->Dbg.tsLastTransferredMs = 0;1254 #endif1255 1379 } 1256 1380 … … 1587 1711 PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream; 1588 1712 AssertPtrReturn(pStreamDS, VERR_INVALID_POINTER); 1713 LogFlowFunc(("Stream '%s' {%s}\n", pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS))); 1589 1714 1590 1715 if (pStreamDS->Cfg.enmDir == PDMAUDIODIR_IN) … … 1712 1837 PDRVHOSTDSOUND pThis = RT_FROM_MEMBER(pInterface, DRVHOSTDSOUND, IHostAudio); 1713 1838 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))); 1715 1840 1716 1841 /* … … 1775 1900 PDRVHOSTDSOUND pThis = RT_FROM_MEMBER(pInterface, DRVHOSTDSOUND, IHostAudio); 1776 1901 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) )); 1778 1905 1779 1906 /* … … 1820 1947 } 1821 1948 1822 LogFlowFunc(("returns %Rrc \n", rc));1949 LogFlowFunc(("returns %Rrc {%s}\n", rc, drvHostDSoundStreamStatusString(pStreamDS))); 1823 1950 return rc; 1824 1951 } … … 1835 1962 PDRVHOSTDSOUND pThis = RT_FROM_MEMBER(pInterface, DRVHOSTDSOUND, IHostAudio); 1836 1963 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) )); 1838 1967 1839 1968 /* … … 1873 2002 } 1874 2003 1875 LogFlowFunc(("returns %Rrc \n", rc));2004 LogFlowFunc(("returns %Rrc {%s}\n", rc, drvHostDSoundStreamStatusString(pStreamDS))); 1876 2005 return rc; 1877 2006 } … … 1918 2047 PDRVHOSTDSOUND pThis = RT_FROM_MEMBER(pInterface, DRVHOSTDSOUND, IHostAudio); 1919 2048 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))); 1921 2050 1922 2051 /* … … 1934 2063 } 1935 2064 1936 LogFlowFunc(("returns %Rrc \n", rc));2065 LogFlowFunc(("returns %Rrc {%s}\n", rc, drvHostDSoundStreamStatusString(pStreamDS))); 1937 2066 return rc; 1938 2067 } … … 1947 2076 PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream; 1948 2077 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) )); 1950 2081 1951 2082 /* … … 1981 2112 } 1982 2113 } 1983 LogFlowFunc(("returns %Rrc \n", rc));2114 LogFlowFunc(("returns %Rrc {%s}\n", rc, drvHostDSoundStreamStatusString(pStreamDS))); 1984 2115 return rc; 1985 2116 } … … 2068 2199 2069 2200 LPDIRECTSOUNDBUFFER8 pDSB = pStreamDS->Out.pDSB; 2070 if (!pDSB) 2071 { 2072 AssertPtr(pDSB); 2073 return VERR_INVALID_POINTER; 2074 } 2201 AssertPtrReturn(pDSB, VERR_INVALID_POINTER); 2075 2202 2076 2203 HRESULT hr = S_OK; … … 2141 2268 PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream; 2142 2269 AssertPtrReturn(pStreamDS, 0); 2270 LogFlowFunc(("Stream '%s' {%s}\n", pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS))); 2143 2271 2144 2272 DWORD cbFree = 0; … … 2160 2288 PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream; 2161 2289 AssertPtrReturn(pStreamDS, 0); 2290 LogFlowFunc(("Stream '%s' {%s}\n", pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS))); 2162 2291 2163 2292 if (pStreamDS->Cfg.enmDir == PDMAUDIODIR_OUT) … … 2188 2317 { 2189 2318 RT_NOREF(pInterface); 2190 AssertPtrReturn(pStream, PDMAUDIOSTREAMSTS_FLAGS_NONE);2191 2192 2319 PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream; 2320 AssertPtrReturn(pStreamDS, PDMAUDIOSTREAMSTS_FLAGS_NONE); 2193 2321 2194 2322 PDMAUDIOSTREAMSTS fStrmStatus = PDMAUDIOSTREAMSTS_FLAGS_INITIALIZED; 2195 2196 2323 if (pStreamDS->fEnabled) 2197 2324 fStrmStatus |= PDMAUDIOSTREAMSTS_FLAGS_ENABLED; 2198 2325 2326 LogFlowFunc(("returns %#x for '%s' {%s}\n", fStrmStatus, pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS))); 2199 2327 return fStrmStatus; 2200 2328 } … … 2218 2346 else 2219 2347 { 2220 Log2Func(("S tream disabled, skipping\n"));2348 Log2Func(("Skipping disabled stream {%s}\n", drvHostDSoundStreamStatusString(pStreamDS))); 2221 2349 return VINF_SUCCESS; 2222 2350 } 2351 Log4Func(("cbBuf=%#x stream '%s' {%s}\n", cbBuf, pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS) )); 2223 2352 2224 2353 /** @todo Any condition under which we should call dsoundUpdateStatusInternal(pThis) here? … … 2242 2371 2243 2372 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) )); 2246 2375 2247 2376 /* … … 2301 2430 if (cbWritten) 2302 2431 { 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) )); 2308 2438 } 2309 2439 return VINF_SUCCESS; … … 2333 2463 } 2334 2464 #endif 2465 Log4Func(("cbBuf=%#x stream '%s' {%s}\n", cbBuf, pStreamDS->Cfg.szName, drvHostDSoundStreamStatusString(pStreamDS) )); 2335 2466 2336 2467 /* … … 2367 2498 2368 2499 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))); 2371 2502 2372 2503 /* … … 2407 2538 * Done. 2408 2539 */ 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 } 2411 2549 2412 2550 #ifdef VBOX_AUDIO_DEBUG_DUMP_PCM_DATA
Note:
See TracChangeset
for help on using the changeset viewer.