Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring of core-plugin callbacks and RTP extensions termination #1884

Merged
merged 9 commits into from
Feb 4, 2020
225 changes: 183 additions & 42 deletions ice.c

Large diffs are not rendered by default.

30 changes: 17 additions & 13 deletions ice.h
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,10 @@ struct janus_ice_stream {
gint mid_ext_id;
/*! \brief RTP Stream extension ID, and the related rtx one */
gint rid_ext_id, ridrtx_ext_id;
/*! \brief Audio levels extension ID */
gint audiolevel_ext_id;
/*! \brief Video orientation extension ID */
gint videoorientation_ext_id;
/*! \brief Frame marking extension ID */
gint framemarking_ext_id;
/*! \brief Whether we do transport wide cc for video */
Expand Down Expand Up @@ -581,23 +585,23 @@ void janus_ice_component_destroy(janus_ice_component *component);
///@{
/*! \brief Core RTP callback, called when a plugin has an RTP packet to send to a peer
* @param[in] handle The Janus ICE handle associated with the peer
* @param[in] video Whether this is an audio or a video frame
* @param[in] buf The packet data (buffer)
* @param[in] len The buffer lenght */
void janus_ice_relay_rtp(janus_ice_handle *handle, int video, char *buf, int len);
* @param[in] packet The RTP packet to send */
void janus_ice_relay_rtp(janus_ice_handle *handle, janus_plugin_rtp *packet);
/*! \brief Core RTCP callback, called when a plugin has an RTCP message to send to a peer
* @param[in] handle The Janus ICE handle associated with the peer
* @param[in] video Whether this is related to an audio or a video stream
* @param[in] buf The message data (buffer)
* @param[in] len The buffer lenght */
void janus_ice_relay_rtcp(janus_ice_handle *handle, int video, char *buf, int len);
* @param[in] packet The RTCP message to send */
void janus_ice_relay_rtcp(janus_ice_handle *handle, janus_plugin_rtcp *packet);
/*! \brief Core SCTP/DataChannel callback, called when a plugin has data to send to a peer
* @param[in] handle The Janus ICE handle associated with the peer
* @param[in] label The label of the data channel to use
* @param[in] textdata Whether the buffer is text (domstring) or binary data
* @param[in] buf The message data (buffer)
* @param[in] len The buffer lenght */
void janus_ice_relay_data(janus_ice_handle *handle, char *label, gboolean textdata, char *buf, int len);
* @param[in] packet The message to send */
void janus_ice_relay_data(janus_ice_handle *handle, janus_plugin_data *packet);
/*! \brief Helper core callback, called when a plugin wants to send a RTCP PLI to a peer
* @param[in] handle The Janus ICE handle associated with the peer */
void janus_ice_send_pli(janus_ice_handle *handle);
/*! \brief Helper core callback, called when a plugin wants to send a RTCP REMB to a peer
* @param[in] handle The Janus ICE handle associated with the peer
* @param[in] bitrate The bitrate value to put in the REMB message */
void janus_ice_send_remb(janus_ice_handle *handle, uint32_t bitrate);
/*! \brief Plugin SCTP/DataChannel callback, called by the SCTP stack when when there's data for a plugin
* @param[in] handle The Janus ICE handle associated with the peer
* @param[in] label The label of the data channel the message is from
Expand Down
99 changes: 79 additions & 20 deletions janus.c
Original file line number Diff line number Diff line change
Expand Up @@ -519,9 +519,11 @@ void janus_transport_task(gpointer data, gpointer user_data);
///@{
int janus_plugin_push_event(janus_plugin_session *plugin_session, janus_plugin *plugin, const char *transaction, json_t *message, json_t *jsep);
json_t *janus_plugin_handle_sdp(janus_plugin_session *plugin_session, janus_plugin *plugin, const char *sdp_type, const char *sdp, gboolean restart);
void janus_plugin_relay_rtp(janus_plugin_session *plugin_session, int video, char *buf, int len);
void janus_plugin_relay_rtcp(janus_plugin_session *plugin_session, int video, char *buf, int len);
void janus_plugin_relay_data(janus_plugin_session *plugin_session, char *label, gboolean textdata, char *buf, int len);
void janus_plugin_relay_rtp(janus_plugin_session *plugin_session, janus_plugin_rtp *packet);
void janus_plugin_relay_rtcp(janus_plugin_session *plugin_session, janus_plugin_rtcp *packet);
void janus_plugin_relay_data(janus_plugin_session *plugin_session, janus_plugin_data *message);
void janus_plugin_send_pli(janus_plugin_session *plugin_session);
void janus_plugin_send_remb(janus_plugin_session *plugin_session, uint32_t bitrate);
void janus_plugin_close_pc(janus_plugin_session *plugin_session);
void janus_plugin_end_session(janus_plugin_session *plugin_session);
void janus_plugin_notify_event(janus_plugin *plugin, janus_plugin_session *plugin_session, json_t *event);
Expand All @@ -533,6 +535,8 @@ static janus_callbacks janus_handler_plugin =
.relay_rtp = janus_plugin_relay_rtp,
.relay_rtcp = janus_plugin_relay_rtcp,
.relay_data = janus_plugin_relay_data,
.send_pli = janus_plugin_send_pli,
.send_remb = janus_plugin_send_remb,
.close_pc = janus_plugin_close_pc,
.end_session = janus_plugin_end_session,
.events_is_enabled = janus_events_is_enabled,
Expand Down Expand Up @@ -1340,6 +1344,10 @@ int janus_process_incoming_request(janus_request *request) {
/* Check if the RTP Stream ID extension is being negotiated */
handle->stream->rid_ext_id = janus_rtp_header_extension_get_id(jsep_sdp, JANUS_RTP_EXTMAP_RID);
handle->stream->ridrtx_ext_id = janus_rtp_header_extension_get_id(jsep_sdp, JANUS_RTP_EXTMAP_REPAIRED_RID);
/* Check if the audio level ID extension is being negotiated */
handle->stream->audiolevel_ext_id = janus_rtp_header_extension_get_id(jsep_sdp, JANUS_RTP_EXTMAP_AUDIO_LEVEL);
/* Check if the video orientation ID extension is being negotiated */
handle->stream->videoorientation_ext_id = janus_rtp_header_extension_get_id(jsep_sdp, JANUS_RTP_EXTMAP_VIDEO_ORIENTATION);
/* Check if the frame marking ID extension is being negotiated */
handle->stream->framemarking_ext_id = janus_rtp_header_extension_get_id(jsep_sdp, JANUS_RTP_EXTMAP_FRAME_MARKING);
/* Check if transport wide CC is supported */
Expand Down Expand Up @@ -2771,6 +2779,20 @@ json_t *janus_admin_stream_summary(janus_ice_stream *stream) {
json_object_set_new(sc, "video-codec", json_string(stream->video_codec));
json_object_set_new(s, "codecs", sc);
}
json_t *se = json_object();
if(stream->mid_ext_id > 0)
json_object_set_new(se, JANUS_RTP_EXTMAP_MID, json_integer(stream->mid_ext_id));
if(stream->rid_ext_id > 0)
json_object_set_new(se, JANUS_RTP_EXTMAP_RID, json_integer(stream->rid_ext_id));
if(stream->ridrtx_ext_id > 0)
json_object_set_new(se, JANUS_RTP_EXTMAP_REPAIRED_RID, json_integer(stream->ridrtx_ext_id));
if(stream->transport_wide_cc_ext_id > 0)
json_object_set_new(se, JANUS_RTP_EXTMAP_TRANSPORT_WIDE_CC, json_integer(stream->transport_wide_cc_ext_id));
if(stream->audiolevel_ext_id > 0)
json_object_set_new(se, JANUS_RTP_EXTMAP_AUDIO_LEVEL, json_integer(stream->audiolevel_ext_id));
if(stream->videoorientation_ext_id > 0)
json_object_set_new(se, JANUS_RTP_EXTMAP_VIDEO_ORIENTATION, json_integer(stream->videoorientation_ext_id));
json_object_set_new(s, "extensions", se);
json_t *bwe = json_object();
json_object_set_new(bwe, "twcc", stream->do_transport_wide_cc ? json_true() : json_false());
if(stream->transport_wide_cc_ext_id > 0)
Expand Down Expand Up @@ -3355,25 +3377,39 @@ json_t *janus_plugin_handle_sdp(janus_plugin_session *plugin_session, janus_plug
}
}
}
/* Make sure we don't send the mid/rid/repaired-rid attributes when offering ourselves */
/* Make sure we don't send the rid/repaired-rid attributes when offering ourselves */
int mid_ext_id = 0, audiolevel_ext_id = 0, videoorientation_ext_id = 0;
GList *temp = parsed_sdp->m_lines;
while(temp) {
janus_sdp_mline *m = (janus_sdp_mline *)temp->data;
GList *tempA = m->attributes;
while(tempA) {
janus_sdp_attribute *a = (janus_sdp_attribute *)tempA->data;
if(a->name && a->value && (strstr(a->value, JANUS_RTP_EXTMAP_MID) ||
strstr(a->value, JANUS_RTP_EXTMAP_RID) ||
strstr(a->value, JANUS_RTP_EXTMAP_REPAIRED_RID))) {
m->attributes = g_list_remove(m->attributes, a);
tempA = m->attributes;
janus_sdp_attribute_destroy(a);
continue;
if(a->name && a->value) {
if(strstr(a->value, JANUS_RTP_EXTMAP_MID))
mid_ext_id = atoi(a->value);
else if(strstr(a->value, JANUS_RTP_EXTMAP_AUDIO_LEVEL))
audiolevel_ext_id = atoi(a->value);
else if(strstr(a->value, JANUS_RTP_EXTMAP_VIDEO_ORIENTATION))
videoorientation_ext_id = atoi(a->value);
else if(strstr(a->value, JANUS_RTP_EXTMAP_RID) ||
strstr(a->value, JANUS_RTP_EXTMAP_REPAIRED_RID)) {
m->attributes = g_list_remove(m->attributes, a);
tempA = m->attributes;
janus_sdp_attribute_destroy(a);
continue;
}
}
tempA = tempA->next;
}
temp = temp->next;
}
if(ice_handle->stream && ice_handle->stream->mid_ext_id != mid_ext_id)
ice_handle->stream->mid_ext_id = mid_ext_id;
if(ice_handle->stream && ice_handle->stream->audiolevel_ext_id != audiolevel_ext_id)
ice_handle->stream->audiolevel_ext_id = audiolevel_ext_id;
if(ice_handle->stream && ice_handle->stream->videoorientation_ext_id != videoorientation_ext_id)
ice_handle->stream->videoorientation_ext_id = videoorientation_ext_id;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Up to you but I find:

if(ice_handle->stream) {
	ice_handle->stream->mid_ext_id = mid_ext_id;
	ice_handle->stream->audiolevel_ext_id = audiolevel_ext_id;
	ice_handle->stream->videoorientation_ext_id = videoorientation_ext_id;
}

a bit easier on the eyes (basically choosing between 3 noop assignments instead of 3 comparisons)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was like that because there were things I only had to do when detecting a change, while your suggestion would always be assigning a value.

} else {
/* Check if the answer does contain the mid/rid/repaired-rid attributes */
gboolean do_mid = FALSE, do_rid = FALSE, do_repaired_rid = FALSE;
Expand Down Expand Up @@ -3531,40 +3567,63 @@ json_t *janus_plugin_handle_sdp(janus_plugin_session *plugin_session, janus_plug
return jsep;
}

void janus_plugin_relay_rtp(janus_plugin_session *plugin_session, int video, char *buf, int len) {
if((plugin_session < (janus_plugin_session *)0x1000) || g_atomic_int_get(&plugin_session->stopped) || buf == NULL || len < 1)
void janus_plugin_relay_rtp(janus_plugin_session *plugin_session, janus_plugin_rtp *packet) {
if((plugin_session < (janus_plugin_session *)0x1000) || g_atomic_int_get(&plugin_session->stopped) ||
packet == NULL || packet->buffer == NULL || packet->length < 1)
return;
janus_ice_handle *handle = (janus_ice_handle *)plugin_session->gateway_handle;
if(!handle || janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_STOP)
|| janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_ALERT))
return;
janus_ice_relay_rtp(handle, video, buf, len);
janus_ice_relay_rtp(handle, packet);
}

void janus_plugin_relay_rtcp(janus_plugin_session *plugin_session, int video, char *buf, int len) {
if((plugin_session < (janus_plugin_session *)0x1000) || g_atomic_int_get(&plugin_session->stopped) || buf == NULL || len < 1)
void janus_plugin_relay_rtcp(janus_plugin_session *plugin_session, janus_plugin_rtcp *packet) {
if((plugin_session < (janus_plugin_session *)0x1000) || g_atomic_int_get(&plugin_session->stopped) ||
packet == NULL || packet->buffer == NULL || packet->length < 1)
return;
janus_ice_handle *handle = (janus_ice_handle *)plugin_session->gateway_handle;
if(!handle || janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_STOP)
|| janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_ALERT))
return;
janus_ice_relay_rtcp(handle, video, buf, len);
janus_ice_relay_rtcp(handle, packet);
}

void janus_plugin_relay_data(janus_plugin_session *plugin_session, char *label, gboolean textdata, char *buf, int len) {
if((plugin_session < (janus_plugin_session *)0x1000) || g_atomic_int_get(&plugin_session->stopped) || buf == NULL || len < 1)
void janus_plugin_relay_data(janus_plugin_session *plugin_session, janus_plugin_data *packet) {
if((plugin_session < (janus_plugin_session *)0x1000) || g_atomic_int_get(&plugin_session->stopped) ||
packet == NULL || packet->buffer == NULL || packet->length < 1)
return;
janus_ice_handle *handle = (janus_ice_handle *)plugin_session->gateway_handle;
if(!handle || janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_STOP)
|| janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_ALERT))
return;
#ifdef HAVE_SCTP
janus_ice_relay_data(handle, label, textdata, buf, len);
janus_ice_relay_data(handle, packet);
#else
JANUS_LOG(LOG_WARN, "Asked to relay data, but Data Channels support has not been compiled...\n");
#endif
}

void janus_plugin_send_pli(janus_plugin_session *plugin_session) {
if((plugin_session < (janus_plugin_session *)0x1000) || g_atomic_int_get(&plugin_session->stopped))
return;
janus_ice_handle *handle = (janus_ice_handle *)plugin_session->gateway_handle;
if(!handle || janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_STOP)
|| janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_ALERT))
return;
janus_ice_send_pli(handle);
}

void janus_plugin_send_remb(janus_plugin_session *plugin_session, uint32_t bitrate) {
if((plugin_session < (janus_plugin_session *)0x1000) || g_atomic_int_get(&plugin_session->stopped))
return;
janus_ice_handle *handle = (janus_ice_handle *)plugin_session->gateway_handle;
if(!handle || janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_STOP)
|| janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_ALERT))
return;
janus_ice_send_remb(handle, bitrate);
}

static gboolean janus_plugin_close_pc_internal(gpointer user_data) {
/* We actually enforce the close_pc here */
janus_plugin_session *plugin_session = (janus_plugin_session *) user_data;
Expand Down
25 changes: 16 additions & 9 deletions plugins/janus_audiobridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -693,8 +693,8 @@ void janus_audiobridge_create_session(janus_plugin_session *handle, int *error);
struct janus_plugin_result *janus_audiobridge_handle_message(janus_plugin_session *handle, char *transaction, json_t *message, json_t *jsep);
json_t *janus_audiobridge_handle_admin_message(json_t *message);
void janus_audiobridge_setup_media(janus_plugin_session *handle);
void janus_audiobridge_incoming_rtp(janus_plugin_session *handle, int video, char *buf, int len);
void janus_audiobridge_incoming_rtcp(janus_plugin_session *handle, int video, char *buf, int len);
void janus_audiobridge_incoming_rtp(janus_plugin_session *handle, janus_plugin_rtp *packet);
void janus_audiobridge_incoming_rtcp(janus_plugin_session *handle, janus_plugin_rtcp *packet);
void janus_audiobridge_hangup_media(janus_plugin_session *handle);
void janus_audiobridge_destroy_session(janus_plugin_session *handle, int *error);
json_t *janus_audiobridge_query_session(janus_plugin_session *handle);
Expand Down Expand Up @@ -3185,7 +3185,7 @@ void janus_audiobridge_setup_media(janus_plugin_session *handle) {
janus_mutex_unlock(&rooms_mutex);
}

void janus_audiobridge_incoming_rtp(janus_plugin_session *handle, int video, char *buf, int len) {
void janus_audiobridge_incoming_rtp(janus_plugin_session *handle, janus_plugin_rtp *packet) {
if(handle == NULL || g_atomic_int_get(&handle->stopped) || g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
return;
janus_audiobridge_session *session = (janus_audiobridge_session *)handle->plugin_handle;
Expand All @@ -3194,6 +3194,8 @@ void janus_audiobridge_incoming_rtp(janus_plugin_session *handle, int video, cha
janus_audiobridge_participant *participant = (janus_audiobridge_participant *)session->participant;
if(!g_atomic_int_get(&participant->active) || participant->muted || !participant->decoder || !participant->room)
return;
char *buf = packet->buffer;
uint16_t len = packet->length;
/* Save the frame if we're recording this leg */
janus_recorder_save_frame(participant->arc, buf, len);
if(g_atomic_int_get(&participant->active) && participant->decoder) {
Expand Down Expand Up @@ -3247,8 +3249,8 @@ void janus_audiobridge_incoming_rtp(janus_plugin_session *handle, int video, cha

if(participant->extmap_id > 0) {
/* Check the audio levels, in case we need to notify participants about who's talking */
int level = 0;
if(janus_rtp_header_extension_parse_audio_level(buf, len, participant->extmap_id, &level) == 0) {
int level = packet->extensions.audio_level;
if(level != -1) {
/* Is this silence? */
pkt->silence = (level == 127);
if(participant->room && participant->room->audiolevel_event) {
Expand Down Expand Up @@ -3426,7 +3428,7 @@ void janus_audiobridge_incoming_rtp(janus_plugin_session *handle, int video, cha
}
}

void janus_audiobridge_incoming_rtcp(janus_plugin_session *handle, int video, char *buf, int len) {
void janus_audiobridge_incoming_rtcp(janus_plugin_session *handle, janus_plugin_rtcp *packet) {
if(handle == NULL || g_atomic_int_get(&handle->stopped) || g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
return;
/* FIXME Should we care? */
Expand Down Expand Up @@ -4471,6 +4473,7 @@ static void *janus_audiobridge_handler(void *data) {
/* Reject video and data channels, if offered */
JANUS_SDP_OA_VIDEO, FALSE,
JANUS_SDP_OA_DATA, FALSE,
JANUS_SDP_OA_ACCEPT_EXTMAP, JANUS_RTP_EXTMAP_MID,
JANUS_SDP_OA_ACCEPT_EXTMAP, JANUS_RTP_EXTMAP_AUDIO_LEVEL,
JANUS_SDP_OA_DONE);
/* Replace the session name */
Expand Down Expand Up @@ -4954,9 +4957,13 @@ static void janus_audiobridge_relay_rtp_packet(gpointer data, gpointer user_data
packet->data->type = participant->opus_pt;
/* Fix sequence number and timestamp (room switching may be involved) */
janus_rtp_header_update(packet->data, &participant->context, FALSE, OPUS_SAMPLES);
if(gateway != NULL)
gateway->relay_rtp(session->handle, 0, (char *)packet->data, packet->length);
/* Restore the timestamp and sequence number to what the publisher set them to */
if(gateway != NULL) {
janus_plugin_rtp rtp = { .video = FALSE, .buffer = (char *)packet->data, .length = packet->length };
janus_plugin_rtp_extensions_reset(&rtp.extensions);
/* FIXME Should we add our own audio level extension? */
gateway->relay_rtp(session->handle, &rtp);
}
/* Restore the timestamp and sequence number to what the mixer set them to */
packet->data->timestamp = htonl(packet->timestamp);
packet->data->seq_number = htons(packet->seq_number);
}
Loading