- Timestamp:
- May 6, 2021 12:15:56 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvAudio.cpp
r88896 r88897 175 175 uint32_t cTriesReInit; 176 176 177 /** The backend state at the last play or capture call.177 /** The last backend state we saw. 178 178 * This is used to detect state changes (for what that is worth). */ 179 179 PDMHOSTAUDIOSTREAMSTATE enmLastBackendState; … … 401 401 static uint32_t drvAudioStreamRetainInternal(PDRVAUDIOSTREAM pStreamEx); 402 402 static uint32_t drvAudioStreamReleaseInternal(PDRVAUDIO pThis, PDRVAUDIOSTREAM pStreamEx, bool fMayDestroy); 403 static void drvAudioStreamResetInternal(PDRVAUDIOSTREAM pStreamEx); 403 404 static int drvAudioStreamIterateInternal(PDRVAUDIO pThis, PDRVAUDIOSTREAM pStreamEx); 404 405 … … 547 548 PDMHOSTAUDIOSTREAMSTATE enmState = pThis->pHostDrvAudio->pfnStreamGetState(pThis->pHostDrvAudio, pStreamEx->pBackend); 548 549 Assert(enmState > PDMHOSTAUDIOSTREAMSTATE_INVALID && enmState < PDMHOSTAUDIOSTREAMSTATE_END); 550 Log9Func(("%s: %s\n", pStreamEx->Core.szName, PDMHostAudioStreamStateGetName(enmState) )); 549 551 return enmState; 550 552 } 553 Log9Func(("%s: not-working\n", pStreamEx->Core.szName)); 551 554 return PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING; 555 } 556 557 558 /** 559 * Processes backend state change. 560 * 561 * @returns the new state value. 562 */ 563 static PDMHOSTAUDIOSTREAMSTATE drvAudioStreamProcessBackendStateChange(PDRVAUDIOSTREAM pStreamEx, 564 PDMHOSTAUDIOSTREAMSTATE enmNewState, 565 PDMHOSTAUDIOSTREAMSTATE enmOldState) 566 { 567 PDMAUDIODIR const enmDir = pStreamEx->Guest.Cfg.enmDir; 568 #ifdef LOG_ENABLED 569 DRVAUDIOPLAYSTATE const enmPlayState = enmDir == PDMAUDIODIR_OUT ? pStreamEx->Out.enmPlayState : DRVAUDIOPLAYSTATE_INVALID; 570 #endif 571 Assert(enmNewState != enmOldState); 572 Assert(enmOldState > PDMHOSTAUDIOSTREAMSTATE_INVALID && enmOldState < PDMHOSTAUDIOSTREAMSTATE_END); 573 AssertReturn(enmNewState > PDMHOSTAUDIOSTREAMSTATE_INVALID && enmNewState < PDMHOSTAUDIOSTREAMSTATE_END, enmOldState); 574 575 /* 576 * Figure out what happend and how that reflects on the playback state and stuff. 577 */ 578 switch (enmNewState) 579 { 580 case PDMHOSTAUDIOSTREAMSTATE_INITIALIZING: 581 /* Guess we're switching device. Nothing to do because the backend will tell us, right? */ 582 break; 583 584 case PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING: 585 /* The stream has stopped working. Switch to noplay mode. */ 586 if (enmDir == PDMAUDIODIR_OUT) 587 pStreamEx->Out.enmPlayState = DRVAUDIOPLAYSTATE_NOPLAY; 588 break; 589 590 case PDMHOSTAUDIOSTREAMSTATE_OKAY: 591 switch (enmOldState) 592 { 593 case PDMHOSTAUDIOSTREAMSTATE_INITIALIZING: 594 /* Should be taken care of elsewhere, so do nothing. */ 595 break; 596 597 case PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING: 598 case PDMHOSTAUDIOSTREAMSTATE_INACTIVE: 599 /* Go back to pre-buffering/playing depending on whether it is enabled 600 or not, resetting the stream state. */ 601 drvAudioStreamResetInternal(pStreamEx); 602 break; 603 604 /* no default: */ 605 case PDMHOSTAUDIOSTREAMSTATE_OKAY: /* impossible */ 606 case PDMHOSTAUDIOSTREAMSTATE_INVALID: 607 case PDMHOSTAUDIOSTREAMSTATE_END: 608 case PDMHOSTAUDIOSTREAMSTATE_32BIT_HACK: 609 break; 610 } 611 break; 612 613 case PDMHOSTAUDIOSTREAMSTATE_INACTIVE: 614 /* Stream is now inactive. Switch to noplay mode. */ 615 if (enmDir == PDMAUDIODIR_OUT) 616 pStreamEx->Out.enmPlayState = DRVAUDIOPLAYSTATE_NOPLAY; 617 break; 618 619 /* no default: */ 620 case PDMHOSTAUDIOSTREAMSTATE_INVALID: 621 case PDMHOSTAUDIOSTREAMSTATE_END: 622 case PDMHOSTAUDIOSTREAMSTATE_32BIT_HACK: 623 break; 624 } 625 626 if (enmDir == PDMAUDIODIR_OUT) 627 LogFunc(("Output stream '%s': %s/%s -> %s/%s\n", pStreamEx->Core.szName, 628 PDMHostAudioStreamStateGetName(enmOldState), drvAudioPlayStateName(enmPlayState), 629 PDMHostAudioStreamStateGetName(enmNewState), drvAudioPlayStateName(pStreamEx->Out.enmPlayState) )); 630 else 631 LogFunc(("Input stream '%s': %s -> %s\n", pStreamEx->Core.szName, 632 PDMHostAudioStreamStateGetName(enmOldState), PDMHostAudioStreamStateGetName(enmNewState) )); 633 634 pStreamEx->enmLastBackendState = enmNewState; 635 return enmNewState; 636 } 637 638 639 /** 640 * This gets the backend state and handles changes compared to 641 * DRVAUDIOSTREAM::enmLastBackendState (updated). 642 * 643 * @returns A PDMHOSTAUDIOSTREAMSTATE value. 644 * @param pThis Pointer to the DrvAudio instance data. 645 * @param pStreamEx The stream to get the backend status for. 646 */ 647 DECLINLINE(PDMHOSTAUDIOSTREAMSTATE) drvAudioStreamGetBackendStateAndProcessChanges(PDRVAUDIO pThis, PDRVAUDIOSTREAM pStreamEx) 648 { 649 PDMHOSTAUDIOSTREAMSTATE const enmBackendState = drvAudioStreamGetBackendState(pThis, pStreamEx); 650 if (pStreamEx->enmLastBackendState == enmBackendState) 651 return enmBackendState; 652 return drvAudioStreamProcessBackendStateChange(pStreamEx, enmBackendState, pStreamEx->enmLastBackendState); 552 653 } 553 654 … … 3234 3335 AssertRCReturn(rc, PDMAUDIOSTREAMSTATE_INVALID); 3235 3336 3236 PDMHOSTAUDIOSTREAMSTATE const enmBackendState = drvAudioStreamGetBackendState (pThis, pStreamEx);3337 PDMHOSTAUDIOSTREAMSTATE const enmBackendState = drvAudioStreamGetBackendStateAndProcessChanges(pThis, pStreamEx); 3237 3338 uint32_t const fStrmStatus = pStreamEx->fStatus; 3238 3339 PDMAUDIODIR const enmDir = pStreamEx->Guest.Cfg.enmDir; … … 3291 3392 3292 3393 return VINF_SUCCESS; 3293 }3294 3295 3296 /**3297 * Processes backend state change.3298 */3299 static void drvAudioStreamPlayProcessBackendStateChange(PDRVAUDIOSTREAM pStreamEx, PDMHOSTAUDIOSTREAMSTATE enmNewState,3300 PDMHOSTAUDIOSTREAMSTATE enmOldState)3301 {3302 #ifdef LOG_ENABLED3303 DRVAUDIOPLAYSTATE const enmPlayState = pStreamEx->Out.enmPlayState;3304 #endif3305 Assert(enmNewState != enmOldState);3306 Assert(enmOldState > PDMHOSTAUDIOSTREAMSTATE_INVALID && enmOldState < PDMHOSTAUDIOSTREAMSTATE_END);3307 AssertReturnVoid(enmNewState > PDMHOSTAUDIOSTREAMSTATE_INVALID && enmNewState < PDMHOSTAUDIOSTREAMSTATE_END);3308 3309 /*3310 * Figure out what happend and how that reflects on the playback state and stuff.3311 */3312 switch (enmNewState)3313 {3314 case PDMHOSTAUDIOSTREAMSTATE_INITIALIZING:3315 /* Guess we're switching device. Nothing to do because the backend will tell us, right? */3316 break;3317 3318 case PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING:3319 /* The stream has stopped working. Switch to noplay mode. */3320 pStreamEx->Out.enmPlayState = DRVAUDIOPLAYSTATE_NOPLAY;3321 break;3322 3323 case PDMHOSTAUDIOSTREAMSTATE_OKAY:3324 switch (enmOldState)3325 {3326 case PDMHOSTAUDIOSTREAMSTATE_INITIALIZING:3327 /* Should be taken care of elsewhere, so do nothing. */3328 break;3329 3330 case PDMHOSTAUDIOSTREAMSTATE_NOT_WORKING:3331 case PDMHOSTAUDIOSTREAMSTATE_INACTIVE:3332 /* Go back to pre-buffering/playing depending on whether it is enabled3333 or not, resetting the stream state. */3334 drvAudioStreamResetInternal(pStreamEx);3335 break;3336 3337 /* no default: */3338 case PDMHOSTAUDIOSTREAMSTATE_OKAY: /* impossible */3339 case PDMHOSTAUDIOSTREAMSTATE_INVALID:3340 case PDMHOSTAUDIOSTREAMSTATE_END:3341 case PDMHOSTAUDIOSTREAMSTATE_32BIT_HACK:3342 break;3343 }3344 break;3345 3346 case PDMHOSTAUDIOSTREAMSTATE_INACTIVE:3347 /* Stream is now inactive. Switch to noplay mode. */3348 pStreamEx->Out.enmPlayState = DRVAUDIOPLAYSTATE_NOPLAY;3349 break;3350 3351 /* no default: */3352 case PDMHOSTAUDIOSTREAMSTATE_INVALID:3353 case PDMHOSTAUDIOSTREAMSTATE_END:3354 case PDMHOSTAUDIOSTREAMSTATE_32BIT_HACK:3355 break;3356 }3357 3358 LogFunc(("Stream '%s': %s/%s -> %s/%s\n", pStreamEx->Guest.Cfg.szName,3359 PDMHostAudioStreamStateGetName(enmOldState), drvAudioPlayStateName(enmPlayState),3360 PDMHostAudioStreamStateGetName(enmNewState), drvAudioPlayStateName(pStreamEx->Out.enmPlayState) ));3361 3394 } 3362 3395 … … 3407 3440 { 3408 3441 /* 3409 * Get the backend state and check if it changed.3442 * Get the backend state and process changes to it since last time we checked. 3410 3443 */ 3411 /** @todo This is the wrong place for doing this, or we need to do it in more places. Problem is that if we've 3412 * entered NOPLAY mode this function won't get called because StreamGetWritable returns zero. A bit difficult to 3413 * reproduce, though. */ 3414 PDMHOSTAUDIOSTREAMSTATE const enmBackendState = drvAudioStreamGetBackendState(pThis, pStreamEx); 3415 if (enmBackendState == pStreamEx->enmLastBackendState) 3416 { /* no relevant change - likely */ } 3417 else 3418 { 3419 drvAudioStreamPlayProcessBackendStateChange(pStreamEx, enmBackendState, pStreamEx->enmLastBackendState); 3420 pStreamEx->enmLastBackendState = enmBackendState; 3421 } 3444 PDMHOSTAUDIOSTREAMSTATE const enmBackendState = drvAudioStreamGetBackendStateAndProcessChanges(pThis, pStreamEx); 3422 3445 3423 3446 /* … … 4030 4053 AssertReturnVoid(pStreamEx->Core.uMagic == PDMAUDIOSTREAM_MAGIC); 4031 4054 AssertReturnVoid(pStreamEx->uMagic == DRVAUDIOSTREAM_MAGIC); 4032 LogFlowFunc(("pStreamEx=%p '%s'\n", pStreamEx, pStreamEx-> Guest.Cfg.szName));4055 LogFlowFunc(("pStreamEx=%p '%s'\n", pStreamEx, pStreamEx->Core.szName)); 4033 4056 4034 4057 /*
Note:
See TracChangeset
for help on using the changeset viewer.