| 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 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 // Finds an IPin on an IBaseFilter given the direction, Category and/or Major | 125 // Finds an IPin on an IBaseFilter given the direction, Category and/or Major |
| 126 // Type. If either |category| or |major_type| are GUID_NULL, they are ignored. | 126 // Type. If either |category| or |major_type| are GUID_NULL, they are ignored. |
| 127 // static | 127 // static |
| 128 ScopedComPtr<IPin> VideoCaptureDeviceWin::GetPin(IBaseFilter* filter, | 128 ScopedComPtr<IPin> VideoCaptureDeviceWin::GetPin(IBaseFilter* filter, |
| 129 PIN_DIRECTION pin_dir, | 129 PIN_DIRECTION pin_dir, |
| 130 REFGUID category, | 130 REFGUID category, |
| 131 REFGUID major_type) { | 131 REFGUID major_type) { |
| 132 ScopedComPtr<IPin> pin; | 132 ScopedComPtr<IPin> pin; |
| 133 ScopedComPtr<IEnumPins> pin_enum; | 133 ScopedComPtr<IEnumPins> pin_enum; |
| 134 HRESULT hr = filter->EnumPins(pin_enum.Receive()); | 134 HRESULT hr = filter->EnumPins(pin_enum.Receive()); |
| 135 if (pin_enum.get() == NULL) | 135 if (pin_enum.Get() == NULL) |
| 136 return pin; | 136 return pin; |
| 137 | 137 |
| 138 // Get first unconnected pin. | 138 // Get first unconnected pin. |
| 139 hr = pin_enum->Reset(); // set to first pin | 139 hr = pin_enum->Reset(); // set to first pin |
| 140 while ((hr = pin_enum->Next(1, pin.Receive(), NULL)) == S_OK) { | 140 while ((hr = pin_enum->Next(1, pin.Receive(), NULL)) == S_OK) { |
| 141 PIN_DIRECTION this_pin_dir = static_cast<PIN_DIRECTION>(-1); | 141 PIN_DIRECTION this_pin_dir = static_cast<PIN_DIRECTION>(-1); |
| 142 hr = pin->QueryDirection(&this_pin_dir); | 142 hr = pin->QueryDirection(&this_pin_dir); |
| 143 if (pin_dir == this_pin_dir) { | 143 if (pin_dir == this_pin_dir) { |
| 144 if ((category == GUID_NULL || PinMatchesCategory(pin.get(), category)) && | 144 if ((category == GUID_NULL || PinMatchesCategory(pin.Get(), category)) && |
| 145 (major_type == GUID_NULL || | 145 (major_type == GUID_NULL || |
| 146 PinMatchesMajorType(pin.get(), major_type))) { | 146 PinMatchesMajorType(pin.Get(), major_type))) { |
| 147 return pin; | 147 return pin; |
| 148 } | 148 } |
| 149 } | 149 } |
| 150 pin.Reset(); | 150 pin.Reset(); |
| 151 } | 151 } |
| 152 | 152 |
| 153 DCHECK(!pin.get()); | 153 DCHECK(!pin.Get()); |
| 154 return pin; | 154 return pin; |
| 155 } | 155 } |
| 156 | 156 |
| 157 // static | 157 // static |
| 158 VideoPixelFormat | 158 VideoPixelFormat |
| 159 VideoCaptureDeviceWin::TranslateMediaSubtypeToPixelFormat( | 159 VideoCaptureDeviceWin::TranslateMediaSubtypeToPixelFormat( |
| 160 const GUID& sub_type) { | 160 const GUID& sub_type) { |
| 161 static struct { | 161 static struct { |
| 162 const GUID& sub_type; | 162 const GUID& sub_type; |
| 163 VideoPixelFormat format; | 163 VideoPixelFormat format; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 | 227 |
| 228 VideoCaptureDeviceWin::VideoCaptureDeviceWin( | 228 VideoCaptureDeviceWin::VideoCaptureDeviceWin( |
| 229 const VideoCaptureDeviceDescriptor& device_descriptor) | 229 const VideoCaptureDeviceDescriptor& device_descriptor) |
| 230 : device_descriptor_(device_descriptor), state_(kIdle) { | 230 : device_descriptor_(device_descriptor), state_(kIdle) { |
| 231 // TODO(mcasas): Check that CoInitializeEx() has been called with the | 231 // TODO(mcasas): Check that CoInitializeEx() has been called with the |
| 232 // appropriate Apartment model, i.e., Single Threaded. | 232 // appropriate Apartment model, i.e., Single Threaded. |
| 233 } | 233 } |
| 234 | 234 |
| 235 VideoCaptureDeviceWin::~VideoCaptureDeviceWin() { | 235 VideoCaptureDeviceWin::~VideoCaptureDeviceWin() { |
| 236 DCHECK(thread_checker_.CalledOnValidThread()); | 236 DCHECK(thread_checker_.CalledOnValidThread()); |
| 237 if (media_control_.get()) | 237 if (media_control_.Get()) |
| 238 media_control_->Stop(); | 238 media_control_->Stop(); |
| 239 | 239 |
| 240 if (graph_builder_.get()) { | 240 if (graph_builder_.Get()) { |
| 241 if (sink_filter_.get()) { | 241 if (sink_filter_.get()) { |
| 242 graph_builder_->RemoveFilter(sink_filter_.get()); | 242 graph_builder_->RemoveFilter(sink_filter_.get()); |
| 243 sink_filter_ = NULL; | 243 sink_filter_ = NULL; |
| 244 } | 244 } |
| 245 | 245 |
| 246 if (capture_filter_.get()) | 246 if (capture_filter_.Get()) |
| 247 graph_builder_->RemoveFilter(capture_filter_.get()); | 247 graph_builder_->RemoveFilter(capture_filter_.Get()); |
| 248 } | 248 } |
| 249 | 249 |
| 250 if (capture_graph_builder_.get()) | 250 if (capture_graph_builder_.Get()) |
| 251 capture_graph_builder_.Reset(); | 251 capture_graph_builder_.Reset(); |
| 252 } | 252 } |
| 253 | 253 |
| 254 bool VideoCaptureDeviceWin::Init() { | 254 bool VideoCaptureDeviceWin::Init() { |
| 255 DCHECK(thread_checker_.CalledOnValidThread()); | 255 DCHECK(thread_checker_.CalledOnValidThread()); |
| 256 HRESULT hr; | 256 HRESULT hr; |
| 257 | 257 |
| 258 hr = GetDeviceFilter(device_descriptor_.device_id, capture_filter_.Receive()); | 258 hr = GetDeviceFilter(device_descriptor_.device_id, capture_filter_.Receive()); |
| 259 DLOG_IF_FAILED_WITH_HRESULT("Failed to create capture filter", hr); | 259 DLOG_IF_FAILED_WITH_HRESULT("Failed to create capture filter", hr); |
| 260 if (!capture_filter_.get()) | 260 if (!capture_filter_.Get()) |
| 261 return false; | 261 return false; |
| 262 | 262 |
| 263 output_capture_pin_ = GetPin(capture_filter_.get(), PINDIR_OUTPUT, | 263 output_capture_pin_ = GetPin(capture_filter_.Get(), PINDIR_OUTPUT, |
| 264 PIN_CATEGORY_CAPTURE, GUID_NULL); | 264 PIN_CATEGORY_CAPTURE, GUID_NULL); |
| 265 if (!output_capture_pin_.get()) { | 265 if (!output_capture_pin_.Get()) { |
| 266 DLOG(ERROR) << "Failed to get capture output pin"; | 266 DLOG(ERROR) << "Failed to get capture output pin"; |
| 267 return false; | 267 return false; |
| 268 } | 268 } |
| 269 | 269 |
| 270 // Create the sink filter used for receiving Captured frames. | 270 // Create the sink filter used for receiving Captured frames. |
| 271 sink_filter_ = new SinkFilter(this); | 271 sink_filter_ = new SinkFilter(this); |
| 272 if (sink_filter_.get() == NULL) { | 272 if (sink_filter_.get() == NULL) { |
| 273 DLOG(ERROR) << "Failed to create sink filter"; | 273 DLOG(ERROR) << "Failed to create sink filter"; |
| 274 return false; | 274 return false; |
| 275 } | 275 } |
| 276 | 276 |
| 277 input_sink_pin_ = sink_filter_->GetPin(0); | 277 input_sink_pin_ = sink_filter_->GetPin(0); |
| 278 | 278 |
| 279 hr = graph_builder_.CreateInstance(CLSID_FilterGraph, NULL, | 279 hr = graph_builder_.CreateInstance(CLSID_FilterGraph, NULL, |
| 280 CLSCTX_INPROC_SERVER); | 280 CLSCTX_INPROC_SERVER); |
| 281 DLOG_IF_FAILED_WITH_HRESULT("Failed to create capture filter", hr); | 281 DLOG_IF_FAILED_WITH_HRESULT("Failed to create capture filter", hr); |
| 282 if (FAILED(hr)) | 282 if (FAILED(hr)) |
| 283 return false; | 283 return false; |
| 284 | 284 |
| 285 hr = capture_graph_builder_.CreateInstance(CLSID_CaptureGraphBuilder2, NULL, | 285 hr = capture_graph_builder_.CreateInstance(CLSID_CaptureGraphBuilder2, NULL, |
| 286 CLSCTX_INPROC); | 286 CLSCTX_INPROC); |
| 287 DLOG_IF_FAILED_WITH_HRESULT("Failed to create the Capture Graph Builder", hr); | 287 DLOG_IF_FAILED_WITH_HRESULT("Failed to create the Capture Graph Builder", hr); |
| 288 if (FAILED(hr)) | 288 if (FAILED(hr)) |
| 289 return false; | 289 return false; |
| 290 | 290 |
| 291 hr = capture_graph_builder_->SetFiltergraph(graph_builder_.get()); | 291 hr = capture_graph_builder_->SetFiltergraph(graph_builder_.Get()); |
| 292 DLOG_IF_FAILED_WITH_HRESULT("Failed to give graph to capture graph builder", | 292 DLOG_IF_FAILED_WITH_HRESULT("Failed to give graph to capture graph builder", |
| 293 hr); | 293 hr); |
| 294 if (FAILED(hr)) | 294 if (FAILED(hr)) |
| 295 return false; | 295 return false; |
| 296 | 296 |
| 297 hr = graph_builder_.QueryInterface(media_control_.Receive()); | 297 hr = graph_builder_.QueryInterface(media_control_.Receive()); |
| 298 DLOG_IF_FAILED_WITH_HRESULT("Failed to create media control builder", hr); | 298 DLOG_IF_FAILED_WITH_HRESULT("Failed to create media control builder", hr); |
| 299 if (FAILED(hr)) | 299 if (FAILED(hr)) |
| 300 return false; | 300 return false; |
| 301 | 301 |
| 302 hr = graph_builder_->AddFilter(capture_filter_.get(), NULL); | 302 hr = graph_builder_->AddFilter(capture_filter_.Get(), NULL); |
| 303 DLOG_IF_FAILED_WITH_HRESULT("Failed to add the capture device to the graph", | 303 DLOG_IF_FAILED_WITH_HRESULT("Failed to add the capture device to the graph", |
| 304 hr); | 304 hr); |
| 305 if (FAILED(hr)) | 305 if (FAILED(hr)) |
| 306 return false; | 306 return false; |
| 307 | 307 |
| 308 hr = graph_builder_->AddFilter(sink_filter_.get(), NULL); | 308 hr = graph_builder_->AddFilter(sink_filter_.get(), NULL); |
| 309 DLOG_IF_FAILED_WITH_HRESULT("Failed to add the sink filter to the graph", hr); | 309 DLOG_IF_FAILED_WITH_HRESULT("Failed to add the sink filter to the graph", hr); |
| 310 if (FAILED(hr)) | 310 if (FAILED(hr)) |
| 311 return false; | 311 return false; |
| 312 | 312 |
| 313 // The following code builds the upstream portions of the graph, for example | 313 // The following code builds the upstream portions of the graph, for example |
| 314 // if a capture device uses a Windows Driver Model (WDM) driver, the graph may | 314 // if a capture device uses a Windows Driver Model (WDM) driver, the graph may |
| 315 // require certain filters upstream from the WDM Video Capture filter, such as | 315 // require certain filters upstream from the WDM Video Capture filter, such as |
| 316 // a TV Tuner filter or an Analog Video Crossbar filter. We try using the more | 316 // a TV Tuner filter or an Analog Video Crossbar filter. We try using the more |
| 317 // prevalent MEDIATYPE_Interleaved first. | 317 // prevalent MEDIATYPE_Interleaved first. |
| 318 base::win::ScopedComPtr<IAMStreamConfig> stream_config; | 318 base::win::ScopedComPtr<IAMStreamConfig> stream_config; |
| 319 | 319 |
| 320 hr = capture_graph_builder_->FindInterface( | 320 hr = capture_graph_builder_->FindInterface( |
| 321 &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, capture_filter_.get(), | 321 &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, capture_filter_.Get(), |
| 322 IID_IAMStreamConfig, (void**)stream_config.Receive()); | 322 IID_IAMStreamConfig, (void**)stream_config.Receive()); |
| 323 if (FAILED(hr)) { | 323 if (FAILED(hr)) { |
| 324 hr = capture_graph_builder_->FindInterface( | 324 hr = capture_graph_builder_->FindInterface( |
| 325 &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, capture_filter_.get(), | 325 &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, capture_filter_.Get(), |
| 326 IID_IAMStreamConfig, (void**)stream_config.Receive()); | 326 IID_IAMStreamConfig, (void**)stream_config.Receive()); |
| 327 DLOG_IF_FAILED_WITH_HRESULT("Failed to find CapFilter:IAMStreamConfig", hr); | 327 DLOG_IF_FAILED_WITH_HRESULT("Failed to find CapFilter:IAMStreamConfig", hr); |
| 328 } | 328 } |
| 329 | 329 |
| 330 return CreateCapabilityMap(); | 330 return CreateCapabilityMap(); |
| 331 } | 331 } |
| 332 | 332 |
| 333 void VideoCaptureDeviceWin::AllocateAndStart( | 333 void VideoCaptureDeviceWin::AllocateAndStart( |
| 334 const VideoCaptureParams& params, | 334 const VideoCaptureParams& params, |
| 335 std::unique_ptr<VideoCaptureDevice::Client> client) { | 335 std::unique_ptr<VideoCaptureDevice::Client> client) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 if (FAILED(hr)) { | 390 if (FAILED(hr)) { |
| 391 SetErrorState(FROM_HERE, "Failed to set capture device output format", hr); | 391 SetErrorState(FROM_HERE, "Failed to set capture device output format", hr); |
| 392 return; | 392 return; |
| 393 } | 393 } |
| 394 | 394 |
| 395 SetAntiFlickerInCaptureFilter(params); | 395 SetAntiFlickerInCaptureFilter(params); |
| 396 | 396 |
| 397 if (media_type->subtype == kMediaSubTypeHDYC) { | 397 if (media_type->subtype == kMediaSubTypeHDYC) { |
| 398 // HDYC pixel format, used by the DeckLink capture card, needs an AVI | 398 // HDYC pixel format, used by the DeckLink capture card, needs an AVI |
| 399 // decompressor filter after source, let |graph_builder_| add it. | 399 // decompressor filter after source, let |graph_builder_| add it. |
| 400 hr = graph_builder_->Connect(output_capture_pin_.get(), | 400 hr = graph_builder_->Connect(output_capture_pin_.Get(), |
| 401 input_sink_pin_.get()); | 401 input_sink_pin_.Get()); |
| 402 } else { | 402 } else { |
| 403 hr = graph_builder_->ConnectDirect(output_capture_pin_.get(), | 403 hr = graph_builder_->ConnectDirect(output_capture_pin_.Get(), |
| 404 input_sink_pin_.get(), NULL); | 404 input_sink_pin_.Get(), NULL); |
| 405 } | 405 } |
| 406 | 406 |
| 407 if (FAILED(hr)) { | 407 if (FAILED(hr)) { |
| 408 SetErrorState(FROM_HERE, "Failed to connect the Capture graph.", hr); | 408 SetErrorState(FROM_HERE, "Failed to connect the Capture graph.", hr); |
| 409 return; | 409 return; |
| 410 } | 410 } |
| 411 | 411 |
| 412 hr = media_control_->Pause(); | 412 hr = media_control_->Pause(); |
| 413 if (FAILED(hr)) { | 413 if (FAILED(hr)) { |
| 414 SetErrorState(FROM_HERE, "Failed to pause the Capture device", hr); | 414 SetErrorState(FROM_HERE, "Failed to pause the Capture device", hr); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 430 DCHECK(thread_checker_.CalledOnValidThread()); | 430 DCHECK(thread_checker_.CalledOnValidThread()); |
| 431 if (state_ != kCapturing) | 431 if (state_ != kCapturing) |
| 432 return; | 432 return; |
| 433 | 433 |
| 434 HRESULT hr = media_control_->Stop(); | 434 HRESULT hr = media_control_->Stop(); |
| 435 if (FAILED(hr)) { | 435 if (FAILED(hr)) { |
| 436 SetErrorState(FROM_HERE, "Failed to stop the capture graph.", hr); | 436 SetErrorState(FROM_HERE, "Failed to stop the capture graph.", hr); |
| 437 return; | 437 return; |
| 438 } | 438 } |
| 439 | 439 |
| 440 graph_builder_->Disconnect(output_capture_pin_.get()); | 440 graph_builder_->Disconnect(output_capture_pin_.Get()); |
| 441 graph_builder_->Disconnect(input_sink_pin_.get()); | 441 graph_builder_->Disconnect(input_sink_pin_.Get()); |
| 442 | 442 |
| 443 client_.reset(); | 443 client_.reset(); |
| 444 state_ = kIdle; | 444 state_ = kIdle; |
| 445 } | 445 } |
| 446 | 446 |
| 447 void VideoCaptureDeviceWin::TakePhoto(TakePhotoCallback callback) { | 447 void VideoCaptureDeviceWin::TakePhoto(TakePhotoCallback callback) { |
| 448 DCHECK(thread_checker_.CalledOnValidThread()); | 448 DCHECK(thread_checker_.CalledOnValidThread()); |
| 449 // DirectShow has other means of capturing still pictures, e.g. connecting a | 449 // DirectShow has other means of capturing still pictures, e.g. connecting a |
| 450 // SampleGrabber filter to a PIN_CATEGORY_STILL of |capture_filter_|. This | 450 // SampleGrabber filter to a PIN_CATEGORY_STILL of |capture_filter_|. This |
| 451 // way, however, is not widespread and proves too cumbersome, so we just grab | 451 // way, however, is not widespread and proves too cumbersome, so we just grab |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 if (format.pixel_format == PIXEL_FORMAT_UNKNOWN) | 518 if (format.pixel_format == PIXEL_FORMAT_UNKNOWN) |
| 519 continue; | 519 continue; |
| 520 | 520 |
| 521 VIDEOINFOHEADER* h = | 521 VIDEOINFOHEADER* h = |
| 522 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); | 522 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); |
| 523 format.frame_size.SetSize(h->bmiHeader.biWidth, h->bmiHeader.biHeight); | 523 format.frame_size.SetSize(h->bmiHeader.biWidth, h->bmiHeader.biHeight); |
| 524 | 524 |
| 525 // 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 |
| 526 // the value from VIDEOINFOHEADER. | 526 // the value from VIDEOINFOHEADER. |
| 527 REFERENCE_TIME time_per_frame = h->AvgTimePerFrame; | 527 REFERENCE_TIME time_per_frame = h->AvgTimePerFrame; |
| 528 if (video_control.get()) { | 528 if (video_control.Get()) { |
| 529 ScopedCoMem<LONGLONG> max_fps; | 529 ScopedCoMem<LONGLONG> max_fps; |
| 530 LONG list_size = 0; | 530 LONG list_size = 0; |
| 531 const SIZE size = {format.frame_size.width(), | 531 const SIZE size = {format.frame_size.width(), |
| 532 format.frame_size.height()}; | 532 format.frame_size.height()}; |
| 533 hr = video_control->GetFrameRateList(output_capture_pin_.get(), | 533 hr = video_control->GetFrameRateList(output_capture_pin_.Get(), |
| 534 stream_index, size, &list_size, | 534 stream_index, size, &list_size, |
| 535 &max_fps); | 535 &max_fps); |
| 536 // Can't assume the first value will return the max fps. | 536 // Can't assume the first value will return the max fps. |
| 537 // Sometimes |list_size| will be > 0, but max_fps will be NULL. Some | 537 // Sometimes |list_size| will be > 0, but max_fps will be NULL. Some |
| 538 // drivers may return an HRESULT of S_FALSE which SUCCEEDED() translates | 538 // drivers may return an HRESULT of S_FALSE which SUCCEEDED() translates |
| 539 // into success, so explicitly check S_OK. See http://crbug.com/306237. | 539 // into success, so explicitly check S_OK. See http://crbug.com/306237. |
| 540 if (hr == S_OK && list_size > 0 && max_fps) { | 540 if (hr == S_OK && list_size > 0 && max_fps) { |
| 541 time_per_frame = | 541 time_per_frame = |
| 542 *std::min_element(max_fps.get(), max_fps.get() + list_size); | 542 *std::min_element(max_fps.get(), max_fps.get() + list_size); |
| 543 } | 543 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 559 void VideoCaptureDeviceWin::SetAntiFlickerInCaptureFilter( | 559 void VideoCaptureDeviceWin::SetAntiFlickerInCaptureFilter( |
| 560 const VideoCaptureParams& params) { | 560 const VideoCaptureParams& params) { |
| 561 const PowerLineFrequency power_line_frequency = GetPowerLineFrequency(params); | 561 const PowerLineFrequency power_line_frequency = GetPowerLineFrequency(params); |
| 562 if (power_line_frequency != media::PowerLineFrequency::FREQUENCY_50HZ && | 562 if (power_line_frequency != media::PowerLineFrequency::FREQUENCY_50HZ && |
| 563 power_line_frequency != media::PowerLineFrequency::FREQUENCY_60HZ) { | 563 power_line_frequency != media::PowerLineFrequency::FREQUENCY_60HZ) { |
| 564 return; | 564 return; |
| 565 } | 565 } |
| 566 ScopedComPtr<IKsPropertySet> ks_propset; | 566 ScopedComPtr<IKsPropertySet> ks_propset; |
| 567 DWORD type_support = 0; | 567 DWORD type_support = 0; |
| 568 HRESULT hr; | 568 HRESULT hr; |
| 569 if (SUCCEEDED(hr = ks_propset.QueryFrom(capture_filter_.get())) && | 569 if (SUCCEEDED(hr = ks_propset.QueryFrom(capture_filter_.Get())) && |
| 570 SUCCEEDED(hr = ks_propset->QuerySupported( | 570 SUCCEEDED(hr = ks_propset->QuerySupported( |
| 571 PROPSETID_VIDCAP_VIDEOPROCAMP, | 571 PROPSETID_VIDCAP_VIDEOPROCAMP, |
| 572 KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY, | 572 KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY, |
| 573 &type_support)) && | 573 &type_support)) && |
| 574 (type_support & KSPROPERTY_SUPPORT_SET)) { | 574 (type_support & KSPROPERTY_SUPPORT_SET)) { |
| 575 KSPROPERTY_VIDEOPROCAMP_S data = {}; | 575 KSPROPERTY_VIDEOPROCAMP_S data = {}; |
| 576 data.Property.Set = PROPSETID_VIDCAP_VIDEOPROCAMP; | 576 data.Property.Set = PROPSETID_VIDCAP_VIDEOPROCAMP; |
| 577 data.Property.Id = KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY; | 577 data.Property.Id = KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY; |
| 578 data.Property.Flags = KSPROPERTY_TYPE_SET; | 578 data.Property.Flags = KSPROPERTY_TYPE_SET; |
| 579 data.Value = | 579 data.Value = |
| (...skipping 10 matching lines...) Expand all Loading... |
| 590 void VideoCaptureDeviceWin::SetErrorState( | 590 void VideoCaptureDeviceWin::SetErrorState( |
| 591 const tracked_objects::Location& from_here, | 591 const tracked_objects::Location& from_here, |
| 592 const std::string& reason, | 592 const std::string& reason, |
| 593 HRESULT hr) { | 593 HRESULT hr) { |
| 594 DCHECK(thread_checker_.CalledOnValidThread()); | 594 DCHECK(thread_checker_.CalledOnValidThread()); |
| 595 DLOG_IF_FAILED_WITH_HRESULT(reason, hr); | 595 DLOG_IF_FAILED_WITH_HRESULT(reason, hr); |
| 596 state_ = kError; | 596 state_ = kError; |
| 597 client_->OnError(from_here, reason); | 597 client_->OnError(from_here, reason); |
| 598 } | 598 } |
| 599 } // namespace media | 599 } // namespace media |
| OLD | NEW |