<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[192838] trunk/Source/WebCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/192838">192838</a></dd>
<dt>Author</dt> <dd>wenson_hsieh@apple.com</dd>
<dt>Date</dt> <dd>2015-11-30 15:48:42 -0800 (Mon, 30 Nov 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Split platform-independent logic in AVCaptureDeviceManager out into a new class
https://bugs.webkit.org/show_bug.cgi?id=151388
<rdar://problem/23593980>
Reviewed by Eric Carlson.
To prepare for creating a MockCaptureDeviceManager to be able to test
MediaDevices.getUserMedia, we create a platform-independent capture device manager
which all platforms should extend and add platform-specific logic to.
The methods CaptureDeviceManager::createMediaSourceForCaptureDeviceWithConstraints and
CaptureDeviceManager::captureDeviceList should be overridden by each platform
CaptureDeviceManager to respectively create a RealtimeMediaSource and return a list of
capture devices. createMediaSourceForCaptureDeviceWithConstraints attempts to create
a media source for a given device with some constraints; if the contraints cannot be
satisfied, this returns null.
The refactored capture device manager also introduces the notion of a platform-
independent capture session which may be extended by platform device managers for
determining whether a given constraint name, value and media type is valid.
A platform-independent CaptureDeviceInfo now represents either the video or audio
component of a capture device, but not both at once. This means a capture device that
supports both video and audio will emit two separate capture devices.
No new tests, since there should be no behavior change.
* Modules/mediastream/CaptureDeviceInfo.h: Added.
(WebCore::CaptureSessionInfo::~CaptureSessionInfo):
(WebCore::CaptureSessionInfo::supportsVideoSize):
(WebCore::CaptureSessionInfo::bestSessionPresetForVideoDimensions):
* Modules/mediastream/CaptureDeviceManager.cpp: Added.
(CaptureDeviceManager::~CaptureDeviceManager):
(CaptureDeviceManager::getSourcesInfo):
(CaptureDeviceManager::captureDeviceFromDeviceID):
(CaptureDeviceManager::verifyConstraintsForMediaType):
(CaptureDeviceManager::bestSourcesForTypeAndConstraints):
(CaptureDeviceManager::sourceWithUID):
(CaptureDeviceManager::bestDeviceForFacingMode):
(facingModeFromString):
(CaptureDeviceManager::sessionSupportsConstraint):
(CaptureDeviceManager::isSupportedFrameRate):
* Modules/mediastream/CaptureDeviceManager.h: Added.
(WebCore::CaptureDeviceManager::refreshCaptureDeviceList):
(WebCore::CaptureDeviceManager::defaultCaptureSession):
* WebCore.xcodeproj/project.pbxproj:
* platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp: Added.
(WebCore::RealtimeMediaSourceSupportedConstraints::nameForConstraint):
(WebCore::RealtimeMediaSourceSupportedConstraints::constraintFromName):
(WebCore::RealtimeMediaSourceSupportedConstraints::supportsConstraint):
* platform/mediastream/RealtimeMediaSourceSupportedConstraints.h:
* platform/mediastream/mac/AVCaptureDeviceManager.h:
* platform/mediastream/mac/AVCaptureDeviceManager.mm:
(WebCore::AVCaptureSessionInfo::AVCaptureSessionInfo):
(WebCore::AVCaptureSessionInfo::supportsVideoSize):
(WebCore::AVCaptureSessionInfo::bestSessionPresetForVideoDimensions):
(WebCore::AVCaptureDeviceManager::captureDeviceList):
(WebCore::shouldConsiderDeviceInDeviceList):
(WebCore::AVCaptureDeviceManager::refreshCaptureDeviceList):
(WebCore::AVCaptureDeviceManager::AVCaptureDeviceManager):
(WebCore::AVCaptureDeviceManager::bestSourcesForTypeAndConstraints):
(WebCore::AVCaptureDeviceManager::sourceWithUID):
(WebCore::AVCaptureDeviceManager::getSourcesInfo):
(WebCore::AVCaptureDeviceManager::verifyConstraintsForMediaType):
(WebCore::AVCaptureDeviceManager::defaultCaptureSession):
(WebCore::AVCaptureDeviceManager::sessionSupportsConstraint):
(WebCore::AVCaptureDeviceManager::createMediaSourceForCaptureDeviceWithConstraints):
(WebCore::AVCaptureDeviceManager::deviceDisconnected):
(WebCore::AVCaptureDeviceManager::isSupportedFrameRate):
(WebCore::CaptureDevice:::m_enabled): Deleted.
(WebCore::captureDeviceList): Deleted.
(WebCore::captureDeviceFromDeviceID): Deleted.
(WebCore::refreshCaptureDeviceList): Deleted.
(WebCore::AVCaptureDeviceManager::bestSessionPresetForVideoSize): Deleted.
(WebCore::AVCaptureDeviceManager::deviceSupportsFacingMode): Deleted.
(WebCore::AVCaptureDeviceManager::bestDeviceForFacingMode): Deleted.
(WebCore::AVCaptureDeviceManager::isValidConstraint): Deleted.
(WebCore::AVCaptureDeviceManager::validConstraintNames): Deleted.
(WebCore::AVCaptureDeviceManager::validFacingModes): Deleted.
* platform/mediastream/mac/AVVideoCaptureSource.mm:
(WebCore::AVVideoCaptureSource::applyConstraints):
* platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp:
(WebCore::RealtimeMediaSourceCenterMac::validateRequestConstraints):
(WebCore::RealtimeMediaSourceCenterMac::createMediaStream):</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceSupportedConstraintsh">trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVCaptureDeviceManagerh">trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVCaptureDeviceManagermm">trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVVideoCaptureSourcemm">trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacRealtimeMediaSourceCenterMaccpp">trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreModulesmediastreamCaptureDeviceInfoh">trunk/Source/WebCore/Modules/mediastream/CaptureDeviceInfo.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamCaptureDeviceManagercpp">trunk/Source/WebCore/Modules/mediastream/CaptureDeviceManager.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamCaptureDeviceManagerh">trunk/Source/WebCore/Modules/mediastream/CaptureDeviceManager.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceSupportedConstraintscpp">trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (192837 => 192838)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-11-30 23:27:23 UTC (rev 192837)
+++ trunk/Source/WebCore/ChangeLog        2015-11-30 23:48:42 UTC (rev 192838)
</span><span class="lines">@@ -1,3 +1,90 @@
</span><ins>+2015-11-30 Wenson Hsieh <wenson_hsieh@apple.com>
+
+ Split platform-independent logic in AVCaptureDeviceManager out into a new class
+ https://bugs.webkit.org/show_bug.cgi?id=151388
+ <rdar://problem/23593980>
+
+ Reviewed by Eric Carlson.
+
+ To prepare for creating a MockCaptureDeviceManager to be able to test
+ MediaDevices.getUserMedia, we create a platform-independent capture device manager
+ which all platforms should extend and add platform-specific logic to.
+
+ The methods CaptureDeviceManager::createMediaSourceForCaptureDeviceWithConstraints and
+ CaptureDeviceManager::captureDeviceList should be overridden by each platform
+ CaptureDeviceManager to respectively create a RealtimeMediaSource and return a list of
+ capture devices. createMediaSourceForCaptureDeviceWithConstraints attempts to create
+ a media source for a given device with some constraints; if the contraints cannot be
+ satisfied, this returns null.
+
+ The refactored capture device manager also introduces the notion of a platform-
+ independent capture session which may be extended by platform device managers for
+ determining whether a given constraint name, value and media type is valid.
+
+ A platform-independent CaptureDeviceInfo now represents either the video or audio
+ component of a capture device, but not both at once. This means a capture device that
+ supports both video and audio will emit two separate capture devices.
+
+ No new tests, since there should be no behavior change.
+
+ * Modules/mediastream/CaptureDeviceInfo.h: Added.
+ (WebCore::CaptureSessionInfo::~CaptureSessionInfo):
+ (WebCore::CaptureSessionInfo::supportsVideoSize):
+ (WebCore::CaptureSessionInfo::bestSessionPresetForVideoDimensions):
+ * Modules/mediastream/CaptureDeviceManager.cpp: Added.
+ (CaptureDeviceManager::~CaptureDeviceManager):
+ (CaptureDeviceManager::getSourcesInfo):
+ (CaptureDeviceManager::captureDeviceFromDeviceID):
+ (CaptureDeviceManager::verifyConstraintsForMediaType):
+ (CaptureDeviceManager::bestSourcesForTypeAndConstraints):
+ (CaptureDeviceManager::sourceWithUID):
+ (CaptureDeviceManager::bestDeviceForFacingMode):
+ (facingModeFromString):
+ (CaptureDeviceManager::sessionSupportsConstraint):
+ (CaptureDeviceManager::isSupportedFrameRate):
+ * Modules/mediastream/CaptureDeviceManager.h: Added.
+ (WebCore::CaptureDeviceManager::refreshCaptureDeviceList):
+ (WebCore::CaptureDeviceManager::defaultCaptureSession):
+ * WebCore.xcodeproj/project.pbxproj:
+ * platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp: Added.
+ (WebCore::RealtimeMediaSourceSupportedConstraints::nameForConstraint):
+ (WebCore::RealtimeMediaSourceSupportedConstraints::constraintFromName):
+ (WebCore::RealtimeMediaSourceSupportedConstraints::supportsConstraint):
+ * platform/mediastream/RealtimeMediaSourceSupportedConstraints.h:
+ * platform/mediastream/mac/AVCaptureDeviceManager.h:
+ * platform/mediastream/mac/AVCaptureDeviceManager.mm:
+ (WebCore::AVCaptureSessionInfo::AVCaptureSessionInfo):
+ (WebCore::AVCaptureSessionInfo::supportsVideoSize):
+ (WebCore::AVCaptureSessionInfo::bestSessionPresetForVideoDimensions):
+ (WebCore::AVCaptureDeviceManager::captureDeviceList):
+ (WebCore::shouldConsiderDeviceInDeviceList):
+ (WebCore::AVCaptureDeviceManager::refreshCaptureDeviceList):
+ (WebCore::AVCaptureDeviceManager::AVCaptureDeviceManager):
+ (WebCore::AVCaptureDeviceManager::bestSourcesForTypeAndConstraints):
+ (WebCore::AVCaptureDeviceManager::sourceWithUID):
+ (WebCore::AVCaptureDeviceManager::getSourcesInfo):
+ (WebCore::AVCaptureDeviceManager::verifyConstraintsForMediaType):
+ (WebCore::AVCaptureDeviceManager::defaultCaptureSession):
+ (WebCore::AVCaptureDeviceManager::sessionSupportsConstraint):
+ (WebCore::AVCaptureDeviceManager::createMediaSourceForCaptureDeviceWithConstraints):
+ (WebCore::AVCaptureDeviceManager::deviceDisconnected):
+ (WebCore::AVCaptureDeviceManager::isSupportedFrameRate):
+ (WebCore::CaptureDevice:::m_enabled): Deleted.
+ (WebCore::captureDeviceList): Deleted.
+ (WebCore::captureDeviceFromDeviceID): Deleted.
+ (WebCore::refreshCaptureDeviceList): Deleted.
+ (WebCore::AVCaptureDeviceManager::bestSessionPresetForVideoSize): Deleted.
+ (WebCore::AVCaptureDeviceManager::deviceSupportsFacingMode): Deleted.
+ (WebCore::AVCaptureDeviceManager::bestDeviceForFacingMode): Deleted.
+ (WebCore::AVCaptureDeviceManager::isValidConstraint): Deleted.
+ (WebCore::AVCaptureDeviceManager::validConstraintNames): Deleted.
+ (WebCore::AVCaptureDeviceManager::validFacingModes): Deleted.
+ * platform/mediastream/mac/AVVideoCaptureSource.mm:
+ (WebCore::AVVideoCaptureSource::applyConstraints):
+ * platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp:
+ (WebCore::RealtimeMediaSourceCenterMac::validateRequestConstraints):
+ (WebCore::RealtimeMediaSourceCenterMac::createMediaStream):
+
</ins><span class="cx"> 2015-11-30 Brady Eidson <beidson@apple.com>
</span><span class="cx">
</span><span class="cx"> Modern IDB: Set the correct source on the IDBRequest for cursor updates
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamCaptureDeviceInfoh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/mediastream/CaptureDeviceInfo.h (0 => 192838)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/CaptureDeviceInfo.h         (rev 0)
+++ trunk/Source/WebCore/Modules/mediastream/CaptureDeviceInfo.h        2015-11-30 23:48:42 UTC (rev 192838)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CaptureDeviceInfo_h
+#define CaptureDeviceInfo_h
+
+#if ENABLE(MEDIA_STREAM)
+
+#include <RealtimeMediaSource.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+struct CaptureDeviceInfo {
+ String m_persistentDeviceID;
+ String m_localizedName;
+ String m_groupID;
+
+ String m_sourceId;
+
+ bool m_enabled { false };
+ RealtimeMediaSource::Type m_sourceType { RealtimeMediaSource::None };
+ RealtimeMediaSourceStates::VideoFacingMode m_position { RealtimeMediaSourceStates::Unknown };
+};
+
+class CaptureSessionInfo {
+public:
+ virtual ~CaptureSessionInfo() { }
+ virtual bool supportsVideoSize(const String& /* videoSize */) const { return false; }
+ virtual String bestSessionPresetForVideoDimensions(int /* width */, int /* height */) const { return emptyString(); }
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
+
+#endif /* CaptureDeviceInfo_h */
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamCaptureDeviceManagercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/mediastream/CaptureDeviceManager.cpp (0 => 192838)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/CaptureDeviceManager.cpp         (rev 0)
+++ trunk/Source/WebCore/Modules/mediastream/CaptureDeviceManager.cpp        2015-11-30 23:48:42 UTC (rev 192838)
</span><span class="lines">@@ -0,0 +1,193 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "CaptureDeviceManager.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#import "Logging.h"
+#import "MediaConstraints.h"
+#import "RealtimeMediaSource.h"
+#import "RealtimeMediaSourceCenter.h"
+#import "RealtimeMediaSourceStates.h"
+#import "UUID.h"
+#import <wtf/MainThread.h>
+#import <wtf/NeverDestroyed.h>
+
+using namespace WebCore;
+
+CaptureDeviceManager::~CaptureDeviceManager()
+{
+}
+
+Vector<RefPtr<TrackSourceInfo>> CaptureDeviceManager::getSourcesInfo(const String& requestOrigin)
+{
+ UNUSED_PARAM(requestOrigin);
+ Vector<RefPtr<TrackSourceInfo>> sourcesInfo;
+ for (auto captureDevice : captureDeviceList()) {
+ if (!captureDevice.m_enabled || captureDevice.m_sourceType == RealtimeMediaSource::None)
+ continue;
+
+ TrackSourceInfo::SourceKind trackSourceType = captureDevice.m_sourceType == RealtimeMediaSource::Video ? TrackSourceInfo::Video : TrackSourceInfo::Audio;
+ sourcesInfo.append(TrackSourceInfo::create(captureDevice.m_sourceId, trackSourceType, captureDevice.m_localizedName, captureDevice.m_groupID));
+ }
+ LOG(Media, "CaptureDeviceManager::getSourcesInfo(%p), found %zu active devices", this, sourcesInfo.size());
+ return sourcesInfo;
+}
+
+bool CaptureDeviceManager::captureDeviceFromDeviceID(const String& captureDeviceID, CaptureDeviceInfo& foundDevice)
+{
+ for (auto& device : captureDeviceList()) {
+ if (device.m_persistentDeviceID == captureDeviceID) {
+ foundDevice = device;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool CaptureDeviceManager::verifyConstraintsForMediaType(RealtimeMediaSource::Type type, MediaConstraints* constraints, const CaptureSessionInfo* session, String& invalidConstraint)
+{
+ if (!constraints)
+ return true;
+
+ Vector<MediaConstraint> mandatoryConstraints;
+ constraints->getMandatoryConstraints(mandatoryConstraints);
+ for (auto& constraint : mandatoryConstraints) {
+ if (sessionSupportsConstraint(session, type, constraint.m_name, constraint.m_value))
+ continue;
+
+ invalidConstraint = constraint.m_name;
+ return false;
+ }
+
+ return true;
+}
+
+Vector<RefPtr<RealtimeMediaSource>> CaptureDeviceManager::bestSourcesForTypeAndConstraints(RealtimeMediaSource::Type type, PassRefPtr<MediaConstraints> constraints)
+{
+ Vector<RefPtr<RealtimeMediaSource>> bestSourcesList;
+
+ struct {
+ bool operator()(RefPtr<RealtimeMediaSource> a, RefPtr<RealtimeMediaSource> b)
+ {
+ return a->fitnessScore() < b->fitnessScore();
+ }
+ } sortBasedOnFitnessScore;
+
+ for (auto& captureDevice : captureDeviceList()) {
+ if (!captureDevice.m_enabled || captureDevice.m_sourceId.isEmpty() || captureDevice.m_sourceType == RealtimeMediaSource::None)
+ continue;
+
+ if (RefPtr<RealtimeMediaSource> captureSource = sourceWithUID(captureDevice.m_persistentDeviceID, type, constraints.get()))
+ bestSourcesList.append(captureSource.leakRef());
+ }
+ std::sort(bestSourcesList.begin(), bestSourcesList.end(), sortBasedOnFitnessScore);
+ return bestSourcesList;
+}
+
+RefPtr<RealtimeMediaSource> CaptureDeviceManager::sourceWithUID(const String& deviceUID, RealtimeMediaSource::Type type, MediaConstraints* constraints)
+{
+ for (auto& captureDevice : captureDeviceList()) {
+ if (captureDevice.m_persistentDeviceID != deviceUID || captureDevice.m_sourceType != type)
+ continue;
+
+ if (!captureDevice.m_enabled || type == RealtimeMediaSource::None || captureDevice.m_sourceId.isEmpty())
+ continue;
+
+ if (RealtimeMediaSource* mediaSource = createMediaSourceForCaptureDeviceWithConstraints(captureDevice, constraints))
+ return mediaSource;
+ }
+ return nullptr;
+}
+
+CaptureDeviceInfo* CaptureDeviceManager::bestDeviceForFacingMode(RealtimeMediaSourceStates::VideoFacingMode facingMode)
+{
+ if (facingMode == RealtimeMediaSourceStates::Unknown)
+ return nullptr;
+
+ for (auto& device : captureDeviceList()) {
+ if (device.m_sourceType == RealtimeMediaSource::Video && device.m_position == facingMode)
+ return &device;
+ }
+ return nullptr;
+}
+
+static inline RealtimeMediaSourceStates::VideoFacingMode facingModeFromString(const String& facingModeString)
+{
+ static NeverDestroyed<AtomicString> userFacingModeString("user", AtomicString::ConstructFromLiteral);
+ static NeverDestroyed<AtomicString> environmentFacingModeString("environment", AtomicString::ConstructFromLiteral);
+ static NeverDestroyed<AtomicString> leftFacingModeString("left", AtomicString::ConstructFromLiteral);
+ static NeverDestroyed<AtomicString> rightFacingModeString("right", AtomicString::ConstructFromLiteral);
+ if (facingModeString == userFacingModeString)
+ return RealtimeMediaSourceStates::User;
+ if (facingModeString == environmentFacingModeString)
+ return RealtimeMediaSourceStates::Environment;
+ if (facingModeString == leftFacingModeString)
+ return RealtimeMediaSourceStates::Left;
+ if (facingModeString == rightFacingModeString)
+ return RealtimeMediaSourceStates::Right;
+ return RealtimeMediaSourceStates::Unknown;
+}
+
+bool CaptureDeviceManager::sessionSupportsConstraint(const CaptureSessionInfo*, RealtimeMediaSource::Type type, const String& name, const String& value)
+{
+ const RealtimeMediaSourceSupportedConstraints& supportedConstraints = RealtimeMediaSourceCenter::singleton().supportedConstraints();
+ MediaConstraintType constraint = supportedConstraints.constraintFromName(name);
+ if (!supportedConstraints.supportsConstraint(constraint))
+ return false;
+
+ switch (constraint) {
+ case MediaConstraintType::Width:
+ return type == RealtimeMediaSource::Video;
+
+ case MediaConstraintType::Height:
+ return type == RealtimeMediaSource::Video;
+
+ case MediaConstraintType::FrameRate: {
+ if (type == RealtimeMediaSource::Audio)
+ return false;
+
+ return isSupportedFrameRate(value.toFloat());
+ }
+ case MediaConstraintType::FacingMode: {
+ if (type == RealtimeMediaSource::Audio)
+ return false;
+
+ return bestDeviceForFacingMode(facingModeFromString(value));
+ }
+ default:
+ return false;
+ }
+}
+
+bool CaptureDeviceManager::isSupportedFrameRate(float frameRate) const
+{
+ return 0 < frameRate && frameRate <= 60;
+}
+
+#endif // ENABLE(MEDIA_STREAM)
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamCaptureDeviceManagerh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/mediastream/CaptureDeviceManager.h (0 => 192838)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/CaptureDeviceManager.h         (rev 0)
+++ trunk/Source/WebCore/Modules/mediastream/CaptureDeviceManager.h        2015-11-30 23:48:42 UTC (rev 192838)
</span><span class="lines">@@ -0,0 +1,64 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CaptureDeviceManager_h
+#define CaptureDeviceManager_h
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "CaptureDeviceInfo.h"
+#include "MediaStreamTrackSourcesRequestClient.h"
+#include "RealtimeMediaSource.h"
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class CaptureDeviceManager {
+public:
+ virtual Vector<CaptureDeviceInfo>& captureDeviceList() = 0;
+ virtual void refreshCaptureDeviceList() { }
+ virtual TrackSourceInfoVector getSourcesInfo(const String&);
+ virtual Vector<RefPtr<RealtimeMediaSource>> bestSourcesForTypeAndConstraints(RealtimeMediaSource::Type, PassRefPtr<MediaConstraints>);
+ virtual RefPtr<RealtimeMediaSource> sourceWithUID(const String&, RealtimeMediaSource::Type, MediaConstraints*);
+
+ virtual bool verifyConstraintsForMediaType(RealtimeMediaSource::Type, MediaConstraints*, const CaptureSessionInfo*, String&);
+
+protected:
+ virtual ~CaptureDeviceManager();
+ virtual RealtimeMediaSource* createMediaSourceForCaptureDeviceWithConstraints(const CaptureDeviceInfo&, MediaConstraints*) = 0;
+
+ virtual CaptureSessionInfo defaultCaptureSession() const { return CaptureSessionInfo(); }
+ virtual bool sessionSupportsConstraint(const CaptureSessionInfo*, RealtimeMediaSource::Type, const String& name, const String& value);
+ virtual bool isSupportedFrameRate(float frameRate) const;
+
+ bool captureDeviceFromDeviceID(const String& captureDeviceID, CaptureDeviceInfo& source);
+ CaptureDeviceInfo* bestDeviceForFacingMode(RealtimeMediaSourceStates::VideoFacingMode);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
+
+#endif /* CaptureDeviceManager_h */
</ins></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (192837 => 192838)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-11-30 23:27:23 UTC (rev 192837)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-11-30 23:48:42 UTC (rev 192838)
</span><span class="lines">@@ -1210,6 +1210,9 @@
</span><span class="cx">                 2E3BC108117D479800B9409A /* DOMFileError.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E3BC106117D479800B9409A /* DOMFileError.h */; };
</span><span class="cx">                 2E3BC109117D479800B9409A /* DOMFileError.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E3BC107117D479800B9409A /* DOMFileError.mm */; };
</span><span class="cx">                 2E3BC10B117D47C800B9409A /* DOMFileErrorInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E3BC10A117D47C800B9409A /* DOMFileErrorInternal.h */; };
</span><ins>+                2E3C8C621BFBA97500309566 /* CaptureDeviceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E3C8C611BFBA8DC00309566 /* CaptureDeviceManager.h */; };
+                2E3C8C641BFBB75D00309566 /* CaptureDeviceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E3C8C631BFBB75D00309566 /* CaptureDeviceManager.cpp */; };
+                2E3C8C681BFBF8E100309566 /* CaptureDeviceInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E3C8C661BFBF8E100309566 /* CaptureDeviceInfo.h */; };
</ins><span class="cx">                 2E4346450F546A8200B0F1BA /* Worker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E4346330F546A8200B0F1BA /* Worker.cpp */; };
</span><span class="cx">                 2E4346460F546A8200B0F1BA /* Worker.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E4346340F546A8200B0F1BA /* Worker.h */; };
</span><span class="cx">                 2E4346480F546A8200B0F1BA /* WorkerGlobalScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E4346360F546A8200B0F1BA /* WorkerGlobalScope.cpp */; };
</span><span class="lines">@@ -1237,6 +1240,7 @@
</span><span class="cx">                 2EB4BCD2121F03E300EC4885 /* BlobResourceHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2EB4BCD0121F03E300EC4885 /* BlobResourceHandle.cpp */; };
</span><span class="cx">                 2EB4BCD3121F03E300EC4885 /* BlobResourceHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EB4BCD1121F03E300EC4885 /* BlobResourceHandle.h */; };
</span><span class="cx">                 2EBBC3D81B65988300F5253D /* WheelEventDeltaFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EBBC3D71B65988300F5253D /* WheelEventDeltaFilter.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                2EC41DE41C0410A300D294FE /* RealtimeMediaSourceSupportedConstraints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2EC41DE21C0410A300D294FE /* RealtimeMediaSourceSupportedConstraints.cpp */; };
</ins><span class="cx">                 2ECF7ADC10162B3800427DE7 /* JSErrorEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ECF7ADA10162B3800427DE7 /* JSErrorEvent.cpp */; };
</span><span class="cx">                 2ECF7ADD10162B3800427DE7 /* JSErrorEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ECF7ADB10162B3800427DE7 /* JSErrorEvent.h */; };
</span><span class="cx">                 2ECF7AE110162B5800427DE7 /* ErrorEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ECF7ADE10162B5800427DE7 /* ErrorEvent.cpp */; };
</span><span class="lines">@@ -8587,6 +8591,9 @@
</span><span class="cx">                 2E3BC106117D479800B9409A /* DOMFileError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMFileError.h; sourceTree = "<group>"; };
</span><span class="cx">                 2E3BC107117D479800B9409A /* DOMFileError.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMFileError.mm; sourceTree = "<group>"; };
</span><span class="cx">                 2E3BC10A117D47C800B9409A /* DOMFileErrorInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMFileErrorInternal.h; sourceTree = "<group>"; };
</span><ins>+                2E3C8C611BFBA8DC00309566 /* CaptureDeviceManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CaptureDeviceManager.h; sourceTree = "<group>"; };
+                2E3C8C631BFBB75D00309566 /* CaptureDeviceManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CaptureDeviceManager.cpp; sourceTree = "<group>"; };
+                2E3C8C661BFBF8E100309566 /* CaptureDeviceInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CaptureDeviceInfo.h; sourceTree = "<group>"; };
</ins><span class="cx">                 2E4346330F546A8200B0F1BA /* Worker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Worker.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 2E4346340F546A8200B0F1BA /* Worker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Worker.h; sourceTree = "<group>"; };
</span><span class="cx">                 2E4346350F546A8200B0F1BA /* Worker.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Worker.idl; sourceTree = "<group>"; };
</span><span class="lines">@@ -8617,6 +8624,7 @@
</span><span class="cx">                 2EB4BCD0121F03E300EC4885 /* BlobResourceHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BlobResourceHandle.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 2EB4BCD1121F03E300EC4885 /* BlobResourceHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlobResourceHandle.h; sourceTree = "<group>"; };
</span><span class="cx">                 2EBBC3D71B65988300F5253D /* WheelEventDeltaFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WheelEventDeltaFilter.h; sourceTree = "<group>"; };
</span><ins>+                2EC41DE21C0410A300D294FE /* RealtimeMediaSourceSupportedConstraints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RealtimeMediaSourceSupportedConstraints.cpp; sourceTree = "<group>"; };
</ins><span class="cx">                 2ECF7ADA10162B3800427DE7 /* JSErrorEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSErrorEvent.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 2ECF7ADB10162B3800427DE7 /* JSErrorEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSErrorEvent.h; sourceTree = "<group>"; };
</span><span class="cx">                 2ECF7ADE10162B5800427DE7 /* ErrorEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ErrorEvent.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -15138,6 +15146,9 @@
</span><span class="cx">                                 070584FE17F9F05E005F2BCB /* CapabilityRange.cpp */,
</span><span class="cx">                                 07C59B7417F7D09D000FBCBB /* CapabilityRange.h */,
</span><span class="cx">                                 07C59B7517F7D09D000FBCBB /* CapabilityRange.idl */,
</span><ins>+                                2E3C8C611BFBA8DC00309566 /* CaptureDeviceManager.h */,
+                                2E3C8C631BFBB75D00309566 /* CaptureDeviceManager.cpp */,
+                                2E3C8C661BFBF8E100309566 /* CaptureDeviceInfo.h */,
</ins><span class="cx">                                 073794ED19EE364200E5A045 /* DOMURLMediaStream.cpp */,
</span><span class="cx">                                 15FCC9FD1B4DF85600E72326 /* DOMURLMediaStream.h */,
</span><span class="cx">                                 073794EE19EE364200E5A045 /* DOMURLMediaStream.idl */,
</span><span class="lines">@@ -15276,6 +15287,7 @@
</span><span class="cx">                                 07FFDE66181AED420072D409 /* MediaStreamTrackPrivate.cpp */,
</span><span class="cx">                                 07FFDE67181AED420072D409 /* MediaStreamTrackPrivate.h */,
</span><span class="cx">                                 07C1C0E41BFB60ED00BD2256 /* RealtimeMediaSourceSupportedConstraints.h */,
</span><ins>+                                2EC41DE21C0410A300D294FE /* RealtimeMediaSourceSupportedConstraints.cpp */,
</ins><span class="cx">                                 076306E217E22A43005A7C4E /* MediaStreamTrackSourcesRequestClient.h */,
</span><span class="cx">                                 4A4F656B1AA997F100E38CDD /* RealtimeMediaSource.cpp */,
</span><span class="cx">                                 4A4F656C1AA997F100E38CDD /* RealtimeMediaSource.h */,
</span><span class="lines">@@ -26619,6 +26631,7 @@
</span><span class="cx">                                 BCEFE1EB0DCA5F6400739219 /* JSXSLTProcessor.h in Headers */,
</span><span class="cx">                                 85031B440A44EFC700F992E0 /* KeyboardEvent.h in Headers */,
</span><span class="cx">                                 1AE00D59182DAC8D00087DD7 /* KeyedCoding.h in Headers */,
</span><ins>+                                2E3C8C621BFBA97500309566 /* CaptureDeviceManager.h in Headers */,
</ins><span class="cx">                                 517A63C51B74318F00E7DCDC /* KeyedDecoderCF.h in Headers */,
</span><span class="cx">                                 517A63C61B74319200E7DCDC /* KeyedEncoderCF.h in Headers */,
</span><span class="cx">                                 A513B3D7114B1666001C429B /* KeyEventCocoa.h in Headers */,
</span><span class="lines">@@ -26704,6 +26717,7 @@
</span><span class="cx">                                 FABE72F91059C1EB00D999DD /* MathMLMathElement.h in Headers */,
</span><span class="cx">                                 44A28AAF12DFB8BF00AE923B /* MathMLNames.h in Headers */,
</span><span class="cx">                                 FA654A6C1108ABED002615E0 /* MathMLTextElement.h in Headers */,
</span><ins>+                                2E3C8C681BFBF8E100309566 /* CaptureDeviceInfo.h in Headers */,
</ins><span class="cx">                                 49D5DC2C0F423A73008F20FD /* Matrix3DTransformOperation.h in Headers */,
</span><span class="cx">                                 49E911C70EF86D47009D0CAF /* MatrixTransformOperation.h in Headers */,
</span><span class="cx">                                 5CBC8DAD1AAA302200E1C803 /* MediaAccessibilitySoftLink.h in Headers */,
</span><span class="lines">@@ -28652,6 +28666,7 @@
</span><span class="cx">                                 E164A2ED191AE6350010737D /* BlobDataFileReferenceMac.mm in Sources */,
</span><span class="cx">                                 E14A94D716DFDF950068DE82 /* BlobRegistry.cpp in Sources */,
</span><span class="cx">                                 2EDEF1F6121B0EFC00726DB2 /* BlobRegistryImpl.cpp in Sources */,
</span><ins>+                                2EC41DE41C0410A300D294FE /* RealtimeMediaSourceSupportedConstraints.cpp in Sources */,
</ins><span class="cx">                                 2EB4BCD2121F03E300EC4885 /* BlobResourceHandle.cpp in Sources */,
</span><span class="cx">                                 976D6C7E122B8A3D001FD1F7 /* BlobURL.cpp in Sources */,
</span><span class="cx">                                 93F19AE108245E59001E9ABC /* BlockExceptions.mm in Sources */,
</span><span class="lines">@@ -30373,6 +30388,7 @@
</span><span class="cx">                                 E4B65A5A132FAAF90070E7BE /* LegacyTileGrid.mm in Sources */,
</span><span class="cx">                                 E424A3A01330DF1E00CF6DC9 /* LegacyTileGridTile.mm in Sources */,
</span><span class="cx">                                 E4B65A5E132FADB60070E7BE /* LegacyTileLayer.mm in Sources */,
</span><ins>+                                2E3C8C641BFBB75D00309566 /* CaptureDeviceManager.cpp in Sources */,
</ins><span class="cx">                                 E4E39AFD1330EFC6003AB274 /* LegacyTileLayerPool.mm in Sources */,
</span><span class="cx">                                 51645B6A1B9FA6C800F789CE /* LegacyTransaction.cpp in Sources */,
</span><span class="cx">                                 51645B6C1B9FA6C800F789CE /* LegacyVersionChangeEvent.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceSupportedConstraintscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp (0 => 192838)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp         (rev 0)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp        2015-11-30 23:48:42 UTC (rev 192838)
</span><span class="lines">@@ -0,0 +1,133 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RealtimeMediaSourceSupportedConstraints.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include <wtf/HashMap.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/text/AtomicString.h>
+#include <wtf/text/AtomicStringHash.h>
+
+namespace WebCore {
+
+const AtomicString& RealtimeMediaSourceSupportedConstraints::nameForConstraint(MediaConstraintType constraint) const
+{
+ static NeverDestroyed<AtomicString> unknownConstraintName(emptyString());
+ static NeverDestroyed<AtomicString> widthConstraintName("width");
+ static NeverDestroyed<AtomicString> heightConstraintName("height");
+ static NeverDestroyed<AtomicString> aspectRatioConstraintName("aspectRatio");
+ static NeverDestroyed<AtomicString> frameRateConstraintName("frameRate");
+ static NeverDestroyed<AtomicString> facingModeConstraintName("facingMode");
+ static NeverDestroyed<AtomicString> volumeConstraintName("volume");
+ static NeverDestroyed<AtomicString> sampleRateConstraintName("sampleRate");
+ static NeverDestroyed<AtomicString> sampleSizeConstraintName("sampleSize");
+ static NeverDestroyed<AtomicString> echoCancellationConstraintName("echoCancellation");
+ static NeverDestroyed<AtomicString> deviceIdConstraintName("deviceId");
+ static NeverDestroyed<AtomicString> groupIdConstraintName("groupId");
+ switch (constraint) {
+ case MediaConstraintType::Unknown:
+ return unknownConstraintName;
+ case MediaConstraintType::Width:
+ return widthConstraintName;
+ case MediaConstraintType::Height:
+ return heightConstraintName;
+ case MediaConstraintType::AspectRatio:
+ return aspectRatioConstraintName;
+ case MediaConstraintType::FrameRate:
+ return frameRateConstraintName;
+ case MediaConstraintType::FacingMode:
+ return facingModeConstraintName;
+ case MediaConstraintType::Volume:
+ return volumeConstraintName;
+ case MediaConstraintType::SampleRate:
+ return sampleRateConstraintName;
+ case MediaConstraintType::SampleSize:
+ return sampleSizeConstraintName;
+ case MediaConstraintType::EchoCancellation:
+ return echoCancellationConstraintName;
+ case MediaConstraintType::DeviceId:
+ return deviceIdConstraintName;
+ case MediaConstraintType::GroupId:
+ return groupIdConstraintName;
+ }
+}
+
+MediaConstraintType RealtimeMediaSourceSupportedConstraints::constraintFromName(const String& constraintName) const
+{
+ static NeverDestroyed<HashMap<AtomicString, MediaConstraintType>> nameToConstraintMap;
+ HashMap<AtomicString, MediaConstraintType>& nameToConstraintMapValue = nameToConstraintMap.get();
+ if (!nameToConstraintMapValue.size()) {
+ nameToConstraintMapValue.add("width", MediaConstraintType::Width);
+ nameToConstraintMapValue.add("height", MediaConstraintType::Height);
+ nameToConstraintMapValue.add("aspectRatio", MediaConstraintType::AspectRatio);
+ nameToConstraintMapValue.add("frameRate", MediaConstraintType::FrameRate);
+ nameToConstraintMapValue.add("facingMode", MediaConstraintType::FacingMode);
+ nameToConstraintMapValue.add("volume", MediaConstraintType::Volume);
+ nameToConstraintMapValue.add("sampleRate", MediaConstraintType::SampleRate);
+ nameToConstraintMapValue.add("sampleSize", MediaConstraintType::SampleSize);
+ nameToConstraintMapValue.add("echoCancellation", MediaConstraintType::EchoCancellation);
+ nameToConstraintMapValue.add("deviceId", MediaConstraintType::DeviceId);
+ nameToConstraintMapValue.add("groupId", MediaConstraintType::GroupId);
+ }
+ auto iter = nameToConstraintMapValue.find(constraintName);
+ return iter == nameToConstraintMapValue.end() ? MediaConstraintType::Unknown : iter->value;
+}
+
+bool RealtimeMediaSourceSupportedConstraints::supportsConstraint(MediaConstraintType constraint) const
+{
+ switch (constraint) {
+ case MediaConstraintType::Unknown:
+ return false;
+ case MediaConstraintType::Width:
+ return supportsWidth();
+ case MediaConstraintType::Height:
+ return supportsHeight();
+ case MediaConstraintType::AspectRatio:
+ return supportsAspectRatio();
+ case MediaConstraintType::FrameRate:
+ return supportsFrameRate();
+ case MediaConstraintType::FacingMode:
+ return supportsFacingMode();
+ case MediaConstraintType::Volume:
+ return supportsVolume();
+ case MediaConstraintType::SampleRate:
+ return supportsSampleRate();
+ case MediaConstraintType::SampleSize:
+ return supportsSampleSize();
+ case MediaConstraintType::EchoCancellation:
+ return supportsEchoCancellation();
+ case MediaConstraintType::DeviceId:
+ return supportsDeviceId();
+ case MediaConstraintType::GroupId:
+ return supportsGroupId();
+ }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceSupportedConstraintsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.h (192837 => 192838)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.h        2015-11-30 23:27:23 UTC (rev 192837)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.h        2015-11-30 23:48:42 UTC (rev 192838)
</span><span class="lines">@@ -33,8 +33,25 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx">
</span><ins>+#include <wtf/text/WTFString.h>
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><ins>+enum class MediaConstraintType {
+ Unknown,
+ Width,
+ Height,
+ AspectRatio,
+ FrameRate,
+ FacingMode,
+ Volume,
+ SampleRate,
+ SampleSize,
+ EchoCancellation,
+ DeviceId,
+ GroupId
+};
+
</ins><span class="cx"> class RealtimeMediaSourceSupportedConstraints {
</span><span class="cx"> public:
</span><span class="cx"> RealtimeMediaSourceSupportedConstraints()
</span><span class="lines">@@ -74,6 +91,10 @@
</span><span class="cx"> bool supportsGroupId() const { return m_supportsGroupId; }
</span><span class="cx"> void setSupportsGroupId(bool value) { m_supportsGroupId = value; }
</span><span class="cx">
</span><ins>+ const AtomicString& nameForConstraint(MediaConstraintType) const;
+ MediaConstraintType constraintFromName(const String& constraintName) const;
+ bool supportsConstraint(MediaConstraintType) const;
+
</ins><span class="cx"> private:
</span><span class="cx"> bool m_supportsWidth { false };
</span><span class="cx"> bool m_supportsHeight { false };
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVCaptureDeviceManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.h (192837 => 192838)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.h        2015-11-30 23:27:23 UTC (rev 192837)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.h        2015-11-30 23:48:42 UTC (rev 192838)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(MEDIA_STREAM) && USE(AVFOUNDATION)
</span><span class="cx">
</span><ins>+#include "CaptureDeviceManager.h"
</ins><span class="cx"> #include "MediaStreamTrackSourcesRequestClient.h"
</span><span class="cx"> #include "RealtimeMediaSource.h"
</span><span class="cx"> #include <wtf/RetainPtr.h>
</span><span class="lines">@@ -40,38 +41,46 @@
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><del>-class CaptureDevice;
</del><ins>+class AVCaptureSessionInfo : public CaptureSessionInfo {
+public:
+ AVCaptureSessionInfo(AVCaptureSession*);
+ virtual bool supportsVideoSize(const String&) const override;
+ virtual String bestSessionPresetForVideoDimensions(int width, int height) const override;
</ins><span class="cx">
</span><del>-class AVCaptureDeviceManager {
</del><ins>+private:
+ AVCaptureSession *m_platformSession;
+};
+
+class AVCaptureDeviceManager final : public CaptureDeviceManager {
</ins><span class="cx"> public:
</span><ins>+ virtual Vector<CaptureDeviceInfo>& captureDeviceList() override;
+
</ins><span class="cx"> static AVCaptureDeviceManager& singleton();
</span><del>- static bool isAvailable();
</del><span class="cx">
</span><del>- TrackSourceInfoVector getSourcesInfo(const String&);
- bool verifyConstraintsForMediaType(AVCaptureSession *, RealtimeMediaSource::Type, MediaConstraints*, String&);
- Vector<RefPtr<RealtimeMediaSource>> bestSourcesForTypeAndConstraints(RealtimeMediaSource::Type, PassRefPtr<MediaConstraints>);
- RefPtr<RealtimeMediaSource> sourceWithUID(const String&, RealtimeMediaSource::Type, MediaConstraints*);
</del><ins>+ virtual RefPtr<RealtimeMediaSource> sourceWithUID(const String&, RealtimeMediaSource::Type, MediaConstraints*) override;
+ virtual Vector<RefPtr<RealtimeMediaSource>> bestSourcesForTypeAndConstraints(RealtimeMediaSource::Type, PassRefPtr<MediaConstraints>) override;
</ins><span class="cx">
</span><del>- enum ValidConstraints { Width = 0, Height, FrameRate, FacingMode, Gain };
- static const Vector<AtomicString>& validConstraintNames();
- static const Vector<AtomicString>& validFacingModes();
</del><ins>+ virtual TrackSourceInfoVector getSourcesInfo(const String&) override;
+ virtual bool verifyConstraintsForMediaType(RealtimeMediaSource::Type, MediaConstraints*, const CaptureSessionInfo*, String&) override;
</ins><span class="cx">
</span><del>- static bool deviceSupportsFacingMode(AVCaptureDevice*, RealtimeMediaSourceStates::VideoFacingMode);
- static bool isValidConstraint(RealtimeMediaSource::Type, const String&);
- static String bestSessionPresetForVideoSize(AVCaptureSession*, int width, int height);
-
- void registerForDeviceNotifications();
</del><span class="cx"> void deviceConnected();
</span><span class="cx"> void deviceDisconnected(AVCaptureDevice*);
</span><span class="cx">
</span><span class="cx"> protected:
</span><ins>+ static bool isAvailable();
+
</ins><span class="cx"> AVCaptureDeviceManager();
</span><del>- ~AVCaptureDeviceManager();
</del><ins>+ virtual ~AVCaptureDeviceManager() override;
+ virtual bool sessionSupportsConstraint(const CaptureSessionInfo*, RealtimeMediaSource::Type, const String& name, const String& value) override;
+ virtual RealtimeMediaSource* createMediaSourceForCaptureDeviceWithConstraints(const CaptureDeviceInfo&, MediaConstraints*) override;
+ virtual CaptureSessionInfo defaultCaptureSession() const override;
+ virtual void refreshCaptureDeviceList() override;
+ virtual bool isSupportedFrameRate(float frameRate) const override;
</ins><span class="cx">
</span><del>- CaptureDevice* bestDeviceForFacingMode(RealtimeMediaSourceStates::VideoFacingMode);
- bool sessionSupportsConstraint(AVCaptureSession*, RealtimeMediaSource::Type, const String& name, const String& value);
</del><ins>+ void registerForDeviceNotifications();
</ins><span class="cx">
</span><span class="cx"> RetainPtr<WebCoreAVCaptureDeviceManagerObserver> m_objcObserver;
</span><ins>+ Vector<CaptureDeviceInfo> m_devices;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVCaptureDeviceManagermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm (192837 => 192838)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm        2015-11-30 23:27:23 UTC (rev 192837)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm        2015-11-30 23:48:42 UTC (rev 192838)
</span><span class="lines">@@ -35,7 +35,9 @@
</span><span class="cx"> #import "Logging.h"
</span><span class="cx"> #import "MediaConstraints.h"
</span><span class="cx"> #import "RealtimeMediaSource.h"
</span><ins>+#import "RealtimeMediaSourceCenter.h"
</ins><span class="cx"> #import "RealtimeMediaSourceStates.h"
</span><ins>+#import "RealtimeMediaSourceSupportedConstraints.h"
</ins><span class="cx"> #import "SoftLinking.h"
</span><span class="cx"> #import "UUID.h"
</span><span class="cx"> #import <AVFoundation/AVFoundation.h>
</span><span class="lines">@@ -89,86 +91,113 @@
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><del>-static void refreshCaptureDeviceList();
</del><ins>+AVCaptureSessionInfo::AVCaptureSessionInfo(AVCaptureSessionType *platformSession)
+ : m_platformSession(platformSession)
+{
+}
</ins><span class="cx">
</span><del>-class CaptureDevice {
-public:
- CaptureDevice()
- :m_enabled(false)
- {
</del><ins>+bool AVCaptureSessionInfo::supportsVideoSize(const String& videoSize) const
+{
+ return [m_platformSession canSetSessionPreset:videoSize];
+}
+
+String AVCaptureSessionInfo::bestSessionPresetForVideoDimensions(int width, int height) const
+{
+ ASSERT(width >= 0);
+ ASSERT(height >= 0);
+
+ if (width > 1280 || height > 720) {
+ // FIXME: this restriction could be adjusted with the videoMaxScaleAndCropFactor property.
+ return emptyString();
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- String m_captureDeviceID;
- String m_localizedName;
- String m_groupID;
</del><ins>+ if (width > 640 || height > 480) {
+ if (supportsVideoSize(AVCaptureSessionPreset1280x720))
+ return AVCaptureSessionPreset1280x720;
</ins><span class="cx">
</span><del>- String m_audioSourceId;
- String m_videoSourceId;
</del><ins>+ return emptyString();
+ }
</ins><span class="cx">
</span><del>- bool m_enabled;
-};
</del><ins>+ if (width > 352 || height > 288) {
+ if (supportsVideoSize(AVCaptureSessionPreset640x480))
+ return AVCaptureSessionPreset640x480;
</ins><span class="cx">
</span><del>-static Vector<CaptureDevice>& captureDeviceList()
</del><ins>+ return emptyString();
+ }
+
+ if (supportsVideoSize(AVCaptureSessionPreset352x288))
+ return AVCaptureSessionPreset352x288;
+
+ if (supportsVideoSize(AVCaptureSessionPresetLow))
+ return AVCaptureSessionPresetLow;
+
+ return emptyString();
+}
+
+
+Vector<CaptureDeviceInfo>& AVCaptureDeviceManager::captureDeviceList()
</ins><span class="cx"> {
</span><del>- DEPRECATED_DEFINE_STATIC_LOCAL(Vector<CaptureDevice>, captureDeviceList, ());
</del><span class="cx"> static bool firstTime = true;
</span><del>-
- if (firstTime && !captureDeviceList.size()) {
</del><ins>+ if (firstTime && !m_devices.size()) {
</ins><span class="cx"> firstTime = false;
</span><span class="cx"> refreshCaptureDeviceList();
</span><del>- AVCaptureDeviceManager::singleton().registerForDeviceNotifications();
</del><ins>+ registerForDeviceNotifications();
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- return captureDeviceList;
</del><ins>+ return m_devices;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-static bool captureDeviceFromDeviceID(const String& captureDeviceID, CaptureDevice& source)
</del><ins>+inline static bool shouldConsiderDeviceInDeviceList(AVCaptureDeviceType *device)
</ins><span class="cx"> {
</span><del>- Vector<CaptureDevice>& devices = captureDeviceList();
-
- size_t count = devices.size();
- for (size_t i = 0; i < count; ++i) {
- if (devices[i].m_captureDeviceID == captureDeviceID) {
- source = devices[i];
- return true;
- }
- }
-
- return false;
</del><ins>+ if (![device isConnected])
+ return false;
+
+#if !PLATFORM(IOS)
+ if ([device isSuspended] || [device isInUseByAnotherApplication])
+ return false;
+#endif
+
+ return true;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-static void refreshCaptureDeviceList()
</del><ins>+void AVCaptureDeviceManager::refreshCaptureDeviceList()
</ins><span class="cx"> {
</span><del>- Vector<CaptureDevice>& devices = captureDeviceList();
-
- for (AVCaptureDeviceType *device in [getAVCaptureDeviceClass() devices]) {
- CaptureDevice source;
-
- if (![device isConnected])
</del><ins>+ for (AVCaptureDeviceType *platformDevice in [getAVCaptureDeviceClass() devices]) {
+ if (!shouldConsiderDeviceInDeviceList(platformDevice))
</ins><span class="cx"> continue;
</span><span class="cx">
</span><del>-#if !PLATFORM(IOS)
- if ([device isSuspended] || [device isInUseByAnotherApplication])
- continue;
-#endif
-
- if (!captureDeviceFromDeviceID(device.uniqueID, source)) {
</del><ins>+ CaptureDeviceInfo captureDevice;
+ if (!captureDeviceFromDeviceID(platformDevice.uniqueID, captureDevice)) {
</ins><span class="cx"> // An AVCaptureDevice has a unique ID, but we can't use it for the source ID because:
</span><span class="cx"> // 1. if it provides both audio and video we will need to create two sources for it
</span><span class="cx"> // 2. the unique ID persists on one system across device connections, disconnections,
</span><span class="cx"> // application restarts, and reboots, so it could be used to figerprint a user.
</span><del>- source.m_captureDeviceID = device.uniqueID;
- source.m_enabled = true;
- if ([device hasMediaType:AVMediaTypeAudio] || [device hasMediaType:AVMediaTypeMuxed])
- source.m_audioSourceId = createCanonicalUUIDString();
</del><ins>+ captureDevice.m_persistentDeviceID = platformDevice.uniqueID;
+ captureDevice.m_enabled = true;
+ captureDevice.m_groupID = createCanonicalUUIDString();
+ captureDevice.m_localizedName = platformDevice.localizedName;
+ if ([platformDevice position] == AVCaptureDevicePositionFront)
+ captureDevice.m_position = RealtimeMediaSourceStates::User;
+ if ([platformDevice position] == AVCaptureDevicePositionBack)
+ captureDevice.m_position = RealtimeMediaSourceStates::Environment;
</ins><span class="cx">
</span><del>- if ([device hasMediaType:AVMediaTypeVideo] || [device hasMediaType:AVMediaTypeMuxed])
- source.m_videoSourceId = createCanonicalUUIDString();
</del><ins>+ bool hasAudio = [platformDevice hasMediaType:AVMediaTypeAudio] || [platformDevice hasMediaType:AVMediaTypeMuxed];
+ bool hasVideo = [platformDevice hasMediaType:AVMediaTypeVideo] || [platformDevice hasMediaType:AVMediaTypeMuxed];
+ if (!hasAudio && !hasVideo)
+ continue;
</ins><span class="cx">
</span><del>- source.m_groupID = createCanonicalUUIDString();
- source.m_localizedName = device.localizedName;
-
- devices.append(source);
</del><ins>+ // FIXME: For a given device, the source ID should persist when visiting the same request origin,
+ // but differ across different request origins.
+ captureDevice.m_sourceId = createCanonicalUUIDString();
+ captureDevice.m_sourceType = hasVideo ? RealtimeMediaSource::Video : RealtimeMediaSource::Audio;
+ if (hasVideo && hasAudio) {
+ // Add the audio component as a separate device.
+ CaptureDeviceInfo audioCaptureDevice = captureDevice;
+ audioCaptureDevice.m_sourceId = createCanonicalUUIDString();
+ audioCaptureDevice.m_sourceType = RealtimeMediaSource::Audio;
+ m_devices.append(audioCaptureDevice);
+ }
+ m_devices.append(captureDevice);
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="lines">@@ -185,7 +214,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> AVCaptureDeviceManager::AVCaptureDeviceManager()
</span><del>- : m_objcObserver(adoptNS([[WebCoreAVCaptureDeviceManagerObserver alloc] initWithCallback:this]))
</del><ins>+ : m_objcObserver(adoptNS([[WebCoreAVCaptureDeviceManagerObserver alloc] initWithCallback: this]))
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -195,269 +224,91 @@
</span><span class="cx"> [m_objcObserver disconnect];
</span><span class="cx"> }
</span><span class="cx">
</span><del>-String AVCaptureDeviceManager::bestSessionPresetForVideoSize(AVCaptureSessionType *captureSession, int width, int height)
</del><ins>+Vector<RefPtr<RealtimeMediaSource>> AVCaptureDeviceManager::bestSourcesForTypeAndConstraints(RealtimeMediaSource::Type type, PassRefPtr<MediaConstraints> constraints)
</ins><span class="cx"> {
</span><del>- ASSERT(width >= 0);
- ASSERT(height >= 0);
-
- if (width > 1280 || height > 720)
- // FIXME: this restriction could be adjusted with the videoMaxScaleAndCropFactor property.
- return emptyString();
-
- if (width > 640 || height > 480) {
- if (![captureSession canSetSessionPreset:AVCaptureSessionPreset1280x720])
- emptyString();
- return AVCaptureSessionPreset1280x720;
- }
-
- if (width > 352 || height > 288) {
- if (![captureSession canSetSessionPreset:AVCaptureSessionPreset640x480])
- emptyString();
- return AVCaptureSessionPreset640x480;
- }
-
- if ([captureSession canSetSessionPreset:AVCaptureSessionPreset352x288])
- return AVCaptureSessionPreset352x288;
-
- if ([captureSession canSetSessionPreset:AVCaptureSessionPresetLow])
- return AVCaptureSessionPresetLow;
-
- return emptyString();
-}
</del><ins>+ if (!isAvailable())
+ return Vector<RefPtr<RealtimeMediaSource>>();
</ins><span class="cx">
</span><del>-bool AVCaptureDeviceManager::deviceSupportsFacingMode(AVCaptureDeviceType *device, RealtimeMediaSourceStates::VideoFacingMode facingMode)
-{
- if (![device hasMediaType:AVMediaTypeVideo])
- return false;
-
- switch (facingMode) {
- case RealtimeMediaSourceStates::User:
- if ([device position] == AVCaptureDevicePositionFront)
- return true;
- break;
- case RealtimeMediaSourceStates::Environment:
- if ([device position] == AVCaptureDevicePositionBack)
- return true;
- break;
- case RealtimeMediaSourceStates::Left:
- case RealtimeMediaSourceStates::Right:
- case RealtimeMediaSourceStates::Unknown:
- return false;
- }
-
- return false;
</del><ins>+ return CaptureDeviceManager::bestSourcesForTypeAndConstraints(type, constraints);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-CaptureDevice* AVCaptureDeviceManager::bestDeviceForFacingMode(RealtimeMediaSourceStates::VideoFacingMode facingMode)
</del><ins>+RefPtr<RealtimeMediaSource> AVCaptureDeviceManager::sourceWithUID(const String& deviceUID, RealtimeMediaSource::Type type, MediaConstraints* constraints)
</ins><span class="cx"> {
</span><del>- Vector<CaptureDevice>& devices = captureDeviceList();
-
- size_t count = devices.size();
- for (size_t i = 0; i < count; ++i) {
- AVCaptureDeviceType *device = [getAVCaptureDeviceClass() deviceWithUniqueID:devices[i].m_captureDeviceID];
- ASSERT(device);
-
- if (device && deviceSupportsFacingMode(device, facingMode))
- return &devices[i];
- }
-
- return 0;
</del><ins>+ if (!isAvailable())
+ return nullptr;
+
+ return CaptureDeviceManager::sourceWithUID(deviceUID, type, constraints);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-bool AVCaptureDeviceManager::sessionSupportsConstraint(AVCaptureSessionType *session, RealtimeMediaSource::Type type, const String& name, const String& value)
</del><ins>+TrackSourceInfoVector AVCaptureDeviceManager::getSourcesInfo(const String& requestOrigin)
</ins><span class="cx"> {
</span><del>- size_t constraint = validConstraintNames().find(name);
- if (constraint == notFound)
- return true;
-
- switch (constraint) {
- case Width:
- if (type == RealtimeMediaSource::Audio)
- return false;
</del><ins>+ if (!isAvailable())
+ return TrackSourceInfoVector();
</ins><span class="cx">
</span><del>- return !bestSessionPresetForVideoSize(session, value.toInt(), 0).isEmpty();
- case Height:
- if (type == RealtimeMediaSource::Audio)
- return false;
-
- return !bestSessionPresetForVideoSize(session, 0, value.toInt()).isEmpty();
- case FrameRate: {
- if (type == RealtimeMediaSource::Audio)
- return false;
-
- // It would make sense to use [AVCaptureConnection videoMinFrameDuration] and
- // [AVCaptureConnection videoMaxFrameDuration], but they only work with a "live" AVCaptureConnection.
- float rate = value.toFloat();
- return rate > 0 && rate <= 60;
- }
- case Gain: {
- if (type != RealtimeMediaSource::Audio)
- return false;
-
- float level = value.toFloat();
- return level > 0 && level <= 1;
- }
- case FacingMode: {
- if (type == RealtimeMediaSource::Audio)
- return false;
-
- size_t facingMode = validFacingModes().find(value);
- if (facingMode != notFound)
- return false;
- return bestDeviceForFacingMode(static_cast<RealtimeMediaSourceStates::VideoFacingMode>(facingMode));
- }
- }
-
- return false;
</del><ins>+ return CaptureDeviceManager::getSourcesInfo(requestOrigin);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-bool AVCaptureDeviceManager::isValidConstraint(RealtimeMediaSource::Type type, const String& name)
</del><ins>+bool AVCaptureDeviceManager::verifyConstraintsForMediaType(RealtimeMediaSource::Type type, MediaConstraints* constraints, const CaptureSessionInfo* session, String& invalidConstraint)
</ins><span class="cx"> {
</span><del>- size_t constraint = validConstraintNames().find(name);
- if (constraint == notFound)
</del><ins>+ if (!isAvailable())
</ins><span class="cx"> return false;
</span><span class="cx">
</span><del>- if (constraint == Gain)
- return type == RealtimeMediaSource::Audio;
-
- return true;
</del><ins>+ return CaptureDeviceManager::verifyConstraintsForMediaType(type, constraints, session, invalidConstraint);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-Vector<RefPtr<TrackSourceInfo>> AVCaptureDeviceManager::getSourcesInfo(const String& requestOrigin)
</del><ins>+CaptureSessionInfo AVCaptureDeviceManager::defaultCaptureSession() const
</ins><span class="cx"> {
</span><del>- UNUSED_PARAM(requestOrigin);
- Vector<RefPtr<TrackSourceInfo>> sourcesInfo;
-
- if (!isAvailable())
- return sourcesInfo;
-
- Vector<CaptureDevice>& devices = captureDeviceList();
- for (auto captureDevice : devices) {
-
- if (!captureDevice.m_enabled)
- continue;
-
- if (!captureDevice.m_videoSourceId.isEmpty())
- sourcesInfo.append(TrackSourceInfo::create(captureDevice.m_videoSourceId, TrackSourceInfo::Video, captureDevice.m_localizedName, captureDevice.m_groupID));
- if (!captureDevice.m_audioSourceId.isEmpty())
- sourcesInfo.append(TrackSourceInfo::create(captureDevice.m_audioSourceId, TrackSourceInfo::Audio, captureDevice.m_localizedName, captureDevice.m_groupID));
- }
-
- LOG(Media, "AVCaptureDeviceManager::getSourcesInfo(%p), found %d active devices", this, sourcesInfo.size());
-
- return sourcesInfo;
</del><ins>+ // FIXME: I don't know if it's safe to use a static var here, since the state of a newly
+ // initialized AVCaptureSession may be different. If not, this should be static and use a
+ // static NeverDestroyed<CaptureSessionInfo>.
+ return AVCaptureSessionInfo([allocAVCaptureSessionInstance() init]);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-bool AVCaptureDeviceManager::verifyConstraintsForMediaType(AVCaptureSessionType *session, RealtimeMediaSource::Type type, MediaConstraints* constraints, String& invalidConstraint)
</del><ins>+bool AVCaptureDeviceManager::sessionSupportsConstraint(const CaptureSessionInfo* session, RealtimeMediaSource::Type type, const String& name, const String& value)
</ins><span class="cx"> {
</span><del>- if (!isAvailable())
</del><ins>+ const RealtimeMediaSourceSupportedConstraints& supportedConstraints = RealtimeMediaSourceCenter::singleton().supportedConstraints();
+ MediaConstraintType constraint = supportedConstraints.constraintFromName(name);
+ if (!supportedConstraints.supportsConstraint(constraint))
</ins><span class="cx"> return false;
</span><span class="cx">
</span><del>- if (!constraints)
- return true;
</del><ins>+ CaptureSessionInfo defaultSession = defaultCaptureSession();
+ if (!session)
+ session = &defaultSession;
</ins><span class="cx">
</span><del>- Vector<MediaConstraint> mandatoryConstraints;
- constraints->getMandatoryConstraints(mandatoryConstraints);
- if (mandatoryConstraints.size()) {
</del><ins>+ if (type == RealtimeMediaSource::Video) {
+ if (constraint == MediaConstraintType::Width)
+ return session->bestSessionPresetForVideoDimensions(value.toInt(), 0) != emptyString();
</ins><span class="cx">
</span><del>- RetainPtr<AVCaptureSessionType> captureSession = session ? session : adoptNS([allocAVCaptureSessionInstance() init]);
- for (size_t i = 0; i < mandatoryConstraints.size(); ++i) {
- const MediaConstraint& constraint = mandatoryConstraints[i];
- if (!sessionSupportsConstraint(captureSession.get(), type, constraint.m_name, constraint.m_value)) {
- invalidConstraint = constraint.m_name;
- return false;
- }
- }
</del><ins>+ if (constraint == MediaConstraintType::Height)
+ return session->bestSessionPresetForVideoDimensions(0, value.toInt()) != emptyString();
</ins><span class="cx"> }
</span><del>-
- return true;
</del><ins>+ return CaptureDeviceManager::sessionSupportsConstraint(session, type, name, value);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-Vector<RefPtr<RealtimeMediaSource>> AVCaptureDeviceManager::bestSourcesForTypeAndConstraints(RealtimeMediaSource::Type type, PassRefPtr<MediaConstraints> constraints)
</del><ins>+RealtimeMediaSource* AVCaptureDeviceManager::createMediaSourceForCaptureDeviceWithConstraints(const CaptureDeviceInfo& captureDevice, MediaConstraints* constraints)
</ins><span class="cx"> {
</span><del>- Vector<RefPtr<RealtimeMediaSource>> bestSourcesList;
-
- if (!isAvailable())
- return bestSourcesList;
-
- struct {
- bool operator()(RefPtr<RealtimeMediaSource> a, RefPtr<RealtimeMediaSource> b)
- {
- return a->fitnessScore() < b->fitnessScore();
- }
- } sortBasedOffFitnessScore;
</del><ins>+ AVCaptureDeviceType *device = [getAVCaptureDeviceClass() deviceWithUniqueID:captureDevice.m_persistentDeviceID];
+ if (!device)
+ return nullptr;
</ins><span class="cx">
</span><del>- Vector<CaptureDevice>& devices = captureDeviceList();
</del><ins>+ RefPtr<AVMediaCaptureSource> captureSource;
+ if (captureDevice.m_sourceType == RealtimeMediaSource::Audio)
+ captureSource = AVAudioCaptureSource::create(device, captureDevice.m_sourceId, constraints);
+ else
+ captureSource = AVVideoCaptureSource::create(device, captureDevice.m_sourceId, constraints);
</ins><span class="cx">
</span><del>- for (auto& captureDevice : devices) {
- if (!captureDevice.m_enabled)
- continue;
</del><ins>+ if (constraints) {
+ CaptureSessionInfo captureSession = defaultCaptureSession();
+ if (captureDevice.m_sourceType != RealtimeMediaSource::None)
+ captureSession = AVCaptureSessionInfo(captureSource->session());
</ins><span class="cx">
</span><del>- if (type == RealtimeMediaSource::Audio && !captureDevice.m_audioSourceId.isEmpty()) {
- RefPtr<RealtimeMediaSource> captureSource = AVCaptureDeviceManager::sourceWithUID(captureDevice.m_captureDeviceID, RealtimeMediaSource::Audio, constraints.get());
- if (!captureSource)
- continue;
-
- bestSourcesList.append(captureSource.leakRef());
- }
-
- if (type == RealtimeMediaSource::Video && !captureDevice.m_videoSourceId.isEmpty()) {
- RefPtr<RealtimeMediaSource> captureSource = AVCaptureDeviceManager::sourceWithUID(captureDevice.m_captureDeviceID, RealtimeMediaSource::Video, constraints.get());
- if (!captureSource)
- continue;
-
- bestSourcesList.append(captureSource.leakRef());
- }
</del><ins>+ String ignoredInvalidConstraints;
+ if (!verifyConstraintsForMediaType(captureDevice.m_sourceType, constraints, &captureSession, ignoredInvalidConstraints))
+ return nullptr;
</ins><span class="cx"> }
</span><del>- std::sort(bestSourcesList.begin(), bestSourcesList.end(), sortBasedOffFitnessScore);
- return bestSourcesList;
</del><ins>+ return captureSource.leakRef();
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-RefPtr<RealtimeMediaSource> AVCaptureDeviceManager::sourceWithUID(const String& deviceUID, RealtimeMediaSource::Type type, MediaConstraints* constraints)
-{
- if (!isAvailable())
- return 0;
-
- Vector<CaptureDevice>& devices = captureDeviceList();
- for (auto& captureDevice : devices) {
- if (captureDevice.m_captureDeviceID != deviceUID || !captureDevice.m_enabled)
- continue;
-
- if (type == RealtimeMediaSource::Audio && captureDevice.m_audioSourceId.isEmpty())
- continue;
- if (type == RealtimeMediaSource::Video && captureDevice.m_videoSourceId.isEmpty())
- continue;
-
- AVCaptureDeviceType *device = [getAVCaptureDeviceClass() deviceWithUniqueID:captureDevice.m_captureDeviceID];
- ASSERT(device);
-
- RefPtr<AVMediaCaptureSource> captureSource;
- if (type == RealtimeMediaSource::Audio)
- captureSource = AVAudioCaptureSource::create(device, captureDevice.m_audioSourceId, constraints);
- else
- captureSource = AVVideoCaptureSource::create(device, captureDevice.m_videoSourceId, constraints);
-
- if (constraints) {
- String invalidConstraints;
- AVCaptureSessionType *session = nil;
-
- if (type == RealtimeMediaSource::Video)
- session = captureSource->session();
- else if (type == RealtimeMediaSource::Audio)
- session = captureSource->session();
- AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(session, type, constraints, invalidConstraints);
-
- if (!invalidConstraints.isEmpty())
- continue;
- }
-
- return captureSource.leakRef();
- }
-
- return nullptr;
-
-}
-
</del><span class="cx"> void AVCaptureDeviceManager::registerForDeviceNotifications()
</span><span class="cx"> {
</span><span class="cx"> [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get() selector:@selector(deviceConnected:) name:AVCaptureDeviceWasConnectedNotification object:nil];
</span><span class="lines">@@ -471,7 +322,7 @@
</span><span class="cx">
</span><span class="cx"> void AVCaptureDeviceManager::deviceDisconnected(AVCaptureDeviceType* device)
</span><span class="cx"> {
</span><del>- Vector<CaptureDevice>& devices = captureDeviceList();
</del><ins>+ Vector<CaptureDeviceInfo>& devices = captureDeviceList();
</ins><span class="cx">
</span><span class="cx"> size_t count = devices.size();
</span><span class="cx"> if (!count)
</span><span class="lines">@@ -479,47 +330,20 @@
</span><span class="cx">
</span><span class="cx"> String deviceID = device.uniqueID;
</span><span class="cx"> for (size_t i = 0; i < count; ++i) {
</span><del>- if (devices[i].m_captureDeviceID == deviceID) {
</del><ins>+ if (devices[i].m_persistentDeviceID == deviceID) {
</ins><span class="cx"> LOG(Media, "AVCaptureDeviceManager::deviceDisconnected(%p), device %d disabled", this, i);
</span><span class="cx"> devices[i].m_enabled = false;
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>-const Vector<AtomicString>& AVCaptureDeviceManager::validConstraintNames()
</del><ins>+bool AVCaptureDeviceManager::isSupportedFrameRate(float frameRate) const
</ins><span class="cx"> {
</span><del>- DEPRECATED_DEFINE_STATIC_LOCAL(Vector<AtomicString>, constraints, ());
- static NeverDestroyed<AtomicString> heightConstraint("height", AtomicString::ConstructFromLiteral);
- static NeverDestroyed<AtomicString> widthConstraint("width", AtomicString::ConstructFromLiteral);
- static NeverDestroyed<AtomicString> frameRateConstraint("frameRate", AtomicString::ConstructFromLiteral);
- static NeverDestroyed<AtomicString> facingModeConstraint("facingMode", AtomicString::ConstructFromLiteral);
- static NeverDestroyed<AtomicString> gainConstraint("gain", AtomicString::ConstructFromLiteral);
-
- if (!constraints.size()) {
- constraints.insert(Width, widthConstraint);
- constraints.insert(Height, heightConstraint);
- constraints.insert(FrameRate, frameRateConstraint);
- constraints.insert(FacingMode, facingModeConstraint);
- constraints.insert(Gain, gainConstraint);
- }
-
- return constraints;
</del><ins>+ // FIXME: We should use [AVCaptureConnection videoMinFrameDuration] and [AVCaptureConnection videoMaxFrameDuration],
+ // but they only work with a "live" AVCaptureConnection. For now, just use the default platform-independent behavior.
+ return CaptureDeviceManager::isSupportedFrameRate(frameRate);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-const Vector<AtomicString>& AVCaptureDeviceManager::validFacingModes()
-{
- DEPRECATED_DEFINE_STATIC_LOCAL(Vector<AtomicString>, modes, ());
-
- if (!modes.size()) {
- modes.insert(RealtimeMediaSourceStates::User, RealtimeMediaSourceStates::facingMode(RealtimeMediaSourceStates::User));
- modes.insert(RealtimeMediaSourceStates::Environment, RealtimeMediaSourceStates::facingMode(RealtimeMediaSourceStates::Environment));
- modes.insert(RealtimeMediaSourceStates::Left, RealtimeMediaSourceStates::facingMode(RealtimeMediaSourceStates::Left));
- modes.insert(RealtimeMediaSourceStates::Right, RealtimeMediaSourceStates::facingMode(RealtimeMediaSourceStates::Right));
- }
-
- return modes;
-}
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> @implementation WebCoreAVCaptureDeviceManagerObserver
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVVideoCaptureSourcemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm (192837 => 192838)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm        2015-11-30 23:27:23 UTC (rev 192837)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm        2015-11-30 23:48:42 UTC (rev 192838)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> #import "MediaConstraints.h"
</span><span class="cx"> #import "NotImplemented.h"
</span><span class="cx"> #import "PlatformLayer.h"
</span><ins>+#import "RealtimeMediaSourceCenter.h"
</ins><span class="cx"> #import "RealtimeMediaSourceStates.h"
</span><span class="cx"> #import <AVFoundation/AVFoundation.h>
</span><span class="cx"> #import <objc/runtime.h>
</span><span class="lines">@@ -179,36 +180,39 @@
</span><span class="cx"> {
</span><span class="cx"> ASSERT(constraints);
</span><span class="cx">
</span><del>- const Vector<AtomicString>& constraintNames = AVCaptureDeviceManager::validConstraintNames();
- String widthConstraint;
- String heightConstraint;
</del><ins>+ const RealtimeMediaSourceSupportedConstraints& supportedConstraints = RealtimeMediaSourceCenter::singleton().supportedConstraints();
+ String widthConstraintValue;
+ String heightConstraintValue;
+ String widthConstraintName = supportedConstraints.nameForConstraint(MediaConstraintType::Width);
+ String heightConstraintName = supportedConstraints.nameForConstraint(MediaConstraintType::Height);
</ins><span class="cx">
</span><del>- constraints->getMandatoryConstraintValue(constraintNames[AVCaptureDeviceManager::Width], widthConstraint);
- constraints->getMandatoryConstraintValue(constraintNames[AVCaptureDeviceManager::Height], heightConstraint);
</del><ins>+ constraints->getMandatoryConstraintValue(widthConstraintName, widthConstraintValue);
+ constraints->getMandatoryConstraintValue(heightConstraintName, heightConstraintValue);
</ins><span class="cx">
</span><del>- int width = widthConstraint.toInt();
- int height = heightConstraint.toInt();
</del><ins>+ int width = widthConstraintValue.toInt();
+ int height = heightConstraintValue.toInt();
</ins><span class="cx"> if (!width && !height) {
</span><del>- constraints->getOptionalConstraintValue(constraintNames[AVCaptureDeviceManager::Width], widthConstraint);
- constraints->getOptionalConstraintValue(constraintNames[AVCaptureDeviceManager::Height], heightConstraint);
- width = widthConstraint.toInt();
- height = heightConstraint.toInt();
</del><ins>+ constraints->getOptionalConstraintValue(widthConstraintName, widthConstraintValue);
+ constraints->getOptionalConstraintValue(heightConstraintName, heightConstraintValue);
+ width = widthConstraintValue.toInt();
+ height = heightConstraintValue.toInt();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (width || height) {
</span><del>- NSString *preset = AVCaptureDeviceManager::bestSessionPresetForVideoSize(session(), width, height);
</del><ins>+ NSString *preset = AVCaptureSessionInfo(session()).bestSessionPresetForVideoDimensions(width, height);
</ins><span class="cx"> if (!preset || ![session() canSetSessionPreset:preset])
</span><span class="cx"> return false;
</span><span class="cx">
</span><span class="cx"> [session() setSessionPreset:preset];
</span><span class="cx"> }
</span><span class="cx">
</span><del>- String frameRateConstraint;
- constraints->getMandatoryConstraintValue(constraintNames[AVCaptureDeviceManager::FrameRate], frameRateConstraint);
- float frameRate = frameRateConstraint.toFloat();
</del><ins>+ String frameRateConstraintValue;
+ String frameRateConstraintName = supportedConstraints.nameForConstraint(MediaConstraintType::FrameRate);
+ constraints->getMandatoryConstraintValue(frameRateConstraintName, frameRateConstraintValue);
+ float frameRate = frameRateConstraintValue.toFloat();
</ins><span class="cx"> if (!frameRate) {
</span><del>- constraints->getOptionalConstraintValue(constraintNames[AVCaptureDeviceManager::FrameRate], frameRateConstraint);
- frameRate = frameRateConstraint.toFloat();
</del><ins>+ constraints->getOptionalConstraintValue(frameRateConstraintName, frameRateConstraintValue);
+ frameRate = frameRateConstraintValue.toFloat();
</ins><span class="cx"> }
</span><span class="cx"> if (frameRate && !setFrameRateConstraint(frameRate, 0))
</span><span class="cx"> return false;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacRealtimeMediaSourceCenterMaccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp (192837 => 192838)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp        2015-11-30 23:27:23 UTC (rev 192837)
+++ trunk/Source/WebCore/platform/mediastream/mac/RealtimeMediaSourceCenterMac.cpp        2015-11-30 23:48:42 UTC (rev 192838)
</span><span class="lines">@@ -76,7 +76,7 @@
</span><span class="cx">
</span><span class="cx"> if (audioConstraints) {
</span><span class="cx"> String invalidConstraint;
</span><del>- AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(nil, RealtimeMediaSource::Audio, audioConstraints.get(), invalidConstraint);
</del><ins>+ AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(RealtimeMediaSource::Audio, audioConstraints.get(), nullptr, invalidConstraint);
</ins><span class="cx"> if (!invalidConstraint.isEmpty()) {
</span><span class="cx"> client->constraintsInvalid(invalidConstraint);
</span><span class="cx"> return;
</span><span class="lines">@@ -87,7 +87,7 @@
</span><span class="cx">
</span><span class="cx"> if (videoConstraints) {
</span><span class="cx"> String invalidConstraint;
</span><del>- AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(nil, RealtimeMediaSource::Video, videoConstraints.get(), invalidConstraint);
</del><ins>+ AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(RealtimeMediaSource::Video, videoConstraints.get(), nullptr, invalidConstraint);
</ins><span class="cx"> if (!invalidConstraint.isEmpty()) {
</span><span class="cx"> client->constraintsInvalid(invalidConstraint);
</span><span class="cx"> return;
</span><span class="lines">@@ -109,7 +109,7 @@
</span><span class="cx">
</span><span class="cx"> if (audioConstraints) {
</span><span class="cx"> String invalidConstraint;
</span><del>- AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(nil, RealtimeMediaSource::Audio, audioConstraints.get(), invalidConstraint);
</del><ins>+ AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(RealtimeMediaSource::Audio, audioConstraints.get(), nullptr, invalidConstraint);
</ins><span class="cx"> if (!invalidConstraint.isEmpty()) {
</span><span class="cx"> client->failedToCreateStreamWithConstraintsError(invalidConstraint);
</span><span class="cx"> return;
</span><span class="lines">@@ -124,7 +124,7 @@
</span><span class="cx">
</span><span class="cx"> if (videoConstraints) {
</span><span class="cx"> String invalidConstraint;
</span><del>- AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(nil, RealtimeMediaSource::Video, videoConstraints.get(), invalidConstraint);
</del><ins>+ AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(RealtimeMediaSource::Video, videoConstraints.get(), nullptr, invalidConstraint);
</ins><span class="cx"> if (!invalidConstraint.isEmpty()) {
</span><span class="cx"> client->failedToCreateStreamWithConstraintsError(invalidConstraint);
</span><span class="cx"> return;
</span></span></pre>
</div>
</div>
</body>
</html>