diff options
Diffstat (limited to 'main/frame.c')
-rw-r--r-- | main/frame.c | 91 |
1 files changed, 62 insertions, 29 deletions
diff --git a/main/frame.c b/main/frame.c index 912d6c739..956fea3e5 100644 --- a/main/frame.c +++ b/main/frame.c @@ -86,9 +86,9 @@ enum frame_type { struct ast_smoother { int size; int format; - int readdata; int flags; float samplesperbyte; + unsigned int opt_needs_swap:1; struct ast_frame f; struct timeval delivery; char data[SMOOTHER_SIZE]; @@ -128,10 +128,54 @@ static const struct ast_format_list AST_FORMAT_LIST[] = { struct ast_frame ast_null_frame = { AST_FRAME_NULL, }; -void ast_smoother_reset(struct ast_smoother *s, int size) +static int smoother_frame_feed(struct ast_smoother *s, struct ast_frame *f, int swap) +{ + if (s->flags & AST_SMOOTHER_FLAG_G729) { + if (s->len % 10) { + ast_log(LOG_NOTICE, "Dropping extra frame of G.729 since we already have a VAD frame at the end\n"); + return 0; + } + } + if (swap) { + ast_swapcopy_samples(s->data + s->len, f->data.ptr, f->samples); + } else { + memcpy(s->data + s->len, f->data.ptr, f->datalen); + } + /* If either side is empty, reset the delivery time */ + if (!s->len || ast_tvzero(f->delivery) || ast_tvzero(s->delivery)) { /* XXX really ? */ + s->delivery = f->delivery; + } + s->len += f->datalen; + + return 0; +} + +void ast_smoother_reset(struct ast_smoother *s, int bytes) { memset(s, 0, sizeof(*s)); - s->size = size; + s->size = bytes; +} + +void ast_smoother_reconfigure(struct ast_smoother *s, int bytes) +{ + /* if there is no change, then nothing to do */ + if (s->size == bytes) { + return; + } + /* set the new desired output size */ + s->size = bytes; + /* if there is no 'optimized' frame in the smoother, + * then there is nothing left to do + */ + if (!s->opt) { + return; + } + /* there is an 'optimized' frame here at the old size, + * but it must now be put into the buffer so the data + * can be extracted at the new size + */ + smoother_frame_feed(s, s->opt, s->opt_needs_swap); + s->opt = NULL; } struct ast_smoother *ast_smoother_new(int size) @@ -176,33 +220,22 @@ int __ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f, int swap) ast_log(LOG_WARNING, "Out of smoother space\n"); return -1; } - if (((f->datalen == s->size) || ((f->datalen < 10) && (s->flags & AST_SMOOTHER_FLAG_G729))) - && !s->opt && (f->offset >= AST_MIN_OFFSET)) { - if (!s->len) { - /* Optimize by sending the frame we just got - on the next read, thus eliminating the douple - copy */ - if (swap) - ast_swapcopy_samples(f->data.ptr, f->data.ptr, f->samples); - s->opt = f; - return 0; - } - } - if (s->flags & AST_SMOOTHER_FLAG_G729) { - if (s->len % 10) { - ast_log(LOG_NOTICE, "Dropping extra frame of G.729 since we already have a VAD frame at the end\n"); - return 0; - } + if (((f->datalen == s->size) || + ((f->datalen < 10) && (s->flags & AST_SMOOTHER_FLAG_G729))) && + !s->opt && + !s->len && + (f->offset >= AST_MIN_OFFSET)) { + /* Optimize by sending the frame we just got + on the next read, thus eliminating the douple + copy */ + if (swap) + ast_swapcopy_samples(f->data.ptr, f->data.ptr, f->samples); + s->opt = f; + s->opt_needs_swap = swap ? 1 : 0; + return 0; } - if (swap) - ast_swapcopy_samples(s->data+s->len, f->data.ptr, f->samples); - else - memcpy(s->data + s->len, f->data.ptr, f->datalen); - /* If either side is empty, reset the delivery time */ - if (!s->len || ast_tvzero(f->delivery) || ast_tvzero(s->delivery)) /* XXX really ? */ - s->delivery = f->delivery; - s->len += f->datalen; - return 0; + + return smoother_frame_feed(s, f, swap); } struct ast_frame *ast_smoother_read(struct ast_smoother *s) |