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

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

Powered by Google App Engine
This is Rietveld 408576698