Changeset 68597 in vbox
- Timestamp:
- Sep 1, 2017 11:40:56 AM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 117820
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvHostDSound.cpp
r68272 r68597 82 82 typedef HRESULT WINAPI FNDIRECTSOUNDCAPTUREENUMERATEW(LPDSENUMCALLBACKW pDSEnumCallback, PVOID pContext); 83 83 typedef FNDIRECTSOUNDCAPTUREENUMERATEW *PFNDIRECTSOUNDCAPTUREENUMERATEW; 84 typedef HRESULT WINAPI FNDIRECTSOUNDCAPTURECREATE8(LPCGUID lpcGUID, LPDIRECTSOUNDCAPTURE8 *lplpDSC, LPUNKNOWN pUnkOuter); 85 typedef FNDIRECTSOUNDCAPTURECREATE8 *PFNDIRECTSOUNDCAPTURECREATE8; 84 86 85 87 #ifdef VBOX_WITH_AUDIO_DEVICE_CALLBACKS … … 110 112 /** Buffer alignment. */ 111 113 uint8_t uAlign; 114 /** Whether this stream is in an enable state on the DirectSound side. */ 115 bool fEnabled; 112 116 union 113 117 { 114 118 struct 115 119 { 116 LPDIRECTSOUNDCAPTURE8 pDSC;117 120 LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB; 118 121 DWORD offCaptureBufRead; 119 122 DWORD cbCaptureBuf; 120 123 HRESULT hrLastCapture; 121 bool fEnabled;122 124 } In; 123 125 struct 124 126 { 125 LPDIRECTSOUND8 pDS; /** @todo Move this out of this structure! Not required per-stream (e.g. for multi-channel). */126 127 LPDIRECTSOUNDBUFFER8 pDSB; 127 128 DWORD offPlayWritePos; 128 129 DWORD cbPlayBuf; 129 bool fEnabled;130 130 bool fRestartPlayback; 131 131 } Out; … … 136 136 { 137 137 /** Pointer to the driver instance structure. */ 138 PPDMDRVINS pDrvIns;138 PPDMDRVINS pDrvIns; 139 139 /** Our audio host audio interface. */ 140 PDMIHOSTAUDIO IHostAudio;140 PDMIHOSTAUDIO IHostAudio; 141 141 /** List of found host input devices. */ 142 RTLISTANCHOR lstDevInput;142 RTLISTANCHOR lstDevInput; 143 143 /** List of found host output devices. */ 144 RTLISTANCHOR lstDevOutput;144 RTLISTANCHOR lstDevOutput; 145 145 /** DirectSound configuration options. */ 146 DSOUNDHOSTCFG cfg;146 DSOUNDHOSTCFG cfg; 147 147 /** Whether this backend supports any audio input. */ 148 bool fEnabledIn;148 bool fEnabledIn; 149 149 /** Whether this backend supports any audio output. */ 150 bool fEnabledOut; 150 bool fEnabledOut; 151 /** The Direct Sound playback interface. */ 152 LPDIRECTSOUND8 pDS; 153 /** The Direct Sound capturing interface. */ 154 LPDIRECTSOUNDCAPTURE8 pDSC; 151 155 #ifdef VBOX_WITH_AUDIO_DEVICE_CALLBACKS 152 156 /** Pointer to the audio connector interface of the driver/device above us. */ 153 PPDMIAUDIOCONNECTOR pUpIAudioConnector;157 PPDMIAUDIOCONNECTOR pUpIAudioConnector; 154 158 /** Stopped indicator. */ 155 bool fStopped;159 bool fStopped; 156 160 /** Shutdown indicator. */ 157 bool fShutdown;161 bool fShutdown; 158 162 /** Notification thread. */ 159 RTTHREAD Thread;163 RTTHREAD Thread; 160 164 /** Array of events to wait for in notification thread. */ 161 HANDLE aEvents[VBOX_DSOUND_MAX_EVENTS];165 HANDLE aEvents[VBOX_DSOUND_MAX_EVENTS]; 162 166 /** Number of events to wait for in notification thread. 163 167 * Must not exceed VBOX_DSOUND_MAX_EVENTS. */ 164 uint8_t cEvents;168 uint8_t cEvents; 165 169 /** Pointer to the input stream. */ 166 PDSOUNDSTREAM pDSStrmIn;170 PDSOUNDSTREAM pDSStrmIn; 167 171 /** Pointer to the output stream. */ 168 PDSOUNDSTREAM pDSStrmOut;172 PDSOUNDSTREAM pDSStrmOut; 169 173 #endif 170 174 } DRVHOSTDSOUND, *PDRVHOSTDSOUND; … … 207 211 static int dsoundNotifyThread(PDRVHOSTDSOUND pThis, bool fShutdown); 208 212 #endif 209 213 static void dsoundUpdateStatusInternal(PDRVHOSTDSOUND pThis); 214 static void dsoundUpdateStatusInternalEx(PDRVHOSTDSOUND pThis, PPDMAUDIOBACKENDCFG pCfg, uint32_t fEnum); 210 215 211 216 … … 332 337 AssertPtrReturnVoid(pThis); 333 338 334 PDSOUNDDEV pDev; 335 while (!RTListIsEmpty(&pThis->lstDevInput)) 336 { 337 pDev = RTListGetFirst(&pThis->lstDevInput, DSOUNDDEV, Node); 339 PDSOUNDDEV pDev, pDevNext; 340 RTListForEachSafe(&pThis->lstDevInput, pDev, pDevNext, DSOUNDDEV, Node) 338 341 dsoundDeviceRemove(pDev); 339 } 340 341 while (!RTListIsEmpty(&pThis->lstDevOutput)) 342 { 343 pDev = RTListGetFirst(&pThis->lstDevOutput, DSOUNDDEV, Node); 342 343 Assert(RTListIsEmpty(&pThis->lstDevInput)); 344 345 RTListForEachSafe(&pThis->lstDevOutput, pDev, pDevNext, DSOUNDDEV, Node) 344 346 dsoundDeviceRemove(pDev); 345 } 347 348 Assert(RTListIsEmpty(&pThis->lstDevOutput)); 346 349 } 347 350 … … 457 460 */ 458 461 459 static void directSoundPlayInterfaceRelease(PDSOUNDSTREAM pStreamDS) 460 { 461 if (pStreamDS->Out.pDS) 462 { 463 IDirectSound8_Release(pStreamDS->Out.pDS); 464 pStreamDS->Out.pDS = NULL; 465 } 466 } 467 468 469 static HRESULT directSoundPlayInterfaceCreate(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS) 470 { 471 AssertPtrReturn(pThis, E_POINTER); 472 AssertPtrReturn(pStreamDS, E_POINTER); 473 474 if (pStreamDS->Out.pDS != NULL) 475 { 476 DSLOG(("DSound: DirectSound instance already exists\n")); 462 static void directSoundPlayInterfaceDestroy(PDRVHOSTDSOUND pThis) 463 { 464 if (pThis->pDS) 465 { 466 LogFlowFuncEnter(); 467 468 IDirectSound8_Release(pThis->pDS); 469 pThis->pDS = NULL; 470 } 471 } 472 473 474 static HRESULT directSoundPlayInterfaceCreate(PDRVHOSTDSOUND pThis) 475 { 476 if (pThis->pDS != NULL) 477 477 return S_OK; 478 } 478 479 LogFlowFuncEnter(); 479 480 480 481 HRESULT hr = CoCreateInstance(CLSID_DirectSound8, NULL, CLSCTX_ALL, 481 IID_IDirectSound8, (void **)&p StreamDS->Out.pDS);482 IID_IDirectSound8, (void **)&pThis->pDS); 482 483 if (FAILED(hr)) 483 484 { … … 486 487 else 487 488 { 488 hr = IDirectSound8_Initialize(p StreamDS->Out.pDS, pThis->cfg.pGuidPlay);489 hr = IDirectSound8_Initialize(pThis->pDS, pThis->cfg.pGuidPlay); 489 490 if (SUCCEEDED(hr)) 490 491 { 491 492 HWND hWnd = GetDesktopWindow(); 492 hr = IDirectSound8_SetCooperativeLevel(p StreamDS->Out.pDS, hWnd, DSSCL_PRIORITY);493 hr = IDirectSound8_SetCooperativeLevel(pThis->pDS, hWnd, DSSCL_PRIORITY); 493 494 if (FAILED(hr)) 494 495 DSLOGREL(("DSound: Setting cooperative level for window %p failed with %Rhrc\n", hWnd, hr)); … … 502 503 DSLOGREL(("DSound: DirectSound playback initialization failed with %Rhrc\n", hr)); 503 504 504 directSoundPlayInterfaceRelease(pStreamDS); 505 } 506 } 507 505 directSoundPlayInterfaceDestroy(pThis); 506 } 507 } 508 509 LogFlowFunc(("Returning %Rhrc\n", hr)); 508 510 return hr; 509 511 } … … 542 544 pStreamDS->Out.pDSB = NULL; 543 545 } 544 else 545 DSLOGREL(("DSound: Stop playback stream %p when closing %Rhrc\n", pStreamDS, hr)); 546 } 547 548 if (SUCCEEDED(hr)) 549 directSoundPlayInterfaceRelease(pStreamDS); 546 } 547 548 if (FAILED(hr)) 549 DSLOGREL(("DSound: Stopping playback stream %p failed with %Rhrc\n", pStreamDS, hr)); 550 550 551 551 return hr; … … 580 580 return E_INVALIDARG; 581 581 582 HRESULT hr = directSoundPlayInterfaceCreate(pThis, pStreamDS); 582 directSoundPlayInterfaceDestroy(pThis); 583 584 dsoundUpdateStatusInternal(pThis); 585 586 HRESULT hr = directSoundPlayInterfaceCreate(pThis); 583 587 if (FAILED(hr)) 584 588 return hr; … … 610 614 bd.dwBufferBytes = pThis->cfg.cbBufferOut; 611 615 612 hr = IDirectSound8_CreateSoundBuffer(p StreamDS->Out.pDS, &bd, &pDSB, NULL);616 hr = IDirectSound8_CreateSoundBuffer(pThis->pDS, &bd, &pDSB, NULL); 613 617 if (FAILED(hr)) 614 618 { … … 812 816 AssertPtrReturn(pStreamDS, E_POINTER); 813 817 814 HRESULT hr; 815 816 if (pStreamDS->Out.pDSB != NULL) 817 { 818 DSLOG(("DSound: Stopping playback\n")); 819 820 HRESULT hr2 = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB); 821 if (FAILED(hr2)) 822 { 823 hr2 = directSoundPlayRestore(pThis, pStreamDS->Out.pDSB); 824 if (FAILED(hr2)) 825 hr2 = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB); 826 } 827 828 if (FAILED(hr2)) 829 DSLOG(("DSound: Stopping playback failed with %Rhrc\n", hr2)); 830 831 hr = S_OK; /* Always report success here. */ 832 } 833 else 834 hr = E_UNEXPECTED; 835 836 if (SUCCEEDED(hr)) 837 { 838 pStreamDS->Out.fEnabled = false; 839 } 840 else 818 HRESULT hr = S_OK; 819 820 if (pStreamDS->Out.pDSB) 821 { 822 if (pStreamDS->fEnabled) 823 { 824 DSLOG(("DSound: Stopping playback\n")); 825 826 hr = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB); 827 if (FAILED(hr)) 828 { 829 hr = directSoundPlayRestore(pThis, pStreamDS->Out.pDSB); 830 if (FAILED(hr)) 831 hr = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB); 832 } 833 834 if (SUCCEEDED(hr)) 835 pStreamDS->fEnabled = false; 836 } 837 } 838 839 if (FAILED(hr)) 841 840 DSLOGREL(("DSound: Stopping playback failed with %Rhrc\n", hr)); 842 841 … … 866 865 867 866 pStreamDS->Out.fRestartPlayback = true; 868 pStreamDS-> Out.fEnabled= true;867 pStreamDS->fEnabled = true; 869 868 870 869 DSLOG(("DSound: Playback started\n")); … … 962 961 } 963 962 964 965 static void directSoundCaptureInterfaceRelease(PDSOUNDSTREAM pStreamDS) 966 { 967 if (pStreamDS->In.pDSC) 963 /** 964 * Destroys the DirectSound capturing interface. 965 * 966 * @return IPRT status code. 967 * @param pThis Driver instance to destroy capturing interface for. 968 */ 969 static void directSoundCaptureInterfaceDestroy(PDRVHOSTDSOUND pThis) 970 { 971 if (pThis->pDSC) 968 972 { 969 973 LogFlowFuncEnter(); 970 IDirectSoundCapture_Release(pStreamDS->In.pDSC); 971 pStreamDS->In.pDSC = NULL; 972 } 973 } 974 975 976 static HRESULT directSoundCaptureInterfaceCreate(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, PPDMAUDIOSTREAMCFG pCfg) 974 975 IDirectSoundCapture_Release(pThis->pDSC); 976 pThis->pDSC = NULL; 977 } 978 } 979 980 /** 981 * Creates the DirectSound capturing interface. 982 * 983 * @return IPRT status code. 984 * @param pThis Driver instance to create the capturing interface for. 985 * @param pCfg Audio stream to use for creating the capturing interface. 986 */ 987 static HRESULT directSoundCaptureInterfaceCreate(PDRVHOSTDSOUND pThis, PPDMAUDIOSTREAMCFG pCfg) 977 988 { 978 989 AssertPtrReturn(pThis, E_POINTER); 979 AssertPtrReturn(pStreamDS, E_POINTER);980 990 AssertPtrReturn(pCfg, E_POINTER); 981 991 982 if (pStreamDS->In.pDSC != NULL) 983 { 984 DSLOG(("DSound: DirectSoundCapture instance already exists\n")); 992 if (pThis->pDSC) 985 993 return S_OK; 986 } 994 995 LogFlowFuncEnter(); 987 996 988 997 HRESULT hr = CoCreateInstance(CLSID_DirectSoundCapture8, NULL, CLSCTX_ALL, 989 IID_IDirectSoundCapture8, (void **)&p StreamDS->In.pDSC);998 IID_IDirectSoundCapture8, (void **)&pThis->pDSC); 990 999 if (FAILED(hr)) 991 1000 { … … 995 1004 { 996 1005 LPCGUID pGUID = dsoundCaptureSelectDevice(pThis, pCfg); 997 hr = IDirectSoundCapture_Initialize(pStreamDS->In.pDSC, pGUID); 1006 /* pGUID can be NULL when using the default device. */ 1007 1008 hr = IDirectSoundCapture_Initialize(pThis->pDSC, pGUID); 998 1009 if (FAILED(hr)) 999 1010 { … … 1003 1014 DSLOGREL(("DSound: Initializing capturing device failed with %Rhrc\n", hr)); 1004 1015 1005 directSoundCaptureInterface Release(pStreamDS);1016 directSoundCaptureInterfaceDestroy(pThis); 1006 1017 } 1007 1018 } … … 1031 1042 DSLOGREL(("DSound: Stopping capture buffer failed with %Rhrc\n", hr)); 1032 1043 } 1033 1034 if (SUCCEEDED(hr))1035 directSoundCaptureInterfaceRelease(pStreamDS);1036 1044 1037 1045 LogFlowFunc(("Returning %Rhrc\n", hr)); … … 1068 1076 return E_INVALIDARG; 1069 1077 1070 HRESULT hr = directSoundCaptureInterfaceCreate(pThis, pStreamDS, pCfgReq); 1078 directSoundCaptureInterfaceDestroy(pThis); 1079 1080 dsoundUpdateStatusInternalEx(pThis, NULL /* Cfg */, DSOUNDENUMCBFLAGS_LOG /* fEnum */); 1081 1082 HRESULT hr = directSoundCaptureInterfaceCreate(pThis, pCfgReq); 1071 1083 if (FAILED(hr)) 1072 1084 return hr; … … 1083 1095 bd.dwBufferBytes = pThis->cfg.cbBufferIn; 1084 1096 1085 hr = IDirectSoundCapture_CreateCaptureBuffer(p StreamDS->In.pDSC, &bd, &pDSCB, NULL);1097 hr = IDirectSoundCapture_CreateCaptureBuffer(pThis->pDSC, &bd, &pDSCB, NULL); 1086 1098 if (FAILED(hr)) 1087 1099 { … … 1188 1200 RT_NOREF(pThis); 1189 1201 1190 HRESULT hr ;1202 HRESULT hr = S_OK; 1191 1203 1192 1204 if (pStreamDS->In.pDSCB) 1193 1205 { 1194 DSLOG(("DSound: Stopping capture\n"));1195 1196 hr = IDirectSoundCaptureBuffer_Stop(pStreamDS->In.pDSCB);1197 if (FAILED(hr)) 1198 DSLOGREL(("DSound: Stopping capture buffer failed with %Rhrc\n", hr));1199 }1200 else1201 hr = E_UNEXPECTED; 1202 1203 if (SUCCEEDED(hr))1204 pStreamDS->In.fEnabled = false;1206 if (pStreamDS->fEnabled) 1207 { 1208 DSLOG(("DSound: Stopping capture\n")); 1209 1210 hr = IDirectSoundCaptureBuffer_Stop(pStreamDS->In.pDSCB); 1211 if (FAILED(hr)) 1212 DSLOGREL(("DSound: Stopping capture buffer failed with %Rhrc\n", hr)); 1213 1214 pStreamDS->fEnabled = false; 1215 } 1216 } 1205 1217 1206 1218 LogFlowFunc(("Returning %Rhrc\n", hr)); … … 1237 1249 DSLOG(("DSound: Starting to capture\n")); 1238 1250 hr = IDirectSoundCaptureBuffer8_Start(pStreamDS->In.pDSCB, fFlags); 1239 if (FAILED(hr)) 1251 if (SUCCEEDED(hr)) 1252 { 1253 pStreamDS->fEnabled = true; 1254 } 1255 else 1240 1256 DSLOGREL(("DSound: Starting to capture failed with %Rhrc\n", hr)); 1241 1257 } … … 1246 1262 1247 1263 if (SUCCEEDED(hr)) 1248 pStreamDS->In.fEnabled = true; 1264 1249 1265 1250 1266 LogFlowFunc(("Returning %Rhrc\n", hr)); … … 1264 1280 1265 1281 int rc = RTUtf16ToUtf8(pwszDescription, &pDev->pszName); 1266 if (RT_SUCCESS(rc)) 1282 if ( RT_SUCCESS(rc) 1283 && pGUID) 1284 { 1267 1285 memcpy(&pDev->Guid, pGUID, sizeof(GUID)); 1286 } 1268 1287 1269 1288 if (RT_SUCCESS(rc)) … … 1281 1300 if (pDev) 1282 1301 { 1283 RTStrFree(pDev->pszName); 1284 pDev->pszName = NULL; 1302 if (pDev->pszName) 1303 { 1304 RTStrFree(pDev->pszName); 1305 pDev->pszName = NULL; 1306 } 1285 1307 1286 1308 RTListNodeRemove(&pDev->Node); … … 1463 1485 LogFlowFunc(("pStreamDS=%p, pCfgReq=%p\n", pStreamDS, pCfgReq)); 1464 1486 1465 pStreamDS->Out.pDS = NULL;1466 1487 pStreamDS->Out.pDSB = NULL; 1467 1488 pStreamDS->Out.offPlayWritePos = 0; … … 1702 1723 pStreamDS->In.offCaptureBufRead = 0; 1703 1724 pStreamDS->In.cbCaptureBuf = 0; 1704 pStreamDS->In.pDSC = NULL;1705 1725 pStreamDS->In.pDSCB = NULL; 1706 1726 pStreamDS->In.hrLastCapture = S_OK; … … 2266 2286 PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream; 2267 2287 2268 if (pStreamDS-> In.fEnabled)2288 if (pStreamDS->fEnabled) 2269 2289 return UINT32_MAX; 2270 2290 … … 2286 2306 PDSOUNDSTREAM pStreamDS = (PDSOUNDSTREAM)pStream; 2287 2307 2288 if (pStreamDS-> Out.fEnabled)2308 if (pStreamDS->fEnabled) 2289 2309 { 2290 2310 DWORD cbFree; … … 2318 2338 if (pStreamDS->pCfg->enmDir == PDMAUDIODIR_IN) 2319 2339 { 2320 if (pStreamDS-> In.fEnabled)2340 if (pStreamDS->fEnabled) 2321 2341 strmSts |= PDMAUDIOSTREAMSTS_FLAG_ENABLED; 2322 2342 } 2323 2343 else 2324 2344 { 2325 if (pStreamDS-> Out.fEnabled)2345 if (pStreamDS->fEnabled) 2326 2346 strmSts |= PDMAUDIOSTREAMSTS_FLAG_ENABLED; 2327 2347 } … … 2397 2417 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns); 2398 2418 2399 HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);2419 HRESULT hr = CoInitializeEx(NULL, 0); 2400 2420 if (FAILED(hr)) 2401 2421 {
Note:
See TracChangeset
for help on using the changeset viewer.