Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/capture/video/win/video_capture_device_win.h" | 5 #include "media/capture/video/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 #include <objbase.h> | 9 #include <objbase.h> |
| 10 #include <vidcap.h> | |
| 11 | 10 |
| 12 #include <algorithm> | 11 #include <algorithm> |
| 13 #include <list> | 12 #include <list> |
| 14 #include <utility> | 13 #include <utility> |
| 15 | 14 |
| 16 #include "base/macros.h" | 15 #include "base/macros.h" |
| 17 #include "base/strings/sys_string_conversions.h" | 16 #include "base/strings/sys_string_conversions.h" |
| 18 #include "base/win/scoped_co_mem.h" | 17 #include "base/win/scoped_co_mem.h" |
| 19 #include "base/win/scoped_variant.h" | 18 #include "base/win/scoped_variant.h" |
| 20 #include "media/base/timestamp_constants.h" | 19 #include "media/base/timestamp_constants.h" |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 259 void VideoCaptureDeviceWin::ScopedMediaType::DeleteMediaType( | 258 void VideoCaptureDeviceWin::ScopedMediaType::DeleteMediaType( |
| 260 AM_MEDIA_TYPE* mt) { | 259 AM_MEDIA_TYPE* mt) { |
| 261 if (mt != NULL) { | 260 if (mt != NULL) { |
| 262 FreeMediaType(mt); | 261 FreeMediaType(mt); |
| 263 CoTaskMemFree(mt); | 262 CoTaskMemFree(mt); |
| 264 } | 263 } |
| 265 } | 264 } |
| 266 | 265 |
| 267 VideoCaptureDeviceWin::VideoCaptureDeviceWin( | 266 VideoCaptureDeviceWin::VideoCaptureDeviceWin( |
| 268 const VideoCaptureDeviceDescriptor& device_descriptor) | 267 const VideoCaptureDeviceDescriptor& device_descriptor) |
| 269 : device_descriptor_(device_descriptor), state_(kIdle) { | 268 : device_descriptor_(device_descriptor), |
| 269 state_(kIdle), | |
| 270 white_balance_mode_manual_(false), | |
| 271 exposure_mode_manual_(false) { | |
| 270 // TODO(mcasas): Check that CoInitializeEx() has been called with the | 272 // TODO(mcasas): Check that CoInitializeEx() has been called with the |
| 271 // appropriate Apartment model, i.e., Single Threaded. | 273 // appropriate Apartment model, i.e., Single Threaded. |
| 272 } | 274 } |
| 273 | 275 |
| 274 VideoCaptureDeviceWin::~VideoCaptureDeviceWin() { | 276 VideoCaptureDeviceWin::~VideoCaptureDeviceWin() { |
| 275 DCHECK(thread_checker_.CalledOnValidThread()); | 277 DCHECK(thread_checker_.CalledOnValidThread()); |
| 276 if (media_control_.Get()) | 278 if (media_control_.Get()) |
| 277 media_control_->Stop(); | 279 media_control_->Stop(); |
| 278 | 280 |
| 279 if (graph_builder_.Get()) { | 281 if (graph_builder_.Get()) { |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 424 // Set the sink filter to request this format. | 426 // Set the sink filter to request this format. |
| 425 sink_filter_->SetRequestedMediaFormat( | 427 sink_filter_->SetRequestedMediaFormat( |
| 426 found_capability.supported_format.pixel_format, frame_rate, | 428 found_capability.supported_format.pixel_format, frame_rate, |
| 427 found_capability.info_header); | 429 found_capability.info_header); |
| 428 // Order the capture device to use this format. | 430 // Order the capture device to use this format. |
| 429 hr = stream_config->SetFormat(media_type.get()); | 431 hr = stream_config->SetFormat(media_type.get()); |
| 430 if (FAILED(hr)) { | 432 if (FAILED(hr)) { |
| 431 SetErrorState(FROM_HERE, "Failed to set capture device output format", hr); | 433 SetErrorState(FROM_HERE, "Failed to set capture device output format", hr); |
| 432 return; | 434 return; |
| 433 } | 435 } |
| 436 current_capture_format_ = found_capability.supported_format; | |
| 434 | 437 |
| 435 SetAntiFlickerInCaptureFilter(params); | 438 SetAntiFlickerInCaptureFilter(params); |
| 436 | 439 |
| 437 if (media_type->subtype == kMediaSubTypeHDYC) { | 440 if (media_type->subtype == kMediaSubTypeHDYC) { |
| 438 // HDYC pixel format, used by the DeckLink capture card, needs an AVI | 441 // HDYC pixel format, used by the DeckLink capture card, needs an AVI |
| 439 // decompressor filter after source, let |graph_builder_| add it. | 442 // decompressor filter after source, let |graph_builder_| add it. |
| 440 hr = graph_builder_->Connect(output_capture_pin_.Get(), | 443 hr = graph_builder_->Connect(output_capture_pin_.Get(), |
| 441 input_sink_pin_.Get()); | 444 input_sink_pin_.Get()); |
| 442 } else { | 445 } else { |
| 443 hr = graph_builder_->ConnectDirect(output_capture_pin_.Get(), | 446 hr = graph_builder_->ConnectDirect(output_capture_pin_.Get(), |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 457 | 460 |
| 458 // Start capturing. | 461 // Start capturing. |
| 459 hr = media_control_->Run(); | 462 hr = media_control_->Run(); |
| 460 if (FAILED(hr)) { | 463 if (FAILED(hr)) { |
| 461 SetErrorState(FROM_HERE, "Failed to start the Capture device.", hr); | 464 SetErrorState(FROM_HERE, "Failed to start the Capture device.", hr); |
| 462 return; | 465 return; |
| 463 } | 466 } |
| 464 | 467 |
| 465 client_->OnStarted(); | 468 client_->OnStarted(); |
| 466 state_ = kCapturing; | 469 state_ = kCapturing; |
| 467 } | |
| 468 | |
| 469 void VideoCaptureDeviceWin::StopAndDeAllocate() { | |
| 470 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 471 if (state_ != kCapturing) | |
| 472 return; | |
| 473 | |
| 474 HRESULT hr = media_control_->Stop(); | |
| 475 if (FAILED(hr)) { | |
| 476 SetErrorState(FROM_HERE, "Failed to stop the capture graph.", hr); | |
| 477 return; | |
| 478 } | |
| 479 | |
| 480 graph_builder_->Disconnect(output_capture_pin_.Get()); | |
| 481 graph_builder_->Disconnect(input_sink_pin_.Get()); | |
| 482 | |
| 483 client_.reset(); | |
| 484 state_ = kIdle; | |
| 485 } | |
| 486 | |
| 487 void VideoCaptureDeviceWin::TakePhoto(TakePhotoCallback callback) { | |
| 488 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 489 // DirectShow has other means of capturing still pictures, e.g. connecting a | |
| 490 // SampleGrabber filter to a PIN_CATEGORY_STILL of |capture_filter_|. This | |
| 491 // way, however, is not widespread and proves too cumbersome, so we just grab | |
| 492 // the next captured frame instead. | |
| 493 take_photo_callbacks_.push(std::move(callback)); | |
| 494 } | |
| 495 | |
| 496 void VideoCaptureDeviceWin::GetPhotoCapabilities( | |
| 497 GetPhotoCapabilitiesCallback callback) { | |
| 498 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 499 | 470 |
| 500 base::win::ScopedComPtr<IKsTopologyInfo> info; | 471 base::win::ScopedComPtr<IKsTopologyInfo> info; |
| 501 HRESULT hr = capture_filter_.CopyTo(info.GetAddressOf()); | 472 hr = capture_filter_.CopyTo(info.GetAddressOf()); |
| 502 if (FAILED(hr)) { | 473 if (FAILED(hr)) { |
| 503 SetErrorState(FROM_HERE, "Failed to obtain the topology info.", hr); | 474 SetErrorState(FROM_HERE, "Failed to obtain the topology info.", hr); |
| 504 return; | 475 return; |
| 505 } | 476 } |
| 506 | 477 |
| 507 DWORD num_nodes = 0; | 478 DWORD num_nodes = 0; |
| 508 hr = info->get_NumNodes(&num_nodes); | 479 hr = info->get_NumNodes(&num_nodes); |
| 509 if (FAILED(hr)) { | 480 if (FAILED(hr)) { |
| 510 SetErrorState(FROM_HERE, "Failed to obtain the number of nodes.", hr); | 481 SetErrorState(FROM_HERE, "Failed to obtain the number of nodes.", hr); |
| 511 return; | 482 return; |
| 512 } | 483 } |
| 513 | 484 |
| 514 // Every UVC camera is expected to have a single ICameraControl and a single | 485 // Every UVC camera is expected to have a single ICameraControl and a single |
| 515 // IVideoProcAmp nodes, and both are needed; ignore any unlikely later ones. | 486 // IVideoProcAmp nodes, and both are needed; ignore any unlikely later ones. |
| 516 GUID node_type; | 487 GUID node_type; |
| 517 base::win::ScopedComPtr<ICameraControl> camera_control; | |
| 518 for (size_t i = 0; i < num_nodes; i++) { | 488 for (size_t i = 0; i < num_nodes; i++) { |
| 519 info->get_NodeType(i, &node_type); | 489 info->get_NodeType(i, &node_type); |
| 520 if (IsEqualGUID(node_type, KSNODETYPE_VIDEO_CAMERA_TERMINAL)) { | 490 if (IsEqualGUID(node_type, KSNODETYPE_VIDEO_CAMERA_TERMINAL)) { |
| 521 hr = info->CreateNodeInstance(i, IID_PPV_ARGS(&camera_control)); | 491 hr = info->CreateNodeInstance( |
| 492 i, IID_PPV_ARGS(camera_control_.GetAddressOf())); | |
|
robliao
2017/05/12 19:34:30
IID_PPV_ARGS(&camera_control) should continue to w
mcasas
2017/05/12 21:27:04
Oops, wrong rebase. Reverted and still working.
| |
| 522 if (SUCCEEDED(hr)) | 493 if (SUCCEEDED(hr)) |
| 523 break; | 494 break; |
| 524 SetErrorState(FROM_HERE, "Failed to retrieve the ICameraControl.", hr); | 495 SetErrorState(FROM_HERE, "Failed to retrieve the ICameraControl.", hr); |
| 525 return; | 496 return; |
| 526 } | 497 } |
| 527 } | 498 } |
| 528 if (!camera_control) | |
| 529 return; | |
| 530 base::win::ScopedComPtr<IVideoProcAmp> video_control; | |
| 531 for (size_t i = 0; i < num_nodes; i++) { | 499 for (size_t i = 0; i < num_nodes; i++) { |
| 532 info->get_NodeType(i, &node_type); | 500 info->get_NodeType(i, &node_type); |
| 533 if (IsEqualGUID(node_type, KSNODETYPE_VIDEO_PROCESSING)) { | 501 if (IsEqualGUID(node_type, KSNODETYPE_VIDEO_PROCESSING)) { |
| 534 hr = info->CreateNodeInstance(i, IID_PPV_ARGS(&video_control)); | 502 hr = info->CreateNodeInstance( |
| 503 i, IID_PPV_ARGS(video_control_.GetAddressOf())); | |
| 535 if (SUCCEEDED(hr)) | 504 if (SUCCEEDED(hr)) |
| 536 break; | 505 break; |
| 537 SetErrorState(FROM_HERE, "Failed to retrieve the IVideoProcAmp.", hr); | 506 SetErrorState(FROM_HERE, "Failed to retrieve the IVideoProcAmp.", hr); |
| 538 return; | 507 return; |
| 539 } | 508 } |
| 540 } | 509 } |
| 541 if (!video_control) | 510 } |
| 511 | |
| 512 void VideoCaptureDeviceWin::StopAndDeAllocate() { | |
| 513 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 514 if (state_ != kCapturing) | |
| 515 return; | |
| 516 | |
| 517 HRESULT hr = media_control_->Stop(); | |
| 518 if (FAILED(hr)) { | |
| 519 SetErrorState(FROM_HERE, "Failed to stop the capture graph.", hr); | |
| 520 return; | |
| 521 } | |
| 522 | |
| 523 graph_builder_->Disconnect(output_capture_pin_.Get()); | |
| 524 graph_builder_->Disconnect(input_sink_pin_.Get()); | |
| 525 | |
| 526 client_.reset(); | |
| 527 state_ = kIdle; | |
| 528 } | |
| 529 | |
| 530 void VideoCaptureDeviceWin::TakePhoto(TakePhotoCallback callback) { | |
| 531 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 532 // DirectShow has other means of capturing still pictures, e.g. connecting a | |
| 533 // SampleGrabber filter to a PIN_CATEGORY_STILL of |capture_filter_|. This | |
| 534 // way, however, is not widespread and proves too cumbersome, so we just grab | |
| 535 // the next captured frame instead. | |
| 536 take_photo_callbacks_.push(std::move(callback)); | |
| 537 } | |
| 538 | |
| 539 void VideoCaptureDeviceWin::GetPhotoCapabilities( | |
| 540 GetPhotoCapabilitiesCallback callback) { | |
| 541 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 542 | |
| 543 if (!camera_control_ || !video_control_) | |
| 542 return; | 544 return; |
| 543 | 545 |
| 544 auto photo_capabilities = mojom::PhotoCapabilities::New(); | 546 auto photo_capabilities = mojom::PhotoCapabilities::New(); |
| 545 | 547 |
| 546 photo_capabilities->exposure_compensation = RetrieveControlRangeAndCurrent( | 548 photo_capabilities->exposure_compensation = RetrieveControlRangeAndCurrent( |
| 547 [camera_control](auto... args) { | 549 [this](auto... args) { |
| 548 return camera_control->getRange_Exposure(args...); | 550 return this->camera_control_->getRange_Exposure(args...); |
| 549 }, | 551 }, |
| 550 [camera_control](auto... args) { | 552 [this](auto... args) { |
| 551 return camera_control->get_Exposure(args...); | 553 return this->camera_control_->get_Exposure(args...); |
| 552 }, | 554 }, |
| 553 &photo_capabilities->supported_exposure_modes, | 555 &photo_capabilities->supported_exposure_modes, |
| 554 &photo_capabilities->current_exposure_mode); | 556 &photo_capabilities->current_exposure_mode); |
| 555 | 557 |
| 556 photo_capabilities->color_temperature = RetrieveControlRangeAndCurrent( | 558 photo_capabilities->color_temperature = RetrieveControlRangeAndCurrent( |
| 557 [video_control](auto... args) { | 559 [this](auto... args) { |
| 558 return video_control->getRange_WhiteBalance(args...); | 560 return this->video_control_->getRange_WhiteBalance(args...); |
| 559 }, | 561 }, |
| 560 [video_control](auto... args) { | 562 [this](auto... args) { |
| 561 return video_control->get_WhiteBalance(args...); | 563 return this->video_control_->get_WhiteBalance(args...); |
| 562 }, | 564 }, |
| 563 &photo_capabilities->supported_white_balance_modes, | 565 &photo_capabilities->supported_white_balance_modes, |
| 564 &photo_capabilities->current_white_balance_mode); | 566 &photo_capabilities->current_white_balance_mode); |
| 565 | 567 |
| 566 // Ignore the returned Focus control range and status. | 568 // Ignore the returned Focus control range and status. |
| 567 RetrieveControlRangeAndCurrent( | 569 RetrieveControlRangeAndCurrent( |
| 568 [camera_control](auto... args) { | 570 [this](auto... args) { |
| 569 return camera_control->getRange_Focus(args...); | 571 return this->camera_control_->getRange_Focus(args...); |
| 570 }, | 572 }, |
| 571 [camera_control](auto... args) { | 573 [this](auto... args) { |
| 572 return camera_control->get_Focus(args...); | 574 return this->camera_control_->get_Focus(args...); |
| 573 }, | 575 }, |
| 574 &photo_capabilities->supported_focus_modes, | 576 &photo_capabilities->supported_focus_modes, |
| 575 &photo_capabilities->current_focus_mode); | 577 &photo_capabilities->current_focus_mode); |
| 576 | 578 |
| 577 photo_capabilities->iso = mojom::Range::New(); | 579 photo_capabilities->iso = mojom::Range::New(); |
| 578 | 580 |
| 579 photo_capabilities->brightness = RetrieveControlRangeAndCurrent( | 581 photo_capabilities->brightness = RetrieveControlRangeAndCurrent( |
| 580 [video_control](auto... args) { | 582 [this](auto... args) { |
| 581 return video_control->getRange_Brightness(args...); | 583 return this->video_control_->getRange_Brightness(args...); |
| 582 }, | 584 }, |
| 583 [video_control](auto... args) { | 585 [this](auto... args) { |
| 584 return video_control->get_Brightness(args...); | 586 return this->video_control_->get_Brightness(args...); |
| 585 }); | 587 }); |
| 586 photo_capabilities->contrast = RetrieveControlRangeAndCurrent( | 588 photo_capabilities->contrast = RetrieveControlRangeAndCurrent( |
| 587 [video_control](auto... args) { | 589 [this](auto... args) { |
| 588 return video_control->getRange_Contrast(args...); | 590 return this->video_control_->getRange_Contrast(args...); |
| 589 }, | 591 }, |
| 590 [video_control](auto... args) { | 592 [this](auto... args) { |
| 591 return video_control->get_Contrast(args...); | 593 return this->video_control_->get_Contrast(args...); |
| 592 }); | 594 }); |
| 593 photo_capabilities->saturation = RetrieveControlRangeAndCurrent( | 595 photo_capabilities->saturation = RetrieveControlRangeAndCurrent( |
| 594 [video_control](auto... args) { | 596 [this](auto... args) { |
| 595 return video_control->getRange_Saturation(args...); | 597 return this->video_control_->getRange_Saturation(args...); |
| 596 }, | 598 }, |
| 597 [video_control](auto... args) { | 599 [this](auto... args) { |
| 598 return video_control->get_Saturation(args...); | 600 return this->video_control_->get_Saturation(args...); |
| 599 }); | 601 }); |
| 600 photo_capabilities->sharpness = RetrieveControlRangeAndCurrent( | 602 photo_capabilities->sharpness = RetrieveControlRangeAndCurrent( |
| 601 [video_control](auto... args) { | 603 [this](auto... args) { |
| 602 return video_control->getRange_Sharpness(args...); | 604 return this->video_control_->getRange_Sharpness(args...); |
| 603 }, | 605 }, |
| 604 [video_control](auto... args) { | 606 [this](auto... args) { |
| 605 return video_control->get_Sharpness(args...); | 607 return this->video_control_->get_Sharpness(args...); |
| 606 }); | 608 }); |
| 607 | 609 |
| 608 photo_capabilities->zoom = RetrieveControlRangeAndCurrent( | 610 photo_capabilities->zoom = RetrieveControlRangeAndCurrent( |
| 609 [camera_control](auto... args) { | 611 [this](auto... args) { |
| 610 return camera_control->getRange_Zoom(args...); | 612 return this->camera_control_->getRange_Zoom(args...); |
| 611 }, | 613 }, |
| 612 [camera_control](auto... args) { | 614 [this](auto... args) { |
| 613 return camera_control->get_Zoom(args...); | 615 return this->camera_control_->get_Zoom(args...); |
| 614 }); | 616 }); |
| 615 | 617 |
| 616 photo_capabilities->red_eye_reduction = mojom::RedEyeReduction::NEVER; | 618 photo_capabilities->red_eye_reduction = mojom::RedEyeReduction::NEVER; |
| 617 photo_capabilities->height = mojom::Range::New(); | 619 photo_capabilities->height = mojom::Range::New( |
| 618 photo_capabilities->width = mojom::Range::New(); | 620 capture_format_.frame_size.height(), capture_format_.frame_size.height(), |
| 621 capture_format_.frame_size.height(), 0 /* step */); | |
| 622 photo_capabilities->width = mojom::Range::New( | |
| 623 capture_format_.frame_size.width(), capture_format_.frame_size.width(), | |
| 624 capture_format_.frame_size.width(), 0 /* step */); | |
| 619 photo_capabilities->torch = false; | 625 photo_capabilities->torch = false; |
| 620 | 626 |
| 621 callback.Run(std::move(photo_capabilities)); | 627 callback.Run(std::move(photo_capabilities)); |
| 622 } | 628 } |
| 623 | 629 |
| 630 void VideoCaptureDeviceWin::SetPhotoOptions( | |
| 631 mojom::PhotoSettingsPtr settings, | |
| 632 VideoCaptureDevice::SetPhotoOptionsCallback callback) { | |
| 633 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 634 | |
| 635 if (!camera_control_ || !video_control_) | |
| 636 return; | |
| 637 | |
| 638 if (settings->has_zoom) { | |
| 639 HRESULT hr = | |
| 640 camera_control_->put_Zoom(settings->zoom, CameraControl_Flags_Manual); | |
| 641 DLOG_IF_FAILED_WITH_HRESULT("Zoom config failed", hr); | |
| 642 } | |
| 643 | |
| 644 if (settings->has_white_balance_mode) { | |
| 645 if (settings->white_balance_mode == mojom::MeteringMode::CONTINUOUS) { | |
| 646 HRESULT hr = | |
| 647 video_control_->put_WhiteBalance(0L, VideoProcAmp_Flags_Auto); | |
| 648 DLOG_IF_FAILED_WITH_HRESULT("Auto white balance config failed", hr); | |
| 649 | |
| 650 white_balance_mode_manual_ = false; | |
| 651 } else { | |
| 652 white_balance_mode_manual_ = true; | |
| 653 } | |
| 654 } | |
| 655 if (white_balance_mode_manual_ && settings->has_color_temperature) { | |
| 656 HRESULT hr = video_control_->put_WhiteBalance(settings->color_temperature, | |
| 657 CameraControl_Flags_Manual); | |
| 658 DLOG_IF_FAILED_WITH_HRESULT("Color temperature config failed", hr); | |
| 659 } | |
| 660 | |
| 661 if (settings->has_exposure_mode) { | |
| 662 if (settings->exposure_mode == mojom::MeteringMode::CONTINUOUS) { | |
| 663 HRESULT hr = camera_control_->put_Exposure(0L, VideoProcAmp_Flags_Auto); | |
| 664 DLOG_IF_FAILED_WITH_HRESULT("Auto exposure config failed", hr); | |
| 665 | |
| 666 exposure_mode_manual_ = false; | |
| 667 } else { | |
| 668 exposure_mode_manual_ = true; | |
| 669 } | |
| 670 } | |
| 671 if (exposure_mode_manual_ && settings->has_exposure_compensation) { | |
| 672 HRESULT hr = camera_control_->put_Exposure(settings->exposure_compensation, | |
| 673 CameraControl_Flags_Manual); | |
| 674 DLOG_IF_FAILED_WITH_HRESULT("Exposure Compensation config failed", hr); | |
| 675 } | |
| 676 | |
| 677 if (settings->has_brightness) { | |
| 678 HRESULT hr = video_control_->put_Brightness(settings->brightness, | |
| 679 CameraControl_Flags_Manual); | |
| 680 DLOG_IF_FAILED_WITH_HRESULT("Brightness config failed", hr); | |
| 681 } | |
| 682 if (settings->has_contrast) { | |
| 683 HRESULT hr = video_control_->put_Contrast(settings->contrast, | |
| 684 CameraControl_Flags_Manual); | |
| 685 DLOG_IF_FAILED_WITH_HRESULT("Contrast config failed", hr); | |
| 686 } | |
| 687 if (settings->has_saturation) { | |
| 688 HRESULT hr = video_control_->put_Saturation(settings->saturation, | |
| 689 CameraControl_Flags_Manual); | |
| 690 DLOG_IF_FAILED_WITH_HRESULT("Saturation config failed", hr); | |
| 691 } | |
| 692 if (settings->has_sharpness) { | |
| 693 HRESULT hr = video_control_->put_Sharpness(settings->sharpness, | |
| 694 CameraControl_Flags_Manual); | |
| 695 DLOG_IF_FAILED_WITH_HRESULT("Sharpness config failed", hr); | |
| 696 } | |
| 697 | |
| 698 callback.Run(true); | |
|
robliao
2017/05/12 19:34:30
Should this be called synchronously or should it b
mcasas
2017/05/12 21:27:04
This callback is a sophisticated ScopedResultCallb
| |
| 699 } | |
| 624 // Implements SinkFilterObserver::SinkFilterObserver. | 700 // Implements SinkFilterObserver::SinkFilterObserver. |
| 625 void VideoCaptureDeviceWin::FrameReceived(const uint8_t* buffer, | 701 void VideoCaptureDeviceWin::FrameReceived(const uint8_t* buffer, |
| 626 int length, | 702 int length, |
| 627 const VideoCaptureFormat& format, | 703 const VideoCaptureFormat& format, |
| 628 base::TimeDelta timestamp) { | 704 base::TimeDelta timestamp) { |
| 629 if (first_ref_time_.is_null()) | 705 if (first_ref_time_.is_null()) |
| 630 first_ref_time_ = base::TimeTicks::Now(); | 706 first_ref_time_ = base::TimeTicks::Now(); |
| 631 | 707 |
| 632 // There is a chance that the platform does not provide us with the timestamp, | 708 // There is a chance that the platform does not provide us with the timestamp, |
| 633 // in which case, we use reference time to calculate a timestamp. | 709 // in which case, we use reference time to calculate a timestamp. |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 758 void VideoCaptureDeviceWin::SetErrorState( | 834 void VideoCaptureDeviceWin::SetErrorState( |
| 759 const tracked_objects::Location& from_here, | 835 const tracked_objects::Location& from_here, |
| 760 const std::string& reason, | 836 const std::string& reason, |
| 761 HRESULT hr) { | 837 HRESULT hr) { |
| 762 DCHECK(thread_checker_.CalledOnValidThread()); | 838 DCHECK(thread_checker_.CalledOnValidThread()); |
| 763 DLOG_IF_FAILED_WITH_HRESULT(reason, hr); | 839 DLOG_IF_FAILED_WITH_HRESULT(reason, hr); |
| 764 state_ = kError; | 840 state_ = kError; |
| 765 client_->OnError(from_here, reason); | 841 client_->OnError(from_here, reason); |
| 766 } | 842 } |
| 767 } // namespace media | 843 } // namespace media |
| OLD | NEW |