Example #1
0
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);
  }
}
Example #2
0
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;
}