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

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: Created 8 years, 8 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::VideoFrame::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 media::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 == media::VideoFrame::kMJPEG && !mjpg_filter_.get()) {
377 // Create MJPG filter if we need it. 377 // Create MJPG filter if we need it.
378 hr = mjpg_filter_.CreateInstance(CLSID_MjpegDec, NULL, CLSCTX_INPROC); 378 hr = mjpg_filter_.CreateInstance(CLSID_MjpegDec, NULL, CLSCTX_INPROC);
379 379
380 if (SUCCEEDED(hr)) { 380 if (SUCCEEDED(hr)) {
381 GetPin(mjpg_filter_, PINDIR_INPUT, GUID_NULL, input_mjpg_pin_.Receive()); 381 GetPin(mjpg_filter_, PINDIR_INPUT, GUID_NULL, input_mjpg_pin_.Receive());
382 GetPin(mjpg_filter_, PINDIR_OUTPUT, GUID_NULL, 382 GetPin(mjpg_filter_, PINDIR_OUTPUT, GUID_NULL,
383 output_mjpg_pin_.Receive()); 383 output_mjpg_pin_.Receive());
384 hr = graph_builder_->AddFilter(mjpg_filter_, NULL); 384 hr = graph_builder_->AddFilter(mjpg_filter_, NULL);
385 } 385 }
386 386
387 if (FAILED(hr)) { 387 if (FAILED(hr)) {
388 mjpg_filter_.Release(); 388 mjpg_filter_.Release();
389 input_mjpg_pin_.Release(); 389 input_mjpg_pin_.Release();
390 output_mjpg_pin_.Release(); 390 output_mjpg_pin_.Release();
391 } 391 }
392 } 392 }
393 393
394 if (capability.color == VideoCaptureDevice::kMJPEG && mjpg_filter_.get()) { 394 if (capability.color == media::VideoFrame::kMJPEG && mjpg_filter_.get()) {
395 // Connect the camera to the MJPEG decoder. 395 // Connect the camera to the MJPEG decoder.
396 hr = graph_builder_->ConnectDirect(output_capture_pin_, input_mjpg_pin_, 396 hr = graph_builder_->ConnectDirect(output_capture_pin_, input_mjpg_pin_,
397 NULL); 397 NULL);
398 // Connect the MJPEG filter to the Capture filter. 398 // Connect the MJPEG filter to the Capture filter.
399 hr += graph_builder_->ConnectDirect(output_mjpg_pin_, input_sink_pin_, 399 hr += graph_builder_->ConnectDirect(output_mjpg_pin_, input_sink_pin_,
400 NULL); 400 NULL);
401 } else { 401 } else {
402 hr = graph_builder_->ConnectDirect(output_capture_pin_, input_sink_pin_, 402 hr = graph_builder_->ConnectDirect(output_capture_pin_, input_sink_pin_,
403 NULL); 403 NULL);
404 } 404 }
405 405
406 if (FAILED(hr)) { 406 if (FAILED(hr)) {
407 SetErrorState("Failed to connect the Capture graph."); 407 SetErrorState("Failed to connect the Capture graph.");
408 return; 408 return;
409 } 409 }
410 410
411 hr = media_control_->Pause(); 411 hr = media_control_->Pause();
412 if (FAILED(hr)) { 412 if (FAILED(hr)) {
413 SetErrorState("Failed to Pause the Capture device. " 413 SetErrorState("Failed to Pause the Capture device. "
414 "Is it already occupied?"); 414 "Is it already occupied?");
415 return; 415 return;
416 } 416 }
417 417
418 // Get the capability back from the sink filter after the filter have been 418 // Get the capability back from the sink filter after the filter have been
419 // connected. 419 // connected.
420 const Capability& used_capability = sink_filter_->ResultingCapability(); 420 const media::VideoCaptureCapability& used_capability =
421 sink_filter_->ResultingCapability();
421 observer_->OnFrameInfo(used_capability); 422 observer_->OnFrameInfo(used_capability);
422 423
423 state_ = kAllocated; 424 state_ = kAllocated;
424 } 425 }
425 426
426 void VideoCaptureDeviceWin::Start() { 427 void VideoCaptureDeviceWin::Start() {
427 if (state_ != kAllocated) 428 if (state_ != kAllocated)
428 return; 429 return;
429 430
430 HRESULT hr = media_control_->Run(); 431 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) { 509 for (int i = 0; i < count; ++i) {
509 hr = stream_config->GetStreamCaps(i, &media_type, 510 hr = stream_config->GetStreamCaps(i, &media_type,
510 reinterpret_cast<BYTE*>(&caps)); 511 reinterpret_cast<BYTE*>(&caps));
511 if (FAILED(hr)) { 512 if (FAILED(hr)) {
512 DVLOG(2) << "Failed to GetStreamCaps"; 513 DVLOG(2) << "Failed to GetStreamCaps";
513 return false; 514 return false;
514 } 515 }
515 516
516 if (media_type->majortype == MEDIATYPE_Video && 517 if (media_type->majortype == MEDIATYPE_Video &&
517 media_type->formattype == FORMAT_VideoInfo) { 518 media_type->formattype == FORMAT_VideoInfo) {
518 Capability capability; 519 media::VideoCaptureCapability capability;
519 REFERENCE_TIME time_per_frame = 0; 520 REFERENCE_TIME time_per_frame = 0;
520 521
521 VIDEOINFOHEADER* h = 522 VIDEOINFOHEADER* h =
522 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); 523 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat);
523 capability.width = h->bmiHeader.biWidth; 524 capability.width = h->bmiHeader.biWidth;
524 capability.height = h->bmiHeader.biHeight; 525 capability.height = h->bmiHeader.biHeight;
525 time_per_frame = h->AvgTimePerFrame; 526 time_per_frame = h->AvgTimePerFrame;
526 527
527 // Try to get the max frame rate from IAMVideoControl. 528 // Try to get the max frame rate from IAMVideoControl.
528 if (video_control.get()) { 529 if (video_control.get()) {
(...skipping 23 matching lines...) Expand all
552 } 553 }
553 } else { 554 } else {
554 // Get frame rate from VIDEOINFOHEADER since IAMVideoControl is 555 // Get frame rate from VIDEOINFOHEADER since IAMVideoControl is
555 // not supported. 556 // not supported.
556 capability.frame_rate = (time_per_frame > 0) ? 557 capability.frame_rate = (time_per_frame > 0) ?
557 static_cast<int>(kSecondsToReferenceTime / time_per_frame) : 0; 558 static_cast<int>(kSecondsToReferenceTime / time_per_frame) : 0;
558 } 559 }
559 560
560 // We can't switch MEDIATYPE :~(. 561 // We can't switch MEDIATYPE :~(.
561 if (media_type->subtype == kMediaSubTypeI420) { 562 if (media_type->subtype == kMediaSubTypeI420) {
562 capability.color = VideoCaptureDevice::kI420; 563 capability.color = media::VideoFrame::kI420;
563 } else if (media_type->subtype == MEDIASUBTYPE_IYUV) { 564 } else if (media_type->subtype == MEDIASUBTYPE_IYUV) {
564 // This is identical to kI420. 565 // This is identical to kI420.
565 capability.color = VideoCaptureDevice::kI420; 566 capability.color = media::VideoFrame::kI420;
566 } else if (media_type->subtype == MEDIASUBTYPE_RGB24) { 567 } else if (media_type->subtype == MEDIASUBTYPE_RGB24) {
567 capability.color = VideoCaptureDevice::kRGB24; 568 capability.color = media::VideoFrame::kRGB24;
568 } else if (media_type->subtype == MEDIASUBTYPE_YUY2) { 569 } else if (media_type->subtype == MEDIASUBTYPE_YUY2) {
569 capability.color = VideoCaptureDevice::kYUY2; 570 capability.color = media::VideoFrame::kYUY2;
570 } else if (media_type->subtype == MEDIASUBTYPE_MJPG) { 571 } else if (media_type->subtype == MEDIASUBTYPE_MJPG) {
571 capability.color = VideoCaptureDevice::kMJPEG; 572 capability.color = media::VideoFrame::kMJPEG;
572 } else { 573 } else {
573 WCHAR guid_str[128]; 574 WCHAR guid_str[128];
574 StringFromGUID2(media_type->subtype, guid_str, arraysize(guid_str)); 575 StringFromGUID2(media_type->subtype, guid_str, arraysize(guid_str));
575 DVLOG(2) << "Device support unknown media type " << guid_str; 576 DVLOG(2) << "Device support unknown media type " << guid_str;
576 continue; 577 continue;
577 } 578 }
578 capabilities_[i] = capability; 579 capabilities_[i] = capability;
579 } 580 }
580 DeleteMediaType(media_type); 581 DeleteMediaType(media_type);
581 media_type = NULL; 582 media_type = NULL;
582 } 583 }
583 584
584 return capabilities_.size() > 0; 585 return capabilities_.size() > 0;
585 } 586 }
586 587
587 // Loops through the list of capabilities and returns an index of the best 588 // Loops through the list of capabilities and returns an index of the best
588 // matching capability. 589 // matching capability.
589 // The algorithm prioritize height, width, frame rate and color format in that 590 // The algorithm prioritize height, width, frame rate and color format in that
590 // order. 591 // order.
591 int VideoCaptureDeviceWin::GetBestMatchedCapability(int requested_width, 592 int VideoCaptureDeviceWin::GetBestMatchedCapability(int requested_width,
592 int requested_height, 593 int requested_height,
593 int requested_frame_rate) { 594 int requested_frame_rate) {
594 std::list<ResolutionDiff> diff_list; 595 std::list<ResolutionDiff> diff_list;
595 596
596 // Loop through the candidates to create a list of differentials between the 597 // Loop through the candidates to create a list of differentials between the
597 // requested resolution and the camera capability. 598 // requested resolution and the camera capability.
598 for (CapabilityMap::iterator iterator = capabilities_.begin(); 599 for (CapabilityMap::iterator iterator = capabilities_.begin();
599 iterator != capabilities_.end(); 600 iterator != capabilities_.end();
600 ++iterator) { 601 ++iterator) {
601 Capability capability = iterator->second; 602 media::VideoCaptureCapability capability = iterator->second;
602 603
603 ResolutionDiff diff; 604 ResolutionDiff diff;
604 diff.capability_index = iterator->first; 605 diff.capability_index = iterator->first;
605 diff.diff_width = capability.width - requested_width; 606 diff.diff_width = capability.width - requested_width;
606 diff.diff_height = capability.height - requested_height; 607 diff.diff_height = capability.height - requested_height;
607 diff.diff_frame_rate = capability.frame_rate - requested_frame_rate; 608 diff.diff_frame_rate = capability.frame_rate - requested_frame_rate;
608 diff.color = capability.color; 609 diff.color = capability.color;
609 diff_list.push_back(diff); 610 diff_list.push_back(diff);
610 } 611 }
611 612
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 return diff_list.front().capability_index; 650 return diff_list.front().capability_index;
650 } 651 }
651 652
652 void VideoCaptureDeviceWin::SetErrorState(const char* reason) { 653 void VideoCaptureDeviceWin::SetErrorState(const char* reason) {
653 DLOG(ERROR) << reason; 654 DLOG(ERROR) << reason;
654 state_ = kError; 655 state_ = kError;
655 observer_->OnError(); 656 observer_->OnError();
656 } 657 }
657 658
658 } // namespace media 659 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698