OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/common/child_process.h" | 6 #include "content/common/child_process.h" |
7 #include "content/renderer/media/capture_video_decoder.h" | 7 #include "content/renderer/media/capture_video_decoder.h" |
8 #include "content/renderer/media/video_capture_impl.h" | 8 #include "content/renderer/media/video_capture_impl.h" |
9 #include "content/renderer/media/video_capture_impl_manager.h" | 9 #include "content/renderer/media/video_capture_impl_manager.h" |
10 #include "media/base/limits.h" | 10 #include "media/base/limits.h" |
11 #include "media/base/mock_callback.h" | 11 #include "media/base/mock_callback.h" |
12 #include "media/base/mock_filters.h" | 12 #include "media/base/mock_filters.h" |
13 #include "media/base/pipeline_status.h" | 13 #include "media/base/pipeline_status.h" |
14 #include "media/video/capture/video_capture_types.h" | 14 #include "media/video/capture/video_capture_types.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
16 | 16 |
17 using ::testing::_; | 17 using ::testing::_; |
18 using ::testing::AnyNumber; | 18 using ::testing::AnyNumber; |
19 using ::testing::Return; | 19 using ::testing::Return; |
20 using ::testing::StrictMock; | 20 using ::testing::StrictMock; |
21 | 21 |
22 static const int kWidth = 176; | 22 static const int kWidth = 176; |
23 static const int kHeight = 144; | 23 static const int kHeight = 144; |
24 static const int kFPS = 30; | 24 static const int kFPS = 30; |
25 static const media::VideoCaptureSessionId kVideoStreamId = 1; | 25 static const media::VideoCaptureSessionId kVideoStreamId = 1; |
26 | 26 |
27 ACTION_P3(CreateDataBufferFromCapture, decoder, vc_impl, data_buffer_number) { | |
28 for (int i = 0; i < data_buffer_number; i++) { | |
29 media::VideoCapture::VideoFrameBuffer* buffer; | |
30 buffer = new media::VideoCapture::VideoFrameBuffer(); | |
31 buffer->width = arg1.width; | |
32 buffer->height = arg1.height; | |
33 int length = buffer->width * buffer->height * 3 / 2; | |
34 buffer->memory_pointer = new uint8[length]; | |
35 buffer->buffer_size = length; | |
36 decoder->OnBufferReady(vc_impl, buffer); | |
37 } | |
38 } | |
39 | |
40 ACTION(DeleteDataBuffer) { | 27 ACTION(DeleteDataBuffer) { |
41 delete[] arg0->memory_pointer; | 28 delete[] arg0->memory_pointer; |
42 } | 29 } |
43 | 30 |
44 ACTION_P2(CaptureStopped, decoder, vc_impl) { | 31 ACTION_P2(CaptureStopped, decoder, vc_impl) { |
45 decoder->OnStopped(vc_impl); | 32 decoder->OnStopped(vc_impl); |
46 } | 33 } |
47 | 34 |
| 35 MATCHER_P2(HasSize, width, height, "") { |
| 36 EXPECT_EQ(arg->data_size().width(), width); |
| 37 EXPECT_EQ(arg->data_size().height(), height); |
| 38 EXPECT_EQ(arg->natural_size().width(), width); |
| 39 EXPECT_EQ(arg->natural_size().height(), height); |
| 40 return (arg->data_size().width() == width) && |
| 41 (arg->data_size().height() == height) && |
| 42 (arg->natural_size().width() == width) && |
| 43 (arg->natural_size().height() == height); |
| 44 } |
| 45 |
48 class MockVideoCaptureImpl : public VideoCaptureImpl { | 46 class MockVideoCaptureImpl : public VideoCaptureImpl { |
49 public: | 47 public: |
50 MockVideoCaptureImpl(const media::VideoCaptureSessionId id, | 48 MockVideoCaptureImpl(const media::VideoCaptureSessionId id, |
51 scoped_refptr<base::MessageLoopProxy> ml_proxy, | 49 scoped_refptr<base::MessageLoopProxy> ml_proxy, |
52 VideoCaptureMessageFilter* filter) | 50 VideoCaptureMessageFilter* filter) |
53 : VideoCaptureImpl(id, ml_proxy, filter) { | 51 : VideoCaptureImpl(id, ml_proxy, filter) { |
54 } | 52 } |
55 | 53 |
56 MOCK_METHOD2(StartCapture, | 54 MOCK_METHOD2(StartCapture, |
57 void(media::VideoCapture::EventHandler* handler, | 55 void(media::VideoCapture::EventHandler* handler, |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 virtual ~CaptureVideoDecoderTest() { | 110 virtual ~CaptureVideoDecoderTest() { |
113 message_loop_->RunAllPending(); | 111 message_loop_->RunAllPending(); |
114 } | 112 } |
115 | 113 |
116 media::StatisticsCB NewStatisticsCB() { | 114 media::StatisticsCB NewStatisticsCB() { |
117 return base::Bind(&media::MockStatisticsCB::OnStatistics, | 115 return base::Bind(&media::MockStatisticsCB::OnStatistics, |
118 base::Unretained(&statistics_cb_object_)); | 116 base::Unretained(&statistics_cb_object_)); |
119 } | 117 } |
120 | 118 |
121 void Initialize() { | 119 void Initialize() { |
122 // Issue a read. | |
123 EXPECT_CALL(*this, FrameReady(media::VideoDecoder::kOk, _)); | |
124 decoder_->Read(read_cb_); | |
125 | |
126 EXPECT_CALL(*vc_manager_, AddDevice(_, _)) | 120 EXPECT_CALL(*vc_manager_, AddDevice(_, _)) |
127 .WillOnce(Return(vc_impl_.get())); | 121 .WillOnce(Return(vc_impl_.get())); |
128 int buffer_count = 1; | 122 EXPECT_CALL(*vc_impl_, StartCapture(capture_client(), _)); |
129 EXPECT_CALL(*vc_impl_, StartCapture(capture_client(), _)) | |
130 .Times(1) | |
131 .WillOnce(CreateDataBufferFromCapture(capture_client(), | |
132 vc_impl_.get(), | |
133 buffer_count)); | |
134 EXPECT_CALL(*vc_impl_, FeedBuffer(_)) | |
135 .Times(buffer_count) | |
136 .WillRepeatedly(DeleteDataBuffer()); | |
137 | |
138 decoder_->Initialize(NULL, | 123 decoder_->Initialize(NULL, |
139 media::NewExpectedStatusCB(media::PIPELINE_OK), | 124 media::NewExpectedStatusCB(media::PIPELINE_OK), |
140 NewStatisticsCB()); | 125 NewStatisticsCB()); |
| 126 |
| 127 EXPECT_CALL(*this, FrameReady(media::VideoDecoder::kOk, |
| 128 HasSize(kWidth, kHeight))); |
| 129 decoder_->Read(read_cb_); |
| 130 SendBufferToDecoder(gfx::Size(kWidth, kHeight)); |
141 message_loop_->RunAllPending(); | 131 message_loop_->RunAllPending(); |
142 } | 132 } |
143 | 133 |
144 void Stop() { | 134 void Stop() { |
145 EXPECT_CALL(*vc_impl_, StopCapture(capture_client())) | 135 EXPECT_CALL(*vc_impl_, StopCapture(capture_client())) |
146 .Times(1) | 136 .Times(1) |
147 .WillOnce(CaptureStopped(capture_client(), vc_impl_.get())); | 137 .WillOnce(CaptureStopped(capture_client(), vc_impl_.get())); |
148 EXPECT_CALL(*vc_manager_, RemoveDevice(_, _)) | 138 EXPECT_CALL(*vc_manager_, RemoveDevice(_, _)) |
149 .WillOnce(Return()); | 139 .WillOnce(Return()); |
150 decoder_->Stop(media::NewExpectedClosure()); | 140 decoder_->Stop(media::NewExpectedClosure()); |
151 message_loop_->RunAllPending(); | 141 message_loop_->RunAllPending(); |
152 } | 142 } |
153 | 143 |
154 media::VideoCapture::EventHandler* capture_client() { | 144 media::VideoCapture::EventHandler* capture_client() { |
155 return static_cast<media::VideoCapture::EventHandler*>(decoder_); | 145 return static_cast<media::VideoCapture::EventHandler*>(decoder_); |
156 } | 146 } |
157 | 147 |
| 148 void SendBufferToDecoder(const gfx::Size& size) { |
| 149 scoped_refptr<media::VideoCapture::VideoFrameBuffer> buffer = |
| 150 new media::VideoCapture::VideoFrameBuffer(); |
| 151 buffer->width = size.width(); |
| 152 buffer->height = size.height(); |
| 153 int length = buffer->width * buffer->height * 3 / 2; |
| 154 buffer->memory_pointer = new uint8[length]; |
| 155 buffer->buffer_size = length; |
| 156 |
| 157 EXPECT_CALL(*vc_impl_, FeedBuffer(_)) |
| 158 .WillOnce(DeleteDataBuffer()); |
| 159 decoder_->OnBufferReady(vc_impl_.get(), buffer); |
| 160 } |
| 161 |
158 MOCK_METHOD2(FrameReady, void(media::VideoDecoder::DecoderStatus status, | 162 MOCK_METHOD2(FrameReady, void(media::VideoDecoder::DecoderStatus status, |
159 const scoped_refptr<media::VideoFrame>&)); | 163 const scoped_refptr<media::VideoFrame>&)); |
160 | 164 |
161 // Fixture members. | 165 // Fixture members. |
162 scoped_refptr<CaptureVideoDecoder> decoder_; | 166 scoped_refptr<CaptureVideoDecoder> decoder_; |
163 scoped_refptr<MockVideoCaptureImplManager> vc_manager_; | 167 scoped_refptr<MockVideoCaptureImplManager> vc_manager_; |
164 scoped_ptr<ChildProcess> child_process_; | 168 scoped_ptr<ChildProcess> child_process_; |
165 scoped_ptr<MockVideoCaptureImpl> vc_impl_; | 169 scoped_ptr<MockVideoCaptureImpl> vc_impl_; |
166 media::MockStatisticsCB statistics_cb_object_; | 170 media::MockStatisticsCB statistics_cb_object_; |
167 scoped_ptr<MessageLoop> message_loop_; | 171 scoped_ptr<MessageLoop> message_loop_; |
168 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; | 172 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; |
169 media::VideoDecoder::ReadCB read_cb_; | 173 media::VideoDecoder::ReadCB read_cb_; |
170 | 174 |
171 private: | 175 private: |
172 DISALLOW_COPY_AND_ASSIGN(CaptureVideoDecoderTest); | 176 DISALLOW_COPY_AND_ASSIGN(CaptureVideoDecoderTest); |
173 }; | 177 }; |
174 | 178 |
175 TEST_F(CaptureVideoDecoderTest, ReadAndReset) { | 179 TEST_F(CaptureVideoDecoderTest, ReadAndReset) { |
176 // Test basic initialize and teardown sequence. | 180 // Test basic initialize and teardown sequence. |
177 Initialize(); | 181 Initialize(); |
178 // Natural size should be initialized to default capability. | 182 EXPECT_CALL(*this, FrameReady(media::VideoDecoder::kOk, |
179 EXPECT_EQ(kWidth, decoder_->natural_size().width()); | 183 HasSize(kWidth, kHeight))); |
180 EXPECT_EQ(kHeight, decoder_->natural_size().height()); | |
181 | |
182 EXPECT_CALL(*this, FrameReady(media::VideoDecoder::kOk, _)); | |
183 decoder_->Read(read_cb_); | 184 decoder_->Read(read_cb_); |
184 decoder_->Reset(media::NewExpectedClosure()); | 185 decoder_->Reset(media::NewExpectedClosure()); |
185 message_loop_->RunAllPending(); | 186 message_loop_->RunAllPending(); |
186 | 187 |
187 Stop(); | 188 Stop(); |
188 } | 189 } |
189 | 190 |
190 TEST_F(CaptureVideoDecoderTest, OnDeviceInfoReceived) { | 191 TEST_F(CaptureVideoDecoderTest, OnDeviceInfoReceived) { |
191 // Test that natural size gets updated as device information is sent. | 192 // Test that natural size gets updated as device information is sent. |
192 Initialize(); | 193 Initialize(); |
193 | 194 |
194 gfx::Size expected_size(kWidth * 2, kHeight * 2); | 195 gfx::Size expected_size(kWidth * 2, kHeight * 2); |
195 | 196 |
196 media::VideoCaptureParams params; | 197 media::VideoCaptureParams params; |
197 params.width = expected_size.width(); | 198 params.width = expected_size.width(); |
198 params.height = expected_size.height(); | 199 params.height = expected_size.height(); |
199 params.frame_per_second = kFPS; | 200 params.frame_per_second = kFPS; |
200 params.session_id = kVideoStreamId; | 201 params.session_id = kVideoStreamId; |
201 | 202 |
202 decoder_->OnDeviceInfoReceived(vc_impl_.get(), params); | 203 decoder_->OnDeviceInfoReceived(vc_impl_.get(), params); |
| 204 |
| 205 EXPECT_CALL(*this, FrameReady(media::VideoDecoder::kOk, |
| 206 HasSize(expected_size.width(), |
| 207 expected_size.height()))); |
| 208 decoder_->Read(read_cb_); |
| 209 SendBufferToDecoder(expected_size); |
203 message_loop_->RunAllPending(); | 210 message_loop_->RunAllPending(); |
204 | 211 |
205 EXPECT_EQ(expected_size.width(), decoder_->natural_size().width()); | |
206 EXPECT_EQ(expected_size.height(), decoder_->natural_size().height()); | |
207 | |
208 Stop(); | 212 Stop(); |
209 } | 213 } |
210 | 214 |
211 TEST_F(CaptureVideoDecoderTest, ReadAndShutdown) { | 215 TEST_F(CaptureVideoDecoderTest, ReadAndShutdown) { |
212 // Test all the Read requests can be fullfilled (which is needed in order to | 216 // Test all the Read requests can be fullfilled (which is needed in order to |
213 // teardown the pipeline) even when there's no input frame. | 217 // teardown the pipeline) even when there's no input frame. |
214 Initialize(); | 218 Initialize(); |
215 | 219 |
216 EXPECT_CALL(*this, FrameReady(media::VideoDecoder::kOk, _)).Times(2); | 220 EXPECT_CALL(*this, FrameReady(media::VideoDecoder::kOk, |
| 221 HasSize(0, 0))).Times(2); |
217 decoder_->Read(read_cb_); | 222 decoder_->Read(read_cb_); |
218 decoder_->PrepareForShutdownHack(); | 223 decoder_->PrepareForShutdownHack(); |
219 decoder_->Read(read_cb_); | 224 decoder_->Read(read_cb_); |
220 message_loop_->RunAllPending(); | 225 message_loop_->RunAllPending(); |
221 | 226 |
222 Stop(); | 227 Stop(); |
223 } | 228 } |
224 | |
OLD | NEW |