Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1072)

Side by Side Diff: trunk/src/media/video/capture/win/video_capture_device_win.cc

Issue 84393002: Revert 236927 "Reorganize media::VideoCapture* types" (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « trunk/src/media/video/capture/win/video_capture_device_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/video/capture/win/video_capture_device_win.h" 5 #include "media/video/capture/win/video_capture_device_win.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <list> 8 #include <list>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 hr = graph_builder_->AddFilter(sink_filter_, NULL); 334 hr = graph_builder_->AddFilter(sink_filter_, NULL);
335 if (FAILED(hr)) { 335 if (FAILED(hr)) {
336 DVLOG(2)<< "Failed to add the send filter to the graph."; 336 DVLOG(2)<< "Failed to add the send filter to the graph.";
337 return false; 337 return false;
338 } 338 }
339 339
340 return CreateCapabilityMap(); 340 return CreateCapabilityMap();
341 } 341 }
342 342
343 void VideoCaptureDeviceWin::AllocateAndStart( 343 void VideoCaptureDeviceWin::AllocateAndStart(
344 const VideoCaptureParams& params, 344 const VideoCaptureCapability& capture_format,
345 scoped_ptr<VideoCaptureDevice::Client> client) { 345 scoped_ptr<VideoCaptureDevice::Client> client) {
346 DCHECK(CalledOnValidThread()); 346 DCHECK(CalledOnValidThread());
347 if (state_ != kIdle) 347 if (state_ != kIdle)
348 return; 348 return;
349 349
350 client_ = client.Pass(); 350 client_ = client.Pass();
351 351
352 // Get the camera capability that best match the requested resolution. 352 // Get the camera capability that best match the requested resolution.
353 const VideoCaptureCapabilityWin& found_capability = 353 const VideoCaptureCapabilityWin& found_capability =
354 capabilities_.GetBestMatchedFormat( 354 capabilities_.GetBestMatchedCapability(capture_format.width,
355 params.requested_format.frame_size.width(), 355 capture_format.height,
356 params.requested_format.frame_size.height(), 356 capture_format.frame_rate);
357 params.requested_format.frame_rate); 357 VideoCaptureCapability capability = found_capability;
358 VideoCaptureFormat format = found_capability.supported_format;
359 358
360 // Reduce the frame rate if the requested frame rate is lower 359 // Reduce the frame rate if the requested frame rate is lower
361 // than the capability. 360 // than the capability.
362 if (format.frame_rate > params.requested_format.frame_rate) 361 if (capability.frame_rate > capture_format.frame_rate)
363 format.frame_rate = params.requested_format.frame_rate; 362 capability.frame_rate = capture_format.frame_rate;
364 363
365 AM_MEDIA_TYPE* pmt = NULL; 364 AM_MEDIA_TYPE* pmt = NULL;
366 VIDEO_STREAM_CONFIG_CAPS caps; 365 VIDEO_STREAM_CONFIG_CAPS caps;
367 366
368 ScopedComPtr<IAMStreamConfig> stream_config; 367 ScopedComPtr<IAMStreamConfig> stream_config;
369 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); 368 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive());
370 if (FAILED(hr)) { 369 if (FAILED(hr)) {
371 SetErrorState("Can't get the Capture format settings"); 370 SetErrorState("Can't get the Capture format settings");
372 return; 371 return;
373 } 372 }
374 373
375 // Get the windows capability from the capture device. 374 // Get the windows capability from the capture device.
376 hr = stream_config->GetStreamCaps(found_capability.stream_index, &pmt, 375 hr = stream_config->GetStreamCaps(found_capability.stream_index, &pmt,
377 reinterpret_cast<BYTE*>(&caps)); 376 reinterpret_cast<BYTE*>(&caps));
378 if (SUCCEEDED(hr)) { 377 if (SUCCEEDED(hr)) {
379 if (pmt->formattype == FORMAT_VideoInfo) { 378 if (pmt->formattype == FORMAT_VideoInfo) {
380 VIDEOINFOHEADER* h = reinterpret_cast<VIDEOINFOHEADER*>(pmt->pbFormat); 379 VIDEOINFOHEADER* h = reinterpret_cast<VIDEOINFOHEADER*>(pmt->pbFormat);
381 if (format.frame_rate > 0) 380 if (capability.frame_rate > 0)
382 h->AvgTimePerFrame = kSecondsToReferenceTime / format.frame_rate; 381 h->AvgTimePerFrame = kSecondsToReferenceTime / capability.frame_rate;
383 } 382 }
384 // Set the sink filter to request this format. 383 // Set the sink filter to request this capability.
385 sink_filter_->SetRequestedMediaFormat(format); 384 sink_filter_->SetRequestedMediaCapability(capability);
386 // Order the capture device to use this format. 385 // Order the capture device to use this capability.
387 hr = stream_config->SetFormat(pmt); 386 hr = stream_config->SetFormat(pmt);
388 } 387 }
389 388
390 if (FAILED(hr)) 389 if (FAILED(hr))
391 SetErrorState("Failed to set capture device output format"); 390 SetErrorState("Failed to set capture device output format");
392 391
393 if (format.pixel_format == PIXEL_FORMAT_MJPEG && !mjpg_filter_.get()) { 392 if (capability.color == PIXEL_FORMAT_MJPEG &&
393 !mjpg_filter_.get()) {
394 // Create MJPG filter if we need it. 394 // Create MJPG filter if we need it.
395 hr = mjpg_filter_.CreateInstance(CLSID_MjpegDec, NULL, CLSCTX_INPROC); 395 hr = mjpg_filter_.CreateInstance(CLSID_MjpegDec, NULL, CLSCTX_INPROC);
396 396
397 if (SUCCEEDED(hr)) { 397 if (SUCCEEDED(hr)) {
398 GetPin(mjpg_filter_, PINDIR_INPUT, GUID_NULL, input_mjpg_pin_.Receive()); 398 GetPin(mjpg_filter_, PINDIR_INPUT, GUID_NULL, input_mjpg_pin_.Receive());
399 GetPin(mjpg_filter_, PINDIR_OUTPUT, GUID_NULL, 399 GetPin(mjpg_filter_, PINDIR_OUTPUT, GUID_NULL,
400 output_mjpg_pin_.Receive()); 400 output_mjpg_pin_.Receive());
401 hr = graph_builder_->AddFilter(mjpg_filter_, NULL); 401 hr = graph_builder_->AddFilter(mjpg_filter_, NULL);
402 } 402 }
403 403
404 if (FAILED(hr)) { 404 if (FAILED(hr)) {
405 mjpg_filter_.Release(); 405 mjpg_filter_.Release();
406 input_mjpg_pin_.Release(); 406 input_mjpg_pin_.Release();
407 output_mjpg_pin_.Release(); 407 output_mjpg_pin_.Release();
408 } 408 }
409 } 409 }
410 410
411 if (format.pixel_format == PIXEL_FORMAT_MJPEG && mjpg_filter_.get()) { 411 if (capability.color == PIXEL_FORMAT_MJPEG &&
412 mjpg_filter_.get()) {
412 // Connect the camera to the MJPEG decoder. 413 // Connect the camera to the MJPEG decoder.
413 hr = graph_builder_->ConnectDirect(output_capture_pin_, input_mjpg_pin_, 414 hr = graph_builder_->ConnectDirect(output_capture_pin_, input_mjpg_pin_,
414 NULL); 415 NULL);
415 // Connect the MJPEG filter to the Capture filter. 416 // Connect the MJPEG filter to the Capture filter.
416 hr += graph_builder_->ConnectDirect(output_mjpg_pin_, input_sink_pin_, 417 hr += graph_builder_->ConnectDirect(output_mjpg_pin_, input_sink_pin_,
417 NULL); 418 NULL);
418 } else { 419 } else {
419 hr = graph_builder_->ConnectDirect(output_capture_pin_, input_sink_pin_, 420 hr = graph_builder_->ConnectDirect(output_capture_pin_, input_sink_pin_,
420 NULL); 421 NULL);
421 } 422 }
422 423
423 if (FAILED(hr)) { 424 if (FAILED(hr)) {
424 SetErrorState("Failed to connect the Capture graph."); 425 SetErrorState("Failed to connect the Capture graph.");
425 return; 426 return;
426 } 427 }
427 428
428 hr = media_control_->Pause(); 429 hr = media_control_->Pause();
429 if (FAILED(hr)) { 430 if (FAILED(hr)) {
430 SetErrorState("Failed to Pause the Capture device. " 431 SetErrorState("Failed to Pause the Capture device. "
431 "Is it already occupied?"); 432 "Is it already occupied?");
432 return; 433 return;
433 } 434 }
434 435
435 // Get the format back from the sink filter after the filter have been 436 // Get the capability back from the sink filter after the filter have been
436 // connected. 437 // connected.
437 capture_format_ = sink_filter_->ResultingFormat(); 438 current_setting_ = sink_filter_->ResultingCapability();
438 439
439 // Start capturing. 440 // Start capturing.
440 hr = media_control_->Run(); 441 hr = media_control_->Run();
441 if (FAILED(hr)) { 442 if (FAILED(hr)) {
442 SetErrorState("Failed to start the Capture device."); 443 SetErrorState("Failed to start the Capture device.");
443 return; 444 return;
444 } 445 }
445 446
446 state_ = kCapturing; 447 state_ = kCapturing;
447 } 448 }
(...skipping 23 matching lines...) Expand all
471 return; 472 return;
472 } 473 }
473 client_.reset(); 474 client_.reset();
474 state_ = kIdle; 475 state_ = kIdle;
475 } 476 }
476 477
477 // Implements SinkFilterObserver::SinkFilterObserver. 478 // Implements SinkFilterObserver::SinkFilterObserver.
478 void VideoCaptureDeviceWin::FrameReceived(const uint8* buffer, 479 void VideoCaptureDeviceWin::FrameReceived(const uint8* buffer,
479 int length) { 480 int length) {
480 client_->OnIncomingCapturedFrame( 481 client_->OnIncomingCapturedFrame(
481 buffer, length, base::Time::Now(), 0, false, false, capture_format_); 482 buffer, length, base::Time::Now(), 0, false, false, current_setting_);
482 } 483 }
483 484
484 bool VideoCaptureDeviceWin::CreateCapabilityMap() { 485 bool VideoCaptureDeviceWin::CreateCapabilityMap() {
485 DCHECK(CalledOnValidThread()); 486 DCHECK(CalledOnValidThread());
486 ScopedComPtr<IAMStreamConfig> stream_config; 487 ScopedComPtr<IAMStreamConfig> stream_config;
487 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive()); 488 HRESULT hr = output_capture_pin_.QueryInterface(stream_config.Receive());
488 if (FAILED(hr)) { 489 if (FAILED(hr)) {
489 DVLOG(2) << "Failed to get IAMStreamConfig interface from " 490 DVLOG(2) << "Failed to get IAMStreamConfig interface from "
490 "capture device"; 491 "capture device";
491 return false; 492 return false;
(...skipping 22 matching lines...) Expand all
514 if (hr != S_OK) { 515 if (hr != S_OK) {
515 DVLOG(2) << "Failed to GetStreamCaps"; 516 DVLOG(2) << "Failed to GetStreamCaps";
516 return false; 517 return false;
517 } 518 }
518 519
519 if (media_type->majortype == MEDIATYPE_Video && 520 if (media_type->majortype == MEDIATYPE_Video &&
520 media_type->formattype == FORMAT_VideoInfo) { 521 media_type->formattype == FORMAT_VideoInfo) {
521 VideoCaptureCapabilityWin capability(i); 522 VideoCaptureCapabilityWin capability(i);
522 VIDEOINFOHEADER* h = 523 VIDEOINFOHEADER* h =
523 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); 524 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat);
524 capability.supported_format.frame_size.SetSize(h->bmiHeader.biWidth, 525 capability.width = h->bmiHeader.biWidth;
525 h->bmiHeader.biHeight); 526 capability.height = h->bmiHeader.biHeight;
526 527
527 // Try to get a better |time_per_frame| from IAMVideoControl. If not, use 528 // Try to get a better |time_per_frame| from IAMVideoControl. If not, use
528 // the value from VIDEOINFOHEADER. 529 // the value from VIDEOINFOHEADER.
529 REFERENCE_TIME time_per_frame = h->AvgTimePerFrame; 530 REFERENCE_TIME time_per_frame = h->AvgTimePerFrame;
530 if (video_control) { 531 if (video_control) {
531 ScopedCoMem<LONGLONG> max_fps; 532 ScopedCoMem<LONGLONG> max_fps;
532 LONG list_size = 0; 533 LONG list_size = 0;
533 SIZE size = {capability.supported_format.frame_size.width(), 534 SIZE size = { capability.width, capability.height };
534 capability.supported_format.frame_size.height()};
535 535
536 // GetFrameRateList doesn't return max frame rate always 536 // GetFrameRateList doesn't return max frame rate always
537 // eg: Logitech Notebook. This may be due to a bug in that API 537 // eg: Logitech Notebook. This may be due to a bug in that API
538 // because GetFrameRateList array is reversed in the above camera. So 538 // because GetFrameRateList array is reversed in the above camera. So
539 // a util method written. Can't assume the first value will return 539 // a util method written. Can't assume the first value will return
540 // the max fps. 540 // the max fps.
541 hr = video_control->GetFrameRateList(output_capture_pin_, i, size, 541 hr = video_control->GetFrameRateList(output_capture_pin_, i, size,
542 &list_size, &max_fps); 542 &list_size, &max_fps);
543 // Sometimes |list_size| will be > 0, but max_fps will be NULL. Some 543 // Sometimes |list_size| will be > 0, but max_fps will be NULL. Some
544 // drivers may return an HRESULT of S_FALSE which SUCCEEDED() translates 544 // drivers may return an HRESULT of S_FALSE which SUCCEEDED() translates
545 // into success, so explicitly check S_OK. See http://crbug.com/306237. 545 // into success, so explicitly check S_OK. See http://crbug.com/306237.
546 if (hr == S_OK && list_size > 0 && max_fps) { 546 if (hr == S_OK && list_size > 0 && max_fps) {
547 time_per_frame = *std::min_element(max_fps.get(), 547 time_per_frame = *std::min_element(max_fps.get(),
548 max_fps.get() + list_size); 548 max_fps.get() + list_size);
549 } 549 }
550 } 550 }
551 551
552 capability.supported_format.frame_rate = 552 capability.frame_rate = (time_per_frame > 0) ?
553 (time_per_frame > 0) 553 static_cast<int>(kSecondsToReferenceTime / time_per_frame) : 0;
554 ? static_cast<int>(kSecondsToReferenceTime / time_per_frame)
555 : 0;
556 554
557 // DirectShow works at the moment only on integer frame_rate but the 555 // DirectShow works at the moment only on integer frame_rate but the
558 // best capability matching class works on rational frame rates. 556 // best capability matching class works on rational frame rates.
559 capability.frame_rate_numerator = capability.supported_format.frame_rate; 557 capability.frame_rate_numerator = capability.frame_rate;
560 capability.frame_rate_denominator = 1; 558 capability.frame_rate_denominator = 1;
561 559
562 // We can't switch MEDIATYPE :~(. 560 // We can't switch MEDIATYPE :~(.
563 if (media_type->subtype == kMediaSubTypeI420) { 561 if (media_type->subtype == kMediaSubTypeI420) {
564 capability.supported_format.pixel_format = PIXEL_FORMAT_I420; 562 capability.color = PIXEL_FORMAT_I420;
565 } else if (media_type->subtype == MEDIASUBTYPE_IYUV) { 563 } else if (media_type->subtype == MEDIASUBTYPE_IYUV) {
566 // This is identical to PIXEL_FORMAT_I420. 564 // This is identical to PIXEL_FORMAT_I420.
567 capability.supported_format.pixel_format = PIXEL_FORMAT_I420; 565 capability.color = PIXEL_FORMAT_I420;
568 } else if (media_type->subtype == MEDIASUBTYPE_RGB24) { 566 } else if (media_type->subtype == MEDIASUBTYPE_RGB24) {
569 capability.supported_format.pixel_format = PIXEL_FORMAT_RGB24; 567 capability.color = PIXEL_FORMAT_RGB24;
570 } else if (media_type->subtype == MEDIASUBTYPE_YUY2) { 568 } else if (media_type->subtype == MEDIASUBTYPE_YUY2) {
571 capability.supported_format.pixel_format = PIXEL_FORMAT_YUY2; 569 capability.color = PIXEL_FORMAT_YUY2;
572 } else if (media_type->subtype == MEDIASUBTYPE_MJPG) { 570 } else if (media_type->subtype == MEDIASUBTYPE_MJPG) {
573 capability.supported_format.pixel_format = PIXEL_FORMAT_MJPEG; 571 capability.color = PIXEL_FORMAT_MJPEG;
574 } else if (media_type->subtype == MEDIASUBTYPE_UYVY) { 572 } else if (media_type->subtype == MEDIASUBTYPE_UYVY) {
575 capability.supported_format.pixel_format = PIXEL_FORMAT_UYVY; 573 capability.color = PIXEL_FORMAT_UYVY;
576 } else if (media_type->subtype == MEDIASUBTYPE_ARGB32) { 574 } else if (media_type->subtype == MEDIASUBTYPE_ARGB32) {
577 capability.supported_format.pixel_format = PIXEL_FORMAT_ARGB; 575 capability.color = PIXEL_FORMAT_ARGB;
578 } else { 576 } else {
579 WCHAR guid_str[128]; 577 WCHAR guid_str[128];
580 StringFromGUID2(media_type->subtype, guid_str, arraysize(guid_str)); 578 StringFromGUID2(media_type->subtype, guid_str, arraysize(guid_str));
581 DVLOG(2) << "Device supports (also) an unknown media type " << guid_str; 579 DVLOG(2) << "Device supports (also) an unknown media type " << guid_str;
582 continue; 580 continue;
583 } 581 }
584 capabilities_.Add(capability); 582 capabilities_.Add(capability);
585 } 583 }
586 DeleteMediaType(media_type); 584 DeleteMediaType(media_type);
587 media_type = NULL; 585 media_type = NULL;
588 } 586 }
589 587
590 return !capabilities_.empty(); 588 return !capabilities_.empty();
591 } 589 }
592 590
593 void VideoCaptureDeviceWin::SetErrorState(const char* reason) { 591 void VideoCaptureDeviceWin::SetErrorState(const char* reason) {
594 DCHECK(CalledOnValidThread()); 592 DCHECK(CalledOnValidThread());
595 DVLOG(1) << reason; 593 DVLOG(1) << reason;
596 state_ = kError; 594 state_ = kError;
597 client_->OnError(); 595 client_->OnError();
598 } 596 }
599 } // namespace media 597 } // namespace media
OLDNEW
« no previous file with comments | « trunk/src/media/video/capture/win/video_capture_device_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698