| 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->coded_size().width()); | 367 EXPECT_EQ(expected_video_frame.width, video_frame->coded_size().width()); |
| 373 EXPECT_EQ(expected_video_frame.height, video_frame->coded_size().height()); | 368 EXPECT_EQ(expected_video_frame.height, video_frame->coded_size().height()); |
| 374 | 369 |
| 375 gfx::Size size(expected_video_frame.width, expected_video_frame.height); | 370 gfx::Size size(expected_video_frame.width, expected_video_frame.height); |
| 376 scoped_refptr<media::VideoFrame> expected_I420_frame = | 371 scoped_refptr<media::VideoFrame> expected_I420_frame = |
| 377 media::VideoFrame::CreateFrame( | 372 media::VideoFrame::CreateFrame( |
| 378 VideoFrame::I420, size, gfx::Rect(size), size, base::TimeDelta()); | 373 VideoFrame::I420, size, gfx::Rect(size), size, base::TimeDelta()); |
| 379 PopulateVideoFrame(expected_I420_frame, expected_video_frame.start_value); | 374 PopulateVideoFrame(expected_I420_frame, expected_video_frame.start_value); |
| 380 | 375 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 test_receiver_audio_callback_(new TestReceiverAudioCallback()), | 416 test_receiver_audio_callback_(new TestReceiverAudioCallback()), |
| 422 test_receiver_video_callback_(new TestReceiverVideoCallback()) { | 417 test_receiver_video_callback_(new TestReceiverVideoCallback()) { |
| 423 testing_clock_sender_->Advance( | 418 testing_clock_sender_->Advance( |
| 424 base::TimeDelta::FromMilliseconds(kStartMillisecond)); | 419 base::TimeDelta::FromMilliseconds(kStartMillisecond)); |
| 425 testing_clock_receiver_->Advance( | 420 testing_clock_receiver_->Advance( |
| 426 base::TimeDelta::FromMilliseconds(kStartMillisecond)); | 421 base::TimeDelta::FromMilliseconds(kStartMillisecond)); |
| 427 cast_environment_sender_->Logging()->AddRawEventSubscriber( | 422 cast_environment_sender_->Logging()->AddRawEventSubscriber( |
| 428 &event_subscriber_sender_); | 423 &event_subscriber_sender_); |
| 429 } | 424 } |
| 430 | 425 |
| 431 void SetupConfig(transport::AudioCodec audio_codec, | 426 void Configure(transport::AudioCodec audio_codec, |
| 432 int audio_sampling_frequency, | 427 int audio_sampling_frequency, |
| 433 // TODO(miu): 3rd arg is meaningless?!? | 428 bool external_audio_decoder, |
| 434 bool external_audio_decoder, | 429 int max_number_of_video_buffers_used) { |
| 435 int max_number_of_video_buffers_used) { | |
| 436 audio_sender_config_.sender_ssrc = 1; | 430 audio_sender_config_.sender_ssrc = 1; |
| 437 audio_sender_config_.incoming_feedback_ssrc = 2; | 431 audio_sender_config_.incoming_feedback_ssrc = 2; |
| 438 audio_sender_config_.rtp_config.payload_type = 96; | 432 audio_sender_config_.rtp_config.payload_type = 96; |
| 439 audio_sender_config_.use_external_encoder = false; | 433 audio_sender_config_.use_external_encoder = false; |
| 440 audio_sender_config_.frequency = audio_sampling_frequency; | 434 audio_sender_config_.frequency = audio_sampling_frequency; |
| 441 audio_sender_config_.channels = kAudioChannels; | 435 audio_sender_config_.channels = kAudioChannels; |
| 442 audio_sender_config_.bitrate = kDefaultAudioEncoderBitrate; | 436 audio_sender_config_.bitrate = kDefaultAudioEncoderBitrate; |
| 443 audio_sender_config_.codec = audio_codec; | 437 audio_sender_config_.codec = audio_codec; |
| 444 | 438 |
| 445 audio_receiver_config_.feedback_ssrc = | 439 audio_receiver_config_.feedback_ssrc = |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 transport_audio_config_.base.ssrc = audio_sender_config_.sender_ssrc; | 477 transport_audio_config_.base.ssrc = audio_sender_config_.sender_ssrc; |
| 484 transport_audio_config_.codec = audio_sender_config_.codec; | 478 transport_audio_config_.codec = audio_sender_config_.codec; |
| 485 transport_audio_config_.base.rtp_config = audio_sender_config_.rtp_config; | 479 transport_audio_config_.base.rtp_config = audio_sender_config_.rtp_config; |
| 486 transport_audio_config_.frequency = audio_sender_config_.frequency; | 480 transport_audio_config_.frequency = audio_sender_config_.frequency; |
| 487 transport_audio_config_.channels = audio_sender_config_.channels; | 481 transport_audio_config_.channels = audio_sender_config_.channels; |
| 488 transport_video_config_.base.ssrc = video_sender_config_.sender_ssrc; | 482 transport_video_config_.base.ssrc = video_sender_config_.sender_ssrc; |
| 489 transport_video_config_.codec = video_sender_config_.codec; | 483 transport_video_config_.codec = video_sender_config_.codec; |
| 490 transport_video_config_.base.rtp_config = video_sender_config_.rtp_config; | 484 transport_video_config_.base.rtp_config = video_sender_config_.rtp_config; |
| 491 } | 485 } |
| 492 | 486 |
| 487 void FeedAudioFrames(int count, bool will_be_checked) { |
| 488 for (int i = 0; i < count; ++i) { |
| 489 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( |
| 490 base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs))); |
| 491 const base::TimeTicks send_time = |
| 492 testing_clock_sender_->NowTicks() + |
| 493 i * base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs); |
| 494 if (will_be_checked) |
| 495 test_receiver_audio_callback_->AddExpectedResult(*audio_bus, send_time); |
| 496 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); |
| 497 } |
| 498 } |
| 499 |
| 500 void FeedAudioFramesWithExpectedDelay(int count, |
| 501 const base::TimeDelta& delay) { |
| 502 for (int i = 0; i < count; ++i) { |
| 503 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( |
| 504 base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs))); |
| 505 const base::TimeTicks send_time = |
| 506 testing_clock_sender_->NowTicks() + |
| 507 i * base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs); |
| 508 test_receiver_audio_callback_->AddExpectedResult(*audio_bus, |
| 509 send_time + delay); |
| 510 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); |
| 511 } |
| 512 } |
| 513 |
| 514 void RequestAudioFrames(int count, bool with_check) { |
| 515 for (int i = 0; i < count; ++i) { |
| 516 frame_receiver_->GetRawAudioFrame( |
| 517 base::Bind(with_check ? &TestReceiverAudioCallback::CheckAudioFrame : |
| 518 &TestReceiverAudioCallback::IgnoreAudioFrame, |
| 519 test_receiver_audio_callback_)); |
| 520 } |
| 521 } |
| 522 |
| 493 void Create() { | 523 void Create() { |
| 494 cast_receiver_ = CastReceiver::Create(cast_environment_receiver_, | 524 cast_receiver_ = CastReceiver::Create(cast_environment_receiver_, |
| 495 audio_receiver_config_, | 525 audio_receiver_config_, |
| 496 video_receiver_config_, | 526 video_receiver_config_, |
| 497 &receiver_to_sender_); | 527 &receiver_to_sender_); |
| 498 net::IPEndPoint dummy_endpoint; | 528 net::IPEndPoint dummy_endpoint; |
| 499 transport_sender_.reset(new transport::CastTransportSenderImpl( | 529 transport_sender_.reset(new transport::CastTransportSenderImpl( |
| 500 NULL, | 530 NULL, |
| 501 testing_clock_sender_, | 531 testing_clock_sender_, |
| 502 dummy_endpoint, | 532 dummy_endpoint, |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 | 647 |
| 618 SimpleEventSubscriber event_subscriber_sender_; | 648 SimpleEventSubscriber event_subscriber_sender_; |
| 619 std::vector<FrameEvent> frame_events_; | 649 std::vector<FrameEvent> frame_events_; |
| 620 std::vector<PacketEvent> packet_events_; | 650 std::vector<PacketEvent> packet_events_; |
| 621 std::vector<GenericEvent> generic_events_; | 651 std::vector<GenericEvent> generic_events_; |
| 622 // |transport_sender_| has a RepeatingTimer which needs a MessageLoop. | 652 // |transport_sender_| has a RepeatingTimer which needs a MessageLoop. |
| 623 base::MessageLoop message_loop_; | 653 base::MessageLoop message_loop_; |
| 624 }; | 654 }; |
| 625 | 655 |
| 626 TEST_F(End2EndTest, LoopNoLossPcm16) { | 656 TEST_F(End2EndTest, LoopNoLossPcm16) { |
| 627 SetupConfig(transport::kPcm16, 32000, false, 1); | 657 Configure(transport::kPcm16, 32000, false, 1); |
| 628 // Reduce video resolution to allow processing multiple frames within a | 658 // Reduce video resolution to allow processing multiple frames within a |
| 629 // reasonable time frame. | 659 // reasonable time frame. |
| 630 video_sender_config_.width = kVideoQcifWidth; | 660 video_sender_config_.width = kVideoQcifWidth; |
| 631 video_sender_config_.height = kVideoQcifHeight; | 661 video_sender_config_.height = kVideoQcifHeight; |
| 632 Create(); | 662 Create(); |
| 633 | 663 |
| 664 const int kNumIterations = 50; |
| 634 int video_start = kVideoStart; | 665 int video_start = kVideoStart; |
| 635 int audio_diff = kFrameTimerMs; | 666 int audio_diff = kFrameTimerMs; |
| 636 int i = 0; | 667 int num_audio_frames_requested = 0; |
| 668 for (int i = 0; i < kNumIterations; ++i) { |
| 669 const int num_audio_frames = audio_diff / kAudioFrameDurationMs; |
| 670 audio_diff -= num_audio_frames * kAudioFrameDurationMs; |
| 637 | 671 |
| 638 for (; i < 300; ++i) { | 672 if (num_audio_frames > 0) |
| 639 int num_10ms_blocks = audio_diff / 10; | 673 FeedAudioFrames(1, true); |
| 640 audio_diff -= num_10ms_blocks * 10; | |
| 641 | |
| 642 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | |
| 643 base::TimeDelta::FromMilliseconds(10) * num_10ms_blocks)); | |
| 644 | |
| 645 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | |
| 646 if (i != 0) { | |
| 647 // Due to the re-sampler and NetEq in the webrtc AudioCodingModule the | |
| 648 // first samples will be 0 and then slowly ramp up to its real | |
| 649 // amplitude; | |
| 650 // ignore the first frame. | |
| 651 test_receiver_audio_callback_->AddExpectedResult( | |
| 652 ToPcmAudioFrame(*audio_bus, audio_sender_config_.frequency), | |
| 653 num_10ms_blocks, | |
| 654 send_time); | |
| 655 } | |
| 656 | |
| 657 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); | |
| 658 | 674 |
| 659 test_receiver_video_callback_->AddExpectedResult( | 675 test_receiver_video_callback_->AddExpectedResult( |
| 660 video_start, | 676 video_start, |
| 661 video_sender_config_.width, | 677 video_sender_config_.width, |
| 662 video_sender_config_.height, | 678 video_sender_config_.height, |
| 663 send_time); | 679 testing_clock_sender_->NowTicks()); |
| 664 SendVideoFrame(video_start, send_time); | 680 SendVideoFrame(video_start, testing_clock_sender_->NowTicks()); |
| 665 | 681 |
| 666 if (i == 0) { | 682 if (num_audio_frames > 0) |
| 667 frame_receiver_->GetRawAudioFrame( | 683 RunTasks(kAudioFrameDurationMs); // Advance clock forward. |
| 668 num_10ms_blocks, | 684 if (num_audio_frames > 1) |
| 669 audio_sender_config_.frequency, | 685 FeedAudioFrames(num_audio_frames - 1, true); |
| 670 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame, | 686 |
| 671 test_receiver_audio_callback_)); | 687 RequestAudioFrames(num_audio_frames, true); |
| 672 } else { | 688 num_audio_frames_requested += num_audio_frames; |
| 673 frame_receiver_->GetRawAudioFrame( | |
| 674 num_10ms_blocks, | |
| 675 audio_sender_config_.frequency, | |
| 676 base::Bind(&TestReceiverAudioCallback::CheckPcmAudioFrame, | |
| 677 test_receiver_audio_callback_)); | |
| 678 } | |
| 679 | 689 |
| 680 frame_receiver_->GetRawVideoFrame( | 690 frame_receiver_->GetRawVideoFrame( |
| 681 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 691 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
| 682 test_receiver_video_callback_)); | 692 test_receiver_video_callback_)); |
| 683 | 693 |
| 684 RunTasks(kFrameTimerMs); | 694 RunTasks(kFrameTimerMs - kAudioFrameDurationMs); |
| 685 audio_diff += kFrameTimerMs; | 695 audio_diff += kFrameTimerMs; |
| 686 video_start++; | 696 video_start++; |
| 687 } | 697 } |
| 688 | 698 |
| 689 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. | 699 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. |
| 690 EXPECT_EQ(i - 1, test_receiver_audio_callback_->number_times_called()); | 700 EXPECT_EQ(num_audio_frames_requested, |
| 691 EXPECT_EQ(i, test_receiver_video_callback_->number_times_called()); | 701 test_receiver_audio_callback_->number_times_called()); |
| 702 EXPECT_EQ(kNumIterations, |
| 703 test_receiver_video_callback_->number_times_called()); |
| 692 } | 704 } |
| 693 | 705 |
| 694 // This tests our external decoder interface for Audio. | 706 // This tests our external decoder interface for Audio. |
| 695 // Audio test without packet loss using raw PCM 16 audio "codec"; | 707 // Audio test without packet loss using raw PCM 16 audio "codec"; |
| 696 TEST_F(End2EndTest, LoopNoLossPcm16ExternalDecoder) { | 708 TEST_F(End2EndTest, LoopNoLossPcm16ExternalDecoder) { |
| 697 SetupConfig(transport::kPcm16, 32000, true, 1); | 709 Configure(transport::kPcm16, 32000, true, 1); |
| 698 Create(); | 710 Create(); |
| 699 | 711 |
| 700 int i = 0; | 712 const int kNumIterations = 10; |
| 701 for (; i < 10; ++i) { | 713 for (int i = 0; i < kNumIterations; ++i) { |
| 702 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | 714 FeedAudioFrames(1, true); |
| 703 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | 715 RunTasks(kAudioFrameDurationMs); |
| 704 base::TimeDelta::FromMilliseconds(10))); | |
| 705 test_receiver_audio_callback_->AddExpectedResult( | |
| 706 ToPcmAudioFrame(*audio_bus, audio_sender_config_.frequency), | |
| 707 1, | |
| 708 send_time); | |
| 709 | |
| 710 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); | |
| 711 | |
| 712 RunTasks(10); | |
| 713 frame_receiver_->GetCodedAudioFrame( | 716 frame_receiver_->GetCodedAudioFrame( |
| 714 base::Bind(&TestReceiverAudioCallback::CheckCodedPcmAudioFrame, | 717 base::Bind(&TestReceiverAudioCallback::CheckCodedAudioFrame, |
| 715 test_receiver_audio_callback_)); | 718 test_receiver_audio_callback_)); |
| 716 } | 719 } |
| 717 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. | 720 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. |
| 718 EXPECT_EQ(10, test_receiver_audio_callback_->number_times_called()); | 721 EXPECT_EQ(kNumIterations, |
| 722 test_receiver_audio_callback_->number_times_called()); |
| 719 } | 723 } |
| 720 | 724 |
| 721 // This tests our Opus audio codec without video. | 725 // This tests our Opus audio codec without video. |
| 722 TEST_F(End2EndTest, LoopNoLossOpus) { | 726 TEST_F(End2EndTest, LoopNoLossOpus) { |
| 723 SetupConfig(transport::kOpus, kDefaultAudioSamplingRate, false, 1); | 727 Configure(transport::kOpus, kDefaultAudioSamplingRate, false, 1); |
| 724 Create(); | 728 Create(); |
| 725 | 729 |
| 726 int i = 0; | 730 const int kNumIterations = 300; |
| 727 for (; i < 10; ++i) { | 731 for (int i = 0; i < kNumIterations; ++i) { |
| 728 int num_10ms_blocks = 3; | 732 // Opus introduces a tiny delay before the sinewave starts; so don't examine |
| 729 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | 733 // the first frame. |
| 730 | 734 const bool examine_audio_data = i > 0; |
| 731 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | 735 FeedAudioFrames(1, examine_audio_data); |
| 732 base::TimeDelta::FromMilliseconds(10) * num_10ms_blocks)); | 736 RunTasks(kAudioFrameDurationMs); |
| 733 | 737 RequestAudioFrames(1, examine_audio_data); |
| 734 if (i != 0) { | |
| 735 test_receiver_audio_callback_->AddExpectedResult( | |
| 736 ToPcmAudioFrame(*audio_bus, audio_sender_config_.frequency), | |
| 737 num_10ms_blocks, | |
| 738 send_time); | |
| 739 } | |
| 740 | |
| 741 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); | |
| 742 | |
| 743 RunTasks(30); | |
| 744 | |
| 745 if (i == 0) { | |
| 746 frame_receiver_->GetRawAudioFrame( | |
| 747 num_10ms_blocks, | |
| 748 audio_sender_config_.frequency, | |
| 749 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame, | |
| 750 test_receiver_audio_callback_)); | |
| 751 } else { | |
| 752 frame_receiver_->GetRawAudioFrame( | |
| 753 num_10ms_blocks, | |
| 754 audio_sender_config_.frequency, | |
| 755 base::Bind(&TestReceiverAudioCallback::CheckPcmAudioFrame, | |
| 756 test_receiver_audio_callback_)); | |
| 757 } | |
| 758 } | 738 } |
| 759 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. | 739 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. |
| 760 EXPECT_EQ(i - 1, test_receiver_audio_callback_->number_times_called()); | 740 EXPECT_EQ(kNumIterations, |
| 741 test_receiver_audio_callback_->number_times_called()); |
| 761 } | 742 } |
| 762 | 743 |
| 763 // This tests start sending audio and video at start-up time before the receiver | 744 // This tests start sending audio and video at start-up time before the receiver |
| 764 // is ready; it sends 2 frames before the receiver comes online. | 745 // is ready; it sends 2 frames before the receiver comes online. |
| 765 TEST_F(End2EndTest, StartSenderBeforeReceiver) { | 746 // |
| 766 SetupConfig(transport::kOpus, kDefaultAudioSamplingRate, false, 1); | 747 // Test disabled due to flakiness: It appears that the RTCP synchronization |
| 748 // sometimes kicks in, and sometimes doesn't. When it does, there's a sharp |
| 749 // discontinuity in the timeline, throwing off the test expectations. See TODOs |
| 750 // in audio_receiver.cc for likely cause(s) of this bug. |
| 751 // http://crbug.com/356942 |
| 752 TEST_F(End2EndTest, DISABLED_StartSenderBeforeReceiver) { |
| 753 Configure(transport::kPcm16, kDefaultAudioSamplingRate, false, 1); |
| 767 Create(); | 754 Create(); |
| 768 | 755 |
| 769 int video_start = kVideoStart; | 756 int video_start = kVideoStart; |
| 770 int audio_diff = kFrameTimerMs; | 757 int audio_diff = kFrameTimerMs; |
| 771 | 758 |
| 772 sender_to_receiver_.SetSendPackets(false); | 759 sender_to_receiver_.SetSendPackets(false); |
| 773 | 760 |
| 774 const int test_delay_ms = 100; | 761 const int test_delay_ms = 100; |
| 775 | 762 |
| 776 base::TimeTicks initial_send_time; | 763 const int kNumVideoFramesBeforeReceiverStarted = 2; |
| 777 for (int i = 0; i < 2; ++i) { | 764 const base::TimeTicks initial_send_time = testing_clock_sender_->NowTicks(); |
| 778 int num_10ms_blocks = audio_diff / 10; | 765 const base::TimeDelta expected_delay = |
| 779 audio_diff -= num_10ms_blocks * 10; | 766 base::TimeDelta::FromMilliseconds(test_delay_ms + kFrameTimerMs); |
| 767 for (int i = 0; i < kNumVideoFramesBeforeReceiverStarted; ++i) { |
| 768 const int num_audio_frames = audio_diff / kAudioFrameDurationMs; |
| 769 audio_diff -= num_audio_frames * kAudioFrameDurationMs; |
| 780 | 770 |
| 781 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | 771 if (num_audio_frames > 0) |
| 782 if (initial_send_time.is_null()) | 772 FeedAudioFramesWithExpectedDelay(1, expected_delay); |
| 783 initial_send_time = send_time; | |
| 784 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | |
| 785 base::TimeDelta::FromMilliseconds(10) * num_10ms_blocks)); | |
| 786 | |
| 787 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); | |
| 788 | 773 |
| 789 // Frame will be rendered with 100mS delay, as the transmission is delayed. | 774 // Frame will be rendered with 100mS delay, as the transmission is delayed. |
| 790 // The receiver at this point cannot be synced to the sender's clock, as no | 775 // The receiver at this point cannot be synced to the sender's clock, as no |
| 791 // packets, and specifically no RTCP packets were sent. | 776 // packets, and specifically no RTCP packets were sent. |
| 792 test_receiver_video_callback_->AddExpectedResult( | 777 test_receiver_video_callback_->AddExpectedResult( |
| 793 video_start, | 778 video_start, |
| 794 video_sender_config_.width, | 779 video_sender_config_.width, |
| 795 video_sender_config_.height, | 780 video_sender_config_.height, |
| 796 initial_send_time + | 781 initial_send_time + expected_delay); |
| 797 base::TimeDelta::FromMilliseconds(test_delay_ms + kFrameTimerMs)); | 782 SendVideoFrame(video_start, testing_clock_sender_->NowTicks()); |
| 798 | 783 |
| 799 SendVideoFrame(video_start, send_time); | 784 if (num_audio_frames > 0) |
| 800 RunTasks(kFrameTimerMs); | 785 RunTasks(kAudioFrameDurationMs); // Advance clock forward. |
| 786 if (num_audio_frames > 1) |
| 787 FeedAudioFramesWithExpectedDelay(num_audio_frames - 1, expected_delay); |
| 788 |
| 789 RunTasks(kFrameTimerMs - kAudioFrameDurationMs); |
| 801 audio_diff += kFrameTimerMs; | 790 audio_diff += kFrameTimerMs; |
| 802 video_start++; | 791 video_start++; |
| 803 } | 792 } |
| 804 | 793 |
| 805 RunTasks(test_delay_ms); | 794 RunTasks(test_delay_ms); |
| 806 sender_to_receiver_.SetSendPackets(true); | 795 sender_to_receiver_.SetSendPackets(true); |
| 807 | 796 |
| 808 int j = 0; | 797 int num_audio_frames_requested = 0; |
| 809 const int number_of_audio_frames_to_ignore = 2; | 798 for (int j = 0; j < 10; ++j) { |
| 810 for (; j < 10; ++j) { | 799 const int num_audio_frames = audio_diff / kAudioFrameDurationMs; |
| 811 int num_10ms_blocks = audio_diff / 10; | 800 audio_diff -= num_audio_frames * kAudioFrameDurationMs; |
| 812 audio_diff -= num_10ms_blocks * 10; | |
| 813 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | |
| 814 | 801 |
| 815 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | 802 if (num_audio_frames > 0) |
| 816 base::TimeDelta::FromMilliseconds(10) * num_10ms_blocks)); | 803 FeedAudioFrames(1, true); |
| 817 | |
| 818 if (j >= number_of_audio_frames_to_ignore) { | |
| 819 test_receiver_audio_callback_->AddExpectedResult( | |
| 820 ToPcmAudioFrame(*audio_bus, audio_sender_config_.frequency), | |
| 821 num_10ms_blocks, | |
| 822 send_time); | |
| 823 } | |
| 824 | |
| 825 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); | |
| 826 | 804 |
| 827 test_receiver_video_callback_->AddExpectedResult( | 805 test_receiver_video_callback_->AddExpectedResult( |
| 828 video_start, | 806 video_start, |
| 829 video_sender_config_.width, | 807 video_sender_config_.width, |
| 830 video_sender_config_.height, | 808 video_sender_config_.height, |
| 831 send_time); | 809 testing_clock_sender_->NowTicks()); |
| 810 SendVideoFrame(video_start, testing_clock_sender_->NowTicks()); |
| 832 | 811 |
| 833 SendVideoFrame(video_start, send_time); | 812 if (num_audio_frames > 0) |
| 834 RunTasks(kFrameTimerMs); | 813 RunTasks(kAudioFrameDurationMs); // Advance clock forward. |
| 835 audio_diff += kFrameTimerMs; | 814 if (num_audio_frames > 1) |
| 815 FeedAudioFrames(num_audio_frames - 1, true); |
| 836 | 816 |
| 837 if (j < number_of_audio_frames_to_ignore) { | 817 RequestAudioFrames(num_audio_frames, true); |
| 838 frame_receiver_->GetRawAudioFrame( | 818 num_audio_frames_requested += num_audio_frames; |
| 839 num_10ms_blocks, | 819 |
| 840 audio_sender_config_.frequency, | |
| 841 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame, | |
| 842 test_receiver_audio_callback_)); | |
| 843 } else { | |
| 844 frame_receiver_->GetRawAudioFrame( | |
| 845 num_10ms_blocks, | |
| 846 audio_sender_config_.frequency, | |
| 847 base::Bind(&TestReceiverAudioCallback::CheckPcmAudioFrame, | |
| 848 test_receiver_audio_callback_)); | |
| 849 } | |
| 850 frame_receiver_->GetRawVideoFrame( | 820 frame_receiver_->GetRawVideoFrame( |
| 851 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 821 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
| 852 test_receiver_video_callback_)); | 822 test_receiver_video_callback_)); |
| 823 |
| 824 RunTasks(kFrameTimerMs - kAudioFrameDurationMs); |
| 825 audio_diff += kFrameTimerMs; |
| 853 video_start++; | 826 video_start++; |
| 854 } | 827 } |
| 855 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. | 828 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. |
| 856 EXPECT_EQ(j - number_of_audio_frames_to_ignore, | 829 EXPECT_EQ(num_audio_frames_requested, |
| 857 test_receiver_audio_callback_->number_times_called()); | 830 test_receiver_audio_callback_->number_times_called()); |
| 858 EXPECT_EQ(j, test_receiver_video_callback_->number_times_called()); | 831 EXPECT_EQ(10, test_receiver_video_callback_->number_times_called()); |
| 859 } | 832 } |
| 860 | 833 |
| 861 // This tests a network glitch lasting for 10 video frames. | 834 // This tests a network glitch lasting for 10 video frames. |
| 862 // Flaky. See crbug.com/351596. | 835 // Flaky. See crbug.com/351596. |
| 863 TEST_F(End2EndTest, DISABLED_GlitchWith3Buffers) { | 836 TEST_F(End2EndTest, DISABLED_GlitchWith3Buffers) { |
| 864 SetupConfig(transport::kOpus, kDefaultAudioSamplingRate, false, 3); | 837 Configure(transport::kOpus, kDefaultAudioSamplingRate, false, 3); |
| 865 video_sender_config_.rtp_config.max_delay_ms = 67; | 838 video_sender_config_.rtp_config.max_delay_ms = 67; |
| 866 video_receiver_config_.rtp_max_delay_ms = 67; | 839 video_receiver_config_.rtp_max_delay_ms = 67; |
| 867 Create(); | 840 Create(); |
| 868 | 841 |
| 869 int video_start = kVideoStart; | 842 int video_start = kVideoStart; |
| 870 base::TimeTicks send_time; | 843 base::TimeTicks send_time; |
| 871 // Frames will rendered on completion until the render time stabilizes, i.e. | 844 // Frames will rendered on completion until the render time stabilizes, i.e. |
| 872 // we got enough data. | 845 // we got enough data. |
| 873 const int frames_before_glitch = 20; | 846 const int frames_before_glitch = 20; |
| 874 for (int i = 0; i < frames_before_glitch; ++i) { | 847 for (int i = 0; i < frames_before_glitch; ++i) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 913 frame_receiver_->GetRawVideoFrame( | 886 frame_receiver_->GetRawVideoFrame( |
| 914 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 887 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
| 915 test_receiver_video_callback_)); | 888 test_receiver_video_callback_)); |
| 916 | 889 |
| 917 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. | 890 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. |
| 918 EXPECT_EQ(frames_before_glitch + 1, | 891 EXPECT_EQ(frames_before_glitch + 1, |
| 919 test_receiver_video_callback_->number_times_called()); | 892 test_receiver_video_callback_->number_times_called()); |
| 920 } | 893 } |
| 921 | 894 |
| 922 TEST_F(End2EndTest, DropEveryOtherFrame3Buffers) { | 895 TEST_F(End2EndTest, DropEveryOtherFrame3Buffers) { |
| 923 SetupConfig(transport::kOpus, kDefaultAudioSamplingRate, false, 3); | 896 Configure(transport::kOpus, kDefaultAudioSamplingRate, false, 3); |
| 924 video_sender_config_.rtp_config.max_delay_ms = 67; | 897 video_sender_config_.rtp_config.max_delay_ms = 67; |
| 925 video_receiver_config_.rtp_max_delay_ms = 67; | 898 video_receiver_config_.rtp_max_delay_ms = 67; |
| 926 Create(); | 899 Create(); |
| 927 sender_to_receiver_.DropAllPacketsBelongingToOddFrames(); | 900 sender_to_receiver_.DropAllPacketsBelongingToOddFrames(); |
| 928 | 901 |
| 929 int video_start = kVideoStart; | 902 int video_start = kVideoStart; |
| 930 base::TimeTicks send_time; | 903 base::TimeTicks send_time; |
| 931 | 904 |
| 932 int i = 0; | 905 int i = 0; |
| 933 for (; i < 20; ++i) { | 906 for (; i < 20; ++i) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 949 } | 922 } |
| 950 RunTasks(kFrameTimerMs); | 923 RunTasks(kFrameTimerMs); |
| 951 video_start++; | 924 video_start++; |
| 952 } | 925 } |
| 953 | 926 |
| 954 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | 927 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. |
| 955 EXPECT_EQ(i / 2, test_receiver_video_callback_->number_times_called()); | 928 EXPECT_EQ(i / 2, test_receiver_video_callback_->number_times_called()); |
| 956 } | 929 } |
| 957 | 930 |
| 958 TEST_F(End2EndTest, ResetReferenceFrameId) { | 931 TEST_F(End2EndTest, ResetReferenceFrameId) { |
| 959 SetupConfig(transport::kOpus, kDefaultAudioSamplingRate, false, 3); | 932 Configure(transport::kOpus, kDefaultAudioSamplingRate, false, 3); |
| 960 video_sender_config_.rtp_config.max_delay_ms = 67; | 933 video_sender_config_.rtp_config.max_delay_ms = 67; |
| 961 video_receiver_config_.rtp_max_delay_ms = 67; | 934 video_receiver_config_.rtp_max_delay_ms = 67; |
| 962 Create(); | 935 Create(); |
| 963 sender_to_receiver_.AlwaysResetReferenceFrameId(); | 936 sender_to_receiver_.AlwaysResetReferenceFrameId(); |
| 964 | 937 |
| 965 int frames_counter = 0; | 938 int frames_counter = 0; |
| 966 for (; frames_counter < 10; ++frames_counter) { | 939 for (; frames_counter < 10; ++frames_counter) { |
| 967 const base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | 940 const base::TimeTicks send_time = testing_clock_sender_->NowTicks(); |
| 968 SendVideoFrame(frames_counter, send_time); | 941 SendVideoFrame(frames_counter, send_time); |
| 969 | 942 |
| 970 test_receiver_video_callback_->AddExpectedResult( | 943 test_receiver_video_callback_->AddExpectedResult( |
| 971 frames_counter, | 944 frames_counter, |
| 972 video_sender_config_.width, | 945 video_sender_config_.width, |
| 973 video_sender_config_.height, | 946 video_sender_config_.height, |
| 974 send_time); | 947 send_time); |
| 975 | 948 |
| 976 // GetRawVideoFrame will not return the frame until we are close to the | 949 // GetRawVideoFrame will not return the frame until we are close to the |
| 977 // time in which we should render the frame. | 950 // time in which we should render the frame. |
| 978 frame_receiver_->GetRawVideoFrame( | 951 frame_receiver_->GetRawVideoFrame( |
| 979 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 952 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
| 980 test_receiver_video_callback_)); | 953 test_receiver_video_callback_)); |
| 981 RunTasks(kFrameTimerMs); | 954 RunTasks(kFrameTimerMs); |
| 982 } | 955 } |
| 983 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | 956 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. |
| 984 EXPECT_EQ(frames_counter, | 957 EXPECT_EQ(frames_counter, |
| 985 test_receiver_video_callback_->number_times_called()); | 958 test_receiver_video_callback_->number_times_called()); |
| 986 } | 959 } |
| 987 | 960 |
| 988 TEST_F(End2EndTest, CryptoVideo) { | 961 TEST_F(End2EndTest, CryptoVideo) { |
| 989 SetupConfig(transport::kPcm16, 32000, false, 1); | 962 Configure(transport::kPcm16, 32000, false, 1); |
| 990 | 963 |
| 991 transport_video_config_.base.aes_iv_mask = | 964 transport_video_config_.base.aes_iv_mask = |
| 992 ConvertFromBase16String("1234567890abcdeffedcba0987654321"); | 965 ConvertFromBase16String("1234567890abcdeffedcba0987654321"); |
| 993 transport_video_config_.base.aes_key = | 966 transport_video_config_.base.aes_key = |
| 994 ConvertFromBase16String("deadbeefcafeb0b0b0b0cafedeadbeef"); | 967 ConvertFromBase16String("deadbeefcafeb0b0b0b0cafedeadbeef"); |
| 995 | 968 |
| 996 video_receiver_config_.aes_iv_mask = transport_video_config_.base.aes_iv_mask; | 969 video_receiver_config_.aes_iv_mask = transport_video_config_.base.aes_iv_mask; |
| 997 video_receiver_config_.aes_key = transport_video_config_.base.aes_key; | 970 video_receiver_config_.aes_key = transport_video_config_.base.aes_key; |
| 998 | 971 |
| 999 Create(); | 972 Create(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1016 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 989 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
| 1017 test_receiver_video_callback_)); | 990 test_receiver_video_callback_)); |
| 1018 RunTasks(kFrameTimerMs); | 991 RunTasks(kFrameTimerMs); |
| 1019 } | 992 } |
| 1020 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | 993 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. |
| 1021 EXPECT_EQ(frames_counter, | 994 EXPECT_EQ(frames_counter, |
| 1022 test_receiver_video_callback_->number_times_called()); | 995 test_receiver_video_callback_->number_times_called()); |
| 1023 } | 996 } |
| 1024 | 997 |
| 1025 TEST_F(End2EndTest, CryptoAudio) { | 998 TEST_F(End2EndTest, CryptoAudio) { |
| 1026 SetupConfig(transport::kPcm16, 32000, false, 1); | 999 Configure(transport::kPcm16, 32000, false, 1); |
| 1027 | 1000 |
| 1028 transport_audio_config_.base.aes_iv_mask = | 1001 transport_audio_config_.base.aes_iv_mask = |
| 1029 ConvertFromBase16String("abcdeffedcba12345678900987654321"); | 1002 ConvertFromBase16String("abcdeffedcba12345678900987654321"); |
| 1030 transport_audio_config_.base.aes_key = | 1003 transport_audio_config_.base.aes_key = |
| 1031 ConvertFromBase16String("deadbeefcafecafedeadbeefb0b0b0b0"); | 1004 ConvertFromBase16String("deadbeefcafecafedeadbeefb0b0b0b0"); |
| 1032 | 1005 |
| 1033 audio_receiver_config_.aes_iv_mask = transport_audio_config_.base.aes_iv_mask; | 1006 audio_receiver_config_.aes_iv_mask = transport_audio_config_.base.aes_iv_mask; |
| 1034 audio_receiver_config_.aes_key = transport_audio_config_.base.aes_key; | 1007 audio_receiver_config_.aes_key = transport_audio_config_.base.aes_key; |
| 1035 | 1008 |
| 1036 Create(); | 1009 Create(); |
| 1037 | 1010 |
| 1038 int frames_counter = 0; | 1011 const int kNumIterations = 3; |
| 1039 for (; frames_counter < 3; ++frames_counter) { | 1012 const int kNumAudioFramesPerIteration = 2; |
| 1040 int num_10ms_blocks = 2; | 1013 for (int i = 0; i < kNumIterations; ++i) { |
| 1041 | 1014 FeedAudioFrames(kNumAudioFramesPerIteration, true); |
| 1042 const base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | 1015 RunTasks(kNumAudioFramesPerIteration * kAudioFrameDurationMs); |
| 1043 | 1016 RequestAudioFrames(kNumAudioFramesPerIteration, true); |
| 1044 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | |
| 1045 base::TimeDelta::FromMilliseconds(10) * num_10ms_blocks)); | |
| 1046 | |
| 1047 if (frames_counter != 0) { | |
| 1048 // Due to the re-sampler and NetEq in the webrtc AudioCodingModule the | |
| 1049 // first samples will be 0 and then slowly ramp up to its real | |
| 1050 // amplitude; | |
| 1051 // ignore the first frame. | |
| 1052 test_receiver_audio_callback_->AddExpectedResult( | |
| 1053 ToPcmAudioFrame(*audio_bus, audio_sender_config_.frequency), | |
| 1054 num_10ms_blocks, | |
| 1055 send_time); | |
| 1056 } | |
| 1057 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); | |
| 1058 | |
| 1059 RunTasks(num_10ms_blocks * 10); | |
| 1060 | |
| 1061 if (frames_counter == 0) { | |
| 1062 frame_receiver_->GetRawAudioFrame( | |
| 1063 num_10ms_blocks, | |
| 1064 32000, | |
| 1065 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame, | |
| 1066 test_receiver_audio_callback_)); | |
| 1067 } else { | |
| 1068 frame_receiver_->GetRawAudioFrame( | |
| 1069 num_10ms_blocks, | |
| 1070 32000, | |
| 1071 base::Bind(&TestReceiverAudioCallback::CheckPcmAudioFrame, | |
| 1072 test_receiver_audio_callback_)); | |
| 1073 } | |
| 1074 } | 1017 } |
| 1075 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | 1018 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. |
| 1076 EXPECT_EQ(frames_counter - 1, | 1019 EXPECT_EQ(kNumIterations * kNumAudioFramesPerIteration, |
| 1077 test_receiver_audio_callback_->number_times_called()); | 1020 test_receiver_audio_callback_->number_times_called()); |
| 1078 } | 1021 } |
| 1079 | 1022 |
| 1080 // Video test without packet loss - tests the logging aspects of the end2end, | 1023 // Video test without packet loss - tests the logging aspects of the end2end, |
| 1081 // but is basically equivalent to LoopNoLossPcm16. | 1024 // but is basically equivalent to LoopNoLossPcm16. |
| 1082 TEST_F(End2EndTest, VideoLogging) { | 1025 TEST_F(End2EndTest, VideoLogging) { |
| 1083 SetupConfig(transport::kPcm16, 32000, false, 1); | 1026 Configure(transport::kPcm16, 32000, false, 1); |
| 1084 Create(); | 1027 Create(); |
| 1085 | 1028 |
| 1086 int video_start = kVideoStart; | 1029 int video_start = kVideoStart; |
| 1087 const int num_frames = 5; | 1030 const int num_frames = 5; |
| 1088 for (int i = 0; i < num_frames; ++i) { | 1031 for (int i = 0; i < num_frames; ++i) { |
| 1089 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | 1032 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); |
| 1090 test_receiver_video_callback_->AddExpectedResult( | 1033 test_receiver_video_callback_->AddExpectedResult( |
| 1091 video_start, | 1034 video_start, |
| 1092 video_sender_config_.width, | 1035 video_sender_config_.width, |
| 1093 video_sender_config_.height, | 1036 video_sender_config_.height, |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1194 | 1137 |
| 1195 // Verify that there were no other events logged with respect to this | 1138 // Verify that there were no other events logged with respect to this |
| 1196 // packet. (i.e. Total event count = expected event count) | 1139 // packet. (i.e. Total event count = expected event count) |
| 1197 EXPECT_EQ(total_event_count_for_packet, expected_event_count_for_packet); | 1140 EXPECT_EQ(total_event_count_for_packet, expected_event_count_for_packet); |
| 1198 } | 1141 } |
| 1199 } | 1142 } |
| 1200 | 1143 |
| 1201 // Audio test without packet loss - tests the logging aspects of the end2end, | 1144 // Audio test without packet loss - tests the logging aspects of the end2end, |
| 1202 // but is basically equivalent to LoopNoLossPcm16. | 1145 // but is basically equivalent to LoopNoLossPcm16. |
| 1203 TEST_F(End2EndTest, AudioLogging) { | 1146 TEST_F(End2EndTest, AudioLogging) { |
| 1204 SetupConfig(transport::kPcm16, 32000, false, 1); | 1147 Configure(transport::kPcm16, 32000, false, 1); |
| 1205 Create(); | 1148 Create(); |
| 1206 | 1149 |
| 1207 int audio_diff = kFrameTimerMs; | 1150 int audio_diff = kFrameTimerMs; |
| 1208 const int num_audio_buses = 10; | 1151 const int kNumVideoFrames = 10; |
| 1209 int num_frames = 0; | 1152 int num_audio_frames_requested = 0; |
| 1210 for (int i = 0; i < num_audio_buses; ++i) { | 1153 for (int i = 0; i < kNumVideoFrames; ++i) { |
| 1211 int num_10ms_blocks = audio_diff / 10; | 1154 const int num_audio_frames = audio_diff / kAudioFrameDurationMs; |
| 1212 audio_diff -= num_10ms_blocks * 10; | 1155 audio_diff -= num_audio_frames * kAudioFrameDurationMs; |
| 1213 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | |
| 1214 | 1156 |
| 1215 // Each audio bus can contain more than one frame. | 1157 FeedAudioFrames(num_audio_frames, true); |
| 1216 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | |
| 1217 base::TimeDelta::FromMilliseconds(10) * num_10ms_blocks)); | |
| 1218 num_frames += num_10ms_blocks; | |
| 1219 | |
| 1220 if (i != 0) { | |
| 1221 // Due to the re-sampler and NetEq in the webrtc AudioCodingModule the | |
| 1222 // first samples will be 0 and then slowly ramp up to its real | |
| 1223 // amplitude; | |
| 1224 // ignore the first frame. | |
| 1225 test_receiver_audio_callback_->AddExpectedResult( | |
| 1226 ToPcmAudioFrame(*audio_bus, audio_sender_config_.frequency), | |
| 1227 num_10ms_blocks, | |
| 1228 send_time); | |
| 1229 } | |
| 1230 | |
| 1231 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); | |
| 1232 | 1158 |
| 1233 RunTasks(kFrameTimerMs); | 1159 RunTasks(kFrameTimerMs); |
| 1234 audio_diff += kFrameTimerMs; | 1160 audio_diff += kFrameTimerMs; |
| 1235 | 1161 |
| 1236 if (i == 0) { | 1162 RequestAudioFrames(num_audio_frames, true); |
| 1237 frame_receiver_->GetRawAudioFrame( | 1163 num_audio_frames_requested += num_audio_frames; |
| 1238 num_10ms_blocks, | |
| 1239 audio_sender_config_.frequency, | |
| 1240 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame, | |
| 1241 test_receiver_audio_callback_)); | |
| 1242 } else { | |
| 1243 frame_receiver_->GetRawAudioFrame( | |
| 1244 num_10ms_blocks, | |
| 1245 audio_sender_config_.frequency, | |
| 1246 base::Bind(&TestReceiverAudioCallback::CheckPcmAudioFrame, | |
| 1247 test_receiver_audio_callback_)); | |
| 1248 } | |
| 1249 } | 1164 } |
| 1250 | 1165 |
| 1251 // Basic tests. | 1166 // Basic tests. |
| 1252 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. | 1167 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. |
| 1253 | 1168 |
| 1254 int num_times_called = test_receiver_audio_callback_->number_times_called(); | 1169 EXPECT_EQ(num_audio_frames_requested, |
| 1255 EXPECT_EQ(num_audio_buses - 1, num_times_called); | 1170 test_receiver_audio_callback_->number_times_called()); |
| 1256 | 1171 |
| 1257 // Logging tests. | 1172 // Logging tests. |
| 1258 // Verify that all frames and all required events were logged. | 1173 // Verify that all frames and all required events were logged. |
| 1259 event_subscriber_sender_.GetFrameEventsAndReset(&frame_events_); | 1174 event_subscriber_sender_.GetFrameEventsAndReset(&frame_events_); |
| 1260 | 1175 |
| 1261 // Construct a map from each frame (RTP timestamp) to a count of each event | 1176 // Construct a map from each frame (RTP timestamp) to a count of each event |
| 1262 // type logged for that frame. | 1177 // type logged for that frame. |
| 1263 std::map<RtpTimestamp, LoggingEventCounts> event_counter_for_frame = | 1178 std::map<RtpTimestamp, LoggingEventCounts> event_counter_for_frame = |
| 1264 GetEventCountForFrameEvents(frame_events_); | 1179 GetEventCountForFrameEvents(frame_events_); |
| 1265 | 1180 |
| 1266 int received_count = 0; | 1181 int received_count = 0; |
| 1267 int encoded_count = 0; | 1182 int encoded_count = 0; |
| 1268 | 1183 |
| 1269 // Verify the right number of events were logged for each event type. | 1184 // Verify the right number of events were logged for each event type. |
| 1270 for (std::map<RtpTimestamp, LoggingEventCounts>::iterator it = | 1185 for (std::map<RtpTimestamp, LoggingEventCounts>::iterator it = |
| 1271 event_counter_for_frame.begin(); | 1186 event_counter_for_frame.begin(); |
| 1272 it != event_counter_for_frame.end(); | 1187 it != event_counter_for_frame.end(); |
| 1273 ++it) { | 1188 ++it) { |
| 1274 received_count += it->second.counter[kAudioFrameReceived]; | 1189 received_count += it->second.counter[kAudioFrameReceived]; |
| 1275 encoded_count += it->second.counter[kAudioFrameEncoded]; | 1190 encoded_count += it->second.counter[kAudioFrameEncoded]; |
| 1276 } | 1191 } |
| 1277 | 1192 |
| 1278 EXPECT_EQ(num_frames, received_count); | 1193 EXPECT_EQ(num_audio_frames_requested, received_count); |
| 1279 EXPECT_EQ(num_frames, encoded_count); | 1194 EXPECT_EQ(num_audio_frames_requested, encoded_count); |
| 1280 | 1195 |
| 1281 std::map<RtpTimestamp, LoggingEventCounts>::iterator map_it = | 1196 std::map<RtpTimestamp, LoggingEventCounts>::iterator map_it = |
| 1282 event_counter_for_frame.begin(); | 1197 event_counter_for_frame.begin(); |
| 1283 | 1198 |
| 1284 // Verify that each frame have the expected types of events logged. | 1199 // Verify that each frame have the expected types of events logged. |
| 1285 // TODO(imcheng): This only checks the first frame. This doesn't work | 1200 // TODO(imcheng): This only checks the first frame. This doesn't work |
| 1286 // properly for all frames because: | 1201 // properly for all frames because: |
| 1287 // 1. kAudioPlayoutDelay and kAudioFrameDecoded RTP timestamps aren't | 1202 // 1. kAudioPlayoutDelay and kAudioFrameDecoded RTP timestamps aren't |
| 1288 // exactly aligned with those of kAudioFrameReceived and kAudioFrameEncoded. | 1203 // exactly aligned with those of kAudioFrameReceived and kAudioFrameEncoded. |
| 1289 // Note that these RTP timestamps are output from webrtc::AudioCodingModule | 1204 // Note that these RTP timestamps are output from webrtc::AudioCodingModule |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1320 EXPECT_EQ(total_event_count_for_frame, expected_event_count_for_frame); | 1235 EXPECT_EQ(total_event_count_for_frame, expected_event_count_for_frame); |
| 1321 } | 1236 } |
| 1322 | 1237 |
| 1323 // TODO(pwestin): Add repeatable packet loss test. | 1238 // TODO(pwestin): Add repeatable packet loss test. |
| 1324 // TODO(pwestin): Add test for misaligned send get calls. | 1239 // TODO(pwestin): Add test for misaligned send get calls. |
| 1325 // TODO(pwestin): Add more tests that does not resample. | 1240 // TODO(pwestin): Add more tests that does not resample. |
| 1326 // TODO(pwestin): Add test when we have starvation for our RunTask. | 1241 // TODO(pwestin): Add test when we have starvation for our RunTask. |
| 1327 | 1242 |
| 1328 } // namespace cast | 1243 } // namespace cast |
| 1329 } // namespace media | 1244 } // namespace media |
| OLD | NEW |