MT#55283 remember DTMF start TS

In case stray audio is receveived before the DTMF event is fully
finished, retain the internal state from the beginning of the event to
make sure that the output is consistent. This fixes both DTMF timestamps
jumping during the end event, and audio timestamps being off after the
end event.

Closes #1929

Change-Id: I4e675b15153e35a8d1546b947e4b82879c1577b4
pull/1855/merge
Richard Fuchs 2 weeks ago
parent 312997c21d
commit 2d1933633a

@ -220,7 +220,7 @@ struct codec_ssrc_handler {
dtmf_rx_state_t *dtmf_dsp;
resample_t dtmf_resampler;
format_t dtmf_format;
uint64_t dtmf_ts, last_dtmf_event_ts;
uint64_t dtmf_ts, last_dtmf_event_ts, dtmf_out_ts;
dtmf_event_q dtmf_events;
struct dtmf_event dtmf_event; // for replacing PCM with DTMF event
struct dtmf_event dtmf_state; // state tracker for DTMF actions
@ -2515,19 +2515,21 @@ static int codec_add_dtmf_packet(struct codec_ssrc_handler *ch, struct codec_ssr
// this is a new event
ch->dtmf_ts = packet->ts; // start TS
ch->last_dtmf_event_ts = 0; // last DTMF event duration
}
unsigned long ts = fraction_divl(output_ch->encoder->next_pts, &output_ch->encoder->clockrate_fact);
// roll back TS to start of event
ts -= ch->last_dtmf_event_ts;
// adjust to output RTP TS
unsigned long packet_ts = ts + output_ch->csch.first_ts;
unsigned long ts = fraction_divl(output_ch->encoder->next_pts, &output_ch->encoder->clockrate_fact);
// roll back TS to start of event
ts -= ch->last_dtmf_event_ts;
// adjust to output RTP TS
unsigned long packet_ts = ts + output_ch->csch.first_ts;
ch->dtmf_out_ts = packet_ts;
ilogs(transcoding, LOG_DEBUG, "Scaling DTMF packet timestamp and duration: TS %lu -> %lu "
"(%u -> %u)",
packet->ts, packet_ts,
h->source_pt.clock_rate, h->dest_pt.clock_rate);
packet->ts = packet_ts;
ilogs(transcoding, LOG_DEBUG, "Scaling DTMF packet timestamp and duration: TS %lu -> %lu "
"(%u -> %u)",
packet->ts, packet_ts,
h->source_pt.clock_rate, h->dest_pt.clock_rate);
}
packet->ts = ch->dtmf_out_ts;
if (packet->payload->len >= sizeof(struct telephone_event_payload)) {
struct telephone_event_payload *dtmf = (void *) packet->payload->s;
@ -2541,10 +2543,16 @@ static int codec_add_dtmf_packet(struct codec_ssrc_handler *ch, struct codec_ssr
ch->dtmf_first_duration = duration;
ts_delay = duration - ch->dtmf_first_duration;
// shift forward our output RTP TS
output_ch->encoder->next_pts = fraction_multl(ts + duration, &output_ch->encoder->clockrate_fact);
output_ch->encoder->packet_pts += fraction_multl(duration - ch->last_dtmf_event_ts, &output_ch->encoder->clockrate_fact);
ch->last_dtmf_event_ts = duration;
if (ch->last_dtmf_event_ts != duration) {
// shift forward our output RTP TS
output_ch->encoder->next_pts
= fraction_multl(packet->ts - output_ch->csch.first_ts + duration,
&output_ch->encoder->clockrate_fact);
output_ch->encoder->packet_pts
+= fraction_multl(duration - ch->last_dtmf_event_ts,
&output_ch->encoder->clockrate_fact);
ch->last_dtmf_event_ts = duration;
}
}
payload_type = h->dtmf_payload_type;
if (payload_type == -1)

Loading…
Cancel
Save