| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // This test generate synthetic data. For audio it's a sinusoid waveform with | 5 // This test generate synthetic data. For audio it's a sinusoid waveform with |
| 6 // frequency kSoundFrequency and different amplitudes. For video it's a pattern | 6 // frequency kSoundFrequency and different amplitudes. For video it's a pattern |
| 7 // that is shifting by one pixel per frame, each pixels neighbors right and down | 7 // that is shifting by one pixel per frame, each pixels neighbors right and down |
| 8 // is this pixels value +1, since the pixel value is 8 bit it will wrap | 8 // is this pixels value +1, since the pixel value is 8 bit it will wrap |
| 9 // frequently within the image. Visually this will create diagonally color bands | 9 // frequently within the image. Visually this will create diagonally color bands |
| 10 // that moves across the screen | 10 // that moves across the screen |
| 11 | 11 |
| 12 #include <math.h> | 12 #include <math.h> |
| 13 | 13 |
| 14 #include <functional> | 14 #include <functional> |
| 15 #include <list> | 15 #include <list> |
| 16 #include <map> | 16 #include <map> |
| 17 | 17 |
| 18 #include "base/bind.h" | 18 #include "base/bind.h" |
| 19 #include "base/bind_helpers.h" | 19 #include "base/bind_helpers.h" |
| 20 #include "base/stl_util.h" |
| 20 #include "base/strings/string_number_conversions.h" | 21 #include "base/strings/string_number_conversions.h" |
| 22 #include "base/sys_byteorder.h" |
| 21 #include "base/test/simple_test_tick_clock.h" | 23 #include "base/test/simple_test_tick_clock.h" |
| 22 #include "base/time/tick_clock.h" | 24 #include "base/time/tick_clock.h" |
| 25 #include "media/base/audio_bus.h" |
| 23 #include "media/base/video_frame.h" | 26 #include "media/base/video_frame.h" |
| 24 #include "media/cast/cast_config.h" | 27 #include "media/cast/cast_config.h" |
| 25 #include "media/cast/cast_environment.h" | 28 #include "media/cast/cast_environment.h" |
| 26 #include "media/cast/cast_receiver.h" | 29 #include "media/cast/cast_receiver.h" |
| 27 #include "media/cast/cast_sender.h" | 30 #include "media/cast/cast_sender.h" |
| 28 #include "media/cast/logging/simple_event_subscriber.h" | 31 #include "media/cast/logging/simple_event_subscriber.h" |
| 29 #include "media/cast/test/fake_single_thread_task_runner.h" | 32 #include "media/cast/test/fake_single_thread_task_runner.h" |
| 30 #include "media/cast/test/utility/audio_utility.h" | 33 #include "media/cast/test/utility/audio_utility.h" |
| 31 #include "media/cast/test/utility/default_config.h" | 34 #include "media/cast/test/utility/default_config.h" |
| 32 #include "media/cast/test/utility/video_utility.h" | 35 #include "media/cast/test/utility/video_utility.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 // retransmitted. | 69 // retransmitted. |
| 67 // In addition, audio packets are sent in 10mS intervals in audio_encoder.cc, | 70 // In addition, audio packets are sent in 10mS intervals in audio_encoder.cc, |
| 68 // although we send an audio frame every 33mS, which adds an extra delay. | 71 // although we send an audio frame every 33mS, which adds an extra delay. |
| 69 // A TODO was added in the code to resolve this. | 72 // A TODO was added in the code to resolve this. |
| 70 static const int kTimerErrorMs = 20; | 73 static const int kTimerErrorMs = 20; |
| 71 | 74 |
| 72 // Start the video synthetic start value to medium range value, to avoid edge | 75 // Start the video synthetic start value to medium range value, to avoid edge |
| 73 // effects cause by encoding and quantization. | 76 // effects cause by encoding and quantization. |
| 74 static const int kVideoStart = 100; | 77 static const int kVideoStart = 100; |
| 75 | 78 |
| 79 // The size of audio frames. The encoder joins/breaks all inserted audio into |
| 80 // chunks of this size. |
| 81 static const int kAudioFrameDurationMs = 10; |
| 82 |
| 76 std::string ConvertFromBase16String(const std::string base_16) { | 83 std::string ConvertFromBase16String(const std::string base_16) { |
| 77 std::string compressed; | 84 std::string compressed; |
| 78 DCHECK_EQ(base_16.size() % 2, 0u) << "Must be a multiple of 2"; | 85 DCHECK_EQ(base_16.size() % 2, 0u) << "Must be a multiple of 2"; |
| 79 compressed.reserve(base_16.size() / 2); | 86 compressed.reserve(base_16.size() / 2); |
| 80 | 87 |
| 81 std::vector<uint8> v; | 88 std::vector<uint8> v; |
| 82 if (!base::HexStringToBytes(base_16, &v)) { | 89 if (!base::HexStringToBytes(base_16, &v)) { |
| 83 NOTREACHED(); | 90 NOTREACHED(); |
| 84 } | 91 } |
| 85 compressed.assign(reinterpret_cast<const char*>(&v[0]), v.size()); | 92 compressed.assign(reinterpret_cast<const char*>(&v[0]), v.size()); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 bool drop_packets_belonging_to_odd_frames_; | 209 bool drop_packets_belonging_to_odd_frames_; |
| 203 bool reset_reference_frame_id_; | 210 bool reset_reference_frame_id_; |
| 204 scoped_refptr<CastEnvironment> cast_environment_; | 211 scoped_refptr<CastEnvironment> cast_environment_; |
| 205 }; | 212 }; |
| 206 | 213 |
| 207 // Class that verifies the audio frames coming out of the receiver. | 214 // Class that verifies the audio frames coming out of the receiver. |
| 208 class TestReceiverAudioCallback | 215 class TestReceiverAudioCallback |
| 209 : public base::RefCountedThreadSafe<TestReceiverAudioCallback> { | 216 : public base::RefCountedThreadSafe<TestReceiverAudioCallback> { |
| 210 public: | 217 public: |
| 211 struct ExpectedAudioFrame { | 218 struct ExpectedAudioFrame { |
| 212 PcmAudioFrame audio_frame; | 219 scoped_ptr<AudioBus> audio_bus; |
| 213 int num_10ms_blocks; | |
| 214 base::TimeTicks record_time; | 220 base::TimeTicks record_time; |
| 215 }; | 221 }; |
| 216 | 222 |
| 217 TestReceiverAudioCallback() : num_called_(0) {} | 223 TestReceiverAudioCallback() : num_called_(0) {} |
| 218 | 224 |
| 219 void SetExpectedSamplingFrequency(int expected_sampling_frequency) { | 225 void SetExpectedSamplingFrequency(int expected_sampling_frequency) { |
| 220 expected_sampling_frequency_ = expected_sampling_frequency; | 226 expected_sampling_frequency_ = expected_sampling_frequency; |
| 221 } | 227 } |
| 222 | 228 |
| 223 void AddExpectedResult(scoped_ptr<PcmAudioFrame> audio_frame, | 229 void AddExpectedResult(const AudioBus& audio_bus, |
| 224 int expected_num_10ms_blocks, | |
| 225 const base::TimeTicks& record_time) { | 230 const base::TimeTicks& record_time) { |
| 226 ExpectedAudioFrame expected_audio_frame; | 231 scoped_ptr<ExpectedAudioFrame> expected_audio_frame( |
| 227 expected_audio_frame.audio_frame = *audio_frame; | 232 new ExpectedAudioFrame()); |
| 228 expected_audio_frame.num_10ms_blocks = expected_num_10ms_blocks; | 233 expected_audio_frame->audio_bus = |
| 229 expected_audio_frame.record_time = record_time; | 234 AudioBus::Create(audio_bus.channels(), audio_bus.frames()).Pass(); |
| 230 expected_frame_.push_back(expected_audio_frame); | 235 audio_bus.CopyTo(expected_audio_frame->audio_bus.get()); |
| 236 expected_audio_frame->record_time = record_time; |
| 237 expected_frames_.push_back(expected_audio_frame.release()); |
| 231 } | 238 } |
| 232 | 239 |
| 233 void IgnoreAudioFrame(scoped_ptr<PcmAudioFrame> audio_frame, | 240 void IgnoreAudioFrame(scoped_ptr<AudioBus> audio_bus, |
| 234 const base::TimeTicks& playout_time) {} | 241 const base::TimeTicks& playout_time, |
| 242 bool is_continuous) { |
| 243 ++num_called_; |
| 244 } |
| 235 | 245 |
| 236 // Check the audio frame parameters but not the audio samples. | 246 void CheckAudioFrame(scoped_ptr<AudioBus> audio_bus, |
| 237 void CheckBasicAudioFrame(const scoped_ptr<PcmAudioFrame>& audio_frame, | 247 const base::TimeTicks& playout_time, |
| 238 const base::TimeTicks& playout_time) { | 248 bool is_continuous) { |
| 239 EXPECT_FALSE(expected_frame_.empty()); // Test for bug in test code. | 249 ++num_called_; |
| 240 ExpectedAudioFrame expected_audio_frame = expected_frame_.front(); | |
| 241 EXPECT_EQ(audio_frame->channels, kAudioChannels); | |
| 242 EXPECT_EQ(audio_frame->frequency, expected_sampling_frequency_); | |
| 243 EXPECT_EQ(static_cast<int>(audio_frame->samples.size()), | |
| 244 expected_audio_frame.num_10ms_blocks * kAudioChannels * | |
| 245 expected_sampling_frequency_ / 100); | |
| 246 | 250 |
| 251 ASSERT_FALSE(expected_frames_.empty()); |
| 252 const scoped_ptr<ExpectedAudioFrame> expected_audio_frame( |
| 253 expected_frames_.front()); |
| 254 expected_frames_.pop_front(); |
| 255 |
| 256 EXPECT_EQ(audio_bus->channels(), kAudioChannels); |
| 257 EXPECT_EQ(audio_bus->frames(), expected_audio_frame->audio_bus->frames()); |
| 258 for (int ch = 0; ch < audio_bus->channels(); ++ch) { |
| 259 EXPECT_NEAR(CountZeroCrossings( |
| 260 expected_audio_frame->audio_bus->channel(ch), |
| 261 expected_audio_frame->audio_bus->frames()), |
| 262 CountZeroCrossings(audio_bus->channel(ch), |
| 263 audio_bus->frames()), |
| 264 1); |
| 265 } |
| 266 |
| 267 // TODO(miu): This is a "fuzzy" way to check the timestamps. We should be |
| 268 // able to compute exact offsets with "omnipotent" knowledge of the system. |
| 247 const base::TimeTicks upper_bound = | 269 const base::TimeTicks upper_bound = |
| 248 expected_audio_frame.record_time + | 270 expected_audio_frame->record_time + |
| 249 base::TimeDelta::FromMilliseconds(kDefaultRtpMaxDelayMs + | 271 base::TimeDelta::FromMilliseconds(kDefaultRtpMaxDelayMs + |
| 250 kTimerErrorMs); | 272 kTimerErrorMs); |
| 251 EXPECT_GE(upper_bound, playout_time) | 273 EXPECT_GE(upper_bound, playout_time) |
| 252 << "playout_time - upper_bound == " | 274 << "playout_time - upper_bound == " |
| 253 << (playout_time - upper_bound).InMicroseconds() << " usec"; | 275 << (playout_time - upper_bound).InMicroseconds() << " usec"; |
| 254 EXPECT_LT(expected_audio_frame.record_time, playout_time) | |
| 255 << "playout_time - expected == " | |
| 256 << (playout_time - expected_audio_frame.record_time).InMilliseconds() | |
| 257 << " mS"; | |
| 258 | 276 |
| 259 EXPECT_EQ(audio_frame->samples.size(), | 277 EXPECT_TRUE(is_continuous); |
| 260 expected_audio_frame.audio_frame.samples.size()); | |
| 261 } | 278 } |
| 262 | 279 |
| 263 void CheckPcmAudioFrame(scoped_ptr<PcmAudioFrame> audio_frame, | 280 void CheckCodedAudioFrame( |
| 264 const base::TimeTicks& playout_time) { | |
| 265 ++num_called_; | |
| 266 | |
| 267 CheckBasicAudioFrame(audio_frame, playout_time); | |
| 268 ExpectedAudioFrame expected_audio_frame = expected_frame_.front(); | |
| 269 expected_frame_.pop_front(); | |
| 270 if (audio_frame->samples.size() == 0) | |
| 271 return; // No more checks needed. | |
| 272 | |
| 273 EXPECT_NEAR(CountZeroCrossings(expected_audio_frame.audio_frame.samples), | |
| 274 CountZeroCrossings(audio_frame->samples), | |
| 275 1); | |
| 276 } | |
| 277 | |
| 278 void CheckCodedPcmAudioFrame( | |
| 279 scoped_ptr<transport::EncodedAudioFrame> audio_frame, | 281 scoped_ptr<transport::EncodedAudioFrame> audio_frame, |
| 280 const base::TimeTicks& playout_time) { | 282 const base::TimeTicks& playout_time) { |
| 281 ++num_called_; | 283 ASSERT_FALSE(expected_frames_.empty()); |
| 284 const ExpectedAudioFrame& expected_audio_frame = |
| 285 *(expected_frames_.front()); |
| 286 // Note: Just peeking here. Will delegate to CheckAudioFrame() to pop. |
| 282 | 287 |
| 283 EXPECT_FALSE(expected_frame_.empty()); // Test for bug in test code. | 288 // We need to "decode" the encoded audio frame. The codec is simply to |
| 284 ExpectedAudioFrame expected_audio_frame = expected_frame_.front(); | 289 // swizzle the bytes of each int16 from host-->network-->host order to get |
| 285 expected_frame_.pop_front(); | 290 // interleaved int16 PCM. Then, make an AudioBus out of that. |
| 291 const int num_elements = audio_frame->data.size() / sizeof(int16); |
| 292 ASSERT_EQ(expected_audio_frame.audio_bus->channels() * |
| 293 expected_audio_frame.audio_bus->frames(), |
| 294 num_elements); |
| 295 int16* const pcm_data = |
| 296 reinterpret_cast<int16*>(string_as_array(&audio_frame->data)); |
| 297 for (int i = 0; i < num_elements; ++i) |
| 298 pcm_data[i] = static_cast<int16>(base::NetToHost16(pcm_data[i])); |
| 299 scoped_ptr<AudioBus> audio_bus( |
| 300 AudioBus::Create(expected_audio_frame.audio_bus->channels(), |
| 301 expected_audio_frame.audio_bus->frames())); |
| 302 audio_bus->FromInterleaved(pcm_data, audio_bus->frames(), sizeof(int16)); |
| 286 | 303 |
| 287 EXPECT_EQ(static_cast<int>(audio_frame->data.size()), | 304 // Delegate the checking from here... |
| 288 2 * kAudioChannels * expected_sampling_frequency_ / 100); | 305 CheckAudioFrame(audio_bus.Pass(), playout_time, true); |
| 289 | |
| 290 base::TimeDelta time_since_recording = | |
| 291 playout_time - expected_audio_frame.record_time; | |
| 292 | |
| 293 EXPECT_LE(time_since_recording, | |
| 294 base::TimeDelta::FromMilliseconds(kDefaultRtpMaxDelayMs + | |
| 295 kTimerErrorMs)); | |
| 296 | |
| 297 EXPECT_LT(expected_audio_frame.record_time, playout_time); | |
| 298 if (audio_frame->data.size() == 0) | |
| 299 return; // No more checks needed. | |
| 300 | |
| 301 // We need to convert our "coded" audio frame to our raw format. | |
| 302 std::vector<int16> output_audio_samples; | |
| 303 size_t number_of_samples = audio_frame->data.size() / 2; | |
| 304 | |
| 305 for (size_t i = 0; i < number_of_samples; ++i) { | |
| 306 uint16 sample = | |
| 307 static_cast<uint8>(audio_frame->data[1 + i * sizeof(uint16)]) + | |
| 308 (static_cast<uint16>(audio_frame->data[i * sizeof(uint16)]) << 8); | |
| 309 output_audio_samples.push_back(static_cast<int16>(sample)); | |
| 310 } | |
| 311 | |
| 312 EXPECT_NEAR(CountZeroCrossings(expected_audio_frame.audio_frame.samples), | |
| 313 CountZeroCrossings(output_audio_samples), | |
| 314 1); | |
| 315 } | 306 } |
| 316 | 307 |
| 317 int number_times_called() const { return num_called_; } | 308 int number_times_called() const { return num_called_; } |
| 318 | 309 |
| 319 protected: | 310 protected: |
| 320 virtual ~TestReceiverAudioCallback() {} | 311 virtual ~TestReceiverAudioCallback() { |
| 312 STLDeleteElements(&expected_frames_); |
| 313 } |
| 321 | 314 |
| 322 private: | 315 private: |
| 323 friend class base::RefCountedThreadSafe<TestReceiverAudioCallback>; | 316 friend class base::RefCountedThreadSafe<TestReceiverAudioCallback>; |
| 324 | 317 |
| 325 int num_called_; | 318 int num_called_; |
| 326 int expected_sampling_frequency_; | 319 int expected_sampling_frequency_; |
| 327 std::list<ExpectedAudioFrame> expected_frame_; | 320 std::list<ExpectedAudioFrame*> expected_frames_; |
| 328 }; | 321 }; |
| 329 | 322 |
| 330 // Class that verifies the video frames coming out of the receiver. | 323 // Class that verifies the video frames coming out of the receiver. |
| 331 class TestReceiverVideoCallback | 324 class TestReceiverVideoCallback |
| 332 : public base::RefCountedThreadSafe<TestReceiverVideoCallback> { | 325 : public base::RefCountedThreadSafe<TestReceiverVideoCallback> { |
| 333 public: | 326 public: |
| 334 struct ExpectedVideoFrame { | 327 struct ExpectedVideoFrame { |
| 335 int start_value; | 328 int start_value; |
| 336 int width; | 329 int width; |
| 337 int height; | 330 int height; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 358 | 351 |
| 359 EXPECT_FALSE(expected_frame_.empty()); // Test for bug in test code. | 352 EXPECT_FALSE(expected_frame_.empty()); // Test for bug in test code. |
| 360 ExpectedVideoFrame expected_video_frame = expected_frame_.front(); | 353 ExpectedVideoFrame expected_video_frame = expected_frame_.front(); |
| 361 expected_frame_.pop_front(); | 354 expected_frame_.pop_front(); |
| 362 | 355 |
| 363 base::TimeDelta time_since_capture = | 356 base::TimeDelta time_since_capture = |
| 364 render_time - expected_video_frame.capture_time; | 357 render_time - expected_video_frame.capture_time; |
| 365 const base::TimeDelta upper_bound = base::TimeDelta::FromMilliseconds( | 358 const base::TimeDelta upper_bound = base::TimeDelta::FromMilliseconds( |
| 366 kDefaultRtpMaxDelayMs + kTimerErrorMs); | 359 kDefaultRtpMaxDelayMs + kTimerErrorMs); |
| 367 | 360 |
| 361 // TODO(miu): This is a "fuzzy" way to check the timestamps. We should be |
| 362 // able to compute exact offsets with "omnipotent" knowledge of the system. |
| 368 EXPECT_GE(upper_bound, time_since_capture) | 363 EXPECT_GE(upper_bound, time_since_capture) |
| 369 << "time_since_capture - upper_bound == " | 364 << "time_since_capture - upper_bound == " |
| 370 << (time_since_capture - upper_bound).InMilliseconds() << " mS"; | 365 << (time_since_capture - upper_bound).InMicroseconds() << " usec"; |
| 371 EXPECT_LE(expected_video_frame.capture_time, render_time); | 366 EXPECT_LE(expected_video_frame.capture_time, render_time); |
| 372 EXPECT_EQ(expected_video_frame.width, video_frame->visible_rect().width()); | 367 EXPECT_EQ(expected_video_frame.width, video_frame->visible_rect().width()); |
| 373 EXPECT_EQ(expected_video_frame.height, | 368 EXPECT_EQ(expected_video_frame.height, |
| 374 video_frame->visible_rect().height()); | 369 video_frame->visible_rect().height()); |
| 375 | 370 |
| 376 gfx::Size size(expected_video_frame.width, expected_video_frame.height); | 371 gfx::Size size(expected_video_frame.width, expected_video_frame.height); |
| 377 scoped_refptr<media::VideoFrame> expected_I420_frame = | 372 scoped_refptr<media::VideoFrame> expected_I420_frame = |
| 378 media::VideoFrame::CreateFrame( | 373 media::VideoFrame::CreateFrame( |
| 379 VideoFrame::I420, size, gfx::Rect(size), size, base::TimeDelta()); | 374 VideoFrame::I420, size, gfx::Rect(size), size, base::TimeDelta()); |
| 380 PopulateVideoFrame(expected_I420_frame, expected_video_frame.start_value); | 375 PopulateVideoFrame(expected_I420_frame, expected_video_frame.start_value); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 test_receiver_audio_callback_(new TestReceiverAudioCallback()), | 414 test_receiver_audio_callback_(new TestReceiverAudioCallback()), |
| 420 test_receiver_video_callback_(new TestReceiverVideoCallback()) { | 415 test_receiver_video_callback_(new TestReceiverVideoCallback()) { |
| 421 testing_clock_sender_->Advance( | 416 testing_clock_sender_->Advance( |
| 422 base::TimeDelta::FromMilliseconds(kStartMillisecond)); | 417 base::TimeDelta::FromMilliseconds(kStartMillisecond)); |
| 423 testing_clock_receiver_->Advance( | 418 testing_clock_receiver_->Advance( |
| 424 base::TimeDelta::FromMilliseconds(kStartMillisecond)); | 419 base::TimeDelta::FromMilliseconds(kStartMillisecond)); |
| 425 cast_environment_sender_->Logging()->AddRawEventSubscriber( | 420 cast_environment_sender_->Logging()->AddRawEventSubscriber( |
| 426 &event_subscriber_sender_); | 421 &event_subscriber_sender_); |
| 427 } | 422 } |
| 428 | 423 |
| 429 void SetupConfig(transport::AudioCodec audio_codec, | 424 void Configure(transport::AudioCodec audio_codec, |
| 430 int audio_sampling_frequency, | 425 int audio_sampling_frequency, |
| 431 // TODO(miu): 3rd arg is meaningless?!? | 426 bool external_audio_decoder, |
| 432 bool external_audio_decoder, | 427 int max_number_of_video_buffers_used) { |
| 433 int max_number_of_video_buffers_used) { | |
| 434 audio_sender_config_.sender_ssrc = 1; | 428 audio_sender_config_.sender_ssrc = 1; |
| 435 audio_sender_config_.incoming_feedback_ssrc = 2; | 429 audio_sender_config_.incoming_feedback_ssrc = 2; |
| 436 audio_sender_config_.rtp_config.payload_type = 96; | 430 audio_sender_config_.rtp_config.payload_type = 96; |
| 437 audio_sender_config_.use_external_encoder = false; | 431 audio_sender_config_.use_external_encoder = false; |
| 438 audio_sender_config_.frequency = audio_sampling_frequency; | 432 audio_sender_config_.frequency = audio_sampling_frequency; |
| 439 audio_sender_config_.channels = kAudioChannels; | 433 audio_sender_config_.channels = kAudioChannels; |
| 440 audio_sender_config_.bitrate = kDefaultAudioEncoderBitrate; | 434 audio_sender_config_.bitrate = kDefaultAudioEncoderBitrate; |
| 441 audio_sender_config_.codec = audio_codec; | 435 audio_sender_config_.codec = audio_codec; |
| 442 | 436 |
| 443 audio_receiver_config_.feedback_ssrc = | 437 audio_receiver_config_.feedback_ssrc = |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 transport_audio_config_.base.ssrc = audio_sender_config_.sender_ssrc; | 475 transport_audio_config_.base.ssrc = audio_sender_config_.sender_ssrc; |
| 482 transport_audio_config_.codec = audio_sender_config_.codec; | 476 transport_audio_config_.codec = audio_sender_config_.codec; |
| 483 transport_audio_config_.base.rtp_config = audio_sender_config_.rtp_config; | 477 transport_audio_config_.base.rtp_config = audio_sender_config_.rtp_config; |
| 484 transport_audio_config_.frequency = audio_sender_config_.frequency; | 478 transport_audio_config_.frequency = audio_sender_config_.frequency; |
| 485 transport_audio_config_.channels = audio_sender_config_.channels; | 479 transport_audio_config_.channels = audio_sender_config_.channels; |
| 486 transport_video_config_.base.ssrc = video_sender_config_.sender_ssrc; | 480 transport_video_config_.base.ssrc = video_sender_config_.sender_ssrc; |
| 487 transport_video_config_.codec = video_sender_config_.codec; | 481 transport_video_config_.codec = video_sender_config_.codec; |
| 488 transport_video_config_.base.rtp_config = video_sender_config_.rtp_config; | 482 transport_video_config_.base.rtp_config = video_sender_config_.rtp_config; |
| 489 } | 483 } |
| 490 | 484 |
| 485 void FeedAudioFrames(int count, bool will_be_checked) { |
| 486 for (int i = 0; i < count; ++i) { |
| 487 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( |
| 488 base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs))); |
| 489 const base::TimeTicks send_time = |
| 490 testing_clock_sender_->NowTicks() + |
| 491 i * base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs); |
| 492 if (will_be_checked) |
| 493 test_receiver_audio_callback_->AddExpectedResult(*audio_bus, send_time); |
| 494 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); |
| 495 } |
| 496 } |
| 497 |
| 498 void FeedAudioFramesWithExpectedDelay(int count, |
| 499 const base::TimeDelta& delay) { |
| 500 for (int i = 0; i < count; ++i) { |
| 501 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( |
| 502 base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs))); |
| 503 const base::TimeTicks send_time = |
| 504 testing_clock_sender_->NowTicks() + |
| 505 i * base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs); |
| 506 test_receiver_audio_callback_->AddExpectedResult(*audio_bus, |
| 507 send_time + delay); |
| 508 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); |
| 509 } |
| 510 } |
| 511 |
| 512 void RequestAudioFrames(int count, bool with_check) { |
| 513 for (int i = 0; i < count; ++i) { |
| 514 frame_receiver_->GetRawAudioFrame( |
| 515 base::Bind(with_check ? &TestReceiverAudioCallback::CheckAudioFrame : |
| 516 &TestReceiverAudioCallback::IgnoreAudioFrame, |
| 517 test_receiver_audio_callback_)); |
| 518 } |
| 519 } |
| 520 |
| 491 void Create() { | 521 void Create() { |
| 492 cast_receiver_ = CastReceiver::Create(cast_environment_receiver_, | 522 cast_receiver_ = CastReceiver::Create(cast_environment_receiver_, |
| 493 audio_receiver_config_, | 523 audio_receiver_config_, |
| 494 video_receiver_config_, | 524 video_receiver_config_, |
| 495 &receiver_to_sender_); | 525 &receiver_to_sender_); |
| 496 net::IPEndPoint dummy_endpoint; | 526 net::IPEndPoint dummy_endpoint; |
| 497 transport_sender_.reset(new transport::CastTransportSenderImpl( | 527 transport_sender_.reset(new transport::CastTransportSenderImpl( |
| 498 NULL, | 528 NULL, |
| 499 testing_clock_sender_, | 529 testing_clock_sender_, |
| 500 dummy_endpoint, | 530 dummy_endpoint, |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 | 643 |
| 614 SimpleEventSubscriber event_subscriber_sender_; | 644 SimpleEventSubscriber event_subscriber_sender_; |
| 615 std::vector<FrameEvent> frame_events_; | 645 std::vector<FrameEvent> frame_events_; |
| 616 std::vector<PacketEvent> packet_events_; | 646 std::vector<PacketEvent> packet_events_; |
| 617 std::vector<GenericEvent> generic_events_; | 647 std::vector<GenericEvent> generic_events_; |
| 618 // |transport_sender_| has a RepeatingTimer which needs a MessageLoop. | 648 // |transport_sender_| has a RepeatingTimer which needs a MessageLoop. |
| 619 base::MessageLoop message_loop_; | 649 base::MessageLoop message_loop_; |
| 620 }; | 650 }; |
| 621 | 651 |
| 622 TEST_F(End2EndTest, LoopNoLossPcm16) { | 652 TEST_F(End2EndTest, LoopNoLossPcm16) { |
| 623 SetupConfig(transport::kPcm16, 32000, false, 1); | 653 Configure(transport::kPcm16, 32000, false, 1); |
| 624 // Reduce video resolution to allow processing multiple frames within a | 654 // Reduce video resolution to allow processing multiple frames within a |
| 625 // reasonable time frame. | 655 // reasonable time frame. |
| 626 video_sender_config_.width = kVideoQcifWidth; | 656 video_sender_config_.width = kVideoQcifWidth; |
| 627 video_sender_config_.height = kVideoQcifHeight; | 657 video_sender_config_.height = kVideoQcifHeight; |
| 628 Create(); | 658 Create(); |
| 629 | 659 |
| 660 const int kNumIterations = 50; |
| 630 int video_start = kVideoStart; | 661 int video_start = kVideoStart; |
| 631 int audio_diff = kFrameTimerMs; | 662 int audio_diff = kFrameTimerMs; |
| 632 int i = 0; | 663 int num_audio_frames_requested = 0; |
| 664 for (int i = 0; i < kNumIterations; ++i) { |
| 665 const int num_audio_frames = audio_diff / kAudioFrameDurationMs; |
| 666 audio_diff -= num_audio_frames * kAudioFrameDurationMs; |
| 633 | 667 |
| 634 for (; i < 300; ++i) { | 668 if (num_audio_frames > 0) |
| 635 int num_10ms_blocks = audio_diff / 10; | 669 FeedAudioFrames(1, true); |
| 636 audio_diff -= num_10ms_blocks * 10; | |
| 637 | |
| 638 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | |
| 639 base::TimeDelta::FromMilliseconds(10) * num_10ms_blocks)); | |
| 640 | |
| 641 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | |
| 642 if (i != 0) { | |
| 643 // Due to the re-sampler and NetEq in the webrtc AudioCodingModule the | |
| 644 // first samples will be 0 and then slowly ramp up to its real | |
| 645 // amplitude; | |
| 646 // ignore the first frame. | |
| 647 test_receiver_audio_callback_->AddExpectedResult( | |
| 648 ToPcmAudioFrame(*audio_bus, audio_sender_config_.frequency), | |
| 649 num_10ms_blocks, | |
| 650 send_time); | |
| 651 } | |
| 652 | |
| 653 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); | |
| 654 | 670 |
| 655 test_receiver_video_callback_->AddExpectedResult( | 671 test_receiver_video_callback_->AddExpectedResult( |
| 656 video_start, | 672 video_start, |
| 657 video_sender_config_.width, | 673 video_sender_config_.width, |
| 658 video_sender_config_.height, | 674 video_sender_config_.height, |
| 659 send_time); | 675 testing_clock_sender_->NowTicks()); |
| 660 SendVideoFrame(video_start, send_time); | 676 SendVideoFrame(video_start, testing_clock_sender_->NowTicks()); |
| 661 | 677 |
| 662 if (i == 0) { | 678 if (num_audio_frames > 0) |
| 663 frame_receiver_->GetRawAudioFrame( | 679 RunTasks(kAudioFrameDurationMs); // Advance clock forward. |
| 664 num_10ms_blocks, | 680 if (num_audio_frames > 1) |
| 665 audio_sender_config_.frequency, | 681 FeedAudioFrames(num_audio_frames - 1, true); |
| 666 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame, | 682 |
| 667 test_receiver_audio_callback_)); | 683 RequestAudioFrames(num_audio_frames, true); |
| 668 } else { | 684 num_audio_frames_requested += num_audio_frames; |
| 669 frame_receiver_->GetRawAudioFrame( | |
| 670 num_10ms_blocks, | |
| 671 audio_sender_config_.frequency, | |
| 672 base::Bind(&TestReceiverAudioCallback::CheckPcmAudioFrame, | |
| 673 test_receiver_audio_callback_)); | |
| 674 } | |
| 675 | 685 |
| 676 frame_receiver_->GetRawVideoFrame( | 686 frame_receiver_->GetRawVideoFrame( |
| 677 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 687 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
| 678 test_receiver_video_callback_)); | 688 test_receiver_video_callback_)); |
| 679 | 689 |
| 680 RunTasks(kFrameTimerMs); | 690 RunTasks(kFrameTimerMs - kAudioFrameDurationMs); |
| 681 audio_diff += kFrameTimerMs; | 691 audio_diff += kFrameTimerMs; |
| 682 video_start++; | 692 video_start++; |
| 683 } | 693 } |
| 684 | 694 |
| 685 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. | 695 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. |
| 686 EXPECT_EQ(i - 1, test_receiver_audio_callback_->number_times_called()); | 696 EXPECT_EQ(num_audio_frames_requested, |
| 687 EXPECT_EQ(i, test_receiver_video_callback_->number_times_called()); | 697 test_receiver_audio_callback_->number_times_called()); |
| 698 EXPECT_EQ(kNumIterations, |
| 699 test_receiver_video_callback_->number_times_called()); |
| 688 } | 700 } |
| 689 | 701 |
| 690 // This tests our external decoder interface for Audio. | 702 // This tests our external decoder interface for Audio. |
| 691 // Audio test without packet loss using raw PCM 16 audio "codec"; | 703 // Audio test without packet loss using raw PCM 16 audio "codec"; |
| 692 TEST_F(End2EndTest, LoopNoLossPcm16ExternalDecoder) { | 704 TEST_F(End2EndTest, LoopNoLossPcm16ExternalDecoder) { |
| 693 SetupConfig(transport::kPcm16, 32000, true, 1); | 705 Configure(transport::kPcm16, 32000, true, 1); |
| 694 Create(); | 706 Create(); |
| 695 | 707 |
| 696 int i = 0; | 708 const int kNumIterations = 10; |
| 697 for (; i < 10; ++i) { | 709 for (int i = 0; i < kNumIterations; ++i) { |
| 698 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | 710 FeedAudioFrames(1, true); |
| 699 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | 711 RunTasks(kAudioFrameDurationMs); |
| 700 base::TimeDelta::FromMilliseconds(10))); | |
| 701 test_receiver_audio_callback_->AddExpectedResult( | |
| 702 ToPcmAudioFrame(*audio_bus, audio_sender_config_.frequency), | |
| 703 1, | |
| 704 send_time); | |
| 705 | |
| 706 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); | |
| 707 | |
| 708 RunTasks(10); | |
| 709 frame_receiver_->GetCodedAudioFrame( | 712 frame_receiver_->GetCodedAudioFrame( |
| 710 base::Bind(&TestReceiverAudioCallback::CheckCodedPcmAudioFrame, | 713 base::Bind(&TestReceiverAudioCallback::CheckCodedAudioFrame, |
| 711 test_receiver_audio_callback_)); | 714 test_receiver_audio_callback_)); |
| 712 } | 715 } |
| 713 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. | 716 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. |
| 714 EXPECT_EQ(10, test_receiver_audio_callback_->number_times_called()); | 717 EXPECT_EQ(kNumIterations, |
| 718 test_receiver_audio_callback_->number_times_called()); |
| 715 } | 719 } |
| 716 | 720 |
| 717 // This tests our Opus audio codec without video. | 721 // This tests our Opus audio codec without video. |
| 718 TEST_F(End2EndTest, LoopNoLossOpus) { | 722 TEST_F(End2EndTest, LoopNoLossOpus) { |
| 719 SetupConfig(transport::kOpus, kDefaultAudioSamplingRate, false, 1); | 723 Configure(transport::kOpus, kDefaultAudioSamplingRate, false, 1); |
| 720 Create(); | 724 Create(); |
| 721 | 725 |
| 722 int i = 0; | 726 const int kNumIterations = 300; |
| 723 for (; i < 10; ++i) { | 727 for (int i = 0; i < kNumIterations; ++i) { |
| 724 int num_10ms_blocks = 3; | 728 // Opus introduces a tiny delay before the sinewave starts; so don't examine |
| 725 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | 729 // the first frame. |
| 726 | 730 const bool examine_audio_data = i > 0; |
| 727 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | 731 FeedAudioFrames(1, examine_audio_data); |
| 728 base::TimeDelta::FromMilliseconds(10) * num_10ms_blocks)); | 732 RunTasks(kAudioFrameDurationMs); |
| 729 | 733 RequestAudioFrames(1, examine_audio_data); |
| 730 if (i != 0) { | |
| 731 test_receiver_audio_callback_->AddExpectedResult( | |
| 732 ToPcmAudioFrame(*audio_bus, audio_sender_config_.frequency), | |
| 733 num_10ms_blocks, | |
| 734 send_time); | |
| 735 } | |
| 736 | |
| 737 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); | |
| 738 | |
| 739 RunTasks(30); | |
| 740 | |
| 741 if (i == 0) { | |
| 742 frame_receiver_->GetRawAudioFrame( | |
| 743 num_10ms_blocks, | |
| 744 audio_sender_config_.frequency, | |
| 745 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame, | |
| 746 test_receiver_audio_callback_)); | |
| 747 } else { | |
| 748 frame_receiver_->GetRawAudioFrame( | |
| 749 num_10ms_blocks, | |
| 750 audio_sender_config_.frequency, | |
| 751 base::Bind(&TestReceiverAudioCallback::CheckPcmAudioFrame, | |
| 752 test_receiver_audio_callback_)); | |
| 753 } | |
| 754 } | 734 } |
| 755 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. | 735 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. |
| 756 EXPECT_EQ(i - 1, test_receiver_audio_callback_->number_times_called()); | 736 EXPECT_EQ(kNumIterations, |
| 737 test_receiver_audio_callback_->number_times_called()); |
| 757 } | 738 } |
| 758 | 739 |
| 759 // This tests start sending audio and video at start-up time before the receiver | 740 // This tests start sending audio and video at start-up time before the receiver |
| 760 // is ready; it sends 2 frames before the receiver comes online. | 741 // is ready; it sends 2 frames before the receiver comes online. |
| 761 TEST_F(End2EndTest, StartSenderBeforeReceiver) { | 742 // |
| 762 SetupConfig(transport::kOpus, kDefaultAudioSamplingRate, false, 1); | 743 // Test disabled due to flakiness: It appears that the RTCP synchronization |
| 744 // sometimes kicks in, and sometimes doesn't. When it does, there's a sharp |
| 745 // discontinuity in the timeline, throwing off the test expectations. See TODOs |
| 746 // in audio_receiver.cc for likely cause(s) of this bug. |
| 747 // http://crbug.com/356942 |
| 748 TEST_F(End2EndTest, DISABLED_StartSenderBeforeReceiver) { |
| 749 Configure(transport::kPcm16, kDefaultAudioSamplingRate, false, 1); |
| 763 Create(); | 750 Create(); |
| 764 | 751 |
| 765 int video_start = kVideoStart; | 752 int video_start = kVideoStart; |
| 766 int audio_diff = kFrameTimerMs; | 753 int audio_diff = kFrameTimerMs; |
| 767 | 754 |
| 768 sender_to_receiver_.SetSendPackets(false); | 755 sender_to_receiver_.SetSendPackets(false); |
| 769 | 756 |
| 770 const int test_delay_ms = 100; | 757 const int test_delay_ms = 100; |
| 771 | 758 |
| 772 base::TimeTicks initial_send_time; | 759 const int kNumVideoFramesBeforeReceiverStarted = 2; |
| 773 for (int i = 0; i < 2; ++i) { | 760 const base::TimeTicks initial_send_time = testing_clock_sender_->NowTicks(); |
| 774 int num_10ms_blocks = audio_diff / 10; | 761 const base::TimeDelta expected_delay = |
| 775 audio_diff -= num_10ms_blocks * 10; | 762 base::TimeDelta::FromMilliseconds(test_delay_ms + kFrameTimerMs); |
| 763 for (int i = 0; i < kNumVideoFramesBeforeReceiverStarted; ++i) { |
| 764 const int num_audio_frames = audio_diff / kAudioFrameDurationMs; |
| 765 audio_diff -= num_audio_frames * kAudioFrameDurationMs; |
| 776 | 766 |
| 777 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | 767 if (num_audio_frames > 0) |
| 778 if (initial_send_time.is_null()) | 768 FeedAudioFramesWithExpectedDelay(1, expected_delay); |
| 779 initial_send_time = send_time; | |
| 780 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | |
| 781 base::TimeDelta::FromMilliseconds(10) * num_10ms_blocks)); | |
| 782 | |
| 783 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); | |
| 784 | 769 |
| 785 // Frame will be rendered with 100mS delay, as the transmission is delayed. | 770 // Frame will be rendered with 100mS delay, as the transmission is delayed. |
| 786 // The receiver at this point cannot be synced to the sender's clock, as no | 771 // The receiver at this point cannot be synced to the sender's clock, as no |
| 787 // packets, and specifically no RTCP packets were sent. | 772 // packets, and specifically no RTCP packets were sent. |
| 788 test_receiver_video_callback_->AddExpectedResult( | 773 test_receiver_video_callback_->AddExpectedResult( |
| 789 video_start, | 774 video_start, |
| 790 video_sender_config_.width, | 775 video_sender_config_.width, |
| 791 video_sender_config_.height, | 776 video_sender_config_.height, |
| 792 initial_send_time + | 777 initial_send_time + expected_delay); |
| 793 base::TimeDelta::FromMilliseconds(test_delay_ms + kFrameTimerMs)); | 778 SendVideoFrame(video_start, testing_clock_sender_->NowTicks()); |
| 794 | 779 |
| 795 SendVideoFrame(video_start, send_time); | 780 if (num_audio_frames > 0) |
| 796 RunTasks(kFrameTimerMs); | 781 RunTasks(kAudioFrameDurationMs); // Advance clock forward. |
| 782 if (num_audio_frames > 1) |
| 783 FeedAudioFramesWithExpectedDelay(num_audio_frames - 1, expected_delay); |
| 784 |
| 785 RunTasks(kFrameTimerMs - kAudioFrameDurationMs); |
| 797 audio_diff += kFrameTimerMs; | 786 audio_diff += kFrameTimerMs; |
| 798 video_start++; | 787 video_start++; |
| 799 } | 788 } |
| 800 | 789 |
| 801 RunTasks(test_delay_ms); | 790 RunTasks(test_delay_ms); |
| 802 sender_to_receiver_.SetSendPackets(true); | 791 sender_to_receiver_.SetSendPackets(true); |
| 803 | 792 |
| 804 int j = 0; | 793 int num_audio_frames_requested = 0; |
| 805 const int number_of_audio_frames_to_ignore = 2; | 794 for (int j = 0; j < 10; ++j) { |
| 806 for (; j < 10; ++j) { | 795 const int num_audio_frames = audio_diff / kAudioFrameDurationMs; |
| 807 int num_10ms_blocks = audio_diff / 10; | 796 audio_diff -= num_audio_frames * kAudioFrameDurationMs; |
| 808 audio_diff -= num_10ms_blocks * 10; | |
| 809 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | |
| 810 | 797 |
| 811 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | 798 if (num_audio_frames > 0) |
| 812 base::TimeDelta::FromMilliseconds(10) * num_10ms_blocks)); | 799 FeedAudioFrames(1, true); |
| 813 | |
| 814 if (j >= number_of_audio_frames_to_ignore) { | |
| 815 test_receiver_audio_callback_->AddExpectedResult( | |
| 816 ToPcmAudioFrame(*audio_bus, audio_sender_config_.frequency), | |
| 817 num_10ms_blocks, | |
| 818 send_time); | |
| 819 } | |
| 820 | |
| 821 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); | |
| 822 | 800 |
| 823 test_receiver_video_callback_->AddExpectedResult( | 801 test_receiver_video_callback_->AddExpectedResult( |
| 824 video_start, | 802 video_start, |
| 825 video_sender_config_.width, | 803 video_sender_config_.width, |
| 826 video_sender_config_.height, | 804 video_sender_config_.height, |
| 827 send_time); | 805 testing_clock_sender_->NowTicks()); |
| 806 SendVideoFrame(video_start, testing_clock_sender_->NowTicks()); |
| 828 | 807 |
| 829 SendVideoFrame(video_start, send_time); | 808 if (num_audio_frames > 0) |
| 830 RunTasks(kFrameTimerMs); | 809 RunTasks(kAudioFrameDurationMs); // Advance clock forward. |
| 831 audio_diff += kFrameTimerMs; | 810 if (num_audio_frames > 1) |
| 811 FeedAudioFrames(num_audio_frames - 1, true); |
| 832 | 812 |
| 833 if (j < number_of_audio_frames_to_ignore) { | 813 RequestAudioFrames(num_audio_frames, true); |
| 834 frame_receiver_->GetRawAudioFrame( | 814 num_audio_frames_requested += num_audio_frames; |
| 835 num_10ms_blocks, | 815 |
| 836 audio_sender_config_.frequency, | |
| 837 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame, | |
| 838 test_receiver_audio_callback_)); | |
| 839 } else { | |
| 840 frame_receiver_->GetRawAudioFrame( | |
| 841 num_10ms_blocks, | |
| 842 audio_sender_config_.frequency, | |
| 843 base::Bind(&TestReceiverAudioCallback::CheckPcmAudioFrame, | |
| 844 test_receiver_audio_callback_)); | |
| 845 } | |
| 846 frame_receiver_->GetRawVideoFrame( | 816 frame_receiver_->GetRawVideoFrame( |
| 847 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 817 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
| 848 test_receiver_video_callback_)); | 818 test_receiver_video_callback_)); |
| 819 |
| 820 RunTasks(kFrameTimerMs - kAudioFrameDurationMs); |
| 821 audio_diff += kFrameTimerMs; |
| 849 video_start++; | 822 video_start++; |
| 850 } | 823 } |
| 851 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. | 824 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. |
| 852 EXPECT_EQ(j - number_of_audio_frames_to_ignore, | 825 EXPECT_EQ(num_audio_frames_requested, |
| 853 test_receiver_audio_callback_->number_times_called()); | 826 test_receiver_audio_callback_->number_times_called()); |
| 854 EXPECT_EQ(j, test_receiver_video_callback_->number_times_called()); | 827 EXPECT_EQ(10, test_receiver_video_callback_->number_times_called()); |
| 855 } | 828 } |
| 856 | 829 |
| 857 // This tests a network glitch lasting for 10 video frames. | 830 // This tests a network glitch lasting for 10 video frames. |
| 858 // Flaky. See crbug.com/351596. | 831 // Flaky. See crbug.com/351596. |
| 859 TEST_F(End2EndTest, DISABLED_GlitchWith3Buffers) { | 832 TEST_F(End2EndTest, DISABLED_GlitchWith3Buffers) { |
| 860 SetupConfig(transport::kOpus, kDefaultAudioSamplingRate, false, 3); | 833 Configure(transport::kOpus, kDefaultAudioSamplingRate, false, 3); |
| 861 video_sender_config_.rtp_config.max_delay_ms = 67; | 834 video_sender_config_.rtp_config.max_delay_ms = 67; |
| 862 video_receiver_config_.rtp_max_delay_ms = 67; | 835 video_receiver_config_.rtp_max_delay_ms = 67; |
| 863 Create(); | 836 Create(); |
| 864 | 837 |
| 865 int video_start = kVideoStart; | 838 int video_start = kVideoStart; |
| 866 base::TimeTicks send_time; | 839 base::TimeTicks send_time; |
| 867 // Frames will rendered on completion until the render time stabilizes, i.e. | 840 // Frames will rendered on completion until the render time stabilizes, i.e. |
| 868 // we got enough data. | 841 // we got enough data. |
| 869 const int frames_before_glitch = 20; | 842 const int frames_before_glitch = 20; |
| 870 for (int i = 0; i < frames_before_glitch; ++i) { | 843 for (int i = 0; i < frames_before_glitch; ++i) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 909 frame_receiver_->GetRawVideoFrame( | 882 frame_receiver_->GetRawVideoFrame( |
| 910 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 883 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
| 911 test_receiver_video_callback_)); | 884 test_receiver_video_callback_)); |
| 912 | 885 |
| 913 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. | 886 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. |
| 914 EXPECT_EQ(frames_before_glitch + 1, | 887 EXPECT_EQ(frames_before_glitch + 1, |
| 915 test_receiver_video_callback_->number_times_called()); | 888 test_receiver_video_callback_->number_times_called()); |
| 916 } | 889 } |
| 917 | 890 |
| 918 TEST_F(End2EndTest, DropEveryOtherFrame3Buffers) { | 891 TEST_F(End2EndTest, DropEveryOtherFrame3Buffers) { |
| 919 SetupConfig(transport::kOpus, kDefaultAudioSamplingRate, false, 3); | 892 Configure(transport::kOpus, kDefaultAudioSamplingRate, false, 3); |
| 920 video_sender_config_.rtp_config.max_delay_ms = 67; | 893 video_sender_config_.rtp_config.max_delay_ms = 67; |
| 921 video_receiver_config_.rtp_max_delay_ms = 67; | 894 video_receiver_config_.rtp_max_delay_ms = 67; |
| 922 Create(); | 895 Create(); |
| 923 sender_to_receiver_.DropAllPacketsBelongingToOddFrames(); | 896 sender_to_receiver_.DropAllPacketsBelongingToOddFrames(); |
| 924 | 897 |
| 925 int video_start = kVideoStart; | 898 int video_start = kVideoStart; |
| 926 base::TimeTicks send_time; | 899 base::TimeTicks send_time; |
| 927 | 900 |
| 928 int i = 0; | 901 int i = 0; |
| 929 for (; i < 20; ++i) { | 902 for (; i < 20; ++i) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 945 } | 918 } |
| 946 RunTasks(kFrameTimerMs); | 919 RunTasks(kFrameTimerMs); |
| 947 video_start++; | 920 video_start++; |
| 948 } | 921 } |
| 949 | 922 |
| 950 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | 923 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. |
| 951 EXPECT_EQ(i / 2, test_receiver_video_callback_->number_times_called()); | 924 EXPECT_EQ(i / 2, test_receiver_video_callback_->number_times_called()); |
| 952 } | 925 } |
| 953 | 926 |
| 954 TEST_F(End2EndTest, ResetReferenceFrameId) { | 927 TEST_F(End2EndTest, ResetReferenceFrameId) { |
| 955 SetupConfig(transport::kOpus, kDefaultAudioSamplingRate, false, 3); | 928 Configure(transport::kOpus, kDefaultAudioSamplingRate, false, 3); |
| 956 video_sender_config_.rtp_config.max_delay_ms = 67; | 929 video_sender_config_.rtp_config.max_delay_ms = 67; |
| 957 video_receiver_config_.rtp_max_delay_ms = 67; | 930 video_receiver_config_.rtp_max_delay_ms = 67; |
| 958 Create(); | 931 Create(); |
| 959 sender_to_receiver_.AlwaysResetReferenceFrameId(); | 932 sender_to_receiver_.AlwaysResetReferenceFrameId(); |
| 960 | 933 |
| 961 int frames_counter = 0; | 934 int frames_counter = 0; |
| 962 for (; frames_counter < 10; ++frames_counter) { | 935 for (; frames_counter < 10; ++frames_counter) { |
| 963 const base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | 936 const base::TimeTicks send_time = testing_clock_sender_->NowTicks(); |
| 964 SendVideoFrame(frames_counter, send_time); | 937 SendVideoFrame(frames_counter, send_time); |
| 965 | 938 |
| 966 test_receiver_video_callback_->AddExpectedResult( | 939 test_receiver_video_callback_->AddExpectedResult( |
| 967 frames_counter, | 940 frames_counter, |
| 968 video_sender_config_.width, | 941 video_sender_config_.width, |
| 969 video_sender_config_.height, | 942 video_sender_config_.height, |
| 970 send_time); | 943 send_time); |
| 971 | 944 |
| 972 // GetRawVideoFrame will not return the frame until we are close to the | 945 // GetRawVideoFrame will not return the frame until we are close to the |
| 973 // time in which we should render the frame. | 946 // time in which we should render the frame. |
| 974 frame_receiver_->GetRawVideoFrame( | 947 frame_receiver_->GetRawVideoFrame( |
| 975 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 948 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
| 976 test_receiver_video_callback_)); | 949 test_receiver_video_callback_)); |
| 977 RunTasks(kFrameTimerMs); | 950 RunTasks(kFrameTimerMs); |
| 978 } | 951 } |
| 979 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | 952 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. |
| 980 EXPECT_EQ(frames_counter, | 953 EXPECT_EQ(frames_counter, |
| 981 test_receiver_video_callback_->number_times_called()); | 954 test_receiver_video_callback_->number_times_called()); |
| 982 } | 955 } |
| 983 | 956 |
| 984 TEST_F(End2EndTest, CryptoVideo) { | 957 TEST_F(End2EndTest, CryptoVideo) { |
| 985 SetupConfig(transport::kPcm16, 32000, false, 1); | 958 Configure(transport::kPcm16, 32000, false, 1); |
| 986 | 959 |
| 987 transport_video_config_.base.aes_iv_mask = | 960 transport_video_config_.base.aes_iv_mask = |
| 988 ConvertFromBase16String("1234567890abcdeffedcba0987654321"); | 961 ConvertFromBase16String("1234567890abcdeffedcba0987654321"); |
| 989 transport_video_config_.base.aes_key = | 962 transport_video_config_.base.aes_key = |
| 990 ConvertFromBase16String("deadbeefcafeb0b0b0b0cafedeadbeef"); | 963 ConvertFromBase16String("deadbeefcafeb0b0b0b0cafedeadbeef"); |
| 991 | 964 |
| 992 video_receiver_config_.aes_iv_mask = transport_video_config_.base.aes_iv_mask; | 965 video_receiver_config_.aes_iv_mask = transport_video_config_.base.aes_iv_mask; |
| 993 video_receiver_config_.aes_key = transport_video_config_.base.aes_key; | 966 video_receiver_config_.aes_key = transport_video_config_.base.aes_key; |
| 994 | 967 |
| 995 Create(); | 968 Create(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1012 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 985 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
| 1013 test_receiver_video_callback_)); | 986 test_receiver_video_callback_)); |
| 1014 RunTasks(kFrameTimerMs); | 987 RunTasks(kFrameTimerMs); |
| 1015 } | 988 } |
| 1016 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | 989 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. |
| 1017 EXPECT_EQ(frames_counter, | 990 EXPECT_EQ(frames_counter, |
| 1018 test_receiver_video_callback_->number_times_called()); | 991 test_receiver_video_callback_->number_times_called()); |
| 1019 } | 992 } |
| 1020 | 993 |
| 1021 TEST_F(End2EndTest, CryptoAudio) { | 994 TEST_F(End2EndTest, CryptoAudio) { |
| 1022 SetupConfig(transport::kPcm16, 32000, false, 1); | 995 Configure(transport::kPcm16, 32000, false, 1); |
| 1023 | 996 |
| 1024 transport_audio_config_.base.aes_iv_mask = | 997 transport_audio_config_.base.aes_iv_mask = |
| 1025 ConvertFromBase16String("abcdeffedcba12345678900987654321"); | 998 ConvertFromBase16String("abcdeffedcba12345678900987654321"); |
| 1026 transport_audio_config_.base.aes_key = | 999 transport_audio_config_.base.aes_key = |
| 1027 ConvertFromBase16String("deadbeefcafecafedeadbeefb0b0b0b0"); | 1000 ConvertFromBase16String("deadbeefcafecafedeadbeefb0b0b0b0"); |
| 1028 | 1001 |
| 1029 audio_receiver_config_.aes_iv_mask = transport_audio_config_.base.aes_iv_mask; | 1002 audio_receiver_config_.aes_iv_mask = transport_audio_config_.base.aes_iv_mask; |
| 1030 audio_receiver_config_.aes_key = transport_audio_config_.base.aes_key; | 1003 audio_receiver_config_.aes_key = transport_audio_config_.base.aes_key; |
| 1031 | 1004 |
| 1032 Create(); | 1005 Create(); |
| 1033 | 1006 |
| 1034 int frames_counter = 0; | 1007 const int kNumIterations = 3; |
| 1035 for (; frames_counter < 3; ++frames_counter) { | 1008 const int kNumAudioFramesPerIteration = 2; |
| 1036 int num_10ms_blocks = 2; | 1009 for (int i = 0; i < kNumIterations; ++i) { |
| 1037 | 1010 FeedAudioFrames(kNumAudioFramesPerIteration, true); |
| 1038 const base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | 1011 RunTasks(kNumAudioFramesPerIteration * kAudioFrameDurationMs); |
| 1039 | 1012 RequestAudioFrames(kNumAudioFramesPerIteration, true); |
| 1040 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | |
| 1041 base::TimeDelta::FromMilliseconds(10) * num_10ms_blocks)); | |
| 1042 | |
| 1043 if (frames_counter != 0) { | |
| 1044 // Due to the re-sampler and NetEq in the webrtc AudioCodingModule the | |
| 1045 // first samples will be 0 and then slowly ramp up to its real | |
| 1046 // amplitude; | |
| 1047 // ignore the first frame. | |
| 1048 test_receiver_audio_callback_->AddExpectedResult( | |
| 1049 ToPcmAudioFrame(*audio_bus, audio_sender_config_.frequency), | |
| 1050 num_10ms_blocks, | |
| 1051 send_time); | |
| 1052 } | |
| 1053 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); | |
| 1054 | |
| 1055 RunTasks(num_10ms_blocks * 10); | |
| 1056 | |
| 1057 if (frames_counter == 0) { | |
| 1058 frame_receiver_->GetRawAudioFrame( | |
| 1059 num_10ms_blocks, | |
| 1060 32000, | |
| 1061 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame, | |
| 1062 test_receiver_audio_callback_)); | |
| 1063 } else { | |
| 1064 frame_receiver_->GetRawAudioFrame( | |
| 1065 num_10ms_blocks, | |
| 1066 32000, | |
| 1067 base::Bind(&TestReceiverAudioCallback::CheckPcmAudioFrame, | |
| 1068 test_receiver_audio_callback_)); | |
| 1069 } | |
| 1070 } | 1013 } |
| 1071 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | 1014 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. |
| 1072 EXPECT_EQ(frames_counter - 1, | 1015 EXPECT_EQ(kNumIterations * kNumAudioFramesPerIteration, |
| 1073 test_receiver_audio_callback_->number_times_called()); | 1016 test_receiver_audio_callback_->number_times_called()); |
| 1074 } | 1017 } |
| 1075 | 1018 |
| 1076 // Video test without packet loss - tests the logging aspects of the end2end, | 1019 // Video test without packet loss - tests the logging aspects of the end2end, |
| 1077 // but is basically equivalent to LoopNoLossPcm16. | 1020 // but is basically equivalent to LoopNoLossPcm16. |
| 1078 TEST_F(End2EndTest, VideoLogging) { | 1021 TEST_F(End2EndTest, VideoLogging) { |
| 1079 SetupConfig(transport::kPcm16, 32000, false, 1); | 1022 Configure(transport::kPcm16, 32000, false, 1); |
| 1080 Create(); | 1023 Create(); |
| 1081 | 1024 |
| 1082 int video_start = kVideoStart; | 1025 int video_start = kVideoStart; |
| 1083 const int num_frames = 5; | 1026 const int num_frames = 5; |
| 1084 for (int i = 0; i < num_frames; ++i) { | 1027 for (int i = 0; i < num_frames; ++i) { |
| 1085 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | 1028 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); |
| 1086 test_receiver_video_callback_->AddExpectedResult( | 1029 test_receiver_video_callback_->AddExpectedResult( |
| 1087 video_start, | 1030 video_start, |
| 1088 video_sender_config_.width, | 1031 video_sender_config_.width, |
| 1089 video_sender_config_.height, | 1032 video_sender_config_.height, |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1190 | 1133 |
| 1191 // Verify that there were no other events logged with respect to this | 1134 // Verify that there were no other events logged with respect to this |
| 1192 // packet. (i.e. Total event count = expected event count) | 1135 // packet. (i.e. Total event count = expected event count) |
| 1193 EXPECT_EQ(total_event_count_for_packet, expected_event_count_for_packet); | 1136 EXPECT_EQ(total_event_count_for_packet, expected_event_count_for_packet); |
| 1194 } | 1137 } |
| 1195 } | 1138 } |
| 1196 | 1139 |
| 1197 // Audio test without packet loss - tests the logging aspects of the end2end, | 1140 // Audio test without packet loss - tests the logging aspects of the end2end, |
| 1198 // but is basically equivalent to LoopNoLossPcm16. | 1141 // but is basically equivalent to LoopNoLossPcm16. |
| 1199 TEST_F(End2EndTest, AudioLogging) { | 1142 TEST_F(End2EndTest, AudioLogging) { |
| 1200 SetupConfig(transport::kPcm16, 32000, false, 1); | 1143 Configure(transport::kPcm16, 32000, false, 1); |
| 1201 Create(); | 1144 Create(); |
| 1202 | 1145 |
| 1203 int audio_diff = kFrameTimerMs; | 1146 int audio_diff = kFrameTimerMs; |
| 1204 const int num_audio_buses = 10; | 1147 const int kNumVideoFrames = 10; |
| 1205 int num_frames = 0; | 1148 int num_audio_frames_requested = 0; |
| 1206 for (int i = 0; i < num_audio_buses; ++i) { | 1149 for (int i = 0; i < kNumVideoFrames; ++i) { |
| 1207 int num_10ms_blocks = audio_diff / 10; | 1150 const int num_audio_frames = audio_diff / kAudioFrameDurationMs; |
| 1208 audio_diff -= num_10ms_blocks * 10; | 1151 audio_diff -= num_audio_frames * kAudioFrameDurationMs; |
| 1209 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | |
| 1210 | 1152 |
| 1211 // Each audio bus can contain more than one frame. | 1153 FeedAudioFrames(num_audio_frames, true); |
| 1212 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | |
| 1213 base::TimeDelta::FromMilliseconds(10) * num_10ms_blocks)); | |
| 1214 num_frames += num_10ms_blocks; | |
| 1215 | |
| 1216 if (i != 0) { | |
| 1217 // Due to the re-sampler and NetEq in the webrtc AudioCodingModule the | |
| 1218 // first samples will be 0 and then slowly ramp up to its real | |
| 1219 // amplitude; | |
| 1220 // ignore the first frame. | |
| 1221 test_receiver_audio_callback_->AddExpectedResult( | |
| 1222 ToPcmAudioFrame(*audio_bus, audio_sender_config_.frequency), | |
| 1223 num_10ms_blocks, | |
| 1224 send_time); | |
| 1225 } | |
| 1226 | |
| 1227 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); | |
| 1228 | 1154 |
| 1229 RunTasks(kFrameTimerMs); | 1155 RunTasks(kFrameTimerMs); |
| 1230 audio_diff += kFrameTimerMs; | 1156 audio_diff += kFrameTimerMs; |
| 1231 | 1157 |
| 1232 if (i == 0) { | 1158 RequestAudioFrames(num_audio_frames, true); |
| 1233 frame_receiver_->GetRawAudioFrame( | 1159 num_audio_frames_requested += num_audio_frames; |
| 1234 num_10ms_blocks, | |
| 1235 audio_sender_config_.frequency, | |
| 1236 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame, | |
| 1237 test_receiver_audio_callback_)); | |
| 1238 } else { | |
| 1239 frame_receiver_->GetRawAudioFrame( | |
| 1240 num_10ms_blocks, | |
| 1241 audio_sender_config_.frequency, | |
| 1242 base::Bind(&TestReceiverAudioCallback::CheckPcmAudioFrame, | |
| 1243 test_receiver_audio_callback_)); | |
| 1244 } | |
| 1245 } | 1160 } |
| 1246 | 1161 |
| 1247 // Basic tests. | 1162 // Basic tests. |
| 1248 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. | 1163 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. |
| 1249 | 1164 |
| 1250 int num_times_called = test_receiver_audio_callback_->number_times_called(); | 1165 EXPECT_EQ(num_audio_frames_requested, |
| 1251 EXPECT_EQ(num_audio_buses - 1, num_times_called); | 1166 test_receiver_audio_callback_->number_times_called()); |
| 1252 | 1167 |
| 1253 // Logging tests. | 1168 // Logging tests. |
| 1254 // Verify that all frames and all required events were logged. | 1169 // Verify that all frames and all required events were logged. |
| 1255 event_subscriber_sender_.GetFrameEventsAndReset(&frame_events_); | 1170 event_subscriber_sender_.GetFrameEventsAndReset(&frame_events_); |
| 1256 | 1171 |
| 1257 // Construct a map from each frame (RTP timestamp) to a count of each event | 1172 // Construct a map from each frame (RTP timestamp) to a count of each event |
| 1258 // type logged for that frame. | 1173 // type logged for that frame. |
| 1259 std::map<RtpTimestamp, LoggingEventCounts> event_counter_for_frame = | 1174 std::map<RtpTimestamp, LoggingEventCounts> event_counter_for_frame = |
| 1260 GetEventCountForFrameEvents(frame_events_); | 1175 GetEventCountForFrameEvents(frame_events_); |
| 1261 | 1176 |
| 1262 int received_count = 0; | 1177 int received_count = 0; |
| 1263 int encoded_count = 0; | 1178 int encoded_count = 0; |
| 1264 | 1179 |
| 1265 // Verify the right number of events were logged for each event type. | 1180 // Verify the right number of events were logged for each event type. |
| 1266 for (std::map<RtpTimestamp, LoggingEventCounts>::iterator it = | 1181 for (std::map<RtpTimestamp, LoggingEventCounts>::iterator it = |
| 1267 event_counter_for_frame.begin(); | 1182 event_counter_for_frame.begin(); |
| 1268 it != event_counter_for_frame.end(); | 1183 it != event_counter_for_frame.end(); |
| 1269 ++it) { | 1184 ++it) { |
| 1270 received_count += it->second.counter[kAudioFrameReceived]; | 1185 received_count += it->second.counter[kAudioFrameReceived]; |
| 1271 encoded_count += it->second.counter[kAudioFrameEncoded]; | 1186 encoded_count += it->second.counter[kAudioFrameEncoded]; |
| 1272 } | 1187 } |
| 1273 | 1188 |
| 1274 EXPECT_EQ(num_frames, received_count); | 1189 EXPECT_EQ(num_audio_frames_requested, received_count); |
| 1275 EXPECT_EQ(num_frames, encoded_count); | 1190 EXPECT_EQ(num_audio_frames_requested, encoded_count); |
| 1276 | 1191 |
| 1277 std::map<RtpTimestamp, LoggingEventCounts>::iterator map_it = | 1192 std::map<RtpTimestamp, LoggingEventCounts>::iterator map_it = |
| 1278 event_counter_for_frame.begin(); | 1193 event_counter_for_frame.begin(); |
| 1279 | 1194 |
| 1280 // Verify that each frame have the expected types of events logged. | 1195 // Verify that each frame have the expected types of events logged. |
| 1281 // TODO(imcheng): This only checks the first frame. This doesn't work | 1196 // TODO(imcheng): This only checks the first frame. This doesn't work |
| 1282 // properly for all frames because: | 1197 // properly for all frames because: |
| 1283 // 1. kAudioPlayoutDelay and kAudioFrameDecoded RTP timestamps aren't | 1198 // 1. kAudioPlayoutDelay and kAudioFrameDecoded RTP timestamps aren't |
| 1284 // exactly aligned with those of kAudioFrameReceived and kAudioFrameEncoded. | 1199 // exactly aligned with those of kAudioFrameReceived and kAudioFrameEncoded. |
| 1285 // Note that these RTP timestamps are output from webrtc::AudioCodingModule | 1200 // Note that these RTP timestamps are output from webrtc::AudioCodingModule |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1316 EXPECT_EQ(total_event_count_for_frame, expected_event_count_for_frame); | 1231 EXPECT_EQ(total_event_count_for_frame, expected_event_count_for_frame); |
| 1317 } | 1232 } |
| 1318 | 1233 |
| 1319 // TODO(pwestin): Add repeatable packet loss test. | 1234 // TODO(pwestin): Add repeatable packet loss test. |
| 1320 // TODO(pwestin): Add test for misaligned send get calls. | 1235 // TODO(pwestin): Add test for misaligned send get calls. |
| 1321 // TODO(pwestin): Add more tests that does not resample. | 1236 // TODO(pwestin): Add more tests that does not resample. |
| 1322 // TODO(pwestin): Add test when we have starvation for our RunTask. | 1237 // TODO(pwestin): Add test when we have starvation for our RunTask. |
| 1323 | 1238 |
| 1324 } // namespace cast | 1239 } // namespace cast |
| 1325 } // namespace media | 1240 } // namespace media |
| OLD | NEW |