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