1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // This test generate synthetic data. For audio it's a sinusoid waveform with
6 // frequency kSoundFrequency and different amplitudes. For video it's a pattern
7 // that is shifting by one pixel per frame, each pixels neighbors right and down
8 // is this pixels value +1, since the pixel value is 8 bit it will wrap
9 // frequently within the image. Visually this will create diagonally color bands
10 // that moves across the screen
19 #include "base/bind.h"
20 #include "base/bind_helpers.h"
21 #include "base/stl_util.h"
22 #include "base/strings/string_number_conversions.h"
23 #include "base/sys_byteorder.h"
24 #include "base/test/simple_test_tick_clock.h"
25 #include "base/time/tick_clock.h"
26 #include "media/base/audio_bus.h"
27 #include "media/base/video_frame.h"
28 #include "media/cast/cast_config.h"
29 #include "media/cast/cast_environment.h"
30 #include "media/cast/cast_receiver.h"
31 #include "media/cast/cast_sender.h"
32 #include "media/cast/logging/simple_event_subscriber.h"
33 #include "media/cast/test/fake_single_thread_task_runner.h"
34 #include "media/cast/test/utility/audio_utility.h"
35 #include "media/cast/test/utility/default_config.h"
36 #include "media/cast/test/utility/udp_proxy.h"
37 #include "media/cast/test/utility/video_utility.h"
38 #include "media/cast/transport/cast_transport_config.h"
39 #include "media/cast/transport/cast_transport_defines.h"
40 #include "media/cast/transport/cast_transport_sender.h"
41 #include "media/cast/transport/cast_transport_sender_impl.h"
42 #include "testing/gtest/include/gtest/gtest.h"
49 static const int64 kStartMillisecond = INT64_C(1245);
50 static const int kAudioChannels = 2;
51 static const double kSoundFrequency = 314.15926535897; // Freq of sine wave.
52 static const float kSoundVolume = 0.5f;
53 static const int kVideoHdWidth = 1280;
54 static const int kVideoHdHeight = 720;
55 static const int kVideoQcifWidth = 176;
56 static const int kVideoQcifHeight = 144;
58 // Since the video encoded and decoded an error will be introduced; when
59 // comparing individual pixels the error can be quite large; we allow a PSNR of
60 // at least |kVideoAcceptedPSNR|.
61 static const double kVideoAcceptedPSNR = 38.0;
63 // The tests are commonly implemented with |kFrameTimerMs| RunTask function;
64 // a normal video is 30 fps hence the 33 ms between frames.
65 static const int kFrameTimerMs = 33;
67 // The packets pass through the pacer which can delay the beginning of the
68 // frame by 10 ms if there is packets belonging to the previous frame being
70 // In addition, audio packets are sent in 10mS intervals in audio_encoder.cc,
71 // although we send an audio frame every 33mS, which adds an extra delay.
72 // A TODO was added in the code to resolve this.
73 static const int kTimerErrorMs = 20;
75 // Start the video synthetic start value to medium range value, to avoid edge
76 // effects cause by encoding and quantization.
77 static const int kVideoStart = 100;
79 // The size of audio frames. The encoder joins/breaks all inserted audio into
80 // chunks of this size.
81 static const int kAudioFrameDurationMs = 10;
83 std::string ConvertFromBase16String(const std::string base_16) {
84 std::string compressed;
85 DCHECK_EQ(base_16.size() % 2, 0u) << "Must be a multiple of 2";
86 compressed.reserve(base_16.size() / 2);
89 if (!base::HexStringToBytes(base_16, &v)) {
92 compressed.assign(reinterpret_cast<const char*>(&v[0]), v.size());
96 void UpdateCastTransportStatus(transport::CastTransportStatus status) {
97 bool result = (status == transport::TRANSPORT_AUDIO_INITIALIZED ||
98 status == transport::TRANSPORT_VIDEO_INITIALIZED);
102 void AudioInitializationStatus(CastInitializationStatus status) {
103 EXPECT_EQ(STATUS_AUDIO_INITIALIZED, status);
106 void VideoInitializationStatus(CastInitializationStatus status) {
107 EXPECT_EQ(STATUS_VIDEO_INITIALIZED, status);
110 // This is wrapped in a struct because it needs to be put into a std::map.
112 int counter[kNumOfLoggingEvents];
113 } LoggingEventCounts;
115 // Constructs a map from each frame (RTP timestamp) to counts of each event
116 // type logged for that frame.
117 std::map<RtpTimestamp, LoggingEventCounts> GetEventCountForFrameEvents(
118 const std::vector<FrameEvent>& frame_events) {
119 std::map<RtpTimestamp, LoggingEventCounts> event_counter_for_frame;
120 for (std::vector<FrameEvent>::const_iterator it = frame_events.begin();
121 it != frame_events.end();
123 std::map<RtpTimestamp, LoggingEventCounts>::iterator map_it =
124 event_counter_for_frame.find(it->rtp_timestamp);
125 if (map_it == event_counter_for_frame.end()) {
126 LoggingEventCounts new_counter;
127 memset(&new_counter, 0, sizeof(new_counter));
128 ++(new_counter.counter[it->type]);
129 event_counter_for_frame.insert(
130 std::make_pair(it->rtp_timestamp, new_counter));
132 ++(map_it->second.counter[it->type]);
135 return event_counter_for_frame;
138 // Constructs a map from each packet (Packet ID) to counts of each event
139 // type logged for that packet.
140 std::map<uint16, LoggingEventCounts> GetEventCountForPacketEvents(
141 const std::vector<PacketEvent>& packet_events) {
142 std::map<uint16, LoggingEventCounts> event_counter_for_packet;
143 for (std::vector<PacketEvent>::const_iterator it = packet_events.begin();
144 it != packet_events.end();
146 std::map<uint16, LoggingEventCounts>::iterator map_it =
147 event_counter_for_packet.find(it->packet_id);
148 if (map_it == event_counter_for_packet.end()) {
149 LoggingEventCounts new_counter;
150 memset(&new_counter, 0, sizeof(new_counter));
151 ++(new_counter.counter[it->type]);
152 event_counter_for_packet.insert(
153 std::make_pair(it->packet_id, new_counter));
155 ++(map_it->second.counter[it->type]);
158 return event_counter_for_packet;
161 void CountVideoFrame(int* counter,
162 const scoped_refptr<media::VideoFrame>& video_frame,
163 const base::TimeTicks& render_time, bool continuous) {
169 class LoopBackPacketPipe : public test::PacketPipe {
171 LoopBackPacketPipe(const transport::PacketReceiverCallback& packet_receiver)
172 : packet_receiver_(packet_receiver) {}
174 virtual ~LoopBackPacketPipe() {}
176 // PacketPipe implementations.
177 virtual void Send(scoped_ptr<transport::Packet> packet) OVERRIDE {
178 packet_receiver_.Run(packet.Pass());
182 transport::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 transport::PacketSender {
189 explicit LoopBackTransport(scoped_refptr<CastEnvironment> cast_environment)
190 : send_packets_(true),
191 drop_packets_belonging_to_odd_frames_(false),
192 cast_environment_(cast_environment) {}
194 void SetPacketReceiver(
195 const transport::PacketReceiverCallback& packet_receiver) {
196 scoped_ptr<test::PacketPipe> loopback_pipe(
197 new LoopBackPacketPipe(packet_receiver));
199 packet_pipe_->AppendToPipe(loopback_pipe.Pass());
201 packet_pipe_ = loopback_pipe.Pass();
205 virtual bool SendPacket(transport::PacketRef packet,
206 const base::Closure& cb) OVERRIDE {
207 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
211 if (drop_packets_belonging_to_odd_frames_) {
212 uint32 frame_id = packet->data[13];
213 if (frame_id % 2 == 1)
217 scoped_ptr<Packet> packet_copy(new Packet(packet->data));
218 packet_pipe_->Send(packet_copy.Pass());
222 void SetSendPackets(bool send_packets) { send_packets_ = send_packets; }
224 void DropAllPacketsBelongingToOddFrames() {
225 drop_packets_belonging_to_odd_frames_ = true;
228 void SetPacketPipe(scoped_ptr<test::PacketPipe> pipe) {
229 // Append the loopback pipe to the end.
230 pipe->AppendToPipe(packet_pipe_.Pass());
231 packet_pipe_ = pipe.Pass();
236 bool drop_packets_belonging_to_odd_frames_;
237 scoped_refptr<CastEnvironment> cast_environment_;
238 scoped_ptr<test::PacketPipe> packet_pipe_;
241 // Class that verifies the audio frames coming out of the receiver.
242 class TestReceiverAudioCallback
243 : public base::RefCountedThreadSafe<TestReceiverAudioCallback> {
245 struct ExpectedAudioFrame {
246 scoped_ptr<AudioBus> audio_bus;
247 base::TimeTicks record_time;
250 TestReceiverAudioCallback() : num_called_(0) {}
252 void SetExpectedSamplingFrequency(int expected_sampling_frequency) {
253 expected_sampling_frequency_ = expected_sampling_frequency;
256 void AddExpectedResult(const AudioBus& audio_bus,
257 const base::TimeTicks& record_time) {
258 scoped_ptr<ExpectedAudioFrame> expected_audio_frame(
259 new ExpectedAudioFrame());
260 expected_audio_frame->audio_bus =
261 AudioBus::Create(audio_bus.channels(), audio_bus.frames()).Pass();
262 audio_bus.CopyTo(expected_audio_frame->audio_bus.get());
263 expected_audio_frame->record_time = record_time;
264 expected_frames_.push_back(expected_audio_frame.release());
267 void IgnoreAudioFrame(scoped_ptr<AudioBus> audio_bus,
268 const base::TimeTicks& playout_time,
269 bool is_continuous) {
273 void CheckAudioFrame(scoped_ptr<AudioBus> audio_bus,
274 const base::TimeTicks& playout_time,
275 bool is_continuous) {
278 ASSERT_TRUE(!!audio_bus);
279 ASSERT_FALSE(expected_frames_.empty());
280 const scoped_ptr<ExpectedAudioFrame> expected_audio_frame(
281 expected_frames_.front());
282 expected_frames_.pop_front();
284 EXPECT_EQ(audio_bus->channels(), kAudioChannels);
285 EXPECT_EQ(audio_bus->frames(), expected_audio_frame->audio_bus->frames());
286 for (int ch = 0; ch < audio_bus->channels(); ++ch) {
287 EXPECT_NEAR(CountZeroCrossings(
288 expected_audio_frame->audio_bus->channel(ch),
289 expected_audio_frame->audio_bus->frames()),
290 CountZeroCrossings(audio_bus->channel(ch),
291 audio_bus->frames()),
295 // TODO(miu): This is a "fuzzy" way to check the timestamps. We should be
296 // able to compute exact offsets with "omnipotent" knowledge of the system.
297 const base::TimeTicks upper_bound =
298 expected_audio_frame->record_time +
299 base::TimeDelta::FromMilliseconds(kDefaultRtpMaxDelayMs +
301 EXPECT_GE(upper_bound, playout_time)
302 << "playout_time - upper_bound == "
303 << (playout_time - upper_bound).InMicroseconds() << " usec";
305 EXPECT_TRUE(is_continuous);
308 void CheckCodedAudioFrame(
309 scoped_ptr<transport::EncodedAudioFrame> audio_frame,
310 const base::TimeTicks& playout_time) {
311 ASSERT_TRUE(!!audio_frame);
312 ASSERT_FALSE(expected_frames_.empty());
313 const ExpectedAudioFrame& expected_audio_frame =
314 *(expected_frames_.front());
315 // Note: Just peeking here. Will delegate to CheckAudioFrame() to pop.
317 // We need to "decode" the encoded audio frame. The codec is simply to
318 // swizzle the bytes of each int16 from host-->network-->host order to get
319 // interleaved int16 PCM. Then, make an AudioBus out of that.
320 const int num_elements = audio_frame->data.size() / sizeof(int16);
321 ASSERT_EQ(expected_audio_frame.audio_bus->channels() *
322 expected_audio_frame.audio_bus->frames(),
324 int16* const pcm_data =
325 reinterpret_cast<int16*>(string_as_array(&audio_frame->data));
326 for (int i = 0; i < num_elements; ++i)
327 pcm_data[i] = static_cast<int16>(base::NetToHost16(pcm_data[i]));
328 scoped_ptr<AudioBus> audio_bus(
329 AudioBus::Create(expected_audio_frame.audio_bus->channels(),
330 expected_audio_frame.audio_bus->frames()));
331 audio_bus->FromInterleaved(pcm_data, audio_bus->frames(), sizeof(int16));
333 // Delegate the checking from here...
334 CheckAudioFrame(audio_bus.Pass(), playout_time, true);
337 int number_times_called() const { return num_called_; }
340 virtual ~TestReceiverAudioCallback() {
341 STLDeleteElements(&expected_frames_);
345 friend class base::RefCountedThreadSafe<TestReceiverAudioCallback>;
348 int expected_sampling_frequency_;
349 std::list<ExpectedAudioFrame*> expected_frames_;
352 // Class that verifies the video frames coming out of the receiver.
353 class TestReceiverVideoCallback
354 : public base::RefCountedThreadSafe<TestReceiverVideoCallback> {
356 struct ExpectedVideoFrame {
360 base::TimeTicks capture_time;
361 bool should_be_continuous;
364 TestReceiverVideoCallback() : num_called_(0) {}
366 void AddExpectedResult(int start_value,
369 const base::TimeTicks& capture_time,
370 bool should_be_continuous) {
371 ExpectedVideoFrame expected_video_frame;
372 expected_video_frame.start_value = start_value;
373 expected_video_frame.width = width;
374 expected_video_frame.height = height;
375 expected_video_frame.capture_time = capture_time;
376 expected_video_frame.should_be_continuous = should_be_continuous;
377 expected_frame_.push_back(expected_video_frame);
380 void CheckVideoFrame(const scoped_refptr<media::VideoFrame>& video_frame,
381 const base::TimeTicks& render_time,
382 bool is_continuous) {
385 ASSERT_TRUE(!!video_frame);
386 ASSERT_FALSE(expected_frame_.empty());
387 ExpectedVideoFrame expected_video_frame = expected_frame_.front();
388 expected_frame_.pop_front();
390 base::TimeDelta time_since_capture =
391 render_time - expected_video_frame.capture_time;
392 const base::TimeDelta upper_bound = base::TimeDelta::FromMilliseconds(
393 kDefaultRtpMaxDelayMs + kTimerErrorMs);
395 // TODO(miu): This is a "fuzzy" way to check the timestamps. We should be
396 // able to compute exact offsets with "omnipotent" knowledge of the system.
397 EXPECT_GE(upper_bound, time_since_capture)
398 << "time_since_capture - upper_bound == "
399 << (time_since_capture - upper_bound).InMicroseconds() << " usec";
400 // TODO(miu): I broke the concept of 100 ms target delay timing on the
401 // receiver side, but the logic for computing playout time really isn't any
402 // more broken than it was. This only affects the receiver, and is to be
403 // rectified in an soon-upcoming change. http://crbug.com/356942
404 // EXPECT_LE(expected_video_frame.capture_time, render_time);
405 EXPECT_EQ(expected_video_frame.width, video_frame->visible_rect().width());
406 EXPECT_EQ(expected_video_frame.height,
407 video_frame->visible_rect().height());
409 gfx::Size size(expected_video_frame.width, expected_video_frame.height);
410 scoped_refptr<media::VideoFrame> expected_I420_frame =
411 media::VideoFrame::CreateFrame(
412 VideoFrame::I420, size, gfx::Rect(size), size, base::TimeDelta());
413 PopulateVideoFrame(expected_I420_frame, expected_video_frame.start_value);
415 EXPECT_GE(I420PSNR(expected_I420_frame, video_frame), kVideoAcceptedPSNR);
417 EXPECT_EQ(expected_video_frame.should_be_continuous, is_continuous);
420 int number_times_called() const { return num_called_; }
423 virtual ~TestReceiverVideoCallback() {}
426 friend class base::RefCountedThreadSafe<TestReceiverVideoCallback>;
429 std::list<ExpectedVideoFrame> expected_frame_;
432 // The actual test class, generate synthetic data for both audio and video and
433 // send those through the sender and receiver and analyzes the result.
434 class End2EndTest : public ::testing::Test {
438 testing_clock_sender_(new base::SimpleTestTickClock()),
439 testing_clock_receiver_(new base::SimpleTestTickClock()),
441 new test::FakeSingleThreadTaskRunner(testing_clock_sender_)),
442 cast_environment_sender_(new CastEnvironment(
443 scoped_ptr<base::TickClock>(testing_clock_sender_).Pass(),
447 cast_environment_receiver_(new CastEnvironment(
448 scoped_ptr<base::TickClock>(testing_clock_receiver_).Pass(),
452 receiver_to_sender_(cast_environment_receiver_),
453 sender_to_receiver_(cast_environment_sender_),
454 test_receiver_audio_callback_(new TestReceiverAudioCallback()),
455 test_receiver_video_callback_(new TestReceiverVideoCallback()) {
456 testing_clock_sender_->Advance(
457 base::TimeDelta::FromMilliseconds(kStartMillisecond));
458 testing_clock_receiver_->Advance(
459 base::TimeDelta::FromMilliseconds(kStartMillisecond));
460 cast_environment_sender_->Logging()->AddRawEventSubscriber(
461 &event_subscriber_sender_);
464 void Configure(transport::VideoCodec video_codec,
465 transport::AudioCodec audio_codec,
466 int audio_sampling_frequency,
467 bool external_audio_decoder,
468 int max_number_of_video_buffers_used) {
469 audio_sender_config_.rtp_config.ssrc = 1;
470 audio_sender_config_.incoming_feedback_ssrc = 2;
471 audio_sender_config_.rtp_config.payload_type = 96;
472 audio_sender_config_.use_external_encoder = false;
473 audio_sender_config_.frequency = audio_sampling_frequency;
474 audio_sender_config_.channels = kAudioChannels;
475 audio_sender_config_.bitrate = kDefaultAudioEncoderBitrate;
476 audio_sender_config_.codec = audio_codec;
478 audio_receiver_config_.feedback_ssrc =
479 audio_sender_config_.incoming_feedback_ssrc;
480 audio_receiver_config_.incoming_ssrc = audio_sender_config_.rtp_config.ssrc;
481 audio_receiver_config_.rtp_payload_type =
482 audio_sender_config_.rtp_config.payload_type;
483 audio_receiver_config_.use_external_decoder = external_audio_decoder;
484 audio_receiver_config_.frequency = audio_sender_config_.frequency;
485 audio_receiver_config_.channels = kAudioChannels;
486 audio_receiver_config_.codec = audio_sender_config_.codec;
488 test_receiver_audio_callback_->SetExpectedSamplingFrequency(
489 audio_receiver_config_.frequency);
491 video_sender_config_.rtp_config.ssrc = 3;
492 video_sender_config_.incoming_feedback_ssrc = 4;
493 video_sender_config_.rtp_config.payload_type = 97;
494 video_sender_config_.use_external_encoder = false;
495 video_sender_config_.width = kVideoHdWidth;
496 video_sender_config_.height = kVideoHdHeight;
497 video_sender_config_.max_bitrate = 5000000;
498 video_sender_config_.min_bitrate = 1000000;
499 video_sender_config_.start_bitrate = 5000000;
500 video_sender_config_.max_qp = 30;
501 video_sender_config_.min_qp = 4;
502 video_sender_config_.max_frame_rate = 30;
503 video_sender_config_.max_number_of_video_buffers_used =
504 max_number_of_video_buffers_used;
505 video_sender_config_.codec = video_codec;
507 video_receiver_config_.feedback_ssrc =
508 video_sender_config_.incoming_feedback_ssrc;
509 video_receiver_config_.incoming_ssrc = video_sender_config_.rtp_config.ssrc;
510 video_receiver_config_.rtp_payload_type =
511 video_sender_config_.rtp_config.payload_type;
512 video_receiver_config_.use_external_decoder = false;
513 video_receiver_config_.codec = video_sender_config_.codec;
516 void FeedAudioFrames(int count, bool will_be_checked) {
517 for (int i = 0; i < count; ++i) {
518 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus(
519 base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs)));
520 const base::TimeTicks send_time =
521 testing_clock_sender_->NowTicks() +
522 i * base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs);
524 test_receiver_audio_callback_->AddExpectedResult(*audio_bus, send_time);
525 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time);
529 void FeedAudioFramesWithExpectedDelay(int count,
530 const base::TimeDelta& delay) {
531 for (int i = 0; i < count; ++i) {
532 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus(
533 base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs)));
534 const base::TimeTicks send_time =
535 testing_clock_sender_->NowTicks() +
536 i * base::TimeDelta::FromMilliseconds(kAudioFrameDurationMs);
537 test_receiver_audio_callback_->AddExpectedResult(*audio_bus,
539 audio_frame_input_->InsertAudio(audio_bus.Pass(), send_time);
543 void RequestAudioFrames(int count, bool with_check) {
544 for (int i = 0; i < count; ++i) {
545 frame_receiver_->GetRawAudioFrame(
546 base::Bind(with_check ? &TestReceiverAudioCallback::CheckAudioFrame :
547 &TestReceiverAudioCallback::IgnoreAudioFrame,
548 test_receiver_audio_callback_));
553 cast_receiver_ = CastReceiver::Create(cast_environment_receiver_,
554 audio_receiver_config_,
555 video_receiver_config_,
556 &receiver_to_sender_);
557 net::IPEndPoint dummy_endpoint;
558 transport_sender_.reset(new transport::CastTransportSenderImpl(
560 testing_clock_sender_,
562 base::Bind(&UpdateCastTransportStatus),
563 base::Bind(&End2EndTest::LogRawEvents, base::Unretained(this)),
564 base::TimeDelta::FromSeconds(1),
566 &sender_to_receiver_));
569 CastSender::Create(cast_environment_sender_, transport_sender_.get());
571 // Initializing audio and video senders.
572 cast_sender_->InitializeAudio(audio_sender_config_,
573 base::Bind(&AudioInitializationStatus));
574 cast_sender_->InitializeVideo(video_sender_config_,
575 base::Bind(&VideoInitializationStatus),
576 CreateDefaultVideoEncodeAcceleratorCallback(),
577 CreateDefaultVideoEncodeMemoryCallback());
579 receiver_to_sender_.SetPacketReceiver(cast_sender_->packet_receiver());
580 sender_to_receiver_.SetPacketReceiver(cast_receiver_->packet_receiver());
582 audio_frame_input_ = cast_sender_->audio_frame_input();
583 video_frame_input_ = cast_sender_->video_frame_input();
585 frame_receiver_ = cast_receiver_->frame_receiver();
587 audio_bus_factory_.reset(
588 new TestAudioBusFactory(audio_sender_config_.channels,
589 audio_sender_config_.frequency,
594 virtual ~End2EndTest() {
595 cast_environment_sender_->Logging()->RemoveRawEventSubscriber(
596 &event_subscriber_sender_);
599 virtual void TearDown() OVERRIDE {
600 cast_sender_.reset();
601 cast_receiver_.reset();
602 task_runner_->RunTasks();
605 void SendVideoFrame(int start_value, const base::TimeTicks& capture_time) {
606 if (start_time_.is_null())
607 start_time_ = capture_time;
608 base::TimeDelta time_diff = capture_time - start_time_;
609 gfx::Size size(video_sender_config_.width, video_sender_config_.height);
610 EXPECT_TRUE(VideoFrame::IsValidConfig(
611 VideoFrame::I420, size, gfx::Rect(size), size));
612 scoped_refptr<media::VideoFrame> video_frame =
613 media::VideoFrame::CreateFrame(
614 VideoFrame::I420, size, gfx::Rect(size), size, time_diff);
615 PopulateVideoFrame(video_frame, start_value);
616 video_frame_input_->InsertRawVideoFrame(video_frame, capture_time);
619 void SendFakeVideoFrame(const base::TimeTicks& capture_time) {
620 video_frame_input_->InsertRawVideoFrame(
621 media::VideoFrame::CreateBlackFrame(gfx::Size(2, 2)), capture_time);
624 void RunTasks(int during_ms) {
625 for (int i = 0; i < during_ms; ++i) {
626 // Call process the timers every 1 ms.
627 testing_clock_sender_->Advance(base::TimeDelta::FromMilliseconds(1));
628 testing_clock_receiver_->Advance(base::TimeDelta::FromMilliseconds(1));
629 task_runner_->RunTasks();
633 void LogRawEvents(const std::vector<PacketEvent>& packet_events) {
634 EXPECT_FALSE(packet_events.empty());
635 for (std::vector<media::cast::PacketEvent>::const_iterator it =
636 packet_events.begin();
637 it != packet_events.end();
639 cast_environment_sender_->Logging()->InsertPacketEvent(it->timestamp,
649 AudioReceiverConfig audio_receiver_config_;
650 VideoReceiverConfig video_receiver_config_;
651 AudioSenderConfig audio_sender_config_;
652 VideoSenderConfig video_sender_config_;
654 base::TimeTicks start_time_;
655 base::SimpleTestTickClock* testing_clock_sender_;
656 base::SimpleTestTickClock* testing_clock_receiver_;
657 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_;
658 scoped_refptr<CastEnvironment> cast_environment_sender_;
659 scoped_refptr<CastEnvironment> cast_environment_receiver_;
661 LoopBackTransport receiver_to_sender_;
662 LoopBackTransport sender_to_receiver_;
663 scoped_ptr<transport::CastTransportSenderImpl> transport_sender_;
665 scoped_ptr<CastReceiver> cast_receiver_;
666 scoped_ptr<CastSender> cast_sender_;
667 scoped_refptr<AudioFrameInput> audio_frame_input_;
668 scoped_refptr<VideoFrameInput> video_frame_input_;
669 scoped_refptr<FrameReceiver> frame_receiver_;
671 scoped_refptr<TestReceiverAudioCallback> test_receiver_audio_callback_;
672 scoped_refptr<TestReceiverVideoCallback> test_receiver_video_callback_;
674 scoped_ptr<TestAudioBusFactory> audio_bus_factory_;
676 SimpleEventSubscriber event_subscriber_sender_;
677 std::vector<FrameEvent> frame_events_;
678 std::vector<PacketEvent> packet_events_;
679 // |transport_sender_| has a RepeatingTimer which needs a MessageLoop.
680 base::MessageLoop message_loop_;
683 TEST_F(End2EndTest, LoopNoLossPcm16) {
684 Configure(transport::kVp8, transport::kPcm16, 32000, false, 1);
685 // Reduce video resolution to allow processing multiple frames within a
686 // reasonable time frame.
687 video_sender_config_.width = kVideoQcifWidth;
688 video_sender_config_.height = kVideoQcifHeight;
691 const int kNumIterations = 50;
692 int video_start = kVideoStart;
693 int audio_diff = kFrameTimerMs;
694 int num_audio_frames_requested = 0;
695 for (int i = 0; i < kNumIterations; ++i) {
696 const int num_audio_frames = audio_diff / kAudioFrameDurationMs;
697 audio_diff -= num_audio_frames * kAudioFrameDurationMs;
699 if (num_audio_frames > 0)
700 FeedAudioFrames(1, true);
702 test_receiver_video_callback_->AddExpectedResult(
704 video_sender_config_.width,
705 video_sender_config_.height,
706 testing_clock_sender_->NowTicks(),
708 SendVideoFrame(video_start, testing_clock_sender_->NowTicks());
710 if (num_audio_frames > 0)
711 RunTasks(kAudioFrameDurationMs); // Advance clock forward.
712 if (num_audio_frames > 1)
713 FeedAudioFrames(num_audio_frames - 1, true);
715 RequestAudioFrames(num_audio_frames, true);
716 num_audio_frames_requested += num_audio_frames;
718 frame_receiver_->GetRawVideoFrame(
719 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame,
720 test_receiver_video_callback_));
722 RunTasks(kFrameTimerMs - kAudioFrameDurationMs);
723 audio_diff += kFrameTimerMs;
727 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline.
728 EXPECT_EQ(num_audio_frames_requested,
729 test_receiver_audio_callback_->number_times_called());
730 EXPECT_EQ(kNumIterations,
731 test_receiver_video_callback_->number_times_called());
734 // This tests our external decoder interface for Audio.
735 // Audio test without packet loss using raw PCM 16 audio "codec";
736 TEST_F(End2EndTest, LoopNoLossPcm16ExternalDecoder) {
737 Configure(transport::kVp8, transport::kPcm16, 32000, true, 1);
740 const int kNumIterations = 10;
741 for (int i = 0; i < kNumIterations; ++i) {
742 FeedAudioFrames(1, true);
743 RunTasks(kAudioFrameDurationMs);
744 frame_receiver_->GetCodedAudioFrame(
745 base::Bind(&TestReceiverAudioCallback::CheckCodedAudioFrame,
746 test_receiver_audio_callback_));
748 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline.
749 EXPECT_EQ(kNumIterations,
750 test_receiver_audio_callback_->number_times_called());
753 // This tests our Opus audio codec without video.
754 TEST_F(End2EndTest, LoopNoLossOpus) {
755 Configure(transport::kVp8, transport::kOpus, kDefaultAudioSamplingRate,
759 const int kNumIterations = 300;
760 for (int i = 0; i < kNumIterations; ++i) {
761 // Opus introduces a tiny delay before the sinewave starts; so don't examine
763 const bool examine_audio_data = i > 0;
764 FeedAudioFrames(1, examine_audio_data);
765 RunTasks(kAudioFrameDurationMs);
766 RequestAudioFrames(1, examine_audio_data);
768 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline.
769 EXPECT_EQ(kNumIterations,
770 test_receiver_audio_callback_->number_times_called());
773 // This tests start sending audio and video at start-up time before the receiver
774 // is ready; it sends 2 frames before the receiver comes online.
776 // Test disabled due to flakiness: It appears that the RTCP synchronization
777 // sometimes kicks in, and sometimes doesn't. When it does, there's a sharp
778 // discontinuity in the timeline, throwing off the test expectations. See TODOs
779 // in audio_receiver.cc for likely cause(s) of this bug.
780 // http://crbug.com/356942
781 TEST_F(End2EndTest, DISABLED_StartSenderBeforeReceiver) {
782 Configure(transport::kVp8, transport::kPcm16, kDefaultAudioSamplingRate,
786 int video_start = kVideoStart;
787 int audio_diff = kFrameTimerMs;
789 sender_to_receiver_.SetSendPackets(false);
791 const int test_delay_ms = 100;
793 const int kNumVideoFramesBeforeReceiverStarted = 2;
794 const base::TimeTicks initial_send_time = testing_clock_sender_->NowTicks();
795 const base::TimeDelta expected_delay =
796 base::TimeDelta::FromMilliseconds(test_delay_ms + kFrameTimerMs);
797 for (int i = 0; i < kNumVideoFramesBeforeReceiverStarted; ++i) {
798 const int num_audio_frames = audio_diff / kAudioFrameDurationMs;
799 audio_diff -= num_audio_frames * kAudioFrameDurationMs;
801 if (num_audio_frames > 0)
802 FeedAudioFramesWithExpectedDelay(1, expected_delay);
804 // Frame will be rendered with 100mS delay, as the transmission is delayed.
805 // The receiver at this point cannot be synced to the sender's clock, as no
806 // packets, and specifically no RTCP packets were sent.
807 test_receiver_video_callback_->AddExpectedResult(
809 video_sender_config_.width,
810 video_sender_config_.height,
811 initial_send_time + expected_delay,
813 SendVideoFrame(video_start, testing_clock_sender_->NowTicks());
815 if (num_audio_frames > 0)
816 RunTasks(kAudioFrameDurationMs); // Advance clock forward.
817 if (num_audio_frames > 1)
818 FeedAudioFramesWithExpectedDelay(num_audio_frames - 1, expected_delay);
820 RunTasks(kFrameTimerMs - kAudioFrameDurationMs);
821 audio_diff += kFrameTimerMs;
825 RunTasks(test_delay_ms);
826 sender_to_receiver_.SetSendPackets(true);
828 int num_audio_frames_requested = 0;
829 for (int j = 0; j < 10; ++j) {
830 const int num_audio_frames = audio_diff / kAudioFrameDurationMs;
831 audio_diff -= num_audio_frames * kAudioFrameDurationMs;
833 if (num_audio_frames > 0)
834 FeedAudioFrames(1, true);
836 test_receiver_video_callback_->AddExpectedResult(
838 video_sender_config_.width,
839 video_sender_config_.height,
840 testing_clock_sender_->NowTicks(),
842 SendVideoFrame(video_start, testing_clock_sender_->NowTicks());
844 if (num_audio_frames > 0)
845 RunTasks(kAudioFrameDurationMs); // Advance clock forward.
846 if (num_audio_frames > 1)
847 FeedAudioFrames(num_audio_frames - 1, true);
849 RequestAudioFrames(num_audio_frames, true);
850 num_audio_frames_requested += num_audio_frames;
852 frame_receiver_->GetRawVideoFrame(
853 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame,
854 test_receiver_video_callback_));
856 RunTasks(kFrameTimerMs - kAudioFrameDurationMs);
857 audio_diff += kFrameTimerMs;
860 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline.
861 EXPECT_EQ(num_audio_frames_requested,
862 test_receiver_audio_callback_->number_times_called());
863 EXPECT_EQ(10, test_receiver_video_callback_->number_times_called());
866 // This tests a network glitch lasting for 10 video frames.
867 // Flaky. See crbug.com/351596.
868 TEST_F(End2EndTest, DISABLED_GlitchWith3Buffers) {
869 Configure(transport::kVp8, transport::kOpus, kDefaultAudioSamplingRate,
871 video_sender_config_.rtp_config.max_delay_ms = 67;
872 video_receiver_config_.rtp_max_delay_ms = 67;
875 int video_start = kVideoStart;
876 base::TimeTicks send_time;
877 // Frames will rendered on completion until the render time stabilizes, i.e.
878 // we got enough data.
879 const int frames_before_glitch = 20;
880 for (int i = 0; i < frames_before_glitch; ++i) {
881 send_time = testing_clock_sender_->NowTicks();
882 SendVideoFrame(video_start, send_time);
883 test_receiver_video_callback_->AddExpectedResult(
885 video_sender_config_.width,
886 video_sender_config_.height,
889 frame_receiver_->GetRawVideoFrame(
890 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame,
891 test_receiver_video_callback_));
892 RunTasks(kFrameTimerMs);
896 // Introduce a glitch lasting for 10 frames.
897 sender_to_receiver_.SetSendPackets(false);
898 for (int i = 0; i < 10; ++i) {
899 send_time = testing_clock_sender_->NowTicks();
900 // First 3 will be sent and lost.
901 SendVideoFrame(video_start, send_time);
902 RunTasks(kFrameTimerMs);
905 sender_to_receiver_.SetSendPackets(true);
907 send_time = testing_clock_sender_->NowTicks();
909 // Frame 1 should be acked by now and we should have an opening to send 4.
910 SendVideoFrame(video_start, send_time);
911 RunTasks(kFrameTimerMs);
913 // Frames 1-3 are old frames by now, and therefore should be decoded, but
914 // not rendered. The next frame we expect to render is frame #4.
915 test_receiver_video_callback_->AddExpectedResult(video_start,
916 video_sender_config_.width,
917 video_sender_config_.height,
921 frame_receiver_->GetRawVideoFrame(
922 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame,
923 test_receiver_video_callback_));
925 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline.
926 EXPECT_EQ(frames_before_glitch + 1,
927 test_receiver_video_callback_->number_times_called());
930 // Disabled due to flakiness and crashiness. http://crbug.com/360951
931 TEST_F(End2EndTest, DISABLED_DropEveryOtherFrame3Buffers) {
932 Configure(transport::kVp8, transport::kOpus, kDefaultAudioSamplingRate, false,
934 video_sender_config_.rtp_config.max_delay_ms = 67;
935 video_receiver_config_.rtp_max_delay_ms = 67;
937 sender_to_receiver_.DropAllPacketsBelongingToOddFrames();
939 int video_start = kVideoStart;
940 base::TimeTicks send_time;
943 for (; i < 20; ++i) {
944 send_time = testing_clock_sender_->NowTicks();
945 SendVideoFrame(video_start, send_time);
948 test_receiver_video_callback_->AddExpectedResult(
950 video_sender_config_.width,
951 video_sender_config_.height,
955 // GetRawVideoFrame will not return the frame until we are close in
956 // time before we should render the frame.
957 frame_receiver_->GetRawVideoFrame(
958 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame,
959 test_receiver_video_callback_));
961 RunTasks(kFrameTimerMs);
965 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline.
966 EXPECT_EQ(i / 2, test_receiver_video_callback_->number_times_called());
969 TEST_F(End2EndTest, CryptoVideo) {
970 Configure(transport::kVp8, transport::kPcm16, 32000, false, 1);
972 video_sender_config_.rtp_config.aes_iv_mask =
973 ConvertFromBase16String("1234567890abcdeffedcba0987654321");
974 video_sender_config_.rtp_config.aes_key =
975 ConvertFromBase16String("deadbeefcafeb0b0b0b0cafedeadbeef");
977 video_receiver_config_.aes_iv_mask =
978 video_sender_config_.rtp_config.aes_iv_mask;
979 video_receiver_config_.aes_key =
980 video_sender_config_.rtp_config.aes_key;
984 int frames_counter = 0;
985 for (; frames_counter < 3; ++frames_counter) {
986 const base::TimeTicks send_time = testing_clock_sender_->NowTicks();
987 SendVideoFrame(frames_counter, send_time);
989 test_receiver_video_callback_->AddExpectedResult(
991 video_sender_config_.width,
992 video_sender_config_.height,
996 RunTasks(kFrameTimerMs);
998 frame_receiver_->GetRawVideoFrame(
999 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame,
1000 test_receiver_video_callback_));
1002 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline.
1003 EXPECT_EQ(frames_counter,
1004 test_receiver_video_callback_->number_times_called());
1007 TEST_F(End2EndTest, CryptoAudio) {
1008 Configure(transport::kVp8, transport::kPcm16, 32000, false, 1);
1010 audio_sender_config_.rtp_config.aes_iv_mask =
1011 ConvertFromBase16String("abcdeffedcba12345678900987654321");
1012 audio_sender_config_.rtp_config.aes_key =
1013 ConvertFromBase16String("deadbeefcafecafedeadbeefb0b0b0b0");
1015 audio_receiver_config_.aes_iv_mask =
1016 audio_sender_config_.rtp_config.aes_iv_mask;
1017 audio_receiver_config_.aes_key =
1018 audio_sender_config_.rtp_config.aes_key;
1022 const int kNumIterations = 3;
1023 const int kNumAudioFramesPerIteration = 2;
1024 for (int i = 0; i < kNumIterations; ++i) {
1025 FeedAudioFrames(kNumAudioFramesPerIteration, true);
1026 RunTasks(kNumAudioFramesPerIteration * kAudioFrameDurationMs);
1027 RequestAudioFrames(kNumAudioFramesPerIteration, true);
1029 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline.
1030 EXPECT_EQ(kNumIterations * kNumAudioFramesPerIteration,
1031 test_receiver_audio_callback_->number_times_called());
1034 // Video test without packet loss - tests the logging aspects of the end2end,
1035 // but is basically equivalent to LoopNoLossPcm16.
1036 TEST_F(End2EndTest, VideoLogging) {
1037 Configure(transport::kVp8, transport::kPcm16, 32000, false, 1);
1040 int video_start = kVideoStart;
1041 const int num_frames = 5;
1042 for (int i = 0; i < num_frames; ++i) {
1043 base::TimeTicks send_time = testing_clock_sender_->NowTicks();
1044 test_receiver_video_callback_->AddExpectedResult(
1046 video_sender_config_.width,
1047 video_sender_config_.height,
1051 SendVideoFrame(video_start, send_time);
1052 RunTasks(kFrameTimerMs);
1054 frame_receiver_->GetRawVideoFrame(
1055 base::Bind(&TestReceiverVideoCallback::CheckVideoFrame,
1056 test_receiver_video_callback_));
1062 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline.
1063 int num_callbacks_called =
1064 test_receiver_video_callback_->number_times_called();
1065 EXPECT_EQ(num_frames, num_callbacks_called);
1067 RunTasks(750); // Make sure that we send a RTCP message with the log.
1071 // Verify that all frames and all required events were logged.
1072 event_subscriber_sender_.GetFrameEventsAndReset(&frame_events_);
1074 // For each frame, count the number of events that occurred for each event
1076 std::map<RtpTimestamp, LoggingEventCounts> event_counter_for_frame =
1077 GetEventCountForFrameEvents(frame_events_);
1079 // Verify that there are logs for expected number of frames.
1080 EXPECT_EQ(num_frames, static_cast<int>(event_counter_for_frame.size()));
1082 // Verify that each frame have the expected types of events logged.
1083 for (std::map<RtpTimestamp, LoggingEventCounts>::iterator map_it =
1084 event_counter_for_frame.begin();
1085 map_it != event_counter_for_frame.end();
1087 int total_event_count_for_frame = 0;
1088 for (int i = 0; i < kNumOfLoggingEvents; ++i) {
1089 total_event_count_for_frame += map_it->second.counter[i];
1092 int expected_event_count_for_frame = 0;
1094 EXPECT_EQ(1, map_it->second.counter[kVideoFrameCaptureBegin]);
1095 expected_event_count_for_frame +=
1096 map_it->second.counter[kVideoFrameCaptureBegin];
1098 EXPECT_EQ(1, map_it->second.counter[kVideoFrameEncoded]);
1099 expected_event_count_for_frame +=
1100 map_it->second.counter[kVideoFrameEncoded];
1102 EXPECT_EQ(1, map_it->second.counter[kVideoFrameCaptureEnd]);
1103 expected_event_count_for_frame +=
1104 map_it->second.counter[kVideoFrameCaptureEnd];
1106 EXPECT_EQ(1, map_it->second.counter[kVideoRenderDelay]);
1107 expected_event_count_for_frame += map_it->second.counter[kVideoRenderDelay];
1109 EXPECT_EQ(1, map_it->second.counter[kVideoFrameDecoded]);
1110 expected_event_count_for_frame +=
1111 map_it->second.counter[kVideoFrameDecoded];
1113 // There is no guarantee that kVideoAckSent is loggeed exactly once per
1115 EXPECT_GT(map_it->second.counter[kVideoAckSent], 0);
1116 expected_event_count_for_frame += map_it->second.counter[kVideoAckSent];
1118 // There is no guarantee that kVideoAckReceived is loggeed exactly once per
1120 EXPECT_GT(map_it->second.counter[kVideoAckReceived], 0);
1121 expected_event_count_for_frame += map_it->second.counter[kVideoAckReceived];
1123 // Verify that there were no other events logged with respect to this
1125 // (i.e. Total event count = expected event count)
1126 EXPECT_EQ(total_event_count_for_frame, expected_event_count_for_frame);
1130 // Verify that all packet related events were logged.
1131 event_subscriber_sender_.GetPacketEventsAndReset(&packet_events_);
1132 std::map<uint16, LoggingEventCounts> event_count_for_packet =
1133 GetEventCountForPacketEvents(packet_events_);
1135 // Verify that each packet have the expected types of events logged.
1136 for (std::map<uint16, LoggingEventCounts>::iterator map_it =
1137 event_count_for_packet.begin();
1138 map_it != event_count_for_packet.end();
1140 int total_event_count_for_packet = 0;
1141 for (int i = 0; i < kNumOfLoggingEvents; ++i) {
1142 total_event_count_for_packet += map_it->second.counter[i];
1145 int expected_event_count_for_packet = 0;
1146 EXPECT_GT(map_it->second.counter[kVideoPacketReceived], 0);
1147 expected_event_count_for_packet +=
1148 map_it->second.counter[kVideoPacketReceived];
1150 // Verify that there were no other events logged with respect to this
1151 // packet. (i.e. Total event count = expected event count)
1152 EXPECT_EQ(total_event_count_for_packet, expected_event_count_for_packet);
1156 // Audio test without packet loss - tests the logging aspects of the end2end,
1157 // but is basically equivalent to LoopNoLossPcm16.
1158 TEST_F(End2EndTest, AudioLogging) {
1159 Configure(transport::kVp8, transport::kPcm16, 32000, false, 1);
1162 int audio_diff = kFrameTimerMs;
1163 const int kNumVideoFrames = 10;
1164 int num_audio_frames_requested = 0;
1165 for (int i = 0; i < kNumVideoFrames; ++i) {
1166 const int num_audio_frames = audio_diff / kAudioFrameDurationMs;
1167 audio_diff -= num_audio_frames * kAudioFrameDurationMs;
1169 FeedAudioFrames(num_audio_frames, true);
1171 RunTasks(kFrameTimerMs);
1172 audio_diff += kFrameTimerMs;
1174 RequestAudioFrames(num_audio_frames, true);
1175 num_audio_frames_requested += num_audio_frames;
1179 RunTasks(2 * kFrameTimerMs + 1); // Empty the receiver pipeline.
1181 EXPECT_EQ(num_audio_frames_requested,
1182 test_receiver_audio_callback_->number_times_called());
1185 // Verify that all frames and all required events were logged.
1186 event_subscriber_sender_.GetFrameEventsAndReset(&frame_events_);
1188 // Construct a map from each frame (RTP timestamp) to a count of each event
1189 // type logged for that frame.
1190 std::map<RtpTimestamp, LoggingEventCounts> event_counter_for_frame =
1191 GetEventCountForFrameEvents(frame_events_);
1193 int encoded_count = 0;
1195 // Verify the right number of events were logged for each event type.
1196 for (std::map<RtpTimestamp, LoggingEventCounts>::iterator it =
1197 event_counter_for_frame.begin();
1198 it != event_counter_for_frame.end();
1200 encoded_count += it->second.counter[kAudioFrameEncoded];
1203 EXPECT_EQ(num_audio_frames_requested, encoded_count);
1205 // Verify that each frame have the expected types of events logged.
1206 for (std::map<RtpTimestamp, LoggingEventCounts>::const_iterator map_it =
1207 event_counter_for_frame.begin();
1208 map_it != event_counter_for_frame.end(); ++map_it) {
1209 int total_event_count_for_frame = 0;
1210 for (int j = 0; j < kNumOfLoggingEvents; ++j)
1211 total_event_count_for_frame += map_it->second.counter[j];
1213 int expected_event_count_for_frame = 0;
1215 EXPECT_EQ(1, map_it->second.counter[kAudioFrameEncoded]);
1216 expected_event_count_for_frame +=
1217 map_it->second.counter[kAudioFrameEncoded];
1219 EXPECT_EQ(1, map_it->second.counter[kAudioPlayoutDelay]);
1220 expected_event_count_for_frame +=
1221 map_it->second.counter[kAudioPlayoutDelay];
1223 EXPECT_EQ(1, map_it->second.counter[kAudioFrameDecoded]);
1224 expected_event_count_for_frame +=
1225 map_it->second.counter[kAudioFrameDecoded];
1227 EXPECT_GT(map_it->second.counter[kAudioAckSent], 0);
1228 expected_event_count_for_frame += map_it->second.counter[kAudioAckSent];
1230 // Verify that there were no other events logged with respect to this frame.
1231 // (i.e. Total event count = expected event count)
1232 EXPECT_EQ(total_event_count_for_frame, expected_event_count_for_frame);
1236 TEST_F(End2EndTest, BasicFakeSoftwareVideo) {
1237 Configure(transport::kFakeSoftwareVideo, transport::kPcm16, 32000, false, 1);
1240 int frames_counter = 0;
1241 int received_counter = 0;
1242 for (; frames_counter < 1000; ++frames_counter) {
1243 SendFakeVideoFrame(testing_clock_sender_->NowTicks());
1244 frame_receiver_->GetRawVideoFrame(
1245 base::Bind(&CountVideoFrame, &received_counter));
1246 RunTasks(kFrameTimerMs);
1248 RunTasks(2 * kFrameTimerMs + 1); // Empty the pipeline.
1249 EXPECT_EQ(1000, received_counter);
1252 // TODO(pwestin): Add repeatable packet loss test.
1253 // TODO(pwestin): Add test for misaligned send get calls.
1254 // TODO(pwestin): Add more tests that does not resample.
1255 // TODO(pwestin): Add test when we have starvation for our RunTask.
1258 } // namespace media