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.
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"
32 static const uint8 kPixelValue
= 123;
33 static const int kWidth
= 320;
34 static const int kHeight
= 240;
37 using testing::AtLeast
;
40 void SaveOperationalStatus(OperationalStatus
* out_status
,
41 OperationalStatus in_status
) {
42 DVLOG(1) << "OperationalStatus transitioning from " << *out_status
<< " to "
44 *out_status
= in_status
;
47 class TestPacketSender
: public PacketSender
{
50 : number_of_rtp_packets_(0),
51 number_of_rtcp_packets_(0),
54 // A singular packet implies a RTCP packet.
55 bool SendPacket(PacketRef packet
, const base::Closure
& cb
) final
{
57 stored_packet_
= packet
;
61 if (Rtcp::IsRtcpPacket(&packet
->data
[0], packet
->data
.size())) {
62 ++number_of_rtcp_packets_
;
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
68 if (number_of_rtp_packets_
== 0)
69 EXPECT_LE(1, number_of_rtcp_packets_
);
70 ++number_of_rtp_packets_
;
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
) {
83 if (!paused
&& stored_packet_
.get()) {
84 SendPacket(stored_packet_
, callback_
);
90 int number_of_rtp_packets_
;
91 int number_of_rtcp_packets_
;
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
{
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
,
115 create_video_encode_mem_cb
,
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(
130 gfx::Rect(resolution
),
132 static_cast<uint8
*>(nullptr) + 1,
133 resolution
.GetArea() * 3 / 2,
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
));
144 class VideoSenderTest
: public ::testing::Test
{
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(),
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(
165 make_scoped_ptr(new base::DictionaryValue
),
166 base::Bind(&UpdateCastTransportStatus
),
167 BulkRawEventsCallback(),
170 PacketReceiverCallback(),
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
);
194 vea_factory_
.SetInitializationWillSucceed(expect_init_success
);
195 video_sender_
.reset(new PeerVideoSender(
198 base::Bind(&SaveOperationalStatus
, &operational_status_
),
200 &FakeVideoEncodeAcceleratorFactory::CreateVideoEncodeAccelerator
,
201 base::Unretained(&vea_factory_
)),
202 base::Bind(&FakeVideoEncodeAcceleratorFactory::CreateSharedMemory
,
203 base::Unretained(&vea_factory_
)),
204 transport_sender_
.get()));
206 video_sender_
.reset(new PeerVideoSender(
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_
++);
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());
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_
);
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
);
300 // VideoSender re-created the encoder for the 320x240 frames we're
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.
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
);
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
);
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());
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());
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
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());
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
);
456 transport_
.number_of_rtp_packets() + transport_
.number_of_rtcp_packets());
458 // Empty the pipeline.
460 // Should have sent at least 7 packets.
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());
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());
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());
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());
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());
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);
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());
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);
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.
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
);
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
) {
624 bool high_frame_rate
;
625 int expected_bitrate
;
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
));