Index: pjproject/trunk/pjmedia/src/pjmedia/dsound.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/dsound.c	(revision 462)
+++ pjproject/trunk/pjmedia/src/pjmedia/dsound.c	(revision 463)
@@ -100,4 +100,5 @@
 
     void		   *buffer;		/**< Temp. frame buffer.    */
+    unsigned		    clock_rate;		/**< Clock rate.	    */
     unsigned		    samples_per_frame;	/**< Samples per frame.	    */
 
@@ -233,7 +234,9 @@
     /* Done setting up play device. */
     PJ_LOG(5,(THIS_FILE, 
-	      " DirectSound player stream initialized (clock_rate=%d, "
-	      "channel_count=%d, samples_per_frame=%d",
-	      clock_rate, channel_count, samples_per_frame));
+	      " DirectSound player \"%s\" initialized (clock_rate=%d, "
+	      "channel_count=%d, samples_per_frame=%d (%dms))",
+	      dev_info[dev_id].info.name,
+	      clock_rate, channel_count, samples_per_frame,
+	      samples_per_frame * 1000 / clock_rate));
 
     return PJ_SUCCESS;
@@ -336,7 +339,9 @@
     /* Done setting up recorder device. */
     PJ_LOG(5,(THIS_FILE, 
-	      " DirectSound capture stream initialized (clock_rate=%d, "
-	      "channel_count=%d, samples_per_frame=%d",
-	      clock_rate, channel_count, samples_per_frame));
+	      " DirectSound capture \"%s\" initialized (clock_rate=%d, "
+	      "channel_count=%d, samples_per_frame=%d (%dms))",
+	      dev_info[dev_id].info.name,
+	      clock_rate, channel_count, samples_per_frame,
+	      samples_per_frame * 1000 / clock_rate));
 
     return PJ_SUCCESS;
@@ -417,5 +422,28 @@
 
 /*
- * Player thread.
+ * Check if there are captured frames in DirectSound capture buffer.
+ */
+static unsigned dsound_captured_size(struct dsound_stream *dsound_strm)
+{
+    HRESULT hr;
+    long size_available;
+    DWORD writePos, readPos;
+
+    hr = IDirectSoundCaptureBuffer_GetCurrentPosition(dsound_strm->ds.capture.lpDsBuffer, 
+						      &writePos, &readPos);
+    if FAILED(hr)
+	return PJ_FALSE;
+
+    if (readPos < dsound_strm->dwBytePos)
+	size_available = readPos +
+		    (dsound_strm->dwDsBufferSize) - dsound_strm->dwBytePos;
+    else
+	size_available = readPos - dsound_strm->dwBytePos;
+
+    return size_available;
+}
+
+/*
+ * DirectSound capture and playback thread.
  */
 static int dsound_dev_thread(void *arg)
@@ -424,4 +452,5 @@
     HANDLE events[2];
     unsigned eventCount;
+    unsigned bytes_per_frame;
     pj_status_t status;
 
@@ -435,10 +464,12 @@
 
     /* Raise self priority */
-    SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
+    //SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
+
+    /* Calculate bytes per frame */
+    bytes_per_frame = strm->samples_per_frame * BYTES_PER_SAMPLE;
 
     /*
-     * Loop while not signalled to quit, wait for event object to be signalled
-     * by DirectSound play buffer, then request for sound data from the 
-     * application and write it to DirectSound buffer.
+     * Loop while not signalled to quit, wait for event objects to be 
+     * signalled by DirectSound capture and play buffer.
      */
     while (!strm->thread_quit_flag) {
@@ -446,7 +477,7 @@
 	DWORD rc;
 	pjmedia_dir signalled_dir;
-	struct dsound_stream *dsound_strm;
-
-	rc = WaitForMultipleObjects(eventCount, events, FALSE, 100);
+
+	rc = WaitForMultipleObjects(eventCount, events, FALSE, 
+				    100);
 	if (rc < WAIT_OBJECT_0 || rc >= WAIT_OBJECT_0+eventCount)
 	    continue;
@@ -468,4 +499,11 @@
 	if (signalled_dir == PJMEDIA_DIR_PLAYBACK) {
 	    
+	    struct dsound_stream *dsound_strm;
+
+	    /*
+	     * DirectSound has requested us to feed some frames to
+	     * playback buffer.
+	     */
+
 	    dsound_strm = &strm->play_strm;
 
@@ -474,6 +512,5 @@
 				      dsound_strm->timestamp.u32.lo,
 				      strm->buffer,
-				      strm->samples_per_frame * 
-					BYTES_PER_SAMPLE);
+				      bytes_per_frame);
 	    if (status != PJ_SUCCESS)
 		break;
@@ -483,46 +520,58 @@
 				  dsound_strm->dwBytePos,
 				  (LPBYTE)strm->buffer, 
-				  strm->samples_per_frame * BYTES_PER_SAMPLE);
+				  bytes_per_frame);
+
+	    /* Increment position. */
+	    dsound_strm->dwBytePos += bytes_per_frame;
+	    if (dsound_strm->dwBytePos >= dsound_strm->dwDsBufferSize)
+		dsound_strm->dwBytePos -= dsound_strm->dwDsBufferSize;
+	    dsound_strm->timestamp.u64 += strm->samples_per_frame;
 
 	} else {
+	    /*
+	     * DirectSound has indicated that it has some frames ready
+	     * in the capture buffer. Get as much frames as possible to
+	     * prevent overflows.
+	     */
+	    struct dsound_stream *dsound_strm;
 	    BOOL rc;
 
 	    dsound_strm = &strm->rec_strm;
 
-	    /* Capture from DirectSound buffer. */
-	    rc = AppReadDataFromBuffer(dsound_strm->ds.capture.lpDsBuffer, 
-				       dsound_strm->dwBytePos,
-				       (LPBYTE)strm->buffer, 
-				       strm->samples_per_frame * 
-					BYTES_PER_SAMPLE);
-	    
-	    if (!rc) {
-		pj_memset(strm->buffer, 0, strm->samples_per_frame * 
-					    BYTES_PER_SAMPLE);
-	    }
-
-	    /* Call callback */
-	    status = (*strm->rec_cb)(strm->user_data, 
-				     dsound_strm->timestamp.u32.lo, 
-				     strm->buffer, 
-				     strm->samples_per_frame * 
-					BYTES_PER_SAMPLE);
-
-	    /* Quit thread on error. */
-	    if (status != PJ_SUCCESS)
-		break;
-
+	    do {
+		/* Capture from DirectSound buffer. */
+		rc = AppReadDataFromBuffer(dsound_strm->ds.capture.lpDsBuffer, 
+					   dsound_strm->dwBytePos,
+					   (LPBYTE)strm->buffer, 
+					   bytes_per_frame);
+		
+		if (!rc) {
+		    pj_memset(strm->buffer, 0, bytes_per_frame);
+		}
+
+		/* Call callback */
+		status = (*strm->rec_cb)(strm->user_data, 
+					 dsound_strm->timestamp.u32.lo, 
+					 strm->buffer, 
+					 bytes_per_frame);
+
+		/* Quit thread on error. */
+		if (status != PJ_SUCCESS)
+		    goto on_error;
+
+
+		/* Increment position. */
+		dsound_strm->dwBytePos += bytes_per_frame;
+		if (dsound_strm->dwBytePos >= dsound_strm->dwDsBufferSize)
+		    dsound_strm->dwBytePos -= dsound_strm->dwDsBufferSize;
+		dsound_strm->timestamp.u64 += strm->samples_per_frame;
+
+	    } while (dsound_captured_size(dsound_strm) >= bytes_per_frame);
 	}
-
-	/* Increment position. */
-	dsound_strm->dwBytePos += strm->samples_per_frame * BYTES_PER_SAMPLE;
-	if (dsound_strm->dwBytePos >= dsound_strm->dwDsBufferSize)
-	    dsound_strm->dwBytePos -= dsound_strm->dwDsBufferSize;
-	dsound_strm->timestamp.u64 += strm->samples_per_frame;
-    }
-
-
+    }
+
+
+on_error:
     PJ_LOG(5,(THIS_FILE, "DirectSound: thread stopping.."));
-
     return 0;
 }
@@ -670,5 +719,5 @@
     strm->play_cb = play_cb;
     strm->user_data = user_data;
-
+    strm->clock_rate = clock_rate;
     strm->samples_per_frame = samples_per_frame;
     strm->buffer = pj_pool_alloc(pool, samples_per_frame * BYTES_PER_SAMPLE);
Index: pjproject/trunk/pjmedia/src/pjmedia/sound_port.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/sound_port.c	(revision 462)
+++ pjproject/trunk/pjmedia/src/pjmedia/sound_port.c	(revision 463)
@@ -117,4 +117,6 @@
 	PJ_LOG(4,(THIS_FILE, "Lost frame generated"));
 #endif
+    } else {
+	pj_memset(output, 0, size);
     }
 
