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/message_loop/message_loop.h" |
6 #include "cc/layers/video_frame_provider.h" | 7 #include "cc/layers/video_frame_provider.h" |
7 #include "content/renderer/media/video_frame_compositor.h" | 8 #include "content/renderer/media/video_frame_compositor.h" |
8 #include "media/base/video_frame.h" | 9 #include "media/base/video_frame.h" |
9 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
10 | 11 |
11 namespace content { | 12 namespace content { |
12 | 13 |
13 using media::VideoFrame; | 14 using media::VideoFrame; |
14 | 15 |
15 class VideoFrameCompositorTest : public testing::Test, | 16 class VideoFrameCompositorTest : public testing::Test, |
16 public cc::VideoFrameProvider::Client { | 17 public cc::VideoFrameProvider::Client { |
17 public: | 18 public: |
18 VideoFrameCompositorTest() | 19 VideoFrameCompositorTest() |
19 : compositor_(new VideoFrameCompositor( | 20 : compositor_(new VideoFrameCompositor( |
| 21 message_loop_.message_loop_proxy(), |
20 base::Bind(&VideoFrameCompositorTest::NaturalSizeChanged, | 22 base::Bind(&VideoFrameCompositorTest::NaturalSizeChanged, |
21 base::Unretained(this)), | 23 base::Unretained(this)), |
22 base::Bind(&VideoFrameCompositorTest::OpacityChanged, | 24 base::Bind(&VideoFrameCompositorTest::OpacityChanged, |
23 base::Unretained(this)))), | 25 base::Unretained(this)))), |
24 did_receive_frame_count_(0), | 26 did_receive_frame_count_(0), |
25 natural_size_changed_count_(0), | 27 natural_size_changed_count_(0), |
26 opacity_changed_count_(0), | 28 opacity_changed_count_(0), |
27 opaque_(false) { | 29 opaque_(false) { |
28 compositor_->SetVideoFrameProviderClient(this); | 30 provider()->SetVideoFrameProviderClient(this); |
29 } | 31 } |
30 | 32 |
31 virtual ~VideoFrameCompositorTest() { | 33 virtual ~VideoFrameCompositorTest() { |
32 compositor_->SetVideoFrameProviderClient(NULL); | 34 provider()->SetVideoFrameProviderClient(NULL); |
| 35 compositor_.reset(); |
| 36 message_loop_.RunUntilIdle(); |
33 } | 37 } |
34 | 38 |
| 39 base::MessageLoop* message_loop() { return &message_loop_; } |
35 VideoFrameCompositor* compositor() { return compositor_.get(); } | 40 VideoFrameCompositor* compositor() { return compositor_.get(); } |
| 41 cc::VideoFrameProvider* provider() { |
| 42 return compositor_->GetVideoFrameProvider(); |
| 43 } |
36 int did_receive_frame_count() { return did_receive_frame_count_; } | 44 int did_receive_frame_count() { return did_receive_frame_count_; } |
37 int natural_size_changed_count() { return natural_size_changed_count_; } | 45 int natural_size_changed_count() { return natural_size_changed_count_; } |
38 gfx::Size natural_size() { return natural_size_; } | 46 gfx::Size natural_size() { return natural_size_; } |
39 | 47 |
40 int opacity_changed_count() { return opacity_changed_count_; } | 48 int opacity_changed_count() { return opacity_changed_count_; } |
41 bool opaque() { return opaque_; } | 49 bool opaque() { return opaque_; } |
42 | 50 |
43 private: | 51 private: |
44 // cc::VideoFrameProvider::Client implementation. | 52 // cc::VideoFrameProvider::Client implementation. |
45 virtual void StopUsingProvider() OVERRIDE {} | 53 virtual void StopUsingProvider() OVERRIDE {} |
46 virtual void DidReceiveFrame() OVERRIDE { | 54 virtual void DidReceiveFrame() OVERRIDE { |
47 ++did_receive_frame_count_; | 55 ++did_receive_frame_count_; |
48 } | 56 } |
49 virtual void DidUpdateMatrix(const float* matrix) OVERRIDE {} | 57 virtual void DidUpdateMatrix(const float* matrix) OVERRIDE {} |
50 | 58 |
51 void NaturalSizeChanged(gfx::Size natural_size) { | 59 void NaturalSizeChanged(gfx::Size natural_size) { |
52 ++natural_size_changed_count_; | 60 ++natural_size_changed_count_; |
53 natural_size_ = natural_size; | 61 natural_size_ = natural_size; |
54 } | 62 } |
55 | 63 |
56 void OpacityChanged(bool opaque) { | 64 void OpacityChanged(bool opaque) { |
57 ++opacity_changed_count_; | 65 ++opacity_changed_count_; |
58 opaque_ = opaque; | 66 opaque_ = opaque; |
59 } | 67 } |
60 | 68 |
| 69 base::MessageLoop message_loop_; |
61 scoped_ptr<VideoFrameCompositor> compositor_; | 70 scoped_ptr<VideoFrameCompositor> compositor_; |
62 int did_receive_frame_count_; | 71 int did_receive_frame_count_; |
63 int natural_size_changed_count_; | 72 int natural_size_changed_count_; |
64 gfx::Size natural_size_; | 73 gfx::Size natural_size_; |
65 int opacity_changed_count_; | 74 int opacity_changed_count_; |
66 bool opaque_; | 75 bool opaque_; |
67 | 76 |
68 DISALLOW_COPY_AND_ASSIGN(VideoFrameCompositorTest); | 77 DISALLOW_COPY_AND_ASSIGN(VideoFrameCompositorTest); |
69 }; | 78 }; |
70 | 79 |
71 TEST_F(VideoFrameCompositorTest, InitialValues) { | 80 TEST_F(VideoFrameCompositorTest, InitialValues) { |
| 81 EXPECT_TRUE(compositor()->GetVideoFrameProvider()); |
72 EXPECT_FALSE(compositor()->GetCurrentFrame()); | 82 EXPECT_FALSE(compositor()->GetCurrentFrame()); |
| 83 EXPECT_EQ(0u, compositor()->GetFramesDroppedBeforeCompositorWasNotified()); |
73 } | 84 } |
74 | 85 |
75 TEST_F(VideoFrameCompositorTest, UpdateCurrentFrame) { | 86 TEST_F(VideoFrameCompositorTest, UpdateCurrentFrame) { |
76 scoped_refptr<VideoFrame> expected = VideoFrame::CreateEOSFrame(); | 87 scoped_refptr<VideoFrame> expected = VideoFrame::CreateEOSFrame(); |
77 | 88 |
78 // Should notify compositor synchronously. | |
79 EXPECT_EQ(0, did_receive_frame_count()); | |
80 compositor()->UpdateCurrentFrame(expected); | 89 compositor()->UpdateCurrentFrame(expected); |
81 scoped_refptr<VideoFrame> actual = compositor()->GetCurrentFrame(); | 90 scoped_refptr<VideoFrame> actual = compositor()->GetCurrentFrame(); |
82 EXPECT_EQ(expected, actual); | 91 EXPECT_EQ(expected, actual); |
| 92 |
| 93 // Should notify compositor asynchronously. |
| 94 EXPECT_EQ(0, did_receive_frame_count()); |
| 95 message_loop()->RunUntilIdle(); |
83 EXPECT_EQ(1, did_receive_frame_count()); | 96 EXPECT_EQ(1, did_receive_frame_count()); |
84 } | 97 } |
85 | 98 |
86 TEST_F(VideoFrameCompositorTest, NaturalSizeChanged) { | 99 TEST_F(VideoFrameCompositorTest, NaturalSizeChanged) { |
87 gfx::Size initial_size(8, 8); | 100 gfx::Size initial_size(8, 8); |
88 scoped_refptr<VideoFrame> initial_frame = | 101 scoped_refptr<VideoFrame> initial_frame = |
89 VideoFrame::CreateBlackFrame(initial_size); | 102 VideoFrame::CreateBlackFrame(initial_size); |
90 | 103 |
91 gfx::Size larger_size(16, 16); | 104 gfx::Size larger_size(16, 16); |
92 scoped_refptr<VideoFrame> larger_frame = | 105 scoped_refptr<VideoFrame> larger_frame = |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 compositor()->UpdateCurrentFrame(opaque_frame); | 165 compositor()->UpdateCurrentFrame(opaque_frame); |
153 EXPECT_TRUE(opaque()); | 166 EXPECT_TRUE(opaque()); |
154 EXPECT_EQ(2, opacity_changed_count()); | 167 EXPECT_EQ(2, opacity_changed_count()); |
155 | 168 |
156 // Callback shouldn't be first subsequent times with same opaqueness. | 169 // Callback shouldn't be first subsequent times with same opaqueness. |
157 compositor()->UpdateCurrentFrame(opaque_frame); | 170 compositor()->UpdateCurrentFrame(opaque_frame); |
158 EXPECT_TRUE(opaque()); | 171 EXPECT_TRUE(opaque()); |
159 EXPECT_EQ(2, opacity_changed_count()); | 172 EXPECT_EQ(2, opacity_changed_count()); |
160 } | 173 } |
161 | 174 |
| 175 TEST_F(VideoFrameCompositorTest, GetFramesDroppedBeforeCompositorWasNotified) { |
| 176 scoped_refptr<VideoFrame> frame = VideoFrame::CreateEOSFrame(); |
| 177 |
| 178 compositor()->UpdateCurrentFrame(frame); |
| 179 EXPECT_EQ(0, did_receive_frame_count()); |
| 180 EXPECT_EQ(0u, compositor()->GetFramesDroppedBeforeCompositorWasNotified()); |
| 181 |
| 182 // Should not increment if we finished notifying the compositor. |
| 183 // |
| 184 // This covers the normal scenario where the compositor is getting |
| 185 // notifications in a timely manner. |
| 186 message_loop()->RunUntilIdle(); |
| 187 compositor()->UpdateCurrentFrame(frame); |
| 188 EXPECT_EQ(1, did_receive_frame_count()); |
| 189 EXPECT_EQ(0u, compositor()->GetFramesDroppedBeforeCompositorWasNotified()); |
| 190 |
| 191 // Should increment if we didn't notify the compositor. |
| 192 // |
| 193 // This covers the scenario where the compositor is falling behind. |
| 194 // Consider it dropped. |
| 195 message_loop()->RunUntilIdle(); |
| 196 compositor()->UpdateCurrentFrame(frame); |
| 197 compositor()->UpdateCurrentFrame(frame); |
| 198 EXPECT_EQ(2, did_receive_frame_count()); |
| 199 EXPECT_EQ(1u, compositor()->GetFramesDroppedBeforeCompositorWasNotified()); |
| 200 |
| 201 // Shouldn't overflow. |
| 202 compositor()->SetFramesDroppedBeforeCompositorWasNotifiedForTesting( |
| 203 kuint32max); |
| 204 compositor()->UpdateCurrentFrame(frame); |
| 205 EXPECT_EQ(kuint32max, |
| 206 compositor()->GetFramesDroppedBeforeCompositorWasNotified()); |
| 207 } |
| 208 |
162 } // namespace content | 209 } // namespace content |
OLD | NEW |