| 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" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "base/process_util.h" | 12 #include "base/process_util.h" |
| 13 #include "base/run_loop.h" |
| 13 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 14 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
| 15 #include "content/browser/browser_thread_impl.h" | 16 #include "content/browser/browser_thread_impl.h" |
| 16 #include "content/browser/renderer_host/media/media_stream_manager.h" | 17 #include "content/browser/renderer_host/media/media_stream_manager.h" |
| 17 #include "content/browser/renderer_host/media/video_capture_host.h" | 18 #include "content/browser/renderer_host/media/video_capture_host.h" |
| 18 #include "content/browser/renderer_host/media/video_capture_manager.h" | 19 #include "content/browser/renderer_host/media/video_capture_manager.h" |
| 19 #include "content/common/media/video_capture_messages.h" | 20 #include "content/common/media/video_capture_messages.h" |
| 20 #include "content/public/test/mock_resource_context.h" | 21 #include "content/public/test/mock_resource_context.h" |
| 22 #include "content/public/test/test_browser_thread_bundle.h" |
| 21 #include "media/audio/audio_manager.h" | 23 #include "media/audio/audio_manager.h" |
| 22 #include "media/video/capture/video_capture_types.h" | 24 #include "media/video/capture/video_capture_types.h" |
| 23 #include "net/url_request/url_request_context.h" | 25 #include "net/url_request/url_request_context.h" |
| 24 #include "testing/gmock/include/gmock/gmock.h" | 26 #include "testing/gmock/include/gmock/gmock.h" |
| 25 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
| 26 | 28 |
| 27 using ::testing::_; | 29 using ::testing::_; |
| 28 using ::testing::AtLeast; | 30 using ::testing::AtLeast; |
| 29 using ::testing::AnyNumber; | 31 using ::testing::AnyNumber; |
| 30 using ::testing::DoAll; | 32 using ::testing::DoAll; |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 } | 179 } |
| 178 OnDeviceInfo(device_id); | 180 OnDeviceInfo(device_id); |
| 179 } | 181 } |
| 180 | 182 |
| 181 std::map<int, base::SharedMemory*> filled_dib_; | 183 std::map<int, base::SharedMemory*> filled_dib_; |
| 182 bool return_buffers_; | 184 bool return_buffers_; |
| 183 bool dump_video_; | 185 bool dump_video_; |
| 184 DumpVideo dumper_; | 186 DumpVideo dumper_; |
| 185 }; | 187 }; |
| 186 | 188 |
| 187 ACTION_P(ExitMessageLoop, message_loop) { | 189 ACTION_P2(ExitMessageLoop, message_loop, quit_closure) { |
| 188 message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); | 190 message_loop->PostTask(FROM_HERE, quit_closure); |
| 189 } | 191 } |
| 190 | 192 |
| 191 class VideoCaptureHostTest : public testing::Test { | 193 class VideoCaptureHostTest : public testing::Test { |
| 192 public: | 194 public: |
| 193 VideoCaptureHostTest() {} | 195 VideoCaptureHostTest() |
| 194 | 196 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), |
| 195 protected: | 197 message_loop_(base::MessageLoopProxy::current()) { |
| 196 virtual void SetUp() OVERRIDE { | |
| 197 // Create a message loop so VideoCaptureHostTest can use it. | |
| 198 message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO)); | |
| 199 | |
| 200 // MediaStreamManager must be created on the IO thread. | |
| 201 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO, | |
| 202 message_loop_.get())); | |
| 203 | |
| 204 // Create our own MediaStreamManager. | 198 // Create our own MediaStreamManager. |
| 205 audio_manager_.reset(media::AudioManager::Create()); | 199 audio_manager_.reset(media::AudioManager::Create()); |
| 206 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get())); | 200 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get())); |
| 207 #ifndef TEST_REAL_CAPTURE_DEVICE | 201 #ifndef TEST_REAL_CAPTURE_DEVICE |
| 208 media_stream_manager_->UseFakeDevice(); | 202 media_stream_manager_->UseFakeDevice(); |
| 209 #endif | 203 #endif |
| 210 | 204 |
| 211 host_ = new MockVideoCaptureHost(media_stream_manager_.get()); | 205 host_ = new MockVideoCaptureHost(media_stream_manager_.get()); |
| 212 | 206 |
| 213 // Simulate IPC channel connected. | 207 // Simulate IPC channel connected. |
| 214 host_->OnChannelConnected(base::GetCurrentProcId()); | 208 host_->OnChannelConnected(base::GetCurrentProcId()); |
| 215 } | 209 } |
| 216 | 210 |
| 217 virtual void TearDown() OVERRIDE { | 211 virtual ~VideoCaptureHostTest() { |
| 218 // Verifies and removes the expectations on host_ and | 212 // Verifies and removes the expectations on host_ and |
| 219 // returns true iff successful. | 213 // returns true iff successful. |
| 220 Mock::VerifyAndClearExpectations(host_.get()); | 214 Mock::VerifyAndClearExpectations(host_.get()); |
| 221 | 215 |
| 222 EXPECT_CALL(*host_.get(), | 216 EXPECT_CALL(*host_.get(), |
| 223 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)) | 217 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)) |
| 224 .Times(AnyNumber()); | 218 .Times(AnyNumber()); |
| 225 | 219 |
| 226 // Simulate closing the IPC channel. | 220 // Simulate closing the IPC channel. |
| 227 host_->OnChannelClosing(); | 221 host_->OnChannelClosing(); |
| 228 | 222 |
| 229 // Release the reference to the mock object. The object will be destructed | 223 // Release the reference to the mock object. The object will be destructed |
| 230 // on message_loop_. | 224 // on the current message loop. |
| 231 host_ = NULL; | 225 host_ = NULL; |
| 232 | |
| 233 // We need to continue running message_loop_ to complete all destructions. | |
| 234 message_loop_->RunUntilIdle(); | |
| 235 | |
| 236 // Delete the IO message loop. This will cause the MediaStreamManager to be | |
| 237 // notified so it will stop its device thread and device managers. | |
| 238 message_loop_.reset(); | |
| 239 } | 226 } |
| 240 | 227 |
| 228 protected: |
| 241 void StartCapture() { | 229 void StartCapture() { |
| 242 InSequence s; | 230 InSequence s; |
| 243 // 1. First - get info about the new resolution | 231 // 1. First - get info about the new resolution |
| 244 EXPECT_CALL(*host_.get(), OnDeviceInfo(kDeviceId)); | 232 EXPECT_CALL(*host_.get(), OnDeviceInfo(kDeviceId)); |
| 245 | 233 |
| 246 // 2. Change state to started | 234 // 2. Change state to started |
| 247 EXPECT_CALL(*host_.get(), | 235 EXPECT_CALL(*host_.get(), |
| 248 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STARTED)); | 236 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STARTED)); |
| 249 | 237 |
| 250 // 3. Newly created buffers will arrive. | 238 // 3. Newly created buffers will arrive. |
| 251 EXPECT_CALL(*host_.get(), OnNewBufferCreated(kDeviceId, _, _, _)) | 239 EXPECT_CALL(*host_.get(), OnNewBufferCreated(kDeviceId, _, _, _)) |
| 252 .Times(AnyNumber()).WillRepeatedly(Return()); | 240 .Times(AnyNumber()).WillRepeatedly(Return()); |
| 253 | 241 |
| 254 // 4. First filled buffer will arrive. | 242 // 4. First filled buffer will arrive. |
| 243 base::RunLoop run_loop; |
| 255 EXPECT_CALL(*host_.get(), OnBufferFilled(kDeviceId, _, _)) | 244 EXPECT_CALL(*host_.get(), OnBufferFilled(kDeviceId, _, _)) |
| 256 .Times(AnyNumber()).WillOnce(ExitMessageLoop(message_loop_.get())); | 245 .Times(AnyNumber()).WillOnce(ExitMessageLoop( |
| 246 message_loop_, run_loop.QuitClosure())); |
| 257 | 247 |
| 258 media::VideoCaptureParams params; | 248 media::VideoCaptureParams params; |
| 259 params.width = 352; | 249 params.width = 352; |
| 260 params.height = 288; | 250 params.height = 288; |
| 261 params.frame_per_second = 30; | 251 params.frame_per_second = 30; |
| 262 params.session_id = kTestFakeDeviceId; | 252 params.session_id = kTestFakeDeviceId; |
| 263 host_->OnStartCapture(kDeviceId, params); | 253 host_->OnStartCapture(kDeviceId, params); |
| 264 message_loop_->Run(); | 254 run_loop.Run(); |
| 265 } | 255 } |
| 266 | 256 |
| 267 #ifdef DUMP_VIDEO | 257 #ifdef DUMP_VIDEO |
| 268 void CaptureAndDumpVideo(int width, int heigt, int frame_rate) { | 258 void CaptureAndDumpVideo(int width, int heigt, int frame_rate) { |
| 269 InSequence s; | 259 InSequence s; |
| 270 // 1. First - get info about the new resolution | 260 // 1. First - get info about the new resolution |
| 271 EXPECT_CALL(*host_, OnDeviceInfo(kDeviceId)); | 261 EXPECT_CALL(*host_, OnDeviceInfo(kDeviceId)); |
| 272 | 262 |
| 273 // 2. Change state to started | 263 // 2. Change state to started |
| 274 EXPECT_CALL(*host_, OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STARTED)); | 264 EXPECT_CALL(*host_, OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STARTED)); |
| 275 | 265 |
| 276 // 3. First filled buffer will arrive. | 266 // 3. First filled buffer will arrive. |
| 267 base::RunLoop run_loop; |
| 277 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _)) | 268 EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _)) |
| 278 .Times(AnyNumber()) | 269 .Times(AnyNumber()) |
| 279 .WillOnce(ExitMessageLoop(message_loop_.get())); | 270 .WillOnce(ExitMessageLoop(message_loop_, run_loop.QuitClosure())); |
| 280 | 271 |
| 281 media::VideoCaptureParams params; | 272 media::VideoCaptureParams params; |
| 282 params.width = width; | 273 params.width = width; |
| 283 params.height = heigt; | 274 params.height = heigt; |
| 284 params.frame_per_second = frame_rate; | 275 params.frame_per_second = frame_rate; |
| 285 params.session_id = kTestFakeDeviceId; | 276 params.session_id = kTestFakeDeviceId; |
| 286 host_->SetDumpVideo(true); | 277 host_->SetDumpVideo(true); |
| 287 host_->OnStartCapture(kDeviceId, params); | 278 host_->OnStartCapture(kDeviceId, params); |
| 288 message_loop_->Run(); | 279 run_loop.Run(); |
| 289 } | 280 } |
| 290 #endif | 281 #endif |
| 291 | 282 |
| 292 void StopCapture() { | 283 void StopCapture() { |
| 284 base::RunLoop run_loop; |
| 293 EXPECT_CALL(*host_.get(), | 285 EXPECT_CALL(*host_.get(), |
| 294 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)) | 286 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_STOPPED)) |
| 295 .WillOnce(ExitMessageLoop(message_loop_.get())); | 287 .WillOnce(ExitMessageLoop(message_loop_, run_loop.QuitClosure())); |
| 296 | 288 |
| 297 host_->OnStopCapture(kDeviceId); | 289 host_->OnStopCapture(kDeviceId); |
| 298 host_->SetReturnReceviedDibs(true); | 290 host_->SetReturnReceviedDibs(true); |
| 299 host_->ReturnReceivedDibs(kDeviceId); | 291 host_->ReturnReceivedDibs(kDeviceId); |
| 300 | 292 |
| 301 message_loop_->Run(); | 293 run_loop.Run(); |
| 302 | 294 |
| 303 host_->SetReturnReceviedDibs(false); | 295 host_->SetReturnReceviedDibs(false); |
| 304 // Expect the VideoCaptureDevice has been stopped | 296 // Expect the VideoCaptureDevice has been stopped |
| 305 EXPECT_EQ(0u, host_->entries_.size()); | 297 EXPECT_EQ(0u, host_->entries_.size()); |
| 306 } | 298 } |
| 307 | 299 |
| 308 void NotifyPacketReady() { | 300 void NotifyPacketReady() { |
| 301 base::RunLoop run_loop; |
| 309 EXPECT_CALL(*host_.get(), OnBufferFilled(kDeviceId, _, _)) | 302 EXPECT_CALL(*host_.get(), OnBufferFilled(kDeviceId, _, _)) |
| 310 .Times(AnyNumber()).WillOnce(ExitMessageLoop(message_loop_.get())) | 303 .Times(AnyNumber()).WillOnce(ExitMessageLoop( |
| 304 message_loop_, run_loop.QuitClosure())) |
| 311 .RetiresOnSaturation(); | 305 .RetiresOnSaturation(); |
| 312 message_loop_->Run(); | 306 run_loop.Run(); |
| 313 } | 307 } |
| 314 | 308 |
| 315 void ReturnReceivedPackets() { | 309 void ReturnReceivedPackets() { |
| 316 host_->ReturnReceivedDibs(kDeviceId); | 310 host_->ReturnReceivedDibs(kDeviceId); |
| 317 } | 311 } |
| 318 | 312 |
| 319 void SimulateError() { | 313 void SimulateError() { |
| 320 // Expect a change state to error state sent through IPC. | 314 // Expect a change state to error state sent through IPC. |
| 321 EXPECT_CALL(*host_.get(), | 315 EXPECT_CALL(*host_.get(), |
| 322 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_ERROR)).Times(1); | 316 OnStateChanged(kDeviceId, VIDEO_CAPTURE_STATE_ERROR)).Times(1); |
| 323 VideoCaptureControllerID id(kDeviceId); | 317 VideoCaptureControllerID id(kDeviceId); |
| 324 host_->OnError(id); | 318 host_->OnError(id); |
| 325 // Wait for the error callback. | 319 // Wait for the error callback. |
| 326 message_loop_->RunUntilIdle(); | 320 base::RunLoop().RunUntilIdle(); |
| 327 } | 321 } |
| 328 | 322 |
| 329 scoped_refptr<MockVideoCaptureHost> host_; | 323 scoped_refptr<MockVideoCaptureHost> host_; |
| 330 | 324 |
| 331 private: | 325 private: |
| 332 scoped_ptr<base::MessageLoop> message_loop_; | |
| 333 scoped_ptr<BrowserThreadImpl> io_thread_; | |
| 334 scoped_ptr<media::AudioManager> audio_manager_; | 326 scoped_ptr<media::AudioManager> audio_manager_; |
| 335 scoped_ptr<MediaStreamManager> media_stream_manager_; | 327 scoped_ptr<MediaStreamManager> media_stream_manager_; |
| 328 content::TestBrowserThreadBundle thread_bundle_; |
| 329 scoped_refptr<base::MessageLoopProxy> message_loop_; |
| 336 | 330 |
| 337 DISALLOW_COPY_AND_ASSIGN(VideoCaptureHostTest); | 331 DISALLOW_COPY_AND_ASSIGN(VideoCaptureHostTest); |
| 338 }; | 332 }; |
| 339 | 333 |
| 340 TEST_F(VideoCaptureHostTest, StartCapture) { | 334 TEST_F(VideoCaptureHostTest, StartCapture) { |
| 341 StartCapture(); | 335 StartCapture(); |
| 342 } | 336 } |
| 343 | 337 |
| 344 TEST_F(VideoCaptureHostTest, StartCapturePlayStop) { | 338 TEST_F(VideoCaptureHostTest, StartCapturePlayStop) { |
| 345 StartCapture(); | 339 StartCapture(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 367 #ifdef DUMP_VIDEO | 361 #ifdef DUMP_VIDEO |
| 368 TEST_F(VideoCaptureHostTest, CaptureAndDumpVideoVga) { | 362 TEST_F(VideoCaptureHostTest, CaptureAndDumpVideoVga) { |
| 369 CaptureAndDumpVideo(640, 480, 30); | 363 CaptureAndDumpVideo(640, 480, 30); |
| 370 } | 364 } |
| 371 TEST_F(VideoCaptureHostTest, CaptureAndDump720P) { | 365 TEST_F(VideoCaptureHostTest, CaptureAndDump720P) { |
| 372 CaptureAndDumpVideo(1280, 720, 30); | 366 CaptureAndDumpVideo(1280, 720, 30); |
| 373 } | 367 } |
| 374 #endif | 368 #endif |
| 375 | 369 |
| 376 } // namespace content | 370 } // namespace content |
| OLD | NEW |