[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