diff --git a/daemon/codec.c b/daemon/codec.c index 28c6cd8a4..63b398cb4 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -18,6 +18,7 @@ struct codec_ssrc_handler { decoder_t *decoder; encoder_t *encoder; unsigned long ts_offset; + u_int32_t ssrc_out; u_int16_t seq_out; }; struct transcode_packet { @@ -75,6 +76,21 @@ static void __make_transcoder(struct codec_handler *handler, struct rtp_payload_ assert(dest->codec_def != NULL); assert(source->payload_type == handler->source_pt.payload_type); + // don't reset handler if it already matches what we want + if (rtp_payload_type_cmp(source, &handler->source_pt)) + goto reset; + if (rtp_payload_type_cmp(dest, &handler->dest_pt)) + goto reset; + if (handler->func != handler_func_transcode) + goto reset; + + ilog(LOG_DEBUG, "Leaving transcode context for " STR_FORMAT "/%u/%i -> " STR_FORMAT "/%u/%i intact", + STR_FMT(&source->encoding), source->clock_rate, source->channels, + STR_FMT(&dest->encoding), dest->clock_rate, dest->channels); + + return; + +reset: __handler_shutdown(handler); handler->source_pt = *source; @@ -87,9 +103,6 @@ static void __make_transcoder(struct codec_handler *handler, struct rtp_payload_ ilog(LOG_DEBUG, "Created transcode context for " STR_FORMAT "/%u/%i -> " STR_FORMAT "/%u/%i", STR_FMT(&source->encoding), source->clock_rate, source->channels, STR_FMT(&dest->encoding), dest->clock_rate, dest->channels); - - return; - } static void __ensure_codec_def(struct rtp_payload_type *pt) { @@ -306,10 +319,13 @@ static void __transcode_packet_free(struct transcode_packet *p) { static struct ssrc_entry *__ssrc_handler_new(void *p) { struct codec_handler *h = p; + u_int32_t ssrc_out = random(); - ilog(LOG_DEBUG, "Creating SSRC handler to transcode from %s/%u/%i to %s/%u/%i", + ilog(LOG_DEBUG, "Creating SSRC handler to transcode from %s/%u/%i to SSRC %x %s/%u/%i", h->source_pt.codec_def->rtpname, h->source_pt.clock_rate, - h->source_pt.channels, h->dest_pt.codec_def->rtpname, h->dest_pt.clock_rate, + h->source_pt.channels, + ntohl(ssrc_out), + h->dest_pt.codec_def->rtpname, h->dest_pt.clock_rate, h->dest_pt.channels); struct codec_ssrc_handler *ch = g_slice_alloc0(sizeof(*ch)); @@ -317,6 +333,7 @@ static struct ssrc_entry *__ssrc_handler_new(void *p) { mutex_init(&ch->lock); packet_sequencer_init(&ch->sequencer, (GDestroyNotify) __transcode_packet_free); ch->seq_out = random(); + ch->ssrc_out = ssrc_out; ch->ts_offset = random(); ch->decoder = decoder_new_fmt(h->source_pt.codec_def, h->source_pt.clock_rate, h->source_pt.channels, 0); if (!ch->decoder) @@ -359,7 +376,7 @@ static int __packet_encoded(encoder_t *enc, void *u1, void *u2) { rh->m_pt = ch->handler->dest_pt.payload_type; rh->seq_num = htons(ch->seq_out++); rh->timestamp = htonl(enc->avpkt.pts + ch->ts_offset); - rh->ssrc = ch->h.ssrc; + rh->ssrc = ch->ssrc_out; // XXX use writev() for output? would make sense if enc->avpkt.data can be stolen memcpy(buf + sizeof(struct rtp_header), enc->avpkt.data, enc->avpkt.size); @@ -397,7 +414,7 @@ static int handler_func_transcode(struct codec_handler *h, struct call_media *me // create new packet and insert it into sequencer queue - ilog(LOG_DEBUG, "Received RTP packet: SSRC %u, PT %u, seq %u, TS %u, len %i", + ilog(LOG_DEBUG, "Received RTP packet: SSRC %x, PT %u, seq %u, TS %u, len %i", ntohl(mp->rtp->ssrc), mp->rtp->m_pt, ntohs(mp->rtp->seq_num), ntohl(mp->rtp->timestamp), mp->payload.len); diff --git a/lib/rtplib.c b/lib/rtplib.c index bc5b8d9ab..0c1586d9a 100644 --- a/lib/rtplib.c +++ b/lib/rtplib.c @@ -139,3 +139,17 @@ const struct rtp_payload_type *rtp_get_rfc_codec(const str *codec) { } return NULL; } + +int rtp_payload_type_cmp(const struct rtp_payload_type *a, const struct rtp_payload_type *b) { + if (a->payload_type != b->payload_type) + return 1; + if (a->clock_rate != b->clock_rate) + return 1; + if (a->channels != b->channels) + return 1; + if (str_cmp_str(&a->encoding_with_params, &b->encoding_with_params)) + return 1; + if (str_cmp_str(&a->format_parameters, &b->format_parameters)) + return 1; + return 0; +} diff --git a/lib/rtplib.h b/lib/rtplib.h index 17b1541f5..a0971e019 100644 --- a/lib/rtplib.h +++ b/lib/rtplib.h @@ -38,5 +38,7 @@ int rtp_padding(struct rtp_header *header, str *payload); const struct rtp_payload_type *rtp_get_rfc_payload_type(unsigned int type); const struct rtp_payload_type *rtp_get_rfc_codec(const str *codec); +int rtp_payload_type_cmp(const struct rtp_payload_type *, const struct rtp_payload_type *); + #endif