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

Side by Side Diff: content/renderer/media/media_stream_video_renderer_sink_unittest.cc

Issue 2472273002: Move passing of WebRTC rendering frames from main thread to compositor thread (Closed)
Patch Set: wez@ nits. Created 4 years, 1 month 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 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/run_loop.h" 7 #include "base/run_loop.h"
8 #include "base/strings/utf_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h"
9 #include "content/child/child_process.h" 9 #include "content/child/child_process.h"
10 #include "content/renderer/media/media_stream_video_renderer_sink.h" 10 #include "content/renderer/media/media_stream_video_renderer_sink.h"
11 #include "content/renderer/media/media_stream_video_track.h"
11 #include "content/renderer/media/mock_media_stream_registry.h" 12 #include "content/renderer/media/mock_media_stream_registry.h"
13 #include "content/renderer/media/mock_media_stream_video_source.h"
12 #include "media/base/video_frame.h" 14 #include "media/base/video_frame.h"
13 #include "media/renderers/gpu_video_accelerator_factories.h" 15 #include "media/renderers/gpu_video_accelerator_factories.h"
14 #include "media/renderers/mock_gpu_memory_buffer_video_frame_pool.h" 16 #include "media/renderers/mock_gpu_memory_buffer_video_frame_pool.h"
15 #include "testing/gmock/include/gmock/gmock.h" 17 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/WebKit/public/platform/WebString.h" 19 #include "third_party/WebKit/public/platform/WebString.h"
18 #include "third_party/WebKit/public/web/WebHeap.h" 20 #include "third_party/WebKit/public/web/WebHeap.h"
19 21
20 using ::testing::_; 22 using ::testing::_;
21 using ::testing::AtLeast; 23 using ::testing::AtLeast;
22 using ::testing::InSequence; 24 using ::testing::InSequence;
23 using ::testing::Lt; 25 using ::testing::Lt;
24 using ::testing::Mock; 26 using ::testing::Mock;
25 27
26 namespace content { 28 namespace content {
27 29
28 ACTION_P(RunClosure, closure) { 30 ACTION_P(RunClosure, closure) {
29 closure.Run(); 31 closure.Run();
30 } 32 }
31 33
32 static const std::string kTestStreamUrl = "stream_url";
33 static const std::string kTestVideoTrackId = "video_track_id";
34
35 class MediaStreamVideoRendererSinkTest : public testing::Test { 34 class MediaStreamVideoRendererSinkTest : public testing::Test {
36 public: 35 public:
37 MediaStreamVideoRendererSinkTest() { 36 MediaStreamVideoRendererSinkTest()
38 registry_.Init(kTestStreamUrl); 37 : child_process_(new ChildProcess()),
39 registry_.AddVideoTrack(kTestVideoTrackId); 38 mock_source_(new MockMediaStreamVideoSource(false)) {
40 39 blink_source_.initialize(base::UTF8ToUTF16("dummy_source_id"),
41 // Extract the Blink Video Track for the MSVRSink. 40 blink::WebMediaStreamSource::TypeVideo,
42 registry_.test_stream().videoTracks(video_tracks_); 41 base::UTF8ToUTF16("dummy_source_name"),
43 EXPECT_EQ(1u, video_tracks_.size()); 42 false /* remote */);
43 blink_source_.setExtraData(mock_source_);
44 blink::WebMediaConstraints constraints;
45 constraints.initialize();
46 blink_track_ = MediaStreamVideoTrack::CreateVideoTrack(
47 mock_source_, constraints, MediaStreamSource::ConstraintsCallback(),
48 true);
49 mock_source_->StartMockedSource();
50 base::RunLoop().RunUntilIdle();
44 51
45 media_stream_video_renderer_sink_ = new MediaStreamVideoRendererSink( 52 media_stream_video_renderer_sink_ = new MediaStreamVideoRendererSink(
46 video_tracks_[0], 53 blink_track_,
47 base::Bind(&MediaStreamVideoRendererSinkTest::ErrorCallback, 54 base::Bind(&MediaStreamVideoRendererSinkTest::ErrorCallback,
48 base::Unretained(this)), 55 base::Unretained(this)),
49 base::Bind(&MediaStreamVideoRendererSinkTest::RepaintCallback, 56 base::Bind(&MediaStreamVideoRendererSinkTest::RepaintCallback,
50 base::Unretained(this)), 57 base::Unretained(this)),
51 message_loop_.task_runner(), message_loop_.task_runner().get(), 58 message_loop_.task_runner(), message_loop_.task_runner(),
52 nullptr /* gpu_factories */); 59 message_loop_.task_runner(), nullptr /* gpu_factories */);
60 base::RunLoop().RunUntilIdle();
53 61
54 EXPECT_TRUE(IsInStoppedState()); 62 EXPECT_TRUE(IsInStoppedState());
55 } 63 }
56 64
57 ~MediaStreamVideoRendererSinkTest() { 65 void TearDown() override {
58 media_stream_video_renderer_sink_ = nullptr; 66 media_stream_video_renderer_sink_ = nullptr;
59 registry_.reset(); 67 blink_source_.reset();
68 blink_track_.reset();
60 blink::WebHeap::collectAllGarbageForTesting(); 69 blink::WebHeap::collectAllGarbageForTesting();
61 70
62 // Let the message loop run to finish destroying the pool. 71 // Let the message loop run to finish destroying the pool.
63 base::RunLoop().RunUntilIdle(); 72 base::RunLoop().RunUntilIdle();
64 } 73 }
65 74
66 MOCK_METHOD1(RepaintCallback, void(const scoped_refptr<media::VideoFrame>&)); 75 MOCK_METHOD1(RepaintCallback, void(scoped_refptr<media::VideoFrame>));
67 MOCK_METHOD0(ErrorCallback, void(void)); 76 MOCK_METHOD0(ErrorCallback, void(void));
68 77
69 bool IsInStartedState() const { 78 bool IsInStartedState() const {
70 return media_stream_video_renderer_sink_->state_ == 79 return media_stream_video_renderer_sink_->GetStateForTesting() ==
71 MediaStreamVideoRendererSink::STARTED; 80 MediaStreamVideoRendererSink::STARTED;
72 } 81 }
73 bool IsInStoppedState() const { 82 bool IsInStoppedState() const {
74 return media_stream_video_renderer_sink_->state_ == 83 return media_stream_video_renderer_sink_->GetStateForTesting() ==
75 MediaStreamVideoRendererSink::STOPPED; 84 MediaStreamVideoRendererSink::STOPPED;
76 } 85 }
77 bool IsInPausedState() const { 86 bool IsInPausedState() const {
78 return media_stream_video_renderer_sink_->state_ == 87 return media_stream_video_renderer_sink_->GetStateForTesting() ==
79 MediaStreamVideoRendererSink::PAUSED; 88 MediaStreamVideoRendererSink::PAUSED;
80 } 89 }
81 90
82 void OnVideoFrame(const scoped_refptr<media::VideoFrame>& frame) { 91 void OnVideoFrame(scoped_refptr<media::VideoFrame> frame) {
83 media_stream_video_renderer_sink_->OnVideoFrame(frame, 92 mock_source_->DeliverVideoFrame(frame);
84 base::TimeTicks::Now()); 93 base::RunLoop().RunUntilIdle();
94
95 // |blink_track_| uses IO thread to send frames to sinks. Make sure that
96 // tasks on IO thread are completed before moving on.
97 base::RunLoop run_loop;
98 child_process_->io_task_runner()->PostTaskAndReply(
99 FROM_HERE, base::Bind([] {}), run_loop.QuitClosure());
100 run_loop.Run();
101 base::RunLoop().RunUntilIdle();
102 }
103
104 void SetGpuMemoryBufferVideoForTesting(
105 media::GpuMemoryBufferVideoFramePool* gpu_memory_buffer_pool) {
106 media_stream_video_renderer_sink_->SetGpuMemoryBufferVideoForTesting(
107 gpu_memory_buffer_pool);
85 } 108 }
86 109
87 scoped_refptr<MediaStreamVideoRendererSink> media_stream_video_renderer_sink_; 110 scoped_refptr<MediaStreamVideoRendererSink> media_stream_video_renderer_sink_;
88 111
112 protected:
89 // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks 113 // A ChildProcess and a MessageLoopForUI are both needed to fool the Tracks
90 // and Sources in |registry_| into believing they are on the right threads. 114 // and Sources in |registry_| into believing they are on the right threads.
91 base::MessageLoopForUI message_loop_; 115 base::MessageLoopForUI message_loop_;
92 const ChildProcess child_process_; 116 const std::unique_ptr<ChildProcess> child_process_;
93 117
94 blink::WebVector<blink::WebMediaStreamTrack> video_tracks_; 118 blink::WebMediaStreamTrack blink_track_;
95 MockMediaStreamRegistry registry_;
96 119
97 private: 120 private:
121 blink::WebMediaStreamSource blink_source_;
122 MockMediaStreamVideoSource* mock_source_;
123
98 DISALLOW_COPY_AND_ASSIGN(MediaStreamVideoRendererSinkTest); 124 DISALLOW_COPY_AND_ASSIGN(MediaStreamVideoRendererSinkTest);
99 }; 125 };
100 126
101 // Checks that the initialization-destruction sequence works fine. 127 // Checks that the initialization-destruction sequence works fine.
102 TEST_F(MediaStreamVideoRendererSinkTest, StartStop) { 128 TEST_F(MediaStreamVideoRendererSinkTest, StartStop) {
103 EXPECT_TRUE(IsInStoppedState()); 129 EXPECT_TRUE(IsInStoppedState());
104 130
105 media_stream_video_renderer_sink_->Start(); 131 media_stream_video_renderer_sink_->Start();
132 base::RunLoop().RunUntilIdle();
106 EXPECT_TRUE(IsInStartedState()); 133 EXPECT_TRUE(IsInStartedState());
107 134
108 media_stream_video_renderer_sink_->Pause(); 135 media_stream_video_renderer_sink_->Pause();
136 base::RunLoop().RunUntilIdle();
109 EXPECT_TRUE(IsInPausedState()); 137 EXPECT_TRUE(IsInPausedState());
110 138
111 media_stream_video_renderer_sink_->Resume(); 139 media_stream_video_renderer_sink_->Resume();
140 base::RunLoop().RunUntilIdle();
112 EXPECT_TRUE(IsInStartedState()); 141 EXPECT_TRUE(IsInStartedState());
113 142
114 media_stream_video_renderer_sink_->Stop(); 143 media_stream_video_renderer_sink_->Stop();
144 base::RunLoop().RunUntilIdle();
115 EXPECT_TRUE(IsInStoppedState()); 145 EXPECT_TRUE(IsInStoppedState());
116 } 146 }
117 147
118 // Sends 2 frames and expect them as WebM contained encoded data in writeData(). 148 // Sends 2 frames and expect them as WebM contained encoded data in writeData().
119 TEST_F(MediaStreamVideoRendererSinkTest, EncodeVideoFrames) { 149 TEST_F(MediaStreamVideoRendererSinkTest, EncodeVideoFrames) {
120 media_stream_video_renderer_sink_->Start(); 150 media_stream_video_renderer_sink_->Start();
121 151
122 InSequence s; 152 InSequence s;
123 const scoped_refptr<media::VideoFrame> video_frame = 153 const scoped_refptr<media::VideoFrame> video_frame =
124 media::VideoFrame::CreateBlackFrame(gfx::Size(160, 80)); 154 media::VideoFrame::CreateBlackFrame(gfx::Size(160, 80));
125 155
126 EXPECT_CALL(*this, RepaintCallback(video_frame)).Times(1); 156 EXPECT_CALL(*this, RepaintCallback(video_frame)).Times(1);
127 OnVideoFrame(video_frame); 157 OnVideoFrame(video_frame);
128 158
129 media_stream_video_renderer_sink_->Stop(); 159 media_stream_video_renderer_sink_->Stop();
130 } 160 }
131 161
132 class MediaStreamVideoRendererSinkAsyncAddFrameReadyTest 162 class MediaStreamVideoRendererSinkAsyncAddFrameReadyTest
133 : public MediaStreamVideoRendererSinkTest { 163 : public MediaStreamVideoRendererSinkTest {
134 public: 164 public:
135 MediaStreamVideoRendererSinkAsyncAddFrameReadyTest() { 165 MediaStreamVideoRendererSinkAsyncAddFrameReadyTest() {
136 media_stream_video_renderer_sink_->SetGpuMemoryBufferVideoForTesting( 166 media_stream_video_renderer_sink_->Start();
167 SetGpuMemoryBufferVideoForTesting(
137 new media::MockGpuMemoryBufferVideoFramePool(&frame_ready_cbs_)); 168 new media::MockGpuMemoryBufferVideoFramePool(&frame_ready_cbs_));
169 base::RunLoop().RunUntilIdle();
138 } 170 }
139 171
140 protected: 172 protected:
141 std::vector<base::Closure> frame_ready_cbs_; 173 std::vector<base::Closure> frame_ready_cbs_;
142 }; 174 };
143 175
144 TEST_F(MediaStreamVideoRendererSinkAsyncAddFrameReadyTest, 176 TEST_F(MediaStreamVideoRendererSinkAsyncAddFrameReadyTest,
145 CreateHardwareFrames) { 177 CreateHardwareFrames) {
146 media_stream_video_renderer_sink_->Start();
147
148 InSequence s; 178 InSequence s;
149 const scoped_refptr<media::VideoFrame> video_frame = 179 const scoped_refptr<media::VideoFrame> video_frame =
150 media::VideoFrame::CreateBlackFrame(gfx::Size(160, 80)); 180 media::VideoFrame::CreateBlackFrame(gfx::Size(160, 80));
151 OnVideoFrame(video_frame); 181 OnVideoFrame(video_frame);
152 base::RunLoop().RunUntilIdle();
153 ASSERT_EQ(1u, frame_ready_cbs_.size()); 182 ASSERT_EQ(1u, frame_ready_cbs_.size());
154 183
155 EXPECT_CALL(*this, RepaintCallback(video_frame)).Times(1); 184 EXPECT_CALL(*this, RepaintCallback(video_frame)).Times(1);
156 frame_ready_cbs_[0].Run(); 185 frame_ready_cbs_[0].Run();
157 base::RunLoop().RunUntilIdle(); 186 base::RunLoop().RunUntilIdle();
158 187
159 media_stream_video_renderer_sink_->Stop(); 188 media_stream_video_renderer_sink_->Stop();
160 } 189 }
161 190
162 class MediaStreamVideoRendererSinkTransparencyTest 191 class MediaStreamVideoRendererSinkTransparencyTest
163 : public MediaStreamVideoRendererSinkTest { 192 : public MediaStreamVideoRendererSinkTest {
164 public: 193 public:
165 MediaStreamVideoRendererSinkTransparencyTest() { 194 MediaStreamVideoRendererSinkTransparencyTest() {
166 media_stream_video_renderer_sink_ = new MediaStreamVideoRendererSink( 195 media_stream_video_renderer_sink_ = new MediaStreamVideoRendererSink(
167 video_tracks_[0], 196 blink_track_,
168 base::Bind(&MediaStreamVideoRendererSinkTest::ErrorCallback, 197 base::Bind(&MediaStreamVideoRendererSinkTest::ErrorCallback,
169 base::Unretained(this)), 198 base::Unretained(this)),
170 base::Bind(&MediaStreamVideoRendererSinkTransparencyTest:: 199 base::Bind(&MediaStreamVideoRendererSinkTransparencyTest::
171 VerifyTransparentFrame, 200 VerifyTransparentFrame,
172 base::Unretained(this)), 201 base::Unretained(this)),
173 message_loop_.task_runner(), message_loop_.task_runner().get(), 202 message_loop_.task_runner(), message_loop_.task_runner(),
174 nullptr /* gpu_factories */); 203 message_loop_.task_runner(), nullptr /* gpu_factories */);
175 } 204 }
176 205
177 void VerifyTransparentFrame(const scoped_refptr<media::VideoFrame>& frame) { 206 void VerifyTransparentFrame(scoped_refptr<media::VideoFrame> frame) {
178 EXPECT_EQ(media::PIXEL_FORMAT_YV12A, frame->format()); 207 EXPECT_EQ(media::PIXEL_FORMAT_YV12A, frame->format());
179 } 208 }
180 }; 209 };
181 210
182 TEST_F(MediaStreamVideoRendererSinkTransparencyTest, 211 TEST_F(MediaStreamVideoRendererSinkTransparencyTest,
183 SendTransparentFrame) { 212 SendTransparentFrame) {
184 media_stream_video_renderer_sink_->Start(); 213 media_stream_video_renderer_sink_->Start();
185 214
186 InSequence s; 215 InSequence s;
187 const gfx::Size kSize(10, 10); 216 const gfx::Size kSize(10, 10);
188 const base::TimeDelta kTimestamp = base::TimeDelta(); 217 const base::TimeDelta kTimestamp = base::TimeDelta();
189 const scoped_refptr<media::VideoFrame> video_frame = 218 const scoped_refptr<media::VideoFrame> video_frame =
190 media::VideoFrame::CreateFrame(media::PIXEL_FORMAT_YV12A, kSize, 219 media::VideoFrame::CreateFrame(media::PIXEL_FORMAT_YV12A, kSize,
191 gfx::Rect(kSize), kSize, kTimestamp); 220 gfx::Rect(kSize), kSize, kTimestamp);
192 OnVideoFrame(video_frame); 221 OnVideoFrame(video_frame);
193 base::RunLoop().RunUntilIdle(); 222 base::RunLoop().RunUntilIdle();
194 223
195 media_stream_video_renderer_sink_->Stop(); 224 media_stream_video_renderer_sink_->Stop();
196 } 225 }
197 226
198 } // namespace content 227 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698