perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 1 | /* |
| 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 | |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 11 | #include "webrtc/api/video/i420_buffer.h" |
| 12 | #include "webrtc/api/video/video_frame.h" |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 13 | #include "webrtc/base/gunit.h" |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 14 | #include "webrtc/media/base/fakevideorenderer.h" |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 15 | #include "webrtc/media/base/videobroadcaster.h" |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 16 | |
| 17 | using rtc::VideoBroadcaster; |
| 18 | using rtc::VideoSinkWants; |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 19 | using cricket::FakeVideoRenderer; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 20 | |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 21 | |
| 22 | TEST(VideoBroadcasterTest, frame_wanted) { |
| 23 | VideoBroadcaster broadcaster; |
| 24 | EXPECT_FALSE(broadcaster.frame_wanted()); |
| 25 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 26 | FakeVideoRenderer sink; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 27 | broadcaster.AddOrUpdateSink(&sink, rtc::VideoSinkWants()); |
| 28 | EXPECT_TRUE(broadcaster.frame_wanted()); |
| 29 | |
| 30 | broadcaster.RemoveSink(&sink); |
| 31 | EXPECT_FALSE(broadcaster.frame_wanted()); |
| 32 | } |
| 33 | |
| 34 | TEST(VideoBroadcasterTest, OnFrame) { |
| 35 | VideoBroadcaster broadcaster; |
| 36 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 37 | FakeVideoRenderer sink1; |
| 38 | FakeVideoRenderer sink2; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 39 | broadcaster.AddOrUpdateSink(&sink1, rtc::VideoSinkWants()); |
| 40 | broadcaster.AddOrUpdateSink(&sink2, rtc::VideoSinkWants()); |
nisse | df2ceb8 | 2016-12-15 06:29:53 -0800 | [diff] [blame] | 41 | static int kWidth = 100; |
| 42 | static int kHeight = 50; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 43 | |
nisse | df2ceb8 | 2016-12-15 06:29:53 -0800 | [diff] [blame] | 44 | rtc::scoped_refptr<webrtc::I420Buffer> buffer( |
| 45 | webrtc::I420Buffer::Create(kWidth, kHeight)); |
| 46 | // Initialize, to avoid warnings on use of initialized values. |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 47 | webrtc::I420Buffer::SetBlack(buffer); |
nisse | df2ceb8 | 2016-12-15 06:29:53 -0800 | [diff] [blame] | 48 | |
| 49 | webrtc::VideoFrame frame(buffer, webrtc::kVideoRotation_0, 0); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 50 | |
| 51 | broadcaster.OnFrame(frame); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 52 | EXPECT_EQ(1, sink1.num_rendered_frames()); |
| 53 | EXPECT_EQ(1, sink2.num_rendered_frames()); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 54 | |
| 55 | broadcaster.RemoveSink(&sink1); |
| 56 | broadcaster.OnFrame(frame); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 57 | EXPECT_EQ(1, sink1.num_rendered_frames()); |
| 58 | EXPECT_EQ(2, sink2.num_rendered_frames()); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 59 | |
| 60 | broadcaster.AddOrUpdateSink(&sink1, rtc::VideoSinkWants()); |
| 61 | broadcaster.OnFrame(frame); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 62 | EXPECT_EQ(2, sink1.num_rendered_frames()); |
| 63 | EXPECT_EQ(3, sink2.num_rendered_frames()); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 64 | } |
| 65 | |
| 66 | TEST(VideoBroadcasterTest, AppliesRotationIfAnySinkWantsRotationApplied) { |
| 67 | VideoBroadcaster broadcaster; |
deadbeef | f5629ad | 2016-03-18 11:38:26 -0700 | [diff] [blame] | 68 | EXPECT_FALSE(broadcaster.wants().rotation_applied); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 69 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 70 | FakeVideoRenderer sink1; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 71 | VideoSinkWants wants1; |
| 72 | wants1.rotation_applied = false; |
| 73 | |
| 74 | broadcaster.AddOrUpdateSink(&sink1, wants1); |
| 75 | EXPECT_FALSE(broadcaster.wants().rotation_applied); |
| 76 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 77 | FakeVideoRenderer sink2; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 78 | 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 | |
| 88 | TEST(VideoBroadcasterTest, AppliesMinOfSinkWantsMaxPixelCount) { |
| 89 | VideoBroadcaster broadcaster; |
sprang | c5d62e2 | 2017-04-02 23:53:04 -0700 | [diff] [blame^] | 90 | EXPECT_EQ(std::numeric_limits<int>::max(), |
| 91 | broadcaster.wants().max_pixel_count); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 92 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 93 | FakeVideoRenderer sink1; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 94 | VideoSinkWants wants1; |
sprang | c5d62e2 | 2017-04-02 23:53:04 -0700 | [diff] [blame^] | 95 | wants1.max_pixel_count = 1280 * 720; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 96 | |
| 97 | broadcaster.AddOrUpdateSink(&sink1, wants1); |
sprang | c5d62e2 | 2017-04-02 23:53:04 -0700 | [diff] [blame^] | 98 | EXPECT_EQ(1280 * 720, broadcaster.wants().max_pixel_count); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 99 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 100 | FakeVideoRenderer sink2; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 101 | VideoSinkWants wants2; |
sprang | c5d62e2 | 2017-04-02 23:53:04 -0700 | [diff] [blame^] | 102 | wants2.max_pixel_count = 640 * 360; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 103 | broadcaster.AddOrUpdateSink(&sink2, wants2); |
sprang | c5d62e2 | 2017-04-02 23:53:04 -0700 | [diff] [blame^] | 104 | EXPECT_EQ(640 * 360, broadcaster.wants().max_pixel_count); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 105 | |
| 106 | broadcaster.RemoveSink(&sink2); |
sprang | c5d62e2 | 2017-04-02 23:53:04 -0700 | [diff] [blame^] | 107 | EXPECT_EQ(1280 * 720, broadcaster.wants().max_pixel_count); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 108 | } |
| 109 | |
sprang | 84a3759 | 2017-02-10 07:04:27 -0800 | [diff] [blame] | 110 | TEST(VideoBroadcasterTest, AppliesMinOfSinkWantsMaxAndTargetPixelCount) { |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 111 | VideoBroadcaster broadcaster; |
sprang | 84a3759 | 2017-02-10 07:04:27 -0800 | [diff] [blame] | 112 | EXPECT_TRUE(!broadcaster.wants().target_pixel_count); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 113 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 114 | FakeVideoRenderer sink1; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 115 | VideoSinkWants wants1; |
sprang | 84a3759 | 2017-02-10 07:04:27 -0800 | [diff] [blame] | 116 | wants1.target_pixel_count = rtc::Optional<int>(1280 * 720); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 117 | |
| 118 | broadcaster.AddOrUpdateSink(&sink1, wants1); |
sprang | 84a3759 | 2017-02-10 07:04:27 -0800 | [diff] [blame] | 119 | EXPECT_EQ(1280 * 720, *broadcaster.wants().target_pixel_count); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 120 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 121 | FakeVideoRenderer sink2; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 122 | VideoSinkWants wants2; |
sprang | 84a3759 | 2017-02-10 07:04:27 -0800 | [diff] [blame] | 123 | wants2.target_pixel_count = rtc::Optional<int>(640 * 360); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 124 | broadcaster.AddOrUpdateSink(&sink2, wants2); |
sprang | 84a3759 | 2017-02-10 07:04:27 -0800 | [diff] [blame] | 125 | EXPECT_EQ(640 * 360, *broadcaster.wants().target_pixel_count); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 126 | |
| 127 | broadcaster.RemoveSink(&sink2); |
sprang | 84a3759 | 2017-02-10 07:04:27 -0800 | [diff] [blame] | 128 | EXPECT_EQ(1280 * 720, *broadcaster.wants().target_pixel_count); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 129 | } |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 130 | |
sprang | c5d62e2 | 2017-04-02 23:53:04 -0700 | [diff] [blame^] | 131 | TEST(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 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 153 | TEST(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; |
nisse | efec590 | 2016-06-09 00:31:39 -0700 | [diff] [blame] | 164 | wants2.black_frames = false; |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 165 | broadcaster.AddOrUpdateSink(&sink2, wants2); |
| 166 | |
nisse | efec590 | 2016-06-09 00:31:39 -0700 | [diff] [blame] | 167 | rtc::scoped_refptr<webrtc::I420Buffer> buffer( |
nisse | af91689 | 2017-01-10 07:44:26 -0800 | [diff] [blame] | 168 | webrtc::I420Buffer::Create(100, 200)); |
nisse | efec590 | 2016-06-09 00:31:39 -0700 | [diff] [blame] | 169 | // Makes it not all black. |
| 170 | buffer->InitializeData(); |
| 171 | |
nisse | acd935b | 2016-11-11 03:55:13 -0800 | [diff] [blame] | 172 | webrtc::VideoFrame frame1(buffer, webrtc::kVideoRotation_0, |
| 173 | 10 /* timestamp_us */); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 174 | broadcaster.OnFrame(frame1); |
| 175 | EXPECT_TRUE(sink1.black_frame()); |
nisse | 306d52b | 2016-09-06 07:52:40 -0700 | [diff] [blame] | 176 | EXPECT_EQ(10, sink1.timestamp_us()); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 177 | EXPECT_FALSE(sink2.black_frame()); |
nisse | 306d52b | 2016-09-06 07:52:40 -0700 | [diff] [blame] | 178 | EXPECT_EQ(10, sink2.timestamp_us()); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 179 | |
| 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 | |
nisse | acd935b | 2016-11-11 03:55:13 -0800 | [diff] [blame] | 186 | webrtc::VideoFrame frame2(buffer, webrtc::kVideoRotation_0, |
| 187 | 30 /* timestamp_us */); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 188 | broadcaster.OnFrame(frame2); |
| 189 | EXPECT_FALSE(sink1.black_frame()); |
nisse | 306d52b | 2016-09-06 07:52:40 -0700 | [diff] [blame] | 190 | EXPECT_EQ(30, sink1.timestamp_us()); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 191 | EXPECT_TRUE(sink2.black_frame()); |
nisse | 306d52b | 2016-09-06 07:52:40 -0700 | [diff] [blame] | 192 | EXPECT_EQ(30, sink2.timestamp_us()); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 193 | } |