[asterisk-commits] jrose: branch 1.8 r365989 - /branches/1.8/codecs/codec_dahdi.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed May 9 14:10:22 CDT 2012


Author: jrose
Date: Wed May  9 14:10:17 2012
New Revision: 365989

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=365989
Log:
Block on frameout if the hardware has enough samples to complete a frame.

Fixes some problems with skipping audio in elaborate scenarios involving
multiple codecs by making codec_dahdi operate in a more synchronous
fashion similar to codec_g729. This change also fixes the use of file
conversion tools from Asterisk's CLI. This change may cause the thread
responsible for transcoding audio to block briefly (Shaun Ruffell describes
this as 'several milliseconds') while waiting for the hardware transcoder.

(closes issue ASTERISK-19643)
reported by: Shaun Ruffell
Patches:
	0001-codec_dahdi-Block-on-frameout-the-hardware-has-enoug.patch
	uploaded by Shaun Ruffell (license 5417)

Modified:
    branches/1.8/codecs/codec_dahdi.c

Modified: branches/1.8/codecs/codec_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/codecs/codec_dahdi.c?view=diff&rev=365989&r1=365988&r2=365989
==============================================================================
--- branches/1.8/codecs/codec_dahdi.c (original)
+++ branches/1.8/codecs/codec_dahdi.c Wed May  9 14:10:17 2012
@@ -56,6 +56,7 @@
 
 #define G723_SAMPLES 240
 #define G729_SAMPLES 160
+#define ULAW_SAMPLES 160
 
 static struct channel_usage {
 	int total;
@@ -89,6 +90,7 @@
 	unsigned int fake:2;
 	uint16_t required_samples;
 	uint16_t samples_in_buffer;
+	uint16_t samples_written_to_hardware;
 	uint8_t ulaw_buffer[1024];
 };
 
@@ -160,7 +162,6 @@
 static void dahdi_write_frame(struct codec_dahdi_pvt *dahdip, const uint8_t *buffer, const ssize_t count)
 {
 	int res;
-	struct pollfd p = {0};
 	if (!count) return;
 	res = write(dahdip->fd, buffer, count);
 	if (option_verbose > 10) {
@@ -171,9 +172,6 @@
 			ast_log(LOG_ERROR, "Requested write of %zd bytes, but only wrote %d bytes.\n", count, res);
 		}
 	}
-	p.fd = dahdip->fd;
-	p.events = POLLOUT;
-	res = poll(&p, 1, 50);
 }
 
 static int dahdi_encoder_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
@@ -206,8 +204,9 @@
 		dahdip->samples_in_buffer += f->samples;
 	}
 
-	while (dahdip->samples_in_buffer > dahdip->required_samples) {
+	while (dahdip->samples_in_buffer >= dahdip->required_samples) {
 		dahdi_write_frame(dahdip, dahdip->ulaw_buffer, dahdip->required_samples);
+		dahdip->samples_written_to_hardware += dahdip->required_samples;
 		dahdip->samples_in_buffer -= dahdip->required_samples;
 		if (dahdip->samples_in_buffer) {
 			/* Shift any remaining bytes down. */
@@ -218,6 +217,14 @@
 	pvt->samples += f->samples;
 	pvt->datalen = 0;
 	return -1;
+}
+
+static void dahdi_wait_for_packet(int fd)
+{
+	struct pollfd p = {0};
+	p.fd = fd;
+	p.events = POLLIN;
+	poll(&p, 1, 10);
 }
 
 static struct ast_frame *dahdi_encoder_frameout(struct ast_trans_pvt *pvt)
@@ -243,6 +250,10 @@
 		return NULL;
 	}
 
+	if (dahdip->samples_written_to_hardware >= dahdip->required_samples) {
+		dahdi_wait_for_packet(dahdip->fd);
+	}
+
 	res = read(dahdip->fd, pvt->outbuf.c + pvt->datalen, pvt->t->buf_size - pvt->datalen);
 	if (-1 == res) {
 		if (EWOULDBLOCK == errno) {
@@ -262,6 +273,10 @@
 		pvt->f.data.ptr = pvt->outbuf.c;
 		pvt->f.samples = ast_codec_get_samples(&pvt->f);
 
+		dahdip->samples_written_to_hardware =
+		  (dahdip->samples_written_to_hardware >= pvt->f.samples) ?
+		     dahdip->samples_written_to_hardware - pvt->f.samples : 0;
+
 		pvt->samples = 0;
 		pvt->datalen = 0;
 		return ast_frisolate(&pvt->f);
@@ -288,6 +303,7 @@
 		}
 	}
 	dahdi_write_frame(dahdip, f->data.ptr, f->datalen);
+	dahdip->samples_written_to_hardware += f->samples;
 	pvt->samples += f->samples;
 	pvt->datalen = 0;
 	return -1;
@@ -315,6 +331,10 @@
 		return NULL;
 	}
 
+	if (dahdip->samples_written_to_hardware >= ULAW_SAMPLES) {
+		dahdi_wait_for_packet(dahdip->fd);
+	}
+
 	/* Let's check to see if there is a new frame for us.... */
 	if (dahdip->softslin) {
 		res = read(dahdip->fd, dahdip->ulaw_buffer, sizeof(dahdip->ulaw_buffer));
@@ -346,6 +366,9 @@
 		pvt->f.data.ptr = pvt->outbuf.c;
 		pvt->f.samples = res;
 		pvt->samples = 0;
+		dahdip->samples_written_to_hardware =
+			(dahdip->samples_written_to_hardware >= res) ?
+			        dahdip->samples_written_to_hardware - res : 0;
 
 		return ast_frisolate(&pvt->f);
 	}




More information about the asterisk-commits mailing list