| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/macros.h" | 6 #include "base/macros.h" |
| 7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
| 8 #include "base/run_loop.h" | 8 #include "base/run_loop.h" |
| 9 #include "base/test/simple_test_tick_clock.h" | 9 #include "base/test/simple_test_tick_clock.h" |
| 10 #include "cc/layers/video_frame_provider.h" | 10 #include "cc/layers/video_frame_provider.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 ACTION_P(RunClosure, closure) { | 22 ACTION_P(RunClosure, closure) { |
| 23 closure.Run(); | 23 closure.Run(); |
| 24 } | 24 } |
| 25 | 25 |
| 26 class VideoFrameCompositorTest : public testing::Test, | 26 class VideoFrameCompositorTest : public testing::Test, |
| 27 public cc::VideoFrameProvider::Client, | 27 public cc::VideoFrameProvider::Client, |
| 28 public VideoRendererSink::RenderCallback { | 28 public VideoRendererSink::RenderCallback { |
| 29 public: | 29 public: |
| 30 VideoFrameCompositorTest() | 30 VideoFrameCompositorTest() |
| 31 : tick_clock_(new base::SimpleTestTickClock()), | 31 : tick_clock_(new base::SimpleTestTickClock()), |
| 32 compositor_(new VideoFrameCompositor( | 32 compositor_(new VideoFrameCompositor(message_loop.task_runner())), |
| 33 message_loop.task_runner(), | 33 did_receive_frame_count_(0) { |
| 34 base::Bind(&VideoFrameCompositorTest::NaturalSizeChanged, | |
| 35 base::Unretained(this)), | |
| 36 base::Bind(&VideoFrameCompositorTest::OpacityChanged, | |
| 37 base::Unretained(this)))), | |
| 38 did_receive_frame_count_(0), | |
| 39 natural_size_changed_count_(0), | |
| 40 opacity_changed_count_(0), | |
| 41 opaque_(false) { | |
| 42 compositor_->SetVideoFrameProviderClient(this); | 34 compositor_->SetVideoFrameProviderClient(this); |
| 43 compositor_->set_tick_clock_for_testing( | 35 compositor_->set_tick_clock_for_testing( |
| 44 std::unique_ptr<base::TickClock>(tick_clock_)); | 36 std::unique_ptr<base::TickClock>(tick_clock_)); |
| 45 // Disable background rendering by default. | 37 // Disable background rendering by default. |
| 46 compositor_->set_background_rendering_for_testing(false); | 38 compositor_->set_background_rendering_for_testing(false); |
| 47 } | 39 } |
| 48 | 40 |
| 49 ~VideoFrameCompositorTest() override { | 41 ~VideoFrameCompositorTest() override { |
| 50 compositor_->SetVideoFrameProviderClient(nullptr); | 42 compositor_->SetVideoFrameProviderClient(nullptr); |
| 51 } | 43 } |
| 52 | 44 |
| 53 scoped_refptr<VideoFrame> CreateOpaqueFrame() { | 45 scoped_refptr<VideoFrame> CreateOpaqueFrame() { |
| 54 gfx::Size size(8, 8); | 46 gfx::Size size(8, 8); |
| 55 return VideoFrame::CreateFrame(PIXEL_FORMAT_YV12, size, gfx::Rect(size), | 47 return VideoFrame::CreateFrame(PIXEL_FORMAT_YV12, size, gfx::Rect(size), |
| 56 size, base::TimeDelta()); | 48 size, base::TimeDelta()); |
| 57 } | 49 } |
| 58 | 50 |
| 59 VideoFrameCompositor* compositor() { return compositor_.get(); } | 51 VideoFrameCompositor* compositor() { return compositor_.get(); } |
| 60 int did_receive_frame_count() { return did_receive_frame_count_; } | 52 int did_receive_frame_count() { return did_receive_frame_count_; } |
| 61 int natural_size_changed_count() { return natural_size_changed_count_; } | |
| 62 gfx::Size natural_size() { return natural_size_; } | |
| 63 | |
| 64 int opacity_changed_count() { return opacity_changed_count_; } | |
| 65 bool opaque() { return opaque_; } | |
| 66 | 53 |
| 67 protected: | 54 protected: |
| 68 // cc::VideoFrameProvider::Client implementation. | 55 // cc::VideoFrameProvider::Client implementation. |
| 69 void StopUsingProvider() override {} | 56 void StopUsingProvider() override {} |
| 70 MOCK_METHOD0(StartRendering, void()); | 57 MOCK_METHOD0(StartRendering, void()); |
| 71 MOCK_METHOD0(StopRendering, void()); | 58 MOCK_METHOD0(StopRendering, void()); |
| 72 void DidReceiveFrame() override { ++did_receive_frame_count_; } | 59 void DidReceiveFrame() override { ++did_receive_frame_count_; } |
| 73 | 60 |
| 74 // VideoRendererSink::RenderCallback implementation. | 61 // VideoRendererSink::RenderCallback implementation. |
| 75 MOCK_METHOD3(Render, | 62 MOCK_METHOD3(Render, |
| 76 scoped_refptr<VideoFrame>(base::TimeTicks, | 63 scoped_refptr<VideoFrame>(base::TimeTicks, |
| 77 base::TimeTicks, | 64 base::TimeTicks, |
| 78 bool)); | 65 bool)); |
| 79 MOCK_METHOD0(OnFrameDropped, void()); | 66 MOCK_METHOD0(OnFrameDropped, void()); |
| 80 | 67 |
| 81 void NaturalSizeChanged(gfx::Size natural_size) { | |
| 82 ++natural_size_changed_count_; | |
| 83 natural_size_ = natural_size; | |
| 84 } | |
| 85 | |
| 86 void OpacityChanged(bool opaque) { | |
| 87 ++opacity_changed_count_; | |
| 88 opaque_ = opaque; | |
| 89 } | |
| 90 | |
| 91 void StartVideoRendererSink() { | 68 void StartVideoRendererSink() { |
| 92 EXPECT_CALL(*this, StartRendering()); | 69 EXPECT_CALL(*this, StartRendering()); |
| 93 const bool had_current_frame = !!compositor_->GetCurrentFrame(); | 70 const bool had_current_frame = !!compositor_->GetCurrentFrame(); |
| 94 compositor()->Start(this); | 71 compositor()->Start(this); |
| 95 // If we previously had a frame, we should still have one now. | 72 // If we previously had a frame, we should still have one now. |
| 96 EXPECT_EQ(had_current_frame, !!compositor_->GetCurrentFrame()); | 73 EXPECT_EQ(had_current_frame, !!compositor_->GetCurrentFrame()); |
| 97 message_loop.RunUntilIdle(); | 74 message_loop.RunUntilIdle(); |
| 98 } | 75 } |
| 99 | 76 |
| 100 void StopVideoRendererSink(bool have_client) { | 77 void StopVideoRendererSink(bool have_client) { |
| 101 if (have_client) | 78 if (have_client) |
| 102 EXPECT_CALL(*this, StopRendering()); | 79 EXPECT_CALL(*this, StopRendering()); |
| 103 const bool had_current_frame = !!compositor_->GetCurrentFrame(); | 80 const bool had_current_frame = !!compositor_->GetCurrentFrame(); |
| 104 compositor()->Stop(); | 81 compositor()->Stop(); |
| 105 // If we previously had a frame, we should still have one now. | 82 // If we previously had a frame, we should still have one now. |
| 106 EXPECT_EQ(had_current_frame, !!compositor_->GetCurrentFrame()); | 83 EXPECT_EQ(had_current_frame, !!compositor_->GetCurrentFrame()); |
| 107 message_loop.RunUntilIdle(); | 84 message_loop.RunUntilIdle(); |
| 108 } | 85 } |
| 109 | 86 |
| 110 void RenderFrame() { | 87 void RenderFrame() { |
| 111 compositor()->GetCurrentFrame(); | 88 compositor()->GetCurrentFrame(); |
| 112 compositor()->PutCurrentFrame(); | 89 compositor()->PutCurrentFrame(); |
| 113 } | 90 } |
| 114 | 91 |
| 115 base::MessageLoop message_loop; | 92 base::MessageLoop message_loop; |
| 116 base::SimpleTestTickClock* tick_clock_; // Owned by |compositor_| | 93 base::SimpleTestTickClock* tick_clock_; // Owned by |compositor_| |
| 117 std::unique_ptr<VideoFrameCompositor> compositor_; | 94 std::unique_ptr<VideoFrameCompositor> compositor_; |
| 118 | 95 |
| 119 int did_receive_frame_count_; | 96 int did_receive_frame_count_; |
| 120 int natural_size_changed_count_; | |
| 121 gfx::Size natural_size_; | |
| 122 int opacity_changed_count_; | |
| 123 bool opaque_; | |
| 124 | 97 |
| 125 DISALLOW_COPY_AND_ASSIGN(VideoFrameCompositorTest); | 98 DISALLOW_COPY_AND_ASSIGN(VideoFrameCompositorTest); |
| 126 }; | 99 }; |
| 127 | 100 |
| 128 TEST_F(VideoFrameCompositorTest, InitialValues) { | 101 TEST_F(VideoFrameCompositorTest, InitialValues) { |
| 129 EXPECT_FALSE(compositor()->GetCurrentFrame().get()); | 102 EXPECT_FALSE(compositor()->GetCurrentFrame().get()); |
| 130 } | 103 } |
| 131 | 104 |
| 132 TEST_F(VideoFrameCompositorTest, PaintFrameUsingOldRenderingPath) { | 105 TEST_F(VideoFrameCompositorTest, PaintFrameUsingOldRenderingPath) { |
| 133 scoped_refptr<VideoFrame> expected = VideoFrame::CreateEOSFrame(); | 106 scoped_refptr<VideoFrame> expected = VideoFrame::CreateEOSFrame(); |
| 134 | 107 |
| 135 // Should notify compositor synchronously. | 108 // Should notify compositor synchronously. |
| 136 EXPECT_EQ(0, did_receive_frame_count()); | 109 EXPECT_EQ(0, did_receive_frame_count()); |
| 137 compositor()->PaintFrameUsingOldRenderingPath(expected); | 110 compositor()->PaintFrameUsingOldRenderingPath(expected); |
| 138 scoped_refptr<VideoFrame> actual = compositor()->GetCurrentFrame(); | 111 scoped_refptr<VideoFrame> actual = compositor()->GetCurrentFrame(); |
| 139 EXPECT_EQ(expected, actual); | 112 EXPECT_EQ(expected, actual); |
| 140 EXPECT_EQ(1, did_receive_frame_count()); | 113 EXPECT_EQ(1, did_receive_frame_count()); |
| 141 } | 114 } |
| 142 | 115 |
| 143 TEST_F(VideoFrameCompositorTest, NaturalSizeChanged) { | |
| 144 gfx::Size initial_size(8, 8); | |
| 145 scoped_refptr<VideoFrame> initial_frame = | |
| 146 VideoFrame::CreateBlackFrame(initial_size); | |
| 147 | |
| 148 gfx::Size larger_size(16, 16); | |
| 149 scoped_refptr<VideoFrame> larger_frame = | |
| 150 VideoFrame::CreateBlackFrame(larger_size); | |
| 151 | |
| 152 gfx::Size empty_size(0, 0); | |
| 153 | |
| 154 // Initial expectations. | |
| 155 EXPECT_EQ(empty_size, natural_size()); | |
| 156 EXPECT_EQ(0, natural_size_changed_count()); | |
| 157 | |
| 158 // Callback is fired for the first frame. | |
| 159 compositor()->PaintFrameUsingOldRenderingPath(initial_frame); | |
| 160 EXPECT_EQ(initial_size, natural_size()); | |
| 161 EXPECT_EQ(1, natural_size_changed_count()); | |
| 162 | |
| 163 // Callback should be fired once. | |
| 164 compositor()->PaintFrameUsingOldRenderingPath(larger_frame); | |
| 165 EXPECT_EQ(larger_size, natural_size()); | |
| 166 EXPECT_EQ(2, natural_size_changed_count()); | |
| 167 | |
| 168 compositor()->PaintFrameUsingOldRenderingPath(larger_frame); | |
| 169 EXPECT_EQ(larger_size, natural_size()); | |
| 170 EXPECT_EQ(2, natural_size_changed_count()); | |
| 171 | |
| 172 // Callback is fired once more when switching back to initial size. | |
| 173 compositor()->PaintFrameUsingOldRenderingPath(initial_frame); | |
| 174 EXPECT_EQ(initial_size, natural_size()); | |
| 175 EXPECT_EQ(3, natural_size_changed_count()); | |
| 176 | |
| 177 compositor()->PaintFrameUsingOldRenderingPath(initial_frame); | |
| 178 EXPECT_EQ(initial_size, natural_size()); | |
| 179 EXPECT_EQ(3, natural_size_changed_count()); | |
| 180 | |
| 181 natural_size_changed_count_ = 0; | |
| 182 natural_size_ = empty_size; | |
| 183 compositor()->clear_current_frame_for_testing(); | |
| 184 | |
| 185 EXPECT_CALL(*this, Render(_, _, _)) | |
| 186 .WillOnce(Return(initial_frame)) | |
| 187 .WillOnce(Return(larger_frame)) | |
| 188 .WillOnce(Return(initial_frame)) | |
| 189 .WillOnce(Return(initial_frame)); | |
| 190 StartVideoRendererSink(); | |
| 191 | |
| 192 // Starting the sink will issue one Render() call, ensure the callback is | |
| 193 // fired for the first frame. | |
| 194 EXPECT_EQ(1, natural_size_changed_count()); | |
| 195 EXPECT_EQ(initial_size, natural_size()); | |
| 196 | |
| 197 // Once another frame is received with a different size it should fire. | |
| 198 EXPECT_TRUE( | |
| 199 compositor()->UpdateCurrentFrame(base::TimeTicks(), base::TimeTicks())); | |
| 200 RenderFrame(); | |
| 201 EXPECT_EQ(larger_size, natural_size()); | |
| 202 EXPECT_EQ(2, natural_size_changed_count()); | |
| 203 | |
| 204 EXPECT_TRUE( | |
| 205 compositor()->UpdateCurrentFrame(base::TimeTicks(), base::TimeTicks())); | |
| 206 RenderFrame(); | |
| 207 EXPECT_EQ(initial_size, natural_size()); | |
| 208 EXPECT_EQ(3, natural_size_changed_count()); | |
| 209 | |
| 210 EXPECT_FALSE( | |
| 211 compositor()->UpdateCurrentFrame(base::TimeTicks(), base::TimeTicks())); | |
| 212 EXPECT_EQ(initial_size, natural_size()); | |
| 213 EXPECT_EQ(3, natural_size_changed_count()); | |
| 214 RenderFrame(); | |
| 215 | |
| 216 StopVideoRendererSink(true); | |
| 217 } | |
| 218 | |
| 219 TEST_F(VideoFrameCompositorTest, OpacityChanged) { | |
| 220 gfx::Size size(8, 8); | |
| 221 scoped_refptr<VideoFrame> opaque_frame = CreateOpaqueFrame(); | |
| 222 scoped_refptr<VideoFrame> not_opaque_frame = VideoFrame::CreateFrame( | |
| 223 PIXEL_FORMAT_YV12A, size, gfx::Rect(size), size, base::TimeDelta()); | |
| 224 | |
| 225 // Initial expectations. | |
| 226 EXPECT_FALSE(opaque()); | |
| 227 EXPECT_EQ(0, opacity_changed_count()); | |
| 228 | |
| 229 // Callback is fired for the first frame. | |
| 230 compositor()->PaintFrameUsingOldRenderingPath(not_opaque_frame); | |
| 231 EXPECT_FALSE(opaque()); | |
| 232 EXPECT_EQ(1, opacity_changed_count()); | |
| 233 | |
| 234 // Callback shouldn't be first subsequent times with same opaqueness. | |
| 235 compositor()->PaintFrameUsingOldRenderingPath(not_opaque_frame); | |
| 236 EXPECT_FALSE(opaque()); | |
| 237 EXPECT_EQ(1, opacity_changed_count()); | |
| 238 | |
| 239 // Callback is fired when using opacity changes. | |
| 240 compositor()->PaintFrameUsingOldRenderingPath(opaque_frame); | |
| 241 EXPECT_TRUE(opaque()); | |
| 242 EXPECT_EQ(2, opacity_changed_count()); | |
| 243 | |
| 244 // Callback shouldn't be first subsequent times with same opaqueness. | |
| 245 compositor()->PaintFrameUsingOldRenderingPath(opaque_frame); | |
| 246 EXPECT_TRUE(opaque()); | |
| 247 EXPECT_EQ(2, opacity_changed_count()); | |
| 248 | |
| 249 opacity_changed_count_ = 0; | |
| 250 compositor()->clear_current_frame_for_testing(); | |
| 251 | |
| 252 EXPECT_CALL(*this, Render(_, _, _)) | |
| 253 .WillOnce(Return(not_opaque_frame)) | |
| 254 .WillOnce(Return(not_opaque_frame)) | |
| 255 .WillOnce(Return(opaque_frame)) | |
| 256 .WillOnce(Return(opaque_frame)); | |
| 257 StartVideoRendererSink(); | |
| 258 EXPECT_FALSE(opaque()); | |
| 259 EXPECT_EQ(1, opacity_changed_count()); | |
| 260 | |
| 261 EXPECT_TRUE( | |
| 262 compositor()->UpdateCurrentFrame(base::TimeTicks(), base::TimeTicks())); | |
| 263 RenderFrame(); | |
| 264 EXPECT_FALSE(opaque()); | |
| 265 EXPECT_EQ(1, opacity_changed_count()); | |
| 266 | |
| 267 EXPECT_TRUE( | |
| 268 compositor()->UpdateCurrentFrame(base::TimeTicks(), base::TimeTicks())); | |
| 269 RenderFrame(); | |
| 270 EXPECT_TRUE(opaque()); | |
| 271 EXPECT_EQ(2, opacity_changed_count()); | |
| 272 | |
| 273 EXPECT_FALSE( | |
| 274 compositor()->UpdateCurrentFrame(base::TimeTicks(), base::TimeTicks())); | |
| 275 EXPECT_TRUE(opaque()); | |
| 276 EXPECT_EQ(2, opacity_changed_count()); | |
| 277 RenderFrame(); | |
| 278 | |
| 279 StopVideoRendererSink(true); | |
| 280 } | |
| 281 | |
| 282 TEST_F(VideoFrameCompositorTest, VideoRendererSinkFrameDropped) { | 116 TEST_F(VideoFrameCompositorTest, VideoRendererSinkFrameDropped) { |
| 283 scoped_refptr<VideoFrame> opaque_frame = CreateOpaqueFrame(); | 117 scoped_refptr<VideoFrame> opaque_frame = CreateOpaqueFrame(); |
| 284 | 118 |
| 285 EXPECT_CALL(*this, Render(_, _, _)).WillRepeatedly(Return(opaque_frame)); | 119 EXPECT_CALL(*this, Render(_, _, _)).WillRepeatedly(Return(opaque_frame)); |
| 286 StartVideoRendererSink(); | 120 StartVideoRendererSink(); |
| 287 | 121 |
| 288 EXPECT_TRUE( | 122 EXPECT_TRUE( |
| 289 compositor()->UpdateCurrentFrame(base::TimeTicks(), base::TimeTicks())); | 123 compositor()->UpdateCurrentFrame(base::TimeTicks(), base::TimeTicks())); |
| 290 | 124 |
| 291 // Another call should trigger a dropped frame callback. | 125 // Another call should trigger a dropped frame callback. |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 | 259 |
| 426 // Advancing the tick clock should allow a new frame to be requested. | 260 // Advancing the tick clock should allow a new frame to be requested. |
| 427 tick_clock_->Advance(base::TimeDelta::FromMilliseconds(10)); | 261 tick_clock_->Advance(base::TimeDelta::FromMilliseconds(10)); |
| 428 ASSERT_EQ(opaque_frame_2, compositor()->GetCurrentFrameAndUpdateIfStale()); | 262 ASSERT_EQ(opaque_frame_2, compositor()->GetCurrentFrameAndUpdateIfStale()); |
| 429 | 263 |
| 430 // Background rendering should tick another render callback. | 264 // Background rendering should tick another render callback. |
| 431 StopVideoRendererSink(false); | 265 StopVideoRendererSink(false); |
| 432 } | 266 } |
| 433 | 267 |
| 434 } // namespace media | 268 } // namespace media |
| OLD | NEW |