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 <map> | 5 #include <map> |
6 #include <string> | 6 #include <string> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 public: | 99 public: |
100 MockVideoCaptureHost(MediaStreamManager* manager) | 100 MockVideoCaptureHost(MediaStreamManager* manager) |
101 : VideoCaptureHost(manager), | 101 : VideoCaptureHost(manager), |
102 return_buffers_(false), | 102 return_buffers_(false), |
103 dump_video_(false) {} | 103 dump_video_(false) {} |
104 | 104 |
105 // A list of mock methods. | 105 // A list of mock methods. |
106 MOCK_METHOD4(OnNewBufferCreated, | 106 MOCK_METHOD4(OnNewBufferCreated, |
107 void(int device_id, base::SharedMemoryHandle handle, | 107 void(int device_id, base::SharedMemoryHandle handle, |
108 int length, int buffer_id)); | 108 int length, int buffer_id)); |
109 MOCK_METHOD3(OnBufferFilled, | 109 MOCK_METHOD2(OnBufferFreed, |
110 void(int device_id, int buffer_id, base::Time timestamp)); | 110 void(int device_id, int buffer_id)); |
| 111 MOCK_METHOD4(OnBufferFilled, |
| 112 void(int device_id, int buffer_id, base::Time timestamp, |
| 113 const media::VideoCaptureFormat& format)); |
111 MOCK_METHOD2(OnStateChanged, void(int device_id, VideoCaptureState state)); | 114 MOCK_METHOD2(OnStateChanged, void(int device_id, VideoCaptureState state)); |
112 MOCK_METHOD1(OnDeviceInfo, void(int device_id)); | |
113 | 115 |
114 // Use class DumpVideo to write I420 video to file. | 116 // Use class DumpVideo to write I420 video to file. |
115 void SetDumpVideo(bool enable) { | 117 void SetDumpVideo(bool enable) { |
116 dump_video_ = enable; | 118 dump_video_ = enable; |
117 } | 119 } |
118 | 120 |
119 void SetReturnReceviedDibs(bool enable) { | 121 void SetReturnReceivedDibs(bool enable) { |
120 return_buffers_ = enable; | 122 return_buffers_ = enable; |
121 } | 123 } |
122 | 124 |
123 // Return Dibs we currently have received. | 125 // Return Dibs we currently have received. |
124 void ReturnReceivedDibs(int device_id) { | 126 void ReturnReceivedDibs(int device_id) { |
125 int handle = GetReceivedDib(); | 127 int handle = GetReceivedDib(); |
126 while (handle) { | 128 while (handle) { |
127 this->OnReceiveEmptyBuffer(device_id, handle); | 129 this->OnReceiveEmptyBuffer(device_id, handle); |
128 handle = GetReceivedDib(); | 130 handle = GetReceivedDib(); |
129 } | 131 } |
(...skipping 20 matching lines...) Expand all Loading... |
150 // these messages here and dispatch to our mock methods to verify the | 152 // these messages here and dispatch to our mock methods to verify the |
151 // conversation between this object and the renderer. | 153 // conversation between this object and the renderer. |
152 virtual bool Send(IPC::Message* message) OVERRIDE { | 154 virtual bool Send(IPC::Message* message) OVERRIDE { |
153 CHECK(message); | 155 CHECK(message); |
154 | 156 |
155 // In this method we dispatch the messages to the according handlers as if | 157 // In this method we dispatch the messages to the according handlers as if |
156 // we are the renderer. | 158 // we are the renderer. |
157 bool handled = true; | 159 bool handled = true; |
158 IPC_BEGIN_MESSAGE_MAP(MockVideoCaptureHost, *message) | 160 IPC_BEGIN_MESSAGE_MAP(MockVideoCaptureHost, *message) |
159 IPC_MESSAGE_HANDLER(VideoCaptureMsg_NewBuffer, OnNewBufferCreatedDispatch) | 161 IPC_MESSAGE_HANDLER(VideoCaptureMsg_NewBuffer, OnNewBufferCreatedDispatch) |
| 162 IPC_MESSAGE_HANDLER(VideoCaptureMsg_FreeBuffer, OnBufferFreedDispatch) |
160 IPC_MESSAGE_HANDLER(VideoCaptureMsg_BufferReady, OnBufferFilledDispatch) | 163 IPC_MESSAGE_HANDLER(VideoCaptureMsg_BufferReady, OnBufferFilledDispatch) |
161 IPC_MESSAGE_HANDLER(VideoCaptureMsg_StateChanged, OnStateChangedDispatch) | 164 IPC_MESSAGE_HANDLER(VideoCaptureMsg_StateChanged, OnStateChangedDispatch) |
162 IPC_MESSAGE_HANDLER(VideoCaptureMsg_DeviceInfo, OnDeviceInfoDispatch) | |
163 IPC_MESSAGE_UNHANDLED(handled = false) | 165 IPC_MESSAGE_UNHANDLED(handled = false) |
164 IPC_END_MESSAGE_MAP() | 166 IPC_END_MESSAGE_MAP() |
165 EXPECT_TRUE(handled); | 167 EXPECT_TRUE(handled); |
166 | 168 |
167 delete message; | 169 delete message; |
168 return true; | 170 return true; |
169 } | 171 } |
170 | 172 |
171 // These handler methods do minimal things and delegate to the mock methods. | 173 // These handler methods do minimal things and delegate to the mock methods. |
172 void OnNewBufferCreatedDispatch(int device_id, | 174 void OnNewBufferCreatedDispatch(int device_id, |
173 base::SharedMemoryHandle handle, | 175 base::SharedMemoryHandle handle, |
174 uint32 length, | 176 uint32 length, |
175 int buffer_id) { | 177 int buffer_id) { |
176 OnNewBufferCreated(device_id, handle, length, buffer_id); | 178 OnNewBufferCreated(device_id, handle, length, buffer_id); |
177 base::SharedMemory* dib = new base::SharedMemory(handle, false); | 179 base::SharedMemory* dib = new base::SharedMemory(handle, false); |
178 dib->Map(length); | 180 dib->Map(length); |
179 filled_dib_[buffer_id] = dib; | 181 filled_dib_[buffer_id] = dib; |
180 } | 182 } |
181 | 183 |
182 void OnBufferFilledDispatch(int device_id, int buffer_id, | 184 void OnBufferFreedDispatch(int device_id, int buffer_id) { |
183 base::Time timestamp) { | 185 OnBufferFreed(device_id, buffer_id); |
| 186 |
| 187 std::map<int, base::SharedMemory*>::iterator it = |
| 188 filled_dib_.find(buffer_id); |
| 189 ASSERT_TRUE(it != filled_dib_.end()); |
| 190 delete it->second; |
| 191 filled_dib_.erase(it); |
| 192 } |
| 193 |
| 194 void OnBufferFilledDispatch(int device_id, |
| 195 int buffer_id, |
| 196 base::Time timestamp, |
| 197 const media::VideoCaptureFormat& frame_format) { |
| 198 base::SharedMemory* dib = filled_dib_[buffer_id]; |
| 199 ASSERT_TRUE(dib != NULL); |
184 if (dump_video_) { | 200 if (dump_video_) { |
185 base::SharedMemory* dib = filled_dib_[buffer_id]; | 201 if (!format_.IsValid()) { |
186 ASSERT_TRUE(dib != NULL); | 202 dumper_.StartDump(frame_format.width, frame_format.height); |
| 203 format_ = frame_format; |
| 204 } |
| 205 ASSERT_EQ(format_.width, frame_format.width) |
| 206 << "Dump format does not handle variable resolution."; |
| 207 ASSERT_EQ(format_.height, frame_format.height) |
| 208 << "Dump format does not handle variable resolution.";; |
187 dumper_.NewVideoFrame(dib->memory()); | 209 dumper_.NewVideoFrame(dib->memory()); |
188 } | 210 } |
189 | 211 |
190 OnBufferFilled(device_id, buffer_id, timestamp); | 212 OnBufferFilled(device_id, buffer_id, timestamp, frame_format); |
191 if (return_buffers_) { | 213 if (return_buffers_) { |
192 VideoCaptureHost::OnReceiveEmptyBuffer(device_id, buffer_id); | 214 VideoCaptureHost::OnReceiveEmptyBuffer(device_id, buffer_id); |
193 } | 215 } |
194 } | 216 } |
195 | 217 |
196 void OnStateChangedDispatch(int device_id, VideoCaptureState state) { | 218 void OnStateChangedDispatch(int device_id, VideoCaptureState state) { |
197 OnStateChanged(device_id, state); | 219 OnStateChanged(device_id, state); |
198 } | 220 } |
199 | 221 |
200 void OnDeviceInfoDispatch(int device_id, | |
201 media::VideoCaptureParams params) { | |
202 if (dump_video_) { | |
203 dumper_.StartDump(params.width, params.height); | |
204 } | |
205 OnDeviceInfo(device_id); | |
206 } | |
207 | |
208 std::map<int, base::SharedMemory*> filled_dib_; | 222 std::map<int, base::SharedMemory*> filled_dib_; |
209 bool return_buffers_; | 223 bool return_buffers_; |
210 bool dump_video_; | 224 bool dump_video_; |
| 225 media::VideoCaptureFormat format_; |
211 DumpVideo dumper_; | 226 DumpVideo dumper_; |
212 }; | 227 }; |
213 | 228 |
214 ACTION_P2(ExitMessageLoop, message_loop, quit_closure) { | 229 ACTION_P2(ExitMessageLoop, message_loop, quit_closure) { |
215 message_loop->PostTask(FROM_HERE, quit_closure); | 230 message_loop->PostTask(FROM_HERE, quit_closure); |
216 } | 231 } |
217 | 232 |
218 // This is an integration test of VideoCaptureHost in conjunction with | 233 // This is an integration test of VideoCaptureHost in conjunction with |
219 // MediaStreamManager, VideoCaptureManager, VideoCaptureController, and | 234 // MediaStreamManager, VideoCaptureManager, VideoCaptureController, and |
220 // VideoCaptureDevice. | 235 // VideoCaptureDevice. |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 void CloseSession() { | 330 void CloseSession() { |
316 if (opened_device_label_.empty()) | 331 if (opened_device_label_.empty()) |
317 return; | 332 return; |
318 media_stream_manager_->CancelRequest(opened_device_label_); | 333 media_stream_manager_->CancelRequest(opened_device_label_); |
319 opened_device_label_.clear(); | 334 opened_device_label_.clear(); |
320 opened_session_id_ = kInvalidMediaCaptureSessionId; | 335 opened_session_id_ = kInvalidMediaCaptureSessionId; |
321 } | 336 } |
322 | 337 |
323 protected: | 338 protected: |
324 void StartCapture() { | 339 void StartCapture() { |
325 InSequence s; | |
326 // 1. First - get info about the new resolution | |
327 EXPECT_CALL(*host_, OnDeviceInfo(kDeviceId)); | |
328 | |
329 // 2. Change state to started | |
330 EXPECT_CALL(*host_, OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STARTED)); | |
331 | |
332 // 3. Newly created buffers will arrive. | |
333 EXPECT_CALL(*host_, OnNewBufferCreated(kDeviceId, _, _, _)) | 340 EXPECT_CALL(*host_, OnNewBufferCreated(kDeviceId, _, _, _)) |
334 .Times(AnyNumber()).WillRepeatedly(Return()); | 341 .Times(AnyNumber()).WillRepeatedly(Return()); |
335 | 342 |
336 // 4. First filled buffer will arrive. | |
337 base::RunLoop run_loop; | 343 base::RunLoop run_loop; |
338 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _)) | 344 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _, _)) |
339 .Times(AnyNumber()).WillOnce(ExitMessageLoop( | 345 .Times(AnyNumber()).WillOnce(ExitMessageLoop( |
340 message_loop_, run_loop.QuitClosure())); | 346 message_loop_, run_loop.QuitClosure())); |
341 | 347 |
342 media::VideoCaptureParams params; | 348 media::VideoCaptureParams params; |
343 params.width = 352; | 349 params.requested_format = media::VideoCaptureFormat( |
344 params.height = 288; | 350 352, 288, 30, media::ConstantResolutionVideoCaptureDevice); |
345 params.frame_rate = 30; | |
346 params.session_id = opened_session_id_; | 351 params.session_id = opened_session_id_; |
347 host_->OnStartCapture(kDeviceId, params); | 352 host_->OnStartCapture(kDeviceId, params); |
348 run_loop.Run(); | 353 run_loop.Run(); |
349 } | 354 } |
350 | 355 |
351 void StartStopCapture() { | 356 void StartStopCapture() { |
352 // Quickly start and then stop capture, without giving much chance for | 357 // Quickly start and then stop capture, without giving much chance for |
353 // asynchronous start operations to complete. | 358 // asynchronous start operations to complete. |
354 InSequence s; | 359 InSequence s; |
355 base::RunLoop run_loop; | 360 base::RunLoop run_loop; |
356 EXPECT_CALL(*host_, OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)); | 361 EXPECT_CALL(*host_, OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)); |
357 media::VideoCaptureParams params; | 362 media::VideoCaptureParams params; |
358 params.width = 352; | 363 params.requested_format = media::VideoCaptureFormat( |
359 params.height = 288; | 364 352, 288, 30, media::ConstantResolutionVideoCaptureDevice); |
360 params.frame_rate = 30; | |
361 params.session_id = opened_session_id_; | 365 params.session_id = opened_session_id_; |
362 host_->OnStartCapture(kDeviceId, params); | 366 host_->OnStartCapture(kDeviceId, params); |
363 host_->OnStopCapture(kDeviceId); | 367 host_->OnStopCapture(kDeviceId); |
364 run_loop.RunUntilIdle(); | 368 run_loop.RunUntilIdle(); |
365 } | 369 } |
366 | 370 |
367 #ifdef DUMP_VIDEO | 371 #ifdef DUMP_VIDEO |
368 void CaptureAndDumpVideo(int width, int height, int frame_rate) { | 372 void CaptureAndDumpVideo(int width, int height, int frame_rate) { |
369 InSequence s; | 373 InSequence s; |
370 // 1. First - get info about the new resolution | 374 EXPECT_CALL(*host_.get(), OnNewBufferCreated(kDeviceId, _, _, _)) |
371 EXPECT_CALL(*host_, OnDeviceInfo(kDeviceId)); | 375 .Times(AnyNumber()).WillRepeatedly(Return()); |
372 | 376 |
373 // 2. Change state to started | |
374 EXPECT_CALL(*host_, OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STARTED)); | |
375 | |
376 // 3. First filled buffer will arrive. | |
377 base::RunLoop run_loop; | 377 base::RunLoop run_loop; |
378 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _)) | 378 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _, _)) |
379 .Times(AnyNumber()) | 379 .Times(AnyNumber()) |
380 .WillOnce(ExitMessageLoop(message_loop_, run_loop.QuitClosure())); | 380 .WillOnce(ExitMessageLoop(message_loop_, run_loop.QuitClosure())); |
381 | 381 |
382 media::VideoCaptureParams params; | 382 media::VideoCaptureParams params; |
383 params.width = width; | 383 params.requested_format = media::VideoCaptureFormat( |
384 params.height = height; | 384 width, height, frame_rate, media::ConstantResolutionVideoCaptureDevice); |
385 params.frame_rate = frame_rate; | |
386 params.session_id = opened_session_id_; | 385 params.session_id = opened_session_id_; |
387 host_->SetDumpVideo(true); | 386 host_->SetDumpVideo(true); |
388 host_->OnStartCapture(kDeviceId, params); | 387 host_->OnStartCapture(kDeviceId, params); |
389 run_loop.Run(); | 388 run_loop.Run(); |
390 } | 389 } |
391 #endif | 390 #endif |
392 | 391 |
393 void StopCapture() { | 392 void StopCapture() { |
394 base::RunLoop run_loop; | 393 base::RunLoop run_loop; |
395 EXPECT_CALL(*host_, OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)) | 394 EXPECT_CALL(*host_, OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)) |
396 .WillOnce(ExitMessageLoop(message_loop_, run_loop.QuitClosure())); | 395 .WillOnce(ExitMessageLoop(message_loop_, run_loop.QuitClosure())); |
397 | 396 |
398 host_->OnStopCapture(kDeviceId); | 397 host_->OnStopCapture(kDeviceId); |
399 host_->SetReturnReceviedDibs(true); | 398 host_->SetReturnReceivedDibs(true); |
400 host_->ReturnReceivedDibs(kDeviceId); | 399 host_->ReturnReceivedDibs(kDeviceId); |
401 | 400 |
402 run_loop.Run(); | 401 run_loop.Run(); |
403 | 402 |
404 host_->SetReturnReceviedDibs(false); | 403 host_->SetReturnReceivedDibs(false); |
405 // Expect the VideoCaptureDevice has been stopped | 404 // Expect the VideoCaptureDevice has been stopped |
406 EXPECT_EQ(0u, host_->entries_.size()); | 405 EXPECT_EQ(0u, host_->entries_.size()); |
407 } | 406 } |
408 | 407 |
409 void NotifyPacketReady() { | 408 void NotifyPacketReady() { |
410 base::RunLoop run_loop; | 409 base::RunLoop run_loop; |
411 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _)) | 410 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _, _)) |
412 .Times(AnyNumber()).WillOnce(ExitMessageLoop( | 411 .Times(AnyNumber()).WillOnce(ExitMessageLoop( |
413 message_loop_, run_loop.QuitClosure())) | 412 message_loop_, run_loop.QuitClosure())) |
414 .RetiresOnSaturation(); | 413 .RetiresOnSaturation(); |
415 run_loop.Run(); | 414 run_loop.Run(); |
416 } | 415 } |
417 | 416 |
418 void ReturnReceivedPackets() { | 417 void ReturnReceivedPackets() { |
419 host_->ReturnReceivedDibs(kDeviceId); | 418 host_->ReturnReceivedDibs(kDeviceId); |
420 } | 419 } |
421 | 420 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 #ifdef DUMP_VIDEO | 483 #ifdef DUMP_VIDEO |
485 TEST_F(VideoCaptureHostTest, CaptureAndDumpVideoVga) { | 484 TEST_F(VideoCaptureHostTest, CaptureAndDumpVideoVga) { |
486 CaptureAndDumpVideo(640, 480, 30); | 485 CaptureAndDumpVideo(640, 480, 30); |
487 } | 486 } |
488 TEST_F(VideoCaptureHostTest, CaptureAndDump720P) { | 487 TEST_F(VideoCaptureHostTest, CaptureAndDump720P) { |
489 CaptureAndDumpVideo(1280, 720, 30); | 488 CaptureAndDumpVideo(1280, 720, 30); |
490 } | 489 } |
491 #endif | 490 #endif |
492 | 491 |
493 } // namespace content | 492 } // namespace content |
OLD | NEW |