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

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

Issue 558623002: Video capture: Refactor GetBestMatchedFormat from Win to OS independent (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove braces in if statement Created 6 years, 2 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
« no previous file with comments | « media/video/capture/win/video_capture_device_mf_win.cc ('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 <ks.h> 7 #include <ks.h>
8 #include <ksmedia.h> 8 #include <ksmedia.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 311
312 void VideoCaptureDeviceWin::AllocateAndStart( 312 void VideoCaptureDeviceWin::AllocateAndStart(
313 const VideoCaptureParams& params, 313 const VideoCaptureParams& params,
314 scoped_ptr<VideoCaptureDevice::Client> client) { 314 scoped_ptr<VideoCaptureDevice::Client> client) {
315 DCHECK(CalledOnValidThread()); 315 DCHECK(CalledOnValidThread());
316 if (state_ != kIdle) 316 if (state_ != kIdle)
317 return; 317 return;
318 318
319 client_ = client.Pass(); 319 client_ = client.Pass();
320 320
321 // Get the camera capability that best match the requested resolution. 321 // Get the camera capability that best match the requested format.
322 const VideoCaptureCapabilityWin& found_capability = 322 const CapabilityWin found_capability =
323 capabilities_.GetBestMatchedFormat( 323 GetBestMatchedCapability(params.requested_format, capabilities_);
324 params.requested_format.frame_size.width(),
325 params.requested_format.frame_size.height(),
326 params.requested_format.frame_rate);
327 VideoCaptureFormat format = found_capability.supported_format; 324 VideoCaptureFormat format = found_capability.supported_format;
328 325
329 // Reduce the frame rate if the requested frame rate is lower 326 // Reduce the frame rate if the requested frame rate is lower
330 // than the capability. 327 // than the capability.
331 if (format.frame_rate > params.requested_format.frame_rate) 328 format.frame_rate =
332 format.frame_rate = params.requested_format.frame_rate; 329 std::min(format.frame_rate, params.requested_format.frame_rate);
333 330
334 ScopedComPtr<IAMStreamConfig> stream_config; 331 ScopedComPtr<IAMStreamConfig> stream_config;
335 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); 332 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive());
336 if (FAILED(hr)) { 333 if (FAILED(hr)) {
337 SetErrorState("Can't get the Capture format settings"); 334 SetErrorState("Can't get the Capture format settings");
338 return; 335 return;
339 } 336 }
340 337
341 int count = 0, size = 0; 338 int count = 0, size = 0;
342 hr = stream_config->GetNumberOfCapabilities(&count, &size); 339 hr = stream_config->GetNumberOfCapabilities(&count, &size);
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 491
495 int count = 0, size = 0; 492 int count = 0, size = 0;
496 hr = stream_config->GetNumberOfCapabilities(&count, &size); 493 hr = stream_config->GetNumberOfCapabilities(&count, &size);
497 if (FAILED(hr)) { 494 if (FAILED(hr)) {
498 DLOG(ERROR) << "Failed to GetNumberOfCapabilities: " 495 DLOG(ERROR) << "Failed to GetNumberOfCapabilities: "
499 << logging::SystemErrorCodeToString(hr); 496 << logging::SystemErrorCodeToString(hr);
500 return false; 497 return false;
501 } 498 }
502 499
503 scoped_ptr<BYTE[]> caps(new BYTE[size]); 500 scoped_ptr<BYTE[]> caps(new BYTE[size]);
504 for (int i = 0; i < count; ++i) { 501 for (int stream_index = 0; stream_index < count; ++stream_index) {
505 ScopedMediaType media_type; 502 ScopedMediaType media_type;
506 hr = stream_config->GetStreamCaps(i, media_type.Receive(), caps.get()); 503 hr = stream_config->GetStreamCaps(
504 stream_index, media_type.Receive(), caps.get());
507 // GetStreamCaps() may return S_FALSE, so don't use FAILED() or SUCCEED() 505 // GetStreamCaps() may return S_FALSE, so don't use FAILED() or SUCCEED()
508 // macros here since they'll trigger incorrectly. 506 // macros here since they'll trigger incorrectly.
509 if (hr != S_OK) { 507 if (hr != S_OK) {
510 DLOG(ERROR) << "Failed to GetStreamCaps: " 508 DLOG(ERROR) << "Failed to GetStreamCaps: "
511 << logging::SystemErrorCodeToString(hr); 509 << logging::SystemErrorCodeToString(hr);
512 return false; 510 return false;
513 } 511 }
514 512
515 if (media_type->majortype == MEDIATYPE_Video && 513 if (media_type->majortype == MEDIATYPE_Video &&
516 media_type->formattype == FORMAT_VideoInfo) { 514 media_type->formattype == FORMAT_VideoInfo) {
517 VideoCaptureCapabilityWin capability(i); 515 VideoCaptureFormat format;
518 capability.supported_format.pixel_format = 516 format.pixel_format =
519 TranslateMediaSubtypeToPixelFormat(media_type->subtype); 517 TranslateMediaSubtypeToPixelFormat(media_type->subtype);
520 if (capability.supported_format.pixel_format == PIXEL_FORMAT_UNKNOWN) 518 if (format.pixel_format == PIXEL_FORMAT_UNKNOWN)
521 continue; 519 continue;
522 520
523 VIDEOINFOHEADER* h = 521 VIDEOINFOHEADER* h =
524 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); 522 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat);
525 capability.supported_format.frame_size.SetSize(h->bmiHeader.biWidth, 523 format.frame_size.SetSize(h->bmiHeader.biWidth, h->bmiHeader.biHeight);
526 h->bmiHeader.biHeight);
527 524
528 // Try to get a better |time_per_frame| from IAMVideoControl. If not, use 525 // Try to get a better |time_per_frame| from IAMVideoControl. If not, use
529 // the value from VIDEOINFOHEADER. 526 // the value from VIDEOINFOHEADER.
530 REFERENCE_TIME time_per_frame = h->AvgTimePerFrame; 527 REFERENCE_TIME time_per_frame = h->AvgTimePerFrame;
531 if (video_control) { 528 if (video_control) {
532 ScopedCoMem<LONGLONG> max_fps; 529 ScopedCoMem<LONGLONG> max_fps;
533 LONG list_size = 0; 530 LONG list_size = 0;
534 SIZE size = {capability.supported_format.frame_size.width(), 531 const SIZE size = {format.frame_size.width(),
535 capability.supported_format.frame_size.height()}; 532 format.frame_size.height()};
536 533 hr = video_control->GetFrameRateList(
537 // GetFrameRateList doesn't return max frame rate always 534 output_capture_pin_, stream_index, size, &list_size, &max_fps);
538 // eg: Logitech Notebook. This may be due to a bug in that API 535 // Can't assume the first value will return the max fps.
539 // because GetFrameRateList array is reversed in the above camera. So 536 // Sometimes |list_size| will be > 0, but max_fps will be NULL. Some
540 // a util method written. Can't assume the first value will return
541 // the max fps.
542 hr = video_control->GetFrameRateList(output_capture_pin_, i, size,
543 &list_size, &max_fps);
544 // Sometimes |list_size| will be > 0, but max_fps will be NULL. Some
545 // drivers may return an HRESULT of S_FALSE which SUCCEEDED() translates 537 // drivers may return an HRESULT of S_FALSE which SUCCEEDED() translates
546 // into success, so explicitly check S_OK. See http://crbug.com/306237. 538 // into success, so explicitly check S_OK. See http://crbug.com/306237.
547 if (hr == S_OK && list_size > 0 && max_fps) { 539 if (hr == S_OK && list_size > 0 && max_fps) {
548 time_per_frame = *std::min_element(max_fps.get(), 540 time_per_frame = *std::min_element(max_fps.get(),
549 max_fps.get() + list_size); 541 max_fps.get() + list_size);
550 } 542 }
551 } 543 }
552 544
553 capability.supported_format.frame_rate = 545 format.frame_rate =
554 (time_per_frame > 0) 546 (time_per_frame > 0)
555 ? (kSecondsToReferenceTime / static_cast<float>(time_per_frame)) 547 ? (kSecondsToReferenceTime / static_cast<float>(time_per_frame))
556 : 0.0; 548 : 0.0;
557 549
558 // DirectShow works at the moment only on integer frame_rate but the 550 capabilities_.emplace_back(stream_index, format);
559 // best capability matching class works on rational frame rates.
560 capability.frame_rate_numerator = capability.supported_format.frame_rate;
561 capability.frame_rate_denominator = 1;
562
563 capabilities_.Add(capability);
564 } 551 }
565 } 552 }
566 553
567 return !capabilities_.empty(); 554 return !capabilities_.empty();
568 } 555 }
569 556
570 // Set the power line frequency removal in |capture_filter_| if available. 557 // Set the power line frequency removal in |capture_filter_| if available.
571 void VideoCaptureDeviceWin::SetAntiFlickerInCaptureFilter() { 558 void VideoCaptureDeviceWin::SetAntiFlickerInCaptureFilter() {
572 const int power_line_frequency = GetPowerLineFrequencyForLocation(); 559 const int power_line_frequency = GetPowerLineFrequencyForLocation();
573 if (power_line_frequency != kPowerLine50Hz && 560 if (power_line_frequency != kPowerLine50Hz &&
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 return E_FAIL; 640 return E_FAIL;
654 return S_OK; 641 return S_OK;
655 } 642 }
656 643
657 void VideoCaptureDeviceWin::SetErrorState(const std::string& reason) { 644 void VideoCaptureDeviceWin::SetErrorState(const std::string& reason) {
658 DCHECK(CalledOnValidThread()); 645 DCHECK(CalledOnValidThread());
659 state_ = kError; 646 state_ = kError;
660 client_->OnError(reason); 647 client_->OnError(reason);
661 } 648 }
662 } // namespace media 649 } // namespace media
OLDNEW
« no previous file with comments | « media/video/capture/win/video_capture_device_mf_win.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698