Exemplo n.º 1
0
bool RRGenerationHandler::isRetransmitOfOldPacket(std::shared_ptr<dataPacket> packet,
    std::shared_ptr<RRPackets> rr_info) {
  RtpHeader *head = reinterpret_cast<RtpHeader*>(packet->data);
  if (!rtpSequenceLessThan(head->getSeqNumber(), rr_info->max_seq) || rr_info->jitter.jitter == 0) {
    return false;
  }
  int64_t time_diff_ms = static_cast<uint32_t>(packet->received_time_ms) - rr_info->last_recv_ts;
  int64_t timestamp_diff = static_cast<int32_t>(head->getTimestamp() - rr_info->last_rtp_ts);
  uint16_t clock_rate = rr_info->type == VIDEO_PACKET ? getVideoClockRate(head->getPayloadType()) :
    getAudioClockRate(head->getPayloadType());
  int64_t rtp_time_stamp_diff_ms = timestamp_diff / clock_rate;
  int64_t max_delay_ms = ((2 * rr_info->jitter.jitter) /  clock_rate);
  return time_diff_ms > rtp_time_stamp_diff_ms + max_delay_ms;
}
Exemplo n.º 2
0
void RtpPacketQueue::pushPacket(const char *data, int length)
{
    const RTPHeader *currentHeader = reinterpret_cast<const RTPHeader*>(data);
    uint16_t currentSequenceNumber = currentHeader->getSeqNumber();

    if(lastSequenceNumberGiven_ >= 0 && (rtpSequenceLessThan(currentSequenceNumber, (uint16_t)lastSequenceNumberGiven_) || currentSequenceNumber == lastSequenceNumberGiven_)) {
        // this sequence number is less than the stuff we've already handed out, which means it's too late to be of any value.
        // TODO adaptive depth?
        ELOG_WARN("SSRC:%u, Payload: %u, discarding very late sample %d that is <= %d.  Current queue depth is %d",currentHeader->getSSRC(),currentHeader->getPayloadType(), currentSequenceNumber, lastSequenceNumberGiven_, this->getSize());
        return;
    }

    // TODO this should be a secret of the dataPacket class.  It should maintain its own memory
    // and copy stuff as necessary.
    boost::shared_ptr<dataPacket> packet(new dataPacket());
    memcpy(packet->data, data, length);
    packet->length = length;

    // let's insert this packet where it belongs in the queue.
    boost::mutex::scoped_lock lock(queueMutex_);

    std::list<boost::shared_ptr<dataPacket> >::iterator it;
    for (it=queue_.begin(); it != queue_.end(); ++it) {
        const RTPHeader *header = reinterpret_cast<const RTPHeader*>((*it)->data);
        uint16_t sequenceNumber = header->getSeqNumber();

        if (sequenceNumber == currentSequenceNumber) {
            // We already have this sequence number in the queue.
            ELOG_INFO("discarding duplicate sample %d", currentSequenceNumber);
            break;
        }

        if (this->rtpSequenceLessThan(sequenceNumber, currentSequenceNumber)) {
            queue_.insert(it, packet);
            break;
        }
    }

    if (it == queue_.end()) {
        // something old, or queue is empty.
        queue_.push_back(packet);
    }

    // Enforce our max queue size.
    while(queue_.size() > max_) {
        ELOG_DEBUG("RtpPacketQueue - Discarding a sample due to hitting MAX_SIZE");
        queue_.pop_back();  // remove oldest samples.
    }
}
Exemplo n.º 3
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);
  }
}