Changeset 73563 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Aug 8, 2018 1:39:53 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvHostDSound.cpp
r73550 r73563 168 168 } Out; 169 169 }; 170 #ifdef LOG_ENABLED 170 171 struct 171 172 { 172 173 uint64_t tsLastTransferredMs; 173 174 } Dbg; 175 #endif 174 176 } DSOUNDSTREAM, *PDSOUNDSTREAM; 175 177 … … 249 251 static int dsoundDevicesEnumerate(PDRVHOSTDSOUND pThis, PPDMAUDIOBACKENDCFG pCfg); 250 252 253 static int dsoundStreamEnable(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, bool fEnable); 254 static void dsoundStreamReset(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS); 251 255 static void dsoundUpdateStatusInternal(PDRVHOSTDSOUND pThis); 252 256 static void dsoundUpdateStatusInternalEx(PDRVHOSTDSOUND pThis, PPDMAUDIOBACKENDCFG pCfg, uint32_t fEnum); … … 808 812 * @return IPRT status code. 809 813 * @param pThis Host audio driver instance. 810 */ 811 static int dsoundPlayTransfer(PDRVHOSTDSOUND pThis) 812 { 813 PDSOUNDSTREAM pStreamDS = pThis->pDSStrmOut; 814 815 if ( !pStreamDS 816 || !pStreamDS->fEnabled) 817 { 814 * @param pStreamDS Stream to transfer playback data for. 815 */ 816 static int dsoundPlayTransfer(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS) 817 { 818 if (!pStreamDS->fEnabled) 819 { 820 Log2Func(("Stream disabled, skipping\n")); 818 821 return VINF_SUCCESS; 819 822 } … … 855 858 if (!pStreamDS->Dbg.tsLastTransferredMs) 856 859 pStreamDS->Dbg.tsLastTransferredMs = RTTimeMilliTS(); 857 Log3Func(("tsLastTransferredMs=%RU64ms, cbAvail=%RU32, cbFree=%RU32 -> cbToTransfer=%RU32 (fDrain=%RTbool)\n", 858 RTTimeMilliTS() - pStreamDS->Dbg.tsLastTransferredMs, cbAvail, cbFree, cbToTransfer, pStreamDS->Out.fDrain)); 860 Log3Func(("offPlay=%RU32, offWrite=%RU32, tsLastTransferredMs=%RU64ms, cbAvail=%RU32, cbFree=%RU32 -> cbToTransfer=%RU32 " 861 "(fFirst=%RTbool, fDrain=%RTbool)\n", 862 offPlayCursor, offWriteCursor, RTTimeMilliTS() - pStreamDS->Dbg.tsLastTransferredMs, cbAvail, cbFree, cbToTransfer, 863 pStreamDS->Out.fFirstTransfer, pStreamDS->Out.fDrain)); 859 864 pStreamDS->Dbg.tsLastTransferredMs = RTTimeMilliTS(); 860 865 #endif … … 915 920 if (SUCCEEDED(hr)) 916 921 { 917 DSLOG(("DSound: Started playing output\n"));918 922 pStreamDS->Out.fFirstTransfer = false; 919 923 } … … 977 981 if (pStreamDS->Out.pDSB) 978 982 { 979 if (pStreamDS->fEnabled)980 {981 DSLOG(("DSound: %s playback\n", fFlush ? "Stopping" : "Pausing"));982 983 hr = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB);983 DSLOG(("DSound: Stopping playback\n")); 984 hr = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB); 985 if (FAILED(hr)) 986 { 987 hr = directSoundPlayRestore(pThis, pStreamDS->Out.pDSB); 984 988 if (FAILED(hr)) 985 { 986 hr = directSoundPlayRestore(pThis, pStreamDS->Out.pDSB); 987 if (FAILED(hr)) 988 hr = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB); 989 } 990 991 pStreamDS->fEnabled = false; 989 hr = IDirectSoundBuffer8_Stop(pStreamDS->Out.pDSB); 992 990 } 993 991 } … … 995 993 if (SUCCEEDED(hr)) 996 994 { 997 if ( fFlush 998 && pStreamDS->pCircBuf) 999 { 1000 RTCircBufReset(pStreamDS->pCircBuf); 1001 } 995 if (fFlush) 996 dsoundStreamReset(pThis, pStreamDS); 1002 997 } 1003 998 … … 1008 1003 } 1009 1004 1005 /** 1006 * Enables or disables a stream. 1007 * 1008 * @return IPRT status code. 1009 * @param pThis Host audio driver instance. 1010 * @param pStreamDS Stream to enable / disable. 1011 * @param fEnable Whether to enable or disable the stream. 1012 */ 1013 static int dsoundStreamEnable(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, bool fEnable) 1014 { 1015 RT_NOREF(pThis); 1016 1017 LogFunc(("%s %s\n", 1018 fEnable ? "Enabling" : "Disabling", 1019 pStreamDS->Cfg.enmDir == PDMAUDIODIR_IN ? "capture" : "playback")); 1020 1021 pStreamDS->fEnabled = fEnable; 1022 1023 return VINF_SUCCESS; 1024 } 1025 1010 1026 1011 1027 /** 1012 1028 * Resets the state of a DirectSound stream. 1013 1029 * 1014 * @return HRESULT1015 1030 * @param pThis Host audio driver instance. 1016 1031 * @param pStreamDS Stream to reset state for. 1017 1032 */ 1018 static HRESULT directSoundPlayReset(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS) 1019 { 1020 AssertPtrReturn(pThis, E_POINTER); 1021 AssertPtrReturn(pStreamDS, E_POINTER); 1022 1023 Assert(pStreamDS->fEnabled == false); 1024 1025 pStreamDS->fEnabled = true; 1026 /* Note: Playing back via DirectSound starts in the notification thread 1027 * once enough audio output data is available. */ 1028 1029 if (pStreamDS->Cfg.enmDir == PDMAUDIODIR_OUT) 1033 static void dsoundStreamReset(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS) 1034 { 1035 RT_NOREF(pThis); 1036 1037 LogFunc(("Resetting %s\n", 1038 pStreamDS->Cfg.enmDir == PDMAUDIODIR_IN ? "capture" : "playback")); 1039 1040 if (pStreamDS->pCircBuf) 1041 RTCircBufReset(pStreamDS->pCircBuf); 1042 1043 if (pStreamDS->Cfg.enmDir == PDMAUDIODIR_IN) 1044 { 1045 pStreamDS->In.offReadPos = 0; 1046 pStreamDS->In.cOverruns = 0; 1047 } 1048 else if (pStreamDS->Cfg.enmDir == PDMAUDIODIR_OUT) 1030 1049 { 1031 1050 pStreamDS->Out.fFirstTransfer = true; 1051 pStreamDS->Out.fDrain = false; 1032 1052 pStreamDS->Out.cUnderruns = 0; 1033 1053 … … 1038 1058 pStreamDS->Out.cbWritten = 0; 1039 1059 1060 pStreamDS->Out.offWritePos = 0; 1040 1061 pStreamDS->Out.offPlayCursorLastPending = 0; 1041 1062 pStreamDS->Out.offPlayCursorLastPlayed = 0; 1042 1063 } 1043 1044 return S_OK; 1064 else 1065 AssertFailed(); 1066 1067 #ifdef LOG_ENABLED 1068 pStreamDS->Dbg.tsLastTransferredMs = 0; 1069 #endif 1045 1070 } 1046 1071 … … 1061 1086 for (unsigned i = 0; i < DRV_DSOUND_RESTORE_ATTEMPTS_MAX; i++) 1062 1087 { 1088 DSLOG(("DSound: Starting playback\n")); 1063 1089 hr = IDirectSoundBuffer8_Play(pStreamDS->Out.pDSB, 0, 0, fFlags); 1064 1090 if ( SUCCEEDED(hr) … … 1158 1184 * @return IPRT status code. 1159 1185 * @param pThis Host audio driver instance. 1160 * /1161 static int dsoundCaptureTransfer(PDRVHOSTDSOUND pThis) 1162 { 1163 PDSOUNDSTREAM pStreamDS = pThis->pDSStrmIn; 1164 AssertPtr(pStreamDS);1186 * @param pStreamDS Stream to capture audio data for. 1187 */ 1188 static int dsoundCaptureTransfer(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS) 1189 { 1190 RT_NOREF(pThis); 1165 1191 1166 1192 LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB = pStreamDS->In.pDSCB; … … 1170 1196 HRESULT hr = IDirectSoundCaptureBuffer_GetCurrentPosition(pDSCB, NULL, &offCaptureCursor); 1171 1197 if (FAILED(hr)) 1198 { 1199 AssertFailed(); 1172 1200 return VERR_ACCESS_DENIED; /** @todo Find a better rc. */ 1201 } 1173 1202 1174 1203 DWORD cbUsed = dsoundRingDistance(offCaptureCursor, pStreamDS->In.offReadPos, pStreamDS->cbBufSize); … … 1473 1502 if (pStreamDS->In.pDSCB) 1474 1503 { 1475 if (pStreamDS->fEnabled) 1476 { 1477 DSLOG(("DSound: Stopping capture\n")); 1478 1479 hr = IDirectSoundCaptureBuffer_Stop(pStreamDS->In.pDSCB); 1480 if (SUCCEEDED(hr)) 1481 pStreamDS->fEnabled = false; 1482 } 1504 DSLOG(("DSound: Stopping capture\n")); 1505 hr = IDirectSoundCaptureBuffer_Stop(pStreamDS->In.pDSCB); 1483 1506 } 1484 1507 1485 1508 if (SUCCEEDED(hr)) 1486 1509 { 1487 if ( fFlush 1488 && pStreamDS->pCircBuf) 1489 { 1490 RTCircBufReset(pStreamDS->pCircBuf); 1491 } 1510 if (fFlush) 1511 dsoundStreamReset(pThis, pStreamDS); 1492 1512 } 1493 1513 … … 1503 1523 AssertPtrReturn(pStreamDS, E_POINTER); 1504 1524 1505 Assert(pStreamDS->fEnabled == false);1506 1507 1525 HRESULT hr; 1508 if (pStreamDS->In.pDSCB != NULL)1526 if (pStreamDS->In.pDSCB) 1509 1527 { 1510 1528 DWORD dwStatus; … … 1526 1544 DSLOG(("DSound: Starting to capture\n")); 1527 1545 hr = IDirectSoundCaptureBuffer8_Start(pStreamDS->In.pDSCB, fFlags); 1528 if (SUCCEEDED(hr)) 1529 { 1530 pStreamDS->fEnabled = true; 1531 1532 pStreamDS->In.offReadPos = 0; 1533 pStreamDS->In.cOverruns = 0; 1534 } 1535 else 1546 if (FAILED(hr)) 1536 1547 DSLOGREL(("DSound: Starting to capture failed with %Rhrc\n", hr)); 1537 1548 } … … 1753 1764 LogFlowFunc(("pStreamDS=%p, pCfgReq=%p\n", pStreamDS, pCfgReq)); 1754 1765 1755 pStreamDS->cbBufSize = 0;1756 1757 pStreamDS->Out.pDSB = NULL;1758 pStreamDS->Out.offWritePos = 0;1759 pStreamDS->Out.offPlayCursorLastPlayed = 0;1760 pStreamDS->Out.offPlayCursorLastPending = 0;1761 pStreamDS->Out.cbWritten = 0;1762 pStreamDS->Out.cbTransferred = 0;1763 pStreamDS->Out.fFirstTransfer = true;1764 pStreamDS->Out.fDrain = false;1765 pStreamDS->Out.cbLastTransferred = 0;1766 pStreamDS->Out.tsLastTransferred = 0;1767 1768 1766 int rc = VINF_SUCCESS; 1769 1767 1770 1768 /* Try to open playback in case the device is already there. */ 1771 1769 HRESULT hr = directSoundPlayOpen(pThis, pStreamDS, pCfgReq, pCfgAcq); 1772 if (FAILED(hr)) 1770 if (SUCCEEDED(hr)) 1771 { 1772 rc = DrvAudioHlpStreamCfgCopy(&pStreamDS->Cfg, pCfgAcq); 1773 if (RT_SUCCESS(rc)) 1774 dsoundStreamReset(pThis, pStreamDS); 1775 } 1776 else 1773 1777 rc = VERR_GENERAL_FAILURE; /** @todo Fudge! */ 1774 1778 … … 1788 1792 case PDMAUDIOSTREAMCMD_ENABLE: 1789 1793 { 1790 hr = directSoundPlayReset(pThis, pStreamDS); 1791 if (FAILED(hr)) 1792 rc = VERR_NOT_SUPPORTED; /** @todo Fix this. */ 1794 dsoundStreamEnable(pThis, pStreamDS, true /* fEnable */); 1793 1795 break; 1794 1796 } … … 1803 1805 1804 1806 case PDMAUDIOSTREAMCMD_DISABLE: 1805 case PDMAUDIOSTREAMCMD_PAUSE:1806 {1807 hr = directSoundPlayStop(pThis, pStreamDS, enmStreamCmd == PDMAUDIOSTREAMCMD_DISABLE/* fFlush */);1807 { 1808 dsoundStreamEnable(pThis, pStreamDS, false /* fEnable */); 1809 hr = directSoundPlayStop(pThis, pStreamDS, true /* fFlush */); 1808 1810 if (FAILED(hr)) 1809 1811 rc = VERR_NOT_SUPPORTED; … … 1811 1813 } 1812 1814 1815 case PDMAUDIOSTREAMCMD_PAUSE: 1816 { 1817 hr = directSoundPlayStop(pThis, pStreamDS, false /* fFlush */); 1818 if (FAILED(hr)) 1819 rc = VERR_NOT_SUPPORTED; 1820 break; 1821 } 1822 1813 1823 case PDMAUDIOSTREAMCMD_DRAIN: 1814 1824 { 1815 1825 /* Make sure we transferred everything. */ 1826 pStreamDS->fEnabled = true; 1816 1827 pStreamDS->Out.fDrain = true; 1817 rc = dsoundPlayTransfer(pThis );1828 rc = dsoundPlayTransfer(pThis, pStreamDS); 1818 1829 if ( RT_SUCCESS(rc) 1819 1830 && pStreamDS->Out.fFirstTransfer) … … 1890 1901 pStreamDS->Out.cbWritten += cbWrittenTotal; 1891 1902 1892 rc = dsoundPlayTransfer(pThis );1903 rc = dsoundPlayTransfer(pThis, pStreamDS); 1893 1904 AssertRC(rc); 1894 1905 … … 1927 1938 pStreamDS, pCfgReq, DrvAudioHlpRecSrcToStr(pCfgReq->DestSource.Source))); 1928 1939 1929 /* Init the stream structure and save relevant information to it. */1930 pStreamDS->cbBufSize = 0;1931 1932 pStreamDS->In.pDSCB = NULL;1933 pStreamDS->In.offReadPos = 0;1934 pStreamDS->In.cOverruns = 0;1935 1936 1940 int rc = VINF_SUCCESS; 1937 1941 1938 1942 /* Try to open capture in case the device is already there. */ 1939 1943 HRESULT hr = directSoundCaptureOpen(pThis, pStreamDS, pCfgReq, pCfgAcq); 1940 if (FAILED(hr)) 1944 if (SUCCEEDED(hr)) 1945 { 1946 rc = DrvAudioHlpStreamCfgCopy(&pStreamDS->Cfg, pCfgAcq); 1947 if (RT_SUCCESS(rc)) 1948 dsoundStreamReset(pThis, pStreamDS); 1949 } 1950 else 1941 1951 rc = VERR_GENERAL_FAILURE; /** @todo Fudge! */ 1942 1952 … … 1954 1964 { 1955 1965 case PDMAUDIOSTREAMCMD_ENABLE: 1966 dsoundStreamEnable(pThis, pStreamDS, true /* fEnable */); 1967 RT_FALL_THROUGH(); 1956 1968 case PDMAUDIOSTREAMCMD_RESUME: 1957 1969 { … … 1984 1996 1985 1997 case PDMAUDIOSTREAMCMD_DISABLE: 1998 dsoundStreamEnable(pThis, pStreamDS, false /* fEnable */); 1999 RT_FALL_THROUGH(); 1986 2000 case PDMAUDIOSTREAMCMD_PAUSE: 1987 2001 { 1988 AssertPtr(pThis->pDSC);1989 1990 2002 directSoundCaptureStop(pThis, pStreamDS, 1991 2003 enmStreamCmd == PDMAUDIOSTREAMCMD_DISABLE /* fFlush */); … … 2331 2343 2332 2344 PDMAUDIOSTREAMSTS strmSts = PDMAUDIOSTREAMSTS_FLAG_INITIALIZED; 2333 if (pStreamDS->Cfg.enmDir == PDMAUDIODIR_IN) 2334 { 2335 if (pStreamDS->fEnabled) 2336 strmSts |= PDMAUDIOSTREAMSTS_FLAG_ENABLED; 2337 } 2338 else 2339 { 2340 if (pStreamDS->fEnabled) 2341 strmSts |= PDMAUDIOSTREAMSTS_FLAG_ENABLED; 2342 } 2345 2346 if (pStreamDS->fEnabled) 2347 strmSts |= PDMAUDIOSTREAMSTS_FLAG_ENABLED; 2343 2348 2344 2349 return strmSts; … … 2357 2362 2358 2363 if (pStreamDS->Cfg.enmDir == PDMAUDIODIR_IN) 2359 return dsoundCaptureTransfer(pThis );2364 return dsoundCaptureTransfer(pThis, pStreamDS); 2360 2365 2361 2366 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.