Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / remote_bitrate_estimator / test / bwe_test_framework.cc
index b3cd7db..f7a7197 100644 (file)
@@ -154,6 +154,12 @@ void Packet::set_send_time_us(int64_t send_time_us) {
   send_time_us_ = send_time_us;
 }
 
+void Packet::SetAbsSendTimeMs(int64_t abs_send_time_ms) {
+  header_.extension.hasAbsoluteSendTime = true;
+  header_.extension.absoluteSendTime = ((static_cast<int64_t>(abs_send_time_ms *
+    (1 << 18)) + 500) / 1000) & 0x00fffffful;
+}
+
 bool IsTimeSorted(const Packets& packets) {
   PacketsConstIt last_it = packets.begin();
   for (PacketsConstIt it = last_it; it != packets.end(); ++it) {
@@ -538,8 +544,11 @@ PacketSender::PacketSender(PacketProcessorListener* listener,
 
 }
 
-VideoSender::VideoSender(int flow_id, PacketProcessorListener* listener,
-                         float fps, uint32_t kbps, uint32_t ssrc,
+VideoSender::VideoSender(int flow_id,
+                         PacketProcessorListener* listener,
+                         float fps,
+                         uint32_t kbps,
+                         uint32_t ssrc,
                          float first_frame_offset)
     : PacketSender(listener, FlowIds(1, flow_id)),
       kMaxPayloadSizeBytes(1200),
@@ -561,17 +570,22 @@ uint32_t VideoSender::GetCapacityKbps() const {
   return (bytes_per_second_ * 8) / 1000;
 }
 
+uint32_t VideoSender::NextFrameSize() {
+  return frame_size_bytes_;
+}
+
+uint32_t VideoSender::NextPacketSize(uint32_t frame_size,
+                                     uint32_t remaining_payload) {
+  return std::min(kMaxPayloadSizeBytes, remaining_payload);
+}
+
 void VideoSender::RunFor(int64_t time_ms, Packets* in_out) {
   assert(in_out);
   now_ms_ += time_ms;
   Packets new_packets;
   while (now_ms_ >= next_frame_ms_) {
-    prototype_header_.sequenceNumber++;
     prototype_header_.timestamp = kTimestampBase +
         static_cast<uint32_t>(next_frame_ms_ * 90.0);
-    prototype_header_.extension.absoluteSendTime = (kTimestampBase +
-        ((static_cast<int64_t>(next_frame_ms_ * (1 << 18)) + 500) / 1000)) &
-            0x00fffffful;
     prototype_header_.extension.transmissionTimeOffset = 0;
 
     // Generate new packets for this frame, all with the same timestamp,
@@ -579,11 +593,15 @@ void VideoSender::RunFor(int64_t time_ms, Packets* in_out) {
     // one packet, we will see a number of equally sized packets followed by
     // one smaller at the tail.
     int64_t send_time_us = next_frame_ms_ * 1000.0;
-    uint32_t payload_size = frame_size_bytes_;
+    uint32_t frame_size = NextFrameSize();
+    uint32_t payload_size = frame_size;
+
     while (payload_size > 0) {
-      uint32_t size = std::min(kMaxPayloadSizeBytes, payload_size);
+      ++prototype_header_.sequenceNumber;
+      uint32_t size = NextPacketSize(frame_size, payload_size);
       new_packets.push_back(Packet(flow_ids()[0], send_time_us, size,
                                    prototype_header_));
+      new_packets.back().SetAbsSendTimeMs(next_frame_ms_);
       payload_size -= size;
     }
 
@@ -598,12 +616,178 @@ AdaptiveVideoSender::AdaptiveVideoSender(int flow_id,
                                          uint32_t kbps,
                                          uint32_t ssrc,
                                          float first_frame_offset)
-    : VideoSender(flow_id, listener, fps, kbps, ssrc, first_frame_offset) {}
+    : VideoSender(flow_id, listener, fps, kbps, ssrc, first_frame_offset) {
+}
 
 void AdaptiveVideoSender::GiveFeedback(const PacketSender::Feedback& feedback) {
-  bytes_per_second_ = feedback.estimated_bps / 8;
+  bytes_per_second_ = std::min(feedback.estimated_bps / 8, 2500000u / 8);
   frame_size_bytes_ = (bytes_per_second_ * frame_period_ms_ + 500) / 1000;
 }
+
+PeriodicKeyFrameSender::PeriodicKeyFrameSender(
+    int flow_id,
+    PacketProcessorListener* listener,
+    float fps,
+    uint32_t kbps,
+    uint32_t ssrc,
+    float first_frame_offset,
+    int key_frame_interval)
+    : AdaptiveVideoSender(flow_id,
+                          listener,
+                          fps,
+                          kbps,
+                          ssrc,
+                          first_frame_offset),
+      key_frame_interval_(key_frame_interval),
+      frame_counter_(0),
+      compensation_bytes_(0),
+      compensation_per_frame_(0) {
+}
+
+uint32_t PeriodicKeyFrameSender::NextFrameSize() {
+  uint32_t payload_size = frame_size_bytes_;
+  if (frame_counter_ == 0) {
+    payload_size = kMaxPayloadSizeBytes * 12;
+    compensation_bytes_ = 4 * frame_size_bytes_;
+    compensation_per_frame_ = compensation_bytes_ / 30;
+  } else if (key_frame_interval_ > 0 &&
+             (frame_counter_ % key_frame_interval_ == 0)) {
+    payload_size *= 5;
+    compensation_bytes_ = payload_size - frame_size_bytes_;
+    compensation_per_frame_ = compensation_bytes_ / 30;
+  } else if (compensation_bytes_ > 0) {
+    if (compensation_per_frame_ > static_cast<int>(payload_size)) {
+      // Skip this frame.
+      compensation_bytes_ -= payload_size;
+      payload_size = 0;
+    } else {
+      payload_size -= compensation_per_frame_;
+      compensation_bytes_ -= compensation_per_frame_;
+    }
+  }
+  if (compensation_bytes_ < 0)
+    compensation_bytes_ = 0;
+  ++frame_counter_;
+  return payload_size;
+}
+
+uint32_t PeriodicKeyFrameSender::NextPacketSize(uint32_t frame_size,
+                                                uint32_t remaining_payload) {
+  uint32_t fragments =
+      (frame_size + (kMaxPayloadSizeBytes - 1)) / kMaxPayloadSizeBytes;
+  uint32_t avg_size = (frame_size + fragments - 1) / fragments;
+  return std::min(avg_size, remaining_payload);
+}
+
+PacedVideoSender::PacedVideoSender(PacketProcessorListener* listener,
+                                   uint32_t kbps,
+                                   AdaptiveVideoSender* source)
+    // It is important that the first_frame_offset and the initial time of
+    // clock_ are both zero, otherwise we can't have absolute time in this
+    // class.
+    : PacketSender(listener, source->flow_ids()),
+      clock_(0),
+      start_of_run_ms_(0),
+      pacer_(&clock_, this, kbps, PacedSender::kDefaultPaceMultiplier* kbps, 0),
+      source_(source) {
+}
+
+void PacedVideoSender::RunFor(int64_t time_ms, Packets* in_out) {
+  start_of_run_ms_ = clock_.TimeInMilliseconds();
+  Packets generated_packets;
+  source_->RunFor(time_ms, &generated_packets);
+  // Run process periodically to allow the packets to be paced out.
+  int64_t end_time_ms = clock_.TimeInMilliseconds() + time_ms;
+  Packets::iterator it = generated_packets.begin();
+  while (clock_.TimeInMilliseconds() <= end_time_ms) {
+    int time_until_process_ms = pacer_.TimeUntilNextProcess();
+    if (time_until_process_ms < 0)
+      time_until_process_ms = 0;
+    int time_until_packet_ms = time_ms;
+    if (it != generated_packets.end())
+      time_until_packet_ms =
+          (it->send_time_us() + 500) / 1000 - clock_.TimeInMilliseconds();
+    assert(time_until_packet_ms >= 0);
+    int time_until_next_event_ms = time_until_packet_ms;
+    if (time_until_process_ms < time_until_packet_ms &&
+        pacer_.QueueSizePackets() > 0)
+      time_until_next_event_ms = time_until_process_ms;
+
+    if (clock_.TimeInMilliseconds() + time_until_next_event_ms > end_time_ms) {
+      clock_.AdvanceTimeMilliseconds(end_time_ms - clock_.TimeInMilliseconds());
+      break;
+    }
+    clock_.AdvanceTimeMilliseconds(time_until_next_event_ms);
+    if (time_until_process_ms < time_until_packet_ms) {
+      // Time to process.
+      pacer_.Process();
+    } else {
+      // Time to send next packet to pacer.
+      pacer_.SendPacket(PacedSender::kNormalPriority,
+                        it->header().ssrc,
+                        it->header().sequenceNumber,
+                        (it->send_time_us() + 500) / 1000,
+                        it->payload_size(),
+                        false);
+      pacer_queue_.push_back(*it);
+      const size_t kMaxPacerQueueSize = 10000;
+      if (pacer_queue_.size() > kMaxPacerQueueSize) {
+        pacer_queue_.pop_front();
+      }
+      ++it;
+    }
+  }
+  QueuePackets(in_out, end_time_ms * 1000);
+}
+
+void PacedVideoSender::QueuePackets(Packets* batch,
+                                    int64_t end_of_batch_time_us) {
+  queue_.merge(*batch);
+  if (queue_.empty()) {
+    return;
+  }
+  Packets::iterator it = queue_.begin();
+  for (; it != queue_.end(); ++it) {
+    if (it->send_time_us() > end_of_batch_time_us) {
+      break;
+    }
+  }
+  Packets to_transfer;
+  to_transfer.splice(to_transfer.begin(), queue_, queue_.begin(), it);
+  batch->merge(to_transfer);
+}
+
+void PacedVideoSender::GiveFeedback(const PacketSender::Feedback& feedback) {
+  source_->GiveFeedback(feedback);
+  pacer_.UpdateBitrate(
+      feedback.estimated_bps / 1000,
+      PacedSender::kDefaultPaceMultiplier * feedback.estimated_bps / 1000,
+      0);
+}
+
+bool PacedVideoSender::TimeToSendPacket(uint32_t ssrc,
+                                        uint16_t sequence_number,
+                                        int64_t capture_time_ms,
+                                        bool retransmission) {
+  for (Packets::iterator it = pacer_queue_.begin(); it != pacer_queue_.end();
+       ++it) {
+    if (it->header().sequenceNumber == sequence_number) {
+      int64_t pace_out_time_ms = clock_.TimeInMilliseconds();
+      // Make sure a packet is never paced out earlier than when it was put into
+      // the pacer.
+      assert(pace_out_time_ms >= (it->send_time_us() + 500) / 1000);
+      it->SetAbsSendTimeMs(pace_out_time_ms);
+      it->set_send_time_us(1000 * pace_out_time_ms);
+      queue_.push_back(*it);
+      return true;
+    }
+  }
+  return false;
+}
+
+int PacedVideoSender::TimeToSendPadding(int bytes) {
+  return 0;
+}
 }  // namespace bwe
 }  // namespace testing
 }  // namespace webrtc