Browse Source

TT#31403 move SSRC mapping out of codec handler

Change-Id: Id5babcef6440f40e45e7e23afc54398a39093a3f
changes/57/18857/7
Richard Fuchs 8 years ago
parent
commit
159729ad0d
7 changed files with 32 additions and 31 deletions
  1. +2
    -2
      daemon/call.h
  2. +9
    -13
      daemon/codec.c
  3. +1
    -2
      daemon/codec.h
  4. +15
    -14
      daemon/media_socket.c
  5. +3
    -0
      daemon/media_socket.h
  6. +1
    -0
      daemon/ssrc.c
  7. +1
    -0
      daemon/ssrc.h

+ 2
- 2
daemon/call.h View File

@ -282,7 +282,7 @@ struct packet_stream {
struct endpoint endpoint; /* LOCK: out_lock */ struct endpoint endpoint; /* LOCK: out_lock */
struct endpoint advertised_endpoint; /* RO */ struct endpoint advertised_endpoint; /* RO */
struct crypto_context crypto; /* OUT direction, LOCK: out_lock */ 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 */ *ssrc_out; /* LOCK: out_lock */
struct stats stats; struct stats stats;
@ -340,7 +340,7 @@ struct call_media {
GQueue codecs_prefs_send; // storage container GQueue codecs_prefs_send; // storage container
GHashTable *codec_handlers; // int payload type -> struct codec_handler 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; volatile struct codec_handler *codec_handler_cache;
int ptime; // either from SDP or overridden int ptime; // either from SDP or overridden


+ 9
- 13
daemon/codec.c View File

@ -21,7 +21,6 @@ struct codec_ssrc_handler {
int ptime; int ptime;
int bytes_per_packet; int bytes_per_packet;
unsigned long ts_out; unsigned long ts_out;
u_int32_t ssrc_out;
u_int16_t seq_out; u_int16_t seq_out;
GString *sample_buffer; 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, 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)); struct codec_packet *p = g_slice_alloc(sizeof(*p));
p->s = mp->raw; p->s = mp->raw;
p->free_func = NULL; p->free_func = NULL;
g_queue_push_tail(out, p);
g_queue_push_tail(&mp->packets_out, p);
return 0; return 0;
} }
@ -385,13 +384,11 @@ static void __transcode_packet_free(struct transcode_packet *p) {
static struct ssrc_entry *__ssrc_handler_new(void *p) { static struct ssrc_entry *__ssrc_handler_new(void *p) {
struct codec_handler *h = p; struct codec_handler *h = p;
u_int32_t ssrc_out = random();
ilog(LOG_DEBUG, "Creating SSRC transcoder from %s/%u/%i to " 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.codec_def->rtpname, h->source_pt.clock_rate,
h->source_pt.channels, h->source_pt.channels,
ntohl(ssrc_out),
h->dest_pt.codec_def->rtpname, h->dest_pt.clock_rate, h->dest_pt.codec_def->rtpname, h->dest_pt.clock_rate,
h->dest_pt.channels); h->dest_pt.channels);
@ -400,7 +397,6 @@ static struct ssrc_entry *__ssrc_handler_new(void *p) {
mutex_init(&ch->lock); mutex_init(&ch->lock);
packet_sequencer_init(&ch->sequencer, (GDestroyNotify) __transcode_packet_free); packet_sequencer_init(&ch->sequencer, (GDestroyNotify) __transcode_packet_free);
ch->seq_out = random(); ch->seq_out = random();
ch->ssrc_out = ssrc_out;
ch->ts_out = random(); ch->ts_out = random();
ch->ptime = h->dest_pt.ptime; ch->ptime = h->dest_pt.ptime;
ch->sample_buffer = g_string_new(""); 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) { static int __packet_encoded(encoder_t *enc, void *u1, void *u2) {
struct codec_ssrc_handler *ch = u1; 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", ilog(LOG_DEBUG, "RTP media successfully encoded: TS %llu, len %i",
(unsigned long long) enc->avpkt.pts, enc->avpkt.size); (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->m_pt = ch->handler->dest_pt.payload_type;
rh->seq_num = htons(ch->seq_out++); rh->seq_num = htons(ch->seq_out++);
rh->timestamp = htonl(enc->avpkt.pts + ch->ts_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 // add to output queue
struct codec_packet *p = g_slice_alloc(sizeof(*p)); struct codec_packet *p = g_slice_alloc(sizeof(*p));
p->s.s = buf; p->s.s = buf;
p->s.len = inout.len + sizeof(struct rtp_header); p->s.len = inout.len + sizeof(struct rtp_header);
p->free_func = free; p->free_func = free;
g_queue_push_tail(out_q, p);
g_queue_push_tail(&mp->packets_out, p);
if (ret == 0) { if (ret == 0) {
// no more to go // 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, 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)) 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); 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", ilog(LOG_DEBUG, "Decoding RTP packet: seq %u, TS %lu",
packet->p.seq, packet->ts); 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"); ilog(LOG_WARN, "Decoder error while processing RTP packet");
__transcode_packet_free(packet); __transcode_packet_free(packet);
} }


+ 1
- 2
daemon/codec.h View File

@ -15,8 +15,7 @@ struct media_packet;
struct ssrc_hash; 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 { struct codec_handler {


+ 15
- 14
daemon/media_socket.c View File

@ -70,7 +70,6 @@ struct packet_handler_ctx {
rewrite_func decrypt_func, encrypt_func; // handlers for decrypt/encrypt 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) 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 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 int rtcp; // true if this is an RTCP packet
// verdicts: // verdicts:
@ -80,7 +79,6 @@ struct packet_handler_ctx {
// output: // output:
struct media_packet mp; // passed to handlers 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); mutex_unlock(&in_srtp->in_lock);
if (MEDIA_ISSET(in_srtp->media, TRANSCODE))
ssrc = (*ssrc_in_p)->ssrc_map_out;
// out direction // out direction
mutex_lock(&out_srtp->out_lock); 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); rtp_padding(phc->mp.rtp, &phc->mp.payload);
if (G_LIKELY(phc->out_srtp != NULL)) 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 // check the payload type
// XXX redundant between SSRC handling and codec_handler stuff -> combine // XXX redundant between SSRC handling and codec_handler stuff -> combine
phc->payload_type = (phc->mp.rtp->m_pt & 0x7f); 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 convert to array? or keep last pointer?
// XXX yet another hash table per payload type -> combine // 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)) { else if (phc->rtcp && !rtcp_payload(&phc->mp.rtcp, NULL, &phc->s)) {
if (G_LIKELY(phc->out_srtp != NULL)) 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 */ * 1 = forward and push update to redis */
int ret = 0; int ret = 0;
if (phc->decrypt_func) 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); 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); 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; 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) if (encret == 1)
phc->update = 1; phc->update = 1;
else if (encret != 0) 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); struct codec_handler *transcoder = codec_handler_get(phc->media, phc->payload_type);
// this transfers the packet from 's' to 'packets_out' // this transfers the packet from 's' to 'packets_out'
phc->mp.raw = phc->s; 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; goto drop;
if (G_LIKELY(handler_ret >= 0)) if (G_LIKELY(handler_ret >= 0))
@ -1630,7 +1631,7 @@ static int stream_packet(struct packet_handler_ctx *phc) {
struct codec_packet *p; struct codec_packet *p;
ret = 0; 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), __C_DBG("Forward to sink endpoint: %s:%d", sockaddr_print_buf(&phc->sink->endpoint.address),
phc->sink->endpoint.port); phc->sink->endpoint.port);
@ -1670,7 +1671,7 @@ out:
rwlock_unlock_r(&phc->call->master_lock); 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; return ret;
} }


+ 3
- 0
daemon/media_socket.h View File

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


+ 1
- 0
daemon/ssrc.c View File

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


+ 1
- 0
daemon/ssrc.h View File

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


Loading…
Cancel
Save