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> |
11 #include <list> | 11 #include <list> |
12 #include <utility> | 12 #include <utility> |
13 | 13 |
14 #include "base/macros.h" | 14 #include "base/macros.h" |
15 #include "base/strings/sys_string_conversions.h" | 15 #include "base/strings/sys_string_conversions.h" |
16 #include "base/win/scoped_co_mem.h" | 16 #include "base/win/scoped_co_mem.h" |
17 #include "base/win/scoped_variant.h" | 17 #include "base/win/scoped_variant.h" |
18 #include "media/base/timestamp_constants.h" | 18 #include "media/base/timestamp_constants.h" |
19 #include "media/capture/video/blob_utils.h" | 19 #include "media/capture/video/blob_utils.h" |
20 | 20 |
21 using base::win::ScopedCoMem; | 21 using base::win::ScopedCoMem; |
22 using base::win::ScopedComPtr; | 22 using base::win::ScopedComPtr; |
23 using base::win::ScopedVariant; | 23 using base::win::ScopedVariant; |
24 | 24 |
25 namespace media { | 25 namespace media { |
26 | 26 |
| 27 #if DCHECK_IS_ON() |
| 28 #define DLOG_IF_FAILED_WITH_HRESULT(message, hr) \ |
| 29 { \ |
| 30 DLOG_IF(ERROR, FAILED(hr)) << (message) << ": " \ |
| 31 << logging::SystemErrorCodeToString(hr); \ |
| 32 } |
| 33 #else |
| 34 #define DLOG_IF_FAILED_WITH_HRESULT(message, hr) \ |
| 35 {} |
| 36 #endif |
| 37 |
27 // Check if a Pin matches a category. | 38 // Check if a Pin matches a category. |
28 bool PinMatchesCategory(IPin* pin, REFGUID category) { | 39 bool PinMatchesCategory(IPin* pin, REFGUID category) { |
29 DCHECK(pin); | 40 DCHECK(pin); |
30 bool found = false; | 41 bool found = false; |
31 ScopedComPtr<IKsPropertySet> ks_property; | 42 ScopedComPtr<IKsPropertySet> ks_property; |
32 HRESULT hr = ks_property.QueryFrom(pin); | 43 HRESULT hr = ks_property.QueryFrom(pin); |
33 if (SUCCEEDED(hr)) { | 44 if (SUCCEEDED(hr)) { |
34 GUID pin_category; | 45 GUID pin_category; |
35 DWORD return_value; | 46 DWORD return_value; |
36 hr = ks_property->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0, | 47 hr = ks_property->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0, |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 | 246 |
236 if (capture_graph_builder_.get()) | 247 if (capture_graph_builder_.get()) |
237 capture_graph_builder_.Release(); | 248 capture_graph_builder_.Release(); |
238 } | 249 } |
239 | 250 |
240 bool VideoCaptureDeviceWin::Init() { | 251 bool VideoCaptureDeviceWin::Init() { |
241 DCHECK(thread_checker_.CalledOnValidThread()); | 252 DCHECK(thread_checker_.CalledOnValidThread()); |
242 HRESULT hr; | 253 HRESULT hr; |
243 | 254 |
244 hr = GetDeviceFilter(device_descriptor_.device_id, capture_filter_.Receive()); | 255 hr = GetDeviceFilter(device_descriptor_.device_id, capture_filter_.Receive()); |
245 | 256 DLOG_IF_FAILED_WITH_HRESULT("Failed to create capture filter", hr); |
246 if (!capture_filter_.get()) { | 257 if (!capture_filter_.get()) |
247 DLOG(ERROR) << "Failed to create capture filter: " | |
248 << logging::SystemErrorCodeToString(hr); | |
249 return false; | 258 return false; |
250 } | |
251 | 259 |
252 output_capture_pin_ = GetPin(capture_filter_.get(), PINDIR_OUTPUT, | 260 output_capture_pin_ = GetPin(capture_filter_.get(), PINDIR_OUTPUT, |
253 PIN_CATEGORY_CAPTURE, GUID_NULL); | 261 PIN_CATEGORY_CAPTURE, GUID_NULL); |
254 if (!output_capture_pin_.get()) { | 262 if (!output_capture_pin_.get()) { |
255 DLOG(ERROR) << "Failed to get capture output pin"; | 263 DLOG(ERROR) << "Failed to get capture output pin"; |
256 return false; | 264 return false; |
257 } | 265 } |
258 | 266 |
259 // Create the sink filter used for receiving Captured frames. | 267 // Create the sink filter used for receiving Captured frames. |
260 sink_filter_ = new SinkFilter(this); | 268 sink_filter_ = new SinkFilter(this); |
261 if (sink_filter_.get() == NULL) { | 269 if (sink_filter_.get() == NULL) { |
262 DLOG(ERROR) << "Failed to create sink filter"; | 270 DLOG(ERROR) << "Failed to create sink filter"; |
263 return false; | 271 return false; |
264 } | 272 } |
265 | 273 |
266 input_sink_pin_ = sink_filter_->GetPin(0); | 274 input_sink_pin_ = sink_filter_->GetPin(0); |
267 | 275 |
268 hr = graph_builder_.CreateInstance(CLSID_FilterGraph, NULL, | 276 hr = graph_builder_.CreateInstance(CLSID_FilterGraph, NULL, |
269 CLSCTX_INPROC_SERVER); | 277 CLSCTX_INPROC_SERVER); |
270 if (FAILED(hr)) { | 278 DLOG_IF_FAILED_WITH_HRESULT("Failed to create capture filter", hr); |
271 DLOG(ERROR) << "Failed to create graph builder: " | 279 if (FAILED(hr)) |
272 << logging::SystemErrorCodeToString(hr); | |
273 return false; | 280 return false; |
274 } | |
275 | 281 |
276 hr = capture_graph_builder_.CreateInstance(CLSID_CaptureGraphBuilder2, NULL, | 282 hr = capture_graph_builder_.CreateInstance(CLSID_CaptureGraphBuilder2, NULL, |
277 CLSCTX_INPROC); | 283 CLSCTX_INPROC); |
278 if (FAILED(hr)) { | 284 DLOG_IF_FAILED_WITH_HRESULT("Failed to create the Capture Graph Builder", hr); |
279 DLOG(ERROR) << "Failed to create the Capture Graph Builder: " | 285 if (FAILED(hr)) |
280 << logging::SystemErrorCodeToString(hr); | |
281 return false; | 286 return false; |
282 } | |
283 | 287 |
284 hr = capture_graph_builder_->SetFiltergraph(graph_builder_.get()); | 288 hr = capture_graph_builder_->SetFiltergraph(graph_builder_.get()); |
285 if (FAILED(hr)) { | 289 DLOG_IF_FAILED_WITH_HRESULT("Failed to give graph to capture graph builder", |
286 DLOG(ERROR) << "Failed to give graph to capture graph builder: " | 290 hr); |
287 << logging::SystemErrorCodeToString(hr); | 291 if (FAILED(hr)) |
288 return false; | 292 return false; |
289 } | |
290 | 293 |
291 hr = graph_builder_.QueryInterface(media_control_.Receive()); | 294 hr = graph_builder_.QueryInterface(media_control_.Receive()); |
292 if (FAILED(hr)) { | 295 DLOG_IF_FAILED_WITH_HRESULT("Failed to create media control builder", hr); |
293 DLOG(ERROR) << "Failed to create media control builder: " | 296 if (FAILED(hr)) |
294 << logging::SystemErrorCodeToString(hr); | |
295 return false; | 297 return false; |
296 } | |
297 | 298 |
298 hr = graph_builder_->AddFilter(capture_filter_.get(), NULL); | 299 hr = graph_builder_->AddFilter(capture_filter_.get(), NULL); |
299 if (FAILED(hr)) { | 300 DLOG_IF_FAILED_WITH_HRESULT("Failed to add the capture device to the graph", |
300 DLOG(ERROR) << "Failed to add the capture device to the graph: " | 301 hr); |
301 << logging::SystemErrorCodeToString(hr); | 302 if (FAILED(hr)) |
302 return false; | 303 return false; |
303 } | |
304 | 304 |
305 hr = graph_builder_->AddFilter(sink_filter_.get(), NULL); | 305 hr = graph_builder_->AddFilter(sink_filter_.get(), NULL); |
306 if (FAILED(hr)) { | 306 DLOG_IF_FAILED_WITH_HRESULT("Failed to add the sink filter to the graph", hr); |
307 DLOG(ERROR) << "Failed to add the sink filter to the graph: " | 307 if (FAILED(hr)) |
308 << logging::SystemErrorCodeToString(hr); | |
309 return false; | 308 return false; |
310 } | |
311 | 309 |
312 // The following code builds the upstream portions of the graph, | 310 // The following code builds the upstream portions of the graph, for example |
313 // for example if a capture device uses a Windows Driver Model (WDM) | 311 // if a capture device uses a Windows Driver Model (WDM) driver, the graph may |
314 // driver, the graph may require certain filters upstream from the | 312 // require certain filters upstream from the WDM Video Capture filter, such as |
315 // WDM Video Capture filter, such as a TV Tuner filter or an Analog | 313 // a TV Tuner filter or an Analog Video Crossbar filter. We try using the more |
316 // Video Crossbar filter. We try using the more prevalent | 314 // prevalent MEDIATYPE_Interleaved first. |
317 // MEDIATYPE_Interleaved first. | |
318 base::win::ScopedComPtr<IAMStreamConfig> stream_config; | 315 base::win::ScopedComPtr<IAMStreamConfig> stream_config; |
319 | 316 |
320 hr = capture_graph_builder_->FindInterface( | 317 hr = capture_graph_builder_->FindInterface( |
321 &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, capture_filter_.get(), | 318 &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, capture_filter_.get(), |
322 IID_IAMStreamConfig, (void**)stream_config.Receive()); | 319 IID_IAMStreamConfig, (void**)stream_config.Receive()); |
323 if (FAILED(hr)) { | 320 if (FAILED(hr)) { |
324 hr = capture_graph_builder_->FindInterface( | 321 hr = capture_graph_builder_->FindInterface( |
325 &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, capture_filter_.get(), | 322 &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, capture_filter_.get(), |
326 IID_IAMStreamConfig, (void**)stream_config.Receive()); | 323 IID_IAMStreamConfig, (void**)stream_config.Receive()); |
327 DLOG_IF(ERROR, FAILED(hr)) << "Failed to find CapFilter:IAMStreamConfig: " | 324 DLOG_IF_FAILED_WITH_HRESULT("Failed to find CapFilter:IAMStreamConfig", hr); |
328 << logging::SystemErrorCodeToString(hr); | |
329 } | 325 } |
330 | 326 |
331 return CreateCapabilityMap(); | 327 return CreateCapabilityMap(); |
332 } | 328 } |
333 | 329 |
334 void VideoCaptureDeviceWin::AllocateAndStart( | 330 void VideoCaptureDeviceWin::AllocateAndStart( |
335 const VideoCaptureParams& params, | 331 const VideoCaptureParams& params, |
336 std::unique_ptr<VideoCaptureDevice::Client> client) { | 332 std::unique_ptr<VideoCaptureDevice::Client> client) { |
337 DCHECK(thread_checker_.CalledOnValidThread()); | 333 DCHECK(thread_checker_.CalledOnValidThread()); |
338 if (state_ != kIdle) | 334 if (state_ != kIdle) |
339 return; | 335 return; |
340 | 336 |
341 client_ = std::move(client); | 337 client_ = std::move(client); |
342 | 338 |
343 // Get the camera capability that best match the requested format. | 339 // Get the camera capability that best match the requested format. |
344 const CapabilityWin found_capability = | 340 const CapabilityWin found_capability = |
345 GetBestMatchedCapability(params.requested_format, capabilities_); | 341 GetBestMatchedCapability(params.requested_format, capabilities_); |
346 | 342 |
347 // Reduce the frame rate if the requested frame rate is lower | 343 // Reduce the frame rate if the requested frame rate is lower |
348 // than the capability. | 344 // than the capability. |
349 const float frame_rate = | 345 const float frame_rate = |
350 std::min(params.requested_format.frame_rate, | 346 std::min(params.requested_format.frame_rate, |
351 found_capability.supported_format.frame_rate); | 347 found_capability.supported_format.frame_rate); |
352 | 348 |
353 ScopedComPtr<IAMStreamConfig> stream_config; | 349 ScopedComPtr<IAMStreamConfig> stream_config; |
354 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); | 350 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); |
355 if (FAILED(hr)) { | 351 if (FAILED(hr)) { |
356 SetErrorState(FROM_HERE, "Can't get the Capture format settings"); | 352 SetErrorState(FROM_HERE, "Can't get the Capture format settings", hr); |
357 return; | 353 return; |
358 } | 354 } |
359 | 355 |
360 int count = 0, size = 0; | 356 int count = 0, size = 0; |
361 hr = stream_config->GetNumberOfCapabilities(&count, &size); | 357 hr = stream_config->GetNumberOfCapabilities(&count, &size); |
362 if (FAILED(hr)) { | 358 if (FAILED(hr)) { |
363 SetErrorState(FROM_HERE, "Failed to GetNumberOfCapabilities"); | 359 SetErrorState(FROM_HERE, "Failed to GetNumberOfCapabilities", hr); |
364 return; | 360 return; |
365 } | 361 } |
366 | 362 |
367 std::unique_ptr<BYTE[]> caps(new BYTE[size]); | 363 std::unique_ptr<BYTE[]> caps(new BYTE[size]); |
368 ScopedMediaType media_type; | 364 ScopedMediaType media_type; |
369 | 365 |
370 // Get the windows capability from the capture device. | 366 // Get the windows capability from the capture device. |
371 // GetStreamCaps can return S_FALSE which we consider an error. Therefore the | 367 // GetStreamCaps can return S_FALSE which we consider an error. Therefore the |
372 // FAILED macro can't be used. | 368 // FAILED macro can't be used. |
373 hr = stream_config->GetStreamCaps(found_capability.stream_index, | 369 hr = stream_config->GetStreamCaps(found_capability.stream_index, |
374 media_type.Receive(), caps.get()); | 370 media_type.Receive(), caps.get()); |
375 if (hr != S_OK) { | 371 if (hr != S_OK) { |
376 SetErrorState(FROM_HERE, "Failed to get capture device capabilities"); | 372 SetErrorState(FROM_HERE, "Failed to get capture device capabilities", hr); |
377 return; | 373 return; |
378 } | 374 } |
379 if (media_type->formattype == FORMAT_VideoInfo) { | 375 if (media_type->formattype == FORMAT_VideoInfo) { |
380 VIDEOINFOHEADER* h = | 376 VIDEOINFOHEADER* h = |
381 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); | 377 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); |
382 if (frame_rate > 0) | 378 if (frame_rate > 0) |
383 h->AvgTimePerFrame = kSecondsToReferenceTime / frame_rate; | 379 h->AvgTimePerFrame = kSecondsToReferenceTime / frame_rate; |
384 } | 380 } |
385 // Set the sink filter to request this format. | 381 // Set the sink filter to request this format. |
386 sink_filter_->SetRequestedMediaFormat( | 382 sink_filter_->SetRequestedMediaFormat( |
387 found_capability.supported_format.pixel_format, frame_rate, | 383 found_capability.supported_format.pixel_format, frame_rate, |
388 found_capability.info_header); | 384 found_capability.info_header); |
389 // Order the capture device to use this format. | 385 // Order the capture device to use this format. |
390 hr = stream_config->SetFormat(media_type.get()); | 386 hr = stream_config->SetFormat(media_type.get()); |
391 if (FAILED(hr)) { | 387 if (FAILED(hr)) { |
392 // TODO(grunell): Log the error. http://crbug.com/405016. | 388 SetErrorState(FROM_HERE, "Failed to set capture device output format", hr); |
393 SetErrorState(FROM_HERE, "Failed to set capture device output format"); | |
394 return; | 389 return; |
395 } | 390 } |
396 | 391 |
397 SetAntiFlickerInCaptureFilter(params); | 392 SetAntiFlickerInCaptureFilter(params); |
398 | 393 |
399 if (media_type->subtype == kMediaSubTypeHDYC) { | 394 if (media_type->subtype == kMediaSubTypeHDYC) { |
400 // HDYC pixel format, used by the DeckLink capture card, needs an AVI | 395 // HDYC pixel format, used by the DeckLink capture card, needs an AVI |
401 // decompressor filter after source, let |graph_builder_| add it. | 396 // decompressor filter after source, let |graph_builder_| add it. |
402 hr = graph_builder_->Connect(output_capture_pin_.get(), | 397 hr = graph_builder_->Connect(output_capture_pin_.get(), |
403 input_sink_pin_.get()); | 398 input_sink_pin_.get()); |
404 } else { | 399 } else { |
405 hr = graph_builder_->ConnectDirect(output_capture_pin_.get(), | 400 hr = graph_builder_->ConnectDirect(output_capture_pin_.get(), |
406 input_sink_pin_.get(), NULL); | 401 input_sink_pin_.get(), NULL); |
407 } | 402 } |
408 | 403 |
409 if (FAILED(hr)) { | 404 if (FAILED(hr)) { |
410 SetErrorState(FROM_HERE, "Failed to connect the Capture graph."); | 405 SetErrorState(FROM_HERE, "Failed to connect the Capture graph.", hr); |
411 return; | 406 return; |
412 } | 407 } |
413 | 408 |
414 hr = media_control_->Pause(); | 409 hr = media_control_->Pause(); |
415 if (FAILED(hr)) { | 410 if (FAILED(hr)) { |
416 SetErrorState( | 411 SetErrorState(FROM_HERE, "Failed to pause the Capture device", hr); |
417 FROM_HERE, | |
418 "Failed to pause the Capture device, is it already occupied?"); | |
419 return; | 412 return; |
420 } | 413 } |
421 | 414 |
422 // Get the format back from the sink filter after the filter have been | 415 // Get the format back from the sink filter after the filter have been |
423 // connected. | 416 // connected. |
424 capture_format_ = sink_filter_->ResultingFormat(); | 417 capture_format_ = sink_filter_->ResultingFormat(); |
425 | 418 |
426 // Start capturing. | 419 // Start capturing. |
427 hr = media_control_->Run(); | 420 hr = media_control_->Run(); |
428 if (FAILED(hr)) { | 421 if (FAILED(hr)) { |
429 SetErrorState(FROM_HERE, "Failed to start the Capture device."); | 422 SetErrorState(FROM_HERE, "Failed to start the Capture device.", hr); |
430 return; | 423 return; |
431 } | 424 } |
432 | 425 |
433 state_ = kCapturing; | 426 state_ = kCapturing; |
434 } | 427 } |
435 | 428 |
436 void VideoCaptureDeviceWin::StopAndDeAllocate() { | 429 void VideoCaptureDeviceWin::StopAndDeAllocate() { |
437 DCHECK(thread_checker_.CalledOnValidThread()); | 430 DCHECK(thread_checker_.CalledOnValidThread()); |
438 if (state_ != kCapturing) | 431 if (state_ != kCapturing) |
439 return; | 432 return; |
440 | 433 |
441 HRESULT hr = media_control_->Stop(); | 434 HRESULT hr = media_control_->Stop(); |
442 if (FAILED(hr)) { | 435 if (FAILED(hr)) { |
443 SetErrorState(FROM_HERE, "Failed to stop the capture graph."); | 436 SetErrorState(FROM_HERE, "Failed to stop the capture graph.", hr); |
444 return; | 437 return; |
445 } | 438 } |
446 | 439 |
447 graph_builder_->Disconnect(output_capture_pin_.get()); | 440 graph_builder_->Disconnect(output_capture_pin_.get()); |
448 graph_builder_->Disconnect(input_sink_pin_.get()); | 441 graph_builder_->Disconnect(input_sink_pin_.get()); |
449 | 442 |
450 client_.reset(); | 443 client_.reset(); |
451 state_ = kIdle; | 444 state_ = kIdle; |
452 } | 445 } |
453 | 446 |
(...skipping 28 matching lines...) Expand all Loading... |
482 mojom::BlobPtr blob = Blobify(buffer, length, capture_format_); | 475 mojom::BlobPtr blob = Blobify(buffer, length, capture_format_); |
483 if (blob) | 476 if (blob) |
484 cb.Run(std::move(blob)); | 477 cb.Run(std::move(blob)); |
485 } | 478 } |
486 } | 479 } |
487 | 480 |
488 bool VideoCaptureDeviceWin::CreateCapabilityMap() { | 481 bool VideoCaptureDeviceWin::CreateCapabilityMap() { |
489 DCHECK(thread_checker_.CalledOnValidThread()); | 482 DCHECK(thread_checker_.CalledOnValidThread()); |
490 ScopedComPtr<IAMStreamConfig> stream_config; | 483 ScopedComPtr<IAMStreamConfig> stream_config; |
491 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); | 484 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); |
492 if (FAILED(hr)) { | 485 DLOG_IF_FAILED_WITH_HRESULT( |
493 DPLOG(ERROR) << "Failed to get IAMStreamConfig interface from " | 486 "Failed to get IAMStreamConfig from capture device", hr); |
494 "capture device: " << logging::SystemErrorCodeToString(hr); | 487 if (FAILED(hr)) |
495 return false; | 488 return false; |
496 } | |
497 | 489 |
498 // Get interface used for getting the frame rate. | 490 // Get interface used for getting the frame rate. |
499 ScopedComPtr<IAMVideoControl> video_control; | 491 ScopedComPtr<IAMVideoControl> video_control; |
500 hr = capture_filter_.QueryInterface(video_control.Receive()); | 492 hr = capture_filter_.QueryInterface(video_control.Receive()); |
501 DLOG_IF(WARNING, FAILED(hr)) << "IAMVideoControl Interface NOT SUPPORTED: " | |
502 << logging::SystemErrorCodeToString(hr); | |
503 | 493 |
504 int count = 0, size = 0; | 494 int count = 0, size = 0; |
505 hr = stream_config->GetNumberOfCapabilities(&count, &size); | 495 hr = stream_config->GetNumberOfCapabilities(&count, &size); |
506 if (FAILED(hr)) { | 496 DLOG_IF_FAILED_WITH_HRESULT("Failed to GetNumberOfCapabilities", hr); |
507 DLOG(ERROR) << "Failed to GetNumberOfCapabilities: " | 497 if (FAILED(hr)) |
508 << logging::SystemErrorCodeToString(hr); | |
509 return false; | 498 return false; |
510 } | |
511 | 499 |
512 std::unique_ptr<BYTE[]> caps(new BYTE[size]); | 500 std::unique_ptr<BYTE[]> caps(new BYTE[size]); |
513 for (int stream_index = 0; stream_index < count; ++stream_index) { | 501 for (int stream_index = 0; stream_index < count; ++stream_index) { |
514 ScopedMediaType media_type; | 502 ScopedMediaType media_type; |
515 hr = stream_config->GetStreamCaps(stream_index, media_type.Receive(), | 503 hr = stream_config->GetStreamCaps(stream_index, media_type.Receive(), |
516 caps.get()); | 504 caps.get()); |
517 // 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() |
518 // macros here since they'll trigger incorrectly. | 506 // macros here since they'll trigger incorrectly. |
519 if (hr != S_OK) { | 507 if (hr != S_OK) { |
520 DLOG(ERROR) << "Failed to GetStreamCaps: " | 508 DLOG(ERROR) << "Failed to GetStreamCaps"; |
521 << logging::SystemErrorCodeToString(hr); | |
522 return false; | 509 return false; |
523 } | 510 } |
524 | 511 |
525 if (media_type->majortype == MEDIATYPE_Video && | 512 if (media_type->majortype == MEDIATYPE_Video && |
526 media_type->formattype == FORMAT_VideoInfo) { | 513 media_type->formattype == FORMAT_VideoInfo) { |
527 VideoCaptureFormat format; | 514 VideoCaptureFormat format; |
528 format.pixel_format = | 515 format.pixel_format = |
529 TranslateMediaSubtypeToPixelFormat(media_type->subtype); | 516 TranslateMediaSubtypeToPixelFormat(media_type->subtype); |
530 if (format.pixel_format == PIXEL_FORMAT_UNKNOWN) | 517 if (format.pixel_format == PIXEL_FORMAT_UNKNOWN) |
531 continue; | 518 continue; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 data.Property.Set = PROPSETID_VIDCAP_VIDEOPROCAMP; | 575 data.Property.Set = PROPSETID_VIDCAP_VIDEOPROCAMP; |
589 data.Property.Id = KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY; | 576 data.Property.Id = KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY; |
590 data.Property.Flags = KSPROPERTY_TYPE_SET; | 577 data.Property.Flags = KSPROPERTY_TYPE_SET; |
591 data.Value = | 578 data.Value = |
592 (power_line_frequency == media::PowerLineFrequency::FREQUENCY_50HZ) ? 1 | 579 (power_line_frequency == media::PowerLineFrequency::FREQUENCY_50HZ) ? 1 |
593 : 2; | 580 : 2; |
594 data.Flags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL; | 581 data.Flags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL; |
595 hr = ks_propset->Set(PROPSETID_VIDCAP_VIDEOPROCAMP, | 582 hr = ks_propset->Set(PROPSETID_VIDCAP_VIDEOPROCAMP, |
596 KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY, &data, | 583 KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY, &data, |
597 sizeof(data), &data, sizeof(data)); | 584 sizeof(data), &data, sizeof(data)); |
598 DLOG_IF(ERROR, FAILED(hr)) << "Anti-flicker setting failed: " | 585 DLOG_IF_FAILED_WITH_HRESULT("Anti-flicker setting failed", hr); |
599 << logging::SystemErrorCodeToString(hr); | |
600 DVLOG_IF(2, SUCCEEDED(hr)) << "Anti-flicker set correctly."; | |
601 } else { | |
602 DVLOG(2) << "Anti-flicker setting not supported."; | |
603 } | 586 } |
604 } | 587 } |
605 | 588 |
606 void VideoCaptureDeviceWin::SetErrorState( | 589 void VideoCaptureDeviceWin::SetErrorState( |
607 const tracked_objects::Location& from_here, | 590 const tracked_objects::Location& from_here, |
608 const std::string& reason) { | 591 const std::string& reason, |
| 592 HRESULT hr) { |
609 DCHECK(thread_checker_.CalledOnValidThread()); | 593 DCHECK(thread_checker_.CalledOnValidThread()); |
| 594 DLOG_IF_FAILED_WITH_HRESULT(reason, hr); |
610 state_ = kError; | 595 state_ = kError; |
611 client_->OnError(from_here, reason); | 596 client_->OnError(from_here, reason); |
612 } | 597 } |
613 } // namespace media | 598 } // namespace media |
OLD | NEW |