Browse Source

TT#92250 reset opposite side supp handlers

If a supplemental codec was removed by the codec tracker, we must reset
any codec handlers on the opposite side that were using this output
codec.

Change-Id: I7fb9d0ec7a061682fe3b28d9ead14ac263aff7c3
pull/1164/head
Richard Fuchs 5 years ago
parent
commit
0bab726e5d
4 changed files with 107 additions and 17 deletions
  1. +1
    -1
      daemon/call.c
  2. +83
    -13
      daemon/codec.c
  3. +1
    -1
      include/codec.h
  4. +22
    -2
      t/transcode-test.c

+ 1
- 1
daemon/call.c View File

@ -2177,7 +2177,7 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams,
codec_tracker_init(media);
codec_rtp_payload_types(media, other_media, &sp->rtp_payload_types, flags);
codec_handlers_update(media, other_media, flags, sp);
codec_tracker_finish(media);
codec_tracker_finish(media, other_media);
/* send and recv are from our POV */
bf_copy_same(&media->media_flags, &sp->sp_flags,


+ 83
- 13
daemon/codec.c View File

@ -1374,6 +1374,9 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink,
for (GList *l = receiver->codecs_prefs_recv.head; l; ) {
struct rtp_payload_type *pt = l->data;
ilogs(internals, LOG_DEBUG, "checking recv codec " STR_FORMAT,
STR_FMT(&pt->encoding));
if (MEDIA_ISSET(sink, TRANSCODE) && flags && flags->opmode == OP_ANSWER) {
// if the other side is transcoding, we may come across a receiver entry
// (recv->recv) that wasn't originally offered (recv->send). we must eliminate
@ -1410,14 +1413,14 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink,
goto next;
}
//ilog(LOG_DEBUG, "XXXXXXXXXXXX pref dest codec " STR_FORMAT " is %i, CN match %i DTMF match %i "
//"sink TC %i/%i recv TC %i TC supp %i DTMF DSP %i",
//STR_FMT(&pref_dest_codec->encoding_with_params),
//pref_dest_codec->for_transcoding,
//cn_pt_match, dtmf_pt_match,
//MEDIA_ISSET(sink, TRANSCODE), sink_transcoding,
//receiver_transcoding,
//transcode_supplemental, pcm_dtmf_detect);
ilogs(internals, LOG_DEBUG, "pref dest codec " STR_FORMAT " is %i, CN match %i DTMF match %i "
"sink TC %i/%i recv TC %i TC supp %i DTMF DSP %i",
STR_FMT(&pref_dest_codec->encoding_with_params),
pref_dest_codec->for_transcoding,
cn_pt_match, dtmf_pt_match,
MEDIA_ISSET(sink, TRANSCODE), sink_transcoding,
receiver_transcoding,
transcode_supplemental, pcm_dtmf_detect);
struct rtp_payload_type *dest_pt; // transcode to this
@ -1525,8 +1528,8 @@ next:
for (GList *l = receiver->codecs_prefs_recv.head; l; ) {
struct rtp_payload_type *pt = l->data;
//ilog(LOG_DEBUG, "XXXX checking recv codec " STR_FORMAT,
//STR_FMT(&pt->encoding));
ilogs(internals, LOG_DEBUG, "checking recv codec " STR_FORMAT,
STR_FMT(&pt->encoding));
if (pt->codec_def) {
// supported
@ -3252,7 +3255,7 @@ static int ptr_cmp(const void *a, const void *b) {
return 1;
return 0;
}
void codec_tracker_finish(struct call_media *media) {
void codec_tracker_finish(struct call_media *media, struct call_media *other_media) {
struct codec_tracker *sct = media->codec_tracker;
if (!sct)
return;
@ -3339,8 +3342,75 @@ void codec_tracker_finish(struct call_media *media) {
GList *link = j->data;
struct rtp_payload_type *pt = link->data;
ilogs(codec, LOG_DEBUG, "Eliminating supplemental codec " STR_FORMAT " with stray clock rate %u",
STR_FMT(&pt->encoding), clockrate);
ilogs(codec, LOG_DEBUG, "Eliminating supplemental codec " STR_FORMAT " (%i) with "
"stray clock rate %u",
STR_FMT(&pt->encoding_with_params), pt->payload_type, clockrate);
// now we have to check the codec handlers on the opposite side to see
// if any of them were using this as output
struct rtp_payload_type *prim_dtmf = NULL;
struct rtp_payload_type *prim_cn = NULL;
for (GList *o = other_media->codecs_prefs_recv.head; o; o = o->next) {
struct rtp_payload_type *opt = o->data;
struct codec_handler *ch = codec_handler_get(other_media,
opt->payload_type);
if (!ch)
continue;
// check DTMF
if (!prim_dtmf && ch->dtmf_payload_type != -1)
prim_dtmf = g_hash_table_lookup(other_media->codecs_recv,
&ch->dtmf_payload_type);
if (prim_dtmf) {
if (ch->dest_pt.payload_type == pt->payload_type) {
ilogs(codec, LOG_DEBUG, "Adjusting output DTMF PT for "
"opposite codec handler for "
STR_FORMAT " (%i) to %i",
STR_FMT(&opt->encoding_with_params),
opt->payload_type,
prim_dtmf->payload_type);
__make_transcoder(ch, prim_dtmf, NULL,
prim_dtmf->payload_type,
ch->pcm_dtmf_detect);
}
else if (ch->dtmf_payload_type == pt->payload_type) {
ilogs(codec, LOG_DEBUG, "Adjusting output DTMF PT for "
"opposite codec handler for "
STR_FORMAT " (%i) to %i",
STR_FMT(&opt->encoding_with_params),
opt->payload_type,
prim_dtmf->payload_type);
__make_transcoder(ch, &ch->dest_pt, NULL,
prim_dtmf->payload_type,
ch->pcm_dtmf_detect);
}
}
// check CN
if (!prim_cn && ch->cn_payload_type != -1)
prim_cn = g_hash_table_lookup(other_media->codecs_recv,
&ch->cn_payload_type);
if (prim_cn) {
if (ch->dest_pt.payload_type == pt->payload_type) {
ilogs(codec, LOG_DEBUG, "Adjusting output CN PT for "
"opposite codec handler for "
STR_FORMAT " (%i) to %i",
STR_FMT(&opt->encoding_with_params),
opt->payload_type,
prim_cn->payload_type);
ch->cn_payload_type = prim_cn->payload_type;
}
else if (ch->cn_payload_type == pt->payload_type) {
ilogs(codec, LOG_DEBUG, "Adjusting output CN PT for "
"opposite codec handler for "
STR_FORMAT " (%i) to %i",
STR_FMT(&opt->encoding_with_params),
opt->payload_type,
prim_cn->payload_type);
ch->cn_payload_type = prim_cn->payload_type;
}
}
}
__delete_receiver_codec(media, link);
}


+ 1
- 1
include/codec.h View File

@ -100,7 +100,7 @@ uint64_t codec_encoder_pts(struct codec_ssrc_handler *ch);
void codec_decoder_skip_pts(struct codec_ssrc_handler *ch, uint64_t);
uint64_t codec_decoder_unskip_pts(struct codec_ssrc_handler *ch);
void codec_tracker_init(struct call_media *);
void codec_tracker_finish(struct call_media *);
void codec_tracker_finish(struct call_media *, struct call_media *);
void codec_handlers_stop(GQueue *);
#else


+ 22
- 2
t/transcode-test.c View File

@ -122,7 +122,7 @@ static void offer(void) {
codec_tracker_init(media_B);
codec_rtp_payload_types(media_B, media_A, &rtp_types, &flags);
codec_handlers_update(media_B, media_A, &flags, NULL);
codec_tracker_finish(media_B);
codec_tracker_finish(media_B, media_A);
__init();
}
@ -132,7 +132,7 @@ static void answer(void) {
codec_tracker_init(media_A);
codec_rtp_payload_types(media_A, media_B, &rtp_types, &flags);
codec_handlers_update(media_A, media_B, &flags, NULL);
codec_tracker_finish(media_A);
codec_tracker_finish(media_A, media_B);
__init();
}
@ -1705,6 +1705,26 @@ int main(void) {
expect(A, recv, "9/G722/8000 101/telephone-event/8000");
packet_seq(A, 101, "\x05\x07\x01\x40", 4000, 10, 97, "\x05\x07\x07\x80");
packet_seq(B, 97, "\x05\x07\x07\x80", 4000, 10, 101, "\x05\x07\x01\x40");
// DTMF PT TC w eq PT
start();
sdp_pt(96, opus, 48000);
sdp_pt(8, PCMA, 8000);
sdp_pt(102, telephone-event, 48000);
sdp_pt(101, telephone-event, 8000);
ht_set(codec_mask, all);
transcode(opus);
transcode(PCMA);
transcode(PCMU);
transcode(telephone-event);
offer();
expect(B, recv, "96/opus/48000 8/PCMA/8000 0/PCMU/8000 102/telephone-event/48000 101/telephone-event/8000");
sdp_pt(0, PCMU, 8000);
sdp_pt(101, telephone-event, 8000);
flags.single_codec = 1;
answer();
expect(A, recv, "96/opus/48000 102/telephone-event/48000");
packet_seq(A, 102, "\x05\x07\x01\x40", 4000, 10, 101, "\x05\x07\x00\x35");
packet_seq(B, 101, "\x05\x07\x07\x80", 4000, 10, 102, "\x05\x07\x2d\x00");
return 0;
}

Loading…
Cancel
Save