Index: pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia-audiodev/pa_dev.c
===================================================================
--- pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia-audiodev/pa_dev.c	(revision 2458)
+++ pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia-audiodev/pa_dev.c	(revision 2459)
@@ -27,5 +27,5 @@
 
 #define THIS_FILE	"pa_dev.c"
-#define DRIVER_NAME	"portaudio"
+#define DRIVER_NAME	"PA"
 
 struct pa_aud_factory
@@ -102,8 +102,8 @@
 static unsigned	    pa_get_dev_count(pjmedia_aud_dev_factory *f);
 static pj_status_t  pa_get_dev_info(pjmedia_aud_dev_factory *f, 
-				    pjmedia_aud_dev_id id,
+				    unsigned index,
 				    pjmedia_aud_dev_info *info);
 static pj_status_t  pa_default_param(pjmedia_aud_dev_factory *f,
-				     pjmedia_aud_dev_id id,
+				     unsigned index,
 				     pjmedia_aud_dev_param *param);
 static pj_status_t  pa_create_stream(pjmedia_aud_dev_factory *f,
@@ -190,6 +190,4 @@
 	++stream->overflow;
 
-    stream->rec_timestamp.u64 += frameCount;
-
     /* Calculate number of samples we've got */
     nsamples = frameCount * stream->channel_count + stream->rec_buf_count;
@@ -202,28 +200,41 @@
 	if (stream->rec_buf_count) {
 	    unsigned chunk_count = 0;
+	    pjmedia_frame frame;
 	
 	    chunk_count = stream->samples_per_frame - stream->rec_buf_count;
 	    pjmedia_copy_samples(stream->rec_buf + stream->rec_buf_count,
 				 (pj_int16_t*)input, chunk_count);
-	    status = (*stream->rec_cb)(stream->user_data, 
-				       &stream->rec_timestamp,
-				       (void*) stream->rec_buf, 
-				       stream->samples_per_frame * 
-				       stream->bytes_per_sample);
+
+	    frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
+	    frame.buf = (void*) stream->rec_buf;
+	    frame.size = stream->samples_per_frame * stream->bytes_per_sample;
+	    frame.timestamp.u64 = stream->rec_timestamp.u64;
+	    frame.bit_info = 0;
+
+	    status = (*stream->rec_cb)(stream->user_data, &frame);
 
 	    input = (pj_int16_t*) input + chunk_count;
 	    nsamples -= stream->samples_per_frame;
 	    stream->rec_buf_count = 0;
+	    stream->rec_timestamp.u64 += stream->samples_per_frame /
+					 stream->channel_count;
 	}
 
 	/* Give all frames we have */
 	while (nsamples >= stream->samples_per_frame && status == 0) {
-	    status = (*stream->rec_cb)(stream->user_data, 
-				       &stream->rec_timestamp,
-				       (void*) input, 
-				       stream->samples_per_frame * 
-				       stream->bytes_per_sample);
+	    pjmedia_frame frame;
+
+	    frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
+	    frame.buf = (void*) input;
+	    frame.size = stream->samples_per_frame * stream->bytes_per_sample;
+	    frame.timestamp.u64 = stream->rec_timestamp.u64;
+	    frame.bit_info = 0;
+
+	    status = (*stream->rec_cb)(stream->user_data, &frame);
+
 	    input = (pj_int16_t*) input + stream->samples_per_frame;
 	    nsamples -= stream->samples_per_frame;
+	    stream->rec_timestamp.u64 += stream->samples_per_frame /
+					 stream->channel_count;
 	}
 
@@ -291,5 +302,4 @@
 	++stream->overflow;
 
-    stream->play_timestamp.u64 += frameCount;
 
     /* Check if any buffered samples */
@@ -319,17 +329,37 @@
     while (nsamples_req && status == 0) {
 	if (nsamples_req >= stream->samples_per_frame) {
-	    status = (*stream->play_cb)(stream->user_data, 
-					&stream->play_timestamp, 
-					output, 
-					stream->samples_per_frame * 
-					stream->bytes_per_sample);
+	    pjmedia_frame frame;
+
+	    frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
+	    frame.buf = output;
+	    frame.size = stream->samples_per_frame *  stream->bytes_per_sample;
+	    frame.timestamp.u64 = stream->play_timestamp.u64;
+	    frame.bit_info = 0;
+
+	    status = (*stream->play_cb)(stream->user_data, &frame);
+	    if (status != PJ_SUCCESS)
+		goto on_break;
+
+	    if (frame.type != PJMEDIA_FRAME_TYPE_AUDIO)
+		pj_bzero(frame.buf, frame.size);
+
 	    nsamples_req -= stream->samples_per_frame;
 	    output = (pj_int16_t*)output + stream->samples_per_frame;
 	} else {
-	    status = (*stream->play_cb)(stream->user_data, 
-					&stream->play_timestamp, 
-					stream->play_buf,
-					stream->samples_per_frame * 
-					stream->bytes_per_sample);
+	    pjmedia_frame frame;
+
+	    frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
+	    frame.buf = stream->play_buf;
+	    frame.size = stream->samples_per_frame *  stream->bytes_per_sample;
+	    frame.timestamp.u64 = stream->play_timestamp.u64;
+	    frame.bit_info = 0;
+
+	    status = (*stream->play_cb)(stream->user_data, &frame);
+	    if (status != PJ_SUCCESS)
+		goto on_break;
+
+	    if (frame.type != PJMEDIA_FRAME_TYPE_AUDIO)
+		pj_bzero(frame.buf, frame.size);
+
 	    pjmedia_copy_samples((pj_int16_t*)output, stream->play_buf, 
 				 nsamples_req);
@@ -340,4 +370,7 @@
 	    nsamples_req = 0;
 	}
+
+	stream->play_timestamp.u64 += stream->samples_per_frame /
+				      stream->channel_count;
     }
     
@@ -453,5 +486,5 @@
 /* API: Get device info. */
 static pj_status_t  pa_get_dev_info(pjmedia_aud_dev_factory *f, 
-				    pjmedia_aud_dev_id id,
+				    unsigned index,
 				    pjmedia_aud_dev_info *info)
 {
@@ -460,5 +493,5 @@
     PJ_UNUSED_ARG(f);
 
-    pa_info = Pa_GetDeviceInfo(id);
+    pa_info = Pa_GetDeviceInfo(index);
     if (!pa_info)
 	return PJMEDIA_EAUD_INVDEV;
@@ -481,5 +514,5 @@
 /* API: fill in with default parameter. */
 static pj_status_t  pa_default_param(pjmedia_aud_dev_factory *f,
-				     pjmedia_aud_dev_id id,
+				     unsigned index,
 				     pjmedia_aud_dev_param *param)
 {
@@ -489,5 +522,5 @@
     PJ_UNUSED_ARG(f);
 
-    status = pjmedia_aud_dev_get_info(id, &adi);
+    status = pa_get_dev_info(f, index, &adi);
     if (status != PJ_SUCCESS)
 	return status;
@@ -496,13 +529,13 @@
     if (adi.input_count && adi.output_count) {
 	param->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
-	param->rec_id = id;
-	param->play_id = id;
+	param->rec_id = index;
+	param->play_id = index;
     } else if (adi.input_count) {
 	param->dir = PJMEDIA_DIR_CAPTURE;
-	param->rec_id = id;
+	param->rec_id = index;
 	param->play_id = PJMEDIA_AUD_DEV_DEFAULT_ID;
     } else if (adi.output_count) {
 	param->dir = PJMEDIA_DIR_PLAYBACK;
-	param->play_id = id;
+	param->play_id = index;
 	param->rec_id = PJMEDIA_AUD_DEV_DEFAULT_ID;
     } else {
@@ -1080,10 +1113,10 @@
 	pi->flags |= PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY;
 	pi->input_latency_ms = (unsigned)(paRecSI ? paRecSI->inputLatency * 
-						    paRecSI->sampleRate : 0);
+						    1000 : 0);
     }
     if (paPlaySI) {
 	pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;
 	pi->output_latency_ms = (unsigned)(paPlaySI? paPlaySI->outputLatency * 
-						     paPlaySI->sampleRate : 0);
+						     1000 : 0);
     }
 
@@ -1106,5 +1139,5 @@
 	    return PJ_EINVALIDOP;
 
-	*(unsigned*)pval = (unsigned)(si->inputLatency * si->sampleRate);
+	*(unsigned*)pval = (unsigned)(si->inputLatency * 1000);
 	return PJ_SUCCESS;
     } else if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY && strm->play_strm) {
@@ -1113,5 +1146,5 @@
 	    return PJ_EINVALIDOP;
 
-	*(unsigned*)pval = (unsigned)(si->outputLatency * si->sampleRate);
+	*(unsigned*)pval = (unsigned)(si->outputLatency * 1000);
 	return PJ_SUCCESS;
     } else {
