What happens upon mmdevapi capture overrun on native?

Maarten Lankhorst m.b.lankhorst at gmail.com
Tue Mar 13 05:16:09 CDT 2012


Hey Joerg,

Op 12-03-12 11:01, Joerg-Cyril.Hoehle at t-systems.com schreef:
> Hi,
>
>>> A. mmdevapi fills the whole buffer once.
>>> B. mmdevapi continuously overwrites the circular buffer.
>>> I think A makes sense but really I don't know.
>> I suspect B
> I realized that I don't need a microphone if I can trust
> IAC_CaptureClient's pu64QPCPosition output parameter: "the value of
> the performance counter at the time that the audio endpoint device
> recorded the device position of the first audio frame in the data
> packet."
>
> Modifying the capture tests to trace that value shows that mmdevapi
> mostly implements behaviour A with a few quirks.  Please visit bug
> #30147 for details.
>
Thanks for figuring it out. winepulse v10 carries the fixed behavior,
diff with v9 attached below for completeness.

commit 9173c8dd53438eeb395ff7ac66498bdbb383474f
Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date:   Tue Mar 13 11:04:04 2012 +0100

    winepulse: v10

diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c
index af8a826..50dcd4a 100644
--- a/dlls/winepulse.drv/mmdevdrv.c
+++ b/dlls/winepulse.drv/mmdevdrv.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright 2011-2012 Maarten Lankhorst
  * Copyright 2010-2011 Maarten Lankhorst for CodeWeavers
  * Copyright 2011 Andrew Eikum for CodeWeavers
  *
@@ -574,9 +575,11 @@ static void pulse_rd_loop(ACImpl *This, size_t bytes)
         UINT32 src_len, copy, rem = This->capture_period;
         if (!(p = (ACPacket*)list_head(&This->packet_free_head))) {
             p = (ACPacket*)list_head(&This->packet_filled_head);
-
-            next = (ACPacket*)p->entry.next;
-            next->discont = 1;
+            if (!p->discont) {
+                next = (ACPacket*)p->entry.next;
+                next->discont = 1;
+            } else
+                p = (ACPacket*)list_tail(&This->packet_filled_head);
             assert(This->pad == This->bufsize_bytes);
         } else {
             assert(This->pad < This->bufsize_bytes);





More information about the wine-devel mailing list