diff options
author | miu <miu@chromium.org> | 2014-10-07 13:06:14 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-07 20:07:08 +0000 |
commit | 641adc1265ca1c6ebadddcfcc0319246b65eefde (patch) | |
tree | 31c95844ba653486e45fb960572fb49a015fc00d /media | |
parent | 33ad38a13f01ea429e3f2f060325cfe2df47ea2e (diff) | |
download | chromium_src-641adc1265ca1c6ebadddcfcc0319246b65eefde.zip chromium_src-641adc1265ca1c6ebadddcfcc0319246b65eefde.tar.gz chromium_src-641adc1265ca1c6ebadddcfcc0319246b65eefde.tar.bz2 |
[Cast] Clean-up: Move max_unacked_frames into CongestionControl.
max_unacked_frames isn't being used anywhere except within
CongestionControl now that FrameSender uses media duration to decide
whether to drop frames.
BUG=404813
Review URL: https://codereview.chromium.org/629493004
Cr-Commit-Position: refs/heads/master@{#298551}
Diffstat (limited to 'media')
-rw-r--r-- | media/cast/receiver/video_decoder_unittest.cc | 2 | ||||
-rw-r--r-- | media/cast/sender/audio_sender.cc | 2 | ||||
-rw-r--r-- | media/cast/sender/congestion_control.cc | 46 | ||||
-rw-r--r-- | media/cast/sender/congestion_control.h | 5 | ||||
-rw-r--r-- | media/cast/sender/congestion_control_unittest.cc | 15 | ||||
-rw-r--r-- | media/cast/sender/frame_sender.cc | 13 | ||||
-rw-r--r-- | media/cast/sender/frame_sender.h | 4 | ||||
-rw-r--r-- | media/cast/sender/video_encoder_impl.cc | 5 | ||||
-rw-r--r-- | media/cast/sender/video_encoder_impl.h | 3 | ||||
-rw-r--r-- | media/cast/sender/video_encoder_impl_unittest.cc | 5 | ||||
-rw-r--r-- | media/cast/sender/video_sender.cc | 22 | ||||
-rw-r--r-- | media/cast/sender/vp8_encoder.cc | 3 | ||||
-rw-r--r-- | media/cast/sender/vp8_encoder.h | 2 |
13 files changed, 74 insertions, 53 deletions
diff --git a/media/cast/receiver/video_decoder_unittest.cc b/media/cast/receiver/video_decoder_unittest.cc index 1397b57..2184707 100644 --- a/media/cast/receiver/video_decoder_unittest.cc +++ b/media/cast/receiver/video_decoder_unittest.cc @@ -40,7 +40,7 @@ class VideoDecoderTest : public ::testing::TestWithParam<Codec> { public: VideoDecoderTest() : cast_environment_(new StandaloneCastEnvironment()), - vp8_encoder_(GetVideoSenderConfigForTest(), 0), + vp8_encoder_(GetVideoSenderConfigForTest()), cond_(&lock_) { vp8_encoder_.Initialize(); } diff --git a/media/cast/sender/audio_sender.cc b/media/cast/sender/audio_sender.cc index 23fd6d1..8916a17 100644 --- a/media/cast/sender/audio_sender.cc +++ b/media/cast/sender/audio_sender.cc @@ -39,8 +39,6 @@ AudioSender::AudioSender(scoped_refptr<CastEnvironment> cast_environment, samples_in_encoder_(0), weak_factory_(this) { cast_initialization_status_ = STATUS_AUDIO_UNINITIALIZED; - VLOG(1) << "max_unacked_frames " << max_unacked_frames_; - DCHECK_GT(max_unacked_frames_, 0); if (!audio_config.use_external_encoder) { audio_encoder_.reset( diff --git a/media/cast/sender/congestion_control.cc b/media/cast/sender/congestion_control.cc index ec134a7..2ce621a9 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, diff --git a/media/cast/sender/congestion_control.h b/media/cast/sender/congestion_control.h index 5d1256f..8c3d764 100644 --- a/media/cast/sender/congestion_control.h +++ b/media/cast/sender/congestion_control.h @@ -22,6 +22,9 @@ class CongestionControl { // Called with latest measured rtt value. virtual void UpdateRtt(base::TimeDelta rtt) = 0; + // Called with an updated target playout delay value. + virtual void UpdateTargetPlayoutDelay(base::TimeDelta delay) = 0; + // Called when an encoded frame is sent to the transport. virtual void SendFrameToTransport(uint32 frame_id, size_t frame_size, @@ -38,7 +41,7 @@ CongestionControl* NewAdaptiveCongestionControl( base::TickClock* clock, uint32 max_bitrate_configured, uint32 min_bitrate_configured, - size_t max_unacked_frames); + double max_frame_rate); CongestionControl* NewFixedCongestionControl(uint32 bitrate); diff --git a/media/cast/sender/congestion_control_unittest.cc b/media/cast/sender/congestion_control_unittest.cc index ec68c02..bf76a35 100644 --- a/media/cast/sender/congestion_control_unittest.cc +++ b/media/cast/sender/congestion_control_unittest.cc @@ -16,6 +16,8 @@ namespace cast { static const uint32 kMaxBitrateConfigured = 5000000; static const uint32 kMinBitrateConfigured = 500000; +static const int64 kFrameDelayMs = 33; +static const double kMaxFrameRate = 1000.0 / kFrameDelayMs; static const int64 kStartMillisecond = INT64_C(12345678900000); static const double kTargetEmptyBufferFraction = 0.9; @@ -26,7 +28,13 @@ class CongestionControlTest : public ::testing::Test { testing_clock_.Advance( base::TimeDelta::FromMilliseconds(kStartMillisecond)); congestion_control_.reset(NewAdaptiveCongestionControl( - &testing_clock_, kMaxBitrateConfigured, kMinBitrateConfigured, 10)); + &testing_clock_, kMaxBitrateConfigured, kMinBitrateConfigured, + kMaxFrameRate)); + const int max_unacked_frames = 10; + const base::TimeDelta target_playout_delay = + (max_unacked_frames - 1) * base::TimeDelta::FromSeconds(1) / + kMaxFrameRate; + congestion_control_->UpdateTargetPlayoutDelay(target_playout_delay); } void AckFrame(uint32 frame_id) { @@ -60,17 +68,16 @@ class CongestionControlTest : public ::testing::Test { }; TEST_F(CongestionControlTest, SimpleRun) { - uint32 frame_delay = 33; uint32 frame_size = 10000 * 8; Run(500, frame_size, base::TimeDelta::FromMilliseconds(10), - base::TimeDelta::FromMilliseconds(frame_delay), + base::TimeDelta::FromMilliseconds(kFrameDelayMs), base::TimeDelta::FromMilliseconds(45)); // Empty the buffer. task_runner_->Sleep(base::TimeDelta::FromMilliseconds(100)); - uint32 safe_bitrate = frame_size * 1000 / frame_delay; + uint32 safe_bitrate = frame_size * 1000 / kFrameDelayMs; uint32 bitrate = congestion_control_->GetBitrate( testing_clock_.NowTicks() + base::TimeDelta::FromMilliseconds(300), base::TimeDelta::FromMilliseconds(300)); diff --git a/media/cast/sender/frame_sender.cc b/media/cast/sender/frame_sender.cc index 0b94f74..04205f3 100644 --- a/media/cast/sender/frame_sender.cc +++ b/media/cast/sender/frame_sender.cc @@ -106,17 +106,20 @@ void FrameSender::OnMeasuredRoundTripTime(base::TimeDelta rtt) { void FrameSender::SetTargetPlayoutDelay( base::TimeDelta new_target_playout_delay) { + if (send_target_playout_delay_ && + target_playout_delay_ == new_target_playout_delay) { + return; + } new_target_playout_delay = std::max(new_target_playout_delay, min_playout_delay_); new_target_playout_delay = std::min(new_target_playout_delay, max_playout_delay_); + VLOG(2) << SENDER_SSRC << "Target playout delay changing from " + << target_playout_delay_.InMilliseconds() << " ms to " + << new_target_playout_delay.InMilliseconds() << " ms."; target_playout_delay_ = new_target_playout_delay; - max_unacked_frames_ = - std::min(kMaxUnackedFrames, - 1 + static_cast<int>(target_playout_delay_ * - max_frame_rate_ / - base::TimeDelta::FromSeconds(1))); send_target_playout_delay_ = true; + congestion_control_->UpdateTargetPlayoutDelay(target_playout_delay_); } void FrameSender::ResendCheck() { diff --git a/media/cast/sender/frame_sender.h b/media/cast/sender/frame_sender.h index 0e8595d..a3ef1e5 100644 --- a/media/cast/sender/frame_sender.h +++ b/media/cast/sender/frame_sender.h @@ -125,10 +125,6 @@ class FrameSender { // Max encoded frames generated per second. double max_frame_rate_; - // Maximum number of outstanding frames before the encoding and sending of - // new frames shall halt. - int max_unacked_frames_; - // Counts how many RTCP reports are being "aggressively" sent (i.e., one per // frame) at the start of the session. Once a threshold is reached, RTCP // reports are instead sent at the configured interval + random drift. diff --git a/media/cast/sender/video_encoder_impl.cc b/media/cast/sender/video_encoder_impl.cc index d27fb10..a54ddfc 100644 --- a/media/cast/sender/video_encoder_impl.cc +++ b/media/cast/sender/video_encoder_impl.cc @@ -54,11 +54,10 @@ void EncodeVideoFrameOnEncoderThread( VideoEncoderImpl::VideoEncoderImpl( scoped_refptr<CastEnvironment> cast_environment, - const VideoSenderConfig& video_config, - int max_unacked_frames) + const VideoSenderConfig& video_config) : cast_environment_(cast_environment) { if (video_config.codec == CODEC_VIDEO_VP8) { - encoder_.reset(new Vp8Encoder(video_config, max_unacked_frames)); + encoder_.reset(new Vp8Encoder(video_config)); cast_environment_->PostTask(CastEnvironment::VIDEO, FROM_HERE, base::Bind(&InitializeEncoderOnEncoderThread, diff --git a/media/cast/sender/video_encoder_impl.h b/media/cast/sender/video_encoder_impl.h index ae2b85f..47401ea 100644 --- a/media/cast/sender/video_encoder_impl.h +++ b/media/cast/sender/video_encoder_impl.h @@ -30,8 +30,7 @@ class VideoEncoderImpl : public VideoEncoder { FrameEncodedCallback; VideoEncoderImpl(scoped_refptr<CastEnvironment> cast_environment, - const VideoSenderConfig& video_config, - int max_unacked_frames); + const VideoSenderConfig& video_config); virtual ~VideoEncoderImpl(); diff --git a/media/cast/sender/video_encoder_impl_unittest.cc b/media/cast/sender/video_encoder_impl_unittest.cc index adacdd0..7c0047f 100644 --- a/media/cast/sender/video_encoder_impl_unittest.cc +++ b/media/cast/sender/video_encoder_impl_unittest.cc @@ -108,9 +108,8 @@ class VideoEncoderImplTest : public ::testing::Test { void CreateEncoder() { test_video_encoder_callback_ = new TestVideoEncoderCallback( video_config_.max_number_of_video_buffers_used != 1); - video_encoder_.reset(new VideoEncoderImpl( - cast_environment_, video_config_, - 0 /* useless arg to be removed in later change */)); + video_encoder_.reset( + new VideoEncoderImpl(cast_environment_, video_config_)); } void AdvanceClockAndVideoFrameTimestamp() { diff --git a/media/cast/sender/video_sender.cc b/media/cast/sender/video_sender.cc index dd8e7f5..16b7159 100644 --- a/media/cast/sender/video_sender.cc +++ b/media/cast/sender/video_sender.cc @@ -56,18 +56,18 @@ VideoSender::VideoSender( video_config.max_frame_rate, video_config.min_playout_delay, video_config.max_playout_delay, - NewFixedCongestionControl( - (video_config.min_bitrate + video_config.max_bitrate) / 2)), + video_config.use_external_encoder ? + NewFixedCongestionControl( + (video_config.min_bitrate + video_config.max_bitrate) / 2) : + NewAdaptiveCongestionControl(cast_environment->Clock(), + video_config.max_bitrate, + video_config.min_bitrate, + video_config.max_frame_rate)), frames_in_encoder_(0), last_bitrate_(0), playout_delay_change_cb_(playout_delay_change_cb), weak_factory_(this) { cast_initialization_status_ = STATUS_VIDEO_UNINITIALIZED; - VLOG(1) << "max_unacked_frames is " << max_unacked_frames_ - << " for target_playout_delay=" - << target_playout_delay_.InMilliseconds() << " ms" - << " and max_frame_rate=" << video_config.max_frame_rate; - DCHECK_GT(max_unacked_frames_, 0); if (video_config.use_external_encoder) { video_encoder_.reset(new ExternalVideoEncoder( @@ -79,13 +79,7 @@ VideoSender::VideoSender( create_video_encode_mem_cb)); } else { // Software encoder is initialized immediately. - congestion_control_.reset( - NewAdaptiveCongestionControl(cast_environment->Clock(), - video_config.max_bitrate, - video_config.min_bitrate, - max_unacked_frames_)); - video_encoder_.reset(new VideoEncoderImpl( - cast_environment, video_config, max_unacked_frames_)); + video_encoder_.reset(new VideoEncoderImpl(cast_environment, video_config)); cast_initialization_status_ = STATUS_VIDEO_INITIALIZED; } diff --git a/media/cast/sender/vp8_encoder.cc b/media/cast/sender/vp8_encoder.cc index da42fc0..54a579d 100644 --- a/media/cast/sender/vp8_encoder.cc +++ b/media/cast/sender/vp8_encoder.cc @@ -15,8 +15,7 @@ namespace cast { static const uint32 kMinIntra = 300; -Vp8Encoder::Vp8Encoder(const VideoSenderConfig& video_config, - int max_unacked_frames) +Vp8Encoder::Vp8Encoder(const VideoSenderConfig& video_config) : cast_config_(video_config), use_multiple_video_buffers_( cast_config_.max_number_of_video_buffers_used == diff --git a/media/cast/sender/vp8_encoder.h b/media/cast/sender/vp8_encoder.h index cb9861f..c9b6705 100644 --- a/media/cast/sender/vp8_encoder.h +++ b/media/cast/sender/vp8_encoder.h @@ -21,7 +21,7 @@ namespace cast { class Vp8Encoder : public SoftwareVideoEncoder { public: - Vp8Encoder(const VideoSenderConfig& video_config, int max_unacked_frames); + explicit Vp8Encoder(const VideoSenderConfig& video_config); virtual ~Vp8Encoder(); |