--- ../asterisk-1.4.11/channels/chan_iax2.c 2007-08-17 09:29:24.000000000 +1200 +++ channels/chan_iax2.c 2007-09-23 22:13:38.000000000 +1200 @@ -494,6 +494,8 @@ struct ast_codec_pref prefs; /*! Requested codec preferences */ struct ast_codec_pref rprefs; + /*! Timestamp smoother */ + struct ast_smoother *smoother; /*! Our call number */ unsigned short callno; /*! Peer callno */ @@ -4662,10 +4664,21 @@ static int iax2_write(struct ast_channel *c, struct ast_frame *f) { unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); + struct chan_iax2_pvt *p = iaxs[callno]; int res = -1; + int alaw_or_ulaw = 0; ast_mutex_lock(&iaxsl[callno]); if (iaxs[callno]) { - /* If there's an outstanding error, return failure now */ + if (c->readformat & AST_FORMAT_ULAW || c->readformat & AST_FORMAT_ALAW ) { + alaw_or_ulaw = 1; + if (!p->smoother) { + p->smoother = ast_smoother_new(160); + if (!p->smoother) + return 0; + } + ast_smoother_feed(p->smoother, f); + } + /* If there's an outstanding error, return failure now */ if (!iaxs[callno]->error) { if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) res = 0; @@ -4676,9 +4689,17 @@ res = 0; else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) res = 0; - else - /* Simple, just queue for transmission */ - res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); + else { + if (!alaw_or_ulaw) { + /* Simple, just queue for transmission */ + res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); + } else { + res = 1; /* we might still be filling the smoother */ + while ((f = ast_smoother_read(p->smoother)) && f->data) { + res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); + } + } + } } else { ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); }