void rtp_session_run_rtcp_send_scheduler(RtpSession *session) { uint64_t tc = ortp_get_cur_time_ms(); OrtpRtcpSendAlgorithm *sa = &session->rtcp.send_algo; if (tc >= sa->tn) { compute_rtcp_interval(session); sa->tn = sa->tp + sa->T_rr; if (tc >= sa->tn) { if (sa->t_rr_last == 0) { rtp_session_schedule_first_rtcp_send(session); } else { if (sa->T_rr_interval != 0) { sa->T_rr_current_interval = (uint32_t)rtcp_rand((float)sa->T_rr_interval); } else { sa->T_rr_current_interval = 0; } if (sa->tn >= (sa->t_rr_last + sa->T_rr_current_interval)) { rtp_session_send_regular_rtcp_packet_and_reschedule(session, tc); } else if (rtp_session_has_fb_packets_to_send(session) == TRUE) { rtp_session_send_fb_rtcp_packet_and_reschedule(session); } else { rtp_session_reschedule(session, tc); } } } } }
void rtp_session_send_regular_rtcp_packet_and_reschedule(RtpSession *session, uint64_t tc) { OrtpRtcpSendAlgorithm *sa = &session->rtcp.send_algo; rtp_session_create_and_send_rtcp_packet(session, TRUE); sa->tp = tc; sa->t_rr_last = sa->tn; compute_rtcp_interval(session); sa->tn = tc + sa->T_rr; sa->initial = FALSE; }
void RtpSession::send_rtcp() { RtcpPacket *p; struct timeval tv; gettimeofday(&tv, NULL); ntp_t ntp = timeval_to_ntp( tv ); uint8_t type = m_event_queue->type; switch ( m_event_queue->type ) { case RTCP_SR: /* We want to send an RTCP Sender Report. */ p = new RtcpPacket( RTCP_SR ); p->set_count( 0 ); p->set_sr_ssrc( m_ssrc ); p->set_sr_ntp_sec( ntp.secs ); p->set_sr_ntp_frac( ntp.frac ); p->set_sr_rtp_ts( m_last_timestamp ); p->set_sr_psent( m_psent ); p->set_sr_osent( m_osent ); break; case RTCP_RR: p = new RtcpPacket( RTCP_RR ); p->set_count( 1 ); default: p = NULL; } if ( ! p ) return; send_rtcp_pkt( p ); /* Advance the queue */ event_t *next = (event_t *)m_event_queue->next; free( m_event_queue ); m_event_queue = next; /* Schedule a new RTCP packet */ event_t *e = (event_t*)malloc( sizeof( event_t ) ); e->type = type; e->time = tv2dbl( tv ) + compute_rtcp_interval(); e->next = NULL; insert_event( e ); }
static void rtp_session_schedule_first_rtcp_send(RtpSession *session) { uint64_t tc; size_t overhead; size_t report_size; size_t sdes_size; size_t xr_size = 0; OrtpRtcpSendAlgorithm *sa = &session->rtcp.send_algo; if ((session->rtcp.enabled == FALSE) || (session->target_upload_bandwidth == 0) || (sa->initialized == TRUE)) return; overhead = (ortp_stream_is_ipv6(&session->rtcp.gs) == TRUE) ? IP6_UDP_OVERHEAD : IP_UDP_OVERHEAD; sdes_size = (session->full_sdes != NULL) ? msgdsize(session->full_sdes) + sizeof(rtcp_common_header_t) : 0; switch (session->mode) { case RTP_SESSION_RECVONLY: report_size = sizeof(rtcp_rr_t); break; case RTP_SESSION_SENDONLY: report_size = sizeof(rtcp_sr_t) - sizeof(report_block_t); break; case RTP_SESSION_SENDRECV: default: report_size = sizeof(rtcp_sr_t); break; } if (session->rtcp.xr_conf.enabled == TRUE) { if (session->rtcp.xr_conf.rcvr_rtt_mode != OrtpRtcpXrRcvrRttNone) xr_size += sizeof(rtcp_xr_header_t) + sizeof(rtcp_xr_rcvr_rtt_report_block_t); if (session->rtcp.xr_conf.stat_summary_enabled == TRUE) xr_size += sizeof(rtcp_xr_header_t) + sizeof(rtcp_xr_stat_summary_report_block_t); if (session->rtcp.xr_conf.voip_metrics_enabled == TRUE) xr_size += sizeof(rtcp_xr_header_t) + sizeof(rtcp_xr_voip_metrics_report_block_t); } sa->avg_rtcp_size = (float)(overhead + report_size + sdes_size + xr_size); sa->initialized = TRUE; tc = ortp_get_cur_time_ms(); compute_rtcp_interval(session); if (sa->T_rr > 0) sa->tn = tc + sa->T_rr; sa->tp = tc; sa->t_rr_last = tc; sa->Tmin = 0; }