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

Side by Side Diff: media/video/capture/win/video_capture_device_win.cc

Issue 10662049: Move the device enumerate/open/close work to device thread from IO thread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: small changes to fix the trybots' failure Created 8 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « media/video/capture/win/video_capture_device_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "media/video/capture/win/video_capture_device_win.h" 5 #include "media/video/capture/win/video_capture_device_win.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <list> 8 #include <list>
9 9
10 #include "base/string_util.h" 10 #include "base/string_util.h"
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 namespace media { 173 namespace media {
174 174
175 // Name of a fake DirectShow filter that exist on computers with 175 // Name of a fake DirectShow filter that exist on computers with
176 // GTalk installed. 176 // GTalk installed.
177 static const char kGoogleCameraAdapter[] = "google camera adapter"; 177 static const char kGoogleCameraAdapter[] = "google camera adapter";
178 178
179 // Gets the names of all video capture devices connected to this computer. 179 // Gets the names of all video capture devices connected to this computer.
180 void VideoCaptureDevice::GetDeviceNames(Names* device_names) { 180 void VideoCaptureDevice::GetDeviceNames(Names* device_names) {
181 DCHECK(device_names); 181 DCHECK(device_names);
182 182
183 base::win::ScopedCOMInitializer coinit;
184 ScopedComPtr<ICreateDevEnum> dev_enum; 183 ScopedComPtr<ICreateDevEnum> dev_enum;
185 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, 184 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL,
186 CLSCTX_INPROC); 185 CLSCTX_INPROC);
187 if (FAILED(hr)) 186 if (FAILED(hr))
188 return; 187 return;
189 188
190 ScopedComPtr<IEnumMoniker> enum_moniker; 189 ScopedComPtr<IEnumMoniker> enum_moniker;
191 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, 190 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
192 enum_moniker.Receive(), 0); 191 enum_moniker.Receive(), 0);
193 // CreateClassEnumerator returns S_FALSE on some Windows OS 192 // CreateClassEnumerator returns S_FALSE on some Windows OS
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 return self; 247 return self;
249 248
250 delete self; 249 delete self;
251 return NULL; 250 return NULL;
252 } 251 }
253 252
254 VideoCaptureDeviceWin::VideoCaptureDeviceWin(const Name& device_name) 253 VideoCaptureDeviceWin::VideoCaptureDeviceWin(const Name& device_name)
255 : device_name_(device_name), 254 : device_name_(device_name),
256 state_(kIdle), 255 state_(kIdle),
257 observer_(NULL) { 256 observer_(NULL) {
257 DetachFromThread();
258 } 258 }
259 259
260 VideoCaptureDeviceWin::~VideoCaptureDeviceWin() { 260 VideoCaptureDeviceWin::~VideoCaptureDeviceWin() {
261 DCHECK(CalledOnValidThread());
261 if (media_control_) 262 if (media_control_)
262 media_control_->Stop(); 263 media_control_->Stop();
263 264
264 if (graph_builder_) { 265 if (graph_builder_) {
265 if (sink_filter_) { 266 if (sink_filter_) {
266 graph_builder_->RemoveFilter(sink_filter_); 267 graph_builder_->RemoveFilter(sink_filter_);
267 sink_filter_ = NULL; 268 sink_filter_ = NULL;
268 } 269 }
269 270
270 if (capture_filter_) 271 if (capture_filter_)
271 graph_builder_->RemoveFilter(capture_filter_); 272 graph_builder_->RemoveFilter(capture_filter_);
272 273
273 if (mjpg_filter_) 274 if (mjpg_filter_)
274 graph_builder_->RemoveFilter(mjpg_filter_); 275 graph_builder_->RemoveFilter(mjpg_filter_);
275 } 276 }
276 } 277 }
277 278
278 bool VideoCaptureDeviceWin::Init() { 279 bool VideoCaptureDeviceWin::Init() {
280 DCHECK(CalledOnValidThread());
279 HRESULT hr = GetDeviceFilter(device_name_, capture_filter_.Receive()); 281 HRESULT hr = GetDeviceFilter(device_name_, capture_filter_.Receive());
280 if (!capture_filter_) { 282 if (!capture_filter_) {
281 DVLOG(2) << "Failed to create capture filter."; 283 DVLOG(2) << "Failed to create capture filter.";
282 return false; 284 return false;
283 } 285 }
284 286
285 hr = GetPin(capture_filter_, PINDIR_OUTPUT, PIN_CATEGORY_CAPTURE, 287 hr = GetPin(capture_filter_, PINDIR_OUTPUT, PIN_CATEGORY_CAPTURE,
286 output_capture_pin_.Receive()); 288 output_capture_pin_.Receive());
287 if (!output_capture_pin_) { 289 if (!output_capture_pin_) {
288 DVLOG(2) << "Failed to get capture output pin"; 290 DVLOG(2) << "Failed to get capture output pin";
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 } 326 }
325 327
326 return CreateCapabilityMap(); 328 return CreateCapabilityMap();
327 } 329 }
328 330
329 void VideoCaptureDeviceWin::Allocate( 331 void VideoCaptureDeviceWin::Allocate(
330 int width, 332 int width,
331 int height, 333 int height,
332 int frame_rate, 334 int frame_rate,
333 VideoCaptureDevice::EventHandler* observer) { 335 VideoCaptureDevice::EventHandler* observer) {
336 DCHECK(CalledOnValidThread());
334 if (state_ != kIdle) 337 if (state_ != kIdle)
335 return; 338 return;
336 339
337 observer_ = observer; 340 observer_ = observer;
338 // Get the camera capability that best match the requested resolution. 341 // Get the camera capability that best match the requested resolution.
339 const int capability_index = GetBestMatchedCapability(width, height, 342 const int capability_index = GetBestMatchedCapability(width, height,
340 frame_rate); 343 frame_rate);
341 VideoCaptureCapability capability = capabilities_[capability_index]; 344 VideoCaptureCapability capability = capabilities_[capability_index];
342 345
343 // Reduce the frame rate if the requested frame rate is lower 346 // Reduce the frame rate if the requested frame rate is lower
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 // Get the capability back from the sink filter after the filter have been 423 // Get the capability back from the sink filter after the filter have been
421 // connected. 424 // connected.
422 const VideoCaptureCapability& used_capability 425 const VideoCaptureCapability& used_capability
423 = sink_filter_->ResultingCapability(); 426 = sink_filter_->ResultingCapability();
424 observer_->OnFrameInfo(used_capability); 427 observer_->OnFrameInfo(used_capability);
425 428
426 state_ = kAllocated; 429 state_ = kAllocated;
427 } 430 }
428 431
429 void VideoCaptureDeviceWin::Start() { 432 void VideoCaptureDeviceWin::Start() {
433 DCHECK(CalledOnValidThread());
430 if (state_ != kAllocated) 434 if (state_ != kAllocated)
431 return; 435 return;
432 436
433 HRESULT hr = media_control_->Run(); 437 HRESULT hr = media_control_->Run();
434 if (FAILED(hr)) { 438 if (FAILED(hr)) {
435 SetErrorState("Failed to start the Capture device."); 439 SetErrorState("Failed to start the Capture device.");
436 return; 440 return;
437 } 441 }
438 442
439 state_ = kCapturing; 443 state_ = kCapturing;
440 } 444 }
441 445
442 void VideoCaptureDeviceWin::Stop() { 446 void VideoCaptureDeviceWin::Stop() {
447 DCHECK(CalledOnValidThread());
443 if (state_ != kCapturing) 448 if (state_ != kCapturing)
444 return; 449 return;
445 450
446 HRESULT hr = media_control_->Stop(); 451 HRESULT hr = media_control_->Stop();
447 if (FAILED(hr)) { 452 if (FAILED(hr)) {
448 SetErrorState("Failed to stop the capture graph."); 453 SetErrorState("Failed to stop the capture graph.");
449 return; 454 return;
450 } 455 }
451 456
452 state_ = kAllocated; 457 state_ = kAllocated;
453 } 458 }
454 459
455 void VideoCaptureDeviceWin::DeAllocate() { 460 void VideoCaptureDeviceWin::DeAllocate() {
461 DCHECK(CalledOnValidThread());
456 if (state_ == kIdle) 462 if (state_ == kIdle)
457 return; 463 return;
458 464
459 HRESULT hr = media_control_->Stop(); 465 HRESULT hr = media_control_->Stop();
460 graph_builder_->Disconnect(output_capture_pin_); 466 graph_builder_->Disconnect(output_capture_pin_);
461 graph_builder_->Disconnect(input_sink_pin_); 467 graph_builder_->Disconnect(input_sink_pin_);
462 468
463 // If the _mjpg filter exist disconnect it even if it has not been used. 469 // If the _mjpg filter exist disconnect it even if it has not been used.
464 if (mjpg_filter_) { 470 if (mjpg_filter_) {
465 graph_builder_->Disconnect(input_mjpg_pin_); 471 graph_builder_->Disconnect(input_mjpg_pin_);
466 graph_builder_->Disconnect(output_mjpg_pin_); 472 graph_builder_->Disconnect(output_mjpg_pin_);
467 } 473 }
468 474
469 if (FAILED(hr)) { 475 if (FAILED(hr)) {
470 SetErrorState("Failed to Stop the Capture device"); 476 SetErrorState("Failed to Stop the Capture device");
471 return; 477 return;
472 } 478 }
473 479
474 state_ = kIdle; 480 state_ = kIdle;
475 } 481 }
476 482
477 const VideoCaptureDevice::Name& VideoCaptureDeviceWin::device_name() { 483 const VideoCaptureDevice::Name& VideoCaptureDeviceWin::device_name() {
484 DCHECK(CalledOnValidThread());
478 return device_name_; 485 return device_name_;
479 } 486 }
480 487
481 // Implements SinkFilterObserver::SinkFilterObserver. 488 // Implements SinkFilterObserver::SinkFilterObserver.
482 void VideoCaptureDeviceWin::FrameReceived(const uint8* buffer, 489 void VideoCaptureDeviceWin::FrameReceived(const uint8* buffer,
483 int length) { 490 int length) {
484 observer_->OnIncomingCapturedFrame(buffer, length, base::Time::Now()); 491 observer_->OnIncomingCapturedFrame(buffer, length, base::Time::Now());
485 } 492 }
486 493
487 bool VideoCaptureDeviceWin::CreateCapabilityMap() { 494 bool VideoCaptureDeviceWin::CreateCapabilityMap() {
495 DCHECK(CalledOnValidThread());
488 ScopedComPtr<IAMStreamConfig> stream_config; 496 ScopedComPtr<IAMStreamConfig> stream_config;
489 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); 497 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive());
490 if (FAILED(hr)) { 498 if (FAILED(hr)) {
491 DVLOG(2) << "Failed to get IAMStreamConfig interface from " 499 DVLOG(2) << "Failed to get IAMStreamConfig interface from "
492 "capture device"; 500 "capture device";
493 return false; 501 return false;
494 } 502 }
495 503
496 // Get interface used for getting the frame rate. 504 // Get interface used for getting the frame rate.
497 ScopedComPtr<IAMVideoControl> video_control; 505 ScopedComPtr<IAMVideoControl> video_control;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 return capabilities_.size() > 0; 595 return capabilities_.size() > 0;
588 } 596 }
589 597
590 // Loops through the list of capabilities and returns an index of the best 598 // Loops through the list of capabilities and returns an index of the best
591 // matching capability. 599 // matching capability.
592 // The algorithm prioritize height, width, frame rate and color format in that 600 // The algorithm prioritize height, width, frame rate and color format in that
593 // order. 601 // order.
594 int VideoCaptureDeviceWin::GetBestMatchedCapability(int requested_width, 602 int VideoCaptureDeviceWin::GetBestMatchedCapability(int requested_width,
595 int requested_height, 603 int requested_height,
596 int requested_frame_rate) { 604 int requested_frame_rate) {
605 DCHECK(CalledOnValidThread());
597 std::list<ResolutionDiff> diff_list; 606 std::list<ResolutionDiff> diff_list;
598 607
599 // Loop through the candidates to create a list of differentials between the 608 // Loop through the candidates to create a list of differentials between the
600 // requested resolution and the camera capability. 609 // requested resolution and the camera capability.
601 for (CapabilityMap::iterator iterator = capabilities_.begin(); 610 for (CapabilityMap::iterator iterator = capabilities_.begin();
602 iterator != capabilities_.end(); 611 iterator != capabilities_.end();
603 ++iterator) { 612 ++iterator) {
604 VideoCaptureCapability capability = iterator->second; 613 VideoCaptureCapability capability = iterator->second;
605 614
606 ResolutionDiff diff; 615 ResolutionDiff diff;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 break; 655 break;
647 } 656 }
648 } 657 }
649 658
650 // Decide the best color format. 659 // Decide the best color format.
651 diff_list.sort(&CompareColor); 660 diff_list.sort(&CompareColor);
652 return diff_list.front().capability_index; 661 return diff_list.front().capability_index;
653 } 662 }
654 663
655 void VideoCaptureDeviceWin::SetErrorState(const char* reason) { 664 void VideoCaptureDeviceWin::SetErrorState(const char* reason) {
665 DCHECK(CalledOnValidThread());
656 DVLOG(1) << reason; 666 DVLOG(1) << reason;
657 state_ = kError; 667 state_ = kError;
658 observer_->OnError(); 668 observer_->OnError();
659 } 669 }
660 670
661 } // namespace media 671 } // namespace media
OLDNEW
« no previous file with comments | « media/video/capture/win/video_capture_device_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698