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;
57 // Since the video encoded and decoded an error will be introduced; when
58 // comparing individual pixels the error can be quite large; we allow a PSNR of
59 // at least |kVideoAcceptedPSNR|.
60 static const double kVideoAcceptedPSNR
= 38.0;
62 // The tests are commonly implemented with |kFrameTimerMs| RunTask function;
63 // a normal video is 30 fps hence the 33 ms between frames.
65 // TODO(miu): The errors in timing will add up significantly. Find an
66 // alternative approach that eliminates use of this constant.
67 static const int kFrameTimerMs
= 33;
69 // Start the video synthetic start value to medium range value, to avoid edge
70 // effects cause by encoding and quantization.
71 static const int kVideoStart
= 100;
73 // The size of audio frames. The encoder joins/breaks all inserted audio into
74 // chunks of this size.
75 static const int kAudioFrameDurationMs
= 10;
77 // The amount of time between frame capture on the sender and playout on the
79 static const int kTargetPlayoutDelayMs
= 100;
81 // The maximum amount of deviation expected in the playout times emitted by the
83 static const int kMaxAllowedPlayoutErrorMs
= 30;
85 std::string
ConvertFromBase16String(const std::string
& base_16
) {
86 std::string compressed
;
87 DCHECK_EQ(base_16
.size() % 2, 0u) << "Must be a multiple of 2";
88 compressed
.reserve(base_16
.size() / 2);
91 if (!base::HexStringToBytes(base_16
, &v
)) {
94 compressed
.assign(reinterpret_cast<const char*>(&v
[0]), v
.size());
98 void UpdateCastTransportStatus(CastTransportStatus status
) {
99 bool result
= (status
== TRANSPORT_AUDIO_INITIALIZED
||
100 status
== TRANSPORT_VIDEO_INITIALIZED
);
104 void ExpectSuccessOperationalStatus(OperationalStatus status
) {
105 EXPECT_EQ(STATUS_INITIALIZED
, status
);
108 // This is wrapped in a struct because it needs to be put into a std::map.
110 int counter
[kNumOfLoggingEvents
+1];
111 } LoggingEventCounts
;
113 // Constructs a map from each frame (RTP timestamp) to counts of each event
114 // type logged for that frame.
115 std::map
<RtpTimestamp
, LoggingEventCounts
> GetEventCountForFrameEvents(
116 const std::vector
<FrameEvent
>& frame_events
) {
117 std::map
<RtpTimestamp
, LoggingEventCounts
> event_counter_for_frame
;
118 for (std::vector
<FrameEvent
>::const_iterator it
= frame_events
.begin();
119 it
!= frame_events
.end();
121 std::map
<RtpTimestamp
, LoggingEventCounts
>::iterator map_it
=
122 event_counter_for_frame
.find(it
->rtp_timestamp
);
123 if (map_it
== event_counter_for_frame
.end()) {
124 LoggingEventCounts new_counter
;
125 memset(&new_counter
, 0, sizeof(new_counter
));
126 ++(new_counter
.counter
[it
->type
]);
127 event_counter_for_frame
.insert(
128 std::make_pair(it
->rtp_timestamp
, new_counter
));
130 ++(map_it
->second
.counter
[it
->type
]);
133 return event_counter_for_frame
;
136 // Constructs a map from each packet (Packet ID) to counts of each event
137 // type logged for that packet.
138 std::map
<uint16
, LoggingEventCounts
> GetEventCountForPacketEvents(
139 const std::vector
<PacketEvent
>& packet_events
) {
140 std::map
<uint16
, LoggingEventCounts
> event_counter_for_packet
;
141 for (std::vector
<PacketEvent
>::const_iterator it
= packet_events
.begin();
142 it
!= packet_events
.end();
144 std::map
<uint16
, LoggingEventCounts
>::iterator map_it
=
145 event_counter_for_packet
.find(it
->packet_id
);
146 if (map_it
== event_counter_for_packet
.end()) {
147 LoggingEventCounts new_counter
;
148 memset(&new_counter
, 0, sizeof(new_counter
));
149 ++(new_counter
.counter
[it
->type
]);
150 event_counter_for_packet
.insert(
151 std::make_pair(it
->packet_id
, new_counter
));
153 ++(map_it
->second
.counter
[it
->type
]);
156 return event_counter_for_packet
;
161 // Shim that turns forwards packets from a test::PacketPipe to a
162 // PacketReceiverCallback.
163 class LoopBackPacketPipe
: public test::PacketPipe
{
165 explicit LoopBackPacketPipe(const PacketReceiverCallback
& packet_receiver
)
166 : packet_receiver_(packet_receiver
) {}
168 ~LoopBackPacketPipe() final
{}
170 // PacketPipe implementations.
171 void Send(scoped_ptr
<Packet
> packet
) final
{
172 packet_receiver_
.Run(packet
.Pass());
176 PacketReceiverCallback packet_receiver_
;
179 // Class that sends the packet direct from sender into the receiver with the
180 // ability to drop packets between the two.
181 class LoopBackTransport
: public PacketSender
{
183 explicit LoopBackTransport(scoped_refptr
<CastEnvironment
> cast_environment
)
184 : send_packets_(true),
185 drop_packets_belonging_to_odd_frames_(false),
186 cast_environment_(cast_environment
),
189 void SetPacketReceiver(
190 const PacketReceiverCallback
& packet_receiver
,
191 const scoped_refptr
<base::SingleThreadTaskRunner
>& task_runner
,
192 base::TickClock
* clock
) {
193 scoped_ptr
<test::PacketPipe
> loopback_pipe(
194 new LoopBackPacketPipe(packet_receiver
));
196 packet_pipe_
->AppendToPipe(loopback_pipe
.Pass());
198 packet_pipe_
= loopback_pipe
.Pass();
200 packet_pipe_
->InitOnIOThread(task_runner
, clock
);
203 bool SendPacket(PacketRef packet
, const base::Closure
& cb
) final
{
204 DCHECK(cast_environment_
->CurrentlyOn(CastEnvironment::MAIN
));
208 bytes_sent_
+= packet
->data
.size();
209 if (drop_packets_belonging_to_odd_frames_
) {
210 uint32 frame_id
= packet
->data
[13];
211 if (frame_id
% 2 == 1)
215 scoped_ptr
<Packet
> packet_copy(new Packet(packet
->data
));
216 packet_pipe_
->Send(packet_copy
.Pass());
220 int64
GetBytesSent() final
{ return bytes_sent_
; }
222 void SetSendPackets(bool send_packets
) { send_packets_
= send_packets
; }
224 void DropAllPacketsBelongingToOddFrames() {
225 drop_packets_belonging_to_odd_frames_
= true;
228 void SetPacketPipe(scoped_ptr
<test::PacketPipe
> pipe
) {
229 // Append the loopback pipe to the end.
230 pipe
->AppendToPipe(packet_pipe_
.Pass());
231 packet_pipe_
= pipe
.Pass();
236 bool drop_packets_belonging_to_odd_frames_
;
237 scoped_refptr
<CastEnvironment
> cast_environment_
;
238 scoped_ptr
<test::PacketPipe
> packet_pipe_
;
242 // Class that verifies the audio frames coming out of the receiver.
243 class TestReceiverAudioCallback
244 : public base::RefCountedThreadSafe
<TestReceiverAudioCallback
> {
246 struct ExpectedAudioFrame
{
247 scoped_ptr
<AudioBus
> audio_bus
;
248 base::TimeTicks playout_time
;
251 TestReceiverAudioCallback() : num_called_(0) {}
253 void SetExpectedSamplingFrequency(int expected_sampling_frequency
) {
254 expected_sampling_frequency_
= expected_sampling_frequency
;
257 void AddExpectedResult(const AudioBus
& audio_bus
,
258 const base::TimeTicks
& playout_time
) {
259 scoped_ptr
<ExpectedAudioFrame
> expected_audio_frame(
260 new ExpectedAudioFrame());
261 expected_audio_frame
->audio_bus
=
262 AudioBus::Create(audio_bus
.channels(), audio_bus
.frames()).Pass();
263 audio_bus
.CopyTo(expected_audio_frame
->audio_bus
.get());
264 expected_audio_frame
->playout_time
= playout_time
;
265 expected_frames_
.push_back(expected_audio_frame
.release());
268 void IgnoreAudioFrame(scoped_ptr
<AudioBus
> audio_bus
,
269 const base::TimeTicks
& playout_time
,
270 bool is_continuous
) {
274 void CheckAudioFrame(scoped_ptr
<AudioBus
> audio_bus
,
275 const base::TimeTicks
& playout_time
,
276 bool is_continuous
) {
279 ASSERT_TRUE(audio_bus
);
280 ASSERT_FALSE(expected_frames_
.empty());
281 const scoped_ptr
<ExpectedAudioFrame
> expected_audio_frame(
282 expected_frames_
.front());
283 expected_frames_
.pop_front();
285 EXPECT_EQ(audio_bus
->channels(), kAudioChannels
);
286 EXPECT_EQ(audio_bus
->frames(), expected_audio_frame
->audio_bus
->frames());
287 for (int ch
= 0; ch
< audio_bus
->channels(); ++ch
) {
288 EXPECT_NEAR(CountZeroCrossings(
289 expected_audio_frame
->audio_bus
->channel(ch
),
290 expected_audio_frame
->audio_bus
->frames()),
291 CountZeroCrossings(audio_bus
->channel(ch
),
292 audio_bus
->frames()),
297 (playout_time
- expected_audio_frame
->playout_time
).InMillisecondsF(),
299 kMaxAllowedPlayoutErrorMs
);
300 VLOG_IF(1, !last_playout_time_
.is_null())
301 << "Audio frame playout time delta (compared to last frame) is "
302 << (playout_time
- last_playout_time_
).InMicroseconds() << " usec.";
303 last_playout_time_
= playout_time
;
305 EXPECT_TRUE(is_continuous
);
308 void CheckCodedAudioFrame(scoped_ptr
<EncodedFrame
> audio_frame
) {
309 ASSERT_TRUE(audio_frame
);
310 ASSERT_FALSE(expected_frames_
.empty());
311 const ExpectedAudioFrame
& expected_audio_frame
=
312 *(expected_frames_
.front());
313 // Note: Just peeking here. Will delegate to CheckAudioFrame() to pop.
315 // We need to "decode" the encoded audio frame. The codec is simply to
316 // swizzle the bytes of each int16 from host-->network-->host order to get
317 // interleaved int16 PCM. Then, make an AudioBus out of that.
318 const int num_elements
= audio_frame
->data
.size() / sizeof(int16
);
319 ASSERT_EQ(expected_audio_frame
.audio_bus
->channels() *
320 expected_audio_frame
.audio_bus
->frames(),
322 int16
* const pcm_data
=
323 reinterpret_cast<int16
*>(audio_frame
->mutable_bytes());
324 for (int i
= 0; i
< num_elements
; ++i
)
325 pcm_data
[i
] = static_cast<int16
>(base::NetToHost16(pcm_data
[i
]));
326 scoped_ptr
<AudioBus
> audio_bus(
327 AudioBus::Create(expected_audio_frame
.audio_bus
->channels(),
328 expected_audio_frame
.audio_bus
->frames()));
329 audio_bus
->FromInterleaved(pcm_data
, audio_bus
->frames(), sizeof(int16
));
331 // Delegate the checking from here...
332 CheckAudioFrame(audio_bus
.Pass(), audio_frame
->reference_time
, true);
335 int number_times_called() const { return num_called_
; }
338 virtual ~TestReceiverAudioCallback() {
339 STLDeleteElements(&expected_frames_
);
343 friend class base::RefCountedThreadSafe
<TestReceiverAudioCallback
>;
346 int expected_sampling_frequency_
;
347 std::list
<ExpectedAudioFrame
*> expected_frames_
;
348 base::TimeTicks last_playout_time_
;
351 // Class that verifies the video frames coming out of the receiver.
352 class TestReceiverVideoCallback
353 : public base::RefCountedThreadSafe
<TestReceiverVideoCallback
> {
355 struct ExpectedVideoFrame
{
357 base::TimeTicks playout_time
;
358 bool should_be_continuous
;
361 TestReceiverVideoCallback() : num_called_(0) {}
363 void AddExpectedResult(int start_value
,
364 const base::TimeTicks
& playout_time
,
365 bool should_be_continuous
) {
366 ExpectedVideoFrame expected_video_frame
;
367 expected_video_frame
.start_value
= start_value
;
368 expected_video_frame
.playout_time
= playout_time
;
369 expected_video_frame
.should_be_continuous
= should_be_continuous
;
370 expected_frame_
.push_back(expected_video_frame
);
373 void CheckVideoFrame(const scoped_refptr
<media::VideoFrame
>& video_frame
,
374 const base::TimeTicks
& playout_time
,
375 bool is_continuous
) {
378 ASSERT_TRUE(video_frame
.get());
379 ASSERT_FALSE(expected_frame_
.empty());
380 ExpectedVideoFrame expected_video_frame
= expected_frame_
.front();
381 expected_frame_
.pop_front();
383 EXPECT_EQ(kVideoHdWidth
, video_frame
->visible_rect().width());
384 EXPECT_EQ(kVideoHdHeight
, video_frame
->visible_rect().height());
386 const gfx::Size
size(kVideoHdWidth
, kVideoHdHeight
);
387 scoped_refptr
<media::VideoFrame
> expected_I420_frame
=
388 media::VideoFrame::CreateFrame(PIXEL_FORMAT_I420
, size
, gfx::Rect(size
),
389 size
, base::TimeDelta());
390 PopulateVideoFrame(expected_I420_frame
.get(),
391 expected_video_frame
.start_value
);
393 if (expected_video_frame
.should_be_continuous
) {
394 EXPECT_GE(I420PSNR(expected_I420_frame
, video_frame
), kVideoAcceptedPSNR
);
398 (playout_time
- expected_video_frame
.playout_time
).InMillisecondsF(),
400 kMaxAllowedPlayoutErrorMs
);
401 VLOG_IF(1, !last_playout_time_
.is_null())
402 << "Video frame playout time delta (compared to last frame) is "
403 << (playout_time
- last_playout_time_
).InMicroseconds() << " usec.";
404 last_playout_time_
= playout_time
;
406 EXPECT_EQ(expected_video_frame
.should_be_continuous
, is_continuous
);
409 int number_times_called() const { return num_called_
; }
412 virtual ~TestReceiverVideoCallback() {}
415 friend class base::RefCountedThreadSafe
<TestReceiverVideoCallback
>;
418 std::list
<ExpectedVideoFrame
> expected_frame_
;
419 base::TimeTicks last_playout_time_
;
422 // The actual test class, generate synthetic data for both audio and video and
423 // send those through the sender and receiver and analyzes the result.
424 class End2EndTest
: public ::testing::Test
{
428 task_runner_(new test::FakeSingleThreadTaskRunner(&testing_clock_
)),
429 testing_clock_sender_(new test::SkewedTickClock(&testing_clock_
)),
431 new test::SkewedSingleThreadTaskRunner(task_runner_
)),
432 testing_clock_receiver_(new test::SkewedTickClock(&testing_clock_
)),
433 task_runner_receiver_(
434 new test::SkewedSingleThreadTaskRunner(task_runner_
)),
435 cast_environment_sender_(new CastEnvironment(
436 scoped_ptr
<base::TickClock
>(testing_clock_sender_
).Pass(),
439 task_runner_sender_
)),
440 cast_environment_receiver_(new CastEnvironment(
441 scoped_ptr
<base::TickClock
>(testing_clock_receiver_
).Pass(),
442 task_runner_receiver_
,
443 task_runner_receiver_
,
444 task_runner_receiver_
)),
445 receiver_to_sender_(cast_environment_receiver_
),
446 sender_to_receiver_(cast_environment_sender_
),
447 test_receiver_audio_callback_(new TestReceiverAudioCallback()),
448 test_receiver_video_callback_(new TestReceiverVideoCallback()) {
449 testing_clock_
.Advance(
450 base::TimeDelta::FromMilliseconds(kStartMillisecond
));
451 cast_environment_sender_
->Logging()->AddRawEventSubscriber(
452 &event_subscriber_sender_
);
455 void Configure(Codec video_codec
,
457 int audio_sampling_frequency
,
458 int max_number_of_video_buffers_used
) {
459 audio_sender_config_
.ssrc
= 1;
460 audio_sender_config_
.receiver_ssrc
= 2;
461 audio_sender_config_
.max_playout_delay
=
462 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
);
463 audio_sender_config_
.rtp_payload_type
= 96;
464 audio_sender_config_
.use_external_encoder
= false;
465 audio_sender_config_
.frequency
= audio_sampling_frequency
;
466 audio_sender_config_
.channels
= kAudioChannels
;
467 audio_sender_config_
.bitrate
= kDefaultAudioEncoderBitrate
;
468 audio_sender_config_
.codec
= audio_codec
;
470 audio_receiver_config_
.receiver_ssrc
=
471 audio_sender_config_
.receiver_ssrc
;
472 audio_receiver_config_
.sender_ssrc
= audio_sender_config_
.ssrc
;
473 audio_receiver_config_
.rtp_max_delay_ms
= kTargetPlayoutDelayMs
;
474 audio_receiver_config_
.rtp_payload_type
=
475 audio_sender_config_
.rtp_payload_type
;
476 audio_receiver_config_
.rtp_timebase
= audio_sender_config_
.frequency
;
477 audio_receiver_config_
.channels
= kAudioChannels
;
478 audio_receiver_config_
.target_frame_rate
= 100;
479 audio_receiver_config_
.codec
= audio_sender_config_
.codec
;
481 test_receiver_audio_callback_
->SetExpectedSamplingFrequency(
482 audio_receiver_config_
.rtp_timebase
);
484 video_sender_config_
.ssrc
= 3;
485 video_sender_config_
.receiver_ssrc
= 4;
486 video_sender_config_
.max_playout_delay
=
487 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
);
488 video_sender_config_
.rtp_payload_type
= 97;
489 video_sender_config_
.use_external_encoder
= false;
490 video_sender_config_
.max_bitrate
= 50000;
491 video_sender_config_
.min_bitrate
= 10000;
492 video_sender_config_
.start_bitrate
= 10000;
493 video_sender_config_
.max_qp
= 30;
494 video_sender_config_
.min_qp
= 4;
495 video_sender_config_
.max_frame_rate
= 30;
496 video_sender_config_
.max_number_of_video_buffers_used
=
497 max_number_of_video_buffers_used
;
498 video_sender_config_
.codec
= video_codec
;
500 video_receiver_config_
.receiver_ssrc
=
501 video_sender_config_
.receiver_ssrc
;
502 video_receiver_config_
.sender_ssrc
= video_sender_config_
.ssrc
;
503 video_receiver_config_
.rtp_max_delay_ms
= kTargetPlayoutDelayMs
;
504 video_receiver_config_
.rtp_payload_type
=
505 video_sender_config_
.rtp_payload_type
;
506 video_receiver_config_
.rtp_timebase
= kVideoFrequency
;
507 video_receiver_config_
.channels
= 1;
508 video_receiver_config_
.target_frame_rate
=
509 video_sender_config_
.max_frame_rate
;
510 video_receiver_config_
.codec
= video_sender_config_
.codec
;
513 void SetReceiverSkew(double skew
, base::TimeDelta offset
) {
514 testing_clock_receiver_
->SetSkew(skew
, offset
);
515 task_runner_receiver_
->SetSkew(1.0 / skew
);
518 // Specify the minimum/maximum difference in playout times between two
519 // consecutive frames. Also, specify the maximum absolute rate of change over
520 // each three consecutive frames.
521 void SetExpectedVideoPlayoutSmoothness(base::TimeDelta min_delta
,
522 base::TimeDelta max_delta
,
523 base::TimeDelta max_curvature
) {
524 min_video_playout_delta_
= min_delta
;
525 max_video_playout_delta_
= max_delta
;
526 max_video_playout_curvature_
= max_curvature
;
529 void FeedAudioFrames(int count
, bool will_be_checked
) {
530 for (int i
= 0; i
< count
; ++i
) {
531 scoped_ptr
<AudioBus
> audio_bus(audio_bus_factory_
->NextAudioBus(
532 base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs
)));
533 const base::TimeTicks reference_time
=
534 testing_clock_sender_
->NowTicks() +
535 i
* base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs
);
536 if (will_be_checked
) {
537 test_receiver_audio_callback_
->AddExpectedResult(
540 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
));
542 audio_frame_input_
->InsertAudio(audio_bus
.Pass(), reference_time
);
546 void FeedAudioFramesWithExpectedDelay(int count
,
547 const base::TimeDelta
& delay
) {
548 for (int i
= 0; i
< count
; ++i
) {
549 scoped_ptr
<AudioBus
> audio_bus(audio_bus_factory_
->NextAudioBus(
550 base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs
)));
551 const base::TimeTicks reference_time
=
552 testing_clock_sender_
->NowTicks() +
553 i
* base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs
);
554 test_receiver_audio_callback_
->AddExpectedResult(
556 reference_time
+ delay
+
557 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
));
558 audio_frame_input_
->InsertAudio(audio_bus
.Pass(), reference_time
);
562 void RequestAudioFrames(int count
, bool with_check
) {
563 for (int i
= 0; i
< count
; ++i
) {
564 cast_receiver_
->RequestDecodedAudioFrame(
565 base::Bind(with_check
? &TestReceiverAudioCallback::CheckAudioFrame
:
566 &TestReceiverAudioCallback::IgnoreAudioFrame
,
567 test_receiver_audio_callback_
));
571 void ReceivePacket(scoped_ptr
<Packet
> packet
) {
572 cast_receiver_
->ReceivePacket(packet
.Pass());
576 net::IPEndPoint dummy_endpoint
;
577 transport_sender_
.reset(new CastTransportSenderImpl(
579 testing_clock_sender_
,
582 make_scoped_ptr(new base::DictionaryValue
),
583 base::Bind(&UpdateCastTransportStatus
),
584 base::Bind(&End2EndTest::LogRawEvents
, base::Unretained(this)),
585 base::TimeDelta::FromMilliseconds(1),
587 PacketReceiverCallback(),
588 &sender_to_receiver_
));
590 transport_receiver_
.reset(new CastTransportSenderImpl(
592 testing_clock_sender_
,
595 make_scoped_ptr(new base::DictionaryValue
),
596 base::Bind(&UpdateCastTransportStatus
),
597 base::Bind(&End2EndTest::LogRawEvents
, base::Unretained(this)),
598 base::TimeDelta::FromMilliseconds(1),
600 base::Bind(&End2EndTest::ReceivePacket
, base::Unretained(this)),
601 &receiver_to_sender_
));
603 cast_receiver_
= CastReceiver::Create(cast_environment_receiver_
,
604 audio_receiver_config_
,
605 video_receiver_config_
,
606 transport_receiver_
.get());
609 CastSender::Create(cast_environment_sender_
, transport_sender_
.get());
611 // Initializing audio and video senders.
612 cast_sender_
->InitializeAudio(
613 audio_sender_config_
,
614 base::Bind(&ExpectSuccessOperationalStatus
));
615 cast_sender_
->InitializeVideo(
616 video_sender_config_
,
617 base::Bind(&ExpectSuccessOperationalStatus
),
618 CreateDefaultVideoEncodeAcceleratorCallback(),
619 CreateDefaultVideoEncodeMemoryCallback());
620 task_runner_
->RunTasks();
622 receiver_to_sender_
.SetPacketReceiver(
623 transport_sender_
->PacketReceiverForTesting(),
626 sender_to_receiver_
.SetPacketReceiver(
627 transport_receiver_
->PacketReceiverForTesting(),
631 audio_frame_input_
= cast_sender_
->audio_frame_input();
632 video_frame_input_
= cast_sender_
->video_frame_input();
634 audio_bus_factory_
.reset(
635 new TestAudioBusFactory(audio_sender_config_
.channels
,
636 audio_sender_config_
.frequency
,
641 ~End2EndTest() override
{
642 cast_environment_sender_
->Logging()->RemoveRawEventSubscriber(
643 &event_subscriber_sender_
);
646 void TearDown() final
{
647 cast_sender_
.reset();
648 cast_receiver_
.reset();
649 task_runner_
->RunTasks();
652 void SendVideoFrame(int start_value
, const base::TimeTicks
& reference_time
) {
653 if (start_time_
.is_null())
654 start_time_
= reference_time
;
655 // TODO(miu): Consider using a slightly skewed clock for the media timestamp
656 // since the video clock may not be the same as the reference clock.
657 const base::TimeDelta time_diff
= reference_time
- start_time_
;
658 const gfx::Size
size(kVideoHdWidth
, kVideoHdHeight
);
659 EXPECT_TRUE(VideoFrame::IsValidConfig(PIXEL_FORMAT_I420
,
660 VideoFrame::STORAGE_UNKNOWN
, size
,
661 gfx::Rect(size
), size
));
662 scoped_refptr
<media::VideoFrame
> video_frame
=
663 media::VideoFrame::CreateFrame(PIXEL_FORMAT_I420
, size
, gfx::Rect(size
),
665 PopulateVideoFrame(video_frame
.get(), start_value
);
666 video_frame_input_
->InsertRawVideoFrame(video_frame
, reference_time
);
669 void SendFakeVideoFrame(const base::TimeTicks
& reference_time
) {
670 if (start_time_
.is_null())
671 start_time_
= reference_time
;
672 const scoped_refptr
<media::VideoFrame
> black_frame
=
673 media::VideoFrame::CreateBlackFrame(gfx::Size(2, 2));
674 // TODO(miu): Consider using a slightly skewed clock for the media timestamp
675 // since the video clock may not be the same as the reference clock.
676 black_frame
->set_timestamp(reference_time
- start_time_
);
677 video_frame_input_
->InsertRawVideoFrame(black_frame
, reference_time
);
680 void RunTasks(int ms
) {
681 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(ms
));
684 void BasicPlayerGotVideoFrame(
685 const scoped_refptr
<media::VideoFrame
>& video_frame
,
686 const base::TimeTicks
& playout_time
, bool continuous
) {
687 // The following tests that the sender and receiver clocks can be
688 // out-of-sync, drift, and jitter with respect to one another; and depsite
689 // this, the receiver will produce smoothly-progressing playout times.
690 // Both first-order and second-order effects are tested.
691 if (!last_video_playout_time_
.is_null() &&
692 min_video_playout_delta_
> base::TimeDelta()) {
693 const base::TimeDelta delta
= playout_time
- last_video_playout_time_
;
694 VLOG(1) << "Video frame playout time delta (compared to last frame) is "
695 << delta
.InMicroseconds() << " usec.";
696 EXPECT_LE(min_video_playout_delta_
.InMicroseconds(),
697 delta
.InMicroseconds());
698 EXPECT_GE(max_video_playout_delta_
.InMicroseconds(),
699 delta
.InMicroseconds());
700 if (last_video_playout_delta_
> base::TimeDelta()) {
701 base::TimeDelta abs_curvature
= delta
- last_video_playout_delta_
;
702 if (abs_curvature
< base::TimeDelta())
703 abs_curvature
= -abs_curvature
;
704 EXPECT_GE(max_video_playout_curvature_
.InMicroseconds(),
705 abs_curvature
.InMicroseconds());
707 last_video_playout_delta_
= delta
;
709 last_video_playout_time_
= playout_time
;
711 video_ticks_
.push_back(std::make_pair(
712 testing_clock_receiver_
->NowTicks(),
714 cast_receiver_
->RequestDecodedVideoFrame(
715 base::Bind(&End2EndTest::BasicPlayerGotVideoFrame
,
716 base::Unretained(this)));
719 void BasicPlayerGotAudioFrame(scoped_ptr
<AudioBus
> audio_bus
,
720 const base::TimeTicks
& playout_time
,
721 bool is_continuous
) {
722 VLOG_IF(1, !last_audio_playout_time_
.is_null())
723 << "Audio frame playout time delta (compared to last frame) is "
724 << (playout_time
- last_audio_playout_time_
).InMicroseconds()
726 last_audio_playout_time_
= playout_time
;
728 audio_ticks_
.push_back(std::make_pair(
729 testing_clock_receiver_
->NowTicks(),
731 cast_receiver_
->RequestDecodedAudioFrame(
732 base::Bind(&End2EndTest::BasicPlayerGotAudioFrame
,
733 base::Unretained(this)));
736 void StartBasicPlayer() {
737 cast_receiver_
->RequestDecodedVideoFrame(
738 base::Bind(&End2EndTest::BasicPlayerGotVideoFrame
,
739 base::Unretained(this)));
740 cast_receiver_
->RequestDecodedAudioFrame(
741 base::Bind(&End2EndTest::BasicPlayerGotAudioFrame
,
742 base::Unretained(this)));
745 void LogRawEvents(const std::vector
<PacketEvent
>& packet_events
,
746 const std::vector
<FrameEvent
>& frame_events
) {
747 for (std::vector
<media::cast::PacketEvent
>::const_iterator it
=
748 packet_events
.begin();
749 it
!= packet_events
.end();
751 cast_environment_sender_
->Logging()->InsertPacketEvent(it
->timestamp
,
760 for (std::vector
<media::cast::FrameEvent
>::const_iterator it
=
761 frame_events
.begin();
762 it
!= frame_events
.end();
764 cast_environment_sender_
->Logging()->InsertFrameEvent(it
->timestamp
,
772 FrameReceiverConfig audio_receiver_config_
;
773 FrameReceiverConfig video_receiver_config_
;
774 AudioSenderConfig audio_sender_config_
;
775 VideoSenderConfig video_sender_config_
;
777 base::TimeTicks start_time_
;
779 // These run in "test time"
780 base::SimpleTestTickClock testing_clock_
;
781 scoped_refptr
<test::FakeSingleThreadTaskRunner
> task_runner_
;
783 // These run on the sender timeline.
784 test::SkewedTickClock
* testing_clock_sender_
;
785 scoped_refptr
<test::SkewedSingleThreadTaskRunner
> task_runner_sender_
;
787 // These run on the receiver timeline.
788 test::SkewedTickClock
* testing_clock_receiver_
;
789 scoped_refptr
<test::SkewedSingleThreadTaskRunner
> task_runner_receiver_
;
790 base::TimeDelta min_video_playout_delta_
;
791 base::TimeDelta max_video_playout_delta_
;
792 base::TimeDelta max_video_playout_curvature_
;
793 base::TimeTicks last_video_playout_time_
;
794 base::TimeDelta last_video_playout_delta_
;
795 base::TimeTicks last_audio_playout_time_
;
797 scoped_refptr
<CastEnvironment
> cast_environment_sender_
;
798 scoped_refptr
<CastEnvironment
> cast_environment_receiver_
;
800 LoopBackTransport receiver_to_sender_
;
801 LoopBackTransport sender_to_receiver_
;
802 scoped_ptr
<CastTransportSenderImpl
> transport_sender_
;
803 scoped_ptr
<CastTransportSenderImpl
> transport_receiver_
;
805 scoped_ptr
<CastReceiver
> cast_receiver_
;
806 scoped_ptr
<CastSender
> cast_sender_
;
807 scoped_refptr
<AudioFrameInput
> audio_frame_input_
;
808 scoped_refptr
<VideoFrameInput
> video_frame_input_
;
810 scoped_refptr
<TestReceiverAudioCallback
> test_receiver_audio_callback_
;
811 scoped_refptr
<TestReceiverVideoCallback
> test_receiver_video_callback_
;
813 scoped_ptr
<TestAudioBusFactory
> audio_bus_factory_
;
815 SimpleEventSubscriber event_subscriber_sender_
;
816 std::vector
<FrameEvent
> frame_events_
;
817 std::vector
<PacketEvent
> packet_events_
;
818 std::vector
<std::pair
<base::TimeTicks
, base::TimeTicks
> > audio_ticks_
;
819 std::vector
<std::pair
<base::TimeTicks
, base::TimeTicks
> > video_ticks_
;
820 // |transport_sender_| has a RepeatingTimer which needs a MessageLoop.
821 base::MessageLoop message_loop_
;
824 TEST_F(End2EndTest
, LoopNoLossPcm16
) {
825 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_PCM16
, 32000, 1);
828 const int kNumIterations
= 50;
829 int video_start
= kVideoStart
;
830 int audio_diff
= kFrameTimerMs
;
831 int num_audio_frames_requested
= 0;
832 for (int i
= 0; i
< kNumIterations
; ++i
) {
833 const int num_audio_frames
= audio_diff
/ kAudioFrameDurationMs
;
834 audio_diff
-= num_audio_frames
* kAudioFrameDurationMs
;
836 if (num_audio_frames
> 0)
837 FeedAudioFrames(1, true);
839 test_receiver_video_callback_
->AddExpectedResult(
841 testing_clock_sender_
->NowTicks() +
842 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
),
844 SendVideoFrame(video_start
, testing_clock_sender_
->NowTicks());
846 if (num_audio_frames
> 0)
847 RunTasks(kAudioFrameDurationMs
); // Advance clock forward.
848 if (num_audio_frames
> 1)
849 FeedAudioFrames(num_audio_frames
- 1, true);
851 RequestAudioFrames(num_audio_frames
, true);
852 num_audio_frames_requested
+= num_audio_frames
;
854 cast_receiver_
->RequestDecodedVideoFrame(
855 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame
,
856 test_receiver_video_callback_
));
858 RunTasks(kFrameTimerMs
- kAudioFrameDurationMs
);
859 audio_diff
+= kFrameTimerMs
;
863 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the receiver pipeline.
864 EXPECT_EQ(num_audio_frames_requested
,
865 test_receiver_audio_callback_
->number_times_called());
866 EXPECT_EQ(kNumIterations
,
867 test_receiver_video_callback_
->number_times_called());
870 // This tests our external decoder interface for Audio.
871 // Audio test without packet loss using raw PCM 16 audio "codec";
872 TEST_F(End2EndTest
, LoopNoLossPcm16ExternalDecoder
) {
873 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_PCM16
, 32000, 1);
876 const int kNumIterations
= 10;
877 for (int i
= 0; i
< kNumIterations
; ++i
) {
878 FeedAudioFrames(1, true);
879 RunTasks(kAudioFrameDurationMs
);
880 cast_receiver_
->RequestEncodedAudioFrame(
881 base::Bind(&TestReceiverAudioCallback::CheckCodedAudioFrame
,
882 test_receiver_audio_callback_
));
884 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the receiver pipeline.
885 EXPECT_EQ(kNumIterations
,
886 test_receiver_audio_callback_
->number_times_called());
889 // This tests our Opus audio codec without video.
890 TEST_F(End2EndTest
, LoopNoLossOpus
) {
891 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_OPUS
,
892 kDefaultAudioSamplingRate
, 1);
895 const int kNumIterations
= 300;
896 for (int i
= 0; i
< kNumIterations
; ++i
) {
897 // Opus introduces a tiny delay before the sinewave starts; so don't examine
899 const bool examine_audio_data
= i
> 0;
900 FeedAudioFrames(1, examine_audio_data
);
901 RunTasks(kAudioFrameDurationMs
);
902 RequestAudioFrames(1, examine_audio_data
);
904 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the receiver pipeline.
905 EXPECT_EQ(kNumIterations
,
906 test_receiver_audio_callback_
->number_times_called());
909 // This tests start sending audio and video at start-up time before the receiver
910 // is ready; it sends 2 frames before the receiver comes online.
912 // Test disabled due to flakiness: It appears that the RTCP synchronization
913 // sometimes kicks in, and sometimes doesn't. When it does, there's a sharp
914 // discontinuity in the timeline, throwing off the test expectations. See TODOs
915 // in audio_receiver.cc for likely cause(s) of this bug.
916 // http://crbug.com/356942
917 TEST_F(End2EndTest
, DISABLED_StartSenderBeforeReceiver
) {
918 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_PCM16
,
919 kDefaultAudioSamplingRate
, 1);
922 int video_start
= kVideoStart
;
923 int audio_diff
= kFrameTimerMs
;
925 sender_to_receiver_
.SetSendPackets(false);
927 const int test_delay_ms
= 100;
929 const int kNumVideoFramesBeforeReceiverStarted
= 2;
930 const base::TimeTicks initial_send_time
= testing_clock_sender_
->NowTicks();
931 const base::TimeDelta expected_delay
=
932 base::TimeDelta::FromMilliseconds(test_delay_ms
+ kFrameTimerMs
);
933 for (int i
= 0; i
< kNumVideoFramesBeforeReceiverStarted
; ++i
) {
934 const int num_audio_frames
= audio_diff
/ kAudioFrameDurationMs
;
935 audio_diff
-= num_audio_frames
* kAudioFrameDurationMs
;
937 if (num_audio_frames
> 0)
938 FeedAudioFramesWithExpectedDelay(1, expected_delay
);
940 // Frame will be rendered with 100mS delay, as the transmission is delayed.
941 // The receiver at this point cannot be synced to the sender's clock, as no
942 // packets, and specifically no RTCP packets were sent.
943 test_receiver_video_callback_
->AddExpectedResult(
945 initial_send_time
+ expected_delay
+
946 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
),
948 SendVideoFrame(video_start
, testing_clock_sender_
->NowTicks());
950 if (num_audio_frames
> 0)
951 RunTasks(kAudioFrameDurationMs
); // Advance clock forward.
952 if (num_audio_frames
> 1)
953 FeedAudioFramesWithExpectedDelay(num_audio_frames
- 1, expected_delay
);
955 RunTasks(kFrameTimerMs
- kAudioFrameDurationMs
);
956 audio_diff
+= kFrameTimerMs
;
960 RunTasks(test_delay_ms
);
961 sender_to_receiver_
.SetSendPackets(true);
963 int num_audio_frames_requested
= 0;
964 for (int j
= 0; j
< 10; ++j
) {
965 const int num_audio_frames
= audio_diff
/ kAudioFrameDurationMs
;
966 audio_diff
-= num_audio_frames
* kAudioFrameDurationMs
;
968 if (num_audio_frames
> 0)
969 FeedAudioFrames(1, true);
971 test_receiver_video_callback_
->AddExpectedResult(
973 testing_clock_sender_
->NowTicks() +
974 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
),
976 SendVideoFrame(video_start
, testing_clock_sender_
->NowTicks());
978 if (num_audio_frames
> 0)
979 RunTasks(kAudioFrameDurationMs
); // Advance clock forward.
980 if (num_audio_frames
> 1)
981 FeedAudioFrames(num_audio_frames
- 1, true);
983 RequestAudioFrames(num_audio_frames
, true);
984 num_audio_frames_requested
+= num_audio_frames
;
986 cast_receiver_
->RequestDecodedVideoFrame(
987 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame
,
988 test_receiver_video_callback_
));
990 RunTasks(kFrameTimerMs
- kAudioFrameDurationMs
);
991 audio_diff
+= kFrameTimerMs
;
994 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the receiver pipeline.
995 EXPECT_EQ(num_audio_frames_requested
,
996 test_receiver_audio_callback_
->number_times_called());
997 EXPECT_EQ(10, test_receiver_video_callback_
->number_times_called());
1000 TEST_F(End2EndTest
, DropEveryOtherFrame3Buffers
) {
1001 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_OPUS
, kDefaultAudioSamplingRate
, 3);
1002 int target_delay
= 300;
1003 video_sender_config_
.max_playout_delay
=
1004 base::TimeDelta::FromMilliseconds(target_delay
);
1005 audio_sender_config_
.max_playout_delay
=
1006 base::TimeDelta::FromMilliseconds(target_delay
);
1007 video_receiver_config_
.rtp_max_delay_ms
= target_delay
;
1009 sender_to_receiver_
.DropAllPacketsBelongingToOddFrames();
1011 int video_start
= kVideoStart
;
1012 base::TimeTicks reference_time
;
1015 for (; i
< 20; ++i
) {
1016 reference_time
= testing_clock_sender_
->NowTicks();
1017 SendVideoFrame(video_start
, reference_time
);
1020 test_receiver_video_callback_
->AddExpectedResult(
1022 reference_time
+ base::TimeDelta::FromMilliseconds(target_delay
),
1025 // GetRawVideoFrame will not return the frame until we are close in
1026 // time before we should render the frame.
1027 cast_receiver_
->RequestDecodedVideoFrame(
1028 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame
,
1029 test_receiver_video_callback_
));
1031 RunTasks(kFrameTimerMs
);
1035 RunTasks(2 * kFrameTimerMs
+ target_delay
); // Empty the pipeline.
1036 EXPECT_EQ(i
/ 2, test_receiver_video_callback_
->number_times_called());
1039 TEST_F(End2EndTest
, CryptoVideo
) {
1040 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_PCM16
, 32000, 1);
1042 video_sender_config_
.aes_iv_mask
=
1043 ConvertFromBase16String("1234567890abcdeffedcba0987654321");
1044 video_sender_config_
.aes_key
=
1045 ConvertFromBase16String("deadbeefcafeb0b0b0b0cafedeadbeef");
1047 video_receiver_config_
.aes_iv_mask
=
1048 video_sender_config_
.aes_iv_mask
;
1049 video_receiver_config_
.aes_key
=
1050 video_sender_config_
.aes_key
;
1054 int frames_counter
= 0;
1055 for (; frames_counter
< 3; ++frames_counter
) {
1056 const base::TimeTicks reference_time
= testing_clock_sender_
->NowTicks();
1057 SendVideoFrame(frames_counter
, reference_time
);
1059 test_receiver_video_callback_
->AddExpectedResult(
1062 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
),
1065 RunTasks(kFrameTimerMs
);
1067 cast_receiver_
->RequestDecodedVideoFrame(
1068 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame
,
1069 test_receiver_video_callback_
));
1071 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the pipeline.
1072 EXPECT_EQ(frames_counter
,
1073 test_receiver_video_callback_
->number_times_called());
1076 TEST_F(End2EndTest
, CryptoAudio
) {
1077 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_PCM16
, 32000, 1);
1079 audio_sender_config_
.aes_iv_mask
=
1080 ConvertFromBase16String("abcdeffedcba12345678900987654321");
1081 audio_sender_config_
.aes_key
=
1082 ConvertFromBase16String("deadbeefcafecafedeadbeefb0b0b0b0");
1084 audio_receiver_config_
.aes_iv_mask
=
1085 audio_sender_config_
.aes_iv_mask
;
1086 audio_receiver_config_
.aes_key
=
1087 audio_sender_config_
.aes_key
;
1091 const int kNumIterations
= 3;
1092 const int kNumAudioFramesPerIteration
= 2;
1093 for (int i
= 0; i
< kNumIterations
; ++i
) {
1094 FeedAudioFrames(kNumAudioFramesPerIteration
, true);
1095 RunTasks(kNumAudioFramesPerIteration
* kAudioFrameDurationMs
);
1096 RequestAudioFrames(kNumAudioFramesPerIteration
, true);
1098 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the pipeline.
1099 EXPECT_EQ(kNumIterations
* kNumAudioFramesPerIteration
,
1100 test_receiver_audio_callback_
->number_times_called());
1103 // Video test without packet loss - tests the logging aspects of the end2end,
1104 // but is basically equivalent to LoopNoLossPcm16.
1105 TEST_F(End2EndTest
, VideoLogging
) {
1106 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_PCM16
, 32000, 1);
1109 int video_start
= kVideoStart
;
1110 const int num_frames
= 5;
1111 for (int i
= 0; i
< num_frames
; ++i
) {
1112 base::TimeTicks reference_time
= testing_clock_sender_
->NowTicks();
1113 test_receiver_video_callback_
->AddExpectedResult(
1116 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs
),
1119 SendVideoFrame(video_start
, reference_time
);
1120 RunTasks(kFrameTimerMs
);
1122 cast_receiver_
->RequestDecodedVideoFrame(
1123 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame
,
1124 test_receiver_video_callback_
));
1130 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the receiver pipeline.
1131 int num_callbacks_called
=
1132 test_receiver_video_callback_
->number_times_called();
1133 EXPECT_EQ(num_frames
, num_callbacks_called
);
1135 RunTasks(750); // Make sure that we send a RTCP message with the log.
1139 // Verify that all frames and all required events were logged.
1140 event_subscriber_sender_
.GetFrameEventsAndReset(&frame_events_
);
1142 // For each frame, count the number of events that occurred for each event
1144 std::map
<RtpTimestamp
, LoggingEventCounts
> event_counter_for_frame
=
1145 GetEventCountForFrameEvents(frame_events_
);
1147 // Verify that there are logs for expected number of frames.
1148 EXPECT_EQ(num_frames
, static_cast<int>(event_counter_for_frame
.size()));
1150 // Verify that each frame have the expected types of events logged.
1151 for (std::map
<RtpTimestamp
, LoggingEventCounts
>::iterator map_it
=
1152 event_counter_for_frame
.begin();
1153 map_it
!= event_counter_for_frame
.end();
1155 int total_event_count_for_frame
= 0;
1156 for (int i
= 0; i
<= kNumOfLoggingEvents
; ++i
) {
1157 total_event_count_for_frame
+= map_it
->second
.counter
[i
];
1160 int expected_event_count_for_frame
= 0;
1162 EXPECT_EQ(1, map_it
->second
.counter
[FRAME_CAPTURE_BEGIN
]);
1163 expected_event_count_for_frame
+=
1164 map_it
->second
.counter
[FRAME_CAPTURE_BEGIN
];
1166 EXPECT_EQ(1, map_it
->second
.counter
[FRAME_CAPTURE_END
]);
1167 expected_event_count_for_frame
+=
1168 map_it
->second
.counter
[FRAME_CAPTURE_END
];
1170 EXPECT_EQ(1, map_it
->second
.counter
[FRAME_ENCODED
]);
1171 expected_event_count_for_frame
+=
1172 map_it
->second
.counter
[FRAME_ENCODED
];
1174 EXPECT_EQ(1, map_it
->second
.counter
[FRAME_DECODED
]);
1175 expected_event_count_for_frame
+=
1176 map_it
->second
.counter
[FRAME_DECODED
];
1178 EXPECT_EQ(1, map_it
->second
.counter
[FRAME_PLAYOUT
]);
1179 expected_event_count_for_frame
+= map_it
->second
.counter
[FRAME_PLAYOUT
];
1182 // There is no guarantee that FRAME_ACK_SENT is loggeed exactly once per
1184 EXPECT_GT(map_it
->second
.counter
[FRAME_ACK_SENT
], 0);
1185 expected_event_count_for_frame
+= map_it
->second
.counter
[FRAME_ACK_SENT
];
1187 // There is no guarantee that FRAME_ACK_RECEIVED is loggeed exactly once per
1189 EXPECT_GT(map_it
->second
.counter
[FRAME_ACK_RECEIVED
], 0);
1190 expected_event_count_for_frame
+=
1191 map_it
->second
.counter
[FRAME_ACK_RECEIVED
];
1193 // Verify that there were no other events logged with respect to this
1195 // (i.e. Total event count = expected event count)
1196 EXPECT_EQ(total_event_count_for_frame
, expected_event_count_for_frame
);
1200 // Verify that all packet related events were logged.
1201 event_subscriber_sender_
.GetPacketEventsAndReset(&packet_events_
);
1202 std::map
<uint16
, LoggingEventCounts
> event_count_for_packet
=
1203 GetEventCountForPacketEvents(packet_events_
);
1205 // Verify that each packet have the expected types of events logged.
1206 for (std::map
<uint16
, LoggingEventCounts
>::iterator map_it
=
1207 event_count_for_packet
.begin();
1208 map_it
!= event_count_for_packet
.end();
1210 int total_event_count_for_packet
= 0;
1211 for (int i
= 0; i
<= kNumOfLoggingEvents
; ++i
) {
1212 total_event_count_for_packet
+= map_it
->second
.counter
[i
];
1215 EXPECT_GT(map_it
->second
.counter
[PACKET_RECEIVED
], 0);
1216 int packets_received
= map_it
->second
.counter
[PACKET_RECEIVED
];
1217 int packets_sent
= map_it
->second
.counter
[PACKET_SENT_TO_NETWORK
];
1218 EXPECT_EQ(packets_sent
, packets_received
);
1220 // Verify that there were no other events logged with respect to this
1221 // packet. (i.e. Total event count = packets sent + packets received)
1222 EXPECT_EQ(packets_received
+ packets_sent
, total_event_count_for_packet
);
1226 // Audio test without packet loss - tests the logging aspects of the end2end,
1227 // but is basically equivalent to LoopNoLossPcm16.
1228 TEST_F(End2EndTest
, AudioLogging
) {
1229 Configure(CODEC_VIDEO_VP8
, CODEC_AUDIO_PCM16
, 32000, 1);
1232 int audio_diff
= kFrameTimerMs
;
1233 const int kNumVideoFrames
= 10;
1234 int num_audio_frames_requested
= 0;
1235 for (int i
= 0; i
< kNumVideoFrames
; ++i
) {
1236 const int num_audio_frames
= audio_diff
/ kAudioFrameDurationMs
;
1237 audio_diff
-= num_audio_frames
* kAudioFrameDurationMs
;
1239 FeedAudioFrames(num_audio_frames
, true);
1241 RunTasks(kFrameTimerMs
);
1242 audio_diff
+= kFrameTimerMs
;
1244 RequestAudioFrames(num_audio_frames
, true);
1245 num_audio_frames_requested
+= num_audio_frames
;
1249 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the receiver pipeline.
1251 EXPECT_EQ(num_audio_frames_requested
,
1252 test_receiver_audio_callback_
->number_times_called());
1255 // Verify that all frames and all required events were logged.
1256 event_subscriber_sender_
.GetFrameEventsAndReset(&frame_events_
);
1258 // Construct a map from each frame (RTP timestamp) to a count of each event
1259 // type logged for that frame.
1260 std::map
<RtpTimestamp
, LoggingEventCounts
> event_counter_for_frame
=
1261 GetEventCountForFrameEvents(frame_events_
);
1263 int encoded_count
= 0;
1265 // Verify the right number of events were logged for each event type.
1266 for (std::map
<RtpTimestamp
, LoggingEventCounts
>::iterator it
=
1267 event_counter_for_frame
.begin();
1268 it
!= event_counter_for_frame
.end();
1270 encoded_count
+= it
->second
.counter
[FRAME_ENCODED
];
1273 EXPECT_EQ(num_audio_frames_requested
, encoded_count
);
1275 // Verify that each frame have the expected types of events logged.
1276 for (std::map
<RtpTimestamp
, LoggingEventCounts
>::const_iterator map_it
=
1277 event_counter_for_frame
.begin();
1278 map_it
!= event_counter_for_frame
.end(); ++map_it
) {
1279 int total_event_count_for_frame
= 0;
1280 for (int j
= 0; j
<= kNumOfLoggingEvents
; ++j
)
1281 total_event_count_for_frame
+= map_it
->second
.counter
[j
];
1283 int expected_event_count_for_frame
= 0;
1285 EXPECT_EQ(1, map_it
->second
.counter
[FRAME_ENCODED
]);
1286 expected_event_count_for_frame
+=
1287 map_it
->second
.counter
[FRAME_ENCODED
];
1289 EXPECT_EQ(1, map_it
->second
.counter
[FRAME_PLAYOUT
]);
1290 expected_event_count_for_frame
+=
1291 map_it
->second
.counter
[FRAME_PLAYOUT
];
1293 EXPECT_EQ(1, map_it
->second
.counter
[FRAME_DECODED
]);
1294 expected_event_count_for_frame
+=
1295 map_it
->second
.counter
[FRAME_DECODED
];
1297 EXPECT_GT(map_it
->second
.counter
[FRAME_ACK_SENT
], 0);
1298 EXPECT_GT(map_it
->second
.counter
[FRAME_ACK_RECEIVED
], 0);
1299 expected_event_count_for_frame
+= map_it
->second
.counter
[FRAME_ACK_SENT
];
1300 expected_event_count_for_frame
+=
1301 map_it
->second
.counter
[FRAME_ACK_RECEIVED
];
1303 // Verify that there were no other events logged with respect to this frame.
1304 // (i.e. Total event count = expected event count)
1305 EXPECT_EQ(total_event_count_for_frame
, expected_event_count_for_frame
);
1309 TEST_F(End2EndTest
, BasicFakeSoftwareVideo
) {
1310 Configure(CODEC_VIDEO_FAKE
, CODEC_AUDIO_PCM16
, 32000,
1314 SetReceiverSkew(1.0, base::TimeDelta::FromMilliseconds(1));
1316 // Expect very smooth playout when there is no clock skew.
1317 SetExpectedVideoPlayoutSmoothness(
1318 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) * 99 / 100,
1319 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) * 101 / 100,
1320 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) / 100);
1322 int frames_counter
= 0;
1323 for (; frames_counter
< 1000; ++frames_counter
) {
1324 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1325 RunTasks(kFrameTimerMs
);
1327 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the pipeline.
1328 EXPECT_EQ(1000ul, video_ticks_
.size());
1331 // The following tests run many many iterations to make sure that
1332 // buffers don't fill, timers don't go askew etc. However, these
1333 // high-level tests are too expensive in debug mode, so we reduce
1334 // the iterations in debug mode.
1336 const size_t kLongTestIterations
= 10000;
1338 const size_t kLongTestIterations
= 1000;
1341 TEST_F(End2EndTest
, ReceiverClockFast
) {
1342 Configure(CODEC_VIDEO_FAKE
, CODEC_AUDIO_PCM16
, 32000,
1346 SetReceiverSkew(2.0, base::TimeDelta::FromMicroseconds(1234567));
1348 for (size_t frames_counter
= 0;
1349 frames_counter
< kLongTestIterations
;
1351 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1352 RunTasks(kFrameTimerMs
);
1354 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the pipeline.
1355 EXPECT_EQ(kLongTestIterations
, video_ticks_
.size());
1358 TEST_F(End2EndTest
, ReceiverClockSlow
) {
1359 Configure(CODEC_VIDEO_FAKE
, CODEC_AUDIO_PCM16
, 32000,
1363 SetReceiverSkew(0.5, base::TimeDelta::FromMicroseconds(-765432));
1365 for (size_t frames_counter
= 0;
1366 frames_counter
< kLongTestIterations
;
1368 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1369 RunTasks(kFrameTimerMs
);
1371 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the pipeline.
1372 EXPECT_EQ(kLongTestIterations
, video_ticks_
.size());
1375 TEST_F(End2EndTest
, SmoothPlayoutWithFivePercentClockRateSkew
) {
1376 Configure(CODEC_VIDEO_FAKE
, CODEC_AUDIO_PCM16
, 32000,
1380 SetReceiverSkew(1.05, base::TimeDelta::FromMilliseconds(-42));
1382 // Expect smooth playout when there is 5% skew.
1383 SetExpectedVideoPlayoutSmoothness(
1384 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) * 90 / 100,
1385 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) * 110 / 100,
1386 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) / 10);
1388 for (size_t frames_counter
= 0;
1389 frames_counter
< kLongTestIterations
;
1391 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1392 RunTasks(kFrameTimerMs
);
1394 RunTasks(2 * kFrameTimerMs
+ 1); // Empty the pipeline.
1395 EXPECT_EQ(kLongTestIterations
, video_ticks_
.size());
1398 TEST_F(End2EndTest
, EvilNetwork
) {
1399 Configure(CODEC_VIDEO_FAKE
, CODEC_AUDIO_PCM16
, 32000,
1401 receiver_to_sender_
.SetPacketPipe(test::EvilNetwork().Pass());
1402 sender_to_receiver_
.SetPacketPipe(test::EvilNetwork().Pass());
1406 for (size_t frames_counter
= 0;
1407 frames_counter
< kLongTestIterations
;
1409 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1410 RunTasks(kFrameTimerMs
);
1412 base::TimeTicks test_end
= testing_clock_receiver_
->NowTicks();
1413 RunTasks(100 * kFrameTimerMs
+ 1); // Empty the pipeline.
1414 EXPECT_GT(video_ticks_
.size(), kLongTestIterations
/ 100);
1415 VLOG(1) << "Fully transmitted " << video_ticks_
.size() << " frames.";
1416 EXPECT_LT((video_ticks_
.back().second
- test_end
).InMilliseconds(), 1000);
1419 // Tests that a system configured for 30 FPS drops frames when input is provided
1420 // at a much higher frame rate.
1421 TEST_F(End2EndTest
, ShoveHighFrameRateDownYerThroat
) {
1422 Configure(CODEC_VIDEO_FAKE
, CODEC_AUDIO_PCM16
, 32000,
1424 receiver_to_sender_
.SetPacketPipe(test::EvilNetwork().Pass());
1425 sender_to_receiver_
.SetPacketPipe(test::EvilNetwork().Pass());
1429 for (size_t frames_counter
= 0;
1430 frames_counter
< kLongTestIterations
;
1432 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1433 RunTasks(10 /* 10 ms, but 33.3 expected by system */);
1435 base::TimeTicks test_end
= testing_clock_receiver_
->NowTicks();
1436 RunTasks(100 * kFrameTimerMs
+ 1); // Empty the pipeline.
1437 EXPECT_LT(kLongTestIterations
/ 100, video_ticks_
.size());
1438 EXPECT_GE(kLongTestIterations
/ 3, video_ticks_
.size());
1439 VLOG(1) << "Fully transmitted " << video_ticks_
.size() << " frames.";
1440 EXPECT_LT((video_ticks_
.back().second
- test_end
).InMilliseconds(), 1000);
1443 TEST_F(End2EndTest
, OldPacketNetwork
) {
1444 Configure(CODEC_VIDEO_FAKE
, CODEC_AUDIO_PCM16
, 32000, 1);
1445 sender_to_receiver_
.SetPacketPipe(test::NewRandomDrop(0.01));
1446 scoped_ptr
<test::PacketPipe
> echo_chamber(
1447 test::NewDuplicateAndDelay(1, 10 * kFrameTimerMs
));
1448 echo_chamber
->AppendToPipe(
1449 test::NewDuplicateAndDelay(1, 20 * kFrameTimerMs
));
1450 echo_chamber
->AppendToPipe(
1451 test::NewDuplicateAndDelay(1, 40 * kFrameTimerMs
));
1452 echo_chamber
->AppendToPipe(
1453 test::NewDuplicateAndDelay(1, 80 * kFrameTimerMs
));
1454 echo_chamber
->AppendToPipe(
1455 test::NewDuplicateAndDelay(1, 160 * kFrameTimerMs
));
1457 receiver_to_sender_
.SetPacketPipe(echo_chamber
.Pass());
1461 SetExpectedVideoPlayoutSmoothness(
1462 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) * 90 / 100,
1463 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) * 110 / 100,
1464 base::TimeDelta::FromMilliseconds(kFrameTimerMs
) / 10);
1466 for (size_t frames_counter
= 0;
1467 frames_counter
< kLongTestIterations
;
1469 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1470 RunTasks(kFrameTimerMs
);
1472 RunTasks(100 * kFrameTimerMs
+ 1); // Empty the pipeline.
1474 EXPECT_EQ(kLongTestIterations
, video_ticks_
.size());
1477 TEST_F(End2EndTest
, TestSetPlayoutDelay
) {
1478 Configure(CODEC_VIDEO_FAKE
, CODEC_AUDIO_PCM16
, 32000, 1);
1479 video_sender_config_
.min_playout_delay
=
1480 video_sender_config_
.max_playout_delay
;
1481 audio_sender_config_
.min_playout_delay
=
1482 audio_sender_config_
.max_playout_delay
;
1483 video_sender_config_
.max_playout_delay
= base::TimeDelta::FromSeconds(1);
1484 audio_sender_config_
.max_playout_delay
= base::TimeDelta::FromSeconds(1);
1487 const int kNewDelay
= 600;
1489 int frames_counter
= 0;
1490 for (; frames_counter
< 200; ++frames_counter
) {
1491 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1492 RunTasks(kFrameTimerMs
);
1494 cast_sender_
->SetTargetPlayoutDelay(
1495 base::TimeDelta::FromMilliseconds(kNewDelay
));
1496 for (; frames_counter
< 400; ++frames_counter
) {
1497 SendFakeVideoFrame(testing_clock_sender_
->NowTicks());
1498 RunTasks(kFrameTimerMs
);
1500 RunTasks(100 * kFrameTimerMs
+ 1); // Empty the pipeline.
1502 for (size_t i
= 1; i
< video_ticks_
.size(); i
++) {
1503 int64 delta
= (video_ticks_
[i
].second
-
1504 video_ticks_
[i
-1].second
).InMilliseconds();
1506 EXPECT_EQ(kNewDelay
- kTargetPlayoutDelayMs
+ kFrameTimerMs
, delta
);
1507 EXPECT_EQ(0u, jump
);
1511 EXPECT_GT(jump
, 199u);
1512 EXPECT_LT(jump
, 220u);
1515 // TODO(pwestin): Add repeatable packet loss test.
1516 // TODO(pwestin): Add test for misaligned send get calls.
1517 // TODO(pwestin): Add more tests that does not resample.
1518 // TODO(pwestin): Add test when we have starvation for our RunTask.
1521 } // namespace media