Report errors from ChromiumEnv::GetChildren in Posix.
[chromium-blink-merge.git] / media / cast / test / end2end_unittest.cc
blob724695b5b5529e2c78b6b6a2b1da39d33aee442f
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
3 // found in the LICENSE file.
4 //
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
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
9 // frequently within the image. Visually this will create diagonally color bands
10 // that moves across the screen
12 #include <math.h>
14 #include <list>
16 #include "base/bind.h"
17 #include "base/test/simple_test_tick_clock.h"
18 #include "base/time/tick_clock.h"
19 #include "media/cast/cast_config.h"
20 #include "media/cast/cast_environment.h"
21 #include "media/cast/cast_receiver.h"
22 #include "media/cast/cast_sender.h"
23 #include "media/cast/test/fake_task_runner.h"
24 #include "media/cast/test/video_utility.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 namespace media {
28 namespace cast {
30 // Since our time is based on year 1600 and NTP is based on year 1900 we must
31 // initialize our fake clock to at least 300 year passed year 1600.
32 static const int64 kStartMillisecond = GG_INT64_C(12345678900000);
33 static const int kAudioChannels = 2;
34 static const int kAudioSamplingFrequency = 48000;
35 static const int kSoundFrequency = 1234; // Frequency of sinusoid wave.
36 static const int kVideoWidth = 1280;
37 static const int kVideoHeight = 720;
39 // Since the video encoded and decoded an error will be introduced; when
40 // comparing individual pixels the error can be quite large; we allow a PSNR of
41 // at least |kVideoAcceptedPSNR|.
42 static const double kVideoAcceptedPSNR = 38.0;
44 // The tests are commonly implemented with |kFrameTimerMs| RunTask function;
45 // a normal video is 30 fps hence the 33 ms between frames.
46 static const int kFrameTimerMs = 33;
48 // The packets pass through the pacer which can delay the beginning of the
49 // frame by 10 ms if there is packets belonging to the previous frame being
50 // retransmitted.
51 static const int kTimerErrorMs = 11;
53 // Class that sends the packet direct from sender into the receiver with the
54 // ability to drop packets between the two.
55 class LoopBackTransport : public PacketSender {
56 public:
57 explicit LoopBackTransport(scoped_refptr<CastEnvironment> cast_environment)
58 : packet_receiver_(NULL),
59 send_packets_(true),
60 drop_packets_belonging_to_odd_frames_(false),
61 cast_environment_(cast_environment) {
64 void RegisterPacketReceiver(PacketReceiver* packet_receiver) {
65 DCHECK(packet_receiver);
66 packet_receiver_ = packet_receiver;
69 virtual bool SendPacket(const Packet& packet) OVERRIDE {
70 DCHECK(packet_receiver_);
71 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
72 if (!send_packets_) return false;
74 uint8* packet_copy = new uint8[packet.size()];
75 memcpy(packet_copy, packet.data(), packet.size());
76 packet_receiver_->ReceivedPacket(packet_copy, packet.size(),
77 base::Bind(PacketReceiver::DeletePacket, packet_copy));
78 return true;
81 virtual bool SendPackets(const PacketList& packets) OVERRIDE {
82 DCHECK(packet_receiver_);
83 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
84 if (!send_packets_) return false;
86 for (size_t i = 0; i < packets.size(); ++i) {
87 const Packet& packet = packets[i];
88 if (drop_packets_belonging_to_odd_frames_) {
89 uint8 frame_id = packet[13];
90 if (frame_id % 2 == 1) continue;
92 uint8* packet_copy = new uint8[packet.size()];
93 memcpy(packet_copy, packet.data(), packet.size());
94 packet_receiver_->ReceivedPacket(packet_copy, packet.size(),
95 base::Bind(PacketReceiver::DeletePacket, packet_copy));
97 return true;
100 void SetSendPackets(bool send_packets) {
101 send_packets_ = send_packets;
104 void DropAllPacketsBelongingToOddFrames() {
105 drop_packets_belonging_to_odd_frames_ = true;
108 private:
109 PacketReceiver* packet_receiver_;
110 bool send_packets_;
111 bool drop_packets_belonging_to_odd_frames_;
112 scoped_refptr<CastEnvironment> cast_environment_;
115 // Class that verifies the audio frames coming out of the receiver.
116 class TestReceiverAudioCallback :
117 public base::RefCountedThreadSafe<TestReceiverAudioCallback> {
118 public:
119 struct ExpectedAudioFrame {
120 PcmAudioFrame audio_frame;
121 int num_10ms_blocks;
122 base::TimeTicks record_time;
125 TestReceiverAudioCallback()
126 : num_called_(0),
127 avg_snr_(0) {}
129 void SetExpectedResult(int expected_sampling_frequency,
130 int expected_min_snr,
131 int expected_avg_snr) {
132 expected_sampling_frequency_ = expected_sampling_frequency;
133 expected_min_snr_ = expected_min_snr;
134 expected_avg_snr_ = expected_avg_snr;
137 void AddExpectedResult(PcmAudioFrame* audio_frame,
138 int expected_num_10ms_blocks,
139 const base::TimeTicks& record_time) {
140 ExpectedAudioFrame expected_audio_frame;
141 expected_audio_frame.audio_frame = *audio_frame;
142 expected_audio_frame.num_10ms_blocks = expected_num_10ms_blocks;
143 expected_audio_frame.record_time = record_time;
144 expected_frame_.push_back(expected_audio_frame);
147 void IgnoreAudioFrame(scoped_ptr<PcmAudioFrame> audio_frame,
148 const base::TimeTicks& playout_time) {}
150 // Check the audio frame parameters but not the audio samples.
151 void CheckBasicAudioFrame(const scoped_ptr<PcmAudioFrame>& audio_frame,
152 const base::TimeTicks& playout_time) {
153 EXPECT_FALSE(expected_frame_.empty()); // Test for bug in test code.
154 ExpectedAudioFrame expected_audio_frame = expected_frame_.front();
155 EXPECT_EQ(audio_frame->channels, kAudioChannels);
156 EXPECT_EQ(audio_frame->frequency, expected_sampling_frequency_);
157 EXPECT_EQ(static_cast<int>(audio_frame->samples.size()),
158 expected_audio_frame.num_10ms_blocks * kAudioChannels *
159 expected_sampling_frequency_ / 100);
161 EXPECT_GE(expected_audio_frame.record_time +
162 base::TimeDelta::FromMilliseconds(kDefaultRtpMaxDelayMs +
163 kTimerErrorMs), playout_time);
164 EXPECT_LT(expected_audio_frame.record_time, playout_time);
166 EXPECT_EQ(audio_frame->samples.size(),
167 expected_audio_frame.audio_frame.samples.size());
170 size_t CalculateMaxResamplingDelay(size_t src_sample_rate_hz,
171 size_t dst_sample_rate_hz,
172 size_t number_of_channels) {
173 // The sinc resampler has a known delay, which we compute here. Multiplying
174 // by two gives us a crude maximum for any resampling, as the old resampler
175 // typically (but not always) has lower delay. Since we sample up and down
176 // we need to double our delay.
177 static const size_t kInputKernelDelaySamples = 16;
178 if (src_sample_rate_hz == dst_sample_rate_hz) return 0;
180 return (dst_sample_rate_hz * kInputKernelDelaySamples *
181 number_of_channels * 4) / src_sample_rate_hz;
184 // Computes the SNR based on the error between |reference_audio_frame| and
185 // |output_audio_frame| given a sample offset of |delay|.
186 double ComputeSNR(const PcmAudioFrame& reference_audio_frame,
187 const std::vector<int16>& output_audio_samples,
188 size_t delay) {
189 // Check all out allowed delays.
190 double square_error = 0;
191 double variance = 0;
192 for (size_t i = 0; i < reference_audio_frame.samples.size() - delay; ++i) {
193 size_t error = reference_audio_frame.samples[i] -
194 output_audio_samples[i + delay];
196 square_error += error * error;
197 variance += reference_audio_frame.samples[i] *
198 reference_audio_frame.samples[i];
200 // 16-bit audio has a dynamic range of 96 dB.
201 double snr = 96.0; // Assigning 96 dB to the zero-error case.
202 if (square_error > 0) {
203 snr = 10 * log10(variance / square_error);
205 return snr;
208 // Computes the best SNR based on the error between |ref_frame| and
209 // |test_frame|. It allows for up to a |max_delay| in samples between the
210 // signals to compensate for the re-sampling delay.
211 double ComputeBestSNR(const PcmAudioFrame& reference_audio_frame,
212 const std::vector<int16>& output_audio_samples,
213 size_t max_delay) {
214 double best_snr = 0;
216 // Check all out allowed delays.
217 for (size_t delay = 0; delay <= max_delay;
218 delay += reference_audio_frame.channels) {
219 double snr = ComputeSNR(reference_audio_frame, output_audio_samples,
220 delay);
221 if (snr > best_snr) {
222 best_snr = snr;
225 if (avg_snr_ == 0) {
226 avg_snr_ = best_snr;
227 } else {
228 avg_snr_ = (avg_snr_ * 7 + best_snr) / 8;
230 return best_snr;
233 void CheckPcmAudioFrame(scoped_ptr<PcmAudioFrame> audio_frame,
234 const base::TimeTicks& playout_time) {
235 ++num_called_;
237 CheckBasicAudioFrame(audio_frame, playout_time);
238 ExpectedAudioFrame expected_audio_frame = expected_frame_.front();
239 expected_frame_.pop_front();
240 if (audio_frame->samples.size() == 0) return; // No more checks needed.
242 size_t max_delay = CalculateMaxResamplingDelay(48000, 32000,
243 expected_audio_frame.audio_frame.channels);
244 EXPECT_GE(ComputeBestSNR(expected_audio_frame.audio_frame,
245 audio_frame->samples, max_delay),
246 expected_min_snr_);
249 void CheckCodedPcmAudioFrame(scoped_ptr<EncodedAudioFrame> audio_frame,
250 const base::TimeTicks& playout_time) {
251 ++num_called_;
253 EXPECT_FALSE(expected_frame_.empty()); // Test for bug in test code.
254 ExpectedAudioFrame expected_audio_frame = expected_frame_.front();
255 expected_frame_.pop_front();
257 EXPECT_EQ(static_cast<int>(audio_frame->data.size()),
258 2 * kAudioChannels * expected_sampling_frequency_ / 100);
260 base::TimeDelta time_since_recording =
261 playout_time - expected_audio_frame.record_time;
263 EXPECT_LE(time_since_recording, base::TimeDelta::FromMilliseconds(
264 kDefaultRtpMaxDelayMs + kTimerErrorMs));
266 EXPECT_LT(expected_audio_frame.record_time, playout_time);
267 if (audio_frame->data.size() == 0) return; // No more checks needed.
269 size_t max_delay = CalculateMaxResamplingDelay(48000, 32000,
270 expected_audio_frame.audio_frame.channels);
272 // We need to convert our "coded" audio frame to our raw format.
273 std::vector<int16> output_audio_samples;
274 int number_of_samples = audio_frame->data.size() / 2;
276 for (int i = 0; i < number_of_samples; ++i) {
277 uint16 sample = (audio_frame->data[1 + i * sizeof(uint16)]) +
278 (static_cast<uint16>(audio_frame->data[i * sizeof(uint16)]) << 8);
279 output_audio_samples.push_back(static_cast<int16>(sample));
281 EXPECT_GE(ComputeBestSNR(expected_audio_frame.audio_frame,
282 output_audio_samples, max_delay),
283 expected_min_snr_);
286 int number_times_called() {
287 EXPECT_GE(avg_snr_, expected_avg_snr_);
288 return num_called_;
291 protected:
292 virtual ~TestReceiverAudioCallback() {}
294 private:
295 friend class base::RefCountedThreadSafe<TestReceiverAudioCallback>;
297 int num_called_;
298 int expected_sampling_frequency_;
299 int expected_min_snr_;
300 int expected_avg_snr_;
301 double avg_snr_;
302 std::list<ExpectedAudioFrame> expected_frame_;
305 // Class that verifies the video frames coming out of the receiver.
306 class TestReceiverVideoCallback :
307 public base::RefCountedThreadSafe<TestReceiverVideoCallback> {
308 public:
309 struct ExpectedVideoFrame {
310 int start_value;
311 int width;
312 int height;
313 base::TimeTicks capture_time;
316 TestReceiverVideoCallback()
317 : num_called_(0) {}
319 void AddExpectedResult(int start_value,
320 int width,
321 int height,
322 const base::TimeTicks& capture_time) {
323 ExpectedVideoFrame expected_video_frame;
324 expected_video_frame.start_value = start_value;
325 expected_video_frame.capture_time = capture_time;
326 expected_video_frame.width = width;
327 expected_video_frame.height = height;
328 expected_frame_.push_back(expected_video_frame);
331 void CheckVideoFrame(scoped_ptr<I420VideoFrame> video_frame,
332 const base::TimeTicks& render_time) {
333 ++num_called_;
335 EXPECT_FALSE(expected_frame_.empty()); // Test for bug in test code.
336 ExpectedVideoFrame expected_video_frame = expected_frame_.front();
337 expected_frame_.pop_front();
339 base::TimeDelta time_since_capture =
340 render_time - expected_video_frame.capture_time;
342 EXPECT_LE(time_since_capture, base::TimeDelta::FromMilliseconds(
343 kDefaultRtpMaxDelayMs + kTimerErrorMs));
344 EXPECT_LE(expected_video_frame.capture_time, render_time);
345 EXPECT_EQ(expected_video_frame.width, video_frame->width);
346 EXPECT_EQ(expected_video_frame.height, video_frame->height);
348 I420VideoFrame* expected_I420_frame = new I420VideoFrame();
349 expected_I420_frame->width = expected_video_frame.width;
350 expected_I420_frame->height = expected_video_frame.height;
351 PopulateVideoFrame(expected_I420_frame, expected_video_frame.start_value);
353 double psnr = I420PSNR(*expected_I420_frame, *(video_frame.get()));
354 EXPECT_GE(psnr, kVideoAcceptedPSNR);
356 FrameInput::DeleteVideoFrame(expected_I420_frame);
359 int number_times_called() { return num_called_;}
361 protected:
362 virtual ~TestReceiverVideoCallback() {}
364 private:
365 friend class base::RefCountedThreadSafe<TestReceiverVideoCallback>;
367 int num_called_;
368 std::list<ExpectedVideoFrame> expected_frame_;
371 // The actual test class, generate synthetic data for both audio and video and
372 // send those through the sender and receiver and analyzes the result.
373 class End2EndTest : public ::testing::Test {
374 protected:
375 End2EndTest()
376 : task_runner_(new test::FakeTaskRunner(&testing_clock_)),
377 cast_environment_(new CastEnvironment(&testing_clock_, task_runner_,
378 task_runner_, task_runner_, task_runner_, task_runner_)),
379 sender_to_receiver_(cast_environment_),
380 receiver_to_sender_(cast_environment_),
381 test_receiver_audio_callback_(new TestReceiverAudioCallback()),
382 test_receiver_video_callback_(new TestReceiverVideoCallback()),
383 audio_angle_(0) {
384 testing_clock_.Advance(
385 base::TimeDelta::FromMilliseconds(kStartMillisecond));
388 void SetupConfig(AudioCodec audio_codec,
389 int audio_sampling_frequency,
390 bool external_audio_decoder,
391 int max_number_of_video_buffers_used) {
392 audio_sender_config_.sender_ssrc = 1;
393 audio_sender_config_.incoming_feedback_ssrc = 2;
394 audio_sender_config_.rtp_payload_type = 96;
395 audio_sender_config_.use_external_encoder = false;
396 audio_sender_config_.frequency = audio_sampling_frequency;
397 audio_sender_config_.channels = kAudioChannels;
398 audio_sender_config_.bitrate = 64000;
399 audio_sender_config_.codec = audio_codec;
401 audio_receiver_config_.feedback_ssrc =
402 audio_sender_config_.incoming_feedback_ssrc;
403 audio_receiver_config_.incoming_ssrc =
404 audio_sender_config_.sender_ssrc;
405 audio_receiver_config_.rtp_payload_type =
406 audio_sender_config_.rtp_payload_type;
407 audio_receiver_config_.use_external_decoder = external_audio_decoder;
408 audio_receiver_config_.frequency = audio_sender_config_.frequency;
409 audio_receiver_config_.channels = kAudioChannels;
410 audio_receiver_config_.codec = audio_sender_config_.codec;
412 video_sender_config_.sender_ssrc = 3;
413 video_sender_config_.incoming_feedback_ssrc = 4;
414 video_sender_config_.rtp_payload_type = 97;
415 video_sender_config_.use_external_encoder = false;
416 video_sender_config_.width = kVideoWidth;
417 video_sender_config_.height = kVideoHeight;
418 video_sender_config_.max_bitrate = 5000000;
419 video_sender_config_.min_bitrate = 1000000;
420 video_sender_config_.start_bitrate = 5000000;
421 video_sender_config_.max_qp = 30;
422 video_sender_config_.min_qp = 4;
423 video_sender_config_.max_frame_rate = 30;
424 video_sender_config_.max_number_of_video_buffers_used =
425 max_number_of_video_buffers_used;
426 video_sender_config_.codec = kVp8;
427 video_sender_config_.number_of_cores = 1;
429 video_receiver_config_.feedback_ssrc =
430 video_sender_config_.incoming_feedback_ssrc;
431 video_receiver_config_.incoming_ssrc =
432 video_sender_config_.sender_ssrc;
433 video_receiver_config_.rtp_payload_type =
434 video_sender_config_.rtp_payload_type;
435 video_receiver_config_.use_external_decoder = false;
436 video_receiver_config_.codec = video_sender_config_.codec;
439 void Create() {
440 cast_receiver_.reset(CastReceiver::CreateCastReceiver(cast_environment_,
441 audio_receiver_config_, video_receiver_config_, &receiver_to_sender_));
443 cast_sender_.reset(CastSender::CreateCastSender(cast_environment_,
444 audio_sender_config_,
445 video_sender_config_,
446 NULL,
447 &sender_to_receiver_));
449 receiver_to_sender_.RegisterPacketReceiver(cast_sender_->packet_receiver());
450 sender_to_receiver_.RegisterPacketReceiver(
451 cast_receiver_->packet_receiver());
453 frame_input_ = cast_sender_->frame_input();
454 frame_receiver_ = cast_receiver_->frame_receiver();
457 virtual ~End2EndTest() {}
459 void SendVideoFrame(int start_value, const base::TimeTicks& capture_time) {
460 I420VideoFrame* video_frame = new I420VideoFrame();
461 video_frame->width = video_sender_config_.width;
462 video_frame->height = video_sender_config_.height;
463 PopulateVideoFrame(video_frame, start_value);
464 frame_input_->InsertRawVideoFrame(video_frame, capture_time,
465 base::Bind(FrameInput::DeleteVideoFrame, video_frame));
468 PcmAudioFrame* CreateAudioFrame(int num_10ms_blocks, int sound_frequency,
469 int sampling_frequency) {
470 int number_of_samples = kAudioChannels * num_10ms_blocks *
471 sampling_frequency / 100;
472 int amplitude = 1000;
474 PcmAudioFrame* audio_frame = new PcmAudioFrame();
475 audio_frame->channels = kAudioChannels;
476 audio_frame->frequency = sampling_frequency;
477 audio_frame->samples.reserve(number_of_samples);
479 // Create the sinusoid.
480 double increment = (2 * 3.1415926535897932384626433) /
481 (static_cast<double>(sampling_frequency) / sound_frequency);
482 int sample = 0;
483 while (sample < number_of_samples) {
484 int16 value = static_cast<int16>(amplitude * sin(audio_angle_));
486 for (int i = 0; i < kAudioChannels; ++i) {
487 audio_frame->samples.insert(audio_frame->samples.end(), value);
488 ++sample;
490 audio_angle_ += increment;
492 return audio_frame;
495 void RunTasks(int during_ms) {
496 for (int i = 0; i < during_ms; ++i) {
497 // Call process the timers every 1 ms.
498 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(1));
499 task_runner_->RunTasks();
503 AudioReceiverConfig audio_receiver_config_;
504 VideoReceiverConfig video_receiver_config_;
505 AudioSenderConfig audio_sender_config_;
506 VideoSenderConfig video_sender_config_;
508 base::SimpleTestTickClock testing_clock_;
509 scoped_refptr<test::FakeTaskRunner> task_runner_;
510 scoped_refptr<CastEnvironment> cast_environment_;
512 LoopBackTransport sender_to_receiver_;
513 LoopBackTransport receiver_to_sender_;
515 scoped_ptr<CastReceiver> cast_receiver_;
516 scoped_ptr<CastSender> cast_sender_;
517 scoped_refptr<FrameInput> frame_input_;
518 scoped_refptr<FrameReceiver> frame_receiver_;
520 double audio_angle_;
522 scoped_refptr<TestReceiverAudioCallback> test_receiver_audio_callback_;
523 scoped_refptr<TestReceiverVideoCallback> test_receiver_video_callback_;
526 // Audio and video test without packet loss using raw PCM 16 audio "codec";
527 // note: even though the audio is not coded it is still re-sampled between
528 // 48 and 32 KHz.
529 TEST_F(End2EndTest, LoopNoLossPcm16) {
530 // Note running codec in different sampling frequency.
531 SetupConfig(kPcm16, 32000, false, 1);
532 Create();
533 test_receiver_audio_callback_->SetExpectedResult(kAudioSamplingFrequency, 20,
534 25);
536 int video_start = 1;
537 int audio_diff = kFrameTimerMs;
538 int i = 0;
540 std::cout << "Progress ";
541 for (; i < 100; ++i) {
542 int num_10ms_blocks = audio_diff / 10;
543 audio_diff -= num_10ms_blocks * 10;
544 base::TimeTicks send_time = testing_clock_.NowTicks();
546 test_receiver_video_callback_->AddExpectedResult(video_start,
547 video_sender_config_.width, video_sender_config_.height, send_time);
549 PcmAudioFrame* audio_frame = CreateAudioFrame(num_10ms_blocks,
550 kSoundFrequency, kAudioSamplingFrequency);
552 if (i != 0) {
553 // Due to the re-sampler and NetEq in the webrtc AudioCodingModule the
554 // first samples will be 0 and then slowly ramp up to its real amplitude;
555 // ignore the first frame.
556 test_receiver_audio_callback_->AddExpectedResult(audio_frame,
557 num_10ms_blocks, send_time);
560 frame_input_->InsertRawAudioFrame(audio_frame, send_time,
561 base::Bind(FrameInput::DeleteAudioFrame, audio_frame));
563 SendVideoFrame(video_start, send_time);
565 RunTasks(kFrameTimerMs);
566 audio_diff += kFrameTimerMs;
568 if (i == 0) {
569 frame_receiver_->GetRawAudioFrame(num_10ms_blocks,
570 kAudioSamplingFrequency,
571 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame,
572 test_receiver_audio_callback_));
573 } else {
574 frame_receiver_->GetRawAudioFrame(num_10ms_blocks,
575 kAudioSamplingFrequency,
576 base::Bind(&TestReceiverAudioCallback::CheckPcmAudioFrame,
577 test_receiver_audio_callback_));
580 frame_receiver_->GetRawVideoFrame(
581 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame,
582 test_receiver_video_callback_));
584 std::cout << " " << i << std::flush;
585 video_start++;
587 std::cout << std::endl;
589 RunTasks(67); // Empty the receiver pipeline.
590 EXPECT_EQ(i - 1, test_receiver_audio_callback_->number_times_called());
591 EXPECT_EQ(i, test_receiver_video_callback_->number_times_called());
594 // This tests our external decoder interface for Audio.
595 // Audio test without packet loss using raw PCM 16 audio "codec";
596 TEST_F(End2EndTest, LoopNoLossPcm16ExternalDecoder) {
597 // Note: Create an input in the same sampling frequency as the codec to avoid
598 // re-sampling.
599 const int audio_sampling_frequency = 32000;
600 SetupConfig(kPcm16, audio_sampling_frequency, true, 1);
601 Create();
602 test_receiver_audio_callback_->SetExpectedResult(audio_sampling_frequency, 96,
603 96);
605 int i = 0;
606 for (; i < 100; ++i) {
607 base::TimeTicks send_time = testing_clock_.NowTicks();
608 PcmAudioFrame* audio_frame = CreateAudioFrame(1, kSoundFrequency,
609 audio_sampling_frequency);
610 test_receiver_audio_callback_->AddExpectedResult(audio_frame, 1,
611 send_time);
613 frame_input_->InsertRawAudioFrame(audio_frame, send_time,
614 base::Bind(FrameInput::DeleteAudioFrame, audio_frame));
616 RunTasks(10);
617 frame_receiver_->GetCodedAudioFrame(
618 base::Bind(&TestReceiverAudioCallback::CheckCodedPcmAudioFrame,
619 test_receiver_audio_callback_));
621 RunTasks(67); // Empty the receiver pipeline.
622 EXPECT_EQ(100, test_receiver_audio_callback_->number_times_called());
625 // This tests our Opus audio codec without video.
626 TEST_F(End2EndTest, LoopNoLossOpus) {
627 SetupConfig(kOpus, kAudioSamplingFrequency, false, 1);
628 Create();
629 test_receiver_audio_callback_->SetExpectedResult(
630 kAudioSamplingFrequency, 18, 20);
632 int i = 0;
633 for (; i < 100; ++i) {
634 int num_10ms_blocks = 3;
635 base::TimeTicks send_time = testing_clock_.NowTicks();
637 PcmAudioFrame* audio_frame = CreateAudioFrame(num_10ms_blocks,
638 kSoundFrequency, kAudioSamplingFrequency);
640 if (i != 0) {
641 test_receiver_audio_callback_->AddExpectedResult(audio_frame,
642 num_10ms_blocks, send_time);
645 frame_input_->InsertRawAudioFrame(audio_frame, send_time,
646 base::Bind(FrameInput::DeleteAudioFrame, audio_frame));
648 RunTasks(30);
650 if (i == 0) {
651 frame_receiver_->GetRawAudioFrame(num_10ms_blocks,
652 kAudioSamplingFrequency,
653 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame,
654 test_receiver_audio_callback_));
655 } else {
656 frame_receiver_->GetRawAudioFrame(num_10ms_blocks,
657 kAudioSamplingFrequency,
658 base::Bind(&TestReceiverAudioCallback::CheckPcmAudioFrame,
659 test_receiver_audio_callback_));
662 RunTasks(67); // Empty the receiver pipeline.
663 EXPECT_EQ(i - 1, test_receiver_audio_callback_->number_times_called());
666 // This tests start sending audio and video before the receiver is ready.
667 TEST_F(End2EndTest, StartSenderBeforeReceiver) {
668 SetupConfig(kOpus, kAudioSamplingFrequency, false, 1);
669 Create();
670 test_receiver_audio_callback_->SetExpectedResult(
671 kAudioSamplingFrequency, 18, 20);
673 int video_start = 1;
674 int audio_diff = kFrameTimerMs;
676 sender_to_receiver_.SetSendPackets(false);
678 for (int i = 0; i < 3; ++i) {
679 int num_10ms_blocks = audio_diff / 10;
680 audio_diff -= num_10ms_blocks * 10;
682 base::TimeTicks send_time = testing_clock_.NowTicks();
683 PcmAudioFrame* audio_frame = CreateAudioFrame(num_10ms_blocks,
684 kSoundFrequency, kAudioSamplingFrequency);
686 frame_input_->InsertRawAudioFrame(audio_frame, send_time,
687 base::Bind(FrameInput::DeleteAudioFrame, audio_frame));
689 SendVideoFrame(video_start, send_time);
690 RunTasks(kFrameTimerMs);
691 audio_diff += kFrameTimerMs;
692 video_start++;
694 RunTasks(100);
695 sender_to_receiver_.SetSendPackets(true);
697 int j = 0;
698 const int number_of_audio_frames_to_ignore = 3;
699 for (; j < 10; ++j) {
700 int num_10ms_blocks = audio_diff / 10;
701 audio_diff -= num_10ms_blocks * 10;
702 base::TimeTicks send_time = testing_clock_.NowTicks();
704 PcmAudioFrame* audio_frame = CreateAudioFrame(num_10ms_blocks,
705 kSoundFrequency, kAudioSamplingFrequency);
707 frame_input_->InsertRawAudioFrame(audio_frame, send_time,
708 base::Bind(FrameInput::DeleteAudioFrame, audio_frame));
710 if (j >= number_of_audio_frames_to_ignore) {
711 test_receiver_audio_callback_->AddExpectedResult(audio_frame,
712 num_10ms_blocks, send_time);
714 test_receiver_video_callback_->AddExpectedResult(video_start,
715 video_sender_config_.width, video_sender_config_.height, send_time);
717 SendVideoFrame(video_start, send_time);
718 RunTasks(kFrameTimerMs);
719 audio_diff += kFrameTimerMs;
721 if (j < number_of_audio_frames_to_ignore) {
722 frame_receiver_->GetRawAudioFrame(num_10ms_blocks,
723 kAudioSamplingFrequency,
724 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame,
725 test_receiver_audio_callback_));
726 } else {
727 frame_receiver_->GetRawAudioFrame(num_10ms_blocks,
728 kAudioSamplingFrequency,
729 base::Bind(&TestReceiverAudioCallback::CheckPcmAudioFrame,
730 test_receiver_audio_callback_));
732 frame_receiver_->GetRawVideoFrame(
733 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame,
734 test_receiver_video_callback_));
735 video_start++;
737 RunTasks(67); // Empty the receiver pipeline.
738 EXPECT_EQ(j - number_of_audio_frames_to_ignore,
739 test_receiver_audio_callback_->number_times_called());
740 EXPECT_EQ(j, test_receiver_video_callback_->number_times_called());
743 // This tests a network glitch lasting for 10 video frames.
744 TEST_F(End2EndTest, GlitchWith3Buffers) {
745 SetupConfig(kOpus, kAudioSamplingFrequency, false, 3);
746 video_sender_config_.rtp_max_delay_ms = 67;
747 video_receiver_config_.rtp_max_delay_ms = 67;
748 Create();
750 int video_start = 50;
751 base::TimeTicks send_time = testing_clock_.NowTicks();
752 SendVideoFrame(video_start, send_time);
753 RunTasks(kFrameTimerMs);
755 test_receiver_video_callback_->AddExpectedResult(video_start,
756 video_sender_config_.width, video_sender_config_.height, send_time);
757 frame_receiver_->GetRawVideoFrame(
758 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame,
759 test_receiver_video_callback_));
761 RunTasks(750); // Make sure that we send a RTCP packet.
763 video_start++;
765 // Introduce a glitch lasting for 10 frames.
766 sender_to_receiver_.SetSendPackets(false);
767 for (int i = 0; i < 10; ++i) {
768 send_time = testing_clock_.NowTicks();
769 // First 3 will be sent and lost.
770 SendVideoFrame(video_start, send_time);
771 RunTasks(kFrameTimerMs);
772 video_start++;
774 sender_to_receiver_.SetSendPackets(true);
775 RunTasks(100);
776 send_time = testing_clock_.NowTicks();
778 // Frame 1 should be acked by now and we should have an opening to send 4.
779 SendVideoFrame(video_start, send_time);
780 RunTasks(kFrameTimerMs);
782 test_receiver_video_callback_->AddExpectedResult(video_start,
783 video_sender_config_.width, video_sender_config_.height, send_time);
785 frame_receiver_->GetRawVideoFrame(
786 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame,
787 test_receiver_video_callback_));
789 RunTasks(67); // Empty the receiver pipeline.
790 EXPECT_EQ(2, test_receiver_video_callback_->number_times_called());
793 TEST_F(End2EndTest, DropEveryOtherFrame3Buffers) {
794 SetupConfig(kOpus, kAudioSamplingFrequency, false, 3);
795 video_sender_config_.rtp_max_delay_ms = 67;
796 video_receiver_config_.rtp_max_delay_ms = 67;
797 Create();
798 sender_to_receiver_.DropAllPacketsBelongingToOddFrames();
800 int video_start = 50;
801 base::TimeTicks send_time;
803 std::cout << "Progress ";
804 int i = 0;
805 for (; i < 20; ++i) {
806 send_time = testing_clock_.NowTicks();
807 SendVideoFrame(video_start, send_time);
809 if (i % 2 == 0) {
810 test_receiver_video_callback_->AddExpectedResult(video_start,
811 video_sender_config_.width, video_sender_config_.height, send_time);
813 // GetRawVideoFrame will not return the frame until we are close in
814 // time before we should render the frame.
815 frame_receiver_->GetRawVideoFrame(
816 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame,
817 test_receiver_video_callback_));
819 RunTasks(kFrameTimerMs);
820 std::cout << " " << i << std::flush;
821 video_start++;
823 std::cout << std::endl;
824 RunTasks(67); // Empty the pipeline.
825 EXPECT_EQ(i / 2, test_receiver_video_callback_->number_times_called());
828 // TODO(pwestin): Add repeatable packet loss test.
829 // TODO(pwestin): Add test for misaligned send get calls.
830 // TODO(pwestin): Add more tests that does not resample.
831 // TODO(pwestin): Add test when we have starvation for our RunTask.
833 } // namespace cast
834 } // namespace media