Refactor WebsiteSettings to operate on a SecurityInfo
[chromium-blink-merge.git] / media / cast / sender / video_sender_unittest.cc
blob4e4996b2fee102de2630c7a1dfe5394c0aae5950
1 // Copyright 2014 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 #include <stdint.h>
7 #include <vector>
9 #include "base/bind.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/test/simple_test_tick_clock.h"
12 #include "media/base/video_frame.h"
13 #include "media/cast/cast_environment.h"
14 #include "media/cast/logging/simple_event_subscriber.h"
15 #include "media/cast/net/cast_transport_config.h"
16 #include "media/cast/net/cast_transport_sender_impl.h"
17 #include "media/cast/net/pacing/paced_sender.h"
18 #include "media/cast/sender/fake_video_encode_accelerator_factory.h"
19 #include "media/cast/sender/video_frame_factory.h"
20 #include "media/cast/sender/video_sender.h"
21 #include "media/cast/test/fake_single_thread_task_runner.h"
22 #include "media/cast/test/utility/default_config.h"
23 #include "media/cast/test/utility/video_utility.h"
24 #include "media/video/fake_video_encode_accelerator.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
28 namespace media {
29 namespace cast {
31 namespace {
32 static const uint8 kPixelValue = 123;
33 static const int kWidth = 320;
34 static const int kHeight = 240;
36 using testing::_;
37 using testing::AtLeast;
40 void SaveOperationalStatus(OperationalStatus* out_status,
41 OperationalStatus in_status) {
42 DVLOG(1) << "OperationalStatus transitioning from " << *out_status << " to "
43 << in_status;
44 *out_status = in_status;
47 class TestPacketSender : public PacketSender {
48 public:
49 TestPacketSender()
50 : number_of_rtp_packets_(0),
51 number_of_rtcp_packets_(0),
52 paused_(false) {}
54 // A singular packet implies a RTCP packet.
55 bool SendPacket(PacketRef packet, const base::Closure& cb) final {
56 if (paused_) {
57 stored_packet_ = packet;
58 callback_ = cb;
59 return false;
61 if (Rtcp::IsRtcpPacket(&packet->data[0], packet->data.size())) {
62 ++number_of_rtcp_packets_;
63 } else {
64 // Check that at least one RTCP packet was sent before the first RTP
65 // packet. This confirms that the receiver will have the necessary lip
66 // sync info before it has to calculate the playout time of the first
67 // frame.
68 if (number_of_rtp_packets_ == 0)
69 EXPECT_LE(1, number_of_rtcp_packets_);
70 ++number_of_rtp_packets_;
72 return true;
75 int64 GetBytesSent() final { return 0; }
77 int number_of_rtp_packets() const { return number_of_rtp_packets_; }
79 int number_of_rtcp_packets() const { return number_of_rtcp_packets_; }
81 void SetPause(bool paused) {
82 paused_ = paused;
83 if (!paused && stored_packet_.get()) {
84 SendPacket(stored_packet_, callback_);
85 callback_.Run();
89 private:
90 int number_of_rtp_packets_;
91 int number_of_rtcp_packets_;
92 bool paused_;
93 base::Closure callback_;
94 PacketRef stored_packet_;
96 DISALLOW_COPY_AND_ASSIGN(TestPacketSender);
99 void IgnorePlayoutDelayChanges(base::TimeDelta unused_playout_delay) {
102 class PeerVideoSender : public VideoSender {
103 public:
104 PeerVideoSender(
105 scoped_refptr<CastEnvironment> cast_environment,
106 const VideoSenderConfig& video_config,
107 const StatusChangeCallback& status_change_cb,
108 const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
109 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
110 CastTransportSender* const transport_sender)
111 : VideoSender(cast_environment,
112 video_config,
113 status_change_cb,
114 create_vea_cb,
115 create_video_encode_mem_cb,
116 transport_sender,
117 base::Bind(&IgnorePlayoutDelayChanges)) {}
118 using VideoSender::OnReceivedCastFeedback;
119 using VideoSender::GetMaximumTargetBitrateForFrame;
122 // Creates a VideoFrame NOT backed by actual memory storage. The frame's
123 // metadata (i.e., size and frame duration) are all that are needed to test the
124 // GetMaximumTargetBitrateForFrame() logic.
125 scoped_refptr<VideoFrame> CreateFakeFrame(const gfx::Size& resolution,
126 bool high_frame_rate_in_metadata) {
127 const scoped_refptr<VideoFrame> frame = VideoFrame::WrapExternalData(
128 PIXEL_FORMAT_I420,
129 resolution,
130 gfx::Rect(resolution),
131 resolution,
132 static_cast<uint8*>(nullptr) + 1,
133 resolution.GetArea() * 3 / 2,
134 base::TimeDelta());
135 const double frame_rate = high_frame_rate_in_metadata ? 60.0 : 30.0;
136 frame->metadata()->SetTimeDelta(
137 VideoFrameMetadata::FRAME_DURATION,
138 base::TimeDelta::FromSecondsD(1.0 / frame_rate));
139 return frame;
142 } // namespace
144 class VideoSenderTest : public ::testing::Test {
145 protected:
146 VideoSenderTest()
147 : testing_clock_(new base::SimpleTestTickClock()),
148 task_runner_(new test::FakeSingleThreadTaskRunner(testing_clock_)),
149 cast_environment_(new CastEnvironment(
150 scoped_ptr<base::TickClock>(testing_clock_).Pass(),
151 task_runner_,
152 task_runner_,
153 task_runner_)),
154 operational_status_(STATUS_UNINITIALIZED),
155 vea_factory_(task_runner_) {
156 testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks());
157 vea_factory_.SetAutoRespond(true);
158 last_pixel_value_ = kPixelValue;
159 net::IPEndPoint dummy_endpoint;
160 transport_sender_.reset(new CastTransportSenderImpl(
161 NULL,
162 testing_clock_,
163 dummy_endpoint,
164 dummy_endpoint,
165 make_scoped_ptr(new base::DictionaryValue),
166 base::Bind(&UpdateCastTransportStatus),
167 BulkRawEventsCallback(),
168 base::TimeDelta(),
169 task_runner_,
170 PacketReceiverCallback(),
171 &transport_));
174 ~VideoSenderTest() override {}
176 void TearDown() final {
177 video_sender_.reset();
178 task_runner_->RunTasks();
181 static void UpdateCastTransportStatus(CastTransportStatus status) {
182 EXPECT_EQ(TRANSPORT_VIDEO_INITIALIZED, status);
185 // If |external| is true then external video encoder (VEA) is used.
186 // |expect_init_sucess| is true if initialization is expected to succeed.
187 void InitEncoder(bool external, bool expect_init_success) {
188 VideoSenderConfig video_config = GetDefaultVideoSenderConfig();
189 video_config.use_external_encoder = external;
191 ASSERT_EQ(operational_status_, STATUS_UNINITIALIZED);
193 if (external) {
194 vea_factory_.SetInitializationWillSucceed(expect_init_success);
195 video_sender_.reset(new PeerVideoSender(
196 cast_environment_,
197 video_config,
198 base::Bind(&SaveOperationalStatus, &operational_status_),
199 base::Bind(
200 &FakeVideoEncodeAcceleratorFactory::CreateVideoEncodeAccelerator,
201 base::Unretained(&vea_factory_)),
202 base::Bind(&FakeVideoEncodeAcceleratorFactory::CreateSharedMemory,
203 base::Unretained(&vea_factory_)),
204 transport_sender_.get()));
205 } else {
206 video_sender_.reset(new PeerVideoSender(
207 cast_environment_,
208 video_config,
209 base::Bind(&SaveOperationalStatus, &operational_status_),
210 CreateDefaultVideoEncodeAcceleratorCallback(),
211 CreateDefaultVideoEncodeMemoryCallback(),
212 transport_sender_.get()));
214 task_runner_->RunTasks();
217 scoped_refptr<media::VideoFrame> GetNewVideoFrame() {
218 if (first_frame_timestamp_.is_null())
219 first_frame_timestamp_ = testing_clock_->NowTicks();
220 gfx::Size size(kWidth, kHeight);
221 scoped_refptr<media::VideoFrame> video_frame =
222 media::VideoFrame::CreateFrame(
223 PIXEL_FORMAT_I420, size, gfx::Rect(size), size,
224 testing_clock_->NowTicks() - first_frame_timestamp_);
225 PopulateVideoFrame(video_frame.get(), last_pixel_value_++);
226 return video_frame;
229 scoped_refptr<media::VideoFrame> GetLargeNewVideoFrame() {
230 if (first_frame_timestamp_.is_null())
231 first_frame_timestamp_ = testing_clock_->NowTicks();
232 gfx::Size size(kWidth, kHeight);
233 scoped_refptr<media::VideoFrame> video_frame =
234 media::VideoFrame::CreateFrame(
235 PIXEL_FORMAT_I420, size, gfx::Rect(size), size,
236 testing_clock_->NowTicks() - first_frame_timestamp_);
237 PopulateVideoFrameWithNoise(video_frame.get());
238 return video_frame;
241 void RunTasks(int during_ms) {
242 task_runner_->Sleep(base::TimeDelta::FromMilliseconds(during_ms));
245 base::SimpleTestTickClock* const testing_clock_; // Owned by CastEnvironment.
246 const scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_;
247 const scoped_refptr<CastEnvironment> cast_environment_;
248 OperationalStatus operational_status_;
249 FakeVideoEncodeAcceleratorFactory vea_factory_;
250 TestPacketSender transport_;
251 scoped_ptr<CastTransportSenderImpl> transport_sender_;
252 scoped_ptr<PeerVideoSender> video_sender_;
253 int last_pixel_value_;
254 base::TimeTicks first_frame_timestamp_;
256 DISALLOW_COPY_AND_ASSIGN(VideoSenderTest);
259 TEST_F(VideoSenderTest, BuiltInEncoder) {
260 InitEncoder(false, true);
261 ASSERT_EQ(STATUS_INITIALIZED, operational_status_);
263 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
265 const base::TimeTicks reference_time = testing_clock_->NowTicks();
266 video_sender_->InsertRawVideoFrame(video_frame, reference_time);
268 task_runner_->RunTasks();
269 EXPECT_LE(1, transport_.number_of_rtp_packets());
270 EXPECT_LE(1, transport_.number_of_rtcp_packets());
273 TEST_F(VideoSenderTest, ExternalEncoder) {
274 InitEncoder(true, true);
275 ASSERT_EQ(STATUS_INITIALIZED, operational_status_);
277 // The SizeAdaptableExternalVideoEncoder initally reports STATUS_INITIALIZED
278 // so that frames will be sent to it. Therefore, no encoder activity should
279 // have occurred at this point. Send a frame to spurn creation of the
280 // underlying ExternalVideoEncoder instance.
281 if (vea_factory_.vea_response_count() == 0) {
282 video_sender_->InsertRawVideoFrame(GetNewVideoFrame(),
283 testing_clock_->NowTicks());
284 task_runner_->RunTasks();
286 ASSERT_EQ(STATUS_INITIALIZED, operational_status_);
287 RunTasks(33);
289 // VideoSender created an encoder for 1280x720 frames, in order to provide the
290 // INITIALIZED status.
291 EXPECT_EQ(1, vea_factory_.vea_response_count());
292 EXPECT_EQ(3, vea_factory_.shm_response_count());
294 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
296 for (int i = 0; i < 3; ++i) {
297 const base::TimeTicks reference_time = testing_clock_->NowTicks();
298 video_sender_->InsertRawVideoFrame(video_frame, reference_time);
299 RunTasks(33);
300 // VideoSender re-created the encoder for the 320x240 frames we're
301 // providing.
302 EXPECT_EQ(1, vea_factory_.vea_response_count());
303 EXPECT_EQ(3, vea_factory_.shm_response_count());
306 video_sender_.reset(NULL);
307 task_runner_->RunTasks();
308 EXPECT_EQ(1, vea_factory_.vea_response_count());
309 EXPECT_EQ(3, vea_factory_.shm_response_count());
312 TEST_F(VideoSenderTest, ExternalEncoderInitFails) {
313 InitEncoder(true, false);
315 // The SizeAdaptableExternalVideoEncoder initally reports STATUS_INITIALIZED
316 // so that frames will be sent to it. Send a frame to spurn creation of the
317 // underlying ExternalVideoEncoder instance, which should result in failure.
318 if (operational_status_ == STATUS_INITIALIZED ||
319 operational_status_ == STATUS_CODEC_REINIT_PENDING) {
320 video_sender_->InsertRawVideoFrame(GetNewVideoFrame(),
321 testing_clock_->NowTicks());
322 task_runner_->RunTasks();
324 EXPECT_EQ(STATUS_CODEC_INIT_FAILED, operational_status_);
326 video_sender_.reset(NULL);
327 task_runner_->RunTasks();
330 TEST_F(VideoSenderTest, RtcpTimer) {
331 InitEncoder(false, true);
332 ASSERT_EQ(STATUS_INITIALIZED, operational_status_);
334 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
336 const base::TimeTicks reference_time = testing_clock_->NowTicks();
337 video_sender_->InsertRawVideoFrame(video_frame, reference_time);
339 // Make sure that we send at least one RTCP packet.
340 base::TimeDelta max_rtcp_timeout =
341 base::TimeDelta::FromMilliseconds(1 + kDefaultRtcpIntervalMs * 3 / 2);
343 RunTasks(max_rtcp_timeout.InMilliseconds());
344 EXPECT_LE(1, transport_.number_of_rtp_packets());
345 EXPECT_LE(1, transport_.number_of_rtcp_packets());
346 // Build Cast msg and expect RTCP packet.
347 RtcpCastMessage cast_feedback(1);
348 cast_feedback.media_ssrc = 2;
349 cast_feedback.ack_frame_id = 0;
350 video_sender_->OnReceivedCastFeedback(cast_feedback);
351 RunTasks(max_rtcp_timeout.InMilliseconds());
352 EXPECT_LE(1, transport_.number_of_rtcp_packets());
355 TEST_F(VideoSenderTest, ResendTimer) {
356 InitEncoder(false, true);
357 ASSERT_EQ(STATUS_INITIALIZED, operational_status_);
359 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
361 const base::TimeTicks reference_time = testing_clock_->NowTicks();
362 video_sender_->InsertRawVideoFrame(video_frame, reference_time);
364 // ACK the key frame.
365 RtcpCastMessage cast_feedback(1);
366 cast_feedback.media_ssrc = 2;
367 cast_feedback.ack_frame_id = 0;
368 video_sender_->OnReceivedCastFeedback(cast_feedback);
370 video_frame = GetNewVideoFrame();
371 video_sender_->InsertRawVideoFrame(video_frame, reference_time);
373 base::TimeDelta max_resend_timeout =
374 base::TimeDelta::FromMilliseconds(1 + kDefaultRtpMaxDelayMs);
376 // Make sure that we do a re-send.
377 RunTasks(max_resend_timeout.InMilliseconds());
378 // Should have sent at least 3 packets.
379 EXPECT_LE(
381 transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets());
384 TEST_F(VideoSenderTest, LogAckReceivedEvent) {
385 InitEncoder(false, true);
386 ASSERT_EQ(STATUS_INITIALIZED, operational_status_);
388 SimpleEventSubscriber event_subscriber;
389 cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber);
391 int num_frames = 10;
392 for (int i = 0; i < num_frames; i++) {
393 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
395 const base::TimeTicks reference_time = testing_clock_->NowTicks();
396 video_sender_->InsertRawVideoFrame(video_frame, reference_time);
397 RunTasks(33);
400 task_runner_->RunTasks();
402 RtcpCastMessage cast_feedback(1);
403 cast_feedback.ack_frame_id = num_frames - 1;
405 video_sender_->OnReceivedCastFeedback(cast_feedback);
407 std::vector<FrameEvent> frame_events;
408 event_subscriber.GetFrameEventsAndReset(&frame_events);
410 ASSERT_TRUE(!frame_events.empty());
411 EXPECT_EQ(FRAME_ACK_RECEIVED, frame_events.rbegin()->type);
412 EXPECT_EQ(VIDEO_EVENT, frame_events.rbegin()->media_type);
413 EXPECT_EQ(num_frames - 1u, frame_events.rbegin()->frame_id);
415 cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber);
418 TEST_F(VideoSenderTest, StopSendingInTheAbsenceOfAck) {
419 InitEncoder(false, true);
420 ASSERT_EQ(STATUS_INITIALIZED, operational_status_);
422 // Send a stream of frames and don't ACK; by default we shouldn't have more
423 // than 4 frames in flight.
424 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
425 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
426 RunTasks(33);
428 // Send 3 more frames and record the number of packets sent.
429 for (int i = 0; i < 3; ++i) {
430 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
431 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
432 RunTasks(33);
434 const int number_of_packets_sent = transport_.number_of_rtp_packets();
436 // Send 3 more frames - they should not be encoded, as we have not received
437 // any acks.
438 for (int i = 0; i < 3; ++i) {
439 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
440 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
441 RunTasks(33);
444 // We expect a frame to be retransmitted because of duplicated ACKs.
445 // Only one packet of the frame is re-transmitted.
446 EXPECT_EQ(number_of_packets_sent + 1,
447 transport_.number_of_rtp_packets());
449 // Start acking and make sure we're back to steady-state.
450 RtcpCastMessage cast_feedback(1);
451 cast_feedback.media_ssrc = 2;
452 cast_feedback.ack_frame_id = 0;
453 video_sender_->OnReceivedCastFeedback(cast_feedback);
454 EXPECT_LE(
456 transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets());
458 // Empty the pipeline.
459 RunTasks(100);
460 // Should have sent at least 7 packets.
461 EXPECT_LE(
463 transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets());
466 TEST_F(VideoSenderTest, DuplicateAckRetransmit) {
467 InitEncoder(false, true);
468 ASSERT_EQ(STATUS_INITIALIZED, operational_status_);
470 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
471 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
472 RunTasks(33);
473 RtcpCastMessage cast_feedback(1);
474 cast_feedback.media_ssrc = 2;
475 cast_feedback.ack_frame_id = 0;
477 // Send 3 more frames but don't ACK.
478 for (int i = 0; i < 3; ++i) {
479 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
480 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
481 RunTasks(33);
483 const int number_of_packets_sent = transport_.number_of_rtp_packets();
485 // Send duplicated ACKs and mix some invalid NACKs.
486 for (int i = 0; i < 10; ++i) {
487 RtcpCastMessage ack_feedback(1);
488 ack_feedback.media_ssrc = 2;
489 ack_feedback.ack_frame_id = 0;
490 RtcpCastMessage nack_feedback(1);
491 nack_feedback.media_ssrc = 2;
492 nack_feedback.missing_frames_and_packets[255] = PacketIdSet();
493 video_sender_->OnReceivedCastFeedback(ack_feedback);
494 video_sender_->OnReceivedCastFeedback(nack_feedback);
496 EXPECT_EQ(number_of_packets_sent, transport_.number_of_rtp_packets());
498 // Re-transmit one packet because of duplicated ACKs.
499 for (int i = 0; i < 3; ++i) {
500 RtcpCastMessage ack_feedback(1);
501 ack_feedback.media_ssrc = 2;
502 ack_feedback.ack_frame_id = 0;
503 video_sender_->OnReceivedCastFeedback(ack_feedback);
505 EXPECT_EQ(number_of_packets_sent + 1, transport_.number_of_rtp_packets());
508 TEST_F(VideoSenderTest, DuplicateAckRetransmitDoesNotCancelRetransmits) {
509 InitEncoder(false, true);
510 ASSERT_EQ(STATUS_INITIALIZED, operational_status_);
512 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
513 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
514 RunTasks(33);
515 RtcpCastMessage cast_feedback(1);
516 cast_feedback.media_ssrc = 2;
517 cast_feedback.ack_frame_id = 0;
519 // Send 2 more frames but don't ACK.
520 for (int i = 0; i < 2; ++i) {
521 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
522 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
523 RunTasks(33);
525 // Pause the transport
526 transport_.SetPause(true);
528 // Insert one more video frame.
529 video_frame = GetLargeNewVideoFrame();
530 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
531 RunTasks(33);
533 const int number_of_packets_sent = transport_.number_of_rtp_packets();
535 // Send duplicated ACKs and mix some invalid NACKs.
536 for (int i = 0; i < 10; ++i) {
537 RtcpCastMessage ack_feedback(1);
538 ack_feedback.media_ssrc = 2;
539 ack_feedback.ack_frame_id = 0;
540 RtcpCastMessage nack_feedback(1);
541 nack_feedback.media_ssrc = 2;
542 nack_feedback.missing_frames_and_packets[255] = PacketIdSet();
543 video_sender_->OnReceivedCastFeedback(ack_feedback);
544 video_sender_->OnReceivedCastFeedback(nack_feedback);
546 EXPECT_EQ(number_of_packets_sent, transport_.number_of_rtp_packets());
548 // Re-transmit one packet because of duplicated ACKs.
549 for (int i = 0; i < 3; ++i) {
550 RtcpCastMessage ack_feedback(1);
551 ack_feedback.media_ssrc = 2;
552 ack_feedback.ack_frame_id = 0;
553 video_sender_->OnReceivedCastFeedback(ack_feedback);
556 transport_.SetPause(false);
557 RunTasks(100);
558 EXPECT_LT(number_of_packets_sent + 1, transport_.number_of_rtp_packets());
561 TEST_F(VideoSenderTest, AcksCancelRetransmits) {
562 InitEncoder(false, true);
563 ASSERT_EQ(STATUS_INITIALIZED, operational_status_);
565 transport_.SetPause(true);
566 scoped_refptr<media::VideoFrame> video_frame = GetLargeNewVideoFrame();
567 video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks());
568 RunTasks(33);
570 // Frame should be in buffer, waiting. Now let's ack it.
571 RtcpCastMessage cast_feedback(1);
572 cast_feedback.media_ssrc = 2;
573 cast_feedback.ack_frame_id = 0;
574 video_sender_->OnReceivedCastFeedback(cast_feedback);
576 transport_.SetPause(false);
577 RunTasks(33);
578 EXPECT_EQ(0, transport_.number_of_rtp_packets());
581 TEST_F(VideoSenderTest, CheckVideoFrameFactoryIsNull) {
582 InitEncoder(false, true);
583 ASSERT_EQ(STATUS_INITIALIZED, operational_status_);
585 EXPECT_EQ(nullptr, video_sender_->CreateVideoFrameFactory().get());
588 TEST_F(VideoSenderTest, PopulatesResourceUtilizationInFrameMetadata) {
589 InitEncoder(false, true);
590 ASSERT_EQ(STATUS_INITIALIZED, operational_status_);
592 for (int i = 0; i < 3; ++i) {
593 scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
594 ASSERT_FALSE(video_frame->metadata()->HasKey(
595 media::VideoFrameMetadata::RESOURCE_UTILIZATION));
597 const base::TimeTicks reference_time = testing_clock_->NowTicks();
598 video_sender_->InsertRawVideoFrame(video_frame, reference_time);
600 // Run encode tasks. VideoSender::OnEncodedVideoFrame() will be called once
601 // encoding of the frame is complete, and this is when the
602 // RESOURCE_UTILIZATION metadata is populated.
603 RunTasks(33);
605 // Check that the RESOURCE_UTILIZATION value is set and non-negative. Don't
606 // check for specific values because they are dependent on real-world CPU
607 // encode time, which can vary across test runs.
608 double utilization = -1.0;
609 EXPECT_TRUE(video_frame->metadata()->GetDouble(
610 media::VideoFrameMetadata::RESOURCE_UTILIZATION, &utilization));
611 EXPECT_LE(0.0, utilization);
612 if (i == 0)
613 EXPECT_GE(1.0, utilization); // Key frames never exceed 1.0.
614 DVLOG(1) << "Utilization computed by VideoSender is: " << utilization;
618 // Tests that VideoSender::GetMaximumTargetBitrateForFrame() returns the correct
619 // result for a number of frame resolution combinations.
620 TEST(VideoSenderMathTest, ComputesCorrectMaximumTargetBitratesForFrames) {
621 const struct {
622 int width;
623 int height;
624 bool high_frame_rate;
625 int expected_bitrate;
626 } kTestCases[] = {
627 // Standard 16:9 resolutions, non-HFR.
628 { 16, 9, false, 1000000 },
629 { 320, 180, false, 1000000 },
630 { 640, 360, false, 2000000 },
631 { 800, 450, false, 2500000 },
632 { 1280, 720, false, 4000000 },
633 { 1920, 1080, false, 6000000 },
634 { 3840, 2160, false, 12000000 },
636 // Standard 16:9 resolutions, HFR.
637 { 16, 9, true, 1000000 },
638 { 320, 180, true, 1500000 },
639 { 640, 360, true, 3000000 },
640 { 800, 450, true, 3750000 },
641 { 1280, 720, true, 6000000 },
642 { 1920, 1080, true, 9000000 },
643 { 3840, 2160, true, 18000000 },
645 // 4:3 and oddball resolutions.
646 { 640, 480, false, 2305555 },
647 { 1024, 768, false, 3694444 },
648 { 10, 5000, false, 1000000 },
649 { 1234, 567, false, 3483333 },
650 { 16384, 16384, true, 102399999 },
653 for (size_t i = 0; i < arraysize(kTestCases); ++i) {
654 const gfx::Size resolution(kTestCases[i].width, kTestCases[i].height);
655 SCOPED_TRACE(::testing::Message() << "resolution=" << resolution.ToString()
656 << ", hfr=" << kTestCases[i].high_frame_rate);
657 const scoped_refptr<VideoFrame> frame =
658 CreateFakeFrame(resolution, kTestCases[i].high_frame_rate);
659 EXPECT_EQ(kTestCases[i].expected_bitrate,
660 PeerVideoSender::GetMaximumTargetBitrateForFrame(*frame));
664 } // namespace cast
665 } // namespace media