[asterisk-commits] russell: branch russell/iax2_media r119424 - /team/russell/iax2_media/channels/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri May 30 16:55:05 CDT 2008


Author: russell
Date: Fri May 30 16:55:04 2008
New Revision: 119424

URL: http://svn.digium.com/view/asterisk?view=rev&rev=119424
Log:
Back up code for another approach i was playing with

Modified:
    team/russell/iax2_media/channels/chan_iax2.c

Modified: team/russell/iax2_media/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/russell/iax2_media/channels/chan_iax2.c?view=diff&rev=119424&r1=119423&r2=119424
==============================================================================
--- team/russell/iax2_media/channels/chan_iax2.c (original)
+++ team/russell/iax2_media/channels/chan_iax2.c Fri May 30 16:55:04 2008
@@ -33,6 +33,7 @@
 /*** MODULEINFO
 	<use>zaptel</use>
 	<use>crypto</use>
+	<depend>jack</depend>
  ***/
 
 #include "asterisk.h"
@@ -54,6 +55,8 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <regex.h>
+
+#include <jack/ringbuffer.h>
 
 #include "asterisk/zapata.h"
 #include "asterisk/paths.h"	/* need ast_config_AST_DATA_DIR for firmware */
@@ -641,8 +644,14 @@
 	/*! received frame count: (just for stats) */
 	int frames_received;
 
-	AST_LIST_HEAD_NOLOCK(, iax_frame) audio_q;
-	AST_LIST_HEAD_NOLOCK(, iax_frame) used_audio_q;
+	jack_ringbuffer_t *audio_rb;
+	#define AUDIO_RB_SIZE 16386
+
+	jack_ringbuffer_t *frame_header_rb;
+	#define FRAME_HEADER_RB_SIZE 3200
+
+	struct ast_frame audio_fr;
+	char audio_buf[2048];
 };
 
 /*!
@@ -1426,12 +1435,15 @@
 
 	jb_destroy(pvt->jb);
 	ast_string_field_free_memory(pvt);
-	
-	while ((cur = AST_LIST_REMOVE_HEAD(&pvt->used_audio_q, pvt_q_entry))) {
-		iax2_frame_free(cur);
-	}
-	while ((cur = AST_LIST_REMOVE_HEAD(&pvt->audio_q, pvt_q_entry))) {
-		iax2_frame_free(cur);
+
+	if (pvt->audio_rb) {
+		jack_ringbuffer_free(pvt->audio_rb);
+		pvt->audio_rb = NULL;
+	}
+
+	if (pvt->frame_header_rb) {
+		jack_ringbuffer_free(pvt->frame_header_rb);
+		pvt->frame_header_rb = NULL;
 	}
 }
 
@@ -1441,6 +1453,18 @@
 	jb_conf jbconf;
 
 	if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
+		return NULL;
+	}
+
+	if (!(tmp->audio_rb = jack_ringbuffer_create(AUDIO_RB_SIZE))) {
+		ao2_ref(tmp, -1);
+		tmp = NULL;
+		return NULL;
+	}
+
+	if (!(tmp->frame_header_rb = jack_ringbuffer_create(FRAME_HEADER_RB_SIZE))) {
+		ao2_ref(tmp, -1);
+		tmp = NULL;
 		return NULL;
 	}
 
@@ -1469,8 +1493,6 @@
 	jb_setconf(tmp->jb,&jbconf);
 
 	AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
-	AST_LIST_HEAD_INIT_NOLOCK(&tmp->audio_q);
-	AST_LIST_HEAD_INIT_NOLOCK(&tmp->used_audio_q);
 
 	return tmp;
 }
@@ -2098,23 +2120,26 @@
 static void iax2_queue_audio(uint16_t call_num, struct iax_frame *fr)
 {
 	struct chan_iax2_pvt *pvt = iaxs[call_num];
+	size_t res;
 
 	ast_assert(pvt->owner != NULL);
 
-	AST_LIST_INSERT_TAIL(&pvt->audio_q, fr, pvt_q_entry);
-
-	while (AST_LIST_FIRST(&pvt->used_audio_q) && 
-		AST_LIST_NEXT(AST_LIST_FIRST(&pvt->used_audio_q), pvt_q_entry) && 
-		(fr = AST_LIST_REMOVE_HEAD(&pvt->used_audio_q, pvt_q_entry))) {
-		iax2_frame_free(fr);
+	res = jack_ringbuffer_write(pvt->frame_header_rb, (char *) &fr->af, sizeof(fr->af));
+	if (res != sizeof(fr->af)) {
+		ast_debug(2, "Tried to write %d bytes to the frame header ringbuffer, but only wrote %d\n",
+			(int) sizeof(fr->af), (int) res);
+	}
+
+	res = jack_ringbuffer_write(pvt->audio_rb, fr->af.data.ptr, fr->af.datalen);
+	if (res != fr->af.datalen) {
+		ast_debug(2, "Tried to write %d bytes to the audio ringbuffer, but only wrote %d\n",
+			(int) fr->af.datalen, (int) res);
 	}
 
 	ast_channel_alert(pvt->owner);
 }
 
 /*!
- * Just deliver the packet by using queueing.
- *
  * \note This function assumes that iaxsl[callno] is locked when called.
  */
 static int deliver_audio_frame(struct iax_frame *fr)
@@ -2885,27 +2910,25 @@
 		case JB_OK:
 			fr = frame.data;
 			deliver_audio_frame(fr);
+			iax2_frame_free(fr);
 			fr = NULL;
 			break;
 		case JB_INTERP:
 		{
-			struct iax_frame *iaxfr;
+			struct iax_frame iaxfr = {
+				.callno = 0,	
+			};
 		
-			if (!(iaxfr = iax_frame_new(DIRECTION_INGRESS, 1024, 1))) {
-				break;
-			}
-
 			/* create an interpolation frame */
 			/* XXX Umm ... setting number of samples but with no audio data? O.o */
-			iaxfr->af.frametype = AST_FRAME_VOICE;
-			iaxfr->af.subclass = pvt->voiceformat;
-			iaxfr->af.samples  = frame.ms * 8;
-			iaxfr->af.src  = "IAX2 JB interpolation";
-			iaxfr->af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
-			iaxfr->af.offset = AST_FRIENDLY_OFFSET;
+			iaxfr.af.frametype = AST_FRAME_VOICE;
+			iaxfr.af.subclass = pvt->voiceformat;
+			iaxfr.af.samples  = frame.ms * 8;
+			iaxfr.af.src  = "IAX2 JB interpolation";
+			iaxfr.af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
+			iaxfr.af.offset = AST_FRIENDLY_OFFSET;
 		
-			deliver_audio_frame(iaxfr);
-			iaxfr = NULL;
+			deliver_audio_frame(&iaxfr);
 		}
 			break;
 		case JB_DROP:
@@ -2943,7 +2966,7 @@
 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
 {
 	int type, len;
-	int ret;
+	int ret = JB_OK;
 	int needfree = 0;
 	struct ast_channel *owner = NULL;
 	struct ast_channel *bridge = NULL;
@@ -2964,23 +2987,25 @@
 	type = JB_TYPE_CONTROL;
 	len = 0;
 
-	if(fr->af.frametype == AST_FRAME_VOICE) {
+	if (fr->af.frametype == AST_FRAME_VOICE) {
 		type = JB_TYPE_VOICE;
 		len = ast_codec_get_samples(&fr->af) / 8;
-	} else if(fr->af.frametype == AST_FRAME_CNG) {
+	} else if (fr->af.frametype == AST_FRAME_CNG) {
 		type = JB_TYPE_SILENCE;
 	}
 
 	if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
-		if (tsout)
+		if (tsout) {
 			*tsout = fr->ts;
+		}
 		deliver_audio_frame(fr);
 		fr = NULL;
 		return -1;
 	}
 
-	if ((owner = iaxs[fr->callno]->owner))
+	if ((owner = iaxs[fr->callno]->owner)) {
 		bridge = ast_bridged_channel(owner);
+	}
 
 	/* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
 	 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
@@ -2997,29 +3022,42 @@
 		AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
 
 		/* deliver this frame now */
-		if (tsout)
+		if (tsout) {
 			*tsout = fr->ts;
+		}
+
 		deliver_audio_frame(fr);
-		fr = NULL;
+
 		return -1;
 	}
 
 	/* insert into jitterbuffer */
 	/* TODO: Perhaps we could act immediately if it's not droppable and late */
-	ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
-			calc_rxstamp(iaxs[fr->callno],fr->ts));
+	do {
+		struct iax_frame *dup_fr;
+		if (!(dup_fr = iaxfrdup2(fr))) {
+			break;
+		}
+		ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
+			calc_rxstamp(iaxs[fr->callno], fr->ts));
+	} while (0);
+
 	if (ret == JB_DROP) {
-		needfree++;
+		needfree = 1;
 	} else if (ret == JB_SCHED) {
 		update_jbsched(iaxs[fr->callno]);
 	}
-	if (tsout)
+
+	if (tsout) {
 		*tsout = fr->ts;
+	}
+
 	if (needfree) {
 		/* Free our iax frame */
 		iax2_frame_free(fr);
 		return -1;
 	}
+
 	return 0;
 }
 
@@ -3755,8 +3793,8 @@
 {
 	struct ast_frame *fr;
 	unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
-	struct iax_frame *iax_fr;
 	struct chan_iax2_pvt *pvt;
+	size_t res;
 
 	ast_mutex_lock(&iaxsl[callno]);
 
@@ -3768,14 +3806,37 @@
 		return &ast_null_frame;
 	}
 
-	if (!(iax_fr = AST_LIST_REMOVE_HEAD(&pvt->audio_q, pvt_q_entry))) {
+	fr = &pvt->audio_fr;
+
+	res = jack_ringbuffer_read_space(pvt->frame_header_rb);
+	if (res < sizeof(*fr)) {
+		ast_debug(2, "iax2_read called, but there are no frame headers available\n");
 		ast_mutex_unlock(&iaxsl[callno]);
 		return &ast_null_frame;
 	}
 
-	fr = &iax_fr->af;
-
-	AST_LIST_INSERT_TAIL(&pvt->used_audio_q, iax_fr, pvt_q_entry);
+	res = jack_ringbuffer_read(pvt->frame_header_rb, (char *) fr, sizeof(*fr));
+	if (res < sizeof(*fr)) {
+		ast_log(LOG_ERROR, "Error reading from frame header ringbuffer\n");
+		ast_mutex_unlock(&iaxsl[callno]);
+		return &ast_null_frame;
+	}
+
+	if (fr->datalen > sizeof(pvt->audio_buf)) {
+		ast_log(LOG_ERROR, "There was a frame in the buffer that claimed %d bytes of audio, but the frame can only hold %d!  We're screwed.\n", 
+			fr->datalen, (int) sizeof(pvt->audio_buf));
+		ast_mutex_unlock(&iaxsl[callno]);
+		return &ast_null_frame;
+	}
+
+	res = jack_ringbuffer_read(pvt->audio_rb, pvt->audio_buf, fr->datalen);
+	if (res < fr->datalen) {
+		ast_log(LOG_ERROR, "Error reading from audio ringbuffer\n");
+		ast_mutex_unlock(&iaxsl[callno]);
+		return &ast_null_frame;
+	}
+
+	fr->data.ptr = pvt->audio_buf;
 
 	ast_mutex_unlock(&iaxsl[callno]);
 
@@ -7870,8 +7931,6 @@
 					fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
 				/* Don't pass any packets until we're started */
 				if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
-					struct iax_frame *duped_fr;
-
 					/* Common things */
 					f.src = "IAX2-1";
 					f.mallocd = 0;
@@ -7882,9 +7941,7 @@
 						f.samples = 0;
 					fr->outoforder = 0;
 					iax_frame_wrap(fr, &f);
-					duped_fr = iaxfrdup2(fr);
-					if (duped_fr)
-						schedule_delivery(duped_fr, 1, 1, &fr->ts);
+					schedule_delivery(fr, 1, 1, &fr->ts);
 					if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
 						iaxs[fr->callno]->last = fr->ts;
 				}
@@ -7998,7 +8055,6 @@
 	int exists;
 	int minivid = 0;
 	char empty[32]="";		/* Safety measure */
-	struct iax_frame *duped_fr;
 	char host_pref_buf[128];
 	char caller_pref_buf[128];
 	struct ast_codec_pref pref;
@@ -9553,10 +9609,7 @@
 		fr->outoforder = -1;
 	}
 	fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
-	duped_fr = iaxfrdup2(fr);
-	if (duped_fr) {
-		schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
-	}
+	schedule_delivery(fr, updatehistory, 0, &fr->ts);
 	if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
 		iaxs[fr->callno]->last = fr->ts;
 #if 1




More information about the asterisk-commits mailing list