@@ -1035,6 +1035,7 @@ typedef struct janus_sip_media {
10351035 srtp_policy_t video_remote_policy , video_local_policy ;
10361036 char * video_srtp_local_profile , * video_srtp_local_crypto ;
10371037 gboolean video_send , video_recv ;
1038+ gboolean video_pli_supported ;
10381039 janus_sdp_mdirection hold_video_dir , pre_hold_video_dir ;
10391040 janus_rtp_switching_context acontext , vcontext ;
10401041 int pipefd [2 ];
@@ -1086,6 +1087,7 @@ static janus_mutex sessions_mutex = JANUS_MUTEX_INITIALIZER;
10861087
10871088static void janus_sip_srtp_cleanup (janus_sip_session * session );
10881089static void janus_sip_media_reset (janus_sip_session * session );
1090+ static void janus_sip_rtcp_pli_send (janus_sip_session * session );
10891091
10901092static void janus_sip_call_update_status (janus_sip_session * session , janus_sip_call_status new_status ) {
10911093 if (session -> status != new_status ) {
@@ -1485,6 +1487,7 @@ static void janus_sip_media_reset(janus_sip_session *session) {
14851487 session -> media .video_pt_name = NULL ; /* Immutable string, no need to free*/
14861488 session -> media .video_send = TRUE;
14871489 session -> media .video_recv = TRUE;
1490+ session -> media .video_pli_supported = FALSE;
14881491 session -> media .hold_video_dir = JANUS_SDP_SENDONLY ;
14891492 session -> media .pre_hold_video_dir = JANUS_SDP_DEFAULT ;
14901493 session -> media .video_orientation_extension_id = -1 ;
@@ -2184,6 +2187,7 @@ void janus_sip_create_session(janus_plugin_session *handle, int *error) {
21842187 session -> media .video_pt = -1 ;
21852188 session -> media .video_pt_name = NULL ;
21862189 session -> media .video_recv = TRUE;
2190+ session -> media .video_pli_supported = FALSE;
21872191 session -> media .hold_video_dir = JANUS_SDP_SENDONLY ;
21882192 session -> media .pre_hold_video_dir = JANUS_SDP_DEFAULT ;
21892193 session -> media .video_orientation_extension_id = -1 ;
@@ -4570,7 +4574,9 @@ static void *janus_sip_handler(void *data) {
45704574 /* If the video-orientation extension has been negotiated, mark it in the recording */
45714575 if (session -> media .video_orientation_extension_id > 0 )
45724576 janus_recorder_add_extmap (session -> vrc_peer , session -> media .video_orientation_extension_id , JANUS_RTP_EXTMAP_VIDEO_ORIENTATION );
4573- /* TODO We should send a FIR/PLI to this peer... */
4577+ /* If we detected PLI support in the remote SDP, craft and send a PLI to the peer */
4578+ if (session -> media .video_pli_supported )
4579+ janus_sip_rtcp_pli_send (session );
45744580 if (rc == NULL ) {
45754581 /* FIXME We should notify the fact the recorder could not be created */
45764582 JANUS_LOG (LOG_ERR , "Couldn't open an video recording file for this peer!\n" );
@@ -6407,6 +6413,9 @@ void janus_sip_sdp_process(janus_sip_session *session, janus_sdp *sdp, gboolean
64076413 }
64086414 }
64096415 }
6416+ } else if (m -> type == JANUS_SDP_VIDEO && !strcasecmp (a -> name , "rtcp-fb" ) && a -> value ) {
6417+ if (strstr (a -> value , " pli" ))
6418+ session -> media .video_pli_supported = TRUE;
64106419 }
64116420 }
64126421 tempA = tempA -> next ;
@@ -7282,3 +7291,46 @@ gpointer janus_sip_sofia_thread(gpointer user_data) {
72827291 g_thread_unref (g_thread_self ());
72837292 return NULL ;
72847293}
7294+
7295+ /* Helper method to send an RTCP PLI to the SIP peer */
7296+ static void janus_sip_rtcp_pli_send (janus_sip_session * session ) {
7297+ if (!session || g_atomic_int_get (& session -> destroyed )) {
7298+ JANUS_LOG (LOG_ERR , "No session associated with this handle...\n" );
7299+ return ;
7300+ }
7301+ if (!janus_sip_call_is_established (session ))
7302+ return ;
7303+ if (!session -> media .has_video || session -> media .video_rtcp_fd == -1 )
7304+ return ;
7305+ /* Generate a PLI */
7306+ char rtcp_buf [12 ];
7307+ int rtcp_len = 12 ;
7308+ janus_rtcp_pli ((char * )& rtcp_buf , rtcp_len );
7309+ /* Fix SSRCs as the Janus core does */
7310+ JANUS_LOG (LOG_HUGE , "[SIP] Fixing SSRCs (local %u, peer %u)\n" ,
7311+ session -> media .video_ssrc , session -> media .video_ssrc_peer );
7312+ janus_rtcp_fix_ssrc (NULL , (char * )rtcp_buf , rtcp_len , 1 , session -> media .video_ssrc , session -> media .video_ssrc_peer );
7313+ /* Is SRTP involved? */
7314+ if (session -> media .has_srtp_local_video ) {
7315+ char sbuf [50 ];
7316+ memcpy (& sbuf , rtcp_buf , rtcp_len );
7317+ int protected = rtcp_len ;
7318+ int res = srtp_protect_rtcp (session -> media .video_srtp_out , & sbuf , & protected );
7319+ if (res != srtp_err_status_ok ) {
7320+ JANUS_LOG (LOG_ERR , "[SIP-%s] Video SRTCP protect error... %s (len=%d-->%d)...\n" ,
7321+ session -> account .username , janus_srtp_error_str (res ), rtcp_len , protected );
7322+ } else {
7323+ /* Forward the message to the peer */
7324+ if (send (session -> media .video_rtcp_fd , sbuf , protected , 0 ) < 0 ) {
7325+ JANUS_LOG (LOG_HUGE , "[SIP-%s] Error sending SRTCP video packet... %s (len=%d)...\n" ,
7326+ session -> account .username , g_strerror (errno ), protected );
7327+ }
7328+ }
7329+ } else {
7330+ /* Forward the message to the peer */
7331+ if (send (session -> media .video_rtcp_fd , rtcp_buf , rtcp_len , 0 ) < 0 ) {
7332+ JANUS_LOG (LOG_HUGE , "[SIP-%s] Error sending RTCP video packet... %s (len=%d)...\n" ,
7333+ session -> account .username , g_strerror (errno ), rtcp_len );
7334+ }
7335+ }
7336+ }
0 commit comments