aboutsummaryrefslogtreecommitdiffstats
path: root/frame.c
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-03-14 18:01:29 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-03-14 18:01:29 +0000
commitcc1a0ac3e718a5f5258fe5c2bc2d1ced4112c37d (patch)
tree40ba86e9428680e67d2879de91296324f495e2fe /frame.c
parent7284e352767f97aeefb67e2a4e513fc8c0ef7309 (diff)
Try to make smoother G.729B aware, and able to handle VAD bytes
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@2421 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'frame.c')
-rwxr-xr-xframe.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/frame.c b/frame.c
index 9b2c55916..2a8989e4c 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;