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

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: Comments. 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
« no previous file with comments | « media/base/null_video_sink.cc ('k') | media/media.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 scoped_ptr<NullVideoSink> ConstructSink(bool clockless,
35 base::TimeDelta interval) {
36 scoped_ptr<NullVideoSink> new_sink(new NullVideoSink(
37 clockless, interval,
38 base::Bind(&NullVideoSinkTest::FrameReceived, base::Unretained(this)),
39 message_loop_.task_runner()));
40 new_sink->set_tick_clock_for_testing(&tick_clock_);
41 return new_sink;
42 }
43
44 scoped_refptr<VideoFrame> CreateFrame(base::TimeDelta timestamp) {
45 const gfx::Size natural_size(8, 8);
46 return VideoFrame::CreateFrame(VideoFrame::YV12, natural_size,
47 gfx::Rect(natural_size), natural_size,
48 timestamp);
49 }
50
51 // VideoRendererSink::RenderCallback implementation.
52 MOCK_METHOD2(Render,
53 scoped_refptr<VideoFrame>(base::TimeTicks, base::TimeTicks));
54 MOCK_METHOD0(OnFrameDropped, void());
55
56 MOCK_METHOD1(FrameReceived, void(const scoped_refptr<VideoFrame>&));
57
58 protected:
59 base::MessageLoop message_loop_;
60 base::SimpleTestTickClock tick_clock_;
61
62 DISALLOW_COPY_AND_ASSIGN(NullVideoSinkTest);
63 };
64
65 TEST_F(NullVideoSinkTest, BasicFunctionality) {
66 const base::TimeDelta kInterval = base::TimeDelta::FromMilliseconds(25);
67
68 scoped_ptr<NullVideoSink> sink = ConstructSink(false, kInterval);
69 scoped_refptr<VideoFrame> test_frame = CreateFrame(base::TimeDelta());
70
71 // The sink shouldn't have to be started to use the paint method.
72 EXPECT_CALL(*this, FrameReceived(test_frame));
73 sink->PaintFrameUsingOldRenderingPath(test_frame);
74
75 {
76 SCOPED_TRACE("Waiting for sink startup.");
77 sink->Start(this);
78 const base::TimeTicks current_time = tick_clock_.NowTicks();
79 const base::TimeTicks current_interval_end = current_time + kInterval;
80 EXPECT_CALL(*this, Render(current_time, current_interval_end))
81 .WillOnce(Return(test_frame));
82 WaitableMessageLoopEvent event;
83 EXPECT_CALL(*this, FrameReceived(test_frame))
84 .WillOnce(RunClosure(event.GetClosure()));
85 event.RunAndWait();
86 }
87
88 // A second call returning the same frame should not result in a new call to
89 // FrameReceived().
90 {
91 SCOPED_TRACE("Waiting for second render call.");
92 WaitableMessageLoopEvent event;
93 EXPECT_CALL(*this, Render(_, _))
94 .WillOnce(Return(test_frame))
95 .WillOnce(Return(nullptr));
96 EXPECT_CALL(*this, FrameReceived(test_frame)).Times(0);
97 EXPECT_CALL(*this, FrameReceived(scoped_refptr<VideoFrame>()))
98 .WillOnce(RunClosure(event.GetClosure()));
99 event.RunAndWait();
100 }
101
102 {
103 SCOPED_TRACE("Waiting for stop event.");
104 WaitableMessageLoopEvent event;
105 sink->set_stop_cb(event.GetClosure());
106 sink->Stop();
107 event.RunAndWait();
108 }
109 }
110
111 TEST_F(NullVideoSinkTest, ClocklessFunctionality) {
112 // Construct the sink with a huge interval, it should still complete quickly.
113 const base::TimeDelta interval = base::TimeDelta::FromSeconds(10);
114 scoped_ptr<NullVideoSink> sink = ConstructSink(true, interval);
115
116 scoped_refptr<VideoFrame> test_frame = CreateFrame(base::TimeDelta());
117 sink->Start(this);
118
119 EXPECT_CALL(*this, FrameReceived(test_frame)).Times(1);
120 EXPECT_CALL(*this, FrameReceived(scoped_refptr<VideoFrame>())).Times(1);
121
122 const int kTestRuns = 6;
123 const base::TimeTicks now = base::TimeTicks::Now();
124 const base::TimeTicks current_time = tick_clock_.NowTicks();
125
126 // Use a RunLoop instead of WaitableMessageLoopEvent() since it will only quit
127 // the loop when it's idle, instead of quitting immediately which is required
128 // when clockless playback is enabled (otherwise the loop is never idle).
129 base::RunLoop run_loop;
130 for (int i = 0; i < kTestRuns; ++i) {
131 if (i < kTestRuns - 1) {
132 EXPECT_CALL(*this, Render(current_time + i * interval,
133 current_time + (i + 1) * interval))
134 .WillOnce(Return(test_frame));
135 } else {
136 EXPECT_CALL(*this, Render(current_time + i * interval,
137 current_time + (i + 1) * interval))
138 .WillOnce(DoAll(RunClosure(run_loop.QuitClosure()), Return(nullptr)));
139 }
140 }
141
142 run_loop.Run();
143 ASSERT_LT(base::TimeTicks::Now() - now, kTestRuns * interval);
144 sink->Stop();
145 }
146
147 }
OLDNEW
« no previous file with comments | « media/base/null_video_sink.cc ('k') | media/media.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698