--- translate.c.timestamp	Mon Jun 14 15:33:23 2004
+++ translate.c	Mon Jun 14 15:33:23 2004
@@ -57,8 +57,8 @@
 	struct ast_translator *step;
 	struct ast_translator_pvt *state;
 	struct ast_trans_pvt *next;
-	struct timeval nextin;
-	struct timeval nextout;
+	struct timeval delivery;	/* Timestamp of first queued sample */
+	int samples_hold;		/* Number of samples hold in codec's "memory" */
 };
 
 
@@ -103,10 +103,6 @@
 				
 			if (tmp) {
 				tmp->next = NULL;
-				tmp->nextin.tv_sec = 0;
-				tmp->nextin.tv_usec = 0;
-				tmp->nextout.tv_sec = 0;
-				tmp->nextout.tv_usec = 0;
 				tmp->step = tr_matrix[source][dest].step;
 				tmp->state = tmp->step->new();
 				if (!tmp->state) {
@@ -132,6 +128,10 @@
 			return NULL;
 		}
 	}
+	if (tmpr) {
+		tmpr->delivery.tv_sec = tmpr->delivery.tv_usec = 0;
+		tmpr->samples_hold = 0;
+	}
 	return tmpr;
 }
 
@@ -141,49 +141,16 @@
 	struct ast_frame *out;
 	struct timeval delivery;
 	p = path;
+	/* Remember timestamp if samples queue is empty */
+	if(!p->samples_hold && (f->delivery.tv_sec || f->delivery.tv_usec)) {
+		p->delivery.tv_sec = f->delivery.tv_sec;
+		p->delivery.tv_usec = f->delivery.tv_usec;
+	}
+	/* Accumulate count of samples being translated */
+	p->hold += f->samples;
+
 	/* Feed the first frame into the first translator */
 	p->step->framein(p->state, f);
-	if (f->delivery.tv_sec || f->delivery.tv_usec) {
-		if (path->nextin.tv_sec || path->nextin.tv_usec) {
-			/* Make sure this is in line with what we were expecting */
-			if ((path->nextin.tv_sec != f->delivery.tv_sec) ||
-			    (path->nextin.tv_usec != f->delivery.tv_usec)) {
-				/* The time has changed between what we expected and this
-				   most recent time on the new packet.  Adjust our output
-				   time appropriately */
-				long sdiff;
-				long udiff;
-				sdiff = f->delivery.tv_sec - path->nextin.tv_sec;
-				udiff = f->delivery.tv_usec - path->nextin.tv_usec;
-				path->nextin.tv_sec = f->delivery.tv_sec;
-				path->nextin.tv_usec = f->delivery.tv_usec;
-				path->nextout.tv_sec += sdiff;
-				path->nextout.tv_usec += udiff;
-				if (path->nextout.tv_usec < 0) {
-					path->nextout.tv_usec += 1000000;
-					path->nextout.tv_sec--;
-				} else if (path->nextout.tv_usec >= 1000000) {
-					path->nextout.tv_usec -= 1000000;
-					path->nextout.tv_sec++;
-				}
-			}
-		} else {
-			/* This is our first pass.  Make sure the timing looks good */
-			path->nextin.tv_sec = f->delivery.tv_sec;
-			path->nextin.tv_usec = f->delivery.tv_usec;
-			path->nextout.tv_sec = f->delivery.tv_sec;
-			path->nextout.tv_usec = f->delivery.tv_usec;
-		}
-		/* Predict next incoming sample */
-		path->nextin.tv_sec += (f->samples / 8000);
-		path->nextin.tv_usec += ((f->samples % 8000) * 125);
-		if (path->nextin.tv_usec >= 1000000) {
-			path->nextin.tv_usec -= 1000000;
-			path->nextin.tv_sec++;
-		}
-	}
-	delivery.tv_sec = f->delivery.tv_sec;
-	delivery.tv_usec = f->delivery.tv_usec;
 	if (consume)
 		ast_frfree(f);
 	while(p) {
@@ -196,23 +163,16 @@
 		if (p->next) 
 			p->next->step->framein(p->next->state, out);
 		else {
-			if (delivery.tv_sec || delivery.tv_usec) {
-				/* Use next predicted outgoing timestamp */
-				out->delivery.tv_sec = path->nextout.tv_sec;
-				out->delivery.tv_usec = path->nextout.tv_usec;
-				
-				/* Predict next outgoing timestamp from samples in this
-				   frame. */
-				path->nextout.tv_sec += (out->samples / 8000);
-				path->nextout.tv_usec += ((out->samples % 8000) * 125);
-				if (path->nextout.tv_usec >= 1000000) {
-					path->nextout.tv_sec++;
-					path->nextout.tv_usec -= 1000000;
-				}
-			} else {
-				out->delivery.tv_sec = 0;
-				out->delivery.tv_usec = 0;
-			}
+			out->delivery.tv_sec = path->delivery.tv_sec;
+			out->delivery.tv_usec = path->delivery.tv_usec;
+			path->samples_hold -= out->samples;
+			/* If something left in codec's queue */
+			if (path->samples_hold) {
+				/* Adjust timestamp by returning frame */
+				path->delivery.tv_sec += out->samples / 8000;
+				path->delivery.tv_usec += (out->samples % 8000) * 125;
+			} else
+				path->delivery.tv_sec = path->delivery.tv_usec = 0;
 			return out;
 		}
 		p = p->next;
