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_WITH_HRESULT(message, hr) \ | |
xianglu
2016/09/22 20:55:14
Would it be better if named DLOG_IF_FAILED_WITH_HR
| |
29 { \ | |
30 DLOG_IF(ERROR, FAILED(hr)) << (message) << ": " \ | |
31 << logging::SystemErrorCodeToString(hr); \ | |
32 } | |
33 #else | |
34 #define DLOG_IF_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_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_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_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_WITH_HRESULT("Failed to give graph to capture graph builder", hr); |
286 DLOG(ERROR) << "Failed to give graph to capture graph builder: " | 290 if (FAILED(hr)) |
287 << logging::SystemErrorCodeToString(hr); | |
288 return false; | 291 return false; |
289 } | |
290 | 292 |
291 hr = graph_builder_.QueryInterface(media_control_.Receive()); | 293 hr = graph_builder_.QueryInterface(media_control_.Receive()); |
292 if (FAILED(hr)) { | 294 DLOG_IF_WITH_HRESULT("Failed to create media control builder", hr); |
293 DLOG(ERROR) << "Failed to create media control builder: " | 295 if (FAILED(hr)) |
294 << logging::SystemErrorCodeToString(hr); | |
295 return false; | 296 return false; |
296 } | |
297 | 297 |
298 hr = graph_builder_->AddFilter(capture_filter_.get(), NULL); | 298 hr = graph_builder_->AddFilter(capture_filter_.get(), NULL); |
299 if (FAILED(hr)) { | 299 DLOG_IF_WITH_HRESULT("Failed to add the capture device to the graph", hr); |
300 DLOG(ERROR) << "Failed to add the capture device to the graph: " | 300 if (FAILED(hr)) |
301 << logging::SystemErrorCodeToString(hr); | |
302 return false; | 301 return false; |
303 } | |
304 | 302 |
305 hr = graph_builder_->AddFilter(sink_filter_.get(), NULL); | 303 hr = graph_builder_->AddFilter(sink_filter_.get(), NULL); |
306 if (FAILED(hr)) { | 304 DLOG_IF_WITH_HRESULT("Failed to add the sink filter to the graph", hr); |
307 DLOG(ERROR) << "Failed to add the sink filter to the graph: " | 305 if (FAILED(hr)) |
308 << logging::SystemErrorCodeToString(hr); | |
309 return false; | 306 return false; |
310 } | |
311 | 307 |
312 // The following code builds the upstream portions of the graph, | 308 // 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) | 309 // 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 | 310 // 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 | 311 // 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 | 312 // prevalent MEDIATYPE_Interleaved first. |
317 // MEDIATYPE_Interleaved first. | |
318 base::win::ScopedComPtr<IAMStreamConfig> stream_config; | 313 base::win::ScopedComPtr<IAMStreamConfig> stream_config; |
319 | 314 |
320 hr = capture_graph_builder_->FindInterface( | 315 hr = capture_graph_builder_->FindInterface( |
321 &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, capture_filter_.get(), | 316 &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, capture_filter_.get(), |
322 IID_IAMStreamConfig, (void**)stream_config.Receive()); | 317 IID_IAMStreamConfig, (void**)stream_config.Receive()); |
323 if (FAILED(hr)) { | 318 if (FAILED(hr)) { |
324 hr = capture_graph_builder_->FindInterface( | 319 hr = capture_graph_builder_->FindInterface( |
325 &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, capture_filter_.get(), | 320 &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, capture_filter_.get(), |
326 IID_IAMStreamConfig, (void**)stream_config.Receive()); | 321 IID_IAMStreamConfig, (void**)stream_config.Receive()); |
327 DLOG_IF(ERROR, FAILED(hr)) << "Failed to find CapFilter:IAMStreamConfig: " | 322 DLOG_IF_WITH_HRESULT("Failed to find CapFilter:IAMStreamConfig", hr); |
328 << logging::SystemErrorCodeToString(hr); | |
329 } | 323 } |
330 | 324 |
331 return CreateCapabilityMap(); | 325 return CreateCapabilityMap(); |
332 } | 326 } |
333 | 327 |
334 void VideoCaptureDeviceWin::AllocateAndStart( | 328 void VideoCaptureDeviceWin::AllocateAndStart( |
335 const VideoCaptureParams& params, | 329 const VideoCaptureParams& params, |
336 std::unique_ptr<VideoCaptureDevice::Client> client) { | 330 std::unique_ptr<VideoCaptureDevice::Client> client) { |
337 DCHECK(thread_checker_.CalledOnValidThread()); | 331 DCHECK(thread_checker_.CalledOnValidThread()); |
338 if (state_ != kIdle) | 332 if (state_ != kIdle) |
339 return; | 333 return; |
340 | 334 |
341 client_ = std::move(client); | 335 client_ = std::move(client); |
342 | 336 |
343 // Get the camera capability that best match the requested format. | 337 // Get the camera capability that best match the requested format. |
344 const CapabilityWin found_capability = | 338 const CapabilityWin found_capability = |
345 GetBestMatchedCapability(params.requested_format, capabilities_); | 339 GetBestMatchedCapability(params.requested_format, capabilities_); |
346 | 340 |
347 // Reduce the frame rate if the requested frame rate is lower | 341 // Reduce the frame rate if the requested frame rate is lower |
348 // than the capability. | 342 // than the capability. |
349 const float frame_rate = | 343 const float frame_rate = |
350 std::min(params.requested_format.frame_rate, | 344 std::min(params.requested_format.frame_rate, |
351 found_capability.supported_format.frame_rate); | 345 found_capability.supported_format.frame_rate); |
352 | 346 |
353 ScopedComPtr<IAMStreamConfig> stream_config; | 347 ScopedComPtr<IAMStreamConfig> stream_config; |
354 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); | 348 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); |
355 if (FAILED(hr)) { | 349 if (FAILED(hr)) { |
356 SetErrorState(FROM_HERE, "Can't get the Capture format settings"); | 350 SetErrorState(FROM_HERE, "Can't get the Capture format settings", hr); |
357 return; | 351 return; |
358 } | 352 } |
359 | 353 |
360 int count = 0, size = 0; | 354 int count = 0, size = 0; |
361 hr = stream_config->GetNumberOfCapabilities(&count, &size); | 355 hr = stream_config->GetNumberOfCapabilities(&count, &size); |
362 if (FAILED(hr)) { | 356 if (FAILED(hr)) { |
363 SetErrorState(FROM_HERE, "Failed to GetNumberOfCapabilities"); | 357 SetErrorState(FROM_HERE, "Failed to GetNumberOfCapabilities", hr); |
364 return; | 358 return; |
365 } | 359 } |
366 | 360 |
367 std::unique_ptr<BYTE[]> caps(new BYTE[size]); | 361 std::unique_ptr<BYTE[]> caps(new BYTE[size]); |
368 ScopedMediaType media_type; | 362 ScopedMediaType media_type; |
369 | 363 |
370 // Get the windows capability from the capture device. | 364 // Get the windows capability from the capture device. |
371 // GetStreamCaps can return S_FALSE which we consider an error. Therefore the | 365 // GetStreamCaps can return S_FALSE which we consider an error. Therefore the |
372 // FAILED macro can't be used. | 366 // FAILED macro can't be used. |
373 hr = stream_config->GetStreamCaps(found_capability.stream_index, | 367 hr = stream_config->GetStreamCaps(found_capability.stream_index, |
374 media_type.Receive(), caps.get()); | 368 media_type.Receive(), caps.get()); |
375 if (hr != S_OK) { | 369 if (hr != S_OK) { |
376 SetErrorState(FROM_HERE, "Failed to get capture device capabilities"); | 370 SetErrorState(FROM_HERE, "Failed to get capture device capabilities", hr); |
377 return; | 371 return; |
378 } | 372 } |
379 if (media_type->formattype == FORMAT_VideoInfo) { | 373 if (media_type->formattype == FORMAT_VideoInfo) { |
380 VIDEOINFOHEADER* h = | 374 VIDEOINFOHEADER* h = |
381 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); | 375 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); |
382 if (frame_rate > 0) | 376 if (frame_rate > 0) |
383 h->AvgTimePerFrame = kSecondsToReferenceTime / frame_rate; | 377 h->AvgTimePerFrame = kSecondsToReferenceTime / frame_rate; |
384 } | 378 } |
385 // Set the sink filter to request this format. | 379 // Set the sink filter to request this format. |
386 sink_filter_->SetRequestedMediaFormat( | 380 sink_filter_->SetRequestedMediaFormat( |
387 found_capability.supported_format.pixel_format, frame_rate, | 381 found_capability.supported_format.pixel_format, frame_rate, |
388 found_capability.info_header); | 382 found_capability.info_header); |
389 // Order the capture device to use this format. | 383 // Order the capture device to use this format. |
390 hr = stream_config->SetFormat(media_type.get()); | 384 hr = stream_config->SetFormat(media_type.get()); |
391 if (FAILED(hr)) { | 385 if (FAILED(hr)) { |
392 // TODO(grunell): Log the error. http://crbug.com/405016. | 386 SetErrorState(FROM_HERE, "Failed to set capture device output format", hr); |
393 SetErrorState(FROM_HERE, "Failed to set capture device output format"); | |
394 return; | 387 return; |
395 } | 388 } |
396 | 389 |
397 SetAntiFlickerInCaptureFilter(params); | 390 SetAntiFlickerInCaptureFilter(params); |
398 | 391 |
399 if (media_type->subtype == kMediaSubTypeHDYC) { | 392 if (media_type->subtype == kMediaSubTypeHDYC) { |
400 // HDYC pixel format, used by the DeckLink capture card, needs an AVI | 393 // HDYC pixel format, used by the DeckLink capture card, needs an AVI |
401 // decompressor filter after source, let |graph_builder_| add it. | 394 // decompressor filter after source, let |graph_builder_| add it. |
402 hr = graph_builder_->Connect(output_capture_pin_.get(), | 395 hr = graph_builder_->Connect(output_capture_pin_.get(), |
403 input_sink_pin_.get()); | 396 input_sink_pin_.get()); |
404 } else { | 397 } else { |
405 hr = graph_builder_->ConnectDirect(output_capture_pin_.get(), | 398 hr = graph_builder_->ConnectDirect(output_capture_pin_.get(), |
406 input_sink_pin_.get(), NULL); | 399 input_sink_pin_.get(), NULL); |
407 } | 400 } |
408 | 401 |
409 if (FAILED(hr)) { | 402 if (FAILED(hr)) { |
410 SetErrorState(FROM_HERE, "Failed to connect the Capture graph."); | 403 SetErrorState(FROM_HERE, "Failed to connect the Capture graph.", hr); |
411 return; | 404 return; |
412 } | 405 } |
413 | 406 |
414 hr = media_control_->Pause(); | 407 hr = media_control_->Pause(); |
415 if (FAILED(hr)) { | 408 if (FAILED(hr)) { |
416 SetErrorState( | 409 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; | 410 return; |
420 } | 411 } |
421 | 412 |
422 // Get the format back from the sink filter after the filter have been | 413 // Get the format back from the sink filter after the filter have been |
423 // connected. | 414 // connected. |
424 capture_format_ = sink_filter_->ResultingFormat(); | 415 capture_format_ = sink_filter_->ResultingFormat(); |
425 | 416 |
426 // Start capturing. | 417 // Start capturing. |
427 hr = media_control_->Run(); | 418 hr = media_control_->Run(); |
428 if (FAILED(hr)) { | 419 if (FAILED(hr)) { |
429 SetErrorState(FROM_HERE, "Failed to start the Capture device."); | 420 SetErrorState(FROM_HERE, "Failed to start the Capture device.", hr); |
430 return; | 421 return; |
431 } | 422 } |
432 | 423 |
433 state_ = kCapturing; | 424 state_ = kCapturing; |
434 } | 425 } |
435 | 426 |
436 void VideoCaptureDeviceWin::StopAndDeAllocate() { | 427 void VideoCaptureDeviceWin::StopAndDeAllocate() { |
437 DCHECK(thread_checker_.CalledOnValidThread()); | 428 DCHECK(thread_checker_.CalledOnValidThread()); |
438 if (state_ != kCapturing) | 429 if (state_ != kCapturing) |
439 return; | 430 return; |
440 | 431 |
441 HRESULT hr = media_control_->Stop(); | 432 HRESULT hr = media_control_->Stop(); |
442 if (FAILED(hr)) { | 433 if (FAILED(hr)) { |
443 SetErrorState(FROM_HERE, "Failed to stop the capture graph."); | 434 SetErrorState(FROM_HERE, "Failed to stop the capture graph.", hr); |
444 return; | 435 return; |
445 } | 436 } |
446 | 437 |
447 graph_builder_->Disconnect(output_capture_pin_.get()); | 438 graph_builder_->Disconnect(output_capture_pin_.get()); |
448 graph_builder_->Disconnect(input_sink_pin_.get()); | 439 graph_builder_->Disconnect(input_sink_pin_.get()); |
449 | 440 |
450 client_.reset(); | 441 client_.reset(); |
451 state_ = kIdle; | 442 state_ = kIdle; |
452 } | 443 } |
453 | 444 |
(...skipping 28 matching lines...) Expand all Loading... | |
482 mojom::BlobPtr blob = Blobify(buffer, length, capture_format_); | 473 mojom::BlobPtr blob = Blobify(buffer, length, capture_format_); |
483 if (blob) | 474 if (blob) |
484 cb.Run(std::move(blob)); | 475 cb.Run(std::move(blob)); |
485 } | 476 } |
486 } | 477 } |
487 | 478 |
488 bool VideoCaptureDeviceWin::CreateCapabilityMap() { | 479 bool VideoCaptureDeviceWin::CreateCapabilityMap() { |
489 DCHECK(thread_checker_.CalledOnValidThread()); | 480 DCHECK(thread_checker_.CalledOnValidThread()); |
490 ScopedComPtr<IAMStreamConfig> stream_config; | 481 ScopedComPtr<IAMStreamConfig> stream_config; |
491 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); | 482 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); |
492 if (FAILED(hr)) { | 483 DLOG_IF_WITH_HRESULT("Failed to get IAMStreamConfig from capture device", hr); |
493 DPLOG(ERROR) << "Failed to get IAMStreamConfig interface from " | 484 if (FAILED(hr)) |
494 "capture device: " << logging::SystemErrorCodeToString(hr); | |
495 return false; | 485 return false; |
496 } | |
497 | 486 |
498 // Get interface used for getting the frame rate. | 487 // Get interface used for getting the frame rate. |
499 ScopedComPtr<IAMVideoControl> video_control; | 488 ScopedComPtr<IAMVideoControl> video_control; |
500 hr = capture_filter_.QueryInterface(video_control.Receive()); | 489 hr = capture_filter_.QueryInterface(video_control.Receive()); |
501 DLOG_IF(WARNING, FAILED(hr)) << "IAMVideoControl Interface NOT SUPPORTED: " | |
502 << logging::SystemErrorCodeToString(hr); | |
503 | 490 |
504 int count = 0, size = 0; | 491 int count = 0, size = 0; |
505 hr = stream_config->GetNumberOfCapabilities(&count, &size); | 492 hr = stream_config->GetNumberOfCapabilities(&count, &size); |
506 if (FAILED(hr)) { | 493 DLOG_IF_WITH_HRESULT("Failed to GetNumberOfCapabilities", hr); |
507 DLOG(ERROR) << "Failed to GetNumberOfCapabilities: " | 494 if (FAILED(hr)) |
508 << logging::SystemErrorCodeToString(hr); | |
509 return false; | 495 return false; |
510 } | |
511 | 496 |
512 std::unique_ptr<BYTE[]> caps(new BYTE[size]); | 497 std::unique_ptr<BYTE[]> caps(new BYTE[size]); |
513 for (int stream_index = 0; stream_index < count; ++stream_index) { | 498 for (int stream_index = 0; stream_index < count; ++stream_index) { |
514 ScopedMediaType media_type; | 499 ScopedMediaType media_type; |
515 hr = stream_config->GetStreamCaps(stream_index, media_type.Receive(), | 500 hr = stream_config->GetStreamCaps(stream_index, media_type.Receive(), |
516 caps.get()); | 501 caps.get()); |
517 // GetStreamCaps() may return S_FALSE, so don't use FAILED() or SUCCEED() | 502 // GetStreamCaps() may return S_FALSE, so don't use FAILED() or SUCCEED() |
518 // macros here since they'll trigger incorrectly. | 503 // macros here since they'll trigger incorrectly. |
519 if (hr != S_OK) { | 504 if (hr != S_OK) { |
520 DLOG(ERROR) << "Failed to GetStreamCaps: " | 505 DLOG(ERROR) << "Failed to GetStreamCaps"; |
521 << logging::SystemErrorCodeToString(hr); | |
522 return false; | 506 return false; |
523 } | 507 } |
524 | 508 |
525 if (media_type->majortype == MEDIATYPE_Video && | 509 if (media_type->majortype == MEDIATYPE_Video && |
526 media_type->formattype == FORMAT_VideoInfo) { | 510 media_type->formattype == FORMAT_VideoInfo) { |
527 VideoCaptureFormat format; | 511 VideoCaptureFormat format; |
528 format.pixel_format = | 512 format.pixel_format = |
529 TranslateMediaSubtypeToPixelFormat(media_type->subtype); | 513 TranslateMediaSubtypeToPixelFormat(media_type->subtype); |
530 if (format.pixel_format == PIXEL_FORMAT_UNKNOWN) | 514 if (format.pixel_format == PIXEL_FORMAT_UNKNOWN) |
531 continue; | 515 continue; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
588 data.Property.Set = PROPSETID_VIDCAP_VIDEOPROCAMP; | 572 data.Property.Set = PROPSETID_VIDCAP_VIDEOPROCAMP; |
589 data.Property.Id = KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY; | 573 data.Property.Id = KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY; |
590 data.Property.Flags = KSPROPERTY_TYPE_SET; | 574 data.Property.Flags = KSPROPERTY_TYPE_SET; |
591 data.Value = | 575 data.Value = |
592 (power_line_frequency == media::PowerLineFrequency::FREQUENCY_50HZ) ? 1 | 576 (power_line_frequency == media::PowerLineFrequency::FREQUENCY_50HZ) ? 1 |
593 : 2; | 577 : 2; |
594 data.Flags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL; | 578 data.Flags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL; |
595 hr = ks_propset->Set(PROPSETID_VIDCAP_VIDEOPROCAMP, | 579 hr = ks_propset->Set(PROPSETID_VIDCAP_VIDEOPROCAMP, |
596 KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY, &data, | 580 KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY, &data, |
597 sizeof(data), &data, sizeof(data)); | 581 sizeof(data), &data, sizeof(data)); |
598 DLOG_IF(ERROR, FAILED(hr)) << "Anti-flicker setting failed: " | 582 DLOG_IF_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 } | 583 } |
604 } | 584 } |
605 | 585 |
606 void VideoCaptureDeviceWin::SetErrorState( | 586 void VideoCaptureDeviceWin::SetErrorState( |
607 const tracked_objects::Location& from_here, | 587 const tracked_objects::Location& from_here, |
608 const std::string& reason) { | 588 const std::string& reason, |
589 HRESULT hr) { | |
609 DCHECK(thread_checker_.CalledOnValidThread()); | 590 DCHECK(thread_checker_.CalledOnValidThread()); |
591 DLOG_IF_WITH_HRESULT(reason, hr); | |
610 state_ = kError; | 592 state_ = kError; |
611 client_->OnError(from_here, reason); | 593 client_->OnError(from_here, reason); |
612 } | 594 } |
613 } // namespace media | 595 } // namespace media |
OLD | NEW |