X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmedia%2Fcast%2Fsender%2Fcongestion_control.cc;h=d14f9b08f3736c6234631ebf78e5f9cbfc7b11f7;hb=1afa4dd80ef85af7c90efaea6959db1d92330844;hp=30e3be7d6e8245503a1c98d137aa33605dc4cf08;hpb=90762837333c13ccf56f2ad88e4481fc71e8d281;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/media/cast/sender/congestion_control.cc b/src/media/cast/sender/congestion_control.cc index 30e3be7..d14f9b0 100644 --- a/src/media/cast/sender/congestion_control.cc +++ b/src/media/cast/sender/congestion_control.cc @@ -27,23 +27,25 @@ 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; + ~AdaptiveCongestionControl() override; - virtual void UpdateRtt(base::TimeDelta rtt) OVERRIDE; + void UpdateRtt(base::TimeDelta rtt) override; + + 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, - base::TimeTicks when) OVERRIDE; + void SendFrameToTransport(uint32 frame_id, + size_t frame_size, + base::TimeTicks when) override; // Called when we receive an ACK for a frame. - virtual void AckFrame(uint32 frame_id, base::TimeTicks when) OVERRIDE; + void AckFrame(uint32 frame_id, base::TimeTicks when) override; // Returns the bitrate we should use for the next frame. - virtual uint32 GetBitrate(base::TimeTicks playout_time, - base::TimeDelta playout_delay) OVERRIDE; + uint32 GetBitrate(base::TimeTicks playout_time, + base::TimeDelta playout_delay) override; private: struct FrameStats { @@ -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 frame_stats_; uint32 last_frame_stats_; uint32 last_acked_frame_; @@ -91,24 +96,23 @@ class AdaptiveCongestionControl : public CongestionControl { class FixedCongestionControl : public CongestionControl { public: FixedCongestionControl(uint32 bitrate) : bitrate_(bitrate) {} - virtual ~FixedCongestionControl() OVERRIDE {} + ~FixedCongestionControl() override {} - virtual void UpdateRtt(base::TimeDelta rtt) OVERRIDE { - } + void UpdateRtt(base::TimeDelta rtt) override {} + + 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, - base::TimeTicks when) OVERRIDE { - } + void SendFrameToTransport(uint32 frame_id, + size_t frame_size, + base::TimeTicks when) override {} // Called when we receive an ACK for a frame. - virtual void AckFrame(uint32 frame_id, base::TimeTicks when) OVERRIDE { - } + void AckFrame(uint32 frame_id, base::TimeTicks when) override {} // Returns the bitrate we should use for the next frame. - virtual uint32 GetBitrate(base::TimeTicks playout_time, - base::TimeDelta playout_delay) OVERRIDE { + uint32 GetBitrate(base::TimeTicks playout_time, + base::TimeDelta playout_delay) override { return bitrate_; } @@ -122,11 +126,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 +154,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(-1)), last_acked_frame_(static_cast(-1)), last_encoded_frame_(static_cast(-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 +180,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(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 +221,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(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 +240,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(frame_stats_.size())) { - return NULL; - } - return &frame_stats_[offset]; } void AdaptiveCongestionControl::AckFrame(uint32 frame_id,