simplified rebuffer-mode to make large block sizes work better
authorPeter Schlaile <peter@schlaile.de>
Mon, 9 Mar 2009 08:25:26 +0000 (09:25 +0100)
committerroot <peter@schlaile.de>
Mon, 9 Mar 2009 08:25:26 +0000 (09:25 +0100)
Thanks to Kristijan Vrban for the patch!

bchannel.c
bchannel.h
chan_lcr.c
chan_lcr.h

index 473de82..e5d2289 100644 (file)
@@ -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");
 }
 
index 267f8b7..f7b3860 100644 (file)
@@ -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];
 };
 
 
index 826804f..1d189bc 100644 (file)
@@ -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);
index 444512b..50e16e5 100644 (file)
@@ -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];