Changeset 88467 in vbox
- Timestamp:
- Apr 12, 2021 12:06:58 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudio.cpp
r88466 r88467 36 36 37 37 #include <pulse/pulseaudio.h> 38 #ifndef PA_STREAM_NOFLAGS 39 # define PA_STREAM_NOFLAGS (pa_context_flags_t)0x0000U /* since 0.9.19 */ 40 #endif 41 #ifndef PA_CONTEXT_NOFLAGS 42 # define PA_CONTEXT_NOFLAGS (pa_context_flags_t)0x0000U /* since 0.9.19 */ 43 #endif 38 44 39 45 #include "VBoxDD.h" … … 43 49 * Defines * 44 50 *********************************************************************************************************************************/ 45 #define VBOX_PULSEAUDIO_MAX_LOG_REL_ERRORS 32 /** @todo Make this configurable thru driver options. */ 46 47 #ifndef PA_STREAM_NOFLAGS 48 # define PA_STREAM_NOFLAGS (pa_context_flags_t)0x0000U /* since 0.9.19 */ 49 #endif 50 51 #ifndef PA_CONTEXT_NOFLAGS 52 # define PA_CONTEXT_NOFLAGS (pa_context_flags_t)0x0000U /* since 0.9.19 */ 53 #endif 51 /** Max number of errors reported by drvHostAudioPaError per instance. 52 * @todo Make this configurable thru driver config. */ 53 #define VBOX_PULSEAUDIO_MAX_LOG_REL_ERRORS 64 54 54 55 55 /** No flags specified. */ … … 57 57 /** (Release) log found devices. */ 58 58 #define PULSEAUDIOENUMCBFLAGS_LOG RT_BIT(0) 59 60 /** Makes DRVHOSTPULSEAUDIO out of PDMIHOSTAUDIO. */61 #define PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface) \62 ( (PDRVHOSTPULSEAUDIO)((uintptr_t)pInterface - RT_UOFFSETOF(DRVHOSTPULSEAUDIO, IHostAudio)) )63 59 64 60 … … 197 193 AssertPtrReturn(szMsg, VERR_INVALID_POINTER); 198 194 199 if (pThis->cLogErrors++ < VBOX_PULSEAUDIO_MAX_LOG_REL_ERRORS) 200 { 195 if ( pThis->cLogErrors < VBOX_PULSEAUDIO_MAX_LOG_REL_ERRORS 196 && LogRelIs2Enabled()) 197 { 198 pThis->cLogErrors++; 201 199 int rc2 = pa_context_errno(pThis->pContext); 202 200 LogRel2(("PulseAudio: %s: %s\n", szMsg, pa_strerror(rc2))); … … 523 521 static DECLCALLBACK(int) drvHostAudioPaHA_GetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg) 524 522 { 525 AssertPtrReturn(pInterface, VERR_INVALID_POINTER);523 PDRVHOSTPULSEAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio); 526 524 AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER); 527 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);528 525 529 526 return drvHostAudioPaEnumerate(pThis, pBackendCfg, PULSEAUDIOENUMCBFLAGS_LOG /* fEnum */); … … 937 934 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 938 935 { 939 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 940 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 941 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER); 942 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 943 944 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 936 PDRVHOSTPULSEAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio); 945 937 PPULSEAUDIOSTREAM pStreamPA = (PPULSEAUDIOSTREAM)pStream; 938 AssertPtrReturn(pStreamPA, VERR_INVALID_POINTER); 939 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER); 940 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 941 946 942 947 943 int rc; … … 969 965 static DECLCALLBACK(int) drvHostAudioPaHA_StreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 970 966 { 971 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 972 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 973 974 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 967 PDRVHOSTPULSEAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio); 975 968 PPULSEAUDIOSTREAM pStreamPA = (PPULSEAUDIOSTREAM)pStream; 969 AssertPtrReturn(pStreamPA, VERR_INVALID_POINTER); 976 970 977 971 if (pStreamPA->pStream) … … 1129 1123 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 1130 1124 { 1131 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1132 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1133 1134 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 1125 PDRVHOSTPULSEAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio); 1135 1126 PPULSEAUDIOSTREAM pStreamPA = (PPULSEAUDIOSTREAM)pStream; 1127 AssertPtrReturn(pStreamPA, VERR_INVALID_POINTER); 1136 1128 1137 1129 if (!pStreamPA->pCfg) /* Not (yet) configured? Skip. */ … … 1191 1183 static DECLCALLBACK(uint32_t) drvHostAudioPaHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 1192 1184 { 1193 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 1194 PPULSEAUDIOSTREAM pStreamPA = (PPULSEAUDIOSTREAM)pStream; 1195 1196 return drvHostAudioPaStreamGetAvailable(pThis, pStreamPA); 1185 return drvHostAudioPaStreamGetAvailable(RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio), 1186 (PPULSEAUDIOSTREAM)pStream); 1197 1187 } 1198 1188 … … 1203 1193 static DECLCALLBACK(uint32_t) drvHostAudioPaHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 1204 1194 { 1205 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 1206 PPULSEAUDIOSTREAM pStreamPA = (PPULSEAUDIOSTREAM)pStream; 1207 1208 return drvHostAudioPaStreamGetAvailable(pThis, pStreamPA); 1195 return drvHostAudioPaStreamGetAvailable(RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio), 1196 (PPULSEAUDIOSTREAM)pStream); 1209 1197 } 1210 1198 … … 1215 1203 static DECLCALLBACK(PDMAUDIOSTREAMSTS) drvHostAudioPaHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 1216 1204 { 1217 AssertPtrReturn(pInterface, VERR_INVALID_POINTER);1205 PDRVHOSTPULSEAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio); 1218 1206 RT_NOREF(pStream); 1219 1207 1220 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 1221 1208 /* Check PulseAudio's general status. */ 1222 1209 PDMAUDIOSTREAMSTS fStrmSts = PDMAUDIOSTREAMSTS_FLAGS_NONE; 1223 1224 /* Check PulseAudio's general status. */1225 1210 if ( pThis->pContext 1226 1211 && PA_CONTEXT_IS_GOOD(pa_context_get_state(pThis->pContext))) … … 1235 1220 */ 1236 1221 static DECLCALLBACK(int) drvHostAudioPaHA_StreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 1237 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 1238 { 1239 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 1240 AssertPtr(pThis); 1241 PPULSEAUDIOSTREAM pPAStream = (PPULSEAUDIOSTREAM)pStream; 1242 AssertPtrReturn(pPAStream, VERR_INVALID_POINTER); 1222 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 1223 { 1224 PDRVHOSTPULSEAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio); 1225 PPULSEAUDIOSTREAM pStreamPA = (PPULSEAUDIOSTREAM)pStream; 1226 AssertPtrReturn(pStreamPA, VERR_INVALID_POINTER); 1243 1227 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); 1244 1228 AssertReturn(cbBuf, VERR_INVALID_PARAMETER); … … 1249 1233 #ifdef LOG_ENABLED 1250 1234 const pa_usec_t tsNowUs = pa_rtclock_now(); 1251 const pa_usec_t tsDeltaPlayedUs = tsNowUs - p PAStream->tsLastReadWrittenUs;1252 p PAStream->tsLastReadWrittenUs = tsNowUs;1235 const pa_usec_t tsDeltaPlayedUs = tsNowUs - pStreamPA->tsLastReadWrittenUs; 1236 pStreamPA->tsLastReadWrittenUs = tsNowUs; 1253 1237 Log3Func(("tsDeltaPlayedMs=%RU64\n", tsDeltaPlayedUs / RT_US_1MS)); 1254 1238 #endif 1255 1239 1256 1240 int rc; 1257 size_t const cbWriteable = pa_stream_writable_size(p PAStream->pStream);1241 size_t const cbWriteable = pa_stream_writable_size(pStreamPA->pStream); 1258 1242 if (cbWriteable != (size_t)-1) 1259 1243 { 1260 1244 size_t cbLeft = RT_MIN(cbWriteable, cbBuf); 1261 1245 Assert(cbLeft > 0 /* At this point we better have *something* to write (DrvAudio checked before calling). */); 1262 if (pa_stream_write(p PAStream->pStream, pvBuf, cbLeft, NULL /*pfnFree*/, 0 /*offset*/, PA_SEEK_RELATIVE) >= 0)1246 if (pa_stream_write(pStreamPA->pStream, pvBuf, cbLeft, NULL /*pfnFree*/, 0 /*offset*/, PA_SEEK_RELATIVE) >= 0) 1263 1247 { 1264 1248 *pcbWritten = (uint32_t)cbLeft; … … 1266 1250 } 1267 1251 else 1268 rc = drvHostAudioPaError(p PAStream->pDrv, "Failed to write to output stream");1252 rc = drvHostAudioPaError(pStreamPA->pDrv, "Failed to write to output stream"); 1269 1253 } 1270 1254 else 1271 rc = drvHostAudioPaError(p PAStream->pDrv, "Failed to determine output data size");1255 rc = drvHostAudioPaError(pStreamPA->pDrv, "Failed to determine output data size"); 1272 1256 1273 1257 pa_threaded_mainloop_unlock(pThis->pMainLoop); … … 1280 1264 */ 1281 1265 static DECLCALLBACK(int) drvHostAudioPaHA_StreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 1282 void *pvBuf, uint32_t uBufSize, uint32_t *puRead) 1283 { 1284 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1285 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1286 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); 1287 AssertReturn(uBufSize, VERR_INVALID_PARAMETER); 1288 /* pcbRead is optional. */ 1289 1290 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 1266 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 1267 { 1268 PDRVHOSTPULSEAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio); 1291 1269 PPULSEAUDIOSTREAM pStreamPA = (PPULSEAUDIOSTREAM)pStream; 1270 AssertPtrReturn(pStreamPA, VERR_INVALID_POINTER); 1271 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); 1272 AssertReturn(cbBuf, VERR_INVALID_PARAMETER); 1273 AssertPtrReturn(pcbRead, VERR_INVALID_POINTER); 1292 1274 1293 1275 /* We should only call pa_stream_readable_size() once and trust the first value. */ … … 1310 1292 if (!cbAvail) /* No data? Bail out. */ 1311 1293 { 1312 if (puRead) 1313 *puRead = 0; 1294 *pcbRead = 0; 1314 1295 return VINF_SUCCESS; 1315 1296 } … … 1317 1298 int rc = VINF_SUCCESS; 1318 1299 1319 size_t cbToRead = RT_MIN(cbAvail, uBufSize);1300 size_t cbToRead = RT_MIN(cbAvail, cbBuf); 1320 1301 1321 1302 Log3Func(("cbToRead=%zu, cbAvail=%zu, offPeekBuf=%zu, cbPeekBuf=%zu\n", … … 1384 1365 1385 1366 if (RT_SUCCESS(rc)) 1386 { 1387 if (puRead) 1388 *puRead = cbReadTotal; 1389 } 1390 1367 *pcbRead = cbReadTotal; 1391 1368 return rc; 1392 1369 }
Note:
See TracChangeset
for help on using the changeset viewer.