--- codecs/codec_speex.c (Asterisk 13.5.0) +++ codecs/codec_speex.c (working copy) @@ -54,6 +54,8 @@ #include "asterisk/module.h" #include "asterisk/config.h" #include "asterisk/utils.h" +#include "asterisk/frame.h" +#include "asterisk/linkedlists.h" /* codec variables */ static int quality = 3; @@ -259,15 +261,16 @@ static struct ast_frame *lintospeex_frameout(struct ast_trans_pvt *pvt) { struct speex_coder_pvt *tmp = pvt->pvt; - int is_speech=1; - int datalen = 0; /* output bytes */ - int samples = 0; /* output samples */ + struct ast_frame *result = NULL; + struct ast_frame *last = NULL; + int samples = 0; /* output samples */ - /* We can't work on anything less than a frame in size */ - if (pvt->samples < tmp->framesize) - return NULL; - speex_bits_reset(&tmp->bits); while (pvt->samples >= tmp->framesize) { + struct ast_frame *current; + int is_speech = 1; + + speex_bits_reset(&tmp->bits); + #ifdef _SPEEX_TYPES_H /* Preprocess audio */ if (preproc) @@ -293,18 +296,18 @@ #endif samples += tmp->framesize; pvt->samples -= tmp->framesize; - } - /* Move the data at the end of the buffer to the front */ - if (pvt->samples) - memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2); + /* Use AST_FRAME_CNG to signify the start of any silence period */ + if (is_speech) { + int datalen = 0; /* output bytes */ - /* Use AST_FRAME_CNG to signify the start of any silence period */ - if (is_speech) { - tmp->silent_state = 0; - } else { - if (tmp->silent_state) { - return NULL; + tmp->silent_state = 0; + /* Terminate bit stream */ + speex_bits_pack(&tmp->bits, 15, 5); + datalen = speex_bits_write(&tmp->bits, pvt->outbuf.c, pvt->t->buf_size); + current = ast_trans_frameout(pvt, datalen, tmp->framesize); + } else if (tmp->silent_state) { + current = NULL; } else { struct ast_frame frm = { .frametype = AST_FRAME_CNG, @@ -320,14 +323,25 @@ tmp->silent_state = 1; /* XXX what now ? format etc... */ - return ast_frisolate(&frm); + current = ast_frisolate(&frm); } + + if (!current) { + continue; + } else if (last) { + AST_LIST_NEXT(last, frame_list) = current; + } else { + result = current; + } + last = current; } - /* Terminate bit stream */ - speex_bits_pack(&tmp->bits, 15, 5); - datalen = speex_bits_write(&tmp->bits, pvt->outbuf.c, pvt->t->buf_size); - return ast_trans_frameout(pvt, datalen, samples); + /* Move the data at the end of the buffer to the front */ + if (samples) { + memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2); + } + + return result; } static void speextolin_destroy(struct ast_trans_pvt *arg)