Skip to content

Commit

Permalink
Dilute frequency of PLI in the VideoRoom (#3423)
Browse files Browse the repository at this point in the history
  • Loading branch information
natikaltura authored Nov 25, 2024
1 parent 02cbae1 commit d7f7a57
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 43 deletions.
75 changes: 35 additions & 40 deletions src/plugins/janus_videoroom.c
Original file line number Diff line number Diff line change
Expand Up @@ -2949,13 +2949,19 @@ static void janus_videoroom_codecstr(janus_videoroom *videoroom, char *audio_cod
}
}

/* Helper method to send an RTCP PLI to a remote publisher */
static void janus_videoroom_rtcp_pli_send(janus_videoroom_publisher_stream *ps) {
if(ps == NULL || ps->publisher == NULL)
return;
janus_videoroom_publisher *publisher = ps->publisher;
if(publisher->remote_rtcp_fd < 0 || publisher->rtcp_addr.ss_family == 0)
/* Helper method to send PLI to publishers.
* Send an PLI to local publisher and RTCP PLI to a remote publishers */
static void janus_videoroom_reqpli(janus_videoroom_publisher_stream *ps, const char *reason) {
if(ps == NULL || g_atomic_int_get(&ps->destroyed))
return;
janus_videoroom_publisher *remote_publisher = NULL;
if(ps->publisher->remote) {
if(ps->publisher == NULL || g_atomic_int_get(&ps->publisher->destroyed))
return;
remote_publisher = ps->publisher;
if(remote_publisher->remote_rtcp_fd < 0 || remote_publisher->rtcp_addr.ss_family == 0)
return;
}
if(!g_atomic_int_compare_and_exchange(&ps->sending_pli, 0, 1))
return;
gint64 now = janus_get_monotonic_time();
Expand All @@ -2965,44 +2971,33 @@ static void janus_videoroom_rtcp_pli_send(janus_videoroom_publisher_stream *ps)
g_atomic_int_set(&ps->sending_pli, 0);
return;
}
/* Update the time of when we last sent a keyframe request */
JANUS_LOG(LOG_VERB, "%s, sending PLI to %s (#%d, %s)\n", reason,
ps->publisher->user_id_str, ps->mindex, ps->publisher->display ? ps->publisher->display : "??");
g_atomic_int_set(&ps->need_pli, 0);
ps->pli_latest = janus_get_monotonic_time();
JANUS_LOG(LOG_HUGE, "Sending PLI\n");
/* Generate a PLI */
char rtcp_buf[12];
int rtcp_len = 12;
janus_rtcp_pli((char *)&rtcp_buf, rtcp_len);
uint32_t ssrc = REMOTE_PUBLISHER_BASE_SSRC + (ps->mindex*REMOTE_PUBLISHER_SSRC_STEP);
janus_rtcp_fix_ssrc(NULL, rtcp_buf, rtcp_len, 1, 1, ssrc);
/* Send the packet */
socklen_t addrlen = publisher->rtcp_addr.ss_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
int sent = 0;
if((sent = sendto(publisher->remote_rtcp_fd, rtcp_buf, rtcp_len, 0,
(struct sockaddr *)&publisher->rtcp_addr, addrlen)) < 0) {
JANUS_LOG(LOG_ERR, "Error in sendto... %d (%s)\n", errno, g_strerror(errno));
} else {
JANUS_LOG(LOG_HUGE, "Sent %d/%d bytes\n", sent, rtcp_len);
}
g_atomic_int_set(&ps->sending_pli, 0);
}

static void janus_videoroom_reqpli(janus_videoroom_publisher_stream *ps, const char *reason) {
if(ps == NULL || g_atomic_int_get(&ps->destroyed) || ps->publisher == NULL || g_atomic_int_get(&ps->publisher->destroyed))
return;
/* Send a PLI */
JANUS_LOG(LOG_VERB, "%s sending PLI to %s (#%d, %s)\n", reason,
ps->publisher->user_id_str, ps->mindex, ps->publisher->display ? ps->publisher->display : "??");
if(!ps->publisher->remote) {
/* Easy enough, local publisher so we ask the Janus core to send a PLI */
/* Update the time of when we last sent a keyframe request */
ps->fir_latest = ps->pli_latest;
if(remote_publisher == NULL) {
/* Local publisher so we ask the Janus core to send a PLI */
gateway->send_pli_stream(ps->publisher->session->handle, ps->mindex);
} else {
/* This is a remote publisher, so we'll need to send a PLI to the remote RTCP address */
JANUS_LOG(LOG_VERB, "Sending PLI to remote publisher\n");
janus_videoroom_rtcp_pli_send(ps);
/* Generate a PLI */
char rtcp_buf[12];
int rtcp_len = 12;
janus_rtcp_pli((char *)&rtcp_buf, rtcp_len);
uint32_t ssrc = REMOTE_PUBLISHER_BASE_SSRC + (ps->mindex*REMOTE_PUBLISHER_SSRC_STEP);
janus_rtcp_fix_ssrc(NULL, rtcp_buf, rtcp_len, 1, 1, ssrc);
/* Send the packet */
socklen_t addrlen = remote_publisher->rtcp_addr.ss_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
int sent = 0;
if((sent = sendto(remote_publisher->remote_rtcp_fd, rtcp_buf, rtcp_len, 0,
(struct sockaddr *)&remote_publisher->rtcp_addr, addrlen)) < 0) {
JANUS_LOG(LOG_ERR, "Error in sendto... %d (%s)\n", errno, g_strerror(errno));
} else {
JANUS_LOG(LOG_HUGE, "Sent %d/%d bytes\n", sent, rtcp_len);
}
}
/* Update the time of when we last sent a keyframe request */
ps->fir_latest = janus_get_monotonic_time();
g_atomic_int_set(&ps->sending_pli, 0);
}

/* Error codes */
Expand Down Expand Up @@ -13803,7 +13798,7 @@ static void *janus_videoroom_remote_publisher_thread(void *user_data) {
ps = (janus_videoroom_publisher_stream *)temp->data;
/* Any PLI and/or REMB we should send back to the source? */
if(ps->type == JANUS_VIDEOROOM_MEDIA_VIDEO && g_atomic_int_get(&ps->need_pli))
janus_videoroom_rtcp_pli_send(ps);
janus_videoroom_reqpli(ps, "Delayed PLI request");
temp = temp->next;
}
janus_mutex_unlock(&publisher->streams_mutex);
Expand Down
7 changes: 4 additions & 3 deletions src/rtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1218,7 +1218,8 @@ gboolean janus_rtp_simulcasting_context_process_rtp(janus_rtp_simulcasting_conte
context->last_relayed = now;
} else if(context->substream > 0) {
/* Check if too much time went by with no packet relayed */
if((now - context->last_relayed) > (context->drop_trigger ? context->drop_trigger : 250000)) {
gint64 delay_us = (now - context->last_relayed);
if(delay_us > (context->drop_trigger ? context->drop_trigger : 250000)) {
context->last_relayed = now;
if(context->substream != substream && context->substream_target_temp != 0) {
if(context->substream_target > substream) {
Expand All @@ -1230,8 +1231,8 @@ gboolean janus_rtp_simulcasting_context_process_rtp(janus_rtp_simulcasting_conte
if(context->substream_target_temp < 0)
context->substream_target_temp = 0;
if(context->substream_target_temp != prev_target) {
JANUS_LOG(LOG_WARN, "No packet received on substream %d for a while, falling back to %d\n",
context->substream, context->substream_target_temp);
JANUS_LOG(LOG_WARN, "No packet received on substream %d for %"SCNi64"ms, falling back to %d\n",
context->substream, (delay_us / 1000), context->substream_target_temp);
/* Notify the caller that we (still) need a PLI */
context->need_pli = TRUE;
}
Expand Down

0 comments on commit d7f7a57

Please sign in to comment.