--- main/translate.c (Asterisk 13.5.0) +++ main/translate.c (working copy) @@ -44,6 +44,7 @@ #include "asterisk/cli.h" #include "asterisk/term.h" #include "asterisk/format.h" +#include "asterisk/linkedlists.h" /*! \todo * TODO: sample frames for each supported input format. @@ -547,7 +548,12 @@ } delivery = f->delivery; for (out = f; out && p ; p = p->next) { - framein(p, out); + struct ast_frame *current = out; + + do { + framein(p, current); + current = AST_LIST_NEXT(current, frame_list); + } while (current); if (out != f) { ast_frfree(out); } @@ -556,22 +562,33 @@ if (out) { /* we have a frame, play with times */ if (!ast_tvzero(delivery)) { - /* Regenerate prediction after a discontinuity */ - if (ast_tvzero(path->nextout)) { - path->nextout = ast_tvnow(); - } + struct ast_frame *current = out; - /* Use next predicted outgoing timestamp */ - out->delivery = path->nextout; + do { + /* Regenerate prediction after a discontinuity */ + if (ast_tvzero(path->nextout)) { + path->nextout = ast_tvnow(); + } - /* Predict next outgoing timestamp from samples in this - frame. */ - path->nextout = ast_tvadd(path->nextout, ast_samp2tv( - out->samples, ast_format_get_sample_rate(out->subclass.format))); - if (f->samples != out->samples && ast_test_flag(out, AST_FRFLAG_HAS_TIMING_INFO)) { - ast_debug(4, "Sample size different %d vs %d\n", f->samples, out->samples); - ast_clear_flag(out, AST_FRFLAG_HAS_TIMING_INFO); - } + /* Use next predicted outgoing timestamp */ + current->delivery = path->nextout; + + /* Invalidate prediction if we're entering a silence period */ + if (current->frametype == AST_FRAME_CNG) { + path->nextout = ast_tv(0, 0); + /* Predict next outgoing timestamp from samples in this + frame. */ + } else { + path->nextout = ast_tvadd(path->nextout, ast_samp2tv( + current->samples, ast_format_get_sample_rate(current->subclass.format))); + } + + if (f->samples != current->samples && ast_test_flag(current, AST_FRFLAG_HAS_TIMING_INFO)) { + ast_debug(4, "Sample size different %d vs %d\n", f->samples, current->samples); + ast_clear_flag(current, AST_FRFLAG_HAS_TIMING_INFO); + } + current = AST_LIST_NEXT(current, frame_list); + } while (current); } else { out->delivery = ast_tv(0, 0); ast_set2_flag(out, has_timing_info, AST_FRFLAG_HAS_TIMING_INFO); @@ -580,10 +597,10 @@ out->len = len; out->seqno = seqno; } - } - /* Invalidate prediction if we're entering a silence period */ - if (out->frametype == AST_FRAME_CNG) { - path->nextout = ast_tv(0, 0); + /* Invalidate prediction if we're entering a silence period */ + if (out->frametype == AST_FRAME_CNG) { + path->nextout = ast_tv(0, 0); + } } } if (consume) {