int rtp_rtcp_interval(void* rtp) { double interval; struct rtp_context *ctx = (struct rtp_context *)rtp; interval = rtcp_interval(rtp_member_list_count(ctx->members), rtp_member_list_count(ctx->senders) + ((RTP_SENDER==ctx->role) ? 1 : 0), ctx->rtcp_bw, (ctx->self->rtp_clock + 2*RTCP_REPORT_INTERVAL > rtpclock()) ? 1 : 0, ctx->avg_rtcp_size, ctx->init); return (int)(interval * 1000); }
/* * Buffer is a raw RTP buffer */ int rtcp_receiver_update(iptv_rtcp_info_t *info, uint8_t *buffer) { union { uint8_t bytes[2]; uint16_t n; } join2; join2.bytes[0] = buffer[2]; join2.bytes[1] = buffer[3]; int new_sequence = ntohs(join2.n); if(new_sequence < info->last_received_sequence) { ++info->sequence_cycle; } info->last_received_sequence = new_sequence; union { uint8_t bytes[4]; uint32_t n; } join4; join4.bytes[0] = buffer[8]; join4.bytes[1] = buffer[9]; join4.bytes[2] = buffer[10]; join4.bytes[3] = buffer[11]; info->source_ssrc = ntohl(join4.n); time_t current_time = time(NULL); if(info->next_ts < current_time) { // Re-send rtcp_send_rr(info); // Re-schedule double interval = rtcp_interval(info->members, info->senders, 12, 0, info->average_packet_size, info->last_ts == 0); info->next_ts = current_time + interval; info->last_ts = current_time; } return 0; }
void OnExpire(event e, int members, int senders, double rtcp_bw, int we_sent, double *avg_rtcp_size, int *initial, time_tp tc, time_tp *tp, int *pmembers) { /* This function is responsible for deciding whether to send * an RTCP report or BYE packet now, or to reschedule transmission. * It is also responsible for updating the pmembers, initial, tp, * and avg_rtcp_size state variables. This function should be called * upon expiration of the event timer used by Schedule(). */ double t; /* Interval */ double tn; /* Next transmit time */ /* In the case of a BYE, we use "unconditional reconsideration" to * reschedule the transmission of the BYE if necessary */ if (TypeOfEvent(e) == EVENT_BYE) { t = rtcp_interval(members, senders, rtcp_bw, we_sent, *avg_rtcp_size, *initial); tn = *tp + t; if (tn <= tc) { SendBYEPacket(e); exit(1); } else { Schedule(tn, e); } } else if (TypeOfEvent(e) == EVENT_REPORT) { t = rtcp_interval(members, senders, rtcp_bw, we_sent, *avg_rtcp_size, *initial); tn = *tp + t; if (tn <= tc) { SendRTCPReport(e); *avg_rtcp_size = (1./16.)*SentPacketSize(e) + (15./16.)*(*avg_rtcp_size); *tp = tc; /* We must redraw the interval. Don't reuse the one computed above, since its not actually distributed the same, as we are conditioned on it being small enough to cause a packet to be sent */ t = rtcp_interval(members, senders, rtcp_bw, we_sent, *avg_rtcp_size, *initial); Schedule(t+tc,e); *initial = 0; } else { Schedule(tn, e); } *pmembers = members; } }