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