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
19 #include "base/bind.h"
20 #include "base/bind_helpers.h"
21 #include "base/strings/string_number_conversions.h"
22 #include "base/sys_byteorder.h"
23 #include "base/test/simple_test_tick_clock.h"
24 #include "base/time/tick_clock.h"
25 #include "media/base/audio_bus.h"
26 #include "media/base/video_frame.h"
27 #include "media/cast/cast_config.h"
28 #include "media/cast/cast_environment.h"
29 #include "media/cast/cast_receiver.h"
30 #include "media/cast/cast_sender.h"
31 #include "media/cast/logging/simple_event_subscriber.h"
32 #include "media/cast/net/cast_transport_config.h"
33 #include "media/cast/net/cast_transport_defines.h"
34 #include "media/cast/net/cast_transport_sender.h"
35 #include "media/cast/net/cast_transport_sender_impl.h"
36 #include "media/cast/test/fake_single_thread_task_runner.h"
37 #include "media/cast/test/skewed_single_thread_task_runner.h"
38 #include "media/cast/test/skewed_tick_clock.h"
39 #include "media/cast/test/utility/audio_utility.h"
40 #include "media/cast/test/utility/default_config.h"
41 #include "media/cast/test/utility/udp_proxy.h"
42 #include "media/cast/test/utility/video_utility.h"
43 #include "testing/gtest/include/gtest/gtest.h"
50 static const int64 kStartMillisecond
= INT64_C(1245);
51 static const int kAudioChannels
= 2;
52 static const double kSoundFrequency
= 314.15926535897; // Freq of sine wave.
53 static const float kSoundVolume
= 0.5f
;
54 static const int kVideoHdWidth
= 1280;
55 static const int kVideoHdHeight
= 720;
56 static const int kVideoQcifWidth
= 176;
57 static const int kVideoQcifHeight
= 144;
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
61 // at least |kVideoAcceptedPSNR|.
62 static const double kVideoAcceptedPSNR
= 38.0;
64 // The tests are commonly implemented with |kFrameTimerMs| RunTask function;
65 // a normal video is 30 fps hence the 33 ms between frames.
67 // TODO(miu): The errors in timing will add up significantly. Find an
68 // alternative approach that eliminates use of this constant.
69 static const int kFrameTimerMs
= 33;
71 // Start the video synthetic start value to medium range value, to avoid edge
72 // effects cause by encoding and quantization.
73 static const int kVideoStart
= 100;
75 // The size of audio frames. The encoder joins/breaks all inserted audio into
76 // chunks of this size.
77 static const int kAudioFrameDurationMs
= 10;
79 // The amount of time between frame capture on the sender and playout on the
81 static const int kTargetPlayoutDelayMs
= 100;
83 // The maximum amount of deviation expected in the playout times emitted by the
85 static const int kMaxAllowedPlayoutErrorMs
= 30;
87 std::string
ConvertFromBase16String(const std::string base_16
) {
88 std::string compressed
;
89 DCHECK_EQ(base_16
.size() % 2, 0u) << "Must be a multiple of 2";
90 compressed
.reserve(base_16
.size() / 2);
93 if (!base::HexStringToBytes(base_16
, &v
)) {
96 compressed
.assign(reinterpret_cast<const char*>(&v
[0]), v
.size());
100 void UpdateCastTransportStatus(CastTransportStatus status
) {
101 bool result
= (status
== TRANSPORT_AUDIO_INITIALIZED
||
102 status
== TRANSPORT_VIDEO_INITIALIZED
);
106 void AudioInitializationStatus(CastInitializationStatus status
) {
107 EXPECT_EQ(STATUS_AUDIO_INITIALIZED
, status
);
110 void VideoInitializationStatus(CastInitializationStatus status
) {
111 EXPECT_EQ(STATUS_VIDEO_INITIALIZED
, status
);
114 // This is wrapped in a struct because it needs to be put into a std::map.
116 int counter
[kNumOfLoggingEvents
+1];
117 } LoggingEventCounts
;
119 // Constructs a map from each frame (RTP timestamp) to counts of each event
120 // type logged for that frame.
121 std::map
<RtpTimestamp
, LoggingEventCounts
> GetEventCountForFrameEvents(
122 const std::vector
<FrameEvent
>& frame_events
) {
123 std::map
<RtpTimestamp
, LoggingEventCounts
> event_counter_for_frame
;
124 for (std::vector
<FrameEvent
>::const_iterator it
= frame_events
.begin();
125 it
!= frame_events
.end();
127 std::map
<RtpTimestamp
, LoggingEventCounts
>::iterator map_it
=
128 event_counter_for_frame
.find(it
->rtp_timestamp
);
129 if (map_it
== event_counter_for_frame
.end()) {
130 LoggingEventCounts new_counter
;
131 memset(&new_counter
, 0, sizeof(new_counter
));
132 ++(new_counter
.counter
[it
->type
]);
133 event_counter_for_frame
.insert(
134 std::make_pair(it
->rtp_timestamp
, new_counter
));
136 ++(map_it
->second
.counter
[it
->type
]);
139 return event_counter_for_frame
;
142 // Constructs a map from each packet (Packet ID) to counts of each event
143 // type logged for that packet.
144 std::map
<uint16
, LoggingEventCounts
> GetEventCountForPacketEvents(
145 const std::vector
<PacketEvent
>& packet_events
) {
146 std::map
<uint16
, LoggingEventCounts
> event_counter_for_packet
;
147 for (std::vector
<PacketEvent
>::const_iterator it
= packet_events
.begin();
148 it
!= packet_events
.end();
150 std::map
<uint16
, LoggingEventCounts
>::iterator map_it
=
151 event_counter_for_packet
.find(it
->packet_id
);
152 if (map_it
== event_counter_for_packet
.end()) {
153 LoggingEventCounts new_counter
;
154 memset(&new_counter
, 0, sizeof(new_counter
));
155 ++(new_counter
.counter
[it
->type
]);
156 event_counter_for_packet
.insert(
157 std::make_pair(it
->packet_id
, new_counter
));
159 ++(map_it
->second
.counter
[it
->type
]);
162 return event_counter_for_packet
;
167 // Shim that turns forwards packets from a test::PacketPipe to a
168 // PacketReceiverCallback.
169 class LoopBackPacketPipe
: public test::PacketPipe
{
171 LoopBackPacketPipe(const PacketReceiverCallback
& packet_receiver
)
172 : packet_receiver_(packet_receiver
) {}
174 ~LoopBackPacketPipe() override
{}
176 // PacketPipe implementations.
177 void Send(scoped_ptr
<Packet
> packet
) override
{
178 packet_receiver_
.Run(packet
.Pass());
182 PacketReceiverCallback packet_receiver_
;
185 // Class that sends the packet direct from sender into the receiver with the
186 // ability to drop packets between the two.
187 class LoopBackTransport
: public PacketSender
{
189 explicit LoopBackTransport(scoped_refptr
<CastEnvironment
> cast_environment
)
190 : send_packets_(true),
191 drop_packets_belonging_to_odd_frames_(false),
192 cast_environment_(cast_environment
),
195 void SetPacketReceiver(
196 const PacketReceiverCallback
& packet_receiver
,
197 const scoped_refptr
<base::SingleThreadTaskRunner
>& task_runner
,
198 base::TickClock
* clock
) {
199 scoped_ptr
<test::PacketPipe
> loopback_pipe(
200 new LoopBackPacketPipe(packet_receiver
));
202 packet_pipe_
->AppendToPipe(loopback_pipe
.Pass());
204 packet_pipe_
= loopback_pipe
.Pass();
206 packet_pipe_
->InitOnIOThread(task_runner
, clock
);
209 bool SendPacket(PacketRef packet
, const base::Closure
& cb
) override
{
210 DCHECK(cast_environment_
->CurrentlyOn(CastEnvironment::MAIN
));
214 bytes_sent_
+= packet
->data
.size();
215 if (drop_packets_belonging_to_odd_frames_
) {
216 uint32 frame_id
= packet
->data
[13];
217 if (frame_id
% 2 == 1)
221 scoped_ptr
<Packet
> packet_copy(new Packet(packet
->data
));
222 packet_pipe_
->Send(packet_copy
.Pass());
226 int64
GetBytesSent() override
{ return bytes_sent_
; }
228 void SetSendPackets(bool send_packets
) { send_packets_
= send_packets
; }
230 void DropAllPacketsBelongingToOddFrames() {
231 drop_packets_belonging_to_odd_frames_
= true;
234 void SetPacketPipe(scoped_ptr
<test::PacketPipe
> pipe
) {
235 // Append the loopback pipe to the end.
236 pipe
->AppendToPipe(packet_pipe_
.Pass());
237 packet_pipe_
= pipe
.Pass();
242 bool drop_packets_belonging_to_odd_frames_
;
243 scoped_refptr
<CastEnvironment
> cast_environment_
;
244 scoped_ptr
<test::PacketPipe
> packet_pipe_
;
248 // Class that verifies the audio frames coming out of the receiver.
249 class TestReceiverAudioCallback
250 : public base::RefCountedThreadSafe
<TestReceiverAudioCallback
> {
252 struct ExpectedAudioFrame
{
253 scoped_ptr
<AudioBus
> audio_bus
;
254 base::TimeTicks playout_time
;
257 TestReceiverAudioCallback() : num_called_(0) {}
259 void SetExpectedSamplingFrequency(int expected_sampling_frequency
) {
260 expected_sampling_frequency_
= expected_sampling_frequency
;
263 void AddExpectedResult(const AudioBus
& audio_bus
,
264 const base::TimeTicks
& playout_time
) {
265 scoped_ptr
<ExpectedAudioFrame
> expected_audio_frame(
266 new ExpectedAudioFrame());
267 expected_audio_frame
->audio_bus
=
268 AudioBus::Create(audio_bus
.channels(), audio_bus
.frames()).Pass();
269 audio_bus
.CopyTo(expected_audio_frame
->audio_bus
.get());
270 expected_audio_frame
->playout_time
= playout_time
;
271 expected_frames_
.push_back(expected_audio_frame
.release());
274 void IgnoreAudioFrame(scoped_ptr
<AudioBus
> audio_bus
,
275 const base::TimeTicks
& playout_time
,
276 bool is_continuous
) {
280 void CheckAudioFrame(scoped_ptr
<AudioBus
> audio_bus
,
281 const base::TimeTicks
& playout_time
,
282 bool is_continuous
) {
285 ASSERT_TRUE(!!audio_bus
);
286 ASSERT_FALSE(expected_frames_
.empty());
287 const scoped_ptr
<ExpectedAudioFrame
> expected_audio_frame(
288 expected_frames_
.front());
289 expected_frames_
.pop_front();
291 EXPECT_EQ(audio_bus
->channels(), kAudioChannels
);
292 EXPECT_EQ(audio_bus
->frames(), expected_audio_frame
->audio_bus
->frames());
293 for (int ch
= 0; ch
< audio_bus
->channels(); ++ch
) {
294 EXPECT_NEAR(CountZeroCrossings(
295 expected_audio_frame
->audio_bus
->channel(ch
),
296 expected_audio_frame
->audio_bus
->frames()),
297 CountZeroCrossings(audio_bus
->channel(ch
),
298 audio_bus
->frames()),
303 (playout_time
- expected_audio_frame
->playout_time
).InMillisecondsF(),
305 kMaxAllowedPlayoutErrorMs
);
306 VLOG_IF(1, !last_playout_time_
.is_null())
307 << "Audio frame playout time delta (compared to last frame) is "
308 << (playout_time
- last_playout_time_
).InMicroseconds() << " usec.";
309 last_playout_time_
= playout_time
;
311 EXPECT_TRUE(is_continuous
);
314 void CheckCodedAudioFrame(scoped_ptr
<EncodedFrame
> audio_frame
) {
315 ASSERT_TRUE(!!audio_frame
);
316 ASSERT_FALSE(expected_frames_
.empty());
317 const ExpectedAudioFrame
& expected_audio_frame
=
318 *(expected_frames_
.front());
319 // Note: Just peeking here. Will delegate to CheckAudioFrame() to pop.
321 // We need to "decode" the encoded audio frame. The codec is simply to
322 // swizzle the bytes of each int16 from host-->network-->host order to get
323 // interleaved int16 PCM. Then, make an AudioBus out of that.
324 const int num_elements
= audio_frame
->data
.size() / sizeof(int16
);
325 ASSERT_EQ(expected_audio_frame
.audio_bus
->channels() *
326 expected_audio_frame
.audio_bus
->frames(),
328 int16
* const pcm_data
=
329 reinterpret_cast<int16
*>(audio_frame
->mutable_bytes());
330 for (int i
= 0; i
< num_elements
; ++i
)
331 pcm_data
[i
] = static_cast<int16
>(base::NetToHost16(pcm_data
[i
]));
332 scoped_ptr
<AudioBus
> audio_bus(
333 AudioBus::Create(expected_audio_frame
.audio_bus
->channels(),
334 expected_audio_frame
.audio_bus
->frames()));
335 audio_bus
->FromInterleaved(pcm_data
, audio_bus
->frames(), sizeof(int16
));
337 // Delegate the checking from here...
338 CheckAudioFrame(audio_bus
.Pass(), audio_frame
->reference_time
, true);
341 int number_times_called() const { return num_called_
; }
344 virtual ~TestReceiverAudioCallback() {
345 STLDeleteElements(&expected_frames_
);
349 friend class base::RefCountedThreadSafe
<TestReceiverAudioCallback
>;
352 int expected_sampling_frequency_
;
353 std::list
<ExpectedAudioFrame
*> expected_frames_
;
354 base::TimeTicks last_playout_time_
;
357 // Class that verifies the video frames coming out of the receiver.
358 class TestReceiverVideoCallback
359 : public base::RefCountedThreadSafe
<TestReceiverVideoCallback
> {
361 struct ExpectedVideoFrame
{
365 base::TimeTicks playout_time
;
366 bool should_be_continuous
;
369 TestReceiverVideoCallback() : num_called_(0) {}
371 void AddExpectedResult(int start_value
,
374 const base::TimeTicks
& playout_time
,
375 bool should_be_continuous
) {
376 ExpectedVideoFrame expected_video_frame
;
377 expected_video_frame
.start_value
= start_value
;
378 expected_video_frame
.width
= width
;
379 expected_video_frame
.height
= height
;
380 expected_video_frame
.playout_time
= playout_time
;
381 expected_video_frame
.should_be_continuous
= should_be_continuous
;
382 expected_frame_
.push_back(expected_video_frame
);
385 void CheckVideoFrame(const scoped_refptr
<media::VideoFrame
>& video_frame
,
386 const base::TimeTicks
& playout_time
,
387 bool is_continuous
) {
390 ASSERT_TRUE(!!video_frame
.get());
391 ASSERT_FALSE(expected_frame_
.empty());
392 ExpectedVideoFrame expected_video_frame
= expected_frame_
.front();
393 expected_frame_
.pop_front();
395 EXPECT_EQ(expected_video_frame
.width
, video_frame
->visible_rect().width());
396 EXPECT_EQ(expected_video_frame
.height
,
397 video_frame
->visible_rect().height());
399 gfx::Size
size(expected_video_frame
.width
, expected_video_frame
.height
);
400 scoped_refptr
<media::VideoFrame
> expected_I420_frame
=
401 media::VideoFrame::CreateFrame(
402 VideoFrame::I420
, size
, gfx::Rect(size
), size
, base::TimeDelta());
403 PopulateVideoFrame(expected_I420_frame
.get(),
404 expected_video_frame
.start_value
);
406 if (expected_video_frame
.should_be_continuous
) {
407 EXPECT_GE(I420PSNR(expected_I420_frame
, video_frame
), kVideoAcceptedPSNR
);
411 (playout_time
- expected_video_frame
.playout_time
).InMillisecondsF(),
413 kMaxAllowedPlayoutErrorMs
);
414 VLOG_IF(1, !last_playout_time_
.is_null())
415 << "Video frame playout time delta (compared to last frame) is "
416 << (playout_time
- last_playout_time_
).InMicroseconds() << " usec.";
417 last_playout_time_
= playout_time
;
419 EXPECT_EQ(expected_video_frame
.should_be_continuous
, is_continuous
);
422 int number_times_called() const { return num_called_
; }
425 virtual ~TestReceiverVideoCallback() {}
428 friend class base::RefCountedThreadSafe
<TestReceiverVideoCallback
>;
431 std::list
<ExpectedVideoFrame
> expected_frame_
;
432 base::TimeTicks last_playout_time_
;
435 // The actual test class, generate synthetic data for both audio and video and
436 // send those through the sender and receiver and analyzes the result.
437 class End2EndTest
: public ::testing::Test
{
441 task_runner_(new test::FakeSingleThreadTaskRunner(&testing_clock_
)),
442 testing_clock_sender_(new test::SkewedTickClock(&testing_clock_
)),
444 new test::SkewedSingleThreadTaskRunner(task_runner_
)),
445 testing_clock_receiver_(new test::SkewedTickClock(&testing_clock_
)),
446 task_runner_receiver_(
447 new test::SkewedSingleThreadTaskRunner(task_runner_
)),
448 cast_environment_sender_(new CastEnvironment(
449 scoped_ptr
<base::TickClock
>(testing_clock_sender_
).Pass(),
452 task_runner_sender_
)),
453 cast_environment_receiver_(new CastEnvironment(
454 scoped_ptr
<base::TickClock
>(testing_clock_receiver_
).Pass(),
455 task_runner_receiver_
,
456 task_runner_receiver_
,
457 task_runner_receiver_
)),
458 receiver_to_sender_(cast_environment_receiver_
),
459 sender_to_receiver_(cast_environment_sender_
),
460 test_receiver_audio_callback_(new TestReceiverAudioCallback()),
461 test_receiver_video_callback_(new TestReceiverVideoCallback()) {
462 testing_clock_
.Advance(
463 base::TimeDelta::FromMilliseconds(kStartMillisecond
));
464 cast_environment_sender_
->Logging()->AddRawEventSubscriber(
465 &event_subscriber_sender_
);
468 void Configure(Codec video_codec
,
470 int audio_sampling_frequency
,
471 int max_number_of_video_buffers_used
) {
472 audio_sender_config_
.ssrc
= 1;
473 audio_sender_config_
.incoming_feedback_ssrc
= 2;
474 audio_sender_config_
.max_playout_delay
=
475 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
);
476 audio_sender_config_
.rtp_payload_type
= 96;
477 audio_sender_config_
.use_external_encoder
= false;
478 audio_sender_config_
.frequency
= audio_sampling_frequency
;
479 audio_sender_config_
.channels
= kAudioChannels
;
480 audio_sender_config_
.bitrate
= kDefaultAudioEncoderBitrate
;
481 audio_sender_config_
.codec
= audio_codec
;
483 audio_receiver_config_
.feedback_ssrc
=
484 audio_sender_config_
.incoming_feedback_ssrc
;
485 audio_receiver_config_
.incoming_ssrc
= audio_sender_config_
.ssrc
;
486 audio_receiver_config_
.rtp_max_delay_ms
= kTargetPlayoutDelayMs
;
487 audio_receiver_config_
.rtp_payload_type
=
488 audio_sender_config_
.rtp_payload_type
;
489 audio_receiver_config_
.frequency
= audio_sender_config_
.frequency
;
490 audio_receiver_config_
.channels
= kAudioChannels
;
491 audio_receiver_config_
.max_frame_rate
= 100;
492 audio_receiver_config_
.codec
= audio_sender_config_
.codec
;
494 test_receiver_audio_callback_
->SetExpectedSamplingFrequency(
495 audio_receiver_config_
.frequency
);
497 video_sender_config_
.ssrc
= 3;
498 video_sender_config_
.incoming_feedback_ssrc
= 4;
499 video_sender_config_
.max_playout_delay
=
500 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
);
501 video_sender_config_
.rtp_payload_type
= 97;
502 video_sender_config_
.use_external_encoder
= false;
503 video_sender_config_
.width
= kVideoHdWidth
;
504 video_sender_config_
.height
= kVideoHdHeight
;
505 video_sender_config_
.max_bitrate
= 50000;
506 video_sender_config_
.min_bitrate
= 10000;
507 video_sender_config_
.start_bitrate
= 10000;
508 video_sender_config_
.max_qp
= 30;
509 video_sender_config_
.min_qp
= 4;
510 video_sender_config_
.max_frame_rate
= 30;
511 video_sender_config_
.max_number_of_video_buffers_used
=
512 max_number_of_video_buffers_used
;
513 video_sender_config_
.codec
= video_codec
;
515 video_receiver_config_
.feedback_ssrc
=
516 video_sender_config_
.incoming_feedback_ssrc
;
517 video_receiver_config_
.incoming_ssrc
= video_sender_config_
.ssrc
;
518 video_receiver_config_
.rtp_max_delay_ms
= kTargetPlayoutDelayMs
;
519 video_receiver_config_
.rtp_payload_type
=
520 video_sender_config_
.rtp_payload_type
;
521 video_receiver_config_
.frequency
= kVideoFrequency
;
522 video_receiver_config_
.channels
= 1;
523 video_receiver_config_
.max_frame_rate
= video_sender_config_
.max_frame_rate
;
524 video_receiver_config_
.codec
= video_sender_config_
.codec
;
527 void SetReceiverSkew(double skew
, base::TimeDelta offset
) {
528 testing_clock_receiver_
->SetSkew(skew
, offset
);
529 task_runner_receiver_
->SetSkew(1.0 / skew
);
532 // Specify the minimum/maximum difference in playout times between two
533 // consecutive frames. Also, specify the maximum absolute rate of change over
534 // each three consecutive frames.
535 void SetExpectedVideoPlayoutSmoothness(base::TimeDelta min_delta
,
536 base::TimeDelta max_delta
,
537 base::TimeDelta max_curvature
) {
538 min_video_playout_delta_
= min_delta
;
539 max_video_playout_delta_
= max_delta
;
540 max_video_playout_curvature_
= max_curvature
;
543 void FeedAudioFrames(int count
, bool will_be_checked
) {
544 for (int i
= 0; i
< count
; ++i
) {
545 scoped_ptr
<AudioBus
> audio_bus(audio_bus_factory_
->NextAudioBus(
546 base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs
)));
547 const base::TimeTicks reference_time
=
548 testing_clock_sender_
->NowTicks() +
549 i
* base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs
);
550 if (will_be_checked
) {
551 test_receiver_audio_callback_
->AddExpectedResult(
554 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
));
556 audio_frame_input_
->InsertAudio(audio_bus
.Pass(), reference_time
);
560 void FeedAudioFramesWithExpectedDelay(int count
,
561 const base::TimeDelta
& delay
) {
562 for (int i
= 0; i
< count
; ++i
) {
563 scoped_ptr
<AudioBus
> audio_bus(audio_bus_factory_
->NextAudioBus(
564 base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs
)));
565 const base::TimeTicks reference_time
=
566 testing_clock_sender_
->NowTicks() +
567 i
* base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs
);
568 test_receiver_audio_callback_
->AddExpectedResult(
570 reference_time
+ delay
+
571 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
));
572 audio_frame_input_
->InsertAudio(audio_bus
.Pass(), reference_time
);
576 void RequestAudioFrames(int count
, bool with_check
) {
577 for (int i
= 0; i
< count
; ++i
) {
578 cast_receiver_
->RequestDecodedAudioFrame(
579 base::Bind(with_check
? &TestReceiverAudioCallback::CheckAudioFrame
:
580 &TestReceiverAudioCallback::IgnoreAudioFrame
,
581 test_receiver_audio_callback_
));
586 cast_receiver_
= CastReceiver::Create(cast_environment_receiver_
,
587 audio_receiver_config_
,
588 video_receiver_config_
,
589 &receiver_to_sender_
);
591 net::IPEndPoint dummy_endpoint
;
592 transport_sender_
.reset(new CastTransportSenderImpl(
594 testing_clock_sender_
,
596 make_scoped_ptr(new base::DictionaryValue
),
597 base::Bind(&UpdateCastTransportStatus
),
598 base::Bind(&End2EndTest::LogRawEvents
, base::Unretained(this)),
599 base::TimeDelta::FromMilliseconds(1),
601 &sender_to_receiver_
));
604 CastSender::Create(cast_environment_sender_
, transport_sender_
.get());
606 // Initializing audio and video senders.
607 cast_sender_
->InitializeAudio(audio_sender_config_
,
608 base::Bind(&AudioInitializationStatus
));
609 cast_sender_
->InitializeVideo(video_sender_config_
,
610 base::Bind(&VideoInitializationStatus
),
611 CreateDefaultVideoEncodeAcceleratorCallback(),
612 CreateDefaultVideoEncodeMemoryCallback());
613 task_runner_
->RunTasks();
615 receiver_to_sender_
.SetPacketReceiver(
616 transport_sender_
->PacketReceiverForTesting(),
619 sender_to_receiver_
.SetPacketReceiver(cast_receiver_
->packet_receiver(),
623 audio_frame_input_
= cast_sender_
->audio_frame_input();
624 video_frame_input_
= cast_sender_
->video_frame_input();
626 audio_bus_factory_
.reset(
627 new TestAudioBusFactory(audio_sender_config_
.channels
,
628 audio_sender_config_
.frequency
,
633 ~End2EndTest() override
{
634 cast_environment_sender_
->Logging()->RemoveRawEventSubscriber(
635 &event_subscriber_sender_
);
638 void TearDown() override
{
639 cast_sender_
.reset();
640 cast_receiver_
.reset();
641 task_runner_
->RunTasks();
644 void SendVideoFrame(int start_value
, const base::TimeTicks
& reference_time
) {
645 if (start_time_
.is_null())
646 start_time_
= reference_time
;
647 // TODO(miu): Consider using a slightly skewed clock for the media timestamp
648 // since the video clock may not be the same as the reference clock.
649 const base::TimeDelta time_diff
= reference_time
- start_time_
;
650 gfx::Size
size(video_sender_config_
.width
, video_sender_config_
.height
);
651 EXPECT_TRUE(VideoFrame::IsValidConfig(
652 VideoFrame::I420
, size
, gfx::Rect(size
), size
));
653 scoped_refptr
<media::VideoFrame
> video_frame
=
654 media::VideoFrame::CreateFrame(
655 VideoFrame::I420
, size
, gfx::Rect(size
), size
,
657 PopulateVideoFrame(video_frame
.get(), start_value
);
658 video_frame_input_
->InsertRawVideoFrame(video_frame
, reference_time
);
661 void SendFakeVideoFrame(const base::TimeTicks
& reference_time
) {
662 if (start_time_
.is_null())
663 start_time_
= reference_time
;
664 const scoped_refptr
<media::VideoFrame
> black_frame
=
665 media::VideoFrame::CreateBlackFrame(gfx::Size(2, 2));
666 // TODO(miu): Consider using a slightly skewed clock for the media timestamp
667 // since the video clock may not be the same as the reference clock.
668 black_frame
->set_timestamp(reference_time
- start_time_
);
669 video_frame_input_
->InsertRawVideoFrame(black_frame
, reference_time
);
672 void RunTasks(int ms
) {
673 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(ms
));
676 void BasicPlayerGotVideoFrame(
677 const scoped_refptr
<media::VideoFrame
>& video_frame
,
678 const base::TimeTicks
& playout_time
, bool continuous
) {
679 // The following tests that the sender and receiver clocks can be
680 // out-of-sync, drift, and jitter with respect to one another; and depsite
681 // this, the receiver will produce smoothly-progressing playout times.
682 // Both first-order and second-order effects are tested.
683 if (!last_video_playout_time_
.is_null() &&
684 min_video_playout_delta_
> base::TimeDelta()) {
685 const base::TimeDelta delta
= playout_time
- last_video_playout_time_
;
686 VLOG(1) << "Video frame playout time delta (compared to last frame) is "
687 << delta
.InMicroseconds() << " usec.";
688 EXPECT_LE(min_video_playout_delta_
.InMicroseconds(),
689 delta
.InMicroseconds());
690 EXPECT_GE(max_video_playout_delta_
.InMicroseconds(),
691 delta
.InMicroseconds());
692 if (last_video_playout_delta_
> base::TimeDelta()) {
693 base::TimeDelta abs_curvature
= delta
- last_video_playout_delta_
;
694 if (abs_curvature
< base::TimeDelta())
695 abs_curvature
= -abs_curvature
;
696 EXPECT_GE(max_video_playout_curvature_
.InMicroseconds(),
697 abs_curvature
.InMicroseconds());
699 last_video_playout_delta_
= delta
;
701 last_video_playout_time_
= playout_time
;
703 video_ticks_
.push_back(std::make_pair(
704 testing_clock_receiver_
->NowTicks(),
706 cast_receiver_
->RequestDecodedVideoFrame(
707 base::Bind(&End2EndTest::BasicPlayerGotVideoFrame
,
708 base::Unretained(this)));
711 void BasicPlayerGotAudioFrame(scoped_ptr
<AudioBus
> audio_bus
,
712 const base::TimeTicks
& playout_time
,
713 bool is_continuous
) {
714 VLOG_IF(1, !last_audio_playout_time_
.is_null())
715 << "Audio frame playout time delta (compared to last frame) is "
716 << (playout_time
- last_audio_playout_time_
).InMicroseconds()
718 last_audio_playout_time_
= playout_time
;
720 audio_ticks_
.push_back(std::make_pair(
721 testing_clock_receiver_
->NowTicks(),
723 cast_receiver_
->RequestDecodedAudioFrame(
724 base::Bind(&End2EndTest::BasicPlayerGotAudioFrame
,
725 base::Unretained(this)));
728 void StartBasicPlayer() {
729 cast_receiver_
->RequestDecodedVideoFrame(
730 base::Bind(&End2EndTest::BasicPlayerGotVideoFrame
,
731 base::Unretained(this)));
732 cast_receiver_
->RequestDecodedAudioFrame(
733 base::Bind(&End2EndTest::BasicPlayerGotAudioFrame
,
734 base::Unretained(this)));
737 void LogRawEvents(const std::vector
<PacketEvent
>& packet_events
,
738 const std::vector
<FrameEvent
>& frame_events
) {
739 for (std::vector
<media::cast::PacketEvent
>::const_iterator it
=
740 packet_events
.begin();
741 it
!= packet_events
.end();
743 cast_environment_sender_
->Logging()->InsertPacketEvent(it
->timestamp
,
752 for (std::vector
<media::cast::FrameEvent
>::const_iterator it
=
753 frame_events
.begin();
754 it
!= frame_events
.end();
756 cast_environment_sender_
->Logging()->InsertFrameEvent(it
->timestamp
,
764 FrameReceiverConfig audio_receiver_config_
;
765 FrameReceiverConfig video_receiver_config_
;
766 AudioSenderConfig audio_sender_config_
;
767 VideoSenderConfig video_sender_config_
;
769 base::TimeTicks start_time_
;
771 // These run in "test time"
772 base::SimpleTestTickClock testing_clock_
;
773 scoped_refptr
<test::FakeSingleThreadTaskRunner
> task_runner_
;
775 // These run on the sender timeline.
776 test::SkewedTickClock
* testing_clock_sender_
;
777 scoped_refptr
<test::SkewedSingleThreadTaskRunner
> task_runner_sender_
;
779 // These run on the receiver timeline.
780 test::SkewedTickClock
* testing_clock_receiver_
;
781 scoped_refptr
<test::SkewedSingleThreadTaskRunner
> task_runner_receiver_
;
782 base::TimeDelta min_video_playout_delta_
;
783 base::TimeDelta max_video_playout_delta_
;
784 base::TimeDelta max_video_playout_curvature_
;
785 base::TimeTicks last_video_playout_time_
;
786 base::TimeDelta last_video_playout_delta_
;
787 base::TimeTicks last_audio_playout_time_
;
789 scoped_refptr
<CastEnvironment
> cast_environment_sender_
;
790 scoped_refptr
<CastEnvironment
> cast_environment_receiver_
;
792 LoopBackTransport receiver_to_sender_
;
793 LoopBackTransport sender_to_receiver_
;
794 scoped_ptr
<CastTransportSenderImpl
> transport_sender_
;
796 scoped_ptr
<CastReceiver
> cast_receiver_
;
797 scoped_ptr
<CastSender
> cast_sender_
;
798 scoped_refptr
<AudioFrameInput
> audio_frame_input_
;
799 scoped_refptr
<VideoFrameInput
> video_frame_input_
;
801 scoped_refptr
<TestReceiverAudioCallback
> test_receiver_audio_callback_
;
802 scoped_refptr
<TestReceiverVideoCallback
> test_receiver_video_callback_
;
804 scoped_ptr
<TestAudioBusFactory
> audio_bus_factory_
;
806 SimpleEventSubscriber event_subscriber_sender_
;
807 std::vector
<FrameEvent
> frame_events_
;
808 std::vector
<PacketEvent
> packet_events_
;
809 std::vector
<std::pair
<base::TimeTicks
, base::TimeTicks
> > audio_ticks_
;
810 std::vector
<std::pair
<base::TimeTicks
, base::TimeTicks
> > video_ticks_
;
811 // |transport_sender_| has a RepeatingTimer which needs a MessageLoop.
812 base::MessageLoop message_loop_
;
815 TEST_F(End2EndTest
, LoopNoLossPcm16
) {
816 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_PCM16
, 32000, 1);
817 // Reduce video resolution to allow processing multiple frames within a
818 // reasonable time frame.
819 video_sender_config_
.width
= kVideoQcifWidth
;
820 video_sender_config_
.height
= kVideoQcifHeight
;
823 const int kNumIterations
= 50;
824 int video_start
= kVideoStart
;
825 int audio_diff
= kFrameTimerMs
;
826 int num_audio_frames_requested
= 0;
827 for (int i
= 0; i
< kNumIterations
; ++i
) {
828 const int num_audio_frames
= audio_diff
/ kAudioFrameDurationMs
;
829 audio_diff
-= num_audio_frames
* kAudioFrameDurationMs
;
831 if (num_audio_frames
> 0)
832 FeedAudioFrames(1, true);
834 test_receiver_video_callback_
->AddExpectedResult(
836 video_sender_config_
.width
,
837 video_sender_config_
.height
,
838 testing_clock_sender_
->NowTicks() +
839 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
),
841 SendVideoFrame(video_start
, testing_clock_sender_
->NowTicks());
843 if (num_audio_frames
> 0)
844 RunTasks(kAudioFrameDurationMs
); // Advance clock forward.
845 if (num_audio_frames
> 1)
846 FeedAudioFrames(num_audio_frames
- 1, true);
848 RequestAudioFrames(num_audio_frames
, true);
849 num_audio_frames_requested
+= num_audio_frames
;
851 cast_receiver_
->RequestDecodedVideoFrame(
852 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame
,
853 test_receiver_video_callback_
));
855 RunTasks(kFrameTimerMs
- kAudioFrameDurationMs
);
856 audio_diff
+= kFrameTimerMs
;
860 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the receiver pipeline.
861 EXPECT_EQ(num_audio_frames_requested
,
862 test_receiver_audio_callback_
->number_times_called());
863 EXPECT_EQ(kNumIterations
,
864 test_receiver_video_callback_
->number_times_called());
867 // This tests our external decoder interface for Audio.
868 // Audio test without packet loss using raw PCM 16 audio "codec";
869 TEST_F(End2EndTest
, LoopNoLossPcm16ExternalDecoder
) {
870 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_PCM16
, 32000, 1);
873 const int kNumIterations
= 10;
874 for (int i
= 0; i
< kNumIterations
; ++i
) {
875 FeedAudioFrames(1, true);
876 RunTasks(kAudioFrameDurationMs
);
877 cast_receiver_
->RequestEncodedAudioFrame(
878 base::Bind(&TestReceiverAudioCallback::CheckCodedAudioFrame
,
879 test_receiver_audio_callback_
));
881 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the receiver pipeline.
882 EXPECT_EQ(kNumIterations
,
883 test_receiver_audio_callback_
->number_times_called());
886 // This tests our Opus audio codec without video.
887 TEST_F(End2EndTest
, LoopNoLossOpus
) {
888 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_OPUS
,
889 kDefaultAudioSamplingRate
, 1);
892 const int kNumIterations
= 300;
893 for (int i
= 0; i
< kNumIterations
; ++i
) {
894 // Opus introduces a tiny delay before the sinewave starts; so don't examine
896 const bool examine_audio_data
= i
> 0;
897 FeedAudioFrames(1, examine_audio_data
);
898 RunTasks(kAudioFrameDurationMs
);
899 RequestAudioFrames(1, examine_audio_data
);
901 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the receiver pipeline.
902 EXPECT_EQ(kNumIterations
,
903 test_receiver_audio_callback_
->number_times_called());
906 // This tests start sending audio and video at start-up time before the receiver
907 // is ready; it sends 2 frames before the receiver comes online.
909 // Test disabled due to flakiness: It appears that the RTCP synchronization
910 // sometimes kicks in, and sometimes doesn't. When it does, there's a sharp
911 // discontinuity in the timeline, throwing off the test expectations. See TODOs
912 // in audio_receiver.cc for likely cause(s) of this bug.
913 // http://crbug.com/356942
914 TEST_F(End2EndTest
, DISABLED_StartSenderBeforeReceiver
) {
915 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_PCM16
,
916 kDefaultAudioSamplingRate
, 1);
919 int video_start
= kVideoStart
;
920 int audio_diff
= kFrameTimerMs
;
922 sender_to_receiver_
.SetSendPackets(false);
924 const int test_delay_ms
= 100;
926 const int kNumVideoFramesBeforeReceiverStarted
= 2;
927 const base::TimeTicks initial_send_time
= testing_clock_sender_
->NowTicks();
928 const base::TimeDelta expected_delay
=
929 base::TimeDelta::FromMilliseconds(test_delay_ms
+ kFrameTimerMs
);
930 for (int i
= 0; i
< kNumVideoFramesBeforeReceiverStarted
; ++i
) {
931 const int num_audio_frames
= audio_diff
/ kAudioFrameDurationMs
;
932 audio_diff
-= num_audio_frames
* kAudioFrameDurationMs
;
934 if (num_audio_frames
> 0)
935 FeedAudioFramesWithExpectedDelay(1, expected_delay
);
937 // Frame will be rendered with 100mS delay, as the transmission is delayed.
938 // The receiver at this point cannot be synced to the sender's clock, as no
939 // packets, and specifically no RTCP packets were sent.
940 test_receiver_video_callback_
->AddExpectedResult(
942 video_sender_config_
.width
,
943 video_sender_config_
.height
,
944 initial_send_time
+ expected_delay
+
945 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
),
947 SendVideoFrame(video_start
, testing_clock_sender_
->NowTicks());
949 if (num_audio_frames
> 0)
950 RunTasks(kAudioFrameDurationMs
); // Advance clock forward.
951 if (num_audio_frames
> 1)
952 FeedAudioFramesWithExpectedDelay(num_audio_frames
- 1, expected_delay
);
954 RunTasks(kFrameTimerMs
- kAudioFrameDurationMs
);
955 audio_diff
+= kFrameTimerMs
;
959 RunTasks(test_delay_ms
);
960 sender_to_receiver_
.SetSendPackets(true);
962 int num_audio_frames_requested
= 0;
963 for (int j
= 0; j
< 10; ++j
) {
964 const int num_audio_frames
= audio_diff
/ kAudioFrameDurationMs
;
965 audio_diff
-= num_audio_frames
* kAudioFrameDurationMs
;
967 if (num_audio_frames
> 0)
968 FeedAudioFrames(1, true);
970 test_receiver_video_callback_
->AddExpectedResult(
972 video_sender_config_
.width
,
973 video_sender_config_
.height
,
974 testing_clock_sender_
->NowTicks() +
975 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
),
977 SendVideoFrame(video_start
, testing_clock_sender_
->NowTicks());
979 if (num_audio_frames
> 0)
980 RunTasks(kAudioFrameDurationMs
); // Advance clock forward.
981 if (num_audio_frames
> 1)
982 FeedAudioFrames(num_audio_frames
- 1, true);
984 RequestAudioFrames(num_audio_frames
, true);
985 num_audio_frames_requested
+= num_audio_frames
;
987 cast_receiver_
->RequestDecodedVideoFrame(
988 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame
,
989 test_receiver_video_callback_
));
991 RunTasks(kFrameTimerMs
- kAudioFrameDurationMs
);
992 audio_diff
+= kFrameTimerMs
;
995 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the receiver pipeline.
996 EXPECT_EQ(num_audio_frames_requested
,
997 test_receiver_audio_callback_
->number_times_called());
998 EXPECT_EQ(10, test_receiver_video_callback_
->number_times_called());
1001 TEST_F(End2EndTest
, DropEveryOtherFrame3Buffers
) {
1002 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_OPUS
, kDefaultAudioSamplingRate
, 3);
1003 int target_delay
= 300;
1004 video_sender_config_
.max_playout_delay
=
1005 base::TimeDelta::FromMilliseconds(target_delay
);
1006 audio_sender_config_
.max_playout_delay
=
1007 base::TimeDelta::FromMilliseconds(target_delay
);
1008 video_receiver_config_
.rtp_max_delay_ms
= target_delay
;
1010 sender_to_receiver_
.DropAllPacketsBelongingToOddFrames();
1012 int video_start
= kVideoStart
;
1013 base::TimeTicks reference_time
;
1016 for (; i
< 20; ++i
) {
1017 reference_time
= testing_clock_sender_
->NowTicks();
1018 SendVideoFrame(video_start
, reference_time
);
1021 test_receiver_video_callback_
->AddExpectedResult(
1023 video_sender_config_
.width
,
1024 video_sender_config_
.height
,
1025 reference_time
+ base::TimeDelta::FromMilliseconds(target_delay
),
1028 // GetRawVideoFrame will not return the frame until we are close in
1029 // time before we should render the frame.
1030 cast_receiver_
->RequestDecodedVideoFrame(
1031 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame
,
1032 test_receiver_video_callback_
));
1034 RunTasks(kFrameTimerMs
);
1038 RunTasks(2 * kFrameTimerMs
+ target_delay
); // Empty the pipeline.
1039 EXPECT_EQ(i
/ 2, test_receiver_video_callback_
->number_times_called());
1042 TEST_F(End2EndTest
, CryptoVideo
) {
1043 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_PCM16
, 32000, 1);
1045 video_sender_config_
.aes_iv_mask
=
1046 ConvertFromBase16String("1234567890abcdeffedcba0987654321");
1047 video_sender_config_
.aes_key
=
1048 ConvertFromBase16String("deadbeefcafeb0b0b0b0cafedeadbeef");
1050 video_receiver_config_
.aes_iv_mask
=
1051 video_sender_config_
.aes_iv_mask
;
1052 video_receiver_config_
.aes_key
=
1053 video_sender_config_
.aes_key
;
1057 int frames_counter
= 0;
1058 for (; frames_counter
< 3; ++frames_counter
) {
1059 const base::TimeTicks reference_time
= testing_clock_sender_
->NowTicks();
1060 SendVideoFrame(frames_counter
, reference_time
);
1062 test_receiver_video_callback_
->AddExpectedResult(
1064 video_sender_config_
.width
,
1065 video_sender_config_
.height
,
1067 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
),
1070 RunTasks(kFrameTimerMs
);
1072 cast_receiver_
->RequestDecodedVideoFrame(
1073 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame
,
1074 test_receiver_video_callback_
));
1076 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the pipeline.
1077 EXPECT_EQ(frames_counter
,
1078 test_receiver_video_callback_
->number_times_called());
1081 TEST_F(End2EndTest
, CryptoAudio
) {
1082 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_PCM16
, 32000, 1);
1084 audio_sender_config_
.aes_iv_mask
=
1085 ConvertFromBase16String("abcdeffedcba12345678900987654321");
1086 audio_sender_config_
.aes_key
=
1087 ConvertFromBase16String("deadbeefcafecafedeadbeefb0b0b0b0");
1089 audio_receiver_config_
.aes_iv_mask
=
1090 audio_sender_config_
.aes_iv_mask
;
1091 audio_receiver_config_
.aes_key
=
1092 audio_sender_config_
.aes_key
;
1096 const int kNumIterations
= 3;
1097 const int kNumAudioFramesPerIteration
= 2;
1098 for (int i
= 0; i
< kNumIterations
; ++i
) {
1099 FeedAudioFrames(kNumAudioFramesPerIteration
, true);
1100 RunTasks(kNumAudioFramesPerIteration
* kAudioFrameDurationMs
);
1101 RequestAudioFrames(kNumAudioFramesPerIteration
, true);
1103 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the pipeline.
1104 EXPECT_EQ(kNumIterations
* kNumAudioFramesPerIteration
,
1105 test_receiver_audio_callback_
->number_times_called());
1108 // Video test without packet loss - tests the logging aspects of the end2end,
1109 // but is basically equivalent to LoopNoLossPcm16.
1110 TEST_F(End2EndTest
, VideoLogging
) {
1111 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_PCM16
, 32000, 1);
1114 int video_start
= kVideoStart
;
1115 const int num_frames
= 5;
1116 for (int i
= 0; i
< num_frames
; ++i
) {
1117 base::TimeTicks reference_time
= testing_clock_sender_
->NowTicks();
1118 test_receiver_video_callback_
->AddExpectedResult(
1120 video_sender_config_
.width
,
1121 video_sender_config_
.height
,
1123 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
),
1126 SendVideoFrame(video_start
, reference_time
);
1127 RunTasks(kFrameTimerMs
);
1129 cast_receiver_
->RequestDecodedVideoFrame(
1130 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame
,
1131 test_receiver_video_callback_
));
1137 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the receiver pipeline.
1138 int num_callbacks_called
=
1139 test_receiver_video_callback_
->number_times_called();
1140 EXPECT_EQ(num_frames
, num_callbacks_called
);
1142 RunTasks(750); // Make sure that we send a RTCP message with the log.
1146 // Verify that all frames and all required events were logged.
1147 event_subscriber_sender_
.GetFrameEventsAndReset(&frame_events_
);
1149 // For each frame, count the number of events that occurred for each event
1151 std::map
<RtpTimestamp
, LoggingEventCounts
> event_counter_for_frame
=
1152 GetEventCountForFrameEvents(frame_events_
);
1154 // Verify that there are logs for expected number of frames.
1155 EXPECT_EQ(num_frames
, static_cast<int>(event_counter_for_frame
.size()));
1157 // Verify that each frame have the expected types of events logged.
1158 for (std::map
<RtpTimestamp
, LoggingEventCounts
>::iterator map_it
=
1159 event_counter_for_frame
.begin();
1160 map_it
!= event_counter_for_frame
.end();
1162 int total_event_count_for_frame
= 0;
1163 for (int i
= 0; i
<= kNumOfLoggingEvents
; ++i
) {
1164 total_event_count_for_frame
+= map_it
->second
.counter
[i
];
1167 int expected_event_count_for_frame
= 0;
1169 EXPECT_EQ(1, map_it
->second
.counter
[FRAME_CAPTURE_BEGIN
]);
1170 expected_event_count_for_frame
+=
1171 map_it
->second
.counter
[FRAME_CAPTURE_BEGIN
];
1173 EXPECT_EQ(1, map_it
->second
.counter
[FRAME_CAPTURE_END
]);
1174 expected_event_count_for_frame
+=
1175 map_it
->second
.counter
[FRAME_CAPTURE_END
];
1177 EXPECT_EQ(1, map_it
->second
.counter
[FRAME_ENCODED
]);
1178 expected_event_count_for_frame
+=
1179 map_it
->second
.counter
[FRAME_ENCODED
];
1181 EXPECT_EQ(1, map_it
->second
.counter
[FRAME_DECODED
]);
1182 expected_event_count_for_frame
+=
1183 map_it
->second
.counter
[FRAME_DECODED
];
1185 EXPECT_EQ(1, map_it
->second
.counter
[FRAME_PLAYOUT
]);
1186 expected_event_count_for_frame
+= map_it
->second
.counter
[FRAME_PLAYOUT
];
1189 // There is no guarantee that FRAME_ACK_SENT is loggeed exactly once per
1191 EXPECT_GT(map_it
->second
.counter
[FRAME_ACK_SENT
], 0);
1192 expected_event_count_for_frame
+= map_it
->second
.counter
[FRAME_ACK_SENT
];
1194 // There is no guarantee that FRAME_ACK_RECEIVED is loggeed exactly once per
1196 EXPECT_GT(map_it
->second
.counter
[FRAME_ACK_RECEIVED
], 0);
1197 expected_event_count_for_frame
+=
1198 map_it
->second
.counter
[FRAME_ACK_RECEIVED
];
1200 // Verify that there were no other events logged with respect to this
1202 // (i.e. Total event count = expected event count)
1203 EXPECT_EQ(total_event_count_for_frame
, expected_event_count_for_frame
);
1207 // Verify that all packet related events were logged.
1208 event_subscriber_sender_
.GetPacketEventsAndReset(&packet_events_
);
1209 std::map
<uint16
, LoggingEventCounts
> event_count_for_packet
=
1210 GetEventCountForPacketEvents(packet_events_
);
1212 // Verify that each packet have the expected types of events logged.
1213 for (std::map
<uint16
, LoggingEventCounts
>::iterator map_it
=
1214 event_count_for_packet
.begin();
1215 map_it
!= event_count_for_packet
.end();
1217 int total_event_count_for_packet
= 0;
1218 for (int i
= 0; i
<= kNumOfLoggingEvents
; ++i
) {
1219 total_event_count_for_packet
+= map_it
->second
.counter
[i
];
1222 EXPECT_GT(map_it
->second
.counter
[PACKET_RECEIVED
], 0);
1223 int packets_received
= map_it
->second
.counter
[PACKET_RECEIVED
];
1224 int packets_sent
= map_it
->second
.counter
[PACKET_SENT_TO_NETWORK
];
1225 EXPECT_EQ(packets_sent
, packets_received
);
1227 // Verify that there were no other events logged with respect to this
1228 // packet. (i.e. Total event count = packets sent + packets received)
1229 EXPECT_EQ(packets_received
+ packets_sent
, total_event_count_for_packet
);
1233 // Audio test without packet loss - tests the logging aspects of the end2end,
1234 // but is basically equivalent to LoopNoLossPcm16.
1235 TEST_F(End2EndTest
, AudioLogging
) {
1236 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_PCM16
, 32000, 1);
1239 int audio_diff
= kFrameTimerMs
;
1240 const int kNumVideoFrames
= 10;
1241 int num_audio_frames_requested
= 0;
1242 for (int i
= 0; i
< kNumVideoFrames
; ++i
) {
1243 const int num_audio_frames
= audio_diff
/ kAudioFrameDurationMs
;
1244 audio_diff
-= num_audio_frames
* kAudioFrameDurationMs
;
1246 FeedAudioFrames(num_audio_frames
, true);
1248 RunTasks(kFrameTimerMs
);
1249 audio_diff
+= kFrameTimerMs
;
1251 RequestAudioFrames(num_audio_frames
, true);
1252 num_audio_frames_requested
+= num_audio_frames
;
1256 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the receiver pipeline.
1258 EXPECT_EQ(num_audio_frames_requested
,
1259 test_receiver_audio_callback_
->number_times_called());
1262 // Verify that all frames and all required events were logged.
1263 event_subscriber_sender_
.GetFrameEventsAndReset(&frame_events_
);
1265 // Construct a map from each frame (RTP timestamp) to a count of each event
1266 // type logged for that frame.
1267 std::map
<RtpTimestamp
, LoggingEventCounts
> event_counter_for_frame
=
1268 GetEventCountForFrameEvents(frame_events_
);
1270 int encoded_count
= 0;
1272 // Verify the right number of events were logged for each event type.
1273 for (std::map
<RtpTimestamp
, LoggingEventCounts
>::iterator it
=
1274 event_counter_for_frame
.begin();
1275 it
!= event_counter_for_frame
.end();
1277 encoded_count
+= it
->second
.counter
[FRAME_ENCODED
];
1280 EXPECT_EQ(num_audio_frames_requested
, encoded_count
);
1282 // Verify that each frame have the expected types of events logged.
1283 for (std::map
<RtpTimestamp
, LoggingEventCounts
>::const_iterator map_it
=
1284 event_counter_for_frame
.begin();
1285 map_it
!= event_counter_for_frame
.end(); ++map_it
) {
1286 int total_event_count_for_frame
= 0;
1287 for (int j
= 0; j
<= kNumOfLoggingEvents
; ++j
)
1288 total_event_count_for_frame
+= map_it
->second
.counter
[j
];
1290 int expected_event_count_for_frame
= 0;
1292 EXPECT_EQ(1, map_it
->second
.counter
[FRAME_ENCODED
]);
1293 expected_event_count_for_frame
+=
1294 map_it
->second
.counter
[FRAME_ENCODED
];
1296 EXPECT_EQ(1, map_it
->second
.counter
[FRAME_PLAYOUT
]);
1297 expected_event_count_for_frame
+=
1298 map_it
->second
.counter
[FRAME_PLAYOUT
];
1300 EXPECT_EQ(1, map_it
->second
.counter
[FRAME_DECODED
]);
1301 expected_event_count_for_frame
+=
1302 map_it
->second
.counter
[FRAME_DECODED
];
1304 EXPECT_GT(map_it
->second
.counter
[FRAME_ACK_SENT
], 0);
1305 EXPECT_GT(map_it
->second
.counter
[FRAME_ACK_RECEIVED
], 0);
1306 expected_event_count_for_frame
+= map_it
->second
.counter
[FRAME_ACK_SENT
];
1307 expected_event_count_for_frame
+=
1308 map_it
->second
.counter
[FRAME_ACK_RECEIVED
];
1310 // Verify that there were no other events logged with respect to this frame.
1311 // (i.e. Total event count = expected event count)
1312 EXPECT_EQ(total_event_count_for_frame
, expected_event_count_for_frame
);
1316 TEST_F(End2EndTest
, BasicFakeSoftwareVideo
) {
1317 Configure(CODEC_VIDEO_FAKE
, CODEC_AUDIO_PCM16
, 32000,
1321 SetReceiverSkew(1.0, base::TimeDelta::FromMilliseconds(1));
1323 // Expect very smooth playout when there is no clock skew.
1324 SetExpectedVideoPlayoutSmoothness(
1325 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) * 99 / 100,
1326 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) * 101 / 100,
1327 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) / 100);
1329 int frames_counter
= 0;
1330 for (; frames_counter
< 1000; ++frames_counter
) {
1331 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1332 RunTasks(kFrameTimerMs
);
1334 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the pipeline.
1335 EXPECT_EQ(1000ul, video_ticks_
.size());
1338 TEST_F(End2EndTest
, ReceiverClockFast
) {
1339 Configure(CODEC_VIDEO_FAKE
, CODEC_AUDIO_PCM16
, 32000,
1343 SetReceiverSkew(2.0, base::TimeDelta::FromMicroseconds(1234567));
1345 int frames_counter
= 0;
1346 for (; frames_counter
< 10000; ++frames_counter
) {
1347 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1348 RunTasks(kFrameTimerMs
);
1350 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the pipeline.
1351 EXPECT_EQ(10000ul, video_ticks_
.size());
1354 TEST_F(End2EndTest
, ReceiverClockSlow
) {
1355 Configure(CODEC_VIDEO_FAKE
, CODEC_AUDIO_PCM16
, 32000,
1359 SetReceiverSkew(0.5, base::TimeDelta::FromMicroseconds(-765432));
1361 int frames_counter
= 0;
1362 for (; frames_counter
< 10000; ++frames_counter
) {
1363 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1364 RunTasks(kFrameTimerMs
);
1366 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the pipeline.
1367 EXPECT_EQ(10000ul, video_ticks_
.size());
1370 TEST_F(End2EndTest
, SmoothPlayoutWithFivePercentClockRateSkew
) {
1371 Configure(CODEC_VIDEO_FAKE
, CODEC_AUDIO_PCM16
, 32000,
1375 SetReceiverSkew(1.05, base::TimeDelta::FromMilliseconds(-42));
1377 // Expect smooth playout when there is 5% skew.
1378 SetExpectedVideoPlayoutSmoothness(
1379 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) * 90 / 100,
1380 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) * 110 / 100,
1381 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) / 10);
1383 int frames_counter
= 0;
1384 for (; frames_counter
< 10000; ++frames_counter
) {
1385 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1386 RunTasks(kFrameTimerMs
);
1388 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the pipeline.
1389 EXPECT_EQ(10000ul, video_ticks_
.size());
1392 TEST_F(End2EndTest
, EvilNetwork
) {
1393 Configure(CODEC_VIDEO_FAKE
, CODEC_AUDIO_PCM16
, 32000,
1395 receiver_to_sender_
.SetPacketPipe(test::EvilNetwork().Pass());
1396 sender_to_receiver_
.SetPacketPipe(test::EvilNetwork().Pass());
1400 int frames_counter
= 0;
1401 for (; frames_counter
< 10000; ++frames_counter
) {
1402 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1403 RunTasks(kFrameTimerMs
);
1405 base::TimeTicks test_end
= testing_clock_receiver_
->NowTicks();
1406 RunTasks(100 * kFrameTimerMs
+ 1); // Empty the pipeline.
1407 EXPECT_GT(video_ticks_
.size(), 100ul);
1408 VLOG(1) << "Fully transmitted " << video_ticks_
.size()
1409 << " out of 10000 frames.";
1410 EXPECT_LT((video_ticks_
.back().second
- test_end
).InMilliseconds(), 1000);
1413 // Tests that a system configured for 30 FPS drops frames when input is provided
1414 // at a much higher frame rate.
1415 TEST_F(End2EndTest
, ShoveHighFrameRateDownYerThroat
) {
1416 Configure(CODEC_VIDEO_FAKE
, CODEC_AUDIO_PCM16
, 32000,
1418 receiver_to_sender_
.SetPacketPipe(test::EvilNetwork().Pass());
1419 sender_to_receiver_
.SetPacketPipe(test::EvilNetwork().Pass());
1423 int frames_counter
= 0;
1424 for (; frames_counter
< 10000; ++frames_counter
) {
1425 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1426 RunTasks(10 /* 10 ms, but 33.3 expected by system */);
1428 base::TimeTicks test_end
= testing_clock_receiver_
->NowTicks();
1429 RunTasks(100 * kFrameTimerMs
+ 1); // Empty the pipeline.
1430 EXPECT_LT(100ul, video_ticks_
.size());
1431 EXPECT_GE(3334ul, video_ticks_
.size());
1432 VLOG(1) << "Fully transmitted " << video_ticks_
.size()
1433 << " out of 10000 frames.";
1434 EXPECT_LT((video_ticks_
.back().second
- test_end
).InMilliseconds(), 1000);
1437 TEST_F(End2EndTest
, OldPacketNetwork
) {
1438 Configure(CODEC_VIDEO_FAKE
, CODEC_AUDIO_PCM16
, 32000, 1);
1439 sender_to_receiver_
.SetPacketPipe(test::NewRandomDrop(0.01));
1440 scoped_ptr
<test::PacketPipe
> echo_chamber(
1441 test::NewDuplicateAndDelay(1, 10 * kFrameTimerMs
));
1442 echo_chamber
->AppendToPipe(
1443 test::NewDuplicateAndDelay(1, 20 * kFrameTimerMs
));
1444 echo_chamber
->AppendToPipe(
1445 test::NewDuplicateAndDelay(1, 40 * kFrameTimerMs
));
1446 echo_chamber
->AppendToPipe(
1447 test::NewDuplicateAndDelay(1, 80 * kFrameTimerMs
));
1448 echo_chamber
->AppendToPipe(
1449 test::NewDuplicateAndDelay(1, 160 * kFrameTimerMs
));
1451 receiver_to_sender_
.SetPacketPipe(echo_chamber
.Pass());
1455 SetExpectedVideoPlayoutSmoothness(
1456 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) * 90 / 100,
1457 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) * 110 / 100,
1458 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) / 10);
1460 int frames_counter
= 0;
1461 for (; frames_counter
< 10000; ++frames_counter
) {
1462 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1463 RunTasks(kFrameTimerMs
);
1465 RunTasks(100 * kFrameTimerMs
+ 1); // Empty the pipeline.
1467 EXPECT_EQ(10000ul, video_ticks_
.size());
1470 TEST_F(End2EndTest
, TestSetPlayoutDelay
) {
1471 Configure(CODEC_VIDEO_FAKE
, CODEC_AUDIO_PCM16
, 32000, 1);
1472 video_sender_config_
.min_playout_delay
=
1473 video_sender_config_
.max_playout_delay
;
1474 audio_sender_config_
.min_playout_delay
=
1475 audio_sender_config_
.max_playout_delay
;
1476 video_sender_config_
.max_playout_delay
= base::TimeDelta::FromSeconds(1);
1477 audio_sender_config_
.max_playout_delay
= base::TimeDelta::FromSeconds(1);
1480 const int kNewDelay
= 600;
1482 int frames_counter
= 0;
1483 for (; frames_counter
< 200; ++frames_counter
) {
1484 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1485 RunTasks(kFrameTimerMs
);
1487 cast_sender_
->SetTargetPlayoutDelay(
1488 base::TimeDelta::FromMilliseconds(kNewDelay
));
1489 for (; frames_counter
< 400; ++frames_counter
) {
1490 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1491 RunTasks(kFrameTimerMs
);
1493 RunTasks(100 * kFrameTimerMs
+ 1); // Empty the pipeline.
1495 for (size_t i
= 1; i
< video_ticks_
.size(); i
++) {
1496 int64 delta
= (video_ticks_
[i
].second
-
1497 video_ticks_
[i
-1].second
).InMilliseconds();
1499 EXPECT_EQ(kNewDelay
- kTargetPlayoutDelayMs
+ kFrameTimerMs
, delta
);
1500 EXPECT_EQ(0u, jump
);
1504 EXPECT_GT(jump
, 199u);
1505 EXPECT_LT(jump
, 220u);
1508 // TODO(pwestin): Add repeatable packet loss test.
1509 // TODO(pwestin): Add test for misaligned send get calls.
1510 // TODO(pwestin): Add more tests that does not resample.
1511 // TODO(pwestin): Add test when we have starvation for our RunTask.
1514 } // namespace media