void RRGenerationHandler::sendRR(std::shared_ptr<RRPackets> selected_packet_info) { if (selected_packet_info->ssrc != 0) { uint64_t now = ClockUtils::timePointToMs(clock::now()); uint64_t delay_since_last_sr = selected_packet_info->last_sr_ts == 0 ? 0 : (now - selected_packet_info->last_sr_ts) * 65536 / 1000; RtcpHeader rtcp_head; rtcp_head.setPacketType(RTCP_Receiver_PT); rtcp_head.setSSRC(selected_packet_info->ssrc); rtcp_head.setSourceSSRC(selected_packet_info->ssrc); rtcp_head.setHighestSeqnum(selected_packet_info->extended_seq); rtcp_head.setSeqnumCycles(selected_packet_info->cycle); rtcp_head.setLostPackets(selected_packet_info->lost); rtcp_head.setFractionLost(selected_packet_info->frac_lost); rtcp_head.setJitter(static_cast<uint32_t>(selected_packet_info->jitter.jitter)); rtcp_head.setDelaySinceLastSr(static_cast<uint32_t>(delay_since_last_sr)); rtcp_head.setLastSr(selected_packet_info->last_sr_mid_ntp); rtcp_head.setLength(7); rtcp_head.setBlockCount(1); int length = (rtcp_head.getLength() + 1) * 4; memcpy(packet_, reinterpret_cast<uint8_t*>(&rtcp_head), length); getContext()->fireWrite(std::make_shared<dataPacket>(0, reinterpret_cast<char*>(&packet_), length, OTHER_PACKET)); selected_packet_info->last_rr_ts = now; ELOG_DEBUG("%s, message: Sending RR, ssrc: %u, type: %u lost: %u, frac: %u, cycle: %u, highseq: %u, jitter: %u, " "dlsr: %u, lsr: %u", connection_->toLog(), selected_packet_info->ssrc, selected_packet_info->type, rtcp_head.getLostPackets(), rtcp_head.getFractionLost(), rtcp_head.getSeqnumCycles(), rtcp_head.getHighestSeqnum(), rtcp_head.getJitter(), rtcp_head.getDelaySinceLastSr(), rtcp_head.getLastSr()); uint16_t selected_interval = selectInterval(selected_packet_info); selected_packet_info->next_packet_ms = now + getRandomValue(0.5 * selected_interval, 1.5 * selected_interval); } }
void GcScopeBar::clickedInterval() { home->setChecked(false); #ifdef GC_HAVE_ICAL diary->setChecked(false); #endif anal->setChecked(false); train->setChecked(false); emit selectInterval(); }
std::shared_ptr<DataPacket> RtcpRrGenerator::generateReceiverReport() { uint64_t now = ClockUtils::timePointToMs(clock_->now()); uint64_t delay_since_last_sr = rr_info_.last_sr_ts == 0 ? 0 : (now - rr_info_.last_sr_ts) * 65536 / 1000; uint32_t expected = rr_info_.extended_seq - rr_info_.base_seq + 1; if (expected < rr_info_.packets_received) { rr_info_.lost = 0; } else { rr_info_.lost = expected - rr_info_.packets_received; } uint8_t fraction = 0; uint32_t expected_interval = expected - rr_info_.expected_prior; rr_info_.expected_prior = expected; uint32_t received_interval = rr_info_.packets_received - rr_info_.received_prior; rr_info_.received_prior = rr_info_.packets_received; int64_t lost_interval = static_cast<int64_t>(expected_interval) - received_interval; if (expected_interval != 0 && lost_interval > 0) { fraction = (static_cast<uint32_t>(lost_interval) << 8) / expected_interval; } rr_info_.frac_lost = fraction; RtcpHeader rtcp_head; rtcp_head.setPacketType(RTCP_Receiver_PT); rtcp_head.setSSRC(ssrc_); rtcp_head.setSourceSSRC(ssrc_); rtcp_head.setHighestSeqnum(rr_info_.extended_seq); rtcp_head.setSeqnumCycles(rr_info_.cycle); rtcp_head.setLostPackets(rr_info_.lost); rtcp_head.setFractionLost(rr_info_.frac_lost); rtcp_head.setJitter(static_cast<uint32_t>(rr_info_.jitter.jitter)); rtcp_head.setDelaySinceLastSr(static_cast<uint32_t>(delay_since_last_sr)); rtcp_head.setLastSr(rr_info_.last_sr_mid_ntp); rtcp_head.setLength(7); rtcp_head.setBlockCount(1); int length = (rtcp_head.getLength() + 1) * 4; memcpy(packet_, reinterpret_cast<uint8_t*>(&rtcp_head), length); rr_info_.last_rr_ts = now; ELOG_DEBUG("message: Sending RR, ssrc: %u, type: %u lost: %u, frac: %u, cycle: %u, highseq: %u, jitter: %u, " "dlsr: %u, lsr: %u", ssrc_, type_, rtcp_head.getLostPackets(), rtcp_head.getFractionLost(), rtcp_head.getSeqnumCycles(), rtcp_head.getHighestSeqnum(), rtcp_head.getJitter(), rtcp_head.getDelaySinceLastSr(), rtcp_head.getLastSr()); uint16_t selected_interval = selectInterval(); rr_info_.next_packet_ms = now + getRandomValue(0.5 * selected_interval, 1.5 * selected_interval); rr_info_.last_packet_ms = now; return (std::make_shared<DataPacket>(0, reinterpret_cast<char*>(&packet_), length, type_)); }
void RRGenerationHandler::handleRtpPacket(std::shared_ptr<dataPacket> packet) { RtpHeader *head = reinterpret_cast<RtpHeader*>(packet->data); auto rr_packet_pair = rr_info_map_.find(head->getSSRC()); if (rr_packet_pair == rr_info_map_.end()) { ELOG_DEBUG("%s message: handleRtpPacket ssrc not found, ssrc: %u", connection_->toLog(), head->getSSRC()); return; } std::shared_ptr<RRPackets> selected_packet_info = rr_packet_pair->second; uint16_t seq_num = head->getSeqNumber(); selected_packet_info->packets_received++; if (selected_packet_info->base_seq == -1) { selected_packet_info->ssrc = head->getSSRC(); selected_packet_info->base_seq = head->getSeqNumber(); } if (selected_packet_info->max_seq == -1) { selected_packet_info->max_seq = seq_num; } else if (!rtpSequenceLessThan(seq_num, selected_packet_info->max_seq)) { if (seq_num < selected_packet_info->max_seq) { selected_packet_info->cycle++; } selected_packet_info->max_seq = seq_num; } selected_packet_info->extended_seq = (selected_packet_info->cycle << 16) | selected_packet_info->max_seq; uint16_t clock_rate = selected_packet_info->type == VIDEO_PACKET ? getVideoClockRate(head->getPayloadType()) : getAudioClockRate(head->getPayloadType()); if (head->getTimestamp() != selected_packet_info->last_rtp_ts && !isRetransmitOfOldPacket(packet, selected_packet_info)) { int transit_time = static_cast<int>((packet->received_time_ms * clock_rate) - head->getTimestamp()); int delta = abs(transit_time - selected_packet_info->jitter.transit_time); if (selected_packet_info->jitter.transit_time != 0 && delta < MAX_DELAY) { selected_packet_info->jitter.jitter += (1. / 16.) * (static_cast<double>(delta) - selected_packet_info->jitter.jitter); } selected_packet_info->jitter.transit_time = transit_time; } selected_packet_info->last_rtp_ts = head->getTimestamp(); selected_packet_info->last_recv_ts = static_cast<uint32_t>(packet->received_time_ms); uint64_t now = ClockUtils::timePointToMs(clock::now()); if (selected_packet_info->next_packet_ms == 0) { // Schedule the first packet uint16_t selected_interval = selectInterval(selected_packet_info); selected_packet_info->next_packet_ms = now + selected_interval; return; } if (now >= selected_packet_info->next_packet_ms) { sendRR(selected_packet_info); } }
bool RtcpRrGenerator::handleRtpPacket(std::shared_ptr<dataPacket> packet) { RtpHeader *head = reinterpret_cast<RtpHeader*>(packet->data); if (ssrc_ != head->getSSRC()) { ELOG_DEBUG("message: handleRtpPacket ssrc not found, ssrc: %u", head->getSSRC()); return false; } uint16_t seq_num = head->getSeqNumber(); rr_info_.packets_received++; if (rr_info_.base_seq == -1) { rr_info_.base_seq = head->getSeqNumber(); } if (rr_info_.max_seq == -1) { rr_info_.max_seq = seq_num; } else if (!RtpUtils::sequenceNumberLessThan(seq_num, rr_info_.max_seq)) { if (seq_num < rr_info_.max_seq) { rr_info_.cycle++; } rr_info_.max_seq = seq_num; } rr_info_.extended_seq = (rr_info_.cycle << 16) | rr_info_.max_seq; uint16_t clock_rate = type_ == VIDEO_PACKET ? getVideoClockRate(head->getPayloadType()) : getAudioClockRate(head->getPayloadType()); if (head->getTimestamp() != rr_info_.last_rtp_ts && !isRetransmitOfOldPacket(packet)) { int transit_time = static_cast<int>((packet->received_time_ms * clock_rate) - head->getTimestamp()); int delta = abs(transit_time - rr_info_.jitter.transit_time); if (rr_info_.jitter.transit_time != 0 && delta < MAX_DELAY) { rr_info_.jitter.jitter += (1. / 16.) * (static_cast<double>(delta) - rr_info_.jitter.jitter); } rr_info_.jitter.transit_time = transit_time; } rr_info_.last_rtp_ts = head->getTimestamp(); rr_info_.last_recv_ts = static_cast<uint32_t>(packet->received_time_ms); uint64_t now = ClockUtils::timePointToMs(clock_->now()); if (rr_info_.next_packet_ms == 0) { // Schedule the first packet uint16_t selected_interval = selectInterval(); rr_info_.next_packet_ms = now + selected_interval; return false; } if (now >= rr_info_.next_packet_ms) { ELOG_DEBUG("message: should send packet, ssrc: %u", ssrc_); return true; } return false; }