| Index: media/cast/sender/congestion_control.cc
|
| diff --git a/media/cast/sender/congestion_control.cc b/media/cast/sender/congestion_control.cc
|
| index ec134a73c0a87c01e2fdf8f4eee6d35d500551ae..2ce621a99685cbc8ef0b501c8881d6d2dd3309d1 100644
|
| --- a/media/cast/sender/congestion_control.cc
|
| +++ b/media/cast/sender/congestion_control.cc
|
| @@ -27,12 +27,14 @@ class AdaptiveCongestionControl : public CongestionControl {
|
| AdaptiveCongestionControl(base::TickClock* clock,
|
| uint32 max_bitrate_configured,
|
| uint32 min_bitrate_configured,
|
| - size_t max_unacked_frames);
|
| + double max_frame_rate);
|
|
|
| virtual ~AdaptiveCongestionControl() override;
|
|
|
| virtual void UpdateRtt(base::TimeDelta rtt) override;
|
|
|
| + virtual void UpdateTargetPlayoutDelay(base::TimeDelta delay) OVERRIDE;
|
| +
|
| // Called when an encoded frame is sent to the transport.
|
| virtual void SendFrameToTransport(uint32 frame_id,
|
| size_t frame_size,
|
| @@ -61,6 +63,8 @@ class AdaptiveCongestionControl : public CongestionControl {
|
| // Get the FrameStats for a given |frame_id|.
|
| // Note: Older FrameStats will be removed automatically.
|
| FrameStats* GetFrameStats(uint32 frame_id);
|
| + // Discard old FrameStats.
|
| + void PruneFrameStats();
|
| // Calculate a safe bitrate. This is based on how much we've been
|
| // sending in the past.
|
| double CalculateSafeBitrate();
|
| @@ -76,6 +80,7 @@ class AdaptiveCongestionControl : public CongestionControl {
|
| base::TickClock* const clock_; // Not owned by this class.
|
| const uint32 max_bitrate_configured_;
|
| const uint32 min_bitrate_configured_;
|
| + const double max_frame_rate_;
|
| std::deque<FrameStats> frame_stats_;
|
| uint32 last_frame_stats_;
|
| uint32 last_acked_frame_;
|
| @@ -96,6 +101,9 @@ class FixedCongestionControl : public CongestionControl {
|
| virtual void UpdateRtt(base::TimeDelta rtt) override {
|
| }
|
|
|
| + virtual void UpdateTargetPlayoutDelay(base::TimeDelta delay) OVERRIDE {
|
| + }
|
| +
|
| // Called when an encoded frame is sent to the transport.
|
| virtual void SendFrameToTransport(uint32 frame_id,
|
| size_t frame_size,
|
| @@ -122,11 +130,11 @@ CongestionControl* NewAdaptiveCongestionControl(
|
| base::TickClock* clock,
|
| uint32 max_bitrate_configured,
|
| uint32 min_bitrate_configured,
|
| - size_t max_unacked_frames) {
|
| + double max_frame_rate) {
|
| return new AdaptiveCongestionControl(clock,
|
| max_bitrate_configured,
|
| min_bitrate_configured,
|
| - max_unacked_frames);
|
| + max_frame_rate);
|
| }
|
|
|
| CongestionControl* NewFixedCongestionControl(uint32 bitrate) {
|
| @@ -150,14 +158,15 @@ AdaptiveCongestionControl::AdaptiveCongestionControl(
|
| base::TickClock* clock,
|
| uint32 max_bitrate_configured,
|
| uint32 min_bitrate_configured,
|
| - size_t max_unacked_frames)
|
| + double max_frame_rate)
|
| : clock_(clock),
|
| max_bitrate_configured_(max_bitrate_configured),
|
| min_bitrate_configured_(min_bitrate_configured),
|
| + max_frame_rate_(max_frame_rate),
|
| last_frame_stats_(static_cast<uint32>(-1)),
|
| last_acked_frame_(static_cast<uint32>(-1)),
|
| last_encoded_frame_(static_cast<uint32>(-1)),
|
| - history_size_(max_unacked_frames + kHistorySize),
|
| + history_size_(kHistorySize),
|
| acked_bits_in_history_(0) {
|
| DCHECK_GE(max_bitrate_configured, min_bitrate_configured) << "Invalid config";
|
| frame_stats_.resize(2);
|
| @@ -175,6 +184,17 @@ void AdaptiveCongestionControl::UpdateRtt(base::TimeDelta rtt) {
|
| rtt_ = (7 * rtt_ + rtt) / 8;
|
| }
|
|
|
| +void AdaptiveCongestionControl::UpdateTargetPlayoutDelay(
|
| + base::TimeDelta delay) {
|
| + const int max_unacked_frames =
|
| + std::min(kMaxUnackedFrames,
|
| + 1 + static_cast<int>(delay * max_frame_rate_ /
|
| + base::TimeDelta::FromSeconds(1)));
|
| + DCHECK_GT(max_unacked_frames, 0);
|
| + history_size_ = max_unacked_frames + kHistorySize;
|
| + PruneFrameStats();
|
| +}
|
| +
|
| // Calculate how much "dead air" there is between two frames.
|
| base::TimeDelta AdaptiveCongestionControl::DeadTime(const FrameStats& a,
|
| const FrameStats& b) {
|
| @@ -205,7 +225,16 @@ AdaptiveCongestionControl::GetFrameStats(uint32 frame_id) {
|
| last_frame_stats_ += offset;
|
| offset = 0;
|
| }
|
| - while (frame_stats_.size() > history_size_) {
|
| + PruneFrameStats();
|
| + offset += frame_stats_.size() - 1;
|
| + if (offset < 0 || offset >= static_cast<int32>(frame_stats_.size())) {
|
| + return NULL;
|
| + }
|
| + return &frame_stats_[offset];
|
| +}
|
| +
|
| +void AdaptiveCongestionControl::PruneFrameStats() {
|
| + while (frame_stats_.size() > history_size_) {
|
| DCHECK_GT(frame_stats_.size(), 1UL);
|
| DCHECK(!frame_stats_[0].ack_time.is_null());
|
| acked_bits_in_history_ -= frame_stats_[0].frame_size;
|
| @@ -215,11 +244,6 @@ AdaptiveCongestionControl::GetFrameStats(uint32 frame_id) {
|
| DCHECK_GE(dead_time_in_history_.InSecondsF(), 0.0);
|
| frame_stats_.pop_front();
|
| }
|
| - offset += frame_stats_.size() - 1;
|
| - if (offset < 0 || offset >= static_cast<int32>(frame_stats_.size())) {
|
| - return NULL;
|
| - }
|
| - return &frame_stats_[offset];
|
| }
|
|
|
| void AdaptiveCongestionControl::AckFrame(uint32 frame_id,
|
|
|