From adc5448774e3ab9987955d15bcd92ab9dcca28f1 Mon Sep 17 00:00:00 2001 From: Peter Schlaile Date: Mon, 9 Mar 2009 09:25:26 +0100 Subject: [PATCH] simplified rebuffer-mode to make large block sizes work better Thanks to Kristijan Vrban for the patch! --- bchannel.c | 47 ++++------------------------------------------- bchannel.h | 2 -- chan_lcr.c | 21 ++++++++++++++++++--- chan_lcr.h | 3 +++ 4 files changed, 25 insertions(+), 48 deletions(-) diff --git a/bchannel.c b/bchannel.c index 473de82..e5d2289 100644 --- a/bchannel.c +++ b/bchannel.c @@ -210,7 +210,6 @@ void bchannel_activate(struct bchannel *bchannel, int activate) CERROR(bchannel->call, NULL, "Failed to send to socket %d\n", bchannel->b_sock); bchannel->b_state = (activate)?BSTATE_ACTIVATING:BSTATE_DEACTIVATING; - bchannel->rebuffer_usage = 0; } @@ -265,7 +264,6 @@ void bchannel_destroy(struct bchannel *bchannel) { close(bchannel->b_sock); bchannel->b_sock = -1; - bchannel->rebuffer_usage = 0; } bchannel->b_state = BSTATE_IDLE; } @@ -390,52 +388,15 @@ static void bchannel_receive(struct bchannel *bchannel, unsigned char *buffer, i } } - /* no hdlc and rebuffer */ - if (bchannel->call->rebuffer && !bchannel->call->hdlc) { - int u = bchannel->rebuffer_usage; - unsigned char * b = bchannel->rebuffer; - int l = len; - int fd = bchannel->call->pipe[1]; - - d = data; - - if (u > 0) { - if (u + l >= 160) { - memcpy(b + u, d, 160 - u); - d += 160 - u; - l -= 160 - u; - u = 0; - if (write(fd, b, 160) < 0) - goto errout; - } else { - memcpy(b + u, d, l); - u += l; - l = 0; - } - } - - while (l >= 160) { - if (write(fd, d, 160) < 0) - goto errout; - d += 160; - l -= 160; - } - - if (l > 0) { - memcpy(b, d, l); - } - bchannel->rebuffer_usage = u + l; - } else { - len = write(bchannel->call->pipe[1], data, len); - if (len < 0) - goto errout; - } + + len = write(bchannel->call->pipe[1], data, len); + if (len < 0) + goto errout; return; errout: close(bchannel->call->pipe[1]); bchannel->call->pipe[1] = -1; - bchannel->rebuffer_usage = 0; CDEBUG(bchannel->call, NULL, "broken pipe on bchannel pipe\n"); } diff --git a/bchannel.h b/bchannel.h index 267f8b7..f7b3860 100644 --- a/bchannel.h +++ b/bchannel.h @@ -30,8 +30,6 @@ struct bchannel { int b_dtmf; int b_bf_len; unsigned char b_bf_key[128]; - int rebuffer_usage; - unsigned char rebuffer[160]; }; diff --git a/chan_lcr.c b/chan_lcr.c index 826804f..1d189bc 100644 --- a/chan_lcr.c +++ b/chan_lcr.c @@ -485,6 +485,7 @@ void apply_opt(struct chan_call *call, char *data) } CDEBUG(call, call->ast, "Option 'r' (re-buffer 160 bytes)"); call->rebuffer = 1; + call->framepos = 0; break; case 's': if (opt[1] != '\0') { @@ -2029,7 +2030,11 @@ static struct ast_frame *lcr_read(struct ast_channel *ast) } if (call->pipe[0] > -1) { if (call->rebuffer && !call->hdlc) { - len = read(call->pipe[0], call->read_buff, 160); + /* Make sure we have a complete 20ms (160byte) frame */ + len=read(call->pipe[0],call->read_buff + call->framepos, 160 - call->framepos); + if (len > 0) { + call->framepos += len; + } } else { len = read(call->pipe[0], call->read_buff, sizeof(call->read_buff)); } @@ -2042,13 +2047,23 @@ static struct ast_frame *lcr_read(struct ast_channel *ast) call->pipe[0] = -1; ast_mutex_unlock(&chan_lock); return NULL; + } else if (call->rebuffer && call->framepos < 160) { + /* Not a complete frame, so we send a null-frame */ + ast_mutex_unlock(&chan_lock); + return &ast_null_frame; } } call->read_fr.frametype = AST_FRAME_VOICE; call->read_fr.subclass = ast->nativeformats; - call->read_fr.datalen = len; - call->read_fr.samples = len; + if (call->rebuffer) { + call->read_fr.datalen = call->framepos; + call->read_fr.samples = call->framepos; + call->framepos = 0; + } else { + call->read_fr.datalen = len; + call->read_fr.samples = len; + } call->read_fr.delivery = ast_tv(0,0); *((unsigned char **)&(call->read_fr.data)) = call->read_buff; ast_mutex_unlock(&chan_lock); diff --git a/chan_lcr.h b/chan_lcr.h index 444512b..50e16e5 100644 --- a/chan_lcr.h +++ b/chan_lcr.h @@ -58,6 +58,9 @@ struct chan_call { requested by asterisk */ int rebuffer; /* send only 160 bytes frames to asterisk */ + + int framepos; /* send only 160 bytes frames to asterisk */ + int on_hold; /* track hold management, since sip phones sometimes screw it up */ char pipeline[256]; -- 2.13.6