TT#31403 move SSRC mapping out of codec handler

Change-Id: Id5babcef6440f40e45e7e23afc54398a39093a3f
changes/57/18857/7
Richard Fuchs 8 years ago
parent 7986ca0860
commit 159729ad0d

@ -282,7 +282,7 @@ struct packet_stream {
struct endpoint endpoint; /* LOCK: out_lock */
struct endpoint advertised_endpoint; /* RO */
struct crypto_context crypto; /* OUT direction, LOCK: out_lock */
struct ssrc_ctx *ssrc_in, /* LOCK: in_lock */
struct ssrc_ctx *ssrc_in, /* LOCK: in_lock */ // XXX eliminate these
*ssrc_out; /* LOCK: out_lock */
struct stats stats;
@ -340,7 +340,7 @@ struct call_media {
GQueue codecs_prefs_send; // storage container
GHashTable *codec_handlers; // int payload type -> struct codec_handler
// XXX combine this with 'codecs' hash table?
// XXX combine this with 'codecs_recv' hash table?
volatile struct codec_handler *codec_handler_cache;
int ptime; // either from SDP or overridden

@ -21,7 +21,6 @@ struct codec_ssrc_handler {
int ptime;
int bytes_per_packet;
unsigned long ts_out;
u_int32_t ssrc_out;
u_int16_t seq_out;
GString *sample_buffer;
};
@ -368,12 +367,12 @@ void codec_handlers_free(struct call_media *m) {
static int handler_func_passthrough(struct codec_handler *h, struct call_media *media,
const struct media_packet *mp, GQueue *out)
struct media_packet *mp)
{
struct codec_packet *p = g_slice_alloc(sizeof(*p));
p->s = mp->raw;
p->free_func = NULL;
g_queue_push_tail(out, p);
g_queue_push_tail(&mp->packets_out, p);
return 0;
}
@ -385,13 +384,11 @@ 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 transcoder from %s/%u/%i to "
"SSRC %" PRIx32 " %s/%u/%i",
"%s/%u/%i",
h->source_pt.codec_def->rtpname, h->source_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);
@ -400,7 +397,6 @@ 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_out = random();
ch->ptime = h->dest_pt.ptime;
ch->sample_buffer = g_string_new("");
@ -461,7 +457,7 @@ static void __ssrc_handler_free(struct codec_ssrc_handler *ch) {
static int __packet_encoded(encoder_t *enc, void *u1, void *u2) {
struct codec_ssrc_handler *ch = u1;
GQueue *out_q = u2;
struct media_packet *mp = u2;
ilog(LOG_DEBUG, "RTP media successfully encoded: TS %llu, len %i",
(unsigned long long) enc->avpkt.pts, enc->avpkt.size);
@ -499,14 +495,14 @@ 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_out);
rh->ssrc = ch->ssrc_out;
rh->ssrc = mp->ssrc_out->ssrc_map_out;
// add to output queue
struct codec_packet *p = g_slice_alloc(sizeof(*p));
p->s.s = buf;
p->s.len = inout.len + sizeof(struct rtp_header);
p->free_func = free;
g_queue_push_tail(out_q, p);
g_queue_push_tail(&mp->packets_out, p);
if (ret == 0) {
// no more to go
@ -533,10 +529,10 @@ static int __packet_decoded(decoder_t *decoder, AVFrame *frame, void *u1, void *
}
static int handler_func_transcode(struct codec_handler *h, struct call_media *media,
const struct media_packet *mp, GQueue *out)
struct media_packet *mp)
{
if (G_UNLIKELY(!mp->rtp || mp->rtcp))
return handler_func_passthrough(h, media, mp, out);
return handler_func_passthrough(h, media, mp);
assert((mp->rtp->m_pt & 0x7f) == h->source_pt.payload_type);
@ -575,7 +571,7 @@ static int handler_func_transcode(struct codec_handler *h, struct call_media *me
ilog(LOG_DEBUG, "Decoding RTP packet: seq %u, TS %lu",
packet->p.seq, packet->ts);
if (decoder_input_data(ch->decoder, packet->payload, packet->ts, __packet_decoded, ch, out))
if (decoder_input_data(ch->decoder, packet->payload, packet->ts, __packet_decoded, ch, mp))
ilog(LOG_WARN, "Decoder error while processing RTP packet");
__transcode_packet_free(packet);
}

@ -15,8 +15,7 @@ struct media_packet;
struct ssrc_hash;
typedef int codec_handler_func(struct codec_handler *, struct call_media *, const struct media_packet *,
GQueue *);
typedef int codec_handler_func(struct codec_handler *, struct call_media *, struct media_packet *);
struct codec_handler {

@ -70,7 +70,6 @@ struct packet_handler_ctx {
rewrite_func decrypt_func, encrypt_func; // handlers for decrypt/encrypt
struct packet_stream *in_srtp, *out_srtp; // SRTP contexts for decrypt/encrypt (relevant for muxed RTCP)
int payload_type; // -1 if unknown or not RTP
struct ssrc_ctx *ssrc_in, *ssrc_out; // SSRC contexts from in_srtp and out_srtp
int rtcp; // true if this is an RTCP packet
// verdicts:
@ -80,7 +79,6 @@ struct packet_handler_ctx {
// output:
struct media_packet mp; // passed to handlers
GQueue packets_out;
};
@ -1182,6 +1180,9 @@ static void __stream_ssrc(struct packet_stream *in_srtp, struct packet_stream *o
mutex_unlock(&in_srtp->in_lock);
if (MEDIA_ISSET(in_srtp->media, TRANSCODE))
ssrc = (*ssrc_in_p)->ssrc_map_out;
// out direction
mutex_lock(&out_srtp->out_lock);
@ -1297,14 +1298,14 @@ static void media_packet_rtp(struct packet_handler_ctx *phc)
rtp_padding(phc->mp.rtp, &phc->mp.payload);
if (G_LIKELY(phc->out_srtp != NULL))
__stream_ssrc(phc->in_srtp, phc->out_srtp, phc->mp.rtp->ssrc, &phc->ssrc_in,
&phc->ssrc_out, phc->call->ssrc_hash);
__stream_ssrc(phc->in_srtp, phc->out_srtp, phc->mp.rtp->ssrc, &phc->mp.ssrc_in,
&phc->mp.ssrc_out, phc->call->ssrc_hash);
// check the payload type
// XXX redundant between SSRC handling and codec_handler stuff -> combine
phc->payload_type = (phc->mp.rtp->m_pt & 0x7f);
if (G_LIKELY(phc->ssrc_in))
phc->ssrc_in->parent->payload_type = phc->payload_type;
if (G_LIKELY(phc->mp.ssrc_in))
phc->mp.ssrc_in->parent->payload_type = phc->payload_type;
// XXX convert to array? or keep last pointer?
// XXX yet another hash table per payload type -> combine
@ -1323,8 +1324,8 @@ static void media_packet_rtp(struct packet_handler_ctx *phc)
}
else if (phc->rtcp && !rtcp_payload(&phc->mp.rtcp, NULL, &phc->s)) {
if (G_LIKELY(phc->out_srtp != NULL))
__stream_ssrc(phc->in_srtp, phc->out_srtp, phc->mp.rtcp->ssrc, &phc->ssrc_in,
&phc->ssrc_out, phc->call->ssrc_hash);
__stream_ssrc(phc->in_srtp, phc->out_srtp, phc->mp.rtcp->ssrc, &phc->mp.ssrc_in,
&phc->mp.ssrc_out, phc->call->ssrc_hash);
}
}
@ -1348,7 +1349,7 @@ static int media_packet_decrypt(struct packet_handler_ctx *phc)
* 1 = forward and push update to redis */
int ret = 0;
if (phc->decrypt_func)
ret = phc->decrypt_func(&phc->s, phc->in_srtp, phc->sfd, &phc->fsin, &phc->tv, phc->ssrc_in);
ret = phc->decrypt_func(&phc->s, phc->in_srtp, phc->sfd, &phc->fsin, &phc->tv, phc->mp.ssrc_in);
mutex_unlock(&phc->in_srtp->in_lock);
@ -1367,9 +1368,9 @@ static int media_packet_encrypt(struct packet_handler_ctx *phc) {
mutex_lock(&phc->out_srtp->out_lock);
for (GList *l = phc->packets_out.head; l; l = l->next) {
for (GList *l = phc->mp.packets_out.head; l; l = l->next) {
struct codec_packet *p = l->data;
int encret = phc->encrypt_func(&p->s, phc->out_srtp, NULL, NULL, NULL, phc->ssrc_out);
int encret = phc->encrypt_func(&p->s, phc->out_srtp, NULL, NULL, NULL, phc->mp.ssrc_out);
if (encret == 1)
phc->update = 1;
else if (encret != 0)
@ -1599,7 +1600,7 @@ static int stream_packet(struct packet_handler_ctx *phc) {
struct codec_handler *transcoder = codec_handler_get(phc->media, phc->payload_type);
// this transfers the packet from 's' to 'packets_out'
phc->mp.raw = phc->s;
if (transcoder->func(transcoder, phc->media, &phc->mp, &phc->packets_out))
if (transcoder->func(transcoder, phc->media, &phc->mp))
goto drop;
if (G_LIKELY(handler_ret >= 0))
@ -1630,7 +1631,7 @@ static int stream_packet(struct packet_handler_ctx *phc) {
struct codec_packet *p;
ret = 0;
while ((p = g_queue_pop_head(&phc->packets_out))) {
while ((p = g_queue_pop_head(&phc->mp.packets_out))) {
__C_DBG("Forward to sink endpoint: %s:%d", sockaddr_print_buf(&phc->sink->endpoint.address),
phc->sink->endpoint.port);
@ -1670,7 +1671,7 @@ out:
rwlock_unlock_r(&phc->call->master_lock);
g_queue_clear_full(&phc->packets_out, codec_packet_free);
g_queue_clear_full(&phc->mp.packets_out, codec_packet_free);
return ret;
}

@ -72,7 +72,10 @@ struct media_packet {
str raw;
struct rtp_header *rtp;
struct rtcp_packet *rtcp;
struct ssrc_ctx *ssrc_in, *ssrc_out; // SSRC contexts from in_srtp and out_srtp
str payload;
GQueue packets_out;
};

@ -8,6 +8,7 @@
static void init_ssrc_ctx(struct ssrc_ctx *c, struct ssrc_entry_call *parent) {
c->parent = parent;
c->ssrc_map_out = random();
}
static void init_ssrc_entry(struct ssrc_entry *ent, u_int32_t ssrc) {
ent->ssrc = ssrc;

@ -40,6 +40,7 @@ struct ssrc_ctx {
u_int64_t srtp_index,
srtcp_index;
// XXX move entire crypto context in here?
u_int32_t ssrc_map_out;
};
struct ssrc_stats_block {

Loading…
Cancel
Save