From 08cdc4ce5a3f425dae3c33095da500af85af8c45 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 18 Nov 2020 10:30:17 -0500 Subject: [PATCH] TT#101653 generalise handling of supplemental payload types Change-Id: Ic4e2387aa45fc0584184bae907f1bf0cbf6be054 --- daemon/codec.c | 65 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/daemon/codec.c b/daemon/codec.c index 159c4c966..8bb266a35 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -1070,6 +1070,33 @@ static void __codec_rtcp_timer(struct call_media *receiver) { } +// returns: 0 = supp codec not present; 1 = sink has codec but receiver does not, 2 = both have codec +int __supp_codec_match(struct call_media *receiver, struct call_media *sink, int pt, + struct rtp_payload_type **sink_pt, struct rtp_payload_type **recv_pt) +{ + if (pt == -1) + return 0; + + struct rtp_payload_type *sink_pt_stor = NULL; + struct rtp_payload_type *recv_pt_stor = NULL; + if (!sink_pt) + sink_pt = &sink_pt_stor; + if (!recv_pt) + recv_pt = &recv_pt_stor; + + // find a matching output payload type + *sink_pt = g_hash_table_lookup(sink->codecs_send, &pt); + if (!*sink_pt) + return 0; + // XXX should go by codec name/params, not payload type number + *recv_pt = g_hash_table_lookup(receiver->codecs_recv, &pt); + if (!*recv_pt) + return 1; + if (rtp_payload_type_cmp(*sink_pt, *recv_pt)) + return 1; + return 2; +} + // call must be locked in W void codec_handlers_update(struct call_media *receiver, struct call_media *sink, const struct sdp_ng_flags *flags, const struct stream_params *sp) @@ -1141,14 +1168,7 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink, struct rtp_payload_type *dtmf_pt = NULL; struct rtp_payload_type *reverse_dtmf_pt = NULL; - - if (dtmf_payload_type != -1) { - // find a matching output DTMF payload type - dtmf_pt = g_hash_table_lookup(sink->codecs_send, &dtmf_payload_type); - reverse_dtmf_pt = g_hash_table_lookup(receiver->codecs_recv, &dtmf_payload_type); - if (reverse_dtmf_pt && dtmf_pt && rtp_payload_type_cmp(reverse_dtmf_pt, dtmf_pt)) - reverse_dtmf_pt = NULL; - } + int dtmf_pt_match = __supp_codec_match(receiver, sink, dtmf_payload_type, &dtmf_pt, &reverse_dtmf_pt); // stop transcoding if we've determined that we don't need it if (MEDIA_ISSET(sink, TRANSCODE) && !sink_transcoding) { @@ -1170,7 +1190,6 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink, // do we need to detect PCM DTMF tones? int pcm_dtmf_detect = 0; - if (reverse_dtmf_pt) if ((MEDIA_ISSET(sink, TRANSCODE) || (flags && flags->always_transcode)) && dtmf_payload_type != -1 && dtmf_pt && (!reverse_dtmf_pt || reverse_dtmf_pt->for_transcoding || @@ -1222,7 +1241,7 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink, GQueue *dest_codecs = NULL; if (!flags || !flags->always_transcode) { // we ignore output codec matches if we must transcode DTMF - if (dtmf_pt && !reverse_dtmf_pt) + if (dtmf_pt_match == 1 && MEDIA_ISSET(sink, TRANSCODE)) ; else if (pcm_dtmf_detect) ; @@ -1343,7 +1362,7 @@ next: // sink's preferred destination codec. if (!transcode_supplemental && !pcm_dtmf_detect) __make_passthrough_ssrc(handler); - else if (dtmf_pt && reverse_dtmf_pt) + else if (dtmf_pt_match == 2) __make_passthrough_ssrc(handler); else if (!pref_dest_codec || !handler->source_pt.codec_def || !pref_dest_codec->codec_def) @@ -2317,13 +2336,21 @@ static int packet_encoded_rtp(encoder_t *enc, void *u1, void *u2) { ilog(LOG_DEBUG, "Received packet of %i bytes from packetizer", inout.len); + // check special payloads + unsigned int repeats = 0; + int payload_type = -1; int is_dtmf = dtmf_event_payload(&inout, (uint64_t *) &enc->avpkt.pts, enc->avpkt.duration, &ch->dtmf_event, &ch->dtmf_events); - if (is_dtmf == 1) - ch->rtp_mark = 1; // DTMF start event - else if (is_dtmf == 3) - repeats = 2; // DTMF end event + if (is_dtmf) { + payload_type = ch->handler->dtmf_payload_type; + if (is_dtmf == 1) + ch->rtp_mark = 1; // DTMF start event + else if (is_dtmf == 3) + repeats = 2; // DTMF end event + } + + // ready to send do { char *send_buf = buf; @@ -2335,7 +2362,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, - is_dtmf ? ch->handler->dtmf_payload_type : -1); + payload_type); mp->ssrc_out->parent->seq_diff++; //mp->iter_out++; ch->rtp_mark = 0; @@ -2702,9 +2729,7 @@ static void __insert_codec_tracker(struct call_media *media, GList *link) { } } #endif -static void __queue_insert_supp(GQueue *q, struct rtp_payload_type *pt, int supp_check, - struct codec_tracker *sct) -{ +static void __queue_insert_supp(GQueue *q, struct rtp_payload_type *pt, int supp_check) { // do we care at all? if (!supp_check) { g_queue_push_tail(q, pt); @@ -2748,7 +2773,7 @@ void __rtp_payload_type_add_recv(struct call_media *media, struct rtp_payload_ty pt->ptime = media->ptime; g_hash_table_insert(media->codecs_recv, &pt->payload_type, pt); __rtp_payload_type_add_name(media->codec_names_recv, pt); - __queue_insert_supp(&media->codecs_prefs_recv, pt, supp_check, media->codec_tracker); + __queue_insert_supp(&media->codecs_prefs_recv, pt, supp_check); } // consumes 'pt' void __rtp_payload_type_add_send(struct call_media *other_media,