Changeset 61386 in vbox
- Timestamp:
- Jun 1, 2016 6:51:16 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 107697
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/pdmaudioifs.h
r61352 r61386 702 702 703 703 /** 704 * Sets the audio volume of a specific audio stream. 705 * 706 * @returns VBox status code. 707 * @param pInterface Pointer to the interface structure containing the called function pointer. 708 * @param pStream Pointer to audio stream. 709 * @param pVol Pointer to audio volume structure to set the stream's audio volume to. 710 */ 711 DECLR3CALLBACKMEMBER(int, pfnStreamSetVolume, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOVOLUME pVol)); 712 713 /** 704 714 * Plays (transfers) all available audio samples of a an output stream via the connected host backend. 705 715 * … … 718 728 719 729 /** PDMIAUDIOCONNECTOR interface ID. */ 720 #define PDMIAUDIOCONNECTOR_IID "9 E03C980-64E9-42EC-9C70-316995990BE3"730 #define PDMIAUDIOCONNECTOR_IID "9C097435-3276-4D88-A49A-A4FE671D86F8" 721 731 722 732 -
trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp
r61352 r61386 1046 1046 1047 1047 /* Note: Always count in parent samples, as the rate can differ! */ 1048 pSrc->cMixed = cDstMixed; 1049 Assert(pSrc->cMixed <= pDst->cSamples); 1048 pSrc->cMixed = RT_MIN(cDstMixed, pDst->cSamples); 1050 1049 1051 1050 pDst->offWrite = offDstWrite; … … 1542 1541 } 1543 1542 1544 PPDMAUDIOMIXBUF pIter; 1545 while (!RTListIsEmpty(&pMixBuf->lstChildren)) 1546 { 1547 pIter = RTListGetFirst(&pMixBuf->lstChildren, PDMAUDIOMIXBUF, Node); 1548 1549 AUDMIXBUF_LOG(("\tUnlinking \"%s\"\n", pIter->pszName)); 1550 1551 AudioMixBufReset(pIter->pParent); 1552 pIter->pParent = NULL; 1553 1554 RTListNodeRemove(&pIter->Node); 1555 } 1543 PPDMAUDIOMIXBUF pChild, pChildNext; 1544 RTListForEachSafe(&pMixBuf->lstChildren, pChild, pChildNext, PDMAUDIOMIXBUF, Node) 1545 { 1546 AUDMIXBUF_LOG(("\tUnlinking \"%s\"\n", pChild->pszName)); 1547 1548 AudioMixBufReset(pChild); 1549 1550 Assert(pChild->pParent == pMixBuf); 1551 pChild->pParent = NULL; 1552 1553 RTListNodeRemove(&pChild->Node); 1554 } 1555 1556 Assert(RTListIsEmpty(&pMixBuf->lstChildren)); 1557 1558 AudioMixBufReset(pMixBuf); 1556 1559 1557 1560 if (pMixBuf->pRate) -
trunk/src/VBox/Devices/Audio/AudioMixer.cpp
r61325 r61386 867 867 RTListForEach(&pSink->lstStreams, pMixStream, AUDMIXSTREAM, Node) 868 868 { 869 if (fOut) 870 AudioMixBufSetVolume(&pMixStream->pStream->MixBuf, &volSink); 871 else 872 AudioMixBufSetVolume(&pMixStream->pStream->MixBuf, &volSink); 869 int rc2 = pMixStream->pConn->pfnStreamSetVolume(pMixStream->pConn, pMixStream->pStream, &volSink); 870 AssertRC(rc2); 873 871 } 874 872 … … 900 898 { 901 899 if (!(pMixStream->pConn->pfnStreamGetStatus(pMixStream->pConn, pMixStream->pStream) & PDMAUDIOSTRMSTS_FLAG_ENABLED)) 900 { 901 LogFlowFunc(("%s: Disabled, skipping ...\n", pSink->pszName)); 902 902 continue; 903 } 903 904 904 905 int rc2 = pMixStream->pConn->pfnStreamWrite(pMixStream->pConn, pMixStream->pStream, pvBuf, cbBuf, &cbProcessed); -
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r61320 r61386 1376 1376 pThis->uTimerTS = cTicksNow; 1377 1377 1378 LogFlowFuncEnter(); 1379 1378 1380 uint32_t cbLineIn; 1379 1381 AudioMixerSinkTimerUpdate(pThis->pSinkLineIn, pThis->cTimerTicks, cTicksPerSec, &cbLineIn); -
trunk/src/VBox/Devices/Audio/DevIchHda.cpp
r61167 r61386 3465 3465 Assert(cbRead <= cbBuf); 3466 3466 Assert(cbRead <= pBDLE->u32BufSize - pBDLE->State.u32BufOff); 3467 //Assert(cbRead <= pStream->u16FIFOS);3468 3467 3469 3468 /* … … 3477 3476 if (pBDLE->State.cbBelowFIFOW + cbRead > hdaStreamGetFIFOW(pThis, pStream)) 3478 3477 { 3478 Assert(pBDLE->State.u32BufOff + cbRead <= pBDLE->u32BufSize); 3479 3479 pBDLE->State.u32BufOff += cbRead; 3480 3480 pBDLE->State.cbBelowFIFOW = 0; … … 3483 3483 else 3484 3484 { 3485 Assert(pBDLE->State.u32BufOff + cbRead <= pBDLE->u32BufSize); 3485 3486 pBDLE->State.u32BufOff += cbRead; 3486 3487 pBDLE->State.cbBelowFIFOW += cbRead; … … 3628 3629 else 3629 3630 { 3630 pBDLE->State.u32BufOff += cbWritten; 3631 Assert(pBDLE->State.u32BufOff + cbWritten <= pBDLE->u32BufSize); 3632 pBDLE->State.u32BufOff += cbWritten; 3631 3633 pBDLE->State.cbBelowFIFOW += cbWritten; 3632 3634 Assert(pBDLE->State.cbBelowFIFOW <= hdaStreamGetFIFOW(pThis, pStream)); -
trunk/src/VBox/Devices/Audio/DevSB16.cpp
r61334 r61386 434 434 if (hold) 435 435 { 436 #ifndef VBOX_WITH_AUDIO_CALLBACKS 436 437 pThis->cStreamsActive++; 437 #ifndef VBOX_WITH_AUDIO_CALLBACKS438 438 sb16TimerMaybeStart(pThis); 439 439 #endif … … 1039 1039 else 1040 1040 TMTimerSet(pThis->pTimerIRQ, TMTimerGet(pThis->pTimerIRQ) + ticks); 1041 LogFlowFunc(("mix silence %d %d % %RU64\n", samples, bytes, ticks));1041 LogFlowFunc(("mix silence: %d samples, %d bytes, %RU64 ticks\n", samples, bytes, ticks)); 1042 1042 break; 1043 1043 } … … 1108 1108 uint8_t lvol = sb16MixRegToVol(pThis, 0x30); 1109 1109 uint8_t rvol = sb16MixRegToVol(pThis, 0x31); 1110 PDMAUDIOVOLUME vol = { false, lvol, rvol }; 1111 1112 // AudioMixerSetMasterVolume(pThis->pMixer, &vol); 1110 1111 PDMAUDIOVOLUME Vol = { false /* fMute */, lvol, rvol }; 1112 1113 PSB16DRIVER pDrv; 1114 RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node) 1115 { 1116 int rc2 = pDrv->pConnector->pfnStreamSetVolume(pDrv->pConnector, pDrv->Out.pStream, &Vol); 1117 AssertRC(rc2); 1118 } 1113 1119 } 1114 1120 … … 1118 1124 uint8_t lvol = sb16MixRegToVol(pThis, 0x32); 1119 1125 uint8_t rvol = sb16MixRegToVol(pThis, 0x33); 1120 PDMAUDIOVOLUME vol = { false, lvol, rvol }; 1121 1122 // AudioMixerSinkSetVolume(pThis->pSinkOutput, &vol); 1126 1127 PDMAUDIOVOLUME Vol = { false /* fMute */, lvol, rvol }; 1128 1129 PSB16DRIVER pDrv; 1130 RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node) 1131 { 1132 int rc2 = pDrv->pConnector->pfnStreamSetVolume(pDrv->pConnector, pDrv->Out.pStream, &Vol); 1133 AssertRC(rc2); 1134 } 1123 1135 } 1124 1136 1125 1137 static void sb16ResetLegacy(PSB16STATE pThis) 1126 1138 { 1139 LogFlowFuncEnter(); 1140 1127 1141 sb16CloseOut(pThis); 1128 1142 … … 1168 1182 dsp_out_data(pThis, 0xaa); 1169 1183 sb16SpeakerControl(pThis, 0); 1184 1170 1185 sb16Control(pThis, 0); 1171 1186 sb16ResetLegacy(pThis); … … 1781 1796 continue; 1782 1797 1783 PDMAUDIOSTRMSTS strmSts = pDrv->pConnector->pfnStreamGetStatus(pDrv->pConnector, pStream);1784 fIsPlaying |= ( (strmSts & PDMAUDIOSTRMSTS_FLAG_ENABLED)1785 || (strmSts & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE));1786 1787 LogFlowFunc(("%s: strmSts=0x%x -> fIsPlaying=%RTbool\n", pStream->szName, strmSts, fIsPlaying));1788 1789 1798 int rc2 = pDrv->pConnector->pfnStreamIterate(pDrv->pConnector, pStream); 1790 1799 if (RT_SUCCESS(rc2)) … … 1801 1810 } 1802 1811 } 1812 1813 PDMAUDIOSTRMSTS strmSts = pDrv->pConnector->pfnStreamGetStatus(pDrv->pConnector, pStream); 1814 fIsPlaying |= ( (strmSts & PDMAUDIOSTRMSTS_FLAG_ENABLED) 1815 || (strmSts & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE)); 1816 1817 LogFlowFunc(("%s: strmSts=0x%x -> fIsPlaying=%RTbool\n", pStream->szName, strmSts, fIsPlaying)); 1803 1818 } 1804 1819 … … 1814 1829 TMTimerSet(pThis->pTimerIO, cTicksNow + cTicks); 1815 1830 } 1831 1832 LogFlowFuncLeave(); 1816 1833 } 1817 1834 … … 2035 2052 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 2036 2053 2054 LogFlowFuncEnter(); 2055 2037 2056 AssertReturn(pCfg->enmDir == PDMAUDIODIR_OUT, VERR_INVALID_PARAMETER); 2038 2039 int rc = VINF_SUCCESS;2040 2057 2041 2058 /* Set a default audio format for the host. */ … … 2052 2069 uint8_t uLUN = 0; 2053 2070 2071 int rc = VINF_SUCCESS; 2072 2054 2073 PSB16DRIVER pDrv; 2055 2074 RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node) … … 2062 2081 } 2063 2082 2083 int rc2; 2084 2064 2085 if (pDrv->Out.pStream) 2065 2086 { 2066 2087 pDrv->pConnector->pfnStreamRelease(pDrv->pConnector, pDrv->Out.pStream); 2067 2088 2068 int rc3 = pDrv->pConnector->pfnStreamDestroy(pDrv->pConnector, pDrv->Out.pStream); 2069 AssertRC(rc3); 2070 2071 pDrv->Out.pStream = NULL; 2089 rc2 = pDrv->pConnector->pfnStreamDestroy(pDrv->pConnector, pDrv->Out.pStream); 2090 if (RT_SUCCESS(rc2)) 2091 pDrv->Out.pStream = NULL; 2072 2092 } 2073 2074 int rc2 = pDrv->pConnector->pfnStreamCreate(pDrv->pConnector, &CfgHost, pCfg, &pDrv->Out.pStream); 2093 else 2094 rc2 = VINF_SUCCESS; 2095 2075 2096 if (RT_SUCCESS(rc2)) 2076 pDrv->pConnector->pfnStreamAddRef(pDrv->pConnector, pDrv->Out.pStream); 2097 { 2098 rc2 = pDrv->pConnector->pfnStreamCreate(pDrv->pConnector, &CfgHost, pCfg, &pDrv->Out.pStream); 2099 if (RT_SUCCESS(rc2)) 2100 pDrv->pConnector->pfnStreamAddRef(pDrv->pConnector, pDrv->Out.pStream); 2101 } 2077 2102 2078 2103 LogFlowFunc(("LUN#%RU8: Created output \"%s\", rc=%Rrc\n", pDrv->uLUN, pCfg->szName, rc2)); … … 2081 2106 } 2082 2107 2108 LogFlowFuncLeaveRC(rc); 2083 2109 return rc; 2084 2110 } … … 2097 2123 pDrv->pConnector->pfnStreamRelease(pDrv->pConnector, pDrv->Out.pStream); 2098 2124 2099 pDrv->pConnector->pfnStreamDestroy(pDrv->pConnector, pDrv->Out.pStream); 2100 pDrv->Out.pStream = NULL; 2125 int rc2 = pDrv->pConnector->pfnStreamDestroy(pDrv->pConnector, pDrv->Out.pStream); 2126 if (RT_SUCCESS(rc2)) 2127 pDrv->Out.pStream = NULL; 2101 2128 } 2102 2129 } 2130 2131 LogFlowFuncLeave(); 2103 2132 } 2104 2133 -
trunk/src/VBox/Devices/Audio/DrvAudio.cpp
r61337 r61386 66 66 67 67 static DECLCALLBACK(int) drvAudioStreamDestroy(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream); 68 static int drvAudioStreamControlInternalBackend(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd); 68 69 static int drvAudioStreamControlInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd); 69 static int drvAudioStreamControlInternalBackend(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd);70 70 static int drvAudioStreamDestroyInternalBackend(PDRVAUDIO pThis, PPDMAUDIOSTREAM pHstStream); 71 71 static int drvAudioStreamDestroyInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream); 72 static int drvAudioStreamIterateInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream); 72 73 73 74 #ifndef VBOX_AUDIO_TESTCASE … … 154 155 ? pStream 155 156 : pStream->pPair; 157 if (pStreamHst) 158 { 159 Assert(pStreamHst->enmCtx == PDMAUDIOSTREAMCTX_HOST); 160 } 161 else 162 LogFlowFunc(("%s: Warning: Does not have a host stream (anymore)\n", pStream->szName)); 163 156 164 return pStreamHst; 157 165 } … … 263 271 return rc; 264 272 265 LogFlowFunc(("%s\n", pStream->szName)); 273 LogFlowFunc(("%s: enmStreamCmd=%ld\n", pStream->szName, enmStreamCmd)); 274 275 rc = drvAudioStreamControlInternal(pThis, pStream, enmStreamCmd); 276 277 int rc2 = RTCritSectLeave(&pThis->CritSect); 278 if (RT_SUCCESS(rc)) 279 rc = rc2; 280 281 return rc; 282 } 283 284 static int drvAudioStreamControlInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 285 { 286 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 287 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 288 289 LogFlowFunc(("%s: enmStreamCmd=%ld\n", pStream->szName, enmStreamCmd)); 266 290 267 291 PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream); 268 PPDMAUDIOSTREAM pGstStream = pHstStream->pPair; 269 270 /* Note: Call the host (backend) first to see if there is any pending disable 271 * actions in progress. */ 272 rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, enmStreamCmd); 273 if ( RT_SUCCESS(rc) 274 || rc == VERR_AUDIO_STREAM_PENDING_DISABLE) 275 { 276 int rc3 = drvAudioStreamControlInternal(pThis, pStream, enmStreamCmd); 277 if (RT_SUCCESS(rc)) 278 rc = rc3; 279 } 280 281 int rc2 = RTCritSectLeave(&pThis->CritSect); 282 if (RT_SUCCESS(rc)) 283 rc = rc2; 284 285 return rc; 286 } 287 288 static int drvAudioStreamControlInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pGstStream, PDMAUDIOSTREAMCMD enmStreamCmd) 289 { 290 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 291 292 if (!pGstStream) 293 return VINF_SUCCESS; 292 PPDMAUDIOSTREAM pGstStream = pHstStream ? pHstStream->pPair : pStream; 293 AssertPtr(pGstStream); 294 294 295 295 int rc = VINF_SUCCESS; … … 299 299 case PDMAUDIOSTREAMCMD_ENABLE: 300 300 { 301 pGstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_ENABLED; 301 if (!(pGstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED)) 302 { 303 if (pHstStream) 304 { 305 /* Is a pending disable outstanding? Then disable first. */ 306 if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE) 307 rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 308 309 if (RT_SUCCESS(rc)) 310 rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_ENABLE); 311 } 312 313 pGstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_ENABLED; 314 } 302 315 break; 303 316 } 304 317 305 318 case PDMAUDIOSTREAMCMD_DISABLE: 306 { 307 pGstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_ENABLED; 319 case PDMAUDIOSTREAMCMD_PAUSE: 320 { 321 if (pGstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED) 322 { 323 /* Is the guest side stream still active? 324 * Mark the host stream as pending disable and bail out. */ 325 if (pHstStream) 326 { 327 LogFlowFunc(("%s: Pending disable/pause\n", pHstStream->szName)); 328 pHstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE; 329 } 330 331 if (enmStreamCmd == PDMAUDIOSTREAMCMD_DISABLE) 332 { 333 pGstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_ENABLED; 334 } 335 else if (enmStreamCmd == PDMAUDIOSTREAMCMD_PAUSE) 336 pGstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_PAUSED; 337 else 338 AssertFailedBreakStmt(rc = VERR_NOT_IMPLEMENTED); 339 } 340 341 if ( pHstStream 342 && !(pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE)) 343 { 344 rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, enmStreamCmd); 345 if (RT_SUCCESS(rc)) 346 pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE; 347 } 308 348 break; 309 349 } 310 350 311 case PDMAUDIOSTREAMCMD_PAUSE:312 {313 pGstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_PAUSED;314 break;315 }316 317 351 case PDMAUDIOSTREAMCMD_RESUME: 318 352 { 319 pGstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PAUSED; 353 if (pGstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PAUSED) 354 { 355 if (pHstStream) 356 rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_RESUME); 357 358 pGstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PAUSED; 359 } 320 360 break; 321 361 } … … 327 367 } 328 368 329 LogFlowFunc(("%s: enmStreamCmd=%ld, rc=%Rrc\n", pGstStream->szName, enmStreamCmd, rc)); 369 if (RT_FAILURE(rc)) 370 LogFunc(("%s: Failed with %Rrc\n", pStream->szName, rc)); 371 330 372 return rc; 331 373 } 332 374 333 static int drvAudioStreamControlInternalBackend(PDRVAUDIO pThis, PPDMAUDIOSTREAM p HstStream, PDMAUDIOSTREAMCMD enmStreamCmd)334 { 335 AssertPtrReturn(pThis, VERR_INVALID_POINTER);336 337 if (!pHstStream) 338 return VINF_SUCCESS;339 340 AssertMsg(pHstStream->enmCtx == PDMAUDIOSTREAMCTX_HOST,341 ("Stream '%s' is not a host stream and therefore has no backend\n", pHstStream->szName));342 343 LogFlowFunc(("%s: enmStreamCmd=%ld\n", pHstStream->szName, enmStreamCmd));375 static int drvAudioStreamControlInternalBackend(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 376 { 377 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 378 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 379 380 LogFlowFunc(("%s: enmStreamCmd=%ld\n", pStream->szName, enmStreamCmd)); 381 382 PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream); 383 AssertPtr(pHstStream); 384 385 AssertPtr(pThis->pHostDrvAudio); 344 386 345 387 int rc = VINF_SUCCESS; 346 388 347 PPDMAUDIOSTREAM pGstStream = pHstStream->pPair; /* Can be NULL. */348 349 389 switch (enmStreamCmd) 350 390 { … … 353 393 if (!(pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED)) 354 394 { 355 if (pThis->pHostDrvAudio) 356 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_ENABLE); 395 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_ENABLE); 357 396 if (RT_SUCCESS(rc)) 358 397 pHstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_ENABLED; … … 363 402 case PDMAUDIOSTREAMCMD_DISABLE: 364 403 { 365 /* Is the guest side stream still active?366 * Mark the host stream as pending disable and bail out. */367 if ( pGstStream368 && (pGstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED))369 {370 LogFlowFunc(("%s: Pending disable\n", pHstStream->szName));371 pHstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE;372 rc = VERR_AUDIO_STREAM_PENDING_DISABLE;373 break;374 }375 376 /* Clear pending disable bit. */377 pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE;378 379 404 if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED) 380 405 { 381 if (pThis->pHostDrvAudio) 382 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 406 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 383 407 if (RT_SUCCESS(rc)) 384 408 { … … 392 416 case PDMAUDIOSTREAMCMD_PAUSE: 393 417 { 394 /* Is the guest side stream still active?395 * Mark the host stream as pending disable and bail out. */396 if ( pGstStream397 && (pGstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED))398 {399 LogFlowFunc(("%s: Pending pause\n", pHstStream->szName));400 pHstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE;401 rc = VERR_AUDIO_STREAM_PENDING_DISABLE;402 break;403 }404 405 418 if (!(pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PAUSED)) 406 419 { 407 if (pThis->pHostDrvAudio) 408 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_PAUSE); 420 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_PAUSE); 409 421 if (RT_SUCCESS(rc)) 410 422 pHstStream->fStatus |= PDMAUDIOSTRMSTS_FLAG_PAUSED; … … 417 429 if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PAUSED) 418 430 { 419 if (pThis->pHostDrvAudio) 420 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_RESUME); 431 rc = pThis->pHostDrvAudio->pfnStreamControl(pThis->pHostDrvAudio, pHstStream, PDMAUDIOSTREAMCMD_RESUME); 421 432 if (RT_SUCCESS(rc)) 422 433 pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PAUSED; … … 432 443 433 444 if (RT_FAILURE(rc)) 434 LogFunc(("%s: Failed with %Rrc\n", p HstStream->szName, rc));445 LogFunc(("%s: Failed with %Rrc\n", pStream->szName, rc)); 435 446 436 447 return rc; … … 671 682 NOREF(pInterface); 672 683 673 Assert(pStream->cRefs); 674 if (pStream->cRefs) 684 if (pStream->cRefs > 1) /* 1 reference always is kept by this audio driver. */ 675 685 pStream->cRefs--; 676 686 … … 682 692 { 683 693 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 694 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 684 695 /* pcData is optional. */ 696 697 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 698 699 int rc = RTCritSectEnter(&pThis->CritSect); 700 if (RT_FAILURE(rc)) 701 return rc; 702 703 LogFlowFunc(("%s\n", pStream->szName)); 704 705 rc = drvAudioStreamIterateInternal(pThis, pStream); 706 707 int rc2 = RTCritSectLeave(&pThis->CritSect); 708 if (RT_SUCCESS(rc)) 709 rc = rc2; 710 711 if (RT_FAILURE(rc)) 712 LogFlowFuncLeaveRC(rc); 713 714 return rc; 715 } 716 717 static int drvAudioStreamIterateInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream) 718 { 719 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 685 720 686 721 if (!pStream) 687 722 return VINF_SUCCESS; 688 723 689 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 690 691 int rc = RTCritSectEnter(&pThis->CritSect); 692 if (RT_FAILURE(rc)) 693 return rc; 694 695 LogFlowFunc(("[%s]\n", pStream->szName)); 724 LogFlowFunc(("%s\n", pStream->szName)); 696 725 697 726 PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream); 698 727 PPDMAUDIOSTREAM pGstStream = pHstStream->pPair; 728 729 int rc = VINF_SUCCESS; 699 730 700 731 do … … 721 752 uint32_t cSamplesToMix = AudioMixBufUsed(&pGstStream->MixBuf); 722 753 723 /* Has this stream marked as disabled but there still were guest streams relying 724 * on it? CheckpHstStreamif this stream now can be closed and do so, if possible. */ 725 if ( (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE) 726 && !cSamplesToMix) 727 { 728 rc = drvAudioStreamControlInternal(pThis, pGstStream, PDMAUDIOSTREAMCMD_DISABLE); 729 if (RT_SUCCESS(rc)) 730 rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 731 732 if (RT_FAILURE(rc)) 733 LogFunc(("%s: Backend vetoed against closing output stream, rc=%Rrc\n", pHstStream->szName, rc)); 734 735 break; 736 } 737 738 uint32_t cSamplesPlayed = 0; 739 if (hstStrmSts & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE) 740 { 754 if (cSamplesToMix) 755 { 756 uint32_t cSamplesPlayed = 0; 757 if (hstStrmSts & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE) 758 { 741 759 /* int rc2 = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream, &cSamplesPlayed); 742 760 if (RT_SUCCESS(rc)) … … 744 762 }*/ 745 763 746 if (cSamplesToMix)747 764 rc = AudioMixBufMixToParent(&pGstStream->MixBuf, cSamplesToMix, &cSamplesMixed); 748 } 749 750 LogFlowFunc(("%s: %RU32/%RU32 samples mixed, %RU32 played\n", 751 pHstStream->szName, cSamplesMixed, cSamplesToMix, cSamplesPlayed)); 765 766 LogFlowFunc(("%s: %RU32/%RU32 samples mixed, rc=%Rrc\n", 767 pHstStream->szName, cSamplesMixed, cSamplesToMix, rc)); 768 } 769 } 752 770 } 753 771 … … 756 774 757 775 } while (0); 758 759 int rc2 = RTCritSectLeave(&pThis->CritSect);760 if (RT_SUCCESS(rc))761 rc = rc2;762 763 if (RT_FAILURE(rc))764 LogFlowFuncLeaveRC(rc);765 776 766 777 return rc; … … 973 984 AssertPtr(pGstStream); 974 985 975 PDMAUDIOSTRMSTS strmSts = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream); 976 977 if (strmSts & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE) 978 { 979 rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream, &cSamplesPlayed); 980 if (RT_FAILURE(rc)) 981 { 982 int rc3 = drvAudioStreamControlInternalBackend(pThis, pStream, PDMAUDIOSTREAMCMD_DISABLE); 983 AssertRC(rc3); 984 } 985 } 986 987 LogFlowFunc(("[%s] strmSts=0x%x, cSamplesPlayed=%RU32, rc=%Rrc\n", pStream->szName, strmSts, cSamplesPlayed, rc)); 988 986 uint32_t cSamplesLive = AudioMixBufUsed(&pHstStream->MixBuf); 987 if (cSamplesLive) 988 { 989 PDMAUDIOSTRMSTS strmSts = pThis->pHostDrvAudio->pfnStreamGetStatus(pThis->pHostDrvAudio, pHstStream); 990 if (strmSts & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE) 991 { 992 rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream, &cSamplesPlayed); 993 if (RT_FAILURE(rc)) 994 drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 995 } 996 997 LogFlowFunc(("[%s] strmSts=0x%x, cSamplesPlayed=%RU32, rc=%Rrc\n", pStream->szName, strmSts, cSamplesPlayed, rc)); 998 999 if (RT_SUCCESS(rc)) 1000 { 1001 rc = drvAudioStreamIterateInternal(pThis, pStream); 1002 if (RT_SUCCESS(rc)) 1003 cSamplesLive = AudioMixBufUsed(&pHstStream->MixBuf); 1004 } 1005 } 1006 1007 if (!cSamplesLive) 1008 { 1009 /* Has the host stream marked as disabled but there still were guest streams relying 1010 * on it? Check if the stream now can be closed and do so, if possible. */ 1011 if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE) 1012 { 1013 LogFunc(("%s: Closing pending stream\n", pHstStream->szName)); 1014 rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 1015 if (RT_SUCCESS(rc)) 1016 { 1017 pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE; 1018 } 1019 else 1020 LogFunc(("%s: Backend vetoed against closing output stream, rc=%Rrc\n", pHstStream->szName, rc)); 1021 } 1022 } 989 1023 #if 0 990 1024 if (pStream->pPair) … … 1332 1366 return; 1333 1367 1334 PPDMAUDIOSTREAM p Stream;1335 RTListForEach(&pThis->lst Streams, pStream, PDMAUDIOSTREAM, Node)1336 drvAudioStreamControlInternal (pThis, pStream, enmCmd);1368 PPDMAUDIOSTREAM pHstStream; 1369 RTListForEach(&pThis->lstHstStreams, pHstStream, PDMAUDIOSTREAM, Node) 1370 drvAudioStreamControlInternalBackend(pThis, pHstStream, enmCmd); 1337 1371 } 1338 1372 … … 1345 1379 LogFlowFunc(("pThis=%p, pDrvIns=%p\n", pThis, pDrvIns)); 1346 1380 1347 RTListInit(&pThis->lstStreams); 1381 RTListInit(&pThis->lstHstStreams); 1382 RTListInit(&pThis->lstGstStreams); 1348 1383 #ifdef VBOX_WITH_AUDIO_CALLBACKS 1349 1384 RTListInit(&pThis->lstCBIn); … … 1647 1682 AssertPtrBreakStmt(pHstStrm, rc = VERR_NO_MEMORY); 1648 1683 1649 RTListAppend(&pThis->lstStreams, &pHstStrm->Node); 1684 pHstStrm->enmCtx = PDMAUDIOSTREAMCTX_HOST; 1685 pHstStrm->enmDir = pCfgHost->enmDir; 1686 1687 RTListAppend(&pThis->lstHstStreams, &pHstStrm->Node); 1650 1688 1651 1689 pGstStrm = (PPDMAUDIOSTREAM)RTMemAllocZ(sizeof(PDMAUDIOSTREAM)); 1652 1690 AssertPtrBreakStmt(pGstStrm, rc = VERR_NO_MEMORY); 1653 1691 1654 RTListAppend(&pThis->lstStreams, &pGstStrm->Node); 1692 pGstStrm->enmCtx = PDMAUDIOSTREAMCTX_GUEST; 1693 pGstStrm->enmDir = pCfgGuest->enmDir; 1694 1695 RTListAppend(&pThis->lstGstStreams, &pGstStrm->Node); 1655 1696 1656 1697 /* … … 1670 1711 } 1671 1712 1672 pHstStrm->enmCtx = PDMAUDIOSTREAMCTX_HOST;1673 pHstStrm->enmDir = pCfgHost->enmDir;1674 1713 pHstStrm->fStatus |= PDMAUDIOSTRMSTS_FLAG_INITIALIZED; 1675 1714 pHstStrm->pPair = pGstStrm; … … 1706 1745 } 1707 1746 1708 pGstStrm->enmCtx = PDMAUDIOSTREAMCTX_GUEST;1709 pGstStrm->enmDir = pCfgGuest->enmDir;1710 1747 pGstStrm->fStatus |= PDMAUDIOSTRMSTS_FLAG_INITIALIZED; 1711 1748 pGstStrm->pPair = pHstStrm; … … 1719 1756 if (RT_FAILURE(rc)) 1720 1757 { 1721 if ( pHstStrm1722 && pHstStrm->enmCtx == PDMAUDIOSTREAMCTX_HOST)1723 {1724 if (pHstStrm->fStatus & PDMAUDIOSTRMSTS_FLAG_INITIALIZED)1725 {1726 rc = drvAudioStreamControlInternalBackend(pThis, pHstStrm, PDMAUDIOSTREAMCMD_DISABLE);1727 if (RT_SUCCESS(rc))1728 {1729 rc = pThis->pHostDrvAudio->pfnStreamDestroy(pThis->pHostDrvAudio, pHstStrm);1730 if (RT_SUCCESS(rc))1731 pHstStrm->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_INITIALIZED;1732 }1733 }1734 1735 AssertMsgRC(rc, ("Host stream '%s' failed to uninit in backend: %Rrc\n", pHstStrm->szName, rc));1736 }1737 1738 1758 drvAudioStreamDestroyInternal(pThis, pGstStrm); 1739 1759 pGstStrm = NULL; … … 1759 1779 } 1760 1780 1781 /* Always return the guest-side part to the device emulation. */ 1761 1782 *ppStream = pGstStrm; 1762 1783 } … … 1815 1836 { 1816 1837 AssertPtrReturn(pInterface, false); 1817 /* pStream is optional. */ 1818 1819 if (!pStream) 1820 return PDMAUDIOSTRMSTS_FLAG_NONE; 1838 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1821 1839 1822 1840 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); … … 1834 1852 return strmSts; 1835 1853 } 1854 1855 static DECLCALLBACK(int) drvAudioStreamSetVolume(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOVOLUME pVol) 1856 { 1857 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1858 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1859 AssertPtrReturn(pVol, VERR_INVALID_POINTER); 1860 1861 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 1862 1863 LogFlowFunc(("%s: volL=%RU32, volR=%RU32, fMute=%RTbool\n", pStream->szName, pVol->uLeft, pVol->uRight, pVol->fMuted)); 1864 1865 AudioMixBufSetVolume(&pStream->MixBuf, pVol); 1866 1867 return VINF_SUCCESS; 1868 } 1836 1869 #endif 1837 1870 1838 1871 static DECLCALLBACK(int) drvAudioStreamDestroy(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAM pStream) 1839 1872 { 1873 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1874 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1875 1840 1876 PDRVAUDIO pThis = PDMIAUDIOCONNECTOR_2_DRVAUDIO(pInterface); 1841 1877 … … 1851 1887 if (RT_SUCCESS(rc)) 1852 1888 { 1853 rc = drvAudioStreamDestroyInternal(pThis, pStream); 1854 if (RT_SUCCESS(rc)) 1855 pStream = NULL; 1889 PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream); 1890 PPDMAUDIOSTREAM pGstStream = pHstStream ? pHstStream->pPair : pStream; 1891 1892 LogFlowFunc(("\tHost : %s\n", pHstStream ? pHstStream->szName : "<None>")); 1893 LogFlowFunc(("\tGuest: %s\n", pGstStream ? pGstStream->szName : "<None>")); 1894 1895 /* Should prevent double frees. */ 1896 Assert(pHstStream != pGstStream); 1897 1898 if (pHstStream) 1899 { 1900 pHstStream->pPair = NULL; 1901 RTListNodeRemove(&pHstStream->Node); 1902 } 1903 1904 if (pGstStream) 1905 { 1906 pGstStream->pPair = NULL; 1907 RTListNodeRemove(&pGstStream->Node); 1908 } 1909 1910 if (pHstStream) 1911 { 1912 rc = drvAudioStreamDestroyInternal(pThis, pHstStream); 1913 AssertRC(rc); 1914 1915 pHstStream = NULL; 1916 } 1917 1918 if (pGstStream) 1919 { 1920 rc = drvAudioStreamDestroyInternal(pThis, pGstStream); 1921 AssertRC(rc); 1922 1923 pGstStream = NULL; 1924 } 1856 1925 } 1857 1926 … … 1872 1941 rc = rc2; 1873 1942 1874 if (RT_FAILURE(rc)) 1875 LogFlowFunc(("Failed with %Rrc\n", rc)); 1876 1943 LogFlowFuncLeaveRC(rc); 1877 1944 return rc; 1878 1945 } … … 1880 1947 static int drvAudioStreamDestroyInternalBackend(PDRVAUDIO pThis, PPDMAUDIOSTREAM pHstStream) 1881 1948 { 1882 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1883 1884 if (!pHstStream) 1885 return VINF_SUCCESS; 1886 1887 AssertPtr(pThis->pHostDrvAudio); 1949 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1950 AssertPtrReturn(pHstStream, VERR_INVALID_POINTER); 1951 1888 1952 AssertMsg(pHstStream->enmCtx == PDMAUDIOSTREAMCTX_HOST, 1889 1953 ("Stream '%s' is not a host stream and therefore has no backend\n", pHstStream->szName)); … … 1895 1959 if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_INITIALIZED) 1896 1960 { 1897 rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 1961 if (pThis->pHostDrvAudio) 1962 rc = pThis->pHostDrvAudio->pfnStreamDestroy(pThis->pHostDrvAudio, pHstStream); 1898 1963 if (RT_SUCCESS(rc)) 1899 { 1900 rc = pThis->pHostDrvAudio->pfnStreamDestroy(pThis->pHostDrvAudio, pHstStream); 1901 if (RT_SUCCESS(rc)) 1902 pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_INITIALIZED; 1903 } 1904 } 1905 else 1906 rc = VINF_SUCCESS; 1964 pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_INITIALIZED; 1965 } 1907 1966 1908 1967 LogFlowFunc(("%s: Returning %Rrc\n", pHstStream->szName, rc)); … … 1912 1971 static int drvAudioStreamDestroyInternal(PDRVAUDIO pThis, PPDMAUDIOSTREAM pStream) 1913 1972 { 1914 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1915 /* pStream is optional. */ 1916 1917 if (!pStream) 1918 return VINF_SUCCESS; 1973 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 1974 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1919 1975 1920 1976 LogFlowFunc(("%s: cRefs=%RU32\n", pStream->szName, pStream->cRefs)); 1921 1977 1922 /* Try to find out which stream is which -- both streams could be destroyed (NULL) 1923 * already, so do some additional checking here. */ 1924 PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream); 1925 PPDMAUDIOSTREAM pGstStream = pHstStream ? pHstStream->pPair : pStream; 1926 1927 if ( ( pHstStream 1928 && pHstStream->cRefs > 1) 1929 || ( pGstStream 1930 && pGstStream->cRefs > 1) 1931 ) 1932 { 1978 if (pStream->cRefs > 1) 1933 1979 return VERR_WRONG_ORDER; 1934 }1935 1980 1936 1981 int rc = VINF_SUCCESS; 1937 1982 1938 if (pGstStream) 1939 { 1940 AssertMsg(pGstStream->enmCtx == PDMAUDIOSTREAMCTX_GUEST, 1941 ("Stream '%s' is not a guest stream\n", pGstStream->szName)); 1942 1943 rc = drvAudioStreamControlInternal(pThis, pGstStream, PDMAUDIOSTREAMCMD_DISABLE); 1944 } 1945 1946 if (RT_SUCCESS(rc)) 1947 rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 1948 1949 if (RT_SUCCESS(rc)) 1950 { 1951 /* Unlink from pair. */ 1952 if (pStream->pPair) 1953 { 1954 pStream->pPair->pPair = NULL; 1955 pStream->pPair = NULL; 1956 } 1957 1983 if (pStream->enmCtx == PDMAUDIOSTREAMCTX_GUEST) 1984 { 1985 if (pStream->fStatus & PDMAUDIOSTRMSTS_FLAG_INITIALIZED) 1986 { 1987 rc = drvAudioStreamControlInternal(pThis, pStream, PDMAUDIOSTREAMCMD_DISABLE); 1988 if (RT_SUCCESS(rc)) 1989 pStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_INITIALIZED; 1990 } 1991 } 1992 else if (pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST) 1993 { 1994 rc = drvAudioStreamDestroyInternalBackend(pThis, pStream); 1995 } 1996 else 1997 AssertFailedReturn(VERR_NOT_IMPLEMENTED); 1998 1999 if (RT_SUCCESS(rc)) 2000 { 1958 2001 /* Destroy mixing buffer. */ 1959 2002 AudioMixBufDestroy(&pStream->MixBuf); 1960 2003 1961 /* Remove from list. */ 1962 RTListNodeRemove(&pStream->Node); 1963 1964 RTMemFree(pStream); 1965 pStream = NULL; 1966 } 1967 1968 if (RT_FAILURE(rc)) 1969 LogFunc(("Failed with %Rrc\n", rc)); 1970 2004 if (pStream) 2005 { 2006 RTMemFree(pStream); 2007 pStream = NULL; 2008 } 2009 } 2010 2011 LogFlowFunc(("Returning %Rrc\n", rc)); 1971 2012 return rc; 1972 2013 } … … 2001 2042 LogFlowFuncEnter(); 2002 2043 2003 PPDMAUDIOSTREAM pStream, pStreamNext; 2004 RTListForEachSafe(&pThis->lstStreams, pStream, pStreamNext, PDMAUDIOSTREAM, Node) 2005 drvAudioStreamDestroyInternal(pThis, pStream); 2044 /* Just destroy the host stream on the backend side. 2045 * The rest will either be destructed by the device emulation or 2046 * in drvAudioDestruct(). */ 2047 PPDMAUDIOSTREAM pStream; 2048 RTListForEach(&pThis->lstHstStreams, pStream, PDMAUDIOSTREAM, Node) 2049 drvAudioStreamDestroyInternalBackend(pThis, pStream); 2006 2050 2007 2051 /* … … 2047 2091 pThis->IAudioConnector.pfnStreamIterate = drvAudioStreamIterate; 2048 2092 pThis->IAudioConnector.pfnStreamGetStatus = drvAudioStreamGetStatus; 2093 pThis->IAudioConnector.pfnStreamSetVolume = drvAudioStreamSetVolume; 2049 2094 pThis->IAudioConnector.pfnStreamPlay = drvAudioStreamPlay; 2050 2095 #ifdef VBOX_WITH_AUDIO_CALLBACKS … … 2105 2150 * do this in drvAudioPowerOff() instead. 2106 2151 */ 2107 PPDMAUDIOSTREAM pStream, pStreamNext;2108 RTListForEachSafe(&pThis->lstStreams, pStream, pStreamNext, PDMAUDIOSTREAM, Node)2109 drvAudioStreamDestroyInternal(pThis, pStream);2110 2152 2111 2153 /* Sanity. */ 2112 Assert(RTListIsEmpty(&pThis->lstStreams)); 2154 Assert(RTListIsEmpty(&pThis->lstHstStreams)); 2155 Assert(RTListIsEmpty(&pThis->lstGstStreams)); 2113 2156 2114 2157 #ifdef VBOX_WITH_AUDIO_CALLBACKS -
trunk/src/VBox/Devices/Audio/DrvAudio.h
r61168 r61386 90 90 /** Pointer to audio driver below us. */ 91 91 PPDMIHOSTAUDIO pHostDrvAudio; 92 /** List of input/output audio streams. */ 93 RTLISTANCHOR lstStreams; 92 /** List of host input/output audio streams. */ 93 RTLISTANCHOR lstHstStreams; 94 /** List of guest input/output audio streams. */ 95 RTLISTANCHOR lstGstStreams; 94 96 /** Max. number of free input streams. 95 97 * UINT32_MAX for unlimited streams. */ -
trunk/src/VBox/Devices/Audio/DrvHostPulseAudio.cpp
r61320 r61386 169 169 static void paSignalWaiter(PDRVHOSTPULSEAUDIO pThis) 170 170 { 171 if (!pThis) 172 return; 173 171 174 pThis->fLoopWait = true; 172 175 pa_threaded_mainloop_signal(pThis->pMainLoop, 0); … … 1143 1146 pa_stream_unref(pStrm->pPAStream); 1144 1147 1148 pStrm->pPAStream = NULL; 1149 1145 1150 pa_threaded_mainloop_unlock(pThis->pMainLoop); 1146 1147 pStrm->pPAStream = NULL;1148 1151 } 1149 1152 … … 1175 1178 pa_stream_unref(pStrm->pPAStream); 1176 1179 1180 pStrm->pPAStream = NULL; 1181 1177 1182 pa_threaded_mainloop_unlock(pThis->pMainLoop); 1178 1179 pStrm->pPAStream = NULL;1180 1183 } 1181 1184 … … 1236 1239 { 1237 1240 rc = paWaitFor(pThis, pa_stream_trigger(pStrm->pPAStream, paStreamCbSuccess, pStrm)); 1238 if (RT_ LIKELY(RT_SUCCESS(rc)))1241 if (RT_SUCCESS(rc)) 1239 1242 pStrm->pDrainOp = pa_stream_drain(pStrm->pPAStream, paStreamCbDrain, pStrm); 1240 1243 } … … 1355 1358 if (pCfg->enmDir == PDMAUDIODIR_IN) 1356 1359 rc = paCreateStreamIn(pInterface, pStream, pCfg, pcSamples); 1360 else if (pStream->enmDir == PDMAUDIODIR_OUT) 1361 rc = paCreateStreamOut(pInterface, pStream, pCfg, pcSamples); 1357 1362 else 1358 rc = paCreateStreamOut(pInterface, pStream, pCfg, pcSamples);1363 AssertFailedReturn(VERR_NOT_IMPLEMENTED); 1359 1364 1360 1365 LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc)); … … 1366 1371 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1367 1372 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1373 1374 LogFlowFunc(("%s\n", pStream->szName)); 1368 1375 1369 1376 int rc; 1370 1377 if (pStream->enmDir == PDMAUDIODIR_IN) 1371 1378 rc = paDestroyStreamIn(pInterface, pStream); 1379 else if (pStream->enmDir == PDMAUDIODIR_OUT) 1380 rc = paDestroyStreamOut(pInterface, pStream); 1372 1381 else 1373 rc = paDestroyStreamOut(pInterface, pStream); 1374 1382 AssertFailedReturn(VERR_NOT_IMPLEMENTED); 1383 1384 LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc)); 1375 1385 return rc; 1376 1386 } … … 1387 1397 if (pStream->enmDir == PDMAUDIODIR_IN) 1388 1398 rc = paControlStreamIn(pInterface, pStream, enmStreamCmd); 1399 else if (pStream->enmDir == PDMAUDIODIR_OUT) 1400 rc = paControlStreamOut(pInterface, pStream, enmStreamCmd); 1389 1401 else 1390 rc = paControlStreamOut(pInterface, pStream, enmStreamCmd); 1391 1402 AssertFailedReturn(VERR_NOT_IMPLEMENTED); 1403 1404 LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc)); 1392 1405 return rc; 1393 1406 }
Note:
See TracChangeset
for help on using the changeset viewer.