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

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

Issue 10035054: Merge VideoCaptureDevice::Capability with media::VideoCaptureCapability (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: fix a namespace issue Created 8 years, 7 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
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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 CoTaskMemFree(mt); 141 CoTaskMemFree(mt);
142 } 142 }
143 } 143 }
144 144
145 // Help structure used for comparing video capture capabilities. 145 // Help structure used for comparing video capture capabilities.
146 struct ResolutionDiff { 146 struct ResolutionDiff {
147 int capability_index; 147 int capability_index;
148 int diff_height; 148 int diff_height;
149 int diff_width; 149 int diff_width;
150 int diff_frame_rate; 150 int diff_frame_rate;
151 media::VideoCaptureDevice::Format color; 151 media::VideoCaptureCapability::Format color;
152 }; 152 };
153 153
154 bool CompareHeight(const ResolutionDiff& item1, const ResolutionDiff& item2) { 154 bool CompareHeight(const ResolutionDiff& item1, const ResolutionDiff& item2) {
155 return abs(item1.diff_height) < abs(item2.diff_height); 155 return abs(item1.diff_height) < abs(item2.diff_height);
156 } 156 }
157 157
158 bool CompareWidth(const ResolutionDiff& item1, const ResolutionDiff& item2) { 158 bool CompareWidth(const ResolutionDiff& item1, const ResolutionDiff& item2) {
159 return abs(item1.diff_width) < abs(item2.diff_width); 159 return abs(item1.diff_width) < abs(item2.diff_width);
160 } 160 }
161 161
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 int height, 331 int height,
332 int frame_rate, 332 int frame_rate,
333 VideoCaptureDevice::EventHandler* observer) { 333 VideoCaptureDevice::EventHandler* observer) {
334 if (state_ != kIdle) 334 if (state_ != kIdle)
335 return; 335 return;
336 336
337 observer_ = observer; 337 observer_ = observer;
338 // Get the camera capability that best match the requested resolution. 338 // Get the camera capability that best match the requested resolution.
339 const int capability_index = GetBestMatchedCapability(width, height, 339 const int capability_index = GetBestMatchedCapability(width, height,
340 frame_rate); 340 frame_rate);
341 Capability capability = capabilities_[capability_index]; 341 VideoCaptureCapability capability = capabilities_[capability_index];
342 342
343 // Reduce the frame rate if the requested frame rate is lower 343 // Reduce the frame rate if the requested frame rate is lower
344 // than the capability. 344 // than the capability.
345 if (capability.frame_rate > frame_rate) 345 if (capability.frame_rate > frame_rate)
346 capability.frame_rate = frame_rate; 346 capability.frame_rate = frame_rate;
347 347
348 AM_MEDIA_TYPE* pmt = NULL; 348 AM_MEDIA_TYPE* pmt = NULL;
349 VIDEO_STREAM_CONFIG_CAPS caps; 349 VIDEO_STREAM_CONFIG_CAPS caps;
350 350
351 ScopedComPtr<IAMStreamConfig> stream_config; 351 ScopedComPtr<IAMStreamConfig> stream_config;
(...skipping 14 matching lines...) Expand all
366 } 366 }
367 // Set the sink filter to request this capability. 367 // Set the sink filter to request this capability.
368 sink_filter_->SetRequestedMediaCapability(capability); 368 sink_filter_->SetRequestedMediaCapability(capability);
369 // Order the capture device to use this capability. 369 // Order the capture device to use this capability.
370 hr = stream_config->SetFormat(pmt); 370 hr = stream_config->SetFormat(pmt);
371 } 371 }
372 372
373 if (FAILED(hr)) 373 if (FAILED(hr))
374 SetErrorState("Failed to set capture device output format"); 374 SetErrorState("Failed to set capture device output format");
375 375
376 if (capability.color == VideoCaptureDevice::kMJPEG && !mjpg_filter_.get()) { 376 if (capability.color == VideoCaptureCapability::kMJPEG &&
377 !mjpg_filter_.get()) {
377 // Create MJPG filter if we need it. 378 // Create MJPG filter if we need it.
378 hr = mjpg_filter_.CreateInstance(CLSID_MjpegDec, NULL, CLSCTX_INPROC); 379 hr = mjpg_filter_.CreateInstance(CLSID_MjpegDec, NULL, CLSCTX_INPROC);
379 380
380 if (SUCCEEDED(hr)) { 381 if (SUCCEEDED(hr)) {
381 GetPin(mjpg_filter_, PINDIR_INPUT, GUID_NULL, input_mjpg_pin_.Receive()); 382 GetPin(mjpg_filter_, PINDIR_INPUT, GUID_NULL, input_mjpg_pin_.Receive());
382 GetPin(mjpg_filter_, PINDIR_OUTPUT, GUID_NULL, 383 GetPin(mjpg_filter_, PINDIR_OUTPUT, GUID_NULL,
383 output_mjpg_pin_.Receive()); 384 output_mjpg_pin_.Receive());
384 hr = graph_builder_->AddFilter(mjpg_filter_, NULL); 385 hr = graph_builder_->AddFilter(mjpg_filter_, NULL);
385 } 386 }
386 387
387 if (FAILED(hr)) { 388 if (FAILED(hr)) {
388 mjpg_filter_.Release(); 389 mjpg_filter_.Release();
389 input_mjpg_pin_.Release(); 390 input_mjpg_pin_.Release();
390 output_mjpg_pin_.Release(); 391 output_mjpg_pin_.Release();
391 } 392 }
392 } 393 }
393 394
394 if (capability.color == VideoCaptureDevice::kMJPEG && mjpg_filter_.get()) { 395 if (capability.color == VideoCaptureCapability::kMJPEG &&
396 mjpg_filter_.get()) {
395 // Connect the camera to the MJPEG decoder. 397 // Connect the camera to the MJPEG decoder.
396 hr = graph_builder_->ConnectDirect(output_capture_pin_, input_mjpg_pin_, 398 hr = graph_builder_->ConnectDirect(output_capture_pin_, input_mjpg_pin_,
397 NULL); 399 NULL);
398 // Connect the MJPEG filter to the Capture filter. 400 // Connect the MJPEG filter to the Capture filter.
399 hr += graph_builder_->ConnectDirect(output_mjpg_pin_, input_sink_pin_, 401 hr += graph_builder_->ConnectDirect(output_mjpg_pin_, input_sink_pin_,
400 NULL); 402 NULL);
401 } else { 403 } else {
402 hr = graph_builder_->ConnectDirect(output_capture_pin_, input_sink_pin_, 404 hr = graph_builder_->ConnectDirect(output_capture_pin_, input_sink_pin_,
403 NULL); 405 NULL);
404 } 406 }
405 407
406 if (FAILED(hr)) { 408 if (FAILED(hr)) {
407 SetErrorState("Failed to connect the Capture graph."); 409 SetErrorState("Failed to connect the Capture graph.");
408 return; 410 return;
409 } 411 }
410 412
411 hr = media_control_->Pause(); 413 hr = media_control_->Pause();
412 if (FAILED(hr)) { 414 if (FAILED(hr)) {
413 SetErrorState("Failed to Pause the Capture device. " 415 SetErrorState("Failed to Pause the Capture device. "
414 "Is it already occupied?"); 416 "Is it already occupied?");
415 return; 417 return;
416 } 418 }
417 419
418 // Get the capability back from the sink filter after the filter have been 420 // Get the capability back from the sink filter after the filter have been
419 // connected. 421 // connected.
420 const Capability& used_capability = sink_filter_->ResultingCapability(); 422 const VideoCaptureCapability& used_capability
423 = sink_filter_->ResultingCapability();
421 observer_->OnFrameInfo(used_capability); 424 observer_->OnFrameInfo(used_capability);
422 425
423 state_ = kAllocated; 426 state_ = kAllocated;
424 } 427 }
425 428
426 void VideoCaptureDeviceWin::Start() { 429 void VideoCaptureDeviceWin::Start() {
427 if (state_ != kAllocated) 430 if (state_ != kAllocated)
428 return; 431 return;
429 432
430 HRESULT hr = media_control_->Run(); 433 HRESULT hr = media_control_->Run();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 for (int i = 0; i < count; ++i) { 511 for (int i = 0; i < count; ++i) {
509 hr = stream_config->GetStreamCaps(i, &media_type, 512 hr = stream_config->GetStreamCaps(i, &media_type,
510 reinterpret_cast<BYTE*>(&caps)); 513 reinterpret_cast<BYTE*>(&caps));
511 if (FAILED(hr)) { 514 if (FAILED(hr)) {
512 DVLOG(2) << "Failed to GetStreamCaps"; 515 DVLOG(2) << "Failed to GetStreamCaps";
513 return false; 516 return false;
514 } 517 }
515 518
516 if (media_type->majortype == MEDIATYPE_Video && 519 if (media_type->majortype == MEDIATYPE_Video &&
517 media_type->formattype == FORMAT_VideoInfo) { 520 media_type->formattype == FORMAT_VideoInfo) {
518 Capability capability; 521 VideoCaptureCapability capability;
519 REFERENCE_TIME time_per_frame = 0; 522 REFERENCE_TIME time_per_frame = 0;
520 523
521 VIDEOINFOHEADER* h = 524 VIDEOINFOHEADER* h =
522 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); 525 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat);
523 capability.width = h->bmiHeader.biWidth; 526 capability.width = h->bmiHeader.biWidth;
524 capability.height = h->bmiHeader.biHeight; 527 capability.height = h->bmiHeader.biHeight;
525 time_per_frame = h->AvgTimePerFrame; 528 time_per_frame = h->AvgTimePerFrame;
526 529
527 // Try to get the max frame rate from IAMVideoControl. 530 // Try to get the max frame rate from IAMVideoControl.
528 if (video_control.get()) { 531 if (video_control.get()) {
(...skipping 23 matching lines...) Expand all
552 } 555 }
553 } else { 556 } else {
554 // Get frame rate from VIDEOINFOHEADER since IAMVideoControl is 557 // Get frame rate from VIDEOINFOHEADER since IAMVideoControl is
555 // not supported. 558 // not supported.
556 capability.frame_rate = (time_per_frame > 0) ? 559 capability.frame_rate = (time_per_frame > 0) ?
557 static_cast<int>(kSecondsToReferenceTime / time_per_frame) : 0; 560 static_cast<int>(kSecondsToReferenceTime / time_per_frame) : 0;
558 } 561 }
559 562
560 // We can't switch MEDIATYPE :~(. 563 // We can't switch MEDIATYPE :~(.
561 if (media_type->subtype == kMediaSubTypeI420) { 564 if (media_type->subtype == kMediaSubTypeI420) {
562 capability.color = VideoCaptureDevice::kI420; 565 capability.color = VideoCaptureCapability::kI420;
563 } else if (media_type->subtype == MEDIASUBTYPE_IYUV) { 566 } else if (media_type->subtype == MEDIASUBTYPE_IYUV) {
564 // This is identical to kI420. 567 // This is identical to kI420.
565 capability.color = VideoCaptureDevice::kI420; 568 capability.color = VideoCaptureCapability::kI420;
566 } else if (media_type->subtype == MEDIASUBTYPE_RGB24) { 569 } else if (media_type->subtype == MEDIASUBTYPE_RGB24) {
567 capability.color = VideoCaptureDevice::kRGB24; 570 capability.color = VideoCaptureCapability::kRGB24;
568 } else if (media_type->subtype == MEDIASUBTYPE_YUY2) { 571 } else if (media_type->subtype == MEDIASUBTYPE_YUY2) {
569 capability.color = VideoCaptureDevice::kYUY2; 572 capability.color = VideoCaptureCapability::kYUY2;
570 } else if (media_type->subtype == MEDIASUBTYPE_MJPG) { 573 } else if (media_type->subtype == MEDIASUBTYPE_MJPG) {
571 capability.color = VideoCaptureDevice::kMJPEG; 574 capability.color = VideoCaptureCapability::kMJPEG;
572 } else { 575 } else {
573 WCHAR guid_str[128]; 576 WCHAR guid_str[128];
574 StringFromGUID2(media_type->subtype, guid_str, arraysize(guid_str)); 577 StringFromGUID2(media_type->subtype, guid_str, arraysize(guid_str));
575 DVLOG(2) << "Device support unknown media type " << guid_str; 578 DVLOG(2) << "Device support unknown media type " << guid_str;
576 continue; 579 continue;
577 } 580 }
578 capabilities_[i] = capability; 581 capabilities_[i] = capability;
579 } 582 }
580 DeleteMediaType(media_type); 583 DeleteMediaType(media_type);
581 media_type = NULL; 584 media_type = NULL;
582 } 585 }
583 586
584 return capabilities_.size() > 0; 587 return capabilities_.size() > 0;
585 } 588 }
586 589
587 // Loops through the list of capabilities and returns an index of the best 590 // Loops through the list of capabilities and returns an index of the best
588 // matching capability. 591 // matching capability.
589 // The algorithm prioritize height, width, frame rate and color format in that 592 // The algorithm prioritize height, width, frame rate and color format in that
590 // order. 593 // order.
591 int VideoCaptureDeviceWin::GetBestMatchedCapability(int requested_width, 594 int VideoCaptureDeviceWin::GetBestMatchedCapability(int requested_width,
592 int requested_height, 595 int requested_height,
593 int requested_frame_rate) { 596 int requested_frame_rate) {
594 std::list<ResolutionDiff> diff_list; 597 std::list<ResolutionDiff> diff_list;
595 598
596 // Loop through the candidates to create a list of differentials between the 599 // Loop through the candidates to create a list of differentials between the
597 // requested resolution and the camera capability. 600 // requested resolution and the camera capability.
598 for (CapabilityMap::iterator iterator = capabilities_.begin(); 601 for (CapabilityMap::iterator iterator = capabilities_.begin();
599 iterator != capabilities_.end(); 602 iterator != capabilities_.end();
600 ++iterator) { 603 ++iterator) {
601 Capability capability = iterator->second; 604 VideoCaptureCapability capability = iterator->second;
602 605
603 ResolutionDiff diff; 606 ResolutionDiff diff;
604 diff.capability_index = iterator->first; 607 diff.capability_index = iterator->first;
605 diff.diff_width = capability.width - requested_width; 608 diff.diff_width = capability.width - requested_width;
606 diff.diff_height = capability.height - requested_height; 609 diff.diff_height = capability.height - requested_height;
607 diff.diff_frame_rate = capability.frame_rate - requested_frame_rate; 610 diff.diff_frame_rate = capability.frame_rate - requested_frame_rate;
608 diff.color = capability.color; 611 diff.color = capability.color;
609 diff_list.push_back(diff); 612 diff_list.push_back(diff);
610 } 613 }
611 614
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 return diff_list.front().capability_index; 652 return diff_list.front().capability_index;
650 } 653 }
651 654
652 void VideoCaptureDeviceWin::SetErrorState(const char* reason) { 655 void VideoCaptureDeviceWin::SetErrorState(const char* reason) {
653 DLOG(ERROR) << reason; 656 DLOG(ERROR) << reason;
654 state_ = kError; 657 state_ = kError;
655 observer_->OnError(); 658 observer_->OnError();
656 } 659 }
657 660
658 } // namespace media 661 } // namespace media
OLDNEW
« no previous file with comments | « media/video/capture/win/video_capture_device_win.h ('k') | webkit/plugins/ppapi/ppb_video_capture_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698