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.
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
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"
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
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
{
57 explicit LoopBackTransport(scoped_refptr
<CastEnvironment
> cast_environment
)
58 : packet_receiver_(NULL
),
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
));
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
));
100 void SetSendPackets(bool send_packets
) {
101 send_packets_
= send_packets
;
104 void DropAllPacketsBelongingToOddFrames() {
105 drop_packets_belonging_to_odd_frames_
= true;
109 PacketReceiver
* packet_receiver_
;
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
> {
119 struct ExpectedAudioFrame
{
120 PcmAudioFrame audio_frame
;
122 base::TimeTicks record_time
;
125 TestReceiverAudioCallback()
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
,
189 // Check all out allowed delays.
190 double square_error
= 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
);
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
,
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
,
221 if (snr
> best_snr
) {
228 avg_snr_
= (avg_snr_
* 7 + best_snr
) / 8;
233 void CheckPcmAudioFrame(scoped_ptr
<PcmAudioFrame
> audio_frame
,
234 const base::TimeTicks
& playout_time
) {
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
),
249 void CheckCodedPcmAudioFrame(scoped_ptr
<EncodedAudioFrame
> audio_frame
,
250 const base::TimeTicks
& playout_time
) {
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
),
286 int number_times_called() {
287 EXPECT_GE(avg_snr_
, expected_avg_snr_
);
292 virtual ~TestReceiverAudioCallback() {}
295 friend class base::RefCountedThreadSafe
<TestReceiverAudioCallback
>;
298 int expected_sampling_frequency_
;
299 int expected_min_snr_
;
300 int expected_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
> {
309 struct ExpectedVideoFrame
{
313 base::TimeTicks capture_time
;
316 TestReceiverVideoCallback()
319 void AddExpectedResult(int start_value
,
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
) {
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_
;}
362 virtual ~TestReceiverVideoCallback() {}
365 friend class base::RefCountedThreadSafe
<TestReceiverVideoCallback
>;
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
{
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()),
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
;
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_
,
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
);
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
);
490 audio_angle_
+= increment
;
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_
;
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
529 TEST_F(End2EndTest
, LoopNoLossPcm16
) {
530 // Note running codec in different sampling frequency.
531 SetupConfig(kPcm16
, 32000, false, 1);
533 test_receiver_audio_callback_
->SetExpectedResult(kAudioSamplingFrequency
, 20,
537 int audio_diff
= kFrameTimerMs
;
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
);
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
;
569 frame_receiver_
->GetRawAudioFrame(num_10ms_blocks
,
570 kAudioSamplingFrequency
,
571 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame
,
572 test_receiver_audio_callback_
));
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
;
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
599 const int audio_sampling_frequency
= 32000;
600 SetupConfig(kPcm16
, audio_sampling_frequency
, true, 1);
602 test_receiver_audio_callback_
->SetExpectedResult(audio_sampling_frequency
, 96,
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,
613 frame_input_
->InsertRawAudioFrame(audio_frame
, send_time
,
614 base::Bind(FrameInput::DeleteAudioFrame
, audio_frame
));
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);
629 test_receiver_audio_callback_
->SetExpectedResult(
630 kAudioSamplingFrequency
, 18, 20);
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
);
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
));
651 frame_receiver_
->GetRawAudioFrame(num_10ms_blocks
,
652 kAudioSamplingFrequency
,
653 base::Bind(&TestReceiverAudioCallback::IgnoreAudioFrame
,
654 test_receiver_audio_callback_
));
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);
670 test_receiver_audio_callback_
->SetExpectedResult(
671 kAudioSamplingFrequency
, 18, 20);
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
;
695 sender_to_receiver_
.SetSendPackets(true);
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_
));
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_
));
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;
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.
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
);
774 sender_to_receiver_
.SetSendPackets(true);
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;
798 sender_to_receiver_
.DropAllPacketsBelongingToOddFrames();
800 int video_start
= 50;
801 base::TimeTicks send_time
;
803 std::cout
<< "Progress ";
805 for (; i
< 20; ++i
) {
806 send_time
= testing_clock_
.NowTicks();
807 SendVideoFrame(video_start
, send_time
);
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
;
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.