Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: media/base/null_video_sink_unittest.cc

Issue 1116473002: Introduce NullVideoSink for test classes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/bind.h"
6 #include "base/callback_helpers.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/run_loop.h"
9 #include "base/test/simple_test_tick_clock.h"
10 #include "media/base/null_video_sink.h"
11 #include "media/base/test_helpers.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 using testing::_;
16 using testing::DoAll;
17 using testing::Return;
18
19 namespace media {
20
21 ACTION_P(RunClosure, closure) {
22 closure.Run();
23 }
24
25 class NullVideoSinkTest : public testing::Test,
26 public VideoRendererSink::RenderCallback {
27 public:
28 NullVideoSinkTest() {
29 // Never use null TimeTicks since they have special connotations.
30 tick_clock_.Advance(base::TimeDelta::FromMicroseconds(12345));
31 }
32 ~NullVideoSinkTest() override {}
33
34 base::TimeDelta default_interval() const {
35 return base::TimeDelta::FromMilliseconds(25);
36 }
37
38 base::TimeTicks current_time() {
39 return tick_clock_.NowTicks();
40 }
41
42 base::TimeTicks current_interval_end() {
43 return tick_clock_.NowTicks() + default_interval();
44 }
xhwang 2015/04/28 23:12:07 style nit: These are not getters and should use no
DaleCurtis 2015/04/29 00:54:07 Removed since they were only in one test.
45
46 scoped_ptr<NullVideoSink> ConstructSink(bool clockless,
47 base::TimeDelta interval) {
48 scoped_ptr<NullVideoSink> new_sink(new NullVideoSink(
49 clockless, interval,
50 base::Bind(&NullVideoSinkTest::FrameReceived, base::Unretained(this)),
51 message_loop_.task_runner()));
52 new_sink->set_tick_clock_for_testing(&tick_clock_);
53 return new_sink;
xhwang 2015/04/28 23:12:06 .Pass()?
DaleCurtis 2015/04/29 00:54:07 Not necessary in this case, it's automatically mov
xhwang 2015/04/29 03:49:13 Cool. TIL!
54 }
55
56 scoped_refptr<VideoFrame> CreateFrame(base::TimeDelta timestamp) {
57 const gfx::Size natural_size(8, 8);
58 return VideoFrame::CreateFrame(VideoFrame::YV12, natural_size,
59 gfx::Rect(natural_size), natural_size,
60 timestamp);
61 }
62
63 // VideoRendererSink::RenderCallback implementation.
64 MOCK_METHOD2(Render,
65 scoped_refptr<VideoFrame>(base::TimeTicks, base::TimeTicks));
66 MOCK_METHOD0(OnFrameDropped, void());
67
68 MOCK_METHOD1(FrameReceived, void(const scoped_refptr<VideoFrame>&));
69
70 protected:
71 base::MessageLoop message_loop_;
72 base::SimpleTestTickClock tick_clock_;
73
74 DISALLOW_COPY_AND_ASSIGN(NullVideoSinkTest);
75 };
76
77
78 TEST_F(NullVideoSinkTest, BasicFunctionality) {
79 scoped_ptr<NullVideoSink> sink = ConstructSink(false, default_interval());
80 scoped_refptr<VideoFrame> test_frame = CreateFrame(base::TimeDelta());
81
82 // The sink shouldn't have to be started to use the paint method.
83 EXPECT_CALL(*this, FrameReceived(test_frame));
84 sink->PaintFrameUsingOldRenderingPath(test_frame);
85
86 {
87 SCOPED_TRACE("Waiting for sink startup.");
88 sink->Start(this);
89 EXPECT_CALL(*this, Render(current_time(), current_interval_end()))
90 .WillOnce(Return(test_frame));
91 base::RunLoop run_loop;
92 EXPECT_CALL(*this, FrameReceived(test_frame))
93 .WillOnce(RunClosure(run_loop.QuitClosure()));
94 run_loop.Run();
95 }
96
97 // A second call returning the same frame should not result in a new call to
98 // FrameReceived().
99 {
100 SCOPED_TRACE("Waiting for second render call.");
101 WaitableMessageLoopEvent event;
102 EXPECT_CALL(*this, Render(_, _))
103 .WillOnce(Return(test_frame))
104 .WillOnce(Return(nullptr));
105 EXPECT_CALL(*this, FrameReceived(test_frame)).Times(0);
106 EXPECT_CALL(*this, FrameReceived(scoped_refptr<VideoFrame>()))
107 .WillOnce(RunClosure(event.GetClosure()));
108 event.RunAndWait();
109 }
110
111 {
112 SCOPED_TRACE("Waiting for stop event.");
113 WaitableMessageLoopEvent event;
114 sink->set_stop_callback(event.GetClosure());
115 sink->Stop();
116 event.RunAndWait();
117 }
118 }
119
120 TEST_F(NullVideoSinkTest, ClocklessFunctionality) {
121 // Construct the sink with a huge interval, it should still complete quickly.
122 const base::TimeDelta interval = base::TimeDelta::FromSeconds(10);
123 scoped_ptr<NullVideoSink> sink = ConstructSink(true, interval);
124
125 scoped_refptr<VideoFrame> test_frame = CreateFrame(base::TimeDelta());
126 sink->Start(this);
127
128 EXPECT_CALL(*this, FrameReceived(test_frame)).Times(1);
129 EXPECT_CALL(*this, FrameReceived(scoped_refptr<VideoFrame>())).Times(1);
130
131 const int kTestRuns = 6;
132 const base::TimeTicks now = base::TimeTicks::Now();
133 const base::TimeTicks current_time = tick_clock_.NowTicks();
134
135 // Use a RunLoop instead of WaitableMessageLoopEvent() since it will only quit
136 // the loop when it's idle, instead of quitting immediately which is required
137 // when clockless playback is enabled (otherwise the loop is never idle).
138 base::RunLoop run_loop;
139 for (int i = 0; i < kTestRuns; ++i) {
140 if (i < kTestRuns - 1) {
141 EXPECT_CALL(*this, Render(current_time + i * interval,
142 current_time + (i + 1) * interval))
143 .WillOnce(Return(test_frame));
144 } else {
145 EXPECT_CALL(*this, Render(current_time + i * interval,
146 current_time + (i + 1) * interval))
147 .WillOnce(DoAll(RunClosure(run_loop.QuitClosure()), Return(nullptr)));
148 }
149 }
150
151 run_loop.Run();
152 ASSERT_LT(base::TimeTicks::Now() - now, kTestRuns * interval);
153 sink->Stop();
154 }
155
xhwang 2015/04/28 23:12:06 Is it interesting to test the case where Render()
DaleCurtis 2015/04/29 00:54:07 Not particularly in this case, it was more importa
xhwang 2015/04/29 03:49:13 Can you just call tick_clock_.Advance() in Render(
156 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698