Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / media / cast / test / end2end_unittest.cc
blobe8137c09e6f1347df4da101c5cd5835c8182f116
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // This test generate synthetic data. For audio it's a sinusoid waveform with
6 // frequency kSoundFrequency and different amplitudes. For video it's a pattern
7 // that is shifting by one pixel per frame, each pixels neighbors right and down
8 // is this pixels value +1, since the pixel value is 8 bit it will wrap
9 // frequently within the image. Visually this will create diagonally color bands
10 // that moves across the screen
12 #include <math.h>
13 #include <stdint.h>
15 #include <functional>
16 #include <list>
17 #include <map>
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"
45 namespace media {
46 namespace cast {
48 namespace {
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
78 // receiver.
79 static const int kTargetPlayoutDelayMs = 100;
81 // The maximum amount of deviation expected in the playout times emitted by the
82 // receiver.
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);
90 std::vector<uint8> v;
91 if (!base::HexStringToBytes(base_16, &v)) {
92 NOTREACHED();
94 compressed.assign(reinterpret_cast<const char*>(&v[0]), v.size());
95 return compressed;
98 void UpdateCastTransportStatus(CastTransportStatus status) {
99 bool result = (status == TRANSPORT_AUDIO_INITIALIZED ||
100 status == TRANSPORT_VIDEO_INITIALIZED);
101 EXPECT_TRUE(result);
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.
109 typedef struct {
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();
120 ++it) {
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));
129 } else {
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();
143 ++it) {
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));
152 } else {
153 ++(map_it->second.counter[it->type]);
156 return event_counter_for_packet;
159 } // namespace
161 // Shim that turns forwards packets from a test::PacketPipe to a
162 // PacketReceiverCallback.
163 class LoopBackPacketPipe : public test::PacketPipe {
164 public:
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());
175 private:
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 {
182 public:
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),
187 bytes_sent_(0) {}
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));
195 if (packet_pipe_) {
196 packet_pipe_->AppendToPipe(loopback_pipe.Pass());
197 } else {
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));
205 if (!send_packets_)
206 return true;
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)
212 return true;
215 scoped_ptr<Packet> packet_copy(new Packet(packet->data));
216 packet_pipe_->Send(packet_copy.Pass());
217 return true;
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();
234 private:
235 bool send_packets_;
236 bool drop_packets_belonging_to_odd_frames_;
237 scoped_refptr<CastEnvironment> cast_environment_;
238 scoped_ptr<test::PacketPipe> packet_pipe_;
239 int64 bytes_sent_;
242 // Class that verifies the audio frames coming out of the receiver.
243 class TestReceiverAudioCallback
244 : public base::RefCountedThreadSafe<TestReceiverAudioCallback> {
245 public:
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) {
271 ++num_called_;
274 void CheckAudioFrame(scoped_ptr<AudioBus> audio_bus,
275 const base::TimeTicks& playout_time,
276 bool is_continuous) {
277 ++num_called_;
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()),
296 EXPECT_NEAR(
297 (playout_time - expected_audio_frame->playout_time).InMillisecondsF(),
298 0.0,
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(),
321 num_elements);
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_; }
337 protected:
338 virtual ~TestReceiverAudioCallback() {
339 STLDeleteElements(&expected_frames_);
342 private:
343 friend class base::RefCountedThreadSafe<TestReceiverAudioCallback>;
345 int num_called_;
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> {
354 public:
355 struct ExpectedVideoFrame {
356 int start_value;
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) {
376 ++num_called_;
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);
397 EXPECT_NEAR(
398 (playout_time - expected_video_frame.playout_time).InMillisecondsF(),
399 0.0,
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_; }
411 protected:
412 virtual ~TestReceiverVideoCallback() {}
414 private:
415 friend class base::RefCountedThreadSafe<TestReceiverVideoCallback>;
417 int num_called_;
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 {
425 protected:
426 End2EndTest()
427 : start_time_(),
428 task_runner_(new test::FakeSingleThreadTaskRunner(&testing_clock_)),
429 testing_clock_sender_(new test::SkewedTickClock(&testing_clock_)),
430 task_runner_sender_(
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(),
437 task_runner_sender_,
438 task_runner_sender_,
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,
456 Codec audio_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(
538 *audio_bus,
539 reference_time +
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(
555 *audio_bus,
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());
575 void Create() {
576 net::IPEndPoint dummy_endpoint;
577 transport_sender_.reset(new CastTransportSenderImpl(
578 NULL,
579 testing_clock_sender_,
580 dummy_endpoint,
581 dummy_endpoint,
582 make_scoped_ptr(new base::DictionaryValue),
583 base::Bind(&UpdateCastTransportStatus),
584 base::Bind(&End2EndTest::LogRawEvents, base::Unretained(this)),
585 base::TimeDelta::FromMilliseconds(1),
586 task_runner_sender_,
587 PacketReceiverCallback(),
588 &sender_to_receiver_));
590 transport_receiver_.reset(new CastTransportSenderImpl(
591 NULL,
592 testing_clock_sender_,
593 dummy_endpoint,
594 dummy_endpoint,
595 make_scoped_ptr(new base::DictionaryValue),
596 base::Bind(&UpdateCastTransportStatus),
597 base::Bind(&End2EndTest::LogRawEvents, base::Unretained(this)),
598 base::TimeDelta::FromMilliseconds(1),
599 task_runner_sender_,
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());
608 cast_sender_ =
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(),
624 task_runner_,
625 &testing_clock_);
626 sender_to_receiver_.SetPacketReceiver(
627 transport_receiver_->PacketReceiverForTesting(),
628 task_runner_,
629 &testing_clock_);
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,
637 kSoundFrequency,
638 kSoundVolume));
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),
664 size, time_diff);
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(),
713 playout_time));
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()
725 << " usec.";
726 last_audio_playout_time_ = playout_time;
728 audio_ticks_.push_back(std::make_pair(
729 testing_clock_receiver_->NowTicks(),
730 playout_time));
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();
750 ++it) {
751 cast_environment_sender_->Logging()->InsertPacketEvent(it->timestamp,
752 it->type,
753 it->media_type,
754 it->rtp_timestamp,
755 it->frame_id,
756 it->packet_id,
757 it->max_packet_id,
758 it->size);
760 for (std::vector<media::cast::FrameEvent>::const_iterator it =
761 frame_events.begin();
762 it != frame_events.end();
763 ++it) {
764 cast_environment_sender_->Logging()->InsertFrameEvent(it->timestamp,
765 it->type,
766 it->media_type,
767 it->rtp_timestamp,
768 it->frame_id);
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);
826 Create();
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(
840 video_start,
841 testing_clock_sender_->NowTicks() +
842 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs),
843 true);
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;
860 video_start++;
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);
874 Create();
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);
893 Create();
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
898 // the first frame.
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);
920 Create();
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(
944 video_start,
945 initial_send_time + expected_delay +
946 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs),
947 true);
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;
957 video_start++;
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(
972 video_start,
973 testing_clock_sender_->NowTicks() +
974 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs),
975 true);
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;
992 video_start++;
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;
1008 Create();
1009 sender_to_receiver_.DropAllPacketsBelongingToOddFrames();
1011 int video_start = kVideoStart;
1012 base::TimeTicks reference_time;
1014 int i = 0;
1015 for (; i < 20; ++i) {
1016 reference_time = testing_clock_sender_->NowTicks();
1017 SendVideoFrame(video_start, reference_time);
1019 if (i % 2 == 0) {
1020 test_receiver_video_callback_->AddExpectedResult(
1021 video_start,
1022 reference_time + base::TimeDelta::FromMilliseconds(target_delay),
1023 i == 0);
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);
1032 video_start++;
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;
1052 Create();
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(
1060 frames_counter,
1061 reference_time +
1062 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs),
1063 true);
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;
1089 Create();
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);
1107 Create();
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(
1114 video_start,
1115 reference_time +
1116 base::TimeDelta::FromMilliseconds(kTargetPlayoutDelayMs),
1117 true);
1119 SendVideoFrame(video_start, reference_time);
1120 RunTasks(kFrameTimerMs);
1122 cast_receiver_->RequestDecodedVideoFrame(
1123 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame,
1124 test_receiver_video_callback_));
1126 video_start++;
1129 // Basic tests.
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.
1137 // Logging tests.
1138 // Frame logging.
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
1143 // for that frame.
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();
1154 ++map_it) {
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
1183 // frame.
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
1188 // frame.
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
1194 // frame.
1195 // (i.e. Total event count = expected event count)
1196 EXPECT_EQ(total_event_count_for_frame, expected_event_count_for_frame);
1199 // Packet logging.
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();
1209 ++map_it) {
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);
1230 Create();
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;
1248 // Basic tests.
1249 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline.
1251 EXPECT_EQ(num_audio_frames_requested,
1252 test_receiver_audio_callback_->number_times_called());
1254 // Logging tests.
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();
1269 ++it) {
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,
1312 Create();
1313 StartBasicPlayer();
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.
1335 #if defined(NDEBUG)
1336 const size_t kLongTestIterations = 10000;
1337 #else
1338 const size_t kLongTestIterations = 1000;
1339 #endif
1341 TEST_F(End2EndTest, ReceiverClockFast) {
1342 Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16, 32000,
1344 Create();
1345 StartBasicPlayer();
1346 SetReceiverSkew(2.0, base::TimeDelta::FromMicroseconds(1234567));
1348 for (size_t frames_counter = 0;
1349 frames_counter < kLongTestIterations;
1350 ++frames_counter) {
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,
1361 Create();
1362 StartBasicPlayer();
1363 SetReceiverSkew(0.5, base::TimeDelta::FromMicroseconds(-765432));
1365 for (size_t frames_counter = 0;
1366 frames_counter < kLongTestIterations;
1367 ++frames_counter) {
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,
1378 Create();
1379 StartBasicPlayer();
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;
1390 ++frames_counter) {
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());
1403 Create();
1404 StartBasicPlayer();
1406 for (size_t frames_counter = 0;
1407 frames_counter < kLongTestIterations;
1408 ++frames_counter) {
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());
1426 Create();
1427 StartBasicPlayer();
1429 for (size_t frames_counter = 0;
1430 frames_counter < kLongTestIterations;
1431 ++frames_counter) {
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());
1458 Create();
1459 StartBasicPlayer();
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;
1468 ++frames_counter) {
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);
1485 Create();
1486 StartBasicPlayer();
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.
1501 size_t jump = 0;
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();
1505 if (delta > 100) {
1506 EXPECT_EQ(kNewDelay - kTargetPlayoutDelayMs + kFrameTimerMs, delta);
1507 EXPECT_EQ(0u, jump);
1508 jump = i;
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.
1520 } // namespace cast
1521 } // namespace media