Index: /trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudio.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudio.cpp	(revision 88466)
+++ /trunk/src/VBox/Devices/Audio/DrvHostAudioPulseAudio.cpp	(revision 88467)
@@ -36,4 +36,10 @@
 
 #include <pulse/pulseaudio.h>
+#ifndef PA_STREAM_NOFLAGS
+# define PA_STREAM_NOFLAGS  (pa_context_flags_t)0x0000U /* since 0.9.19 */
+#endif
+#ifndef PA_CONTEXT_NOFLAGS
+# define PA_CONTEXT_NOFLAGS (pa_context_flags_t)0x0000U /* since 0.9.19 */
+#endif
 
 #include "VBoxDD.h"
@@ -43,13 +49,7 @@
 *   Defines                                                                                                                      *
 *********************************************************************************************************************************/
-#define VBOX_PULSEAUDIO_MAX_LOG_REL_ERRORS 32 /** @todo Make this configurable thru driver options. */
-
-#ifndef PA_STREAM_NOFLAGS
-# define PA_STREAM_NOFLAGS (pa_context_flags_t)0x0000U /* since 0.9.19 */
-#endif
-
-#ifndef PA_CONTEXT_NOFLAGS
-# define PA_CONTEXT_NOFLAGS (pa_context_flags_t)0x0000U /* since 0.9.19 */
-#endif
+/** Max number of errors reported by drvHostAudioPaError per instance.
+ * @todo Make this configurable thru driver config. */
+#define VBOX_PULSEAUDIO_MAX_LOG_REL_ERRORS  64
 
 /** No flags specified. */
@@ -57,8 +57,4 @@
 /** (Release) log found devices. */
 #define PULSEAUDIOENUMCBFLAGS_LOG           RT_BIT(0)
-
-/** Makes DRVHOSTPULSEAUDIO out of PDMIHOSTAUDIO. */
-#define PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface) \
-    ( (PDRVHOSTPULSEAUDIO)((uintptr_t)pInterface - RT_UOFFSETOF(DRVHOSTPULSEAUDIO, IHostAudio)) )
 
 
@@ -197,6 +193,8 @@
     AssertPtrReturn(szMsg, VERR_INVALID_POINTER);
 
-    if (pThis->cLogErrors++ < VBOX_PULSEAUDIO_MAX_LOG_REL_ERRORS)
-    {
+    if (   pThis->cLogErrors < VBOX_PULSEAUDIO_MAX_LOG_REL_ERRORS
+        && LogRelIs2Enabled())
+    {
+        pThis->cLogErrors++;
         int rc2 = pa_context_errno(pThis->pContext);
         LogRel2(("PulseAudio: %s: %s\n", szMsg, pa_strerror(rc2)));
@@ -523,7 +521,6 @@
 static DECLCALLBACK(int) drvHostAudioPaHA_GetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg)
 {
-    AssertPtrReturn(pInterface,  VERR_INVALID_POINTER);
+    PDRVHOSTPULSEAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio);
     AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER);
-    PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
 
     return drvHostAudioPaEnumerate(pThis, pBackendCfg, PULSEAUDIOENUMCBFLAGS_LOG /* fEnum */);
@@ -937,11 +934,10 @@
                                                        PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
 {
-    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
-    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
-    AssertPtrReturn(pCfgReq,    VERR_INVALID_POINTER);
-    AssertPtrReturn(pCfgAcq,    VERR_INVALID_POINTER);
-
-    PDRVHOSTPULSEAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
+    PDRVHOSTPULSEAUDIO pThis     = RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio);
     PPULSEAUDIOSTREAM  pStreamPA = (PPULSEAUDIOSTREAM)pStream;
+    AssertPtrReturn(pStreamPA, VERR_INVALID_POINTER);
+    AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER);
+    AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER);
+
 
     int rc;
@@ -969,9 +965,7 @@
 static DECLCALLBACK(int) drvHostAudioPaHA_StreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
 {
-    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
-    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
-
-    PDRVHOSTPULSEAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
+    PDRVHOSTPULSEAUDIO pThis     = RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio);
     PPULSEAUDIOSTREAM  pStreamPA = (PPULSEAUDIOSTREAM)pStream;
+    AssertPtrReturn(pStreamPA, VERR_INVALID_POINTER);
 
     if (pStreamPA->pStream)
@@ -1129,9 +1123,7 @@
                                                         PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
 {
-    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
-    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
-
-    PDRVHOSTPULSEAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
+    PDRVHOSTPULSEAUDIO pThis     = RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio);
     PPULSEAUDIOSTREAM  pStreamPA = (PPULSEAUDIOSTREAM)pStream;
+    AssertPtrReturn(pStreamPA, VERR_INVALID_POINTER);
 
     if (!pStreamPA->pCfg) /* Not (yet) configured? Skip. */
@@ -1191,8 +1183,6 @@
 static DECLCALLBACK(uint32_t) drvHostAudioPaHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
 {
-    PDRVHOSTPULSEAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
-    PPULSEAUDIOSTREAM  pStreamPA = (PPULSEAUDIOSTREAM)pStream;
-
-    return drvHostAudioPaStreamGetAvailable(pThis, pStreamPA);
+    return drvHostAudioPaStreamGetAvailable(RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio),
+                                            (PPULSEAUDIOSTREAM)pStream);
 }
 
@@ -1203,8 +1193,6 @@
 static DECLCALLBACK(uint32_t) drvHostAudioPaHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
 {
-    PDRVHOSTPULSEAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
-    PPULSEAUDIOSTREAM  pStreamPA = (PPULSEAUDIOSTREAM)pStream;
-
-    return drvHostAudioPaStreamGetAvailable(pThis, pStreamPA);
+    return drvHostAudioPaStreamGetAvailable(RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio),
+                                            (PPULSEAUDIOSTREAM)pStream);
 }
 
@@ -1215,12 +1203,9 @@
 static DECLCALLBACK(PDMAUDIOSTREAMSTS) drvHostAudioPaHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
 {
-    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
+    PDRVHOSTPULSEAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio);
     RT_NOREF(pStream);
 
-    PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
-
+    /* Check PulseAudio's general status. */
     PDMAUDIOSTREAMSTS fStrmSts = PDMAUDIOSTREAMSTS_FLAGS_NONE;
-
-    /* Check PulseAudio's general status. */
     if (   pThis->pContext
         && PA_CONTEXT_IS_GOOD(pa_context_get_state(pThis->pContext)))
@@ -1235,10 +1220,9 @@
  */
 static DECLCALLBACK(int) drvHostAudioPaHA_StreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
-                                                        const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
-{
-    PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
-    AssertPtr(pThis);
-    PPULSEAUDIOSTREAM pPAStream = (PPULSEAUDIOSTREAM)pStream;
-    AssertPtrReturn(pPAStream, VERR_INVALID_POINTER);
+                                                     const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
+{
+    PDRVHOSTPULSEAUDIO pThis     = RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio);
+    PPULSEAUDIOSTREAM  pStreamPA = (PPULSEAUDIOSTREAM)pStream;
+    AssertPtrReturn(pStreamPA, VERR_INVALID_POINTER);
     AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
     AssertReturn(cbBuf, VERR_INVALID_PARAMETER);
@@ -1249,16 +1233,16 @@
 #ifdef LOG_ENABLED
     const pa_usec_t tsNowUs         = pa_rtclock_now();
-    const pa_usec_t tsDeltaPlayedUs = tsNowUs - pPAStream->tsLastReadWrittenUs;
-    pPAStream->tsLastReadWrittenUs  = tsNowUs;
+    const pa_usec_t tsDeltaPlayedUs = tsNowUs - pStreamPA->tsLastReadWrittenUs;
+    pStreamPA->tsLastReadWrittenUs  = tsNowUs;
     Log3Func(("tsDeltaPlayedMs=%RU64\n", tsDeltaPlayedUs / RT_US_1MS));
 #endif
 
     int          rc;
-    size_t const cbWriteable = pa_stream_writable_size(pPAStream->pStream);
+    size_t const cbWriteable = pa_stream_writable_size(pStreamPA->pStream);
     if (cbWriteable != (size_t)-1)
     {
         size_t cbLeft = RT_MIN(cbWriteable, cbBuf);
         Assert(cbLeft > 0 /* At this point we better have *something* to write (DrvAudio checked before calling). */);
-        if (pa_stream_write(pPAStream->pStream, pvBuf, cbLeft, NULL /*pfnFree*/, 0 /*offset*/, PA_SEEK_RELATIVE) >= 0)
+        if (pa_stream_write(pStreamPA->pStream, pvBuf, cbLeft, NULL /*pfnFree*/, 0 /*offset*/, PA_SEEK_RELATIVE) >= 0)
         {
             *pcbWritten = (uint32_t)cbLeft;
@@ -1266,8 +1250,8 @@
         }
         else
-            rc = drvHostAudioPaError(pPAStream->pDrv, "Failed to write to output stream");
+            rc = drvHostAudioPaError(pStreamPA->pDrv, "Failed to write to output stream");
     }
     else
-        rc = drvHostAudioPaError(pPAStream->pDrv, "Failed to determine output data size");
+        rc = drvHostAudioPaError(pStreamPA->pDrv, "Failed to determine output data size");
 
     pa_threaded_mainloop_unlock(pThis->pMainLoop);
@@ -1280,14 +1264,12 @@
  */
 static DECLCALLBACK(int) drvHostAudioPaHA_StreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
-                                                           void *pvBuf, uint32_t uBufSize, uint32_t *puRead)
-{
-    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
-    AssertPtrReturn(pStream,    VERR_INVALID_POINTER);
-    AssertPtrReturn(pvBuf,      VERR_INVALID_POINTER);
-    AssertReturn(uBufSize,      VERR_INVALID_PARAMETER);
-    /* pcbRead is optional. */
-
-    PDRVHOSTPULSEAUDIO pThis     = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);
+                                                        void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
+{
+    PDRVHOSTPULSEAUDIO pThis     = RT_FROM_MEMBER(pInterface, DRVHOSTPULSEAUDIO, IHostAudio);
     PPULSEAUDIOSTREAM  pStreamPA = (PPULSEAUDIOSTREAM)pStream;
+    AssertPtrReturn(pStreamPA, VERR_INVALID_POINTER);
+    AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
+    AssertReturn(cbBuf, VERR_INVALID_PARAMETER);
+    AssertPtrReturn(pcbRead, VERR_INVALID_POINTER);
 
     /* We should only call pa_stream_readable_size() once and trust the first value. */
@@ -1310,6 +1292,5 @@
     if (!cbAvail) /* No data? Bail out. */
     {
-        if (puRead)
-            *puRead = 0;
+        *pcbRead = 0;
         return VINF_SUCCESS;
     }
@@ -1317,5 +1298,5 @@
     int rc = VINF_SUCCESS;
 
-    size_t cbToRead = RT_MIN(cbAvail, uBufSize);
+    size_t cbToRead = RT_MIN(cbAvail, cbBuf);
 
     Log3Func(("cbToRead=%zu, cbAvail=%zu, offPeekBuf=%zu, cbPeekBuf=%zu\n",
@@ -1384,9 +1365,5 @@
 
     if (RT_SUCCESS(rc))
-    {
-        if (puRead)
-            *puRead = cbReadTotal;
-    }
-
+        *pcbRead = cbReadTotal;
     return rc;
 }
