Skip to content

Commit

Permalink
Made RTP context and rewriting part of the core, rather than plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
lminiero committed Feb 27, 2017
1 parent 64181d9 commit e8323e1
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 205 deletions.
31 changes: 3 additions & 28 deletions plugins/janus_audiobridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -755,12 +755,6 @@ static GHashTable *sessions;
static GList *old_sessions;
static janus_mutex sessions_mutex;

typedef struct janus_audiobridge_rtp_context {
/* Needed to fix seq and ts in case of publisher switching */
uint32_t a_last_ssrc, a_last_ts, a_base_ts, a_base_ts_prev;
uint16_t a_last_seq, a_base_seq, a_base_seq_prev;
} janus_audiobridge_rtp_context;

typedef struct janus_audiobridge_participant {
janus_audiobridge_session *session;
janus_audiobridge_room *room; /* Room */
Expand All @@ -780,7 +774,7 @@ typedef struct janus_audiobridge_participant {
int opus_pt; /* Opus payload type */
int extmap_id; /* Audio level RTP extension id, if any */
int dBov_level; /* Value in dBov of the audio level (last value from extension) */
janus_audiobridge_rtp_context context; /* Needed in case the participant changes room */
janus_rtp_switching_context context; /* Needed in case the participant changes room */
/* Opus stuff */
OpusEncoder *encoder; /* Opus encoder instance */
OpusDecoder *decoder; /* Opus decoder instance */
Expand Down Expand Up @@ -2567,13 +2561,7 @@ static void *janus_audiobridge_handler(void *data) {
participant->active = session->started;
if(!session->started) {
/* Initialize the RTP context only if we're renegotiating */
participant->context.a_last_ssrc = 0;
participant->context.a_last_ts = 0;
participant->context.a_base_ts = 0;
participant->context.a_base_ts_prev = 0;
participant->context.a_last_seq = 0;
participant->context.a_base_seq = 0;
participant->context.a_base_seq_prev = 0;
janus_rtp_switching_context_reset(&participant->context);
participant->opus_pt = 0;
participant->extmap_id = 0;
participant->dBov_level = 0;
Expand Down Expand Up @@ -3739,20 +3727,7 @@ static void janus_audiobridge_relay_rtp_packet(gpointer data, gpointer user_data
/* Set the payload type */
packet->data->type = participant->opus_pt;
/* Fix sequence number and timestamp (room switching may be involved) */
if(ntohl(packet->data->ssrc) != participant->context.a_last_ssrc) {
participant->context.a_last_ssrc = ntohl(packet->data->ssrc);
participant->context.a_base_ts_prev = participant->context.a_last_ts;
participant->context.a_base_ts = packet->timestamp;
participant->context.a_base_seq_prev = participant->context.a_last_seq;
participant->context.a_base_seq = packet->seq_number;
}
/* Compute a coherent timestamp and sequence number */
participant->context.a_last_ts = (packet->timestamp-participant->context.a_base_ts)
+ participant->context.a_base_ts_prev+960; /* FIXME When switching, we assume Opus and so a 960 ts step */
participant->context.a_last_seq = (packet->seq_number-participant->context.a_base_seq)+participant->context.a_base_seq_prev+1;
/* Update the timestamp and sequence number in the RTP packet, and send it */
packet->data->timestamp = htonl(participant->context.a_last_ts);
packet->data->seq_number = htons(participant->context.a_last_seq);
janus_rtp_header_update(packet->data, &participant->context, FALSE, 960);
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 */
Expand Down
63 changes: 4 additions & 59 deletions plugins/janus_sip.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,14 +322,6 @@ typedef struct janus_sip_account {
janus_sip_registration_status registration_status;
} janus_sip_account;

typedef struct janus_sip_rtp_context {
/* Needed to fix seq and ts in case of re-INVITEs/UPDATEs that result in a RTP stream */
uint32_t a_last_ssrc, a_last_ts, a_base_ts, a_base_ts_prev,
v_last_ssrc, v_last_ts, v_base_ts, v_base_ts_prev;
uint16_t a_last_seq, a_base_seq, a_base_seq_prev,
v_last_seq, v_base_seq, v_base_seq_prev;
} janus_sip_rtp_context;

typedef struct janus_sip_media {
char *remote_ip;
int ready:1;
Expand Down Expand Up @@ -357,7 +349,7 @@ typedef struct janus_sip_media {
srtp_policy_t video_remote_policy, video_local_policy;
int video_srtp_suite_in, video_srtp_suite_out;
gboolean video_send;
janus_sip_rtp_context context;
janus_rtp_switching_context context;
int pipefd[2];
gboolean updated;
} janus_sip_media;
Expand Down Expand Up @@ -1100,21 +1092,7 @@ void janus_sip_create_session(janus_plugin_session *handle, int *error) {
session->media.video_srtp_suite_out = 0;
session->media.video_send = TRUE;
/* Initialize the RTP context */
session->media.context.a_last_ssrc = 0;
session->media.context.a_last_ssrc = 0;
session->media.context.a_last_ts = 0;
session->media.context.a_base_ts = 0;
session->media.context.a_base_ts_prev = 0;
session->media.context.v_last_ssrc = 0;
session->media.context.v_last_ts = 0;
session->media.context.v_base_ts = 0;
session->media.context.v_base_ts_prev = 0;
session->media.context.a_last_seq = 0;
session->media.context.a_base_seq = 0;
session->media.context.a_base_seq_prev = 0;
session->media.context.v_last_seq = 0;
session->media.context.v_base_seq = 0;
session->media.context.v_base_seq_prev = 0;
janus_rtp_switching_context_reset(&session->media.context);
session->media.pipefd[0] = -1;
session->media.pipefd[1] = -1;
session->media.updated = FALSE;
Expand Down Expand Up @@ -3426,25 +3404,8 @@ static void *janus_sip_relay_thread(void *data) {
bytes = buflen;
}
/* Check if the SSRC changed (e.g., after a re-INVITE or UPDATE) */
guint32 ssrc = ntohl(header->ssrc);
guint32 timestamp = ntohl(header->timestamp);
guint16 seq = ntohs(header->seq_number);
if(ssrc != session->media.context.a_last_ssrc) {
JANUS_LOG(LOG_VERB, "Audio SSRC changed (re-INVITE?), %"SCNu32" --> %"SCNu32"\n",
session->media.context.a_last_ssrc, ssrc);
session->media.context.a_last_ssrc = ssrc;
session->media.context.a_base_ts_prev = session->media.context.a_last_ts;
session->media.context.a_base_ts = timestamp;
session->media.context.a_base_seq_prev = session->media.context.a_last_seq;
session->media.context.a_base_seq = seq;
}
/* Compute a coherent timestamp and sequence number */
session->media.context.a_last_ts = (timestamp-session->media.context.a_base_ts)
+ session->media.context.a_base_ts_prev+(astep ? astep : 960); /* FIXME */
session->media.context.a_last_seq = (seq-session->media.context.a_base_seq)+session->media.context.a_base_seq_prev+1;
/* Update the timestamp and sequence number in the RTP packet, and send it */
header->timestamp = htonl(session->media.context.a_last_ts);
header->seq_number = htons(session->media.context.a_last_seq);
janus_rtp_header_update(header, &session->media.context, FALSE, astep ? astep : 960);
if(ats == 0) {
ats = timestamp;
} else if(astep == 0) {
Expand Down Expand Up @@ -3503,24 +3464,8 @@ static void *janus_sip_relay_thread(void *data) {
bytes = buflen;
}
/* Check if the SSRC changed (e.g., after a re-INVITE or UPDATE) */
guint32 ssrc = ntohl(header->ssrc);
janus_rtp_header_update(header, &session->media.context, TRUE, vstep ? vstep : 4500);
guint32 timestamp = ntohl(header->timestamp);
guint16 seq = ntohs(header->seq_number);
if(ssrc != session->media.context.v_last_ssrc) {
JANUS_LOG(LOG_VERB, "Video SSRC changed (re-INVITE?)\n");
session->media.context.v_last_ssrc = ssrc;
session->media.context.v_base_ts_prev = session->media.context.v_last_ts;
session->media.context.v_base_ts = timestamp;
session->media.context.v_base_seq_prev = session->media.context.v_last_seq;
session->media.context.v_base_seq = seq;
}
/* Compute a coherent timestamp and sequence number */
session->media.context.v_last_ts = (timestamp-session->media.context.v_base_ts)
+ session->media.context.v_base_ts_prev+(vstep ? vstep : 4500); /* FIXME */
session->media.context.v_last_seq = (seq-session->media.context.v_base_seq)+session->media.context.v_base_seq_prev+1;
/* Update the timestamp and sequence number in the RTP packet, and send it */
header->timestamp = htonl(session->media.context.v_last_ts);
header->seq_number = htons(session->media.context.v_last_seq);
if(vts == 0) {
vts = timestamp;
} else if(vstep == 0) {
Expand Down
57 changes: 6 additions & 51 deletions plugins/janus_streaming.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,20 +464,12 @@ static void janus_streaming_message_free(janus_streaming_message *msg) {
}


typedef struct janus_streaming_context {
/* Needed to fix seq and ts in case of stream switching */
uint32_t a_last_ssrc, a_last_ts, a_base_ts, a_base_ts_prev,
v_last_ssrc, v_last_ts, v_base_ts, v_base_ts_prev;
uint16_t a_last_seq, a_base_seq, a_base_seq_prev,
v_last_seq, v_base_seq, v_base_seq_prev;
} janus_streaming_context;

typedef struct janus_streaming_session {
janus_plugin_session *handle;
janus_streaming_mountpoint *mountpoint;
gboolean started;
gboolean paused;
janus_streaming_context context;
janus_rtp_switching_context context;
gboolean stopping;
volatile gint hangingup;
gint64 destroyed; /* Time at which this session was marked as destroyed */
Expand Down Expand Up @@ -2055,20 +2047,7 @@ void janus_streaming_setup_media(janus_plugin_session *handle) {
return;
g_atomic_int_set(&session->hangingup, 0);
/* We only start streaming towards this user when we get this event */
session->context.a_last_ssrc = 0;
session->context.a_last_ts = 0;
session->context.a_base_ts = 0;
session->context.a_base_ts_prev = 0;
session->context.v_last_ssrc = 0;
session->context.v_last_ts = 0;
session->context.v_base_ts = 0;
session->context.v_base_ts_prev = 0;
session->context.a_last_seq = 0;
session->context.a_base_seq = 0;
session->context.a_base_seq_prev = 0;
session->context.v_last_seq = 0;
session->context.v_base_seq = 0;
session->context.v_base_seq_prev = 0;
janus_rtp_switching_context_reset(&session->context);
/* If this is related to a live RTP mountpoint, any keyframe we can shoot already? */
janus_streaming_mountpoint *mountpoint = session->mountpoint;
if(mountpoint->streaming_source == janus_streaming_source_rtp) {
Expand Down Expand Up @@ -3808,40 +3787,16 @@ static void janus_streaming_relay_rtp_packet(gpointer data, gpointer user_data)
if(packet->is_rtp) {
/* Make sure there hasn't been a publisher switch by checking the SSRC */
if(packet->is_video) {
if(ntohl(packet->data->ssrc) != session->context.v_last_ssrc) {
session->context.v_last_ssrc = ntohl(packet->data->ssrc);
session->context.v_base_ts_prev = session->context.v_last_ts;
session->context.v_base_ts = packet->timestamp;
session->context.v_base_seq_prev = session->context.v_last_seq;
session->context.v_base_seq = packet->seq_number;
}
/* Compute a coherent timestamp and sequence number */
session->context.v_last_ts = (packet->timestamp-session->context.v_base_ts)
+ session->context.v_base_ts_prev+4500; /* FIXME When switching, we assume 15fps */
session->context.v_last_seq = (packet->seq_number-session->context.v_base_seq)+session->context.v_base_seq_prev+1;
/* Update the timestamp and sequence number in the RTP packet, and send it */
packet->data->timestamp = htonl(session->context.v_last_ts);
packet->data->seq_number = htons(session->context.v_last_seq);
/* Fix sequence number and timestamp (switching may be involved) */
janus_rtp_header_update(packet->data, &session->context, TRUE, 4500);
if(gateway != NULL)
gateway->relay_rtp(session->handle, packet->is_video, (char *)packet->data, packet->length);
/* Restore the timestamp and sequence number to what the publisher set them to */
packet->data->timestamp = htonl(packet->timestamp);
packet->data->seq_number = htons(packet->seq_number);
} else {
if(ntohl(packet->data->ssrc) != session->context.a_last_ssrc) {
session->context.a_last_ssrc = ntohl(packet->data->ssrc);
session->context.a_base_ts_prev = session->context.a_last_ts;
session->context.a_base_ts = packet->timestamp;
session->context.a_base_seq_prev = session->context.a_last_seq;
session->context.a_base_seq = packet->seq_number;
}
/* Compute a coherent timestamp and sequence number */
session->context.a_last_ts = (packet->timestamp-session->context.a_base_ts)
+ session->context.a_base_ts_prev+960; /* FIXME When switching, we assume Opus and so a 960 ts step */
session->context.a_last_seq = (packet->seq_number-session->context.a_base_seq)+session->context.a_base_seq_prev+1;
/* Update the timestamp and sequence number in the RTP packet, and send it */
packet->data->timestamp = htonl(session->context.a_last_ts);
packet->data->seq_number = htons(session->context.a_last_seq);
/* Fix sequence number and timestamp (switching may be involved) */
janus_rtp_header_update(packet->data, &session->context, FALSE, 960);
if(gateway != NULL)
gateway->relay_rtp(session->handle, packet->is_video, (char *)packet->data, packet->length);
/* Restore the timestamp and sequence number to what the publisher set them to */
Expand Down
73 changes: 6 additions & 67 deletions plugins/janus_videoroom.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,21 +486,13 @@ static void janus_videoroom_participant_free(janus_videoroom_participant *p);
static void janus_videoroom_rtp_forwarder_free_helper(gpointer data);
static guint32 janus_videoroom_rtp_forwarder_add_helper(janus_videoroom_participant *p,
const gchar* host, int port, int pt, uint32_t ssrc, gboolean is_video, gboolean is_data);
typedef struct janus_videoroom_listener_context {
/* Needed to fix seq and ts in case of publisher switching */
uint32_t a_last_ssrc, a_last_ts, a_base_ts, a_base_ts_prev,
v_last_ssrc, v_last_ts, v_base_ts, v_base_ts_prev;
uint16_t a_last_seq, a_base_seq, a_base_seq_prev,
v_last_seq, v_base_seq, v_base_seq_prev;
gboolean a_seq_reset, v_seq_reset;
} janus_videoroom_listener_context;

typedef struct janus_videoroom_listener {
janus_videoroom_session *session;
janus_videoroom *room; /* Room */
janus_videoroom_participant *feed; /* Participant this listener is subscribed to */
guint32 pvt_id; /* Private ID of the participant that is subscribing (if available/provided) */
janus_videoroom_listener_context context; /* Needed in case there are publisher switches on this listener */
janus_rtp_switching_context context; /* Needed in case there are publisher switches on this listener */
gboolean audio, video, data; /* Whether audio, video and/or data must be sent to this publisher */
struct janus_videoroom_listener_muxed *parent; /* Overall subscriber, if this is a sub-listener in a Multiplexed one */
gboolean paused;
Expand Down Expand Up @@ -3104,22 +3096,7 @@ static void *janus_videoroom_handler(void *data) {
listener->feed = publisher;
listener->pvt_id = pvt_id;
/* Initialize the listener context */
listener->context.a_last_ssrc = 0;
listener->context.a_last_ts = 0;
listener->context.a_base_ts = 0;
listener->context.a_base_ts_prev = 0;
listener->context.v_last_ssrc = 0;
listener->context.v_last_ts = 0;
listener->context.v_base_ts = 0;
listener->context.v_base_ts_prev = 0;
listener->context.a_last_seq = 0;
listener->context.a_base_seq = 0;
listener->context.a_base_seq_prev = 0;
listener->context.v_last_seq = 0;
listener->context.v_base_seq = 0;
listener->context.v_base_seq_prev = 0;
listener->context.a_seq_reset = FALSE;
listener->context.v_seq_reset = FALSE;
janus_rtp_switching_context_reset(&listener->context);
listener->audio = audio ? json_is_true(audio) : TRUE; /* True by default */
if(!publisher->audio)
listener->audio = FALSE; /* ... unless the publisher isn't sending any audio */
Expand Down Expand Up @@ -4376,27 +4353,8 @@ static void janus_videoroom_relay_rtp_packet(gpointer data, gpointer user_data)
/* Nope, don't relay */
return;
}
if(ntohl(packet->data->ssrc) != listener->context.v_last_ssrc) {
/* Publisher switch? Fix sequence numbers and timestamps */
listener->context.v_last_ssrc = ntohl(packet->data->ssrc);
listener->context.v_base_ts_prev = listener->context.v_last_ts;
listener->context.v_base_ts = packet->timestamp;
listener->context.v_base_seq_prev = listener->context.v_last_seq;
listener->context.v_base_seq = packet->seq_number;
}
if(listener->context.v_seq_reset) {
/* video_active false-->true? Fix sequence numbers */
listener->context.v_seq_reset = FALSE;
listener->context.v_base_seq_prev = listener->context.v_last_seq;
listener->context.v_base_seq = packet->seq_number;
}
/* Compute a coherent timestamp and sequence number */
listener->context.v_last_ts = (packet->timestamp-listener->context.v_base_ts)
+ listener->context.v_base_ts_prev+4500; /* FIXME When switching, we assume 15fps */
listener->context.v_last_seq = (packet->seq_number-listener->context.v_base_seq)+listener->context.v_base_seq_prev+1;
/* Update the timestamp and sequence number in the RTP packet, and send it */
packet->data->timestamp = htonl(listener->context.v_last_ts);
packet->data->seq_number = htons(listener->context.v_last_seq);
/* Fix sequence number and timestamp (publisher switching may be involved) */
janus_rtp_header_update(packet->data, &listener->context, TRUE, 4500);
if(gateway != NULL)
gateway->relay_rtp(session->handle, packet->is_video, (char *)packet->data, packet->length);
/* Restore the timestamp and sequence number to what the publisher set them to */
Expand All @@ -4408,27 +4366,8 @@ static void janus_videoroom_relay_rtp_packet(gpointer data, gpointer user_data)
/* Nope, don't relay */
return;
}
if(ntohl(packet->data->ssrc) != listener->context.a_last_ssrc) {
/* Publisher switch? Fix sequence numbers and timestamps */
listener->context.a_last_ssrc = ntohl(packet->data->ssrc);
listener->context.a_base_ts_prev = listener->context.a_last_ts;
listener->context.a_base_ts = packet->timestamp;
listener->context.a_base_seq_prev = listener->context.a_last_seq;
listener->context.a_base_seq = packet->seq_number;
}
if(listener->context.a_seq_reset) {
/* audio_active false-->true? Fix sequence numbers */
listener->context.a_seq_reset = FALSE;
listener->context.a_base_seq_prev = listener->context.a_last_seq;
listener->context.a_base_seq = packet->seq_number;
}
/* Compute a coherent timestamp and sequence number */
listener->context.a_last_ts = (packet->timestamp-listener->context.a_base_ts)
+ listener->context.a_base_ts_prev+960; /* FIXME When switching, we assume Opus and so a 960 ts step */
listener->context.a_last_seq = (packet->seq_number-listener->context.a_base_seq)+listener->context.a_base_seq_prev+1;
/* Update the timestamp and sequence number in the RTP packet, and send it */
packet->data->timestamp = htonl(listener->context.a_last_ts);
packet->data->seq_number = htons(listener->context.a_last_seq);
/* Fix sequence number and timestamp (publisher switching may be involved) */
janus_rtp_header_update(packet->data, &listener->context, FALSE, 960);
if(gateway != NULL)
gateway->relay_rtp(session->handle, packet->is_video, (char *)packet->data, packet->length);
/* Restore the timestamp and sequence number to what the publisher set them to */
Expand Down
Loading

0 comments on commit e8323e1

Please sign in to comment.