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 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 static const int kVideoQcifWidth = 176; | 56 static const int kVideoQcifWidth = 176; |
57 static const int kVideoQcifHeight = 144; | 57 static const int kVideoQcifHeight = 144; |
58 | 58 |
59 // Since the video encoded and decoded an error will be introduced; when | 59 // Since the video encoded and decoded an error will be introduced; when |
60 // comparing individual pixels the error can be quite large; we allow a PSNR of | 60 // comparing individual pixels the error can be quite large; we allow a PSNR of |
61 // at least |kVideoAcceptedPSNR|. | 61 // at least |kVideoAcceptedPSNR|. |
62 static const double kVideoAcceptedPSNR = 38.0; | 62 static const double kVideoAcceptedPSNR = 38.0; |
63 | 63 |
64 // The tests are commonly implemented with |kFrameTimerMs| RunTask function; | 64 // The tests are commonly implemented with |kFrameTimerMs| RunTask function; |
65 // a normal video is 30 fps hence the 33 ms between frames. | 65 // a normal video is 30 fps hence the 33 ms between frames. |
| 66 // |
| 67 // TODO(miu): The errors in timing will add up significantly. Find an |
| 68 // alternative approach that eliminates use of this constant. |
66 static const int kFrameTimerMs = 33; | 69 static const int kFrameTimerMs = 33; |
67 | 70 |
68 // The packets pass through the pacer which can delay the beginning of the | |
69 // frame by 10 ms if there is packets belonging to the previous frame being | |
70 // retransmitted. | |
71 // In addition, audio packets are sent in 10mS intervals in audio_encoder.cc, | |
72 // although we send an audio frame every 33mS, which adds an extra delay. | |
73 // A TODO was added in the code to resolve this. | |
74 static const int kTimerErrorMs = 20; | |
75 | |
76 // Start the video synthetic start value to medium range value, to avoid edge | 71 // Start the video synthetic start value to medium range value, to avoid edge |
77 // effects cause by encoding and quantization. | 72 // effects cause by encoding and quantization. |
78 static const int kVideoStart = 100; | 73 static const int kVideoStart = 100; |
79 | 74 |
80 // The size of audio frames. The encoder joins/breaks all inserted audio into | 75 // The size of audio frames. The encoder joins/breaks all inserted audio into |
81 // chunks of this size. | 76 // chunks of this size. |
82 static const int kAudioFrameDurationMs = 10; | 77 static const int kAudioFrameDurationMs = 10; |
83 | 78 |
| 79 // The amount of time between frame capture on the sender and playout on the |
| 80 // receiver. |
| 81 static const int kTargetPlayoutDelayMs = 100; |
| 82 |
| 83 // The maximum amount of deviation expected in the playout times emitted by the |
| 84 // receiver. |
| 85 static const int kMaxAllowedPlayoutErrorMs = 30; |
| 86 |
84 std::string ConvertFromBase16String(const std::string base_16) { | 87 std::string ConvertFromBase16String(const std::string base_16) { |
85 std::string compressed; | 88 std::string compressed; |
86 DCHECK_EQ(base_16.size() % 2, 0u) << "Must be a multiple of 2"; | 89 DCHECK_EQ(base_16.size() % 2, 0u) << "Must be a multiple of 2"; |
87 compressed.reserve(base_16.size() / 2); | 90 compressed.reserve(base_16.size() / 2); |
88 | 91 |
89 std::vector<uint8> v; | 92 std::vector<uint8> v; |
90 if (!base::HexStringToBytes(base_16, &v)) { | 93 if (!base::HexStringToBytes(base_16, &v)) { |
91 NOTREACHED(); | 94 NOTREACHED(); |
92 } | 95 } |
93 compressed.assign(reinterpret_cast<const char*>(&v[0]), v.size()); | 96 compressed.assign(reinterpret_cast<const char*>(&v[0]), v.size()); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 scoped_refptr<CastEnvironment> cast_environment_; | 240 scoped_refptr<CastEnvironment> cast_environment_; |
238 scoped_ptr<test::PacketPipe> packet_pipe_; | 241 scoped_ptr<test::PacketPipe> packet_pipe_; |
239 }; | 242 }; |
240 | 243 |
241 // Class that verifies the audio frames coming out of the receiver. | 244 // Class that verifies the audio frames coming out of the receiver. |
242 class TestReceiverAudioCallback | 245 class TestReceiverAudioCallback |
243 : public base::RefCountedThreadSafe<TestReceiverAudioCallback> { | 246 : public base::RefCountedThreadSafe<TestReceiverAudioCallback> { |
244 public: | 247 public: |
245 struct ExpectedAudioFrame { | 248 struct ExpectedAudioFrame { |
246 scoped_ptr<AudioBus> audio_bus; | 249 scoped_ptr<AudioBus> audio_bus; |
247 base::TimeTicks record_time; | 250 base::TimeTicks playout_time; |
248 }; | 251 }; |
249 | 252 |
250 TestReceiverAudioCallback() : num_called_(0) {} | 253 TestReceiverAudioCallback() : num_called_(0) {} |
251 | 254 |
252 void SetExpectedSamplingFrequency(int expected_sampling_frequency) { | 255 void SetExpectedSamplingFrequency(int expected_sampling_frequency) { |
253 expected_sampling_frequency_ = expected_sampling_frequency; | 256 expected_sampling_frequency_ = expected_sampling_frequency; |
254 } | 257 } |
255 | 258 |
256 void AddExpectedResult(const AudioBus& audio_bus, | 259 void AddExpectedResult(const AudioBus& audio_bus, |
257 const base::TimeTicks& record_time) { | 260 const base::TimeTicks& playout_time) { |
258 scoped_ptr<ExpectedAudioFrame> expected_audio_frame( | 261 scoped_ptr<ExpectedAudioFrame> expected_audio_frame( |
259 new ExpectedAudioFrame()); | 262 new ExpectedAudioFrame()); |
260 expected_audio_frame->audio_bus = | 263 expected_audio_frame->audio_bus = |
261 AudioBus::Create(audio_bus.channels(), audio_bus.frames()).Pass(); | 264 AudioBus::Create(audio_bus.channels(), audio_bus.frames()).Pass(); |
262 audio_bus.CopyTo(expected_audio_frame->audio_bus.get()); | 265 audio_bus.CopyTo(expected_audio_frame->audio_bus.get()); |
263 expected_audio_frame->record_time = record_time; | 266 expected_audio_frame->playout_time = playout_time; |
264 expected_frames_.push_back(expected_audio_frame.release()); | 267 expected_frames_.push_back(expected_audio_frame.release()); |
265 } | 268 } |
266 | 269 |
267 void IgnoreAudioFrame(scoped_ptr<AudioBus> audio_bus, | 270 void IgnoreAudioFrame(scoped_ptr<AudioBus> audio_bus, |
268 const base::TimeTicks& playout_time, | 271 const base::TimeTicks& playout_time, |
269 bool is_continuous) { | 272 bool is_continuous) { |
270 ++num_called_; | 273 ++num_called_; |
271 } | 274 } |
272 | 275 |
273 void CheckAudioFrame(scoped_ptr<AudioBus> audio_bus, | 276 void CheckAudioFrame(scoped_ptr<AudioBus> audio_bus, |
(...skipping 11 matching lines...) Expand all Loading... |
285 EXPECT_EQ(audio_bus->frames(), expected_audio_frame->audio_bus->frames()); | 288 EXPECT_EQ(audio_bus->frames(), expected_audio_frame->audio_bus->frames()); |
286 for (int ch = 0; ch < audio_bus->channels(); ++ch) { | 289 for (int ch = 0; ch < audio_bus->channels(); ++ch) { |
287 EXPECT_NEAR(CountZeroCrossings( | 290 EXPECT_NEAR(CountZeroCrossings( |
288 expected_audio_frame->audio_bus->channel(ch), | 291 expected_audio_frame->audio_bus->channel(ch), |
289 expected_audio_frame->audio_bus->frames()), | 292 expected_audio_frame->audio_bus->frames()), |
290 CountZeroCrossings(audio_bus->channel(ch), | 293 CountZeroCrossings(audio_bus->channel(ch), |
291 audio_bus->frames()), | 294 audio_bus->frames()), |
292 1); | 295 1); |
293 } | 296 } |
294 | 297 |
295 // TODO(miu): This is a "fuzzy" way to check the timestamps. We should be | 298 EXPECT_NEAR( |
296 // able to compute exact offsets with "omnipotent" knowledge of the system. | 299 (playout_time - expected_audio_frame->playout_time).InMillisecondsF(), |
297 const base::TimeTicks upper_bound = | 300 0.0, |
298 expected_audio_frame->record_time + | 301 kMaxAllowedPlayoutErrorMs); |
299 base::TimeDelta::FromMilliseconds(kDefaultRtpMaxDelayMs + | 302 VLOG_IF(1, !last_playout_time_.is_null()) |
300 kTimerErrorMs); | 303 << "Audio frame playout time delta (compared to last frame) is " |
301 EXPECT_GE(upper_bound, playout_time) | 304 << (playout_time - last_playout_time_).InMicroseconds() << " usec."; |
302 << "playout_time - upper_bound == " | 305 last_playout_time_ = playout_time; |
303 << (playout_time - upper_bound).InMicroseconds() << " usec"; | |
304 | 306 |
305 EXPECT_TRUE(is_continuous); | 307 EXPECT_TRUE(is_continuous); |
306 } | 308 } |
307 | 309 |
308 void CheckCodedAudioFrame(scoped_ptr<transport::EncodedFrame> audio_frame) { | 310 void CheckCodedAudioFrame(scoped_ptr<transport::EncodedFrame> audio_frame) { |
309 ASSERT_TRUE(!!audio_frame); | 311 ASSERT_TRUE(!!audio_frame); |
310 ASSERT_FALSE(expected_frames_.empty()); | 312 ASSERT_FALSE(expected_frames_.empty()); |
311 const ExpectedAudioFrame& expected_audio_frame = | 313 const ExpectedAudioFrame& expected_audio_frame = |
312 *(expected_frames_.front()); | 314 *(expected_frames_.front()); |
313 // Note: Just peeking here. Will delegate to CheckAudioFrame() to pop. | 315 // Note: Just peeking here. Will delegate to CheckAudioFrame() to pop. |
(...skipping 24 matching lines...) Expand all Loading... |
338 virtual ~TestReceiverAudioCallback() { | 340 virtual ~TestReceiverAudioCallback() { |
339 STLDeleteElements(&expected_frames_); | 341 STLDeleteElements(&expected_frames_); |
340 } | 342 } |
341 | 343 |
342 private: | 344 private: |
343 friend class base::RefCountedThreadSafe<TestReceiverAudioCallback>; | 345 friend class base::RefCountedThreadSafe<TestReceiverAudioCallback>; |
344 | 346 |
345 int num_called_; | 347 int num_called_; |
346 int expected_sampling_frequency_; | 348 int expected_sampling_frequency_; |
347 std::list<ExpectedAudioFrame*> expected_frames_; | 349 std::list<ExpectedAudioFrame*> expected_frames_; |
| 350 base::TimeTicks last_playout_time_; |
348 }; | 351 }; |
349 | 352 |
350 // Class that verifies the video frames coming out of the receiver. | 353 // Class that verifies the video frames coming out of the receiver. |
351 class TestReceiverVideoCallback | 354 class TestReceiverVideoCallback |
352 : public base::RefCountedThreadSafe<TestReceiverVideoCallback> { | 355 : public base::RefCountedThreadSafe<TestReceiverVideoCallback> { |
353 public: | 356 public: |
354 struct ExpectedVideoFrame { | 357 struct ExpectedVideoFrame { |
355 int start_value; | 358 int start_value; |
356 int width; | 359 int width; |
357 int height; | 360 int height; |
358 base::TimeTicks capture_time; | 361 base::TimeTicks playout_time; |
359 bool should_be_continuous; | 362 bool should_be_continuous; |
360 }; | 363 }; |
361 | 364 |
362 TestReceiverVideoCallback() : num_called_(0) {} | 365 TestReceiverVideoCallback() : num_called_(0) {} |
363 | 366 |
364 void AddExpectedResult(int start_value, | 367 void AddExpectedResult(int start_value, |
365 int width, | 368 int width, |
366 int height, | 369 int height, |
367 const base::TimeTicks& capture_time, | 370 const base::TimeTicks& playout_time, |
368 bool should_be_continuous) { | 371 bool should_be_continuous) { |
369 ExpectedVideoFrame expected_video_frame; | 372 ExpectedVideoFrame expected_video_frame; |
370 expected_video_frame.start_value = start_value; | 373 expected_video_frame.start_value = start_value; |
371 expected_video_frame.width = width; | 374 expected_video_frame.width = width; |
372 expected_video_frame.height = height; | 375 expected_video_frame.height = height; |
373 expected_video_frame.capture_time = capture_time; | 376 expected_video_frame.playout_time = playout_time; |
374 expected_video_frame.should_be_continuous = should_be_continuous; | 377 expected_video_frame.should_be_continuous = should_be_continuous; |
375 expected_frame_.push_back(expected_video_frame); | 378 expected_frame_.push_back(expected_video_frame); |
376 } | 379 } |
377 | 380 |
378 void CheckVideoFrame(const scoped_refptr<media::VideoFrame>& video_frame, | 381 void CheckVideoFrame(const scoped_refptr<media::VideoFrame>& video_frame, |
379 const base::TimeTicks& render_time, | 382 const base::TimeTicks& playout_time, |
380 bool is_continuous) { | 383 bool is_continuous) { |
381 ++num_called_; | 384 ++num_called_; |
382 | 385 |
383 ASSERT_TRUE(!!video_frame); | 386 ASSERT_TRUE(!!video_frame); |
384 ASSERT_FALSE(expected_frame_.empty()); | 387 ASSERT_FALSE(expected_frame_.empty()); |
385 ExpectedVideoFrame expected_video_frame = expected_frame_.front(); | 388 ExpectedVideoFrame expected_video_frame = expected_frame_.front(); |
386 expected_frame_.pop_front(); | 389 expected_frame_.pop_front(); |
387 | 390 |
388 base::TimeDelta time_since_capture = | |
389 render_time - expected_video_frame.capture_time; | |
390 const base::TimeDelta upper_bound = base::TimeDelta::FromMilliseconds( | |
391 kDefaultRtpMaxDelayMs + kTimerErrorMs); | |
392 | |
393 // TODO(miu): This is a "fuzzy" way to check the timestamps. We should be | |
394 // able to compute exact offsets with "omnipotent" knowledge of the system. | |
395 EXPECT_GE(upper_bound, time_since_capture) | |
396 << "time_since_capture - upper_bound == " | |
397 << (time_since_capture - upper_bound).InMicroseconds() << " usec"; | |
398 // TODO(miu): I broke the concept of 100 ms target delay timing on the | |
399 // receiver side, but the logic for computing playout time really isn't any | |
400 // more broken than it was. This only affects the receiver, and is to be | |
401 // rectified in an soon-upcoming change. http://crbug.com/356942 | |
402 // EXPECT_LE(expected_video_frame.capture_time, render_time); | |
403 EXPECT_EQ(expected_video_frame.width, video_frame->visible_rect().width()); | 391 EXPECT_EQ(expected_video_frame.width, video_frame->visible_rect().width()); |
404 EXPECT_EQ(expected_video_frame.height, | 392 EXPECT_EQ(expected_video_frame.height, |
405 video_frame->visible_rect().height()); | 393 video_frame->visible_rect().height()); |
406 | 394 |
407 gfx::Size size(expected_video_frame.width, expected_video_frame.height); | 395 gfx::Size size(expected_video_frame.width, expected_video_frame.height); |
408 scoped_refptr<media::VideoFrame> expected_I420_frame = | 396 scoped_refptr<media::VideoFrame> expected_I420_frame = |
409 media::VideoFrame::CreateFrame( | 397 media::VideoFrame::CreateFrame( |
410 VideoFrame::I420, size, gfx::Rect(size), size, base::TimeDelta()); | 398 VideoFrame::I420, size, gfx::Rect(size), size, base::TimeDelta()); |
411 PopulateVideoFrame(expected_I420_frame, expected_video_frame.start_value); | 399 PopulateVideoFrame(expected_I420_frame, expected_video_frame.start_value); |
412 | 400 |
413 EXPECT_GE(I420PSNR(expected_I420_frame, video_frame), kVideoAcceptedPSNR); | 401 EXPECT_GE(I420PSNR(expected_I420_frame, video_frame), kVideoAcceptedPSNR); |
414 | 402 |
| 403 EXPECT_NEAR( |
| 404 (playout_time - expected_video_frame.playout_time).InMillisecondsF(), |
| 405 0.0, |
| 406 kMaxAllowedPlayoutErrorMs); |
| 407 VLOG_IF(1, !last_playout_time_.is_null()) |
| 408 << "Video frame playout time delta (compared to last frame) is " |
| 409 << (playout_time - last_playout_time_).InMicroseconds() << " usec."; |
| 410 last_playout_time_ = playout_time; |
| 411 |
415 EXPECT_EQ(expected_video_frame.should_be_continuous, is_continuous); | 412 EXPECT_EQ(expected_video_frame.should_be_continuous, is_continuous); |
416 } | 413 } |
417 | 414 |
418 int number_times_called() const { return num_called_; } | 415 int number_times_called() const { return num_called_; } |
419 | 416 |
420 protected: | 417 protected: |
421 virtual ~TestReceiverVideoCallback() {} | 418 virtual ~TestReceiverVideoCallback() {} |
422 | 419 |
423 private: | 420 private: |
424 friend class base::RefCountedThreadSafe<TestReceiverVideoCallback>; | 421 friend class base::RefCountedThreadSafe<TestReceiverVideoCallback>; |
425 | 422 |
426 int num_called_; | 423 int num_called_; |
427 std::list<ExpectedVideoFrame> expected_frame_; | 424 std::list<ExpectedVideoFrame> expected_frame_; |
| 425 base::TimeTicks last_playout_time_; |
428 }; | 426 }; |
429 | 427 |
430 // The actual test class, generate synthetic data for both audio and video and | 428 // The actual test class, generate synthetic data for both audio and video and |
431 // send those through the sender and receiver and analyzes the result. | 429 // send those through the sender and receiver and analyzes the result. |
432 class End2EndTest : public ::testing::Test { | 430 class End2EndTest : public ::testing::Test { |
433 protected: | 431 protected: |
434 End2EndTest() | 432 End2EndTest() |
435 : start_time_(), | 433 : start_time_(), |
436 task_runner_(new test::FakeSingleThreadTaskRunner(&testing_clock_)), | 434 task_runner_(new test::FakeSingleThreadTaskRunner(&testing_clock_)), |
437 testing_clock_sender_(new test::SkewedTickClock(&testing_clock_)), | 435 testing_clock_sender_(new test::SkewedTickClock(&testing_clock_)), |
(...skipping 21 matching lines...) Expand all Loading... |
459 cast_environment_sender_->Logging()->AddRawEventSubscriber( | 457 cast_environment_sender_->Logging()->AddRawEventSubscriber( |
460 &event_subscriber_sender_); | 458 &event_subscriber_sender_); |
461 } | 459 } |
462 | 460 |
463 void Configure(transport::VideoCodec video_codec, | 461 void Configure(transport::VideoCodec video_codec, |
464 transport::AudioCodec audio_codec, | 462 transport::AudioCodec audio_codec, |
465 int audio_sampling_frequency, | 463 int audio_sampling_frequency, |
466 bool external_audio_decoder, | 464 bool external_audio_decoder, |
467 int max_number_of_video_buffers_used) { | 465 int max_number_of_video_buffers_used) { |
468 audio_sender_config_.rtp_config.ssrc = 1; | 466 audio_sender_config_.rtp_config.ssrc = 1; |
| 467 audio_sender_config_.rtp_config.max_delay_ms = kTargetPlayoutDelayMs; |
469 audio_sender_config_.incoming_feedback_ssrc = 2; | 468 audio_sender_config_.incoming_feedback_ssrc = 2; |
470 audio_sender_config_.rtp_config.payload_type = 96; | 469 audio_sender_config_.rtp_config.payload_type = 96; |
471 audio_sender_config_.use_external_encoder = false; | 470 audio_sender_config_.use_external_encoder = false; |
472 audio_sender_config_.frequency = audio_sampling_frequency; | 471 audio_sender_config_.frequency = audio_sampling_frequency; |
473 audio_sender_config_.channels = kAudioChannels; | 472 audio_sender_config_.channels = kAudioChannels; |
474 audio_sender_config_.bitrate = kDefaultAudioEncoderBitrate; | 473 audio_sender_config_.bitrate = kDefaultAudioEncoderBitrate; |
475 audio_sender_config_.codec = audio_codec; | 474 audio_sender_config_.codec = audio_codec; |
476 | 475 |
477 audio_receiver_config_.feedback_ssrc = | 476 audio_receiver_config_.feedback_ssrc = |
478 audio_sender_config_.incoming_feedback_ssrc; | 477 audio_sender_config_.incoming_feedback_ssrc; |
479 audio_receiver_config_.incoming_ssrc = audio_sender_config_.rtp_config.ssrc; | 478 audio_receiver_config_.incoming_ssrc = audio_sender_config_.rtp_config.ssrc; |
| 479 audio_receiver_config_.rtp_max_delay_ms = kTargetPlayoutDelayMs; |
480 audio_receiver_config_.rtp_payload_type = | 480 audio_receiver_config_.rtp_payload_type = |
481 audio_sender_config_.rtp_config.payload_type; | 481 audio_sender_config_.rtp_config.payload_type; |
482 audio_receiver_config_.use_external_decoder = external_audio_decoder; | 482 audio_receiver_config_.use_external_decoder = external_audio_decoder; |
483 audio_receiver_config_.frequency = audio_sender_config_.frequency; | 483 audio_receiver_config_.frequency = audio_sender_config_.frequency; |
484 audio_receiver_config_.channels = kAudioChannels; | 484 audio_receiver_config_.channels = kAudioChannels; |
485 audio_receiver_config_.codec = audio_sender_config_.codec; | 485 audio_receiver_config_.codec = audio_sender_config_.codec; |
486 | 486 |
487 test_receiver_audio_callback_->SetExpectedSamplingFrequency( | 487 test_receiver_audio_callback_->SetExpectedSamplingFrequency( |
488 audio_receiver_config_.frequency); | 488 audio_receiver_config_.frequency); |
489 | 489 |
490 video_sender_config_.rtp_config.ssrc = 3; | 490 video_sender_config_.rtp_config.ssrc = 3; |
| 491 video_sender_config_.rtp_config.max_delay_ms = kTargetPlayoutDelayMs; |
491 video_sender_config_.incoming_feedback_ssrc = 4; | 492 video_sender_config_.incoming_feedback_ssrc = 4; |
492 video_sender_config_.rtp_config.payload_type = 97; | 493 video_sender_config_.rtp_config.payload_type = 97; |
493 video_sender_config_.use_external_encoder = false; | 494 video_sender_config_.use_external_encoder = false; |
494 video_sender_config_.width = kVideoHdWidth; | 495 video_sender_config_.width = kVideoHdWidth; |
495 video_sender_config_.height = kVideoHdHeight; | 496 video_sender_config_.height = kVideoHdHeight; |
496 video_sender_config_.max_bitrate = 50000; | 497 video_sender_config_.max_bitrate = 50000; |
497 video_sender_config_.min_bitrate = 10000; | 498 video_sender_config_.min_bitrate = 10000; |
498 video_sender_config_.start_bitrate = 10000; | 499 video_sender_config_.start_bitrate = 10000; |
499 video_sender_config_.max_qp = 30; | 500 video_sender_config_.max_qp = 30; |
500 video_sender_config_.min_qp = 4; | 501 video_sender_config_.min_qp = 4; |
501 video_sender_config_.max_frame_rate = 30; | 502 video_sender_config_.max_frame_rate = 30; |
502 video_sender_config_.max_number_of_video_buffers_used = | 503 video_sender_config_.max_number_of_video_buffers_used = |
503 max_number_of_video_buffers_used; | 504 max_number_of_video_buffers_used; |
504 video_sender_config_.codec = video_codec; | 505 video_sender_config_.codec = video_codec; |
505 | 506 |
506 video_receiver_config_.feedback_ssrc = | 507 video_receiver_config_.feedback_ssrc = |
507 video_sender_config_.incoming_feedback_ssrc; | 508 video_sender_config_.incoming_feedback_ssrc; |
508 video_receiver_config_.incoming_ssrc = video_sender_config_.rtp_config.ssrc; | 509 video_receiver_config_.incoming_ssrc = video_sender_config_.rtp_config.ssrc; |
| 510 video_receiver_config_.rtp_max_delay_ms = kTargetPlayoutDelayMs; |
509 video_receiver_config_.rtp_payload_type = | 511 video_receiver_config_.rtp_payload_type = |
510 video_sender_config_.rtp_config.payload_type; | 512 video_sender_config_.rtp_config.payload_type; |
511 video_receiver_config_.use_external_decoder = false; | 513 video_receiver_config_.use_external_decoder = false; |
512 video_receiver_config_.codec = video_sender_config_.codec; | 514 video_receiver_config_.codec = video_sender_config_.codec; |
513 } | 515 } |
514 | 516 |
515 void SetSenderSkew(double skew, base::TimeDelta offset) { | |
516 testing_clock_sender_->SetSkew(skew, offset); | |
517 task_runner_sender_->SetSkew(1.0 / skew); | |
518 } | |
519 | |
520 void SetReceiverSkew(double skew, base::TimeDelta offset) { | 517 void SetReceiverSkew(double skew, base::TimeDelta offset) { |
521 testing_clock_receiver_->SetSkew(skew, offset); | 518 testing_clock_receiver_->SetSkew(skew, offset); |
522 task_runner_receiver_->SetSkew(1.0 / skew); | 519 task_runner_receiver_->SetSkew(1.0 / skew); |
523 } | 520 } |
524 | 521 |
| 522 // Specify the minimum/maximum difference in playout times between two |
| 523 // consecutive frames. Also, specify the maximum absolute rate of change over |
| 524 // each three consecutive frames. |
| 525 void SetExpectedVideoPlayoutSmoothness(base::TimeDelta min_delta, |
| 526 base::TimeDelta max_delta, |
| 527 base::TimeDelta max_curvature) { |
| 528 min_video_playout_delta_ = min_delta; |
| 529 max_video_playout_delta_ = max_delta; |
| 530 max_video_playout_curvature_ = max_curvature; |
| 531 } |
| 532 |
525 void FeedAudioFrames(int count, bool will_be_checked) { | 533 void FeedAudioFrames(int count, bool will_be_checked) { |
526 for (int i = 0; i < count; ++i) { | 534 for (int i = 0; i < count; ++i) { |
527 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | 535 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( |
528 base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs))); | 536 base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs))); |
529 const base::TimeTicks send_time = | 537 const base::TimeTicks capture_time = |
530 testing_clock_sender_->NowTicks() + | 538 testing_clock_sender_->NowTicks() + |
531 i * base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs); | 539 i * base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs); |
532 if (will_be_checked) | 540 if (will_be_checked) { |
533 test_receiver_audio_callback_->AddExpectedResult(*audio_bus, send_time); | 541 test_receiver_audio_callback_->AddExpectedResult( |
534 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); | 542 *audio_bus, |
| 543 capture_time + |
| 544 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs)); |
| 545 } |
| 546 audio_frame_input_->InsertAudio(audio_bus.Pass(), capture_time); |
535 } | 547 } |
536 } | 548 } |
537 | 549 |
538 void FeedAudioFramesWithExpectedDelay(int count, | 550 void FeedAudioFramesWithExpectedDelay(int count, |
539 const base::TimeDelta& delay) { | 551 const base::TimeDelta& delay) { |
540 for (int i = 0; i < count; ++i) { | 552 for (int i = 0; i < count; ++i) { |
541 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | 553 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( |
542 base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs))); | 554 base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs))); |
543 const base::TimeTicks send_time = | 555 const base::TimeTicks capture_time = |
544 testing_clock_sender_->NowTicks() + | 556 testing_clock_sender_->NowTicks() + |
545 i * base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs); | 557 i * base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs); |
546 test_receiver_audio_callback_->AddExpectedResult(*audio_bus, | 558 test_receiver_audio_callback_->AddExpectedResult( |
547 send_time + delay); | 559 *audio_bus, |
548 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time); | 560 capture_time + delay + |
| 561 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs)); |
| 562 audio_frame_input_->InsertAudio(audio_bus.Pass(), capture_time); |
549 } | 563 } |
550 } | 564 } |
551 | 565 |
552 void RequestAudioFrames(int count, bool with_check) { | 566 void RequestAudioFrames(int count, bool with_check) { |
553 for (int i = 0; i < count; ++i) { | 567 for (int i = 0; i < count; ++i) { |
554 frame_receiver_->GetRawAudioFrame( | 568 frame_receiver_->GetRawAudioFrame( |
555 base::Bind(with_check ? &TestReceiverAudioCallback::CheckAudioFrame : | 569 base::Bind(with_check ? &TestReceiverAudioCallback::CheckAudioFrame : |
556 &TestReceiverAudioCallback::IgnoreAudioFrame, | 570 &TestReceiverAudioCallback::IgnoreAudioFrame, |
557 test_receiver_audio_callback_)); | 571 test_receiver_audio_callback_)); |
558 } | 572 } |
559 } | 573 } |
560 | 574 |
561 void Create() { | 575 void Create() { |
562 cast_receiver_ = CastReceiver::Create(cast_environment_receiver_, | 576 cast_receiver_ = CastReceiver::Create(cast_environment_receiver_, |
563 audio_receiver_config_, | 577 audio_receiver_config_, |
564 video_receiver_config_, | 578 video_receiver_config_, |
565 &receiver_to_sender_); | 579 &receiver_to_sender_); |
| 580 |
566 net::IPEndPoint dummy_endpoint; | 581 net::IPEndPoint dummy_endpoint; |
567 transport_sender_.reset(new transport::CastTransportSenderImpl( | 582 transport_sender_.reset(new transport::CastTransportSenderImpl( |
568 NULL, | 583 NULL, |
569 testing_clock_sender_, | 584 testing_clock_sender_, |
570 dummy_endpoint, | 585 dummy_endpoint, |
571 base::Bind(&UpdateCastTransportStatus), | 586 base::Bind(&UpdateCastTransportStatus), |
572 base::Bind(&End2EndTest::LogRawEvents, base::Unretained(this)), | 587 base::Bind(&End2EndTest::LogRawEvents, base::Unretained(this)), |
573 base::TimeDelta::FromSeconds(1), | 588 base::TimeDelta::FromSeconds(1), |
574 task_runner_sender_, | 589 task_runner_sender_, |
575 &sender_to_receiver_)); | 590 &sender_to_receiver_)); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 video_frame_input_->InsertRawVideoFrame( | 648 video_frame_input_->InsertRawVideoFrame( |
634 media::VideoFrame::CreateBlackFrame(gfx::Size(2, 2)), capture_time); | 649 media::VideoFrame::CreateBlackFrame(gfx::Size(2, 2)), capture_time); |
635 } | 650 } |
636 | 651 |
637 void RunTasks(int ms) { | 652 void RunTasks(int ms) { |
638 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(ms)); | 653 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(ms)); |
639 } | 654 } |
640 | 655 |
641 void BasicPlayerGotVideoFrame( | 656 void BasicPlayerGotVideoFrame( |
642 const scoped_refptr<media::VideoFrame>& video_frame, | 657 const scoped_refptr<media::VideoFrame>& video_frame, |
643 const base::TimeTicks& render_time, bool continuous) { | 658 const base::TimeTicks& playout_time, bool continuous) { |
| 659 // The following tests that the sender and receiver clocks can be |
| 660 // out-of-sync, drift, and jitter with respect to one another; and depsite |
| 661 // this, the receiver will produce smoothly-progressing playout times. |
| 662 // Both first-order and second-order effects are tested. |
| 663 if (!last_video_playout_time_.is_null() && |
| 664 min_video_playout_delta_ > base::TimeDelta()) { |
| 665 const base::TimeDelta delta = playout_time - last_video_playout_time_; |
| 666 VLOG(1) << "Video frame playout time delta (compared to last frame) is " |
| 667 << delta.InMicroseconds() << " usec."; |
| 668 EXPECT_LE(min_video_playout_delta_.InMicroseconds(), |
| 669 delta.InMicroseconds()); |
| 670 EXPECT_GE(max_video_playout_delta_.InMicroseconds(), |
| 671 delta.InMicroseconds()); |
| 672 if (last_video_playout_delta_ > base::TimeDelta()) { |
| 673 base::TimeDelta abs_curvature = delta - last_video_playout_delta_; |
| 674 if (abs_curvature < base::TimeDelta()) |
| 675 abs_curvature = -abs_curvature; |
| 676 EXPECT_GE(max_video_playout_curvature_.InMicroseconds(), |
| 677 abs_curvature.InMicroseconds()); |
| 678 } |
| 679 last_video_playout_delta_ = delta; |
| 680 } |
| 681 last_video_playout_time_ = playout_time; |
| 682 |
644 video_ticks_.push_back(std::make_pair( | 683 video_ticks_.push_back(std::make_pair( |
645 testing_clock_receiver_->NowTicks(), | 684 testing_clock_receiver_->NowTicks(), |
646 render_time)); | 685 playout_time)); |
647 frame_receiver_->GetRawVideoFrame( | 686 frame_receiver_->GetRawVideoFrame( |
648 base::Bind(&End2EndTest::BasicPlayerGotVideoFrame, | 687 base::Bind(&End2EndTest::BasicPlayerGotVideoFrame, |
649 base::Unretained(this))); | 688 base::Unretained(this))); |
650 } | 689 } |
651 | 690 |
652 void BasicPlayerGotAudioFrame(scoped_ptr<AudioBus> audio_bus, | 691 void BasicPlayerGotAudioFrame(scoped_ptr<AudioBus> audio_bus, |
653 const base::TimeTicks& playout_time, | 692 const base::TimeTicks& playout_time, |
654 bool is_continuous) { | 693 bool is_continuous) { |
| 694 VLOG_IF(1, !last_audio_playout_time_.is_null()) |
| 695 << "Audio frame playout time delta (compared to last frame) is " |
| 696 << (playout_time - last_audio_playout_time_).InMicroseconds() |
| 697 << " usec."; |
| 698 last_audio_playout_time_ = playout_time; |
| 699 |
655 audio_ticks_.push_back(std::make_pair( | 700 audio_ticks_.push_back(std::make_pair( |
656 testing_clock_receiver_->NowTicks(), | 701 testing_clock_receiver_->NowTicks(), |
657 playout_time)); | 702 playout_time)); |
658 frame_receiver_->GetRawAudioFrame( | 703 frame_receiver_->GetRawAudioFrame( |
659 base::Bind(&End2EndTest::BasicPlayerGotAudioFrame, | 704 base::Bind(&End2EndTest::BasicPlayerGotAudioFrame, |
660 base::Unretained(this))); | 705 base::Unretained(this))); |
661 } | 706 } |
662 | 707 |
663 void StartBasicPlayer() { | 708 void StartBasicPlayer() { |
664 frame_receiver_->GetRawVideoFrame( | 709 frame_receiver_->GetRawVideoFrame( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 base::SimpleTestTickClock testing_clock_; | 742 base::SimpleTestTickClock testing_clock_; |
698 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; | 743 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; |
699 | 744 |
700 // These run on the sender timeline. | 745 // These run on the sender timeline. |
701 test::SkewedTickClock* testing_clock_sender_; | 746 test::SkewedTickClock* testing_clock_sender_; |
702 scoped_refptr<test::SkewedSingleThreadTaskRunner> task_runner_sender_; | 747 scoped_refptr<test::SkewedSingleThreadTaskRunner> task_runner_sender_; |
703 | 748 |
704 // These run on the receiver timeline. | 749 // These run on the receiver timeline. |
705 test::SkewedTickClock* testing_clock_receiver_; | 750 test::SkewedTickClock* testing_clock_receiver_; |
706 scoped_refptr<test::SkewedSingleThreadTaskRunner> task_runner_receiver_; | 751 scoped_refptr<test::SkewedSingleThreadTaskRunner> task_runner_receiver_; |
| 752 base::TimeDelta min_video_playout_delta_; |
| 753 base::TimeDelta max_video_playout_delta_; |
| 754 base::TimeDelta max_video_playout_curvature_; |
| 755 base::TimeTicks last_video_playout_time_; |
| 756 base::TimeDelta last_video_playout_delta_; |
| 757 base::TimeTicks last_audio_playout_time_; |
707 | 758 |
708 scoped_refptr<CastEnvironment> cast_environment_sender_; | 759 scoped_refptr<CastEnvironment> cast_environment_sender_; |
709 scoped_refptr<CastEnvironment> cast_environment_receiver_; | 760 scoped_refptr<CastEnvironment> cast_environment_receiver_; |
710 | 761 |
711 LoopBackTransport receiver_to_sender_; | 762 LoopBackTransport receiver_to_sender_; |
712 LoopBackTransport sender_to_receiver_; | 763 LoopBackTransport sender_to_receiver_; |
713 scoped_ptr<transport::CastTransportSenderImpl> transport_sender_; | 764 scoped_ptr<transport::CastTransportSenderImpl> transport_sender_; |
714 | 765 |
715 scoped_ptr<CastReceiver> cast_receiver_; | 766 scoped_ptr<CastReceiver> cast_receiver_; |
716 scoped_ptr<CastSender> cast_sender_; | 767 scoped_ptr<CastSender> cast_sender_; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
748 const int num_audio_frames = audio_diff / kAudioFrameDurationMs; | 799 const int num_audio_frames = audio_diff / kAudioFrameDurationMs; |
749 audio_diff -= num_audio_frames * kAudioFrameDurationMs; | 800 audio_diff -= num_audio_frames * kAudioFrameDurationMs; |
750 | 801 |
751 if (num_audio_frames > 0) | 802 if (num_audio_frames > 0) |
752 FeedAudioFrames(1, true); | 803 FeedAudioFrames(1, true); |
753 | 804 |
754 test_receiver_video_callback_->AddExpectedResult( | 805 test_receiver_video_callback_->AddExpectedResult( |
755 video_start, | 806 video_start, |
756 video_sender_config_.width, | 807 video_sender_config_.width, |
757 video_sender_config_.height, | 808 video_sender_config_.height, |
758 testing_clock_sender_->NowTicks(), | 809 testing_clock_sender_->NowTicks() + |
| 810 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs), |
759 true); | 811 true); |
760 SendVideoFrame(video_start, testing_clock_sender_->NowTicks()); | 812 SendVideoFrame(video_start, testing_clock_sender_->NowTicks()); |
761 | 813 |
762 if (num_audio_frames > 0) | 814 if (num_audio_frames > 0) |
763 RunTasks(kAudioFrameDurationMs); // Advance clock forward. | 815 RunTasks(kAudioFrameDurationMs); // Advance clock forward. |
764 if (num_audio_frames > 1) | 816 if (num_audio_frames > 1) |
765 FeedAudioFrames(num_audio_frames - 1, true); | 817 FeedAudioFrames(num_audio_frames - 1, true); |
766 | 818 |
767 RequestAudioFrames(num_audio_frames, true); | 819 RequestAudioFrames(num_audio_frames, true); |
768 num_audio_frames_requested += num_audio_frames; | 820 num_audio_frames_requested += num_audio_frames; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
853 if (num_audio_frames > 0) | 905 if (num_audio_frames > 0) |
854 FeedAudioFramesWithExpectedDelay(1, expected_delay); | 906 FeedAudioFramesWithExpectedDelay(1, expected_delay); |
855 | 907 |
856 // Frame will be rendered with 100mS delay, as the transmission is delayed. | 908 // Frame will be rendered with 100mS delay, as the transmission is delayed. |
857 // The receiver at this point cannot be synced to the sender's clock, as no | 909 // The receiver at this point cannot be synced to the sender's clock, as no |
858 // packets, and specifically no RTCP packets were sent. | 910 // packets, and specifically no RTCP packets were sent. |
859 test_receiver_video_callback_->AddExpectedResult( | 911 test_receiver_video_callback_->AddExpectedResult( |
860 video_start, | 912 video_start, |
861 video_sender_config_.width, | 913 video_sender_config_.width, |
862 video_sender_config_.height, | 914 video_sender_config_.height, |
863 initial_send_time + expected_delay, | 915 initial_send_time + expected_delay + |
| 916 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs), |
864 true); | 917 true); |
865 SendVideoFrame(video_start, testing_clock_sender_->NowTicks()); | 918 SendVideoFrame(video_start, testing_clock_sender_->NowTicks()); |
866 | 919 |
867 if (num_audio_frames > 0) | 920 if (num_audio_frames > 0) |
868 RunTasks(kAudioFrameDurationMs); // Advance clock forward. | 921 RunTasks(kAudioFrameDurationMs); // Advance clock forward. |
869 if (num_audio_frames > 1) | 922 if (num_audio_frames > 1) |
870 FeedAudioFramesWithExpectedDelay(num_audio_frames - 1, expected_delay); | 923 FeedAudioFramesWithExpectedDelay(num_audio_frames - 1, expected_delay); |
871 | 924 |
872 RunTasks(kFrameTimerMs - kAudioFrameDurationMs); | 925 RunTasks(kFrameTimerMs - kAudioFrameDurationMs); |
873 audio_diff += kFrameTimerMs; | 926 audio_diff += kFrameTimerMs; |
874 video_start++; | 927 video_start++; |
875 } | 928 } |
876 | 929 |
877 RunTasks(test_delay_ms); | 930 RunTasks(test_delay_ms); |
878 sender_to_receiver_.SetSendPackets(true); | 931 sender_to_receiver_.SetSendPackets(true); |
879 | 932 |
880 int num_audio_frames_requested = 0; | 933 int num_audio_frames_requested = 0; |
881 for (int j = 0; j < 10; ++j) { | 934 for (int j = 0; j < 10; ++j) { |
882 const int num_audio_frames = audio_diff / kAudioFrameDurationMs; | 935 const int num_audio_frames = audio_diff / kAudioFrameDurationMs; |
883 audio_diff -= num_audio_frames * kAudioFrameDurationMs; | 936 audio_diff -= num_audio_frames * kAudioFrameDurationMs; |
884 | 937 |
885 if (num_audio_frames > 0) | 938 if (num_audio_frames > 0) |
886 FeedAudioFrames(1, true); | 939 FeedAudioFrames(1, true); |
887 | 940 |
888 test_receiver_video_callback_->AddExpectedResult( | 941 test_receiver_video_callback_->AddExpectedResult( |
889 video_start, | 942 video_start, |
890 video_sender_config_.width, | 943 video_sender_config_.width, |
891 video_sender_config_.height, | 944 video_sender_config_.height, |
892 testing_clock_sender_->NowTicks(), | 945 testing_clock_sender_->NowTicks() + |
| 946 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs), |
893 true); | 947 true); |
894 SendVideoFrame(video_start, testing_clock_sender_->NowTicks()); | 948 SendVideoFrame(video_start, testing_clock_sender_->NowTicks()); |
895 | 949 |
896 if (num_audio_frames > 0) | 950 if (num_audio_frames > 0) |
897 RunTasks(kAudioFrameDurationMs); // Advance clock forward. | 951 RunTasks(kAudioFrameDurationMs); // Advance clock forward. |
898 if (num_audio_frames > 1) | 952 if (num_audio_frames > 1) |
899 FeedAudioFrames(num_audio_frames - 1, true); | 953 FeedAudioFrames(num_audio_frames - 1, true); |
900 | 954 |
901 RequestAudioFrames(num_audio_frames, true); | 955 RequestAudioFrames(num_audio_frames, true); |
902 num_audio_frames_requested += num_audio_frames; | 956 num_audio_frames_requested += num_audio_frames; |
(...skipping 15 matching lines...) Expand all Loading... |
918 // This tests a network glitch lasting for 10 video frames. | 972 // This tests a network glitch lasting for 10 video frames. |
919 // Flaky. See crbug.com/351596. | 973 // Flaky. See crbug.com/351596. |
920 TEST_F(End2EndTest, DISABLED_GlitchWith3Buffers) { | 974 TEST_F(End2EndTest, DISABLED_GlitchWith3Buffers) { |
921 Configure(transport::kVp8, transport::kOpus, kDefaultAudioSamplingRate, | 975 Configure(transport::kVp8, transport::kOpus, kDefaultAudioSamplingRate, |
922 false, 3); | 976 false, 3); |
923 video_sender_config_.rtp_config.max_delay_ms = 67; | 977 video_sender_config_.rtp_config.max_delay_ms = 67; |
924 video_receiver_config_.rtp_max_delay_ms = 67; | 978 video_receiver_config_.rtp_max_delay_ms = 67; |
925 Create(); | 979 Create(); |
926 | 980 |
927 int video_start = kVideoStart; | 981 int video_start = kVideoStart; |
928 base::TimeTicks send_time; | 982 base::TimeTicks capture_time; |
929 // Frames will rendered on completion until the render time stabilizes, i.e. | 983 // Frames will rendered on completion until the render time stabilizes, i.e. |
930 // we got enough data. | 984 // we got enough data. |
931 const int frames_before_glitch = 20; | 985 const int frames_before_glitch = 20; |
932 for (int i = 0; i < frames_before_glitch; ++i) { | 986 for (int i = 0; i < frames_before_glitch; ++i) { |
933 send_time = testing_clock_sender_->NowTicks(); | 987 capture_time = testing_clock_sender_->NowTicks(); |
934 SendVideoFrame(video_start, send_time); | 988 SendVideoFrame(video_start, capture_time); |
935 test_receiver_video_callback_->AddExpectedResult( | 989 test_receiver_video_callback_->AddExpectedResult( |
936 video_start, | 990 video_start, |
937 video_sender_config_.width, | 991 video_sender_config_.width, |
938 video_sender_config_.height, | 992 video_sender_config_.height, |
939 send_time, | 993 capture_time + base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs), |
940 true); | 994 true); |
941 frame_receiver_->GetRawVideoFrame( | 995 frame_receiver_->GetRawVideoFrame( |
942 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 996 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
943 test_receiver_video_callback_)); | 997 test_receiver_video_callback_)); |
944 RunTasks(kFrameTimerMs); | 998 RunTasks(kFrameTimerMs); |
945 video_start++; | 999 video_start++; |
946 } | 1000 } |
947 | 1001 |
948 // Introduce a glitch lasting for 10 frames. | 1002 // Introduce a glitch lasting for 10 frames. |
949 sender_to_receiver_.SetSendPackets(false); | 1003 sender_to_receiver_.SetSendPackets(false); |
950 for (int i = 0; i < 10; ++i) { | 1004 for (int i = 0; i < 10; ++i) { |
951 send_time = testing_clock_sender_->NowTicks(); | 1005 capture_time = testing_clock_sender_->NowTicks(); |
952 // First 3 will be sent and lost. | 1006 // First 3 will be sent and lost. |
953 SendVideoFrame(video_start, send_time); | 1007 SendVideoFrame(video_start, capture_time); |
954 RunTasks(kFrameTimerMs); | 1008 RunTasks(kFrameTimerMs); |
955 video_start++; | 1009 video_start++; |
956 } | 1010 } |
957 sender_to_receiver_.SetSendPackets(true); | 1011 sender_to_receiver_.SetSendPackets(true); |
958 RunTasks(100); | 1012 RunTasks(100); |
959 send_time = testing_clock_sender_->NowTicks(); | 1013 capture_time = testing_clock_sender_->NowTicks(); |
960 | 1014 |
961 // Frame 1 should be acked by now and we should have an opening to send 4. | 1015 // Frame 1 should be acked by now and we should have an opening to send 4. |
962 SendVideoFrame(video_start, send_time); | 1016 SendVideoFrame(video_start, capture_time); |
963 RunTasks(kFrameTimerMs); | 1017 RunTasks(kFrameTimerMs); |
964 | 1018 |
965 // Frames 1-3 are old frames by now, and therefore should be decoded, but | 1019 // Frames 1-3 are old frames by now, and therefore should be decoded, but |
966 // not rendered. The next frame we expect to render is frame #4. | 1020 // not rendered. The next frame we expect to render is frame #4. |
967 test_receiver_video_callback_->AddExpectedResult(video_start, | 1021 test_receiver_video_callback_->AddExpectedResult( |
968 video_sender_config_.width, | 1022 video_start, |
969 video_sender_config_.height, | 1023 video_sender_config_.width, |
970 send_time, | 1024 video_sender_config_.height, |
971 true); | 1025 capture_time + base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs), |
| 1026 true); |
972 | 1027 |
973 frame_receiver_->GetRawVideoFrame( | 1028 frame_receiver_->GetRawVideoFrame( |
974 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 1029 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
975 test_receiver_video_callback_)); | 1030 test_receiver_video_callback_)); |
976 | 1031 |
977 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. | 1032 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline. |
978 EXPECT_EQ(frames_before_glitch + 1, | 1033 EXPECT_EQ(frames_before_glitch + 1, |
979 test_receiver_video_callback_->number_times_called()); | 1034 test_receiver_video_callback_->number_times_called()); |
980 } | 1035 } |
981 | 1036 |
982 // Disabled due to flakiness and crashiness. http://crbug.com/360951 | 1037 // Disabled due to flakiness and crashiness. http://crbug.com/360951 |
983 TEST_F(End2EndTest, DISABLED_DropEveryOtherFrame3Buffers) { | 1038 TEST_F(End2EndTest, DISABLED_DropEveryOtherFrame3Buffers) { |
984 Configure(transport::kVp8, transport::kOpus, kDefaultAudioSamplingRate, false, | 1039 Configure(transport::kVp8, transport::kOpus, kDefaultAudioSamplingRate, false, |
985 3); | 1040 3); |
986 video_sender_config_.rtp_config.max_delay_ms = 67; | 1041 video_sender_config_.rtp_config.max_delay_ms = 67; |
987 video_receiver_config_.rtp_max_delay_ms = 67; | 1042 video_receiver_config_.rtp_max_delay_ms = 67; |
988 Create(); | 1043 Create(); |
989 sender_to_receiver_.DropAllPacketsBelongingToOddFrames(); | 1044 sender_to_receiver_.DropAllPacketsBelongingToOddFrames(); |
990 | 1045 |
991 int video_start = kVideoStart; | 1046 int video_start = kVideoStart; |
992 base::TimeTicks send_time; | 1047 base::TimeTicks capture_time; |
993 | 1048 |
994 int i = 0; | 1049 int i = 0; |
995 for (; i < 20; ++i) { | 1050 for (; i < 20; ++i) { |
996 send_time = testing_clock_sender_->NowTicks(); | 1051 capture_time = testing_clock_sender_->NowTicks(); |
997 SendVideoFrame(video_start, send_time); | 1052 SendVideoFrame(video_start, capture_time); |
998 | 1053 |
999 if (i % 2 == 0) { | 1054 if (i % 2 == 0) { |
1000 test_receiver_video_callback_->AddExpectedResult( | 1055 test_receiver_video_callback_->AddExpectedResult( |
1001 video_start, | 1056 video_start, |
1002 video_sender_config_.width, | 1057 video_sender_config_.width, |
1003 video_sender_config_.height, | 1058 video_sender_config_.height, |
1004 send_time, | 1059 capture_time + |
| 1060 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs), |
1005 i == 0); | 1061 i == 0); |
1006 | 1062 |
1007 // GetRawVideoFrame will not return the frame until we are close in | 1063 // GetRawVideoFrame will not return the frame until we are close in |
1008 // time before we should render the frame. | 1064 // time before we should render the frame. |
1009 frame_receiver_->GetRawVideoFrame( | 1065 frame_receiver_->GetRawVideoFrame( |
1010 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 1066 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
1011 test_receiver_video_callback_)); | 1067 test_receiver_video_callback_)); |
1012 } | 1068 } |
1013 RunTasks(kFrameTimerMs); | 1069 RunTasks(kFrameTimerMs); |
1014 video_start++; | 1070 video_start++; |
(...skipping 13 matching lines...) Expand all Loading... |
1028 | 1084 |
1029 video_receiver_config_.aes_iv_mask = | 1085 video_receiver_config_.aes_iv_mask = |
1030 video_sender_config_.rtp_config.aes_iv_mask; | 1086 video_sender_config_.rtp_config.aes_iv_mask; |
1031 video_receiver_config_.aes_key = | 1087 video_receiver_config_.aes_key = |
1032 video_sender_config_.rtp_config.aes_key; | 1088 video_sender_config_.rtp_config.aes_key; |
1033 | 1089 |
1034 Create(); | 1090 Create(); |
1035 | 1091 |
1036 int frames_counter = 0; | 1092 int frames_counter = 0; |
1037 for (; frames_counter < 3; ++frames_counter) { | 1093 for (; frames_counter < 3; ++frames_counter) { |
1038 const base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | 1094 const base::TimeTicks capture_time = testing_clock_sender_->NowTicks(); |
1039 SendVideoFrame(frames_counter, send_time); | 1095 SendVideoFrame(frames_counter, capture_time); |
1040 | 1096 |
1041 test_receiver_video_callback_->AddExpectedResult( | 1097 test_receiver_video_callback_->AddExpectedResult( |
1042 frames_counter, | 1098 frames_counter, |
1043 video_sender_config_.width, | 1099 video_sender_config_.width, |
1044 video_sender_config_.height, | 1100 video_sender_config_.height, |
1045 send_time, | 1101 capture_time + base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs), |
1046 true); | 1102 true); |
1047 | 1103 |
1048 RunTasks(kFrameTimerMs); | 1104 RunTasks(kFrameTimerMs); |
1049 | 1105 |
1050 frame_receiver_->GetRawVideoFrame( | 1106 frame_receiver_->GetRawVideoFrame( |
1051 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 1107 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
1052 test_receiver_video_callback_)); | 1108 test_receiver_video_callback_)); |
1053 } | 1109 } |
1054 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | 1110 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. |
1055 EXPECT_EQ(frames_counter, | 1111 EXPECT_EQ(frames_counter, |
(...skipping 29 matching lines...) Expand all Loading... |
1085 | 1141 |
1086 // Video test without packet loss - tests the logging aspects of the end2end, | 1142 // Video test without packet loss - tests the logging aspects of the end2end, |
1087 // but is basically equivalent to LoopNoLossPcm16. | 1143 // but is basically equivalent to LoopNoLossPcm16. |
1088 TEST_F(End2EndTest, VideoLogging) { | 1144 TEST_F(End2EndTest, VideoLogging) { |
1089 Configure(transport::kVp8, transport::kPcm16, 32000, false, 1); | 1145 Configure(transport::kVp8, transport::kPcm16, 32000, false, 1); |
1090 Create(); | 1146 Create(); |
1091 | 1147 |
1092 int video_start = kVideoStart; | 1148 int video_start = kVideoStart; |
1093 const int num_frames = 5; | 1149 const int num_frames = 5; |
1094 for (int i = 0; i < num_frames; ++i) { | 1150 for (int i = 0; i < num_frames; ++i) { |
1095 base::TimeTicks send_time = testing_clock_sender_->NowTicks(); | 1151 base::TimeTicks capture_time = testing_clock_sender_->NowTicks(); |
1096 test_receiver_video_callback_->AddExpectedResult( | 1152 test_receiver_video_callback_->AddExpectedResult( |
1097 video_start, | 1153 video_start, |
1098 video_sender_config_.width, | 1154 video_sender_config_.width, |
1099 video_sender_config_.height, | 1155 video_sender_config_.height, |
1100 send_time, | 1156 capture_time + base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs), |
1101 true); | 1157 true); |
1102 | 1158 |
1103 SendVideoFrame(video_start, send_time); | 1159 SendVideoFrame(video_start, capture_time); |
1104 RunTasks(kFrameTimerMs); | 1160 RunTasks(kFrameTimerMs); |
1105 | 1161 |
1106 frame_receiver_->GetRawVideoFrame( | 1162 frame_receiver_->GetRawVideoFrame( |
1107 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, | 1163 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame, |
1108 test_receiver_video_callback_)); | 1164 test_receiver_video_callback_)); |
1109 | 1165 |
1110 video_start++; | 1166 video_start++; |
1111 } | 1167 } |
1112 | 1168 |
1113 // Basic tests. | 1169 // Basic tests. |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 // Verify that there were no other events logged with respect to this frame. | 1340 // Verify that there were no other events logged with respect to this frame. |
1285 // (i.e. Total event count = expected event count) | 1341 // (i.e. Total event count = expected event count) |
1286 EXPECT_EQ(total_event_count_for_frame, expected_event_count_for_frame); | 1342 EXPECT_EQ(total_event_count_for_frame, expected_event_count_for_frame); |
1287 } | 1343 } |
1288 } | 1344 } |
1289 | 1345 |
1290 TEST_F(End2EndTest, BasicFakeSoftwareVideo) { | 1346 TEST_F(End2EndTest, BasicFakeSoftwareVideo) { |
1291 Configure(transport::kFakeSoftwareVideo, transport::kPcm16, 32000, false, 1); | 1347 Configure(transport::kFakeSoftwareVideo, transport::kPcm16, 32000, false, 1); |
1292 Create(); | 1348 Create(); |
1293 StartBasicPlayer(); | 1349 StartBasicPlayer(); |
| 1350 SetReceiverSkew(1.0, base::TimeDelta::FromMilliseconds(1)); |
| 1351 |
| 1352 // Expect very smooth playout when there is no clock skew. |
| 1353 SetExpectedVideoPlayoutSmoothness( |
| 1354 base::TimeDelta::FromMilliseconds(kFrameTimerMs) * 99 / 100, |
| 1355 base::TimeDelta::FromMilliseconds(kFrameTimerMs) * 101 / 100, |
| 1356 base::TimeDelta::FromMilliseconds(kFrameTimerMs) / 100); |
1294 | 1357 |
1295 int frames_counter = 0; | 1358 int frames_counter = 0; |
1296 for (; frames_counter < 1000; ++frames_counter) { | 1359 for (; frames_counter < 1000; ++frames_counter) { |
1297 SendFakeVideoFrame(testing_clock_sender_->NowTicks()); | 1360 SendFakeVideoFrame(testing_clock_sender_->NowTicks()); |
1298 RunTasks(kFrameTimerMs); | 1361 RunTasks(kFrameTimerMs); |
1299 } | 1362 } |
1300 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | 1363 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. |
1301 EXPECT_EQ(1000ul, video_ticks_.size()); | 1364 EXPECT_EQ(1000ul, video_ticks_.size()); |
1302 } | 1365 } |
1303 | 1366 |
1304 TEST_F(End2EndTest, ReceiverClockFast) { | 1367 TEST_F(End2EndTest, ReceiverClockFast) { |
1305 Configure(transport::kFakeSoftwareVideo, transport::kPcm16, 32000, false, 1); | 1368 Configure(transport::kFakeSoftwareVideo, transport::kPcm16, 32000, false, 1); |
1306 Create(); | 1369 Create(); |
1307 StartBasicPlayer(); | 1370 StartBasicPlayer(); |
1308 SetReceiverSkew(2.0, base::TimeDelta()); | 1371 SetReceiverSkew(2.0, base::TimeDelta::FromMicroseconds(1234567)); |
1309 | 1372 |
1310 int frames_counter = 0; | 1373 int frames_counter = 0; |
1311 for (; frames_counter < 10000; ++frames_counter) { | 1374 for (; frames_counter < 10000; ++frames_counter) { |
1312 SendFakeVideoFrame(testing_clock_sender_->NowTicks()); | 1375 SendFakeVideoFrame(testing_clock_sender_->NowTicks()); |
1313 RunTasks(kFrameTimerMs); | 1376 RunTasks(kFrameTimerMs); |
1314 } | 1377 } |
1315 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | 1378 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. |
1316 EXPECT_EQ(10000ul, video_ticks_.size()); | 1379 EXPECT_EQ(10000ul, video_ticks_.size()); |
1317 } | 1380 } |
1318 | 1381 |
1319 TEST_F(End2EndTest, ReceiverClockSlow) { | 1382 TEST_F(End2EndTest, ReceiverClockSlow) { |
1320 Configure(transport::kFakeSoftwareVideo, transport::kPcm16, 32000, false, 1); | 1383 Configure(transport::kFakeSoftwareVideo, transport::kPcm16, 32000, false, 1); |
1321 Create(); | 1384 Create(); |
1322 StartBasicPlayer(); | 1385 StartBasicPlayer(); |
1323 SetReceiverSkew(0.5, base::TimeDelta()); | 1386 SetReceiverSkew(0.5, base::TimeDelta::FromMicroseconds(-765432)); |
1324 | 1387 |
1325 int frames_counter = 0; | 1388 int frames_counter = 0; |
1326 for (; frames_counter < 10000; ++frames_counter) { | 1389 for (; frames_counter < 10000; ++frames_counter) { |
| 1390 SendFakeVideoFrame(testing_clock_sender_->NowTicks()); |
| 1391 RunTasks(kFrameTimerMs); |
| 1392 } |
| 1393 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. |
| 1394 EXPECT_EQ(10000ul, video_ticks_.size()); |
| 1395 } |
| 1396 |
| 1397 TEST_F(End2EndTest, SmoothPlayoutWithFivePercentClockRateSkew) { |
| 1398 Configure(transport::kFakeSoftwareVideo, transport::kPcm16, 32000, false, 1); |
| 1399 Create(); |
| 1400 StartBasicPlayer(); |
| 1401 SetReceiverSkew(1.05, base::TimeDelta::FromMilliseconds(-42)); |
| 1402 |
| 1403 // Expect smooth playout when there is 5% skew. |
| 1404 SetExpectedVideoPlayoutSmoothness( |
| 1405 base::TimeDelta::FromMilliseconds(kFrameTimerMs) * 90 / 100, |
| 1406 base::TimeDelta::FromMilliseconds(kFrameTimerMs) * 110 / 100, |
| 1407 base::TimeDelta::FromMilliseconds(kFrameTimerMs) / 10); |
| 1408 |
| 1409 int frames_counter = 0; |
| 1410 for (; frames_counter < 10000; ++frames_counter) { |
1327 SendFakeVideoFrame(testing_clock_sender_->NowTicks()); | 1411 SendFakeVideoFrame(testing_clock_sender_->NowTicks()); |
1328 RunTasks(kFrameTimerMs); | 1412 RunTasks(kFrameTimerMs); |
1329 } | 1413 } |
1330 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. | 1414 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline. |
1331 EXPECT_EQ(10000ul, video_ticks_.size()); | 1415 EXPECT_EQ(10000ul, video_ticks_.size()); |
1332 } | 1416 } |
1333 | 1417 |
1334 TEST_F(End2EndTest, EvilNetwork) { | 1418 TEST_F(End2EndTest, EvilNetwork) { |
1335 Configure(transport::kFakeSoftwareVideo, transport::kPcm16, 32000, false, 1); | 1419 Configure(transport::kFakeSoftwareVideo, transport::kPcm16, 32000, false, 1); |
1336 receiver_to_sender_.SetPacketPipe(test::EvilNetwork().Pass()); | 1420 receiver_to_sender_.SetPacketPipe(test::EvilNetwork().Pass()); |
(...skipping 12 matching lines...) Expand all Loading... |
1349 EXPECT_LT((video_ticks_.back().second - test_end).InMilliseconds(), 1000); | 1433 EXPECT_LT((video_ticks_.back().second - test_end).InMilliseconds(), 1000); |
1350 } | 1434 } |
1351 | 1435 |
1352 // TODO(pwestin): Add repeatable packet loss test. | 1436 // TODO(pwestin): Add repeatable packet loss test. |
1353 // TODO(pwestin): Add test for misaligned send get calls. | 1437 // TODO(pwestin): Add test for misaligned send get calls. |
1354 // TODO(pwestin): Add more tests that does not resample. | 1438 // TODO(pwestin): Add more tests that does not resample. |
1355 // TODO(pwestin): Add test when we have starvation for our RunTask. | 1439 // TODO(pwestin): Add test when we have starvation for our RunTask. |
1356 | 1440 |
1357 } // namespace cast | 1441 } // namespace cast |
1358 } // namespace media | 1442 } // namespace media |
OLD | NEW |