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