1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file.
43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// The purpose of this file is determine what bitrate to use for mirroring.
6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Ideally this should be as much as possible, without causing any frames to
7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// arrive late.
8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// The current algorithm is to measure how much bandwidth we've been using
10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// recently. We also keep track of how much data has been queued up for sending
11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// in a virtual "buffer" (this virtual buffer represents all the buffers between
12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// the sender and the receiver, including retransmissions and so forth.)
13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// If we estimate that our virtual buffer is mostly empty, we try to use
14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// more bandwidth than our recent usage, otherwise we use less.
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/cast/sender/congestion_control.h"
173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/logging.h"
193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "media/cast/cast_config.h"
203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "media/cast/cast_defines.h"
213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace media {
233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace cast {
243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass AdaptiveCongestionControl : public CongestionControl {
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AdaptiveCongestionControl(base::TickClock* clock,
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            uint32 max_bitrate_configured,
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            uint32 min_bitrate_configured,
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            size_t max_unacked_frames);
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~AdaptiveCongestionControl() OVERRIDE;
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void UpdateRtt(base::TimeDelta rtt) OVERRIDE;
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Called when an encoded frame is sent to the transport.
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void SendFrameToTransport(uint32 frame_id,
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                    size_t frame_size,
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                    base::TimeTicks when) OVERRIDE;
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Called when we receive an ACK for a frame.
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void AckFrame(uint32 frame_id, base::TimeTicks when) OVERRIDE;
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Returns the bitrate we should use for the next frame.
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual uint32 GetBitrate(base::TimeTicks playout_time,
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            base::TimeDelta playout_delay) OVERRIDE;
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct FrameStats {
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    FrameStats();
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Time this frame was sent to the transport.
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::TimeTicks sent_time;
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Time this frame was acked.
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::TimeTicks ack_time;
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Size of encoded frame in bits.
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    size_t frame_size;
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Calculate how much "dead air" (idle time) there is between two frames.
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static base::TimeDelta DeadTime(const FrameStats& a, const FrameStats& b);
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Get the FrameStats for a given |frame_id|.
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Note: Older FrameStats will be removed automatically.
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FrameStats* GetFrameStats(uint32 frame_id);
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Calculate a safe bitrate. This is based on how much we've been
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // sending in the past.
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  double CalculateSafeBitrate();
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // For a given frame, calculate when it might be acked.
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // (Or return the time it was acked, if it was.)
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeTicks EstimatedAckTime(uint32 frame_id, double bitrate);
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Calculate when we start sending the data for a given frame.
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // This is done by calculating when we were done sending the previous
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // frame, but obviously can't be less than |sent_time| (if known).
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeTicks EstimatedSendingTime(uint32 frame_id, double bitrate);
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TickClock* const clock_;  // Not owned by this class.
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const uint32 max_bitrate_configured_;
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const uint32 min_bitrate_configured_;
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::deque<FrameStats> frame_stats_;
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint32 last_frame_stats_;
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint32 last_acked_frame_;
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint32 last_encoded_frame_;
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeDelta rtt_;
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t history_size_;
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t acked_bits_in_history_;
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeDelta dead_time_in_history_;
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(AdaptiveCongestionControl);
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass FixedCongestionControl : public CongestionControl {
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FixedCongestionControl(uint32 bitrate) : bitrate_(bitrate) {}
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~FixedCongestionControl() OVERRIDE {}
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void UpdateRtt(base::TimeDelta rtt) OVERRIDE {
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Called when an encoded frame is sent to the transport.
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void SendFrameToTransport(uint32 frame_id,
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                    size_t frame_size,
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                    base::TimeTicks when) OVERRIDE {
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Called when we receive an ACK for a frame.
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void AckFrame(uint32 frame_id, base::TimeTicks when) OVERRIDE {
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Returns the bitrate we should use for the next frame.
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual uint32 GetBitrate(base::TimeTicks playout_time,
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            base::TimeDelta playout_delay) OVERRIDE {
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return bitrate_;
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint32 bitrate_;
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(FixedCongestionControl);
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciCongestionControl* NewAdaptiveCongestionControl(
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::TickClock* clock,
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint32 max_bitrate_configured,
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint32 min_bitrate_configured,
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    size_t max_unacked_frames) {
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return new AdaptiveCongestionControl(clock,
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                       max_bitrate_configured,
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                       min_bitrate_configured,
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                       max_unacked_frames);
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciCongestionControl* NewFixedCongestionControl(uint32 bitrate) {
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return new FixedCongestionControl(bitrate);
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// This means that we *try* to keep our buffer 90% empty.
137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// If it is less full, we increase the bandwidth, if it is more
138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// we decrease the bandwidth. Making this smaller makes the
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// congestion control more aggressive.
140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)static const double kTargetEmptyBufferFraction = 0.9;
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// This is the size of our history in frames. Larger values makes the
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// congestion control adapt slower.
144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)static const size_t kHistorySize = 100;
1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciAdaptiveCongestionControl::FrameStats::FrameStats() : frame_size(0) {
147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciAdaptiveCongestionControl::AdaptiveCongestionControl(
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::TickClock* clock,
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint32 max_bitrate_configured,
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint32 min_bitrate_configured,
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    size_t max_unacked_frames)
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : clock_(clock),
1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      max_bitrate_configured_(max_bitrate_configured),
1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      min_bitrate_configured_(min_bitrate_configured),
157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      last_frame_stats_(static_cast<uint32>(-1)),
158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      last_acked_frame_(static_cast<uint32>(-1)),
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      last_encoded_frame_(static_cast<uint32>(-1)),
160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      history_size_(max_unacked_frames + kHistorySize),
161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      acked_bits_in_history_(0) {
1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_GE(max_bitrate_configured, min_bitrate_configured) << "Invalid config";
163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  frame_stats_.resize(2);
164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::TimeTicks now = clock->NowTicks();
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  frame_stats_[0].ack_time = now;
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  frame_stats_[0].sent_time = now;
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  frame_stats_[1].ack_time = now;
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(!frame_stats_[0].ack_time.is_null());
1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CongestionControl::~CongestionControl() {}
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciAdaptiveCongestionControl::~AdaptiveCongestionControl() {}
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AdaptiveCongestionControl::UpdateRtt(base::TimeDelta rtt) {
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  rtt_ = (7 * rtt_ + rtt) / 8;
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Calculate how much "dead air" there is between two frames.
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::TimeDelta AdaptiveCongestionControl::DeadTime(const FrameStats& a,
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                    const FrameStats& b) {
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (b.sent_time > a.ack_time) {
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return b.sent_time - a.ack_time;
183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  } else {
184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return base::TimeDelta();
185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccidouble AdaptiveCongestionControl::CalculateSafeBitrate() {
189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  double transmit_time =
190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      (GetFrameStats(last_acked_frame_)->ack_time -
191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)       frame_stats_.front().sent_time - dead_time_in_history_).InSecondsF();
192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (acked_bits_in_history_ == 0 || transmit_time <= 0.0) {
194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return min_bitrate_configured_;
195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return acked_bits_in_history_ / std::max(transmit_time, 1E-3);
197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciAdaptiveCongestionControl::FrameStats*
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciAdaptiveCongestionControl::GetFrameStats(uint32 frame_id) {
201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int32 offset = static_cast<int32>(frame_id - last_frame_stats_);
202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK_LT(offset, static_cast<int32>(kHistorySize));
203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (offset > 0) {
204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    frame_stats_.resize(frame_stats_.size() + offset);
205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    last_frame_stats_ += offset;
206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    offset = 0;
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  while (frame_stats_.size() > history_size_) {
209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    DCHECK_GT(frame_stats_.size(), 1UL);
210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    DCHECK(!frame_stats_[0].ack_time.is_null());
211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    acked_bits_in_history_ -= frame_stats_[0].frame_size;
212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    dead_time_in_history_ -= DeadTime(frame_stats_[0], frame_stats_[1]);
213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    DCHECK_GE(acked_bits_in_history_, 0UL);
214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    VLOG(2) << "DT: " << dead_time_in_history_.InSecondsF();
215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    DCHECK_GE(dead_time_in_history_.InSecondsF(), 0.0);
216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    frame_stats_.pop_front();
217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  offset += frame_stats_.size() - 1;
219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (offset < 0 || offset >= static_cast<int32>(frame_stats_.size())) {
220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return NULL;
221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return &frame_stats_[offset];
223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AdaptiveCongestionControl::AckFrame(uint32 frame_id,
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         base::TimeTicks when) {
227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  FrameStats* frame_stats = GetFrameStats(last_acked_frame_);
228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  while (IsNewerFrameId(frame_id, last_acked_frame_)) {
229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    FrameStats* last_frame_stats = frame_stats;
23003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    frame_stats = GetFrameStats(last_acked_frame_ + 1);
231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    DCHECK(frame_stats);
23203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (frame_stats->sent_time.is_null()) {
23303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // Can't ack a frame that hasn't been sent yet.
23403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return;
23503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    last_acked_frame_++;
23703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (when < frame_stats->sent_time)
23803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      when = frame_stats->sent_time;
23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    frame_stats->ack_time = when;
241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    acked_bits_in_history_ += frame_stats->frame_size;
242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    dead_time_in_history_ += DeadTime(*last_frame_stats, *frame_stats);
2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AdaptiveCongestionControl::SendFrameToTransport(uint32 frame_id,
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                     size_t frame_size,
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                     base::TimeTicks when) {
249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  last_encoded_frame_ = frame_id;
250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  FrameStats* frame_stats = GetFrameStats(frame_id);
251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(frame_stats);
252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  frame_stats->frame_size = frame_size;
253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  frame_stats->sent_time = when;
254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::TimeTicks AdaptiveCongestionControl::EstimatedAckTime(uint32 frame_id,
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                            double bitrate) {
258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  FrameStats* frame_stats = GetFrameStats(frame_id);
259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(frame_stats);
260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (frame_stats->ack_time.is_null()) {
261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    DCHECK(frame_stats->frame_size) << "frame_id: " << frame_id;
262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    base::TimeTicks ret = EstimatedSendingTime(frame_id, bitrate);
263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ret += base::TimeDelta::FromSecondsD(frame_stats->frame_size / bitrate);
264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ret += rtt_;
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    base::TimeTicks now = clock_->NowTicks();
266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (ret < now) {
267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // This is a little counter-intuitive, but it seems to work.
268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // Basically, when we estimate that the ACK should have already happened,
269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // we figure out how long ago it should have happened and guess that the
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // ACK will happen half of that time in the future. This will cause some
271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // over-estimation when acks are late, which is actually what we want.
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return now + (now - ret) / 2;
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    } else {
274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return ret;
275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  } else {
277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return frame_stats->ack_time;
2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::TimeTicks AdaptiveCongestionControl::EstimatedSendingTime(
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint32 frame_id,
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    double bitrate) {
284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  FrameStats* frame_stats = GetFrameStats(frame_id);
285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(frame_stats);
286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::TimeTicks ret = EstimatedAckTime(frame_id - 1, bitrate) - rtt_;
287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (frame_stats->sent_time.is_null()) {
288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Not sent yet, but we can't start sending it in the past.
289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return std::max(ret, clock_->NowTicks());
290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  } else {
291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return std::max(ret, frame_stats->sent_time);
292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciuint32 AdaptiveCongestionControl::GetBitrate(base::TimeTicks playout_time,
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                             base::TimeDelta playout_delay) {
297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  double safe_bitrate = CalculateSafeBitrate();
298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Estimate when we might start sending the next frame.
299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::TimeDelta time_to_catch_up =
300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      playout_time -
301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      EstimatedSendingTime(last_encoded_frame_ + 1, safe_bitrate);
302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  double empty_buffer_fraction =
304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      time_to_catch_up.InSecondsF() / playout_delay.InSecondsF();
305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  empty_buffer_fraction = std::min(empty_buffer_fraction, 1.0);
306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  empty_buffer_fraction = std::max(empty_buffer_fraction, 0.0);
307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  uint32 bits_per_second = static_cast<uint32>(
309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      safe_bitrate * empty_buffer_fraction / kTargetEmptyBufferFraction);
310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  VLOG(3) << " FBR:" << (bits_per_second / 1E6)
311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          << " EBF:" << empty_buffer_fraction
312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          << " SBR:" << (safe_bitrate / 1E6);
313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bits_per_second = std::max(bits_per_second, min_bitrate_configured_);
314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bits_per_second = std::min(bits_per_second, max_bitrate_configured_);
315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return bits_per_second;
3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}  // namespace cast
3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}  // namespace media
320