From f33877bfe3135f5dbf4340e07a9dccd7f6ee680d Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 28 Jan 2021 13:43:46 -0500 Subject: [PATCH] TT#102450 fix some timestamping issues Make sure G.722 rate multiplies is applied in the right places Don't trust encoders to return proper timestamps, but instead track them explicitly based on frame duration Change-Id: Ia9fa96cf662da97159fa170c3a3f37516889e1bd --- daemon/codec.c | 23 ++++++++++++----------- lib/codeclib.c | 6 ++++++ lib/codeclib.h | 1 + 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/daemon/codec.c b/daemon/codec.c index fb69b2f30..17a1de118 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -1938,10 +1938,11 @@ 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 - struct codec_ssrc_handler *output_ch = NULL; - struct codec_ssrc_handler *decoder_ch = NULL; if (ch->handler->dtmf_scaler) { + struct codec_ssrc_handler *output_ch = NULL; + struct codec_ssrc_handler *decoder_ch = NULL; + // this is actually a DTMF -> PCM handler // grab our underlying PCM transcoder struct codec_handler *decoder_handler = __decoder_handler(ch->handler, mp); @@ -1964,14 +1965,14 @@ static int packet_dtmf_fwd(struct codec_ssrc_handler *ch, struct transcode_packe if (ch->dtmf_ts != packet->ts) { // this is a new event ch->dtmf_ts = packet->ts; // start TS - ch->last_dtmf_event_ts = 0; // last shifted FIFO PTS + ch->last_dtmf_event_ts = 0; // last DTMF event duration } - unsigned long ts = output_ch->encoder->fifo_pts; + unsigned long ts = output_ch->encoder->next_pts / output_ch->encoder->def->clockrate_mult; // 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->encoder->def->clockrate_mult + output_ch->first_ts; + unsigned long packet_ts = ts + output_ch->first_ts; ilogs(transcoding, LOG_DEBUG, "Scaling DTMF packet timestamp and duration: TS %lu -> %lu " "(%u -> %u)", @@ -1986,18 +1987,18 @@ static int packet_dtmf_fwd(struct codec_ssrc_handler *ch, struct transcode_packe dtmf->duration = htons(duration); // shift forward our output RTP TS - output_ch->encoder->fifo_pts = ts + duration; + 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; ch->last_dtmf_event_ts = duration; } payload_type = ch->handler->dtmf_payload_type; - } skip: - if (output_ch) - obj_put(&output_ch->h); - if (decoder_ch) - obj_put(&decoder_ch->h); + if (output_ch) + obj_put(&output_ch->h); + if (decoder_ch) + obj_put(&decoder_ch->h); + } char *buf = malloc(packet->payload->len + sizeof(struct rtp_header) + RTP_BUFFER_TAIL_ROOM); memcpy(buf + sizeof(struct rtp_header), packet->payload->s, packet->payload->len); diff --git a/lib/codeclib.c b/lib/codeclib.c index 79e1e5dbc..e5c684f40 100644 --- a/lib/codeclib.c +++ b/lib/codeclib.c @@ -1285,11 +1285,17 @@ int encoder_input_data(encoder_t *enc, AVFrame *frame, return -1; if (enc->avpkt.size) { + // don't rely on the encoder producing steady timestamps, + // instead keep track of them ourselves based on the returned + // frame duration + enc->avpkt.pts = enc->next_pts; + if (enc->def->codec_type->encoder_got_packet) enc->def->codec_type->encoder_got_packet(enc); callback(enc, u1, u2); + enc->next_pts += enc->avpkt.duration; enc->mux_dts = enc->avpkt.dts + 1; // min next expected dts av_packet_unref(&enc->avpkt); diff --git a/lib/codeclib.h b/lib/codeclib.h index 7af12fdce..cda735ce9 100644 --- a/lib/codeclib.h +++ b/lib/codeclib.h @@ -240,6 +240,7 @@ struct encoder_s { AVAudioFifo *fifo; int64_t fifo_pts; // pts of first data in fifo int64_t packet_pts; // first pts of data in packetizer buffer + int64_t next_pts; // next pts expected from the encoder int ptime; int bitrate; int samples_per_frame; // for encoding