blob: ad9ccb7dbcc86bc3b60e0a47d95fce535c2c1c1e [file] [log] [blame]
perkj2d5f0912016-02-29 00:04:41 -08001/*
2 * Copyright 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
nisseaf916892017-01-10 07:44:26 -080011#include "webrtc/api/video/i420_buffer.h"
12#include "webrtc/api/video/video_frame.h"
perkj2d5f0912016-02-29 00:04:41 -080013#include "webrtc/base/gunit.h"
perkjd6c39542016-03-17 10:35:23 +010014#include "webrtc/media/base/fakevideorenderer.h"
perkj2d5f0912016-02-29 00:04:41 -080015#include "webrtc/media/base/videobroadcaster.h"
perkj2d5f0912016-02-29 00:04:41 -080016
17using rtc::VideoBroadcaster;
18using rtc::VideoSinkWants;
perkjd6c39542016-03-17 10:35:23 +010019using cricket::FakeVideoRenderer;
perkj2d5f0912016-02-29 00:04:41 -080020
perkj2d5f0912016-02-29 00:04:41 -080021
22TEST(VideoBroadcasterTest, frame_wanted) {
23 VideoBroadcaster broadcaster;
24 EXPECT_FALSE(broadcaster.frame_wanted());
25
perkjd6c39542016-03-17 10:35:23 +010026 FakeVideoRenderer sink;
perkj2d5f0912016-02-29 00:04:41 -080027 broadcaster.AddOrUpdateSink(&sink, rtc::VideoSinkWants());
28 EXPECT_TRUE(broadcaster.frame_wanted());
29
30 broadcaster.RemoveSink(&sink);
31 EXPECT_FALSE(broadcaster.frame_wanted());
32}
33
34TEST(VideoBroadcasterTest, OnFrame) {
35 VideoBroadcaster broadcaster;
36
perkjd6c39542016-03-17 10:35:23 +010037 FakeVideoRenderer sink1;
38 FakeVideoRenderer sink2;
perkj2d5f0912016-02-29 00:04:41 -080039 broadcaster.AddOrUpdateSink(&sink1, rtc::VideoSinkWants());
40 broadcaster.AddOrUpdateSink(&sink2, rtc::VideoSinkWants());
nissedf2ceb82016-12-15 06:29:53 -080041 static int kWidth = 100;
42 static int kHeight = 50;
perkj2d5f0912016-02-29 00:04:41 -080043
nissedf2ceb82016-12-15 06:29:53 -080044 rtc::scoped_refptr<webrtc::I420Buffer> buffer(
45 webrtc::I420Buffer::Create(kWidth, kHeight));
46 // Initialize, to avoid warnings on use of initialized values.
nisseaf916892017-01-10 07:44:26 -080047 webrtc::I420Buffer::SetBlack(buffer);
nissedf2ceb82016-12-15 06:29:53 -080048
49 webrtc::VideoFrame frame(buffer, webrtc::kVideoRotation_0, 0);
perkj2d5f0912016-02-29 00:04:41 -080050
51 broadcaster.OnFrame(frame);
perkjd6c39542016-03-17 10:35:23 +010052 EXPECT_EQ(1, sink1.num_rendered_frames());
53 EXPECT_EQ(1, sink2.num_rendered_frames());
perkj2d5f0912016-02-29 00:04:41 -080054
55 broadcaster.RemoveSink(&sink1);
56 broadcaster.OnFrame(frame);
perkjd6c39542016-03-17 10:35:23 +010057 EXPECT_EQ(1, sink1.num_rendered_frames());
58 EXPECT_EQ(2, sink2.num_rendered_frames());
perkj2d5f0912016-02-29 00:04:41 -080059
60 broadcaster.AddOrUpdateSink(&sink1, rtc::VideoSinkWants());
61 broadcaster.OnFrame(frame);
perkjd6c39542016-03-17 10:35:23 +010062 EXPECT_EQ(2, sink1.num_rendered_frames());
63 EXPECT_EQ(3, sink2.num_rendered_frames());
perkj2d5f0912016-02-29 00:04:41 -080064}
65
66TEST(VideoBroadcasterTest, AppliesRotationIfAnySinkWantsRotationApplied) {
67 VideoBroadcaster broadcaster;
deadbeeff5629ad2016-03-18 11:38:26 -070068 EXPECT_FALSE(broadcaster.wants().rotation_applied);
perkj2d5f0912016-02-29 00:04:41 -080069
perkjd6c39542016-03-17 10:35:23 +010070 FakeVideoRenderer sink1;
perkj2d5f0912016-02-29 00:04:41 -080071 VideoSinkWants wants1;
72 wants1.rotation_applied = false;
73
74 broadcaster.AddOrUpdateSink(&sink1, wants1);
75 EXPECT_FALSE(broadcaster.wants().rotation_applied);
76
perkjd6c39542016-03-17 10:35:23 +010077 FakeVideoRenderer sink2;
perkj2d5f0912016-02-29 00:04:41 -080078 VideoSinkWants wants2;
79 wants2.rotation_applied = true;
80
81 broadcaster.AddOrUpdateSink(&sink2, wants2);
82 EXPECT_TRUE(broadcaster.wants().rotation_applied);
83
84 broadcaster.RemoveSink(&sink2);
85 EXPECT_FALSE(broadcaster.wants().rotation_applied);
86}
87
88TEST(VideoBroadcasterTest, AppliesMinOfSinkWantsMaxPixelCount) {
89 VideoBroadcaster broadcaster;
sprangc5d62e22017-04-02 23:53:04 -070090 EXPECT_EQ(std::numeric_limits<int>::max(),
91 broadcaster.wants().max_pixel_count);
perkj2d5f0912016-02-29 00:04:41 -080092
perkjd6c39542016-03-17 10:35:23 +010093 FakeVideoRenderer sink1;
perkj2d5f0912016-02-29 00:04:41 -080094 VideoSinkWants wants1;
sprangc5d62e22017-04-02 23:53:04 -070095 wants1.max_pixel_count = 1280 * 720;
perkj2d5f0912016-02-29 00:04:41 -080096
97 broadcaster.AddOrUpdateSink(&sink1, wants1);
sprangc5d62e22017-04-02 23:53:04 -070098 EXPECT_EQ(1280 * 720, broadcaster.wants().max_pixel_count);
perkj2d5f0912016-02-29 00:04:41 -080099
perkjd6c39542016-03-17 10:35:23 +0100100 FakeVideoRenderer sink2;
perkj2d5f0912016-02-29 00:04:41 -0800101 VideoSinkWants wants2;
sprangc5d62e22017-04-02 23:53:04 -0700102 wants2.max_pixel_count = 640 * 360;
perkj2d5f0912016-02-29 00:04:41 -0800103 broadcaster.AddOrUpdateSink(&sink2, wants2);
sprangc5d62e22017-04-02 23:53:04 -0700104 EXPECT_EQ(640 * 360, broadcaster.wants().max_pixel_count);
perkj2d5f0912016-02-29 00:04:41 -0800105
106 broadcaster.RemoveSink(&sink2);
sprangc5d62e22017-04-02 23:53:04 -0700107 EXPECT_EQ(1280 * 720, broadcaster.wants().max_pixel_count);
perkj2d5f0912016-02-29 00:04:41 -0800108}
109
sprang84a37592017-02-10 07:04:27 -0800110TEST(VideoBroadcasterTest, AppliesMinOfSinkWantsMaxAndTargetPixelCount) {
perkj2d5f0912016-02-29 00:04:41 -0800111 VideoBroadcaster broadcaster;
sprang84a37592017-02-10 07:04:27 -0800112 EXPECT_TRUE(!broadcaster.wants().target_pixel_count);
perkj2d5f0912016-02-29 00:04:41 -0800113
perkjd6c39542016-03-17 10:35:23 +0100114 FakeVideoRenderer sink1;
perkj2d5f0912016-02-29 00:04:41 -0800115 VideoSinkWants wants1;
sprang84a37592017-02-10 07:04:27 -0800116 wants1.target_pixel_count = rtc::Optional<int>(1280 * 720);
perkj2d5f0912016-02-29 00:04:41 -0800117
118 broadcaster.AddOrUpdateSink(&sink1, wants1);
sprang84a37592017-02-10 07:04:27 -0800119 EXPECT_EQ(1280 * 720, *broadcaster.wants().target_pixel_count);
perkj2d5f0912016-02-29 00:04:41 -0800120
perkjd6c39542016-03-17 10:35:23 +0100121 FakeVideoRenderer sink2;
perkj2d5f0912016-02-29 00:04:41 -0800122 VideoSinkWants wants2;
sprang84a37592017-02-10 07:04:27 -0800123 wants2.target_pixel_count = rtc::Optional<int>(640 * 360);
perkj2d5f0912016-02-29 00:04:41 -0800124 broadcaster.AddOrUpdateSink(&sink2, wants2);
sprang84a37592017-02-10 07:04:27 -0800125 EXPECT_EQ(640 * 360, *broadcaster.wants().target_pixel_count);
perkj2d5f0912016-02-29 00:04:41 -0800126
127 broadcaster.RemoveSink(&sink2);
sprang84a37592017-02-10 07:04:27 -0800128 EXPECT_EQ(1280 * 720, *broadcaster.wants().target_pixel_count);
perkj2d5f0912016-02-29 00:04:41 -0800129}
perkjd6c39542016-03-17 10:35:23 +0100130
sprangc5d62e22017-04-02 23:53:04 -0700131TEST(VideoBroadcasterTest, AppliesMinOfSinkWantsMaxFramerate) {
132 VideoBroadcaster broadcaster;
133 EXPECT_EQ(std::numeric_limits<int>::max(),
134 broadcaster.wants().max_framerate_fps);
135
136 FakeVideoRenderer sink1;
137 VideoSinkWants wants1;
138 wants1.max_framerate_fps = 30;
139
140 broadcaster.AddOrUpdateSink(&sink1, wants1);
141 EXPECT_EQ(30, broadcaster.wants().max_framerate_fps);
142
143 FakeVideoRenderer sink2;
144 VideoSinkWants wants2;
145 wants2.max_framerate_fps = 15;
146 broadcaster.AddOrUpdateSink(&sink2, wants2);
147 EXPECT_EQ(15, broadcaster.wants().max_framerate_fps);
148
149 broadcaster.RemoveSink(&sink2);
150 EXPECT_EQ(30, broadcaster.wants().max_framerate_fps);
151}
152
perkjd6c39542016-03-17 10:35:23 +0100153TEST(VideoBroadcasterTest, SinkWantsBlackFrames) {
154 VideoBroadcaster broadcaster;
155 EXPECT_TRUE(!broadcaster.wants().black_frames);
156
157 FakeVideoRenderer sink1;
158 VideoSinkWants wants1;
159 wants1.black_frames = true;
160 broadcaster.AddOrUpdateSink(&sink1, wants1);
161
162 FakeVideoRenderer sink2;
163 VideoSinkWants wants2;
nisseefec5902016-06-09 00:31:39 -0700164 wants2.black_frames = false;
perkjd6c39542016-03-17 10:35:23 +0100165 broadcaster.AddOrUpdateSink(&sink2, wants2);
166
nisseefec5902016-06-09 00:31:39 -0700167 rtc::scoped_refptr<webrtc::I420Buffer> buffer(
nisseaf916892017-01-10 07:44:26 -0800168 webrtc::I420Buffer::Create(100, 200));
nisseefec5902016-06-09 00:31:39 -0700169 // Makes it not all black.
170 buffer->InitializeData();
171
nisseacd935b2016-11-11 03:55:13 -0800172 webrtc::VideoFrame frame1(buffer, webrtc::kVideoRotation_0,
173 10 /* timestamp_us */);
perkjd6c39542016-03-17 10:35:23 +0100174 broadcaster.OnFrame(frame1);
175 EXPECT_TRUE(sink1.black_frame());
nisse306d52b2016-09-06 07:52:40 -0700176 EXPECT_EQ(10, sink1.timestamp_us());
perkjd6c39542016-03-17 10:35:23 +0100177 EXPECT_FALSE(sink2.black_frame());
nisse306d52b2016-09-06 07:52:40 -0700178 EXPECT_EQ(10, sink2.timestamp_us());
perkjd6c39542016-03-17 10:35:23 +0100179
180 // Switch the sink wants.
181 wants1.black_frames = false;
182 broadcaster.AddOrUpdateSink(&sink1, wants1);
183 wants2.black_frames = true;
184 broadcaster.AddOrUpdateSink(&sink2, wants2);
185
nisseacd935b2016-11-11 03:55:13 -0800186 webrtc::VideoFrame frame2(buffer, webrtc::kVideoRotation_0,
187 30 /* timestamp_us */);
perkjd6c39542016-03-17 10:35:23 +0100188 broadcaster.OnFrame(frame2);
189 EXPECT_FALSE(sink1.black_frame());
nisse306d52b2016-09-06 07:52:40 -0700190 EXPECT_EQ(30, sink1.timestamp_us());
perkjd6c39542016-03-17 10:35:23 +0100191 EXPECT_TRUE(sink2.black_frame());
nisse306d52b2016-09-06 07:52:40 -0700192 EXPECT_EQ(30, sink2.timestamp_us());
perkjd6c39542016-03-17 10:35:23 +0100193}