summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authormiu <miu@chromium.org>2014-10-07 13:06:14 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-07 20:07:08 +0000
commit641adc1265ca1c6ebadddcfcc0319246b65eefde (patch)
tree31c95844ba653486e45fb960572fb49a015fc00d /media
parent33ad38a13f01ea429e3f2f060325cfe2df47ea2e (diff)
downloadchromium_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.cc2
-rw-r--r--media/cast/sender/audio_sender.cc2
-rw-r--r--media/cast/sender/congestion_control.cc46
-rw-r--r--media/cast/sender/congestion_control.h5
-rw-r--r--media/cast/sender/congestion_control_unittest.cc15
-rw-r--r--media/cast/sender/frame_sender.cc13
-rw-r--r--media/cast/sender/frame_sender.h4
-rw-r--r--media/cast/sender/video_encoder_impl.cc5
-rw-r--r--media/cast/sender/video_encoder_impl.h3
-rw-r--r--media/cast/sender/video_encoder_impl_unittest.cc5
-rw-r--r--media/cast/sender/video_sender.cc22
-rw-r--r--media/cast/sender/vp8_encoder.cc3
-rw-r--r--media/cast/sender/vp8_encoder.h2
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();