From d4fbec39d1bc2144150c6233f51c88cb40453559 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 19 May 2021 13:22:42 -0400 Subject: [PATCH] TT#122401 return ptime from decoded packets for DTX Change-Id: I382b842406fbee73ec752f6f4f0832736222ef52 --- daemon/codec.c | 24 ++++++++++++++++++++---- include/media_socket.h | 1 + lib/codeclib.c | 22 +++++++++++++++++----- lib/codeclib.h | 2 ++ 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/daemon/codec.c b/daemon/codec.c index 984c53ff6..752f48c49 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -2558,6 +2558,9 @@ static void __dtx_send_later(struct timerthread_queue *ttq, void *p) { timerthread_queue_push(&dtxb->ttq, &dtxb->ttq_entry); + int ptime = dtxb->ptime; + int dtx_ptime = ptime; + mutex_unlock(&dtxb->lock); rwlock_lock_r(&call->master_lock); @@ -2568,8 +2571,13 @@ static void __dtx_send_later(struct timerthread_queue *ttq, void *p) { ilogs(dtx, LOG_DEBUG, "Decoding DTX-buffered RTP packet (TS %lu) now; " "%i packets left in queue", ts, p_left); + mp_copy.ptime = -1; ret = dtxp->func(ch, dtxp->packet, &mp_copy); - if (ret) + if (!ret) { + if (mp_copy.ptime > 0) + ptime = mp_copy.ptime; + } + else ilogs(dtx, LOG_WARN | LOG_FLAG_LIMIT, "Decoder error while processing buffered RTP packet"); } @@ -2583,7 +2591,7 @@ static void __dtx_send_later(struct timerthread_queue *ttq, void *p) { // synthetic packet mp_copy.rtp->seq_num += htons(1); - ret = decoder_dtx(ch->decoder, ts, dtxb->ptime, + ret = decoder_dtx(ch->decoder, ts, ptime, ch->handler->packet_decoded, ch, &mp_copy); if (ret) ilogs(dtx, LOG_WARN | LOG_FLAG_LIMIT, @@ -2598,6 +2606,13 @@ static void __dtx_send_later(struct timerthread_queue *ttq, void *p) { } } + if (ptime != dtx_ptime) { + mutex_lock(&dtxb->lock); + dtxb->ptime = ptime; + dtxb->tspp = ptime * dtxb->clockrate / 1000; + mutex_unlock(&dtxb->lock); + } + __ssrc_unlock_both(&mp_copy); if (mp_copy.packets_out.length && ret == 0) { @@ -2664,8 +2679,8 @@ static void __dtx_setup(struct codec_ssrc_handler *ch) { dtx->ptime = 20; ilogs(dtx, LOG_DEBUG, "Using DTX ptime %i based on handler=%i codec=%i", dtx->ptime, ch->ptime, ch->handler->source_pt.codec_def->default_ptime); - dtx->tspp = dtx->ptime * ch->handler->source_pt.clock_rate / 1000; dtx->clockrate = ch->handler->source_pt.clock_rate; + dtx->tspp = dtx->ptime * dtx->clockrate / 1000; } static void __ssrc_handler_stop(void *p) { struct codec_ssrc_handler *ch = p; @@ -3094,7 +3109,8 @@ static int packet_decoded_direct(decoder_t *decoder, AVFrame *frame, void *u1, v static int __rtp_decode(struct codec_ssrc_handler *ch, struct transcode_packet *packet, struct media_packet *mp) { - int ret = decoder_input_data(ch->decoder, packet->payload, packet->ts, ch->handler->packet_decoded, + int ret = decoder_input_data_ptime(ch->decoder, packet->payload, packet->ts, &mp->ptime, + ch->handler->packet_decoded, ch, mp); mp->ssrc_out->parent->seq_diff--; return ret; diff --git a/include/media_socket.h b/include/media_socket.h index f39559c5c..de2933769 100644 --- a/include/media_socket.h +++ b/include/media_socket.h @@ -139,6 +139,7 @@ struct media_packet { str payload; GQueue packets_out; + int ptime; // returned from decoding }; diff --git a/lib/codeclib.c b/lib/codeclib.c index c45c9829a..43bf402b0 100644 --- a/lib/codeclib.c +++ b/lib/codeclib.c @@ -842,7 +842,7 @@ err: return -1; } -static int __decoder_input_data(decoder_t *dec, const str *data, unsigned long ts, int ptime, +static int __decoder_input_data(decoder_t *dec, const str *data, unsigned long ts, int *ptime, int (*callback)(decoder_t *, AVFrame *, void *u1, void *u2), void *u1, void *u2) { GQueue frames = G_QUEUE_INIT; @@ -850,7 +850,7 @@ static int __decoder_input_data(decoder_t *dec, const str *data, unsigned long t if (G_UNLIKELY(!dec)) return -1; - if (!data && !dec->dtx.do_dtx) + if (!data && (!dec->dtx.do_dtx || !ptime)) return 0; ts *= dec->def->clockrate_mult; @@ -879,11 +879,13 @@ static int __decoder_input_data(decoder_t *dec, const str *data, unsigned long t if (data) dec->def->codec_type->decoder_input(dec, data, &frames); else - dec->dtx.do_dtx(dec, &frames, ptime); + dec->dtx.do_dtx(dec, &frames, *ptime); AVFrame *frame; int ret = 0; + unsigned long samples = 0; while ((frame = g_queue_pop_head(&frames))) { + samples += frame->nb_samples; dec->dec_out_format.format = frame->format; AVFrame *rsmp_frame = resample_frame(&dec->resampler, frame, &dec->dest_format); if (!rsmp_frame) { @@ -897,6 +899,9 @@ static int __decoder_input_data(decoder_t *dec, const str *data, unsigned long t av_frame_free(&frame); } + if (ptime) + *ptime = samples * 1000L / dec->in_format.clockrate; + return ret; } int decoder_input_data(decoder_t *dec, const str *data, unsigned long ts, @@ -904,12 +909,19 @@ int decoder_input_data(decoder_t *dec, const str *data, unsigned long ts, { if (!data || !data->s || !data->len) return 0; - return __decoder_input_data(dec, data, ts, 0, callback, u1, u2); + return __decoder_input_data(dec, data, ts, NULL, callback, u1, u2); +} +int decoder_input_data_ptime(decoder_t *dec, const str *data, unsigned long ts, int *ptime, + int (*callback)(decoder_t *, AVFrame *, void *u1, void *u2), void *u1, void *u2) +{ + if (!data || !data->s || !data->len) + return 0; + return __decoder_input_data(dec, data, ts, ptime, callback, u1, u2); } int decoder_dtx(decoder_t *dec, unsigned long ts, int ptime, int (*callback)(decoder_t *, AVFrame *, void *u1, void *u2), void *u1, void *u2) { - return __decoder_input_data(dec, NULL, ts, ptime, callback, u1, u2); + return __decoder_input_data(dec, NULL, ts, &ptime, callback, u1, u2); } diff --git a/lib/codeclib.h b/lib/codeclib.h index b6b87bb36..e8a294a3f 100644 --- a/lib/codeclib.h +++ b/lib/codeclib.h @@ -307,6 +307,8 @@ decoder_t *decoder_new_fmtp(const codec_def_t *def, int clockrate, int channels, void decoder_close(decoder_t *dec); int decoder_input_data(decoder_t *dec, const str *data, unsigned long ts, int (*callback)(decoder_t *, AVFrame *, void *u1, void *u2), void *u1, void *u2); +int decoder_input_data_ptime(decoder_t *dec, const str *data, unsigned long ts, int *ptime, + int (*callback)(decoder_t *, AVFrame *, void *u1, void *u2), void *u1, void *u2); gboolean decoder_has_dtx(decoder_t *); int decoder_switch_dtx(decoder_t *dec, enum dtx_method); int decoder_set_cn_dtx(decoder_t *dec, const str *);