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 | |
| 11 | #include "webrtc/base/gunit.h" |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 12 | #include "webrtc/media/base/fakevideorenderer.h" |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 13 | #include "webrtc/media/base/videobroadcaster.h" |
nisse | acd935b | 2016-11-11 03:55:13 -0800 | [diff] [blame] | 14 | #include "webrtc/video_frame.h" |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 15 | |
| 16 | using rtc::VideoBroadcaster; |
| 17 | using rtc::VideoSinkWants; |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 18 | using cricket::FakeVideoRenderer; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 19 | |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 20 | |
| 21 | TEST(VideoBroadcasterTest, frame_wanted) { |
| 22 | VideoBroadcaster broadcaster; |
| 23 | EXPECT_FALSE(broadcaster.frame_wanted()); |
| 24 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 25 | FakeVideoRenderer sink; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 26 | broadcaster.AddOrUpdateSink(&sink, rtc::VideoSinkWants()); |
| 27 | EXPECT_TRUE(broadcaster.frame_wanted()); |
| 28 | |
| 29 | broadcaster.RemoveSink(&sink); |
| 30 | EXPECT_FALSE(broadcaster.frame_wanted()); |
| 31 | } |
| 32 | |
| 33 | TEST(VideoBroadcasterTest, OnFrame) { |
| 34 | VideoBroadcaster broadcaster; |
| 35 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 36 | FakeVideoRenderer sink1; |
| 37 | FakeVideoRenderer sink2; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 38 | broadcaster.AddOrUpdateSink(&sink1, rtc::VideoSinkWants()); |
| 39 | broadcaster.AddOrUpdateSink(&sink2, rtc::VideoSinkWants()); |
nisse | df2ceb8 | 2016-12-15 06:29:53 -0800 | [diff] [blame^] | 40 | static int kWidth = 100; |
| 41 | static int kHeight = 50; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 42 | |
nisse | df2ceb8 | 2016-12-15 06:29:53 -0800 | [diff] [blame^] | 43 | rtc::scoped_refptr<webrtc::I420Buffer> buffer( |
| 44 | webrtc::I420Buffer::Create(kWidth, kHeight)); |
| 45 | // Initialize, to avoid warnings on use of initialized values. |
| 46 | buffer->SetToBlack(); |
| 47 | |
| 48 | webrtc::VideoFrame frame(buffer, webrtc::kVideoRotation_0, 0); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 49 | |
| 50 | broadcaster.OnFrame(frame); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 51 | EXPECT_EQ(1, sink1.num_rendered_frames()); |
| 52 | EXPECT_EQ(1, sink2.num_rendered_frames()); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 53 | |
| 54 | broadcaster.RemoveSink(&sink1); |
| 55 | broadcaster.OnFrame(frame); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 56 | EXPECT_EQ(1, sink1.num_rendered_frames()); |
| 57 | EXPECT_EQ(2, sink2.num_rendered_frames()); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 58 | |
| 59 | broadcaster.AddOrUpdateSink(&sink1, rtc::VideoSinkWants()); |
| 60 | broadcaster.OnFrame(frame); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 61 | EXPECT_EQ(2, sink1.num_rendered_frames()); |
| 62 | EXPECT_EQ(3, sink2.num_rendered_frames()); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 63 | } |
| 64 | |
| 65 | TEST(VideoBroadcasterTest, AppliesRotationIfAnySinkWantsRotationApplied) { |
| 66 | VideoBroadcaster broadcaster; |
deadbeef | f5629ad | 2016-03-18 11:38:26 -0700 | [diff] [blame] | 67 | EXPECT_FALSE(broadcaster.wants().rotation_applied); |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 68 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 69 | FakeVideoRenderer sink1; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 70 | VideoSinkWants wants1; |
| 71 | wants1.rotation_applied = false; |
| 72 | |
| 73 | broadcaster.AddOrUpdateSink(&sink1, wants1); |
| 74 | EXPECT_FALSE(broadcaster.wants().rotation_applied); |
| 75 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 76 | FakeVideoRenderer sink2; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 77 | VideoSinkWants wants2; |
| 78 | wants2.rotation_applied = true; |
| 79 | |
| 80 | broadcaster.AddOrUpdateSink(&sink2, wants2); |
| 81 | EXPECT_TRUE(broadcaster.wants().rotation_applied); |
| 82 | |
| 83 | broadcaster.RemoveSink(&sink2); |
| 84 | EXPECT_FALSE(broadcaster.wants().rotation_applied); |
| 85 | } |
| 86 | |
| 87 | TEST(VideoBroadcasterTest, AppliesMinOfSinkWantsMaxPixelCount) { |
| 88 | VideoBroadcaster broadcaster; |
| 89 | EXPECT_TRUE(!broadcaster.wants().max_pixel_count); |
| 90 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 91 | FakeVideoRenderer sink1; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 92 | VideoSinkWants wants1; |
| 93 | wants1.max_pixel_count = rtc::Optional<int>(1280 * 720); |
| 94 | |
| 95 | broadcaster.AddOrUpdateSink(&sink1, wants1); |
| 96 | EXPECT_EQ(1280 * 720, *broadcaster.wants().max_pixel_count); |
| 97 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 98 | FakeVideoRenderer sink2; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 99 | VideoSinkWants wants2; |
| 100 | wants2.max_pixel_count = rtc::Optional<int>(640 * 360); |
| 101 | broadcaster.AddOrUpdateSink(&sink2, wants2); |
| 102 | EXPECT_EQ(640 * 360, *broadcaster.wants().max_pixel_count); |
| 103 | |
| 104 | broadcaster.RemoveSink(&sink2); |
| 105 | EXPECT_EQ(1280 * 720, *broadcaster.wants().max_pixel_count); |
| 106 | } |
| 107 | |
| 108 | TEST(VideoBroadcasterTest, AppliesMinOfSinkWantsMaxPixelCountStepUp) { |
| 109 | VideoBroadcaster broadcaster; |
| 110 | EXPECT_TRUE(!broadcaster.wants().max_pixel_count_step_up); |
| 111 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 112 | FakeVideoRenderer sink1; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 113 | VideoSinkWants wants1; |
| 114 | wants1.max_pixel_count_step_up = rtc::Optional<int>(1280 * 720); |
| 115 | |
| 116 | broadcaster.AddOrUpdateSink(&sink1, wants1); |
| 117 | EXPECT_EQ(1280 * 720, *broadcaster.wants().max_pixel_count_step_up); |
| 118 | |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 119 | FakeVideoRenderer sink2; |
perkj | 2d5f091 | 2016-02-29 00:04:41 -0800 | [diff] [blame] | 120 | VideoSinkWants wants2; |
| 121 | wants2.max_pixel_count_step_up = rtc::Optional<int>(640 * 360); |
| 122 | broadcaster.AddOrUpdateSink(&sink2, wants2); |
| 123 | EXPECT_EQ(640 * 360, *broadcaster.wants().max_pixel_count_step_up); |
| 124 | |
| 125 | broadcaster.RemoveSink(&sink2); |
| 126 | EXPECT_EQ(1280 * 720, *broadcaster.wants().max_pixel_count_step_up); |
| 127 | } |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 128 | |
| 129 | TEST(VideoBroadcasterTest, SinkWantsBlackFrames) { |
| 130 | VideoBroadcaster broadcaster; |
| 131 | EXPECT_TRUE(!broadcaster.wants().black_frames); |
| 132 | |
| 133 | FakeVideoRenderer sink1; |
| 134 | VideoSinkWants wants1; |
| 135 | wants1.black_frames = true; |
| 136 | broadcaster.AddOrUpdateSink(&sink1, wants1); |
| 137 | |
| 138 | FakeVideoRenderer sink2; |
| 139 | VideoSinkWants wants2; |
nisse | efec590 | 2016-06-09 00:31:39 -0700 | [diff] [blame] | 140 | wants2.black_frames = false; |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 141 | broadcaster.AddOrUpdateSink(&sink2, wants2); |
| 142 | |
nisse | efec590 | 2016-06-09 00:31:39 -0700 | [diff] [blame] | 143 | rtc::scoped_refptr<webrtc::I420Buffer> buffer( |
| 144 | new rtc::RefCountedObject<webrtc::I420Buffer>(100, 200)); |
| 145 | // Makes it not all black. |
| 146 | buffer->InitializeData(); |
| 147 | |
nisse | acd935b | 2016-11-11 03:55:13 -0800 | [diff] [blame] | 148 | webrtc::VideoFrame frame1(buffer, webrtc::kVideoRotation_0, |
| 149 | 10 /* timestamp_us */); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 150 | broadcaster.OnFrame(frame1); |
| 151 | EXPECT_TRUE(sink1.black_frame()); |
nisse | 306d52b | 2016-09-06 07:52:40 -0700 | [diff] [blame] | 152 | EXPECT_EQ(10, sink1.timestamp_us()); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 153 | EXPECT_FALSE(sink2.black_frame()); |
nisse | 306d52b | 2016-09-06 07:52:40 -0700 | [diff] [blame] | 154 | EXPECT_EQ(10, sink2.timestamp_us()); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 155 | |
| 156 | // Switch the sink wants. |
| 157 | wants1.black_frames = false; |
| 158 | broadcaster.AddOrUpdateSink(&sink1, wants1); |
| 159 | wants2.black_frames = true; |
| 160 | broadcaster.AddOrUpdateSink(&sink2, wants2); |
| 161 | |
nisse | acd935b | 2016-11-11 03:55:13 -0800 | [diff] [blame] | 162 | webrtc::VideoFrame frame2(buffer, webrtc::kVideoRotation_0, |
| 163 | 30 /* timestamp_us */); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 164 | broadcaster.OnFrame(frame2); |
| 165 | EXPECT_FALSE(sink1.black_frame()); |
nisse | 306d52b | 2016-09-06 07:52:40 -0700 | [diff] [blame] | 166 | EXPECT_EQ(30, sink1.timestamp_us()); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 167 | EXPECT_TRUE(sink2.black_frame()); |
nisse | 306d52b | 2016-09-06 07:52:40 -0700 | [diff] [blame] | 168 | EXPECT_EQ(30, sink2.timestamp_us()); |
perkj | d6c3954 | 2016-03-17 10:35:23 +0100 | [diff] [blame] | 169 | } |