Skip to content

Commit

Permalink
Fixed bitrate settings not working in MCU (issue meetecho#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
meetecho committed Nov 25, 2014
1 parent 291d85c commit d60a964
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 76 deletions.
126 changes: 50 additions & 76 deletions plugins/janus_videoroom.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ typedef struct janus_videoroom_participant {
gboolean video_active;
gboolean firefox; /* We send Firefox users a different kind of FIR */
uint64_t bitrate;
gint64 remb_latest; /* Time of latest sent REMB (to avoid flooding) */
gint64 fir_latest; /* Time of latest sent FIR (to avoid flooding) */
gint fir_seq; /* FIR sequence number */
gboolean recording_active; /* Whether this publisher has to be recorded or not */
Expand Down Expand Up @@ -1105,10 +1106,7 @@ void janus_videoroom_setup_media(janus_plugin_session *handle) {
/* Send a FIR */
char buf[20];
memset(buf, 0, 20);
if(!p->firefox)
janus_rtcp_fir((char *)&buf, 20, &p->fir_seq);
else
janus_rtcp_fir_legacy((char *)&buf, 20, &p->fir_seq);
janus_rtcp_fir((char *)&buf, 20, &p->fir_seq);
JANUS_LOG(LOG_VERB, "New listener available, sending FIR to %"SCNu64" (%s)\n", p->user_id, p->display ? p->display : "??");
gateway->relay_rtcp(p->session->handle, 1, buf, 20);
/* Send a PLI too, just in case... */
Expand All @@ -1132,10 +1130,7 @@ void janus_videoroom_setup_media(janus_plugin_session *handle) {
/* Send a FIR */
char buf[20];
memset(buf, 0, 20);
if(!p->firefox)
janus_rtcp_fir((char *)&buf, 20, &p->fir_seq);
else
janus_rtcp_fir_legacy((char *)&buf, 20, &p->fir_seq);
janus_rtcp_fir((char *)&buf, 20, &p->fir_seq);
JANUS_LOG(LOG_VERB, "New Multiplexed listener available, sending FIR to %"SCNu64" (%s)\n", p->user_id, p->display ? p->display : "??");
gateway->relay_rtcp(p->session->handle, 1, buf, 20);
/* Send a PLI too, just in case... */
Expand Down Expand Up @@ -1178,6 +1173,28 @@ void janus_videoroom_incoming_rtp(janus_plugin_session *handle, int video, char
packet.seq_number = ntohs(packet.data->seq_number);
/* Go */
g_slist_foreach(participant->listeners, janus_videoroom_relay_rtp_packet, &packet);

/* Did we send a REMB already? */
if(video && participant->video_active && participant->remb_latest == 0) {
participant->remb_latest = janus_get_monotonic_time();
char rtcpbuf[200];
memset(rtcpbuf, 0, 200);
/* FIXME First put a RR (fake)... */
int rrlen = 32;
rtcp_rr *rr = (rtcp_rr *)&rtcpbuf;
rr->header.version = 2;
rr->header.type = RTCP_RR;
rr->header.rc = 1;
rr->header.length = htons((rrlen/4)-1);
/* ... then put a SDES... */
int sdeslen = janus_rtcp_sdes((char *)(&rtcpbuf)+rrlen, 200-rrlen, "janusvideo", 10);
if(sdeslen > 0) {
/* ... and then finally a REMB */
janus_rtcp_remb((char *)(&rtcpbuf)+rrlen+sdeslen, 24, participant->bitrate ? participant->bitrate : 1024*1024);
gateway->relay_rtcp(handle, video, rtcpbuf, rrlen+sdeslen+24);
}
}
/* Generate FIR/PLI too, if needed */
if(video && participant->video_active && (participant->room->fir_freq > 0)) {
/* FIXME Very ugly hack to generate RTCP every tot seconds/frames */
gint64 now = janus_get_monotonic_time();
Expand All @@ -1187,71 +1204,20 @@ void janus_videoroom_incoming_rtp(janus_plugin_session *handle, int video, char
char rtcpbuf[24];
memset(rtcpbuf, 0, 24);
janus_rtcp_fir((char *)&rtcpbuf, 20, &participant->fir_seq);
//~ if(!participant->firefox)
//~ janus_rtcp_fir((char *)&rtcpbuf, 20, &participant->fir_seq);
//~ else
//~ janus_rtcp_fir_legacy((char *)&rtcpbuf, 20, &participant->fir_seq);
JANUS_LOG(LOG_VERB, "Sending FIR to %"SCNu64" (%s)\n", participant->user_id, participant->display ? participant->display : "??");
gateway->relay_rtcp(handle, video, rtcpbuf, 20);
/* Send a PLI too, just in case... */
memset(rtcpbuf, 0, 12);
janus_rtcp_pli((char *)&rtcpbuf, 12);
JANUS_LOG(LOG_VERB, "Sending PLI to %"SCNu64" (%s)\n", participant->user_id, participant->display ? participant->display : "??");
gateway->relay_rtcp(handle, video, rtcpbuf, 12);
if(participant->firefox && participant->bitrate > 0) {
/* Now that we're there, let's send a REMB as well */
janus_rtcp_remb((char *)&rtcpbuf, 24, participant->bitrate);
gateway->relay_rtcp(handle, video, rtcpbuf, 24);
}
}
}
}
}

void janus_videoroom_incoming_rtcp(janus_plugin_session *handle, int video, char *buf, int len) {
if(handle == NULL || handle->stopped || stopping || !initialized || !gateway)
return;
janus_videoroom_session *session = (janus_videoroom_session *)handle->plugin_handle;
if(!session || session->destroyed || !session->participant || !video)
return;
if(session->participant_type == janus_videoroom_p_type_subscriber) {
/* FIXME Badly: we're blinding forwarding the listener RTCP to the publisher: this probably means confusing him... */
//~ janus_videoroom_listener *l = (janus_videoroom_listener *)session->participant;
//~ if(l && l->feed) {
//~ janus_videoroom_participant *p = l->feed;
//~ if(p && p->session) {
//~ if((!video && p->audio_active) || (video && p->video_active)) {
//~ if(p->bitrate > 0)
//~ janus_rtcp_cap_remb(buf, len, p->bitrate);
//~ gateway->relay_rtcp(p->session->handle, video, buf, len);
//~ }
//~ }
//~ }
} else if(session->participant_type == janus_videoroom_p_type_subscriber_muxed) {
/* TODO What should we do here? */
} else if(session->participant_type == janus_videoroom_p_type_publisher) {
/* FIXME Badly: we're just bouncing the incoming RTCP back with modified REMB, we need to improve this... */
janus_videoroom_participant *participant = (janus_videoroom_participant *)session->participant;
if(participant && participant->session) {
if((!video && participant->audio_active) || (video && participant->video_active)) {
janus_rtcp_fix_ssrc(buf, len, 1, video ? participant->video_ssrc : participant->audio_ssrc, 0);
if(participant->bitrate > 0)
janus_rtcp_cap_remb(buf, len, participant->bitrate);
gateway->relay_rtcp(handle, video, buf, len);
//~ /* FIXME Badly: we're also blinding forwarding the publisher RTCP to all the listeners: this probably means confusing them... */
//~ if(participant->listeners != NULL) {
//~ GSList *ps = participant->listeners;
//~ while(ps) {
//~ janus_videoroom_listener *l = (janus_videoroom_listener *)ps->data;
//~ if(l->session && l->session->handle) {
//~ gateway->relay_rtcp(l->session->handle, video, buf, len);
//~ }
//~ ps = ps->next;
//~ }
//~ }
}
}
}
/* FIXME We ignore incoming RTCP, should we care? */
}

void janus_videoroom_incoming_data(janus_plugin_session *handle, char *buf, int len) {
Expand Down Expand Up @@ -1291,6 +1257,7 @@ void janus_videoroom_hangup_media(janus_plugin_session *handle) {
participant->firefox = FALSE;
participant->audio_active = FALSE;
participant->video_active = FALSE;
participant->remb_latest = 0;
participant->fir_latest = 0;
participant->fir_seq = 0;
janus_mutex_lock(&participant->listeners_mutex);
Expand Down Expand Up @@ -1559,6 +1526,7 @@ static void *janus_videoroom_handler(void *data) {
janus_mutex_init(&publisher->listeners_mutex);
publisher->audio_ssrc = g_random_int();
publisher->video_ssrc = g_random_int();
publisher->remb_latest = 0;
publisher->fir_latest = 0;
publisher->fir_seq = 0;
/* In case we also wanted to configure */
Expand Down Expand Up @@ -1842,6 +1810,24 @@ static void *janus_videoroom_handler(void *data) {
if(bitrate) {
participant->bitrate = json_integer_value(bitrate);
JANUS_LOG(LOG_VERB, "Setting video bitrate: %"SCNu64" (room %"SCNu64", user %"SCNu64")\n", participant->bitrate, participant->room->room_id, participant->user_id);
/* Send a new REMB */
participant->remb_latest = janus_get_monotonic_time();
char rtcpbuf[200];
memset(rtcpbuf, 0, 200);
/* FIXME First put a RR (fake)... */
int rrlen = 32;
rtcp_rr *rr = (rtcp_rr *)&rtcpbuf;
rr->header.version = 2;
rr->header.type = RTCP_RR;
rr->header.rc = 1;
rr->header.length = htons((rrlen/4)-1);
/* ... then put a SDES... */
int sdeslen = janus_rtcp_sdes((char *)(&rtcpbuf)+rrlen, 200-rrlen, "janusvideo", 10);
if(sdeslen > 0) {
/* ... and then finally a REMB */
janus_rtcp_remb((char *)(&rtcpbuf)+rrlen+sdeslen, 24, participant->bitrate ? participant->bitrate : 1024*1024);
gateway->relay_rtcp(msg->handle, 1, rtcpbuf, rrlen+sdeslen+24);
}
}
gboolean prev_recording_active = participant->recording_active;
if(record) {
Expand Down Expand Up @@ -1911,10 +1897,7 @@ static void *janus_videoroom_handler(void *data) {
/* Send a FIR */
char buf[20];
memset(buf, 0, 20);
if(!participant->firefox)
janus_rtcp_fir((char *)&buf, 20, &participant->fir_seq);
else
janus_rtcp_fir_legacy((char *)&buf, 20, &participant->fir_seq);
janus_rtcp_fir((char *)&buf, 20, &participant->fir_seq);
JANUS_LOG(LOG_VERB, "Recording video, sending FIR to %"SCNu64" (%s)\n",
participant->user_id, participant->display ? participant->display : "??");
gateway->relay_rtcp(participant->session->handle, 1, buf, 20);
Expand Down Expand Up @@ -2004,10 +1987,7 @@ static void *janus_videoroom_handler(void *data) {
/* Send a FIR */
char buf[20];
memset(buf, 0, 20);
if(!publisher->firefox)
janus_rtcp_fir((char *)&buf, 20, &publisher->fir_seq);
else
janus_rtcp_fir_legacy((char *)&buf, 20, &publisher->fir_seq);
janus_rtcp_fir((char *)&buf, 20, &publisher->fir_seq);
JANUS_LOG(LOG_VERB, "Resuming publisher, sending FIR to %"SCNu64" (%s)\n", publisher->user_id, publisher->display ? publisher->display : "??");
gateway->relay_rtcp(publisher->session->handle, 1, buf, 20);
/* Send a PLI too, just in case... */
Expand Down Expand Up @@ -2064,10 +2044,7 @@ static void *janus_videoroom_handler(void *data) {
/* Send a FIR to the new publisher */
char buf[20];
memset(buf, 0, 20);
if(!publisher->firefox)
janus_rtcp_fir((char *)&buf, 20, &publisher->fir_seq);
else
janus_rtcp_fir_legacy((char *)&buf, 20, &publisher->fir_seq);
janus_rtcp_fir((char *)&buf, 20, &publisher->fir_seq);
JANUS_LOG(LOG_VERB, "Switching existing listener to new publisher, sending FIR to %"SCNu64" (%s)\n", publisher->user_id, publisher->display ? publisher->display : "??");
gateway->relay_rtcp(publisher->session->handle, 1, buf, 20);
/* Send a PLI too, just in case... */
Expand Down Expand Up @@ -2217,10 +2194,7 @@ static void *janus_videoroom_handler(void *data) {
//~ /* Send a FIR */
//~ char buf[20];
//~ memset(buf, 0, 20);
//~ if(!publisher->firefox)
//~ janus_rtcp_fir((char *)&buf, 20, &publisher->fir_seq);
//~ else
//~ janus_rtcp_fir_legacy((char *)&buf, 20, &publisher->fir_seq);
//~ janus_rtcp_fir((char *)&buf, 20, &publisher->fir_seq);
//~ JANUS_LOG(LOG_VERB, "Resuming publisher, sending FIR to %"SCNu64" (%s)\n", publisher->user_id, publisher->display ? publisher->display : "??");
//~ gateway->relay_rtcp(publisher->session->handle, 1, buf, 20);
//~ /* Send a PLI too, just in case... */
Expand Down
27 changes: 27 additions & 0 deletions rtcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,33 @@ int janus_rtcp_cap_remb(char *packet, int len, uint64_t bitrate) {
return 0;
}

/* Generate a new SDES message */
int janus_rtcp_sdes(char *packet, int len, const char *cname, int cnamelen) {
if(packet == NULL || len <= 0 || cname == NULL || cnamelen <= 0)
return -1;
memset(packet, 0, len);
rtcp_header *rtcp = (rtcp_header *)packet;
/* Set header */
rtcp->version = 2;
rtcp->type = RTCP_SDES;
rtcp->rc = 1;
int plen = 12; /* Header + SSRC + CSRC in chunk */
plen += cnamelen+2;
if((cnamelen+2)%4) /* Account for padding */
plen += 4;
if(len < plen) {
JANUS_LOG(LOG_ERR, "Buffer too small for SDES message: %d < %d\n", len, plen);
return -1;
}
rtcp->length = htons((plen/4)-1);
/* Now set SDES stuff */
rtcp_sdes *rtcpsdes = (rtcp_sdes *)rtcp;
rtcpsdes->item.type = 1;
rtcpsdes->item.len = cnamelen;
memcpy(rtcpsdes->item.content, cname, cnamelen);
return plen;
}

/* Generate a new REMB message */
int janus_rtcp_remb(char *packet, int len, uint64_t bitrate) {
if(packet == NULL || len != 24)
Expand Down
8 changes: 8 additions & 0 deletions rtcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,14 @@ uint64_t janus_rtcp_get_remb(char *packet, int len);
* @returns 0 in case of success, -1 on errors */
int janus_rtcp_cap_remb(char *packet, int len, uint64_t bitrate);

/*! \brief Method to generate a new RTCP SDES message
* @param[in] packet The buffer data
* @param[in] len The buffer data length in bytes
* @param[in] cname The CNAME to write
* @param[in] cnamelen The CNAME data length in bytes
* @returns The size of the message, if successful, -1 on errors */
int janus_rtcp_sdes(char *packet, int len, const char *cname, int cnamelen);

/*! \brief Method to generate a new RTCP REMB message to cap the reported bitrate
* @param[in] packet The buffer data (MUST be at least 24 chars)
* @param[in] len The message data length in bytes (MUST be 24)
Expand Down
2 changes: 2 additions & 0 deletions sdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,8 @@ char *janus_sdp_anonymize(const char *sdp) {
sdp_attribute_remove(&m->m_attributes, "candidate");
while(sdp_attribute_find(m->m_attributes, "ssrc"))
sdp_attribute_remove(&m->m_attributes, "ssrc");
while(sdp_attribute_find(m->m_attributes, "ssrc-group"))
sdp_attribute_remove(&m->m_attributes, "ssrc-group");
while(sdp_attribute_find(m->m_attributes, "extmap")) /* TODO Actually implement RTP extensions */
sdp_attribute_remove(&m->m_attributes, "extmap");
while(sdp_attribute_find(m->m_attributes, "sctpmap"))
Expand Down

0 comments on commit d60a964

Please sign in to comment.