From 79898006746738ec4838ea54990897fd5eb9d704 Mon Sep 17 00:00:00 2001 From: Mark Spencer <markster@digium.com> Date: Sun, 14 Mar 2004 18:01:29 +0000 Subject: [PATCH] Try to make smoother G.729B aware, and able to handle VAD bytes git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2421 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- frame.c | 46 +++++++++++++++++++++++++++++++--------- include/asterisk/frame.h | 4 ++++ rtp.c | 2 ++ 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/frame.c b/frame.c index 9b2c559162..2a8989e4c1 100755 --- a/frame.c +++ b/frame.c @@ -38,6 +38,7 @@ struct ast_smoother { int format; int readdata; int optimizablestream; + int flags; float samplesperbyte; struct ast_frame f; struct timeval delivery; @@ -64,6 +65,16 @@ struct ast_smoother *ast_smoother_new(int size) return s; } +int ast_smoother_get_flags(struct ast_smoother *s) +{ + return s->flags; +} + +void ast_smoother_set_flags(struct ast_smoother *s, int flags) +{ + s->flags = flags; +} + int ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f) { if (f->frametype != AST_FRAME_VOICE) { @@ -81,7 +92,8 @@ int ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f) ast_log(LOG_WARNING, "Out of smoother space\n"); return -1; } - if ((f->datalen == s->size) && !s->opt && (f->offset >= AST_MIN_OFFSET)) { + if (((f->datalen == s->size) || ((f->datalen == 2) && (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 @@ -103,6 +115,12 @@ int ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f) } } else s->optimizablestream = 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; + } + } memcpy(s->data + s->len, f->data, f->datalen); /* If we're empty, reset delivery time */ if (!s->len) @@ -114,7 +132,7 @@ int ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f) struct ast_frame *ast_smoother_read(struct ast_smoother *s) { struct ast_frame *opt; - + int len; /* IF we have an optimization frame, send it */ if (s->opt) { opt = s->opt; @@ -124,24 +142,32 @@ struct ast_frame *ast_smoother_read(struct ast_smoother *s) /* Make sure we have enough data */ if (s->len < s->size) { - return NULL; + /* Or, if this is a G.729 frame with VAD on it, send it immediately anyway */ + if (!((s->flags & AST_SMOOTHER_FLAG_G729) && (s->size % 10))) + return NULL; } + len = s->size; + if (len > s->len) + len = s->len; /* Make frame */ s->f.frametype = AST_FRAME_VOICE; s->f.subclass = s->format; s->f.data = s->framedata + AST_FRIENDLY_OFFSET; s->f.offset = AST_FRIENDLY_OFFSET; - s->f.datalen = s->size; - s->f.samples = s->size * s->samplesperbyte; + s->f.datalen = len; + /* Samples will be improper given VAD, but with VAD the concept really doesn't even exist */ + s->f.samples = len * s->samplesperbyte; s->f.delivery = s->delivery; /* Fill Data */ - memcpy(s->f.data, s->data, s->size); - s->len -= s->size; + memcpy(s->f.data, s->data, len); + s->len -= len; /* Move remaining data to the front if applicable */ if (s->len) { - memmove(s->data, s->data + s->size, s->len); - s->delivery.tv_sec += (s->size * s->samplesperbyte) / 8000.0; - s->delivery.tv_usec += (((int)(s->size * s->samplesperbyte)) % 8000) * 125; + /* In principle this should all be fine because if we are sending + G.729 VAD, the next timestamp will take over anyawy */ + memmove(s->data, s->data + len, s->len); + s->delivery.tv_sec += (len * s->samplesperbyte) / 8000.0; + s->delivery.tv_usec += (((int)(len * s->samplesperbyte)) % 8000) * 125; if (s->delivery.tv_usec > 1000000) { s->delivery.tv_usec -= 1000000; s->delivery.tv_sec += 1; diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h index bf7844e05a..c2409a8dae 100755 --- a/include/asterisk/frame.h +++ b/include/asterisk/frame.h @@ -210,6 +210,8 @@ struct ast_frame_chain { /*! Indicate CALL_PROCEEDING or PROGRESS */ #define AST_CONTROL_PROGRESS 14 +#define AST_SMOOTHER_FLAG_G729 (1 << 0) + /* Option identifiers and flags */ #define AST_OPTION_FLAG_REQUEST 0 #define AST_OPTION_FLAG_ACCEPT 1 @@ -345,6 +347,8 @@ extern int ast_best_codec(int fmts); struct ast_smoother; extern struct ast_smoother *ast_smoother_new(int bytes); +extern void ast_smoother_set_flags(struct ast_smoother *smoother, int flags); +extern int ast_smoother_get_flags(struct ast_smoother *smoother); extern void ast_smoother_free(struct ast_smoother *s); extern void ast_smoother_reset(struct ast_smoother *s, int bytes); extern int ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f); diff --git a/rtp.c b/rtp.c index d031c2db68..10178bb6bb 100755 --- a/rtp.c +++ b/rtp.c @@ -1083,6 +1083,8 @@ int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_f) case AST_FORMAT_G729A: if (!rtp->smoother) { rtp->smoother = ast_smoother_new(20); + if (rtp->smoother) + ast_smoother_set_flags(rtp->smoother, AST_SMOOTHER_FLAG_G729); } if (!rtp->smoother) { ast_log(LOG_WARNING, "Unable to create g729 smoother :(\n"); -- GitLab