diff --git a/daemon/codec.c b/daemon/codec.c index 444c5b695..d41697629 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -123,6 +123,9 @@ struct codec_ssrc_handler { // silence detection GQueue silence_events; + // DTMF send delay + unsigned long dtmf_first_duration; + uint64_t skip_pts; int rtp_mark:1; @@ -1841,7 +1844,8 @@ static void __output_rtp(struct media_packet *mp, struct codec_ssrc_handler *ch, char *buf, // malloc'd, room for rtp_header + filled-in payload unsigned int payload_len, unsigned long payload_ts, - int marker, int seq, int seq_inc, int payload_type) + int marker, int seq, int seq_inc, int payload_type, + unsigned long ts_delay) { struct rtp_header *rh = (void *) buf; struct ssrc_ctx *ssrc_out = mp->ssrc_out; @@ -1877,6 +1881,7 @@ static void __output_rtp(struct media_packet *mp, struct codec_ssrc_handler *ch, // scale first_send from first_send_ts to ts p->ttq_entry.when = ch->first_send; uint32_t ts_diff = (uint32_t) ts - (uint32_t) ch->first_send_ts; // allow for wrap-around + ts_diff += ts_delay; long long ts_diff_us = (unsigned long long) ts_diff * 1000000 / ch->encoder_format.clockrate * ch->handler->dest_pt.codec_def->clockrate_mult; @@ -1941,6 +1946,7 @@ static int packet_dtmf_fwd(struct codec_ssrc_handler *ch, struct transcode_packe struct media_packet *mp) { int payload_type = -1; // take from handler's output config + unsigned long ts_delay = 0; if (ch->handler->dtmf_scaler) { struct codec_ssrc_handler *output_ch = NULL; @@ -1956,10 +1962,11 @@ static int packet_dtmf_fwd(struct codec_ssrc_handler *ch, struct transcode_packe goto skip; // init some vars - if (!ch->first_ts) - ch->first_ts = output_ch->first_ts; - if (!ch->first_send_ts) - ch->first_send_ts = output_ch->first_send_ts; + ch->first_ts = output_ch->first_ts; + ch->first_send_ts = output_ch->first_send_ts; + ch->output_skew = output_ch->output_skew; + ch->first_send = output_ch->first_send; + // the correct output TS is the encoder's FIFO PTS at the start of the DTMF // event. however, we must shift the FIFO PTS forward as the DTMF event goes on @@ -1989,6 +1996,12 @@ static int packet_dtmf_fwd(struct codec_ssrc_handler *ch, struct transcode_packe ch->handler->dest_pt.clock_rate, ch->handler->source_pt.clock_rate); dtmf->duration = htons(duration); + // we can't directly use the RTP TS to schedule the send, as we have to adjust it + // by the duration + if (ch->dtmf_first_duration == 0 || duration < ch->dtmf_first_duration) + ch->dtmf_first_duration = duration; + ts_delay = duration - ch->dtmf_first_duration; + // shift forward our output RTP TS output_ch->encoder->next_pts = (ts + duration) * output_ch->encoder->def->clockrate_mult; output_ch->encoder->packet_pts += (duration - ch->last_dtmf_event_ts) * output_ch->encoder->def->clockrate_mult; @@ -2006,10 +2019,10 @@ skip: memcpy(buf + sizeof(struct rtp_header), packet->payload->s, packet->payload->len); if (packet->ignore_seq) // inject original seq __output_rtp(mp, ch, packet->handler ? : ch->handler, buf, packet->payload->len, packet->ts, - packet->marker, packet->p.seq, -1, payload_type); + packet->marker, packet->p.seq, -1, payload_type, ts_delay); else // use our own sequencing __output_rtp(mp, ch, packet->handler ? : ch->handler, buf, packet->payload->len, packet->ts, - packet->marker, -1, 0, payload_type); + packet->marker, -1, 0, payload_type, ts_delay); return 0; } @@ -2809,7 +2822,7 @@ static int packet_encoded_rtp(encoder_t *enc, void *u1, void *u2) { __output_rtp(mp, ch, ch->handler, send_buf, inout.len, ch->first_ts + enc->avpkt.pts / enc->def->clockrate_mult, ch->rtp_mark ? 1 : 0, -1, 0, - payload_type); + payload_type, 0); mp->ssrc_out->parent->seq_diff++; //mp->iter_out++; ch->rtp_mark = 0;