| 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 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 | 341 |
| 342 // Reduce the frame rate if the requested frame rate is lower | 342 // Reduce the frame rate if the requested frame rate is lower |
| 343 // than the capability. | 343 // than the capability. |
| 344 const float frame_rate = | 344 const float frame_rate = |
| 345 std::min(params.requested_format.frame_rate, | 345 std::min(params.requested_format.frame_rate, |
| 346 found_capability.supported_format.frame_rate); | 346 found_capability.supported_format.frame_rate); |
| 347 | 347 |
| 348 ScopedComPtr<IAMStreamConfig> stream_config; | 348 ScopedComPtr<IAMStreamConfig> stream_config; |
| 349 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); | 349 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); |
| 350 if (FAILED(hr)) { | 350 if (FAILED(hr)) { |
| 351 SetErrorState("Can't get the Capture format settings"); | 351 SetErrorState(FROM_HERE, "Can't get the Capture format settings"); |
| 352 return; | 352 return; |
| 353 } | 353 } |
| 354 | 354 |
| 355 int count = 0, size = 0; | 355 int count = 0, size = 0; |
| 356 hr = stream_config->GetNumberOfCapabilities(&count, &size); | 356 hr = stream_config->GetNumberOfCapabilities(&count, &size); |
| 357 if (FAILED(hr)) { | 357 if (FAILED(hr)) { |
| 358 SetErrorState("Failed to GetNumberOfCapabilities"); | 358 SetErrorState(FROM_HERE, "Failed to GetNumberOfCapabilities"); |
| 359 return; | 359 return; |
| 360 } | 360 } |
| 361 | 361 |
| 362 scoped_ptr<BYTE[]> caps(new BYTE[size]); | 362 scoped_ptr<BYTE[]> caps(new BYTE[size]); |
| 363 ScopedMediaType media_type; | 363 ScopedMediaType media_type; |
| 364 | 364 |
| 365 // Get the windows capability from the capture device. | 365 // Get the windows capability from the capture device. |
| 366 // GetStreamCaps can return S_FALSE which we consider an error. Therefore the | 366 // GetStreamCaps can return S_FALSE which we consider an error. Therefore the |
| 367 // FAILED macro can't be used. | 367 // FAILED macro can't be used. |
| 368 hr = stream_config->GetStreamCaps(found_capability.stream_index, | 368 hr = stream_config->GetStreamCaps(found_capability.stream_index, |
| 369 media_type.Receive(), caps.get()); | 369 media_type.Receive(), caps.get()); |
| 370 if (hr != S_OK) { | 370 if (hr != S_OK) { |
| 371 SetErrorState("Failed to get capture device capabilities"); | 371 SetErrorState(FROM_HERE, "Failed to get capture device capabilities"); |
| 372 return; | 372 return; |
| 373 } | 373 } |
| 374 if (media_type->formattype == FORMAT_VideoInfo) { | 374 if (media_type->formattype == FORMAT_VideoInfo) { |
| 375 VIDEOINFOHEADER* h = | 375 VIDEOINFOHEADER* h = |
| 376 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); | 376 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); |
| 377 if (frame_rate > 0) | 377 if (frame_rate > 0) |
| 378 h->AvgTimePerFrame = kSecondsToReferenceTime / frame_rate; | 378 h->AvgTimePerFrame = kSecondsToReferenceTime / frame_rate; |
| 379 } | 379 } |
| 380 // Set the sink filter to request this format. | 380 // Set the sink filter to request this format. |
| 381 sink_filter_->SetRequestedMediaFormat( | 381 sink_filter_->SetRequestedMediaFormat( |
| 382 found_capability.supported_format.pixel_format, frame_rate, | 382 found_capability.supported_format.pixel_format, frame_rate, |
| 383 found_capability.info_header); | 383 found_capability.info_header); |
| 384 // Order the capture device to use this format. | 384 // Order the capture device to use this format. |
| 385 hr = stream_config->SetFormat(media_type.get()); | 385 hr = stream_config->SetFormat(media_type.get()); |
| 386 if (FAILED(hr)) { | 386 if (FAILED(hr)) { |
| 387 // TODO(grunell): Log the error. http://crbug.com/405016. | 387 // TODO(grunell): Log the error. http://crbug.com/405016. |
| 388 SetErrorState("Failed to set capture device output format"); | 388 SetErrorState(FROM_HERE, "Failed to set capture device output format"); |
| 389 return; | 389 return; |
| 390 } | 390 } |
| 391 | 391 |
| 392 SetAntiFlickerInCaptureFilter(params); | 392 SetAntiFlickerInCaptureFilter(params); |
| 393 | 393 |
| 394 if (media_type->subtype == kMediaSubTypeHDYC) { | 394 if (media_type->subtype == kMediaSubTypeHDYC) { |
| 395 // 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 |
| 396 // decompressor filter after source, let |graph_builder_| add it. | 396 // decompressor filter after source, let |graph_builder_| add it. |
| 397 hr = graph_builder_->Connect(output_capture_pin_.get(), | 397 hr = graph_builder_->Connect(output_capture_pin_.get(), |
| 398 input_sink_pin_.get()); | 398 input_sink_pin_.get()); |
| 399 } else { | 399 } else { |
| 400 hr = graph_builder_->ConnectDirect(output_capture_pin_.get(), | 400 hr = graph_builder_->ConnectDirect(output_capture_pin_.get(), |
| 401 input_sink_pin_.get(), NULL); | 401 input_sink_pin_.get(), NULL); |
| 402 } | 402 } |
| 403 | 403 |
| 404 if (FAILED(hr)) { | 404 if (FAILED(hr)) { |
| 405 SetErrorState("Failed to connect the Capture graph."); | 405 SetErrorState(FROM_HERE, "Failed to connect the Capture graph."); |
| 406 return; | 406 return; |
| 407 } | 407 } |
| 408 | 408 |
| 409 hr = media_control_->Pause(); | 409 hr = media_control_->Pause(); |
| 410 if (FAILED(hr)) { | 410 if (FAILED(hr)) { |
| 411 SetErrorState( | 411 SetErrorState( |
| 412 FROM_HERE, |
| 412 "Failed to pause the Capture device, is it already occupied?"); | 413 "Failed to pause the Capture device, is it already occupied?"); |
| 413 return; | 414 return; |
| 414 } | 415 } |
| 415 | 416 |
| 416 // Get the format back from the sink filter after the filter have been | 417 // Get the format back from the sink filter after the filter have been |
| 417 // connected. | 418 // connected. |
| 418 capture_format_ = sink_filter_->ResultingFormat(); | 419 capture_format_ = sink_filter_->ResultingFormat(); |
| 419 | 420 |
| 420 // Start capturing. | 421 // Start capturing. |
| 421 hr = media_control_->Run(); | 422 hr = media_control_->Run(); |
| 422 if (FAILED(hr)) { | 423 if (FAILED(hr)) { |
| 423 SetErrorState("Failed to start the Capture device."); | 424 SetErrorState(FROM_HERE, "Failed to start the Capture device."); |
| 424 return; | 425 return; |
| 425 } | 426 } |
| 426 | 427 |
| 427 state_ = kCapturing; | 428 state_ = kCapturing; |
| 428 } | 429 } |
| 429 | 430 |
| 430 void VideoCaptureDeviceWin::StopAndDeAllocate() { | 431 void VideoCaptureDeviceWin::StopAndDeAllocate() { |
| 431 DCHECK(thread_checker_.CalledOnValidThread()); | 432 DCHECK(thread_checker_.CalledOnValidThread()); |
| 432 if (state_ != kCapturing) | 433 if (state_ != kCapturing) |
| 433 return; | 434 return; |
| 434 | 435 |
| 435 HRESULT hr = media_control_->Stop(); | 436 HRESULT hr = media_control_->Stop(); |
| 436 if (FAILED(hr)) { | 437 if (FAILED(hr)) { |
| 437 SetErrorState("Failed to stop the capture graph."); | 438 SetErrorState(FROM_HERE, "Failed to stop the capture graph."); |
| 438 return; | 439 return; |
| 439 } | 440 } |
| 440 | 441 |
| 441 graph_builder_->Disconnect(output_capture_pin_.get()); | 442 graph_builder_->Disconnect(output_capture_pin_.get()); |
| 442 graph_builder_->Disconnect(input_sink_pin_.get()); | 443 graph_builder_->Disconnect(input_sink_pin_.get()); |
| 443 | 444 |
| 444 client_.reset(); | 445 client_.reset(); |
| 445 state_ = kIdle; | 446 state_ = kIdle; |
| 446 } | 447 } |
| 447 | 448 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY, &data, | 566 KSPROPERTY_VIDEOPROCAMP_POWERLINE_FREQUENCY, &data, |
| 566 sizeof(data), &data, sizeof(data)); | 567 sizeof(data), &data, sizeof(data)); |
| 567 DLOG_IF(ERROR, FAILED(hr)) << "Anti-flicker setting failed: " | 568 DLOG_IF(ERROR, FAILED(hr)) << "Anti-flicker setting failed: " |
| 568 << logging::SystemErrorCodeToString(hr); | 569 << logging::SystemErrorCodeToString(hr); |
| 569 DVLOG_IF(2, SUCCEEDED(hr)) << "Anti-flicker set correctly."; | 570 DVLOG_IF(2, SUCCEEDED(hr)) << "Anti-flicker set correctly."; |
| 570 } else { | 571 } else { |
| 571 DVLOG(2) << "Anti-flicker setting not supported."; | 572 DVLOG(2) << "Anti-flicker setting not supported."; |
| 572 } | 573 } |
| 573 } | 574 } |
| 574 | 575 |
| 575 void VideoCaptureDeviceWin::SetErrorState(const std::string& reason) { | 576 void VideoCaptureDeviceWin::SetErrorState( |
| 577 const tracked_objects::Location& from_here, |
| 578 const std::string& reason) { |
| 576 DCHECK(thread_checker_.CalledOnValidThread()); | 579 DCHECK(thread_checker_.CalledOnValidThread()); |
| 577 state_ = kError; | 580 state_ = kError; |
| 578 client_->OnError(reason); | 581 client_->OnError(from_here, reason); |
| 579 } | 582 } |
| 580 } // namespace media | 583 } // namespace media |
| OLD | NEW |