From 41874c23859b9a333bb6e6f48c9f815fe8c90c7d Mon Sep 17 00:00:00 2001 From: "mcasas@chromium.org" Date: Thu, 14 Aug 2014 14:07:12 +0000 Subject: [PATCH] Mac QTKit Video Capture: Force BlackMagic cameras to be opened in HD This is a refry of http://crrev.com/410363002, original description: >Force BlackMagic cameras to be opened in HD > >The Blackmagic driver causes a crash in QTKit when opened in VGA >when NTSC/PAL 10-bit is selected. QTKit does not allow us to query a >device's supported resolution, so this change adds BlackMagic to another >blacklist so that it is always opened in HD. In this continuation CL, Blacklisted QTKit devices are found during enumeration and flagged, so a) a special capability list is cooked for them, only including HD, b) they are not reconfigured on opening/capturing. BUG=396812, 347371 COLLABORATOR= vrk@chromium.org R=tommi@chromium.org, vrk@chromium.org Review URL: https://codereview.chromium.org/468833002 Cr-Commit-Position: refs/heads/master@{#289552} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289552 0039d316-1c4b-4281-b951-d872f2087c98 --- .../mac/video_capture_device_factory_mac.mm | 31 ++++++++++++++++++++-- .../video/capture/mac/video_capture_device_mac.mm | 23 +++++++++------- media/video/capture/video_capture_device.cc | 6 +++-- media/video/capture/video_capture_device.h | 8 ++++++ 4 files changed, 54 insertions(+), 14 deletions(-) diff --git a/media/video/capture/mac/video_capture_device_factory_mac.mm b/media/video/capture/mac/video_capture_device_factory_mac.mm index af97fd21e03c..f0efe6b760b5 100644 --- a/media/video/capture/mac/video_capture_device_factory_mac.mm +++ b/media/video/capture/mac/video_capture_device_factory_mac.mm @@ -20,10 +20,16 @@ namespace media { // Some devices are not correctly supported in AVFoundation, f.i. Blackmagic, // see http://crbug.com/347371. The devices are identified by a characteristic // trailing substring of uniqueId and by (part of) the vendor's name. +// Blackmagic cameras are known to crash if VGA is requested , see +// http://crbug.com/396812; for them HD is the only supported resolution. const struct NameAndVid { const char* unique_id_signature; const char* name; -} kBlacklistedCameras[] = { { "-01FDA82C8A9C", "Blackmagic" } }; + const int capture_width; + const int capture_height; + const float capture_frame_rate; +} kBlacklistedCameras[] = { + { "-01FDA82C8A9C", "Blackmagic", 1280, 720, 60.0f } }; static scoped_ptr EnumerateDevicesUsingQTKit() { @@ -36,6 +42,13 @@ EnumerateDevicesUsingQTKit() { VideoCaptureDevice::Name name( [[[capture_devices valueForKey:key] deviceName] UTF8String], [key UTF8String], VideoCaptureDevice::Name::QTKIT); + for (size_t i = 0; i < arraysize(kBlacklistedCameras); ++i) { + if (name.id().find(kBlacklistedCameras[i].name) != std::string::npos) { + DVLOG(2) << "Found blacklisted camera: " << name.id(); + name.set_is_blacklisted(true); + break; + } + } device_names->push_back(name); } return device_names.Pass(); @@ -175,7 +188,21 @@ void VideoCaptureDeviceFactoryMac::GetDeviceSupportedFormats( [VideoCaptureDeviceAVFoundation getDevice:device supportedFormats:supported_formats]; } else { - NOTIMPLEMENTED(); + // Blacklisted cameras provide their own supported format(s), otherwise no + // such information is provided for QTKit. + if (device.is_blacklisted()) { + for (size_t i = 0; i < arraysize(kBlacklistedCameras); ++i) { + if (device.id().find(kBlacklistedCameras[i].name) != + std::string::npos) { + supported_formats->push_back(media::VideoCaptureFormat( + gfx::Size(kBlacklistedCameras[i].capture_width, + kBlacklistedCameras[i].capture_height), + kBlacklistedCameras[i].capture_frame_rate, + media::PIXEL_FORMAT_UYVY)); + break; + } + } + } } } diff --git a/media/video/capture/mac/video_capture_device_mac.mm b/media/video/capture/mac/video_capture_device_mac.mm index b13496c8058b..2c1943b0b9a6 100644 --- a/media/video/capture/mac/video_capture_device_mac.mm +++ b/media/video/capture/mac/video_capture_device_mac.mm @@ -43,8 +43,9 @@ namespace media { -const int kMinFrameRate = 1; -const int kMaxFrameRate = 30; +// Mac specific limits for minimum and maximum frame rate. +const float kMinFrameRate = 1.0f; +const float kMaxFrameRate = 30.0f; // In device identifiers, the USB VID and PID are stored in 4 bytes each. const size_t kVidPidSize = 4; @@ -350,7 +351,9 @@ VideoCaptureDeviceMac::VideoCaptureDeviceMac(const Name& device_name) state_(kNotInitialized), capture_device_(nil), weak_factory_(this) { - final_resolution_selected_ = AVFoundationGlue::IsAVFoundationSupported(); + // Avoid reconfiguring AVFoundation or blacklisted devices. + final_resolution_selected_ = AVFoundationGlue::IsAVFoundationSupported() || + device_name.is_blacklisted(); } VideoCaptureDeviceMac::~VideoCaptureDeviceMac() { @@ -569,13 +572,13 @@ void VideoCaptureDeviceMac::LogMessage(const std::string& message) { } bool VideoCaptureDeviceMac::UpdateCaptureResolution() { - if (![capture_device_ setCaptureHeight:capture_format_.frame_size.height() - width:capture_format_.frame_size.width() - frameRate:capture_format_.frame_rate]) { - ReceiveError("Could not configure capture device."); - return false; - } - return true; + if (![capture_device_ setCaptureHeight:capture_format_.frame_size.height() + width:capture_format_.frame_size.width() + frameRate:capture_format_.frame_rate]) { + ReceiveError("Could not configure capture device."); + return false; + } + return true; } } // namespace media diff --git a/media/video/capture/video_capture_device.cc b/media/video/capture/video_capture_device.cc index 2d8420791fc8..3aa18269f013 100644 --- a/media/video/capture/video_capture_device.cc +++ b/media/video/capture/video_capture_device.cc @@ -38,7 +38,8 @@ VideoCaptureDevice::Name::Name(const std::string& name, : device_name_(name), unique_id_(id), capture_api_class_(api_type), - transport_type_(OTHER_TRANSPORT) {} + transport_type_(OTHER_TRANSPORT), + is_blacklisted_(false) {} VideoCaptureDevice::Name::Name(const std::string& name, const std::string& id, @@ -47,7 +48,8 @@ VideoCaptureDevice::Name::Name(const std::string& name, : device_name_(name), unique_id_(id), capture_api_class_(api_type), - transport_type_(transport_type) {} + transport_type_(transport_type), + is_blacklisted_(false) {} #endif VideoCaptureDevice::Name::~Name() {} diff --git a/media/video/capture/video_capture_device.h b/media/video/capture/video_capture_device.h index 3f953f889628..1edecc39c12c 100644 --- a/media/video/capture/video_capture_device.h +++ b/media/video/capture/video_capture_device.h @@ -109,6 +109,12 @@ class MEDIA_EXPORT VideoCaptureDevice { TransportType transport_type() const { return transport_type_; } + bool is_blacklisted() const { + return is_blacklisted_; + } + void set_is_blacklisted(bool is_blacklisted) { + is_blacklisted_ = is_blacklisted; + } #endif // if defined(OS_WIN) private: @@ -134,6 +140,8 @@ class MEDIA_EXPORT VideoCaptureDevice { #endif #if defined(OS_MACOSX) TransportType transport_type_; + // Flag used to mark blacklisted devices for QTKit Api. + bool is_blacklisted_; #endif // Allow generated copy constructor and assignment. }; -- 2.11.4.GIT