<!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>[205348] trunk</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/205348">205348</a></dd>
<dt>Author</dt> <dd>eric.carlson@apple.com</dd>
<dt>Date</dt> <dd>2016-09-02 10:36:29 -0700 (Fri, 02 Sep 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>[MediaStream] applyConstraints pt. 1 - mandatory constraints
https://bugs.webkit.org/show_bug.cgi?id=161469
<rdar://problem/28109325>
Reviewed by Jer Noble.
Source/WebCore:
Tests: fast/mediastream/apply-constraints-audio.html
fast/mediastream/apply-constraints-video.html
* Modules/mediastream/MediaStreamTrack.cpp:
(WebCore::MediaStreamTrack::MediaStreamTrack): Initialize the weak pointer factory.
(WebCore::MediaStreamTrack::applyConstraints): Make it work.
* Modules/mediastream/MediaStreamTrack.h:
* Modules/mediastream/MediaStreamTrack.idl:
* WebCore.xcodeproj/project.pbxproj: Add JSMediaDevicesCustom.h.
* bindings/js/JSMediaDevicesCustom.cpp:
(WebCore::createStringConstraint): Add name parameter.
(WebCore::createBooleanConstraint): Ditto.
(WebCore::createDoubleConstraint): Ditto.
(WebCore::createIntConstraint): Ditto.
(WebCore::parseMediaTrackConstraintSetForKey): Drop type parameter because we don't need to
filter by source media type.
(WebCore::parseAdvancedConstraints): Ditto.
(WebCore::parseMediaConstraintsDictionary): Renamed from parseConstraints.
(WebCore::JSMediaDevices::getUserMedia): Don't throw exceptions, always return a promise.
(WebCore::parseConstraints): Deleted.
* bindings/js/JSMediaDevicesCustom.h: Added.
* bindings/js/JSMediaStreamTrackCustom.cpp:
(WebCore::JSMediaStreamTrack::getSettings): Don't include aspect ratio if the value is 0.
(WebCore::capabilityValue): asULong -> asInt.
(WebCore::JSMediaStreamTrack::applyConstraints): New.
(WebCore::JSMediaStreamTrack::getConstraints): New.
* bindings/js/WebCoreBuiltinNames.h: Add "mediaStreamTrackConstraints".
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::setSrcObject): Drive by fix: don't call DOMURL::createPublicURL(null).
* platform/mediastream/MediaConstraints.cpp:
(WebCore::MediaConstraint::create): Pass name to constructors.
(WebCore::StringConstraint::find): New.
* platform/mediastream/MediaConstraints.h:
* platform/mediastream/MediaStreamTrackPrivate.cpp:
(WebCore::MediaStreamTrackPrivate::applyConstraints): Add callback parameters.
* platform/mediastream/MediaStreamTrackPrivate.h:
* platform/mediastream/RealtimeMediaSource.cpp:
(WebCore::RealtimeMediaSource::RealtimeMediaSource): Initialize weak pointer factory.
(WebCore::RealtimeMediaSource::settingsDidChange): Don't call observers immediately so we can
coalesce multiple changes in the same runloop cycle.
(WebCore::RealtimeMediaSource::supportsConstraint): New.
(WebCore::value): Return the most appropriate value from a numeric constraint.
(WebCore::RealtimeMediaSource::applyConstraint): New, apply one constraint.
(WebCore::RealtimeMediaSource::applyConstraints): New, validate and apply constraints.
(WebCore::RealtimeMediaSource::setWidth): New.
(WebCore::RealtimeMediaSource::setHeight): New.
(WebCore::RealtimeMediaSource::setFrameRate): New.
(WebCore::RealtimeMediaSource::setAspectRatio): New.
(WebCore::RealtimeMediaSource::setFacingMode): New.
(WebCore::RealtimeMediaSource::setVolume): New.
(WebCore::RealtimeMediaSource::setSampleRate): New.
(WebCore::RealtimeMediaSource::setSampleSize): New.
(WebCore::RealtimeMediaSource::setEchoCancellation) New.:
(WebCore::RealtimeMediaSource::scheduleDeferredTask): New.
* platform/mediastream/RealtimeMediaSource.h:
* platform/mediastream/RealtimeMediaSourceCapabilities.h:
(WebCore::CapabilityValueOrRange::CapabilityValueOrRange): "unsigned long" -> "int"
* platform/mediastream/RealtimeMediaSourceSettings.cpp:
(WebCore::userFacing): New.
(WebCore::environmentFacing): New.
(WebCore::leftFacing): New.
(WebCore::rightFacing): New.
(WebCore::RealtimeMediaSourceSettings::facingMode):
(WebCore::RealtimeMediaSourceSettings::videoFacingModeEnum):
* platform/mediastream/RealtimeMediaSourceSettings.h:
* platform/mediastream/mac/AVAudioCaptureSource.mm:
(WebCore::AVAudioCaptureSource::initializeCapabilities): Volume range is 0.0 .. 1.0.
* platform/mediastream/mac/AVMediaCaptureSource.h:
(WebCore::AVMediaCaptureSource::createWeakPtr): Deleted.
* platform/mediastream/mac/AVMediaCaptureSource.mm:
(WebCore::AVMediaCaptureSource::AVMediaCaptureSource): Don't need the weak ptr factory, it is
in the base class.
(WebCore::AVMediaCaptureSource::scheduleDeferredTask): Deleted.
* platform/mediastream/mac/AVVideoCaptureSource.h:
* platform/mediastream/mac/AVVideoCaptureSource.mm:
(WebCore::AVVideoCaptureSource::applySize): New.
(WebCore::AVVideoCaptureSource::applyFrameRate): New.
(WebCore::AVVideoCaptureSource::setupCaptureSession):
(WebCore::AVVideoCaptureSource::setFrameRateConstraint): Deleted.
(WebCore::AVVideoCaptureSource::applyConstraints): Deleted.
* platform/mock/MockRealtimeAudioSource.cpp:
(WebCore::MockRealtimeAudioSource::updateSettings): Set volume and echoCancellation to the
current values.
(WebCore::MockRealtimeAudioSource::initializeCapabilities): Volume takes a float, not an int.
* platform/mock/MockRealtimeAudioSource.h:
* platform/mock/MockRealtimeMediaSource.cpp: Minor cleanup.
* platform/mock/MockRealtimeMediaSource.h:
* platform/mock/MockRealtimeVideoSource.cpp:
(WebCore::MockRealtimeVideoSource::MockRealtimeVideoSource): Initialize frame rate.
(WebCore::MockRealtimeVideoSource::startProducingData): m_size -> size().
(WebCore::MockRealtimeVideoSource::updateSettings): Use accessors because instance variables
have been moved to the base class.
(WebCore::MockRealtimeVideoSource::initializeCapabilities): Ditto.
(WebCore::MockRealtimeVideoSource::applyFrameRate): New.
(WebCore::MockRealtimeVideoSource::applySize):
(WebCore::MockRealtimeVideoSource::drawAnimation):
(WebCore::MockRealtimeVideoSource::drawBoxes):
(WebCore::MockRealtimeVideoSource::drawText):
(WebCore::MockRealtimeVideoSource::generateFrame):
(WebCore::MockRealtimeVideoSource::imageBuffer):
(WebCore::MockRealtimeVideoSource::setFrameRate): Deleted.
(WebCore::MockRealtimeVideoSource::setSize): Deleted.
* platform/mock/MockRealtimeVideoSource.h:
(WebCore::MockRealtimeVideoSource::size): Deleted.
LayoutTests:
* fast/mediastream/apply-constraints-audio-expected.txt: Added.
* fast/mediastream/apply-constraints-audio.html: Added.
* fast/mediastream/apply-constraints-video-expected.txt: Added.
* fast/mediastream/apply-constraints-video.html: Added.
* fast/mediastream/resources/apply-constraints-utils.js: Added.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamMediaStreamTrackcpp">trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamMediaStreamTrackh">trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediastreamMediaStreamTrackidl">trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSMediaDevicesCustomcpp">trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSMediaStreamTrackCustomcpp">trunk/Source/WebCore/bindings/js/JSMediaStreamTrackCustom.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsWebCoreBuiltinNamesh">trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaElementcpp">trunk/Source/WebCore/html/HTMLMediaElement.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaStreamAVFObjCmm">trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamMediaConstraintscpp">trunk/Source/WebCore/platform/mediastream/MediaConstraints.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamMediaConstraintsh">trunk/Source/WebCore/platform/mediastream/MediaConstraints.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamMediaStreamTrackPrivatecpp">trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamMediaStreamTrackPrivateh">trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeMediaSourcecpp">trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceh">trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceCapabilitiesh">trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCapabilities.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceSettingscpp">trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceSettingsh">trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVAudioCaptureSourcemm">trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVMediaCaptureSourceh">trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVMediaCaptureSourcemm">trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVVideoCaptureSourceh">trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmediastreammacAVVideoCaptureSourcemm">trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformmockMockRealtimeAudioSourcecpp">trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmockMockRealtimeAudioSourceh">trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmockMockRealtimeMediaSourcecpp">trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmockMockRealtimeMediaSourceh">trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmockMockRealtimeVideoSourcecpp">trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmockMockRealtimeVideoSourceh">trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastmediastreamapplyconstraintsaudioexpectedtxt">trunk/LayoutTests/fast/mediastream/apply-constraints-audio-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamapplyconstraintsaudiohtml">trunk/LayoutTests/fast/mediastream/apply-constraints-audio.html</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamapplyconstraintsvideoexpectedtxt">trunk/LayoutTests/fast/mediastream/apply-constraints-video-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamapplyconstraintsvideohtml">trunk/LayoutTests/fast/mediastream/apply-constraints-video.html</a></li>
<li><a href="#trunkLayoutTestsfastmediastreamresourcesapplyconstraintsutilsjs">trunk/LayoutTests/fast/mediastream/resources/apply-constraints-utils.js</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSMediaDevicesCustomh">trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/LayoutTests/ChangeLog        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2016-09-02 Eric Carlson <eric.carlson@apple.com>
+
+ [MediaStream] applyConstraints pt. 1 - mandatory constraints
+ https://bugs.webkit.org/show_bug.cgi?id=161469
+ <rdar://problem/28109325>
+
+ Reviewed by Jer Noble.
+
+ * fast/mediastream/apply-constraints-audio-expected.txt: Added.
+ * fast/mediastream/apply-constraints-audio.html: Added.
+ * fast/mediastream/apply-constraints-video-expected.txt: Added.
+ * fast/mediastream/apply-constraints-video.html: Added.
+ * fast/mediastream/resources/apply-constraints-utils.js: Added.
+
</ins><span class="cx"> 2016-09-01 Ryosuke Niwa <rniwa@webkit.org>
</span><span class="cx">
</span><span class="cx"> Only update connected custom elements
</span></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamapplyconstraintsaudioexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/mediastream/apply-constraints-audio-expected.txt (0 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/apply-constraints-audio-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/mediastream/apply-constraints-audio-expected.txt        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+Tests applyConstraints on an audio stream track.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS stream.getVideoTracks().length is 0
+PASS stream.getAudioTracks().length is 1
+PASS video.videoTracks.length is 0
+PASS video.audioTracks.length is 1
+
+** Constraint: {"volume":0.5} - set volume to a valid value.
+PASS settings['volume'] is 0.5
+PASS typeof settings['echoCancellation'] is 'boolean'
+PASS settings['echoCancellation'] is false
+
+** Constraint: {"volume":{"exact":2.1}} - the 'exact' constraint it too big, promise should reject and no settings should change.
+PASS Promise was rejected
+PASS error.constraint is "volume"
+PASS settings['volume'] is 0.5
+PASS typeof settings['echoCancellation'] is 'boolean'
+PASS settings['echoCancellation'] is false
+
+** Constraint: {"volume":{"exact":-1}} - the 'exact' constraint it too small, promise should reject and no settings should change.
+PASS Promise was rejected
+PASS error.constraint is "volume"
+PASS settings['volume'] is 0.5
+PASS typeof settings['echoCancellation'] is 'boolean'
+PASS settings['echoCancellation'] is false
+
+** Constraint: {"echoCancellation":true} - set echoCancellation to a valid value.
+PASS settings['volume'] is 0.5
+PASS typeof settings['echoCancellation'] is 'boolean'
+PASS settings['echoCancellation'] is true
+
+** Constraint: {"facingMode":"environment","frameRate":30,"volume":1} - constraint not supported by an audio track should be ignored.
+PASS settings['volume'] is 1
+PASS typeof settings['echoCancellation'] is 'boolean'
+PASS settings['echoCancellation'] is true
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamapplyconstraintsaudiohtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/mediastream/apply-constraints-audio.html (0 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/apply-constraints-audio.html         (rev 0)
+++ trunk/LayoutTests/fast/mediastream/apply-constraints-audio.html        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -0,0 +1,63 @@
</span><ins>+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="../../resources/js-test-pre.js"></script>
+ <script src="resources/apply-constraints-utils.js"></script>
+ <script>
+
+ let tests = [
+ {
+ message: "set volume to a valid value.",
+ constraint: { volume: .5 },
+ expected: { volume: .5, echoCancellation: false },
+ },
+ {
+ message: "the 'exact' constraint it too big, promise should reject and no settings should change.",
+ constraint: { volume: { exact: 2.1 } },
+ expected: { volume: .5, echoCancellation: false },
+ error: "volume",
+ },
+ {
+ message: "the 'exact' constraint it too small, promise should reject and no settings should change.",
+ constraint: { volume: { exact: -1 } },
+ expected: { volume: .5, echoCancellation: false },
+ error: "volume",
+ },
+ {
+ message: "set echoCancellation to a valid value.",
+ constraint: { echoCancellation: true },
+ expected: { volume: .5, echoCancellation: true },
+ },
+ {
+ message: "constraint not supported by an audio track should be ignored.",
+ constraint: { facingMode: "environment", frameRate: 30, volume: 1.0 },
+ expected: { volume: 1.0, echoCancellation: true },
+ },
+
+ ];
+
+ let tester = new ConstraintsTest({ audio: true }, tests, "Tests applyConstraints on an audio stream track.")
+ .onStreamReady((s) => {
+ stream = s;
+ shouldBe('stream.getVideoTracks().length', '0');
+ shouldBe('stream.getAudioTracks().length', '1');
+ tester.setStreamTrack(stream.getAudioTracks()[0]);
+ })
+ .onVideoReady((v) => {
+ video = v;
+ shouldBe('video.videoTracks.length', '0');
+ shouldBe('video.audioTracks.length', '1');
+ })
+ .start();
+
+ </script>
+ <script src="../../resources/js-test-post.js"></script>
+ </head>
+ <body>
+ <video controls id="video"</video>
+ <br>
+ <div id="div"></div>
+
+ </body>
+</html>
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamapplyconstraintsvideoexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/mediastream/apply-constraints-video-expected.txt (0 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/apply-constraints-video-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/mediastream/apply-constraints-video-expected.txt        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -0,0 +1,97 @@
</span><ins>+Tests applyConstraints on a video stream track.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS stream.getVideoTracks().length is 1
+PASS stream.getAudioTracks().length is 0
+PASS video.videoTracks.length is 1
+PASS video.audioTracks.length is 0
+
+** Constraint: {"width":640,"height":480,"frameRate":30} - set width, height, and frame rate to valid values.
+PASS settings['width'] is 640
+PASS settings['height'] is 480
+PASS settings['frameRate'] is 30
+
+** Constraint: {"width":320,"height":240} - change width and height, frame rate should remain unchanged.
+PASS settings['width'] is 320
+PASS settings['height'] is 240
+PASS settings['frameRate'] is 30
+
+** Constraint: {"width":{"exact":2000}} - the 'exact' constraint can't be satisfied, promise should reject and no settings should change.
+PASS Promise was rejected
+PASS error.constraint is "width"
+PASS settings['width'] is 320
+PASS settings['height'] is 240
+PASS settings['frameRate'] is 30
+
+** Constraint: {"width":640,"height":{"min":3000}} - the 'min' constraint can't be satisfied, promise should reject and no settings should change.
+PASS Promise was rejected
+PASS error.constraint is "height"
+PASS settings['width'] is 320
+PASS settings['height'] is 240
+PASS settings['frameRate'] is 30
+
+** Constraint: {"frameRate":{"max":6}} - the 'max' constraint can't be satisfied, promise should reject and no settings should change.
+PASS Promise was rejected
+PASS error.constraint is "frameRate"
+PASS settings['frameRate'] is 30
+
+** Constraint: {"width":{"exact":400}} - the 'exact' constraint can be satisfied.
+PASS settings['width'] is 400
+PASS settings['height'] is 240
+
+** Constraint: {"width":{"min":300,"ideal":5000}} - the 'ideal' constraint can't be satisfied but the 'min' can, max should be chosen.
+PASS settings['width'] is 1920
+PASS settings['height'] is 240
+
+** Constraint: {"width":{"min":320,"ideal":1280},"height":{"min":480,"ideal":720}} - 'ideal' and 'min' constraints can be satisfied, 'ideal' should be chosen.
+PASS settings['width'] is 1280
+PASS settings['height'] is 720
+
+** Constraint: {"width":3000} - ideal width is greater than track capability, should be clamped to the maximum value.
+PASS settings['width'] is 1920
+
+** Constraint: {"width":160,"height":120,"frameRate":10} - all values are less than track capabilities, should be clamped to the minimum values.
+PASS settings['width'] is 320
+PASS settings['height'] is 240
+PASS settings['frameRate'] is 15
+
+** Constraint: {"facingMode":"environment"} - set facing mode, width and height should remain unchanged
+PASS settings['width'] is 320
+PASS settings['height'] is 240
+PASS settings['facingMode'] is "environment"
+
+** Constraint: {"facingMode":"USER","height":400} - illegal facing mode value should be ignored, height should change.
+PASS settings['facingMode'] is "environment"
+PASS settings['width'] is 320
+PASS settings['height'] is 400
+
+** Constraint: {"FACINGMODE":"user","frameRate":30} - unknown constraint should be ignored, frame rate should change.
+PASS settings['facingMode'] is "environment"
+PASS settings['frameRate'] is 30
+
+** Constraint: {"aspectRatio":"1.3333"} - aspect ratio should change width and height.
+PASS settings['width'] is 320
+PASS settings['height'] is 240
+
+** Constraint: {"aspectRatio":"1.7778"} - new aspect ratio should again change width and height.
+PASS settings['width'] is 320
+PASS settings['height'] is 180
+
+** Constraint: {"width":1920} - when aspect ratio has been set, changing width should change height.
+PASS settings['width'] is 1920
+PASS settings['height'] is 1080
+
+** Constraint: {"height":576} - when aspect ratio has been set, changing height should change width.
+PASS settings['width'] is 1024
+PASS settings['height'] is 576
+
+** Constraint: {"deviceId":{"exact":"20983-20o198-109283-098-09812"}} - the 'exact' deviceID doesn't match, promise should reject.
+PASS Promise was rejected
+PASS error.constraint is "deviceId"
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamapplyconstraintsvideohtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/mediastream/apply-constraints-video.html (0 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/apply-constraints-video.html         (rev 0)
+++ trunk/LayoutTests/fast/mediastream/apply-constraints-video.html        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -0,0 +1,129 @@
</span><ins>+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="../../resources/js-test-pre.js"></script>
+ <script src="resources/apply-constraints-utils.js"></script>
+ <script>
+
+ let tests = [
+ {
+ message: "set width, height, and frame rate to valid values.",
+ constraint: { width: 640, height: 480, frameRate: 30 },
+ expected: { width: 640, height: 480, frameRate: 30 },
+ },
+ {
+ message: "change width and height, frame rate should remain unchanged.",
+ constraint: { width: 320, height: 240 },
+ expected: { width: 320, height: 240, frameRate: 30 },
+ },
+ {
+ message: "the 'exact' constraint can't be satisfied, promise should reject and no settings should change.",
+ constraint: { width: { exact: 2000 } },
+ expected: { width: 320, height: 240, frameRate: 30 },
+ error: "width",
+ },
+ {
+ message: "the 'min' constraint can't be satisfied, promise should reject and no settings should change.",
+ constraint: { width: 640, height: {min: 3000}, },
+ expected: { width: 320, height: 240, frameRate: 30 },
+ error: "height",
+ },
+ {
+ message: "the 'max' constraint can't be satisfied, promise should reject and no settings should change.",
+ constraint: { frameRate: {max: 6}, },
+ expected: { frameRate: 30 },
+ error: "frameRate",
+ },
+ {
+ message: "the 'exact' constraint can be satisfied.",
+ constraint: { width: { exact: 400 } },
+ expected: { width: 400, height: 240 },
+ },
+ {
+ message: "the 'ideal' constraint can't be satisfied but the 'min' can, max should be chosen.",
+ constraint: { width: {min: 300, ideal: 5000} },
+ expected: { width: 1920, height: 240 },
+ },
+ {
+ message: "'ideal' and 'min' constraints can be satisfied, 'ideal' should be chosen.",
+ constraint: { width: {min: 320, ideal: 1280}, height: {min: 480, ideal: 720}, },
+ expected: { width: 1280, height: 720 },
+ },
+ {
+ message: "ideal width is greater than track capability, should be clamped to the maximum value.",
+ constraint: { width: 3000 },
+ expected: { width: 1920},
+ },
+ {
+ message: "all values are less than track capabilities, should be clamped to the minimum values.",
+ constraint: { width: 160, height: 120, frameRate: 10 },
+ expected: { width: 320, height: 240, frameRate: 15 },
+ },
+ {
+ message: "set facing mode, width and height should remain unchanged",
+ constraint: { facingMode: "environment" },
+ expected: { width: 320, height: 240, facingMode: "environment" },
+ },
+ {
+ message: "illegal facing mode value should be ignored, height should change.",
+ constraint: { facingMode: "USER", height: 400 },
+ expected: { facingMode: "environment", width: 320, height: 400 },
+ },
+ {
+ message: "unknown constraint should be ignored, frame rate should change.",
+ constraint: { FACINGMODE: "user", frameRate: 30 },
+ expected: { facingMode: "environment", frameRate: 30 },
+ },
+ {
+ message: "aspect ratio should change width and height.",
+ constraint: { aspectRatio: (4/3).toFixed(4) },
+ expected: { width: 320, height: 240 },
+ },
+ {
+ message: "new aspect ratio should again change width and height.",
+ constraint: { aspectRatio: (16/9).toFixed(4) },
+ expected: { width: 320, height: 180 },
+ },
+ {
+ message: "when aspect ratio has been set, changing width should change height.",
+ constraint: { width: 1920 },
+ expected: { width: 1920, height: 1080},
+ },
+ {
+ message: "when aspect ratio has been set, changing height should change width.",
+ constraint: { height: 576 },
+ expected: { width: 1024, height: 576},
+ },
+ {
+ message: "the 'exact' deviceID doesn't match, promise should reject.",
+ constraint: { deviceId: {exact: "20983-20o198-109283-098-09812"}, },
+ expected: { },
+ error: "deviceId",
+ },
+ ];
+
+ let tester = new ConstraintsTest({ video: true }, tests, "Tests applyConstraints on a video stream track.")
+ .onStreamReady((s) => {
+ stream = s;
+ shouldBe('stream.getVideoTracks().length', '1');
+ shouldBe('stream.getAudioTracks().length', '0');
+ tester.setStreamTrack(stream.getVideoTracks()[0]);
+ })
+ .onVideoReady((v) => {
+ video = v;
+ shouldBe('video.videoTracks.length', '1');
+ shouldBe('video.audioTracks.length', '0');
+ })
+ .start();
+
+ </script>
+ <script src="../../resources/js-test-post.js"></script>
+ </head>
+ <body>
+ <video controls id="video"</video>
+ <br>
+ <div id="div"></div>
+
+ </body>
+</html>
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastmediastreamresourcesapplyconstraintsutilsjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/mediastream/resources/apply-constraints-utils.js (0 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/mediastream/resources/apply-constraints-utils.js         (rev 0)
+++ trunk/LayoutTests/fast/mediastream/resources/apply-constraints-utils.js        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -0,0 +1,115 @@
</span><ins>+let settings;
+let error;
+
+ConstraintsTest = class ConstraintsTest {
+
+ constructor(constraints, tests, description)
+ {
+ this.constraints = constraints;
+ this.tests = tests;
+ this.description = description;
+
+ window.jsTestIsAsync = true;
+ window.successfullyParsed = true;
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(true);
+ }
+
+ onStreamReady(callback)
+ {
+ if (typeof callback == "function")
+ this.streamCallback = callback;
+ return this;
+ }
+
+ onVideoReady(callback)
+ {
+ if (typeof callback == "function")
+ this.videoCallback = callback;
+ return this;
+ }
+
+ scheduleNextTest()
+ {
+ new Promise(resolved => this.runNextTest());
+ }
+
+ checkTrackSettings()
+ {
+ settings = this.track.getSettings();
+ for (let property in this.currentTest.expected) {
+ let expected = this.currentTest.expected[property];
+ if (typeof expected === "string")
+ shouldBeEqualToString(`settings['${property}']`, expected);
+ else
+ shouldEvaluateTo(`settings['${property}']`, expected);
+ }
+ }
+
+ runNextTest()
+ {
+ description(this.description);
+
+ debug("");
+ if (!this.tests.length) {
+ finishJSTest();
+ return;
+ }
+
+ this.currentTest = this.tests.shift();
+ debug(`** Constraint: ${JSON.stringify(this.currentTest.constraint)} - ${this.currentTest.message}`);
+ this.track.applyConstraints(this.currentTest.constraint)
+ .then(() => {
+ if (this.currentTest.error)
+ testFailed(`Constraint '${this.currentTest.error}' should have failed to apply, is '${settings[this.currentTest.error]}'`);
+ else
+ this.checkTrackSettings()
+ this.scheduleNextTest();
+ })
+ .catch((evt) => {
+ if (!this.currentTest.error) {
+ testFailed("Promise was rejected");
+ testFailed(`Constraint failed to apply: ${evt} - constraint = ${evt.constraint}`);
+ } else {
+ testPassed("Promise was rejected");
+ error = evt;
+ shouldBeEqualToString("error.constraint", this.currentTest.error);
+ }
+ this.checkTrackSettings()
+ this.scheduleNextTest();
+ });
+ }
+
+ setStreamTrack(track)
+ {
+ this.track = track;
+ }
+
+ start()
+ {
+ window.addEventListener("load", function () {
+
+ navigator.mediaDevices.getUserMedia(this.constraints)
+ .then(stream => {
+ this.video = document.querySelector("video");
+ this.video.srcObject = stream;
+ if (this.streamCallback)
+ this.streamCallback(stream);
+ })
+ .then(() => new Promise(resolve => this.video.onloadedmetadata = resolve))
+ .then(() => {
+ if (this.videoCallback)
+ this.videoCallback(this.video);
+ this.runNextTest();
+ })
+ .catch(err => {
+ testFailed(`Stream setup failed with error: ${err}`);
+ finishJSTest();
+ });
+
+ }.bind(this), false);
+
+ return this;
+ }
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/ChangeLog        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -1,3 +1,132 @@
</span><ins>+2016-09-02 Eric Carlson <eric.carlson@apple.com>
+
+ [MediaStream] applyConstraints pt. 1 - mandatory constraints
+ https://bugs.webkit.org/show_bug.cgi?id=161469
+ <rdar://problem/28109325>
+
+ Reviewed by Jer Noble.
+
+ Tests: fast/mediastream/apply-constraints-audio.html
+ fast/mediastream/apply-constraints-video.html
+
+ * Modules/mediastream/MediaStreamTrack.cpp:
+ (WebCore::MediaStreamTrack::MediaStreamTrack): Initialize the weak pointer factory.
+ (WebCore::MediaStreamTrack::applyConstraints): Make it work.
+ * Modules/mediastream/MediaStreamTrack.h:
+ * Modules/mediastream/MediaStreamTrack.idl:
+
+ * WebCore.xcodeproj/project.pbxproj: Add JSMediaDevicesCustom.h.
+
+ * bindings/js/JSMediaDevicesCustom.cpp:
+ (WebCore::createStringConstraint): Add name parameter.
+ (WebCore::createBooleanConstraint): Ditto.
+ (WebCore::createDoubleConstraint): Ditto.
+ (WebCore::createIntConstraint): Ditto.
+ (WebCore::parseMediaTrackConstraintSetForKey): Drop type parameter because we don't need to
+ filter by source media type.
+ (WebCore::parseAdvancedConstraints): Ditto.
+ (WebCore::parseMediaConstraintsDictionary): Renamed from parseConstraints.
+ (WebCore::JSMediaDevices::getUserMedia): Don't throw exceptions, always return a promise.
+ (WebCore::parseConstraints): Deleted.
+ * bindings/js/JSMediaDevicesCustom.h: Added.
+
+ * bindings/js/JSMediaStreamTrackCustom.cpp:
+ (WebCore::JSMediaStreamTrack::getSettings): Don't include aspect ratio if the value is 0.
+ (WebCore::capabilityValue): asULong -> asInt.
+ (WebCore::JSMediaStreamTrack::applyConstraints): New.
+ (WebCore::JSMediaStreamTrack::getConstraints): New.
+
+ * bindings/js/WebCoreBuiltinNames.h: Add "mediaStreamTrackConstraints".
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::setSrcObject): Drive by fix: don't call DOMURL::createPublicURL(null).
+
+ * platform/mediastream/MediaConstraints.cpp:
+ (WebCore::MediaConstraint::create): Pass name to constructors.
+ (WebCore::StringConstraint::find): New.
+ * platform/mediastream/MediaConstraints.h:
+
+ * platform/mediastream/MediaStreamTrackPrivate.cpp:
+ (WebCore::MediaStreamTrackPrivate::applyConstraints): Add callback parameters.
+ * platform/mediastream/MediaStreamTrackPrivate.h:
+
+ * platform/mediastream/RealtimeMediaSource.cpp:
+ (WebCore::RealtimeMediaSource::RealtimeMediaSource): Initialize weak pointer factory.
+ (WebCore::RealtimeMediaSource::settingsDidChange): Don't call observers immediately so we can
+ coalesce multiple changes in the same runloop cycle.
+ (WebCore::RealtimeMediaSource::supportsConstraint): New.
+ (WebCore::value): Return the most appropriate value from a numeric constraint.
+ (WebCore::RealtimeMediaSource::applyConstraint): New, apply one constraint.
+ (WebCore::RealtimeMediaSource::applyConstraints): New, validate and apply constraints.
+ (WebCore::RealtimeMediaSource::setWidth): New.
+ (WebCore::RealtimeMediaSource::setHeight): New.
+ (WebCore::RealtimeMediaSource::setFrameRate): New.
+ (WebCore::RealtimeMediaSource::setAspectRatio): New.
+ (WebCore::RealtimeMediaSource::setFacingMode): New.
+ (WebCore::RealtimeMediaSource::setVolume): New.
+ (WebCore::RealtimeMediaSource::setSampleRate): New.
+ (WebCore::RealtimeMediaSource::setSampleSize): New.
+ (WebCore::RealtimeMediaSource::setEchoCancellation) New.:
+ (WebCore::RealtimeMediaSource::scheduleDeferredTask): New.
+ * platform/mediastream/RealtimeMediaSource.h:
+
+ * platform/mediastream/RealtimeMediaSourceCapabilities.h:
+ (WebCore::CapabilityValueOrRange::CapabilityValueOrRange): "unsigned long" -> "int"
+
+ * platform/mediastream/RealtimeMediaSourceSettings.cpp:
+ (WebCore::userFacing): New.
+ (WebCore::environmentFacing): New.
+ (WebCore::leftFacing): New.
+ (WebCore::rightFacing): New.
+ (WebCore::RealtimeMediaSourceSettings::facingMode):
+ (WebCore::RealtimeMediaSourceSettings::videoFacingModeEnum):
+ * platform/mediastream/RealtimeMediaSourceSettings.h:
+
+ * platform/mediastream/mac/AVAudioCaptureSource.mm:
+ (WebCore::AVAudioCaptureSource::initializeCapabilities): Volume range is 0.0 .. 1.0.
+
+ * platform/mediastream/mac/AVMediaCaptureSource.h:
+ (WebCore::AVMediaCaptureSource::createWeakPtr): Deleted.
+ * platform/mediastream/mac/AVMediaCaptureSource.mm:
+ (WebCore::AVMediaCaptureSource::AVMediaCaptureSource): Don't need the weak ptr factory, it is
+ in the base class.
+ (WebCore::AVMediaCaptureSource::scheduleDeferredTask): Deleted.
+
+ * platform/mediastream/mac/AVVideoCaptureSource.h:
+ * platform/mediastream/mac/AVVideoCaptureSource.mm:
+ (WebCore::AVVideoCaptureSource::applySize): New.
+ (WebCore::AVVideoCaptureSource::applyFrameRate): New.
+ (WebCore::AVVideoCaptureSource::setupCaptureSession):
+ (WebCore::AVVideoCaptureSource::setFrameRateConstraint): Deleted.
+ (WebCore::AVVideoCaptureSource::applyConstraints): Deleted.
+
+ * platform/mock/MockRealtimeAudioSource.cpp:
+ (WebCore::MockRealtimeAudioSource::updateSettings): Set volume and echoCancellation to the
+ current values.
+ (WebCore::MockRealtimeAudioSource::initializeCapabilities): Volume takes a float, not an int.
+ * platform/mock/MockRealtimeAudioSource.h:
+
+ * platform/mock/MockRealtimeMediaSource.cpp: Minor cleanup.
+ * platform/mock/MockRealtimeMediaSource.h:
+
+ * platform/mock/MockRealtimeVideoSource.cpp:
+ (WebCore::MockRealtimeVideoSource::MockRealtimeVideoSource): Initialize frame rate.
+ (WebCore::MockRealtimeVideoSource::startProducingData): m_size -> size().
+ (WebCore::MockRealtimeVideoSource::updateSettings): Use accessors because instance variables
+ have been moved to the base class.
+ (WebCore::MockRealtimeVideoSource::initializeCapabilities): Ditto.
+ (WebCore::MockRealtimeVideoSource::applyFrameRate): New.
+ (WebCore::MockRealtimeVideoSource::applySize):
+ (WebCore::MockRealtimeVideoSource::drawAnimation):
+ (WebCore::MockRealtimeVideoSource::drawBoxes):
+ (WebCore::MockRealtimeVideoSource::drawText):
+ (WebCore::MockRealtimeVideoSource::generateFrame):
+ (WebCore::MockRealtimeVideoSource::imageBuffer):
+ (WebCore::MockRealtimeVideoSource::setFrameRate): Deleted.
+ (WebCore::MockRealtimeVideoSource::setSize): Deleted.
+ * platform/mock/MockRealtimeVideoSource.h:
+ (WebCore::MockRealtimeVideoSource::size): Deleted.
+
</ins><span class="cx"> 2016-09-02 Brady Eidson <beidson@apple.com>
</span><span class="cx">
</span><span class="cx"> Weak link the GameController.framework on macOS.
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaStreamTrackcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx"> #include "EventNames.h"
</span><span class="cx"> #include "ExceptionCode.h"
</span><span class="cx"> #include "ExceptionCodePlaceholder.h"
</span><ins>+#include "JSOverconstrainedError.h"
</ins><span class="cx"> #include "MediaConstraintsImpl.h"
</span><span class="cx"> #include "MediaSourceSettings.h"
</span><span class="cx"> #include "MediaStream.h"
</span><span class="lines">@@ -41,6 +42,7 @@
</span><span class="cx"> #include "MediaStreamPrivate.h"
</span><span class="cx"> #include "MediaTrackConstraints.h"
</span><span class="cx"> #include "NotImplemented.h"
</span><ins>+#include "OverconstrainedError.h"
</ins><span class="cx"> #include "ScriptExecutionContext.h"
</span><span class="cx"> #include <wtf/NeverDestroyed.h>
</span><span class="cx">
</span><span class="lines">@@ -52,9 +54,9 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack)
</span><del>- : RefCounted()
- , ActiveDOMObject(&context)
</del><ins>+ : ActiveDOMObject(&context)
</ins><span class="cx"> , m_private(privateTrack)
</span><ins>+ , m_weakPtrFactory(this)
</ins><span class="cx"> {
</span><span class="cx"> suspendIfNeeded();
</span><span class="cx">
</span><span class="lines">@@ -167,18 +169,37 @@
</span><span class="cx"> return m_private->capabilities();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void MediaStreamTrack::applyConstraints(const Dictionary& constraints)
</del><ins>+void MediaStreamTrack::applyConstraints(Ref<MediaConstraints>&& constraints, ApplyConstraintsPromise&& promise)
</ins><span class="cx"> {
</span><del>- // FIXME: Implement correctly. https://bugs.webkit.org/show_bug.cgi?id=160579
</del><ins>+ if (!constraints->isValid()) {
+ promise.reject(TypeError);
+ return;
+ }
</ins><span class="cx">
</span><del>- m_constraints->initialize(constraints);
- m_private->applyConstraints(*m_constraints);
</del><ins>+ m_constraints = WTFMove(constraints);
+ m_promise = WTFMove(promise);
+
+ applyConstraints(*m_constraints);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void MediaStreamTrack::applyConstraints(const MediaConstraints&)
</del><ins>+void MediaStreamTrack::applyConstraints(const MediaConstraints& constraints)
</ins><span class="cx"> {
</span><del>- // FIXME: apply the new constraints to the track
- // https://bugs.webkit.org/show_bug.cgi?id=122428
</del><ins>+ auto weakThis = createWeakPtr();
+ std::function<void(const String&, const String&)> failureHandler = [weakThis](const String& failedConstraint, const String& message) {
+ if (!weakThis || !weakThis->m_promise)
+ return;
+
+ weakThis->m_promise->reject(OverconstrainedError::create(failedConstraint, message).get());
+ };
+
+ std::function<void()> successHandler = [weakThis]() {
+ if (!weakThis || !weakThis->m_promise)
+ return;
+
+ weakThis->m_promise->resolve(nullptr);
+ };
+
+ m_private->applyConstraints(constraints, successHandler, failureHandler);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void MediaStreamTrack::addObserver(MediaStreamTrack::Observer* observer)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaStreamTrackh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -31,18 +31,20 @@
</span><span class="cx">
</span><span class="cx"> #include "ActiveDOMObject.h"
</span><span class="cx"> #include "EventTarget.h"
</span><ins>+#include "JSDOMPromise.h"
</ins><span class="cx"> #include "MediaStreamTrackPrivate.h"
</span><span class="cx"> #include "RealtimeMediaSource.h"
</span><span class="cx"> #include "ScriptWrappable.h"
</span><ins>+#include <wtf/Optional.h>
</ins><span class="cx"> #include <wtf/RefPtr.h>
</span><span class="cx"> #include <wtf/Vector.h>
</span><ins>+#include <wtf/WeakPtr.h>
</ins><span class="cx"> #include <wtf/text/WTFString.h>
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> class AudioSourceProvider;
</span><del>-class Dictionary;
-class MediaConstraintsImpl;
</del><ins>+class MediaConstraints;
</ins><span class="cx"> class MediaSourceSettings;
</span><span class="cx"> class MediaTrackConstraints;
</span><span class="cx">
</span><span class="lines">@@ -79,7 +81,9 @@
</span><span class="cx"> RefPtr<MediaTrackConstraints> getConstraints() const;
</span><span class="cx"> RefPtr<MediaSourceSettings> getSettings() const;
</span><span class="cx"> RefPtr<RealtimeMediaSourceCapabilities> getCapabilities() const;
</span><del>- void applyConstraints(const Dictionary&);
</del><ins>+
+ using ApplyConstraintsPromise = DOMPromise<std::nullptr_t>;
+ void applyConstraints(Ref<MediaConstraints>&&, ApplyConstraintsPromise&&);
</ins><span class="cx"> void applyConstraints(const MediaConstraints&);
</span><span class="cx">
</span><span class="cx"> RealtimeMediaSource& source() const { return m_private->source(); }
</span><span class="lines">@@ -118,10 +122,14 @@
</span><span class="cx"> void trackSettingsChanged(MediaStreamTrackPrivate&) override;
</span><span class="cx"> void trackEnabledChanged(MediaStreamTrackPrivate&) override;
</span><span class="cx">
</span><ins>+ WeakPtr<MediaStreamTrack> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
+
</ins><span class="cx"> Vector<Observer*> m_observers;
</span><span class="cx"> Ref<MediaStreamTrackPrivate> m_private;
</span><span class="cx">
</span><del>- RefPtr<MediaConstraintsImpl> m_constraints;
</del><ins>+ RefPtr<MediaConstraints> m_constraints;
+ Optional<ApplyConstraintsPromise> m_promise;
+ WeakPtrFactory<MediaStreamTrack> m_weakPtrFactory;
</ins><span class="cx">
</span><span class="cx"> bool m_ended { false };
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediastreamMediaStreamTrackidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -47,10 +47,10 @@
</span><span class="cx"> MediaStreamTrack clone();
</span><span class="cx"> [ImplementedAs=stopProducingData] void stop();
</span><span class="cx">
</span><del>- MediaTrackConstraints getConstraints();
</del><ins>+ [Custom] MediaTrackConstraints getConstraints();
</ins><span class="cx"> [Custom] MediaSourceSettings getSettings();
</span><span class="cx"> [Custom] MediaTrackCapabilities getCapabilities();
</span><del>- void applyConstraints(Dictionary constraints);
</del><ins>+ [Custom] Promise applyConstraints(Dictionary? constraints);
</ins><span class="cx">
</span><span class="cx"> attribute EventHandler onoverconstrained;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -139,6 +139,7 @@
</span><span class="cx">                 07297FA71C1881C5003F0735 /* UserMediaPermissionCheck.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07297FA51C1881C5003F0735 /* UserMediaPermissionCheck.cpp */; };
</span><span class="cx">                 07297FA81C1881C5003F0735 /* UserMediaPermissionCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 07297FA61C1881C5003F0735 /* UserMediaPermissionCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 072A70401D6E8F6200DF0AFC /* OverconstrainedErrorEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 072A703E1D6E8F6200DF0AFC /* OverconstrainedErrorEvent.h */; };
</span><ins>+                072A70431D7396B300DF0AFC /* JSMediaDevicesCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = 072A70421D7396B200DF0AFC /* JSMediaDevicesCustom.h */; };
</ins><span class="cx">                 072AE1E5183C0741000A5988 /* PluginReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 072AE1DF183C0741000A5988 /* PluginReplacement.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 072AE1E6183C0741000A5988 /* QuickTimePluginReplacement.mm in Sources */ = {isa = PBXBuildFile; fileRef = 072AE1E0183C0741000A5988 /* QuickTimePluginReplacement.mm */; };
</span><span class="cx">                 072AE1E8183C0741000A5988 /* QuickTimePluginReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 072AE1E2183C0741000A5988 /* QuickTimePluginReplacement.h */; };
</span><span class="lines">@@ -6943,6 +6944,7 @@
</span><span class="cx">                 07297FA61C1881C5003F0735 /* UserMediaPermissionCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMediaPermissionCheck.h; sourceTree = "<group>"; };
</span><span class="cx">                 072A703E1D6E8F6200DF0AFC /* OverconstrainedErrorEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OverconstrainedErrorEvent.h; sourceTree = "<group>"; };
</span><span class="cx">                 072A703F1D6E8F6200DF0AFC /* OverconstrainedErrorEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = OverconstrainedErrorEvent.idl; sourceTree = "<group>"; };
</span><ins>+                072A70421D7396B200DF0AFC /* JSMediaDevicesCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMediaDevicesCustom.h; sourceTree = "<group>"; };
</ins><span class="cx">                 072AE1DF183C0741000A5988 /* PluginReplacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PluginReplacement.h; sourceTree = "<group>"; };
</span><span class="cx">                 072AE1E0183C0741000A5988 /* QuickTimePluginReplacement.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QuickTimePluginReplacement.mm; sourceTree = "<group>"; };
</span><span class="cx">                 072AE1E1183C0741000A5988 /* QuickTimePluginReplacement.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = QuickTimePluginReplacement.css; sourceTree = "<group>"; };
</span><span class="lines">@@ -21096,6 +21098,7 @@
</span><span class="cx">                                 7A74ECBC101839DA00BF939E /* JSInspectorFrontendHostCustom.cpp */,
</span><span class="cx">                                 BCE1C43F0D9830F4003B02F2 /* JSLocationCustom.cpp */,
</span><span class="cx">                                 1B88DD121D5AD3B200E3B7A4 /* JSMediaDevicesCustom.cpp */,
</span><ins>+                                072A70421D7396B200DF0AFC /* JSMediaDevicesCustom.h */,
</ins><span class="cx">                                 AD726FE716D9F204003A4E6D /* JSMediaListCustom.h */,
</span><span class="cx">                                 07C59B6D17F794F6000FBCBB /* JSMediaStreamTrackCustom.cpp */,
</span><span class="cx">                                 07C1C0E61BFB90A700BD2256 /* JSMediaTrackSupportedConstraintsCustom.cpp */,
</span><span class="lines">@@ -26281,6 +26284,7 @@
</span><span class="cx">                                 93309EA3099EB78C0056E581 /* SharedTimer.h in Headers */,
</span><span class="cx">                                 E48944A3180B57D800F165D8 /* SimpleLineLayout.h in Headers */,
</span><span class="cx">                                 585D6E041A1A792E00FA4F12 /* SimpleLineLayoutFlowContents.h in Headers */,
</span><ins>+                                072A70431D7396B300DF0AFC /* JSMediaDevicesCustom.h in Headers */,
</ins><span class="cx">                                 E4E9B11D1814569C003ACCDF /* SimpleLineLayoutFunctions.h in Headers */,
</span><span class="cx">                                 E4E9B1191810916F003ACCDF /* SimpleLineLayoutResolver.h in Headers */,
</span><span class="cx">                                 582CB0531A78A14B00AFFCC4 /* SimpleLineLayoutTextFragmentIterator.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSMediaDevicesCustomcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -24,7 +24,7 @@
</span><span class="cx"> */
</span><span class="cx">
</span><span class="cx"> #include "config.h"
</span><del>-#include "JSMediaDevices.h"
</del><ins>+#include "JSMediaDevicesCustom.h"
</ins><span class="cx">
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx">
</span><span class="lines">@@ -31,8 +31,8 @@
</span><span class="cx"> #include "ArrayValue.h"
</span><span class="cx"> #include "Dictionary.h"
</span><span class="cx"> #include "ExceptionCode.h"
</span><ins>+#include "JSMediaDevices.h"
</ins><span class="cx"> #include "Logging.h"
</span><del>-#include "MediaConstraints.h"
</del><span class="cx"> #include "MediaConstraintsImpl.h"
</span><span class="cx"> #include "RealtimeMediaSourceCenter.h"
</span><span class="cx"> #include "RealtimeMediaSourceSupportedConstraints.h"
</span><span class="lines">@@ -60,7 +60,7 @@
</span><span class="cx">
</span><span class="cx"> static RefPtr<StringConstraint> createStringConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
</span><span class="cx"> {
</span><del>- auto constraint = StringConstraint::create(type);
</del><ins>+ auto constraint = StringConstraint::create(name, type);
</ins><span class="cx">
</span><span class="cx"> // Dictionary constraint value.
</span><span class="cx"> Dictionary dictionaryValue;
</span><span class="lines">@@ -122,7 +122,7 @@
</span><span class="cx">
</span><span class="cx"> static RefPtr<BooleanConstraint> createBooleanConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
</span><span class="cx"> {
</span><del>- auto constraint = BooleanConstraint::create(type);
</del><ins>+ auto constraint = BooleanConstraint::create(name, type);
</ins><span class="cx">
</span><span class="cx"> // Dictionary constraint value.
</span><span class="cx"> Dictionary dictionaryValue;
</span><span class="lines">@@ -161,7 +161,7 @@
</span><span class="cx">
</span><span class="cx"> static RefPtr<DoubleConstraint> createDoubleConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
</span><span class="cx"> {
</span><del>- auto constraint = DoubleConstraint::create(type);
</del><ins>+ auto constraint = DoubleConstraint::create(name, type);
</ins><span class="cx">
</span><span class="cx"> // Dictionary constraint value.
</span><span class="cx"> Dictionary dictionaryValue;
</span><span class="lines">@@ -208,7 +208,7 @@
</span><span class="cx">
</span><span class="cx"> static RefPtr<IntConstraint> createIntConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
</span><span class="cx"> {
</span><del>- auto constraint = IntConstraint::create(type);
</del><ins>+ auto constraint = IntConstraint::create(name, type);
</ins><span class="cx">
</span><span class="cx"> // Dictionary constraint value.
</span><span class="cx"> Dictionary dictionaryValue;
</span><span class="lines">@@ -253,61 +253,45 @@
</span><span class="cx"> return nullptr;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static void parseMediaTrackConstraintSetForKey(const Dictionary& mediaTrackConstraintSet, const String& name, MediaTrackConstraintSetMap& map, ConstraintSetType constraintSetType, RealtimeMediaSource::Type sourceType)
</del><ins>+static void parseMediaTrackConstraintSetForKey(const Dictionary& mediaTrackConstraintSet, const String& name, MediaTrackConstraintSetMap& map, ConstraintSetType constraintSetType)
</ins><span class="cx"> {
</span><span class="cx"> MediaConstraintType constraintType = RealtimeMediaSourceSupportedConstraints::constraintFromName(name);
</span><span class="cx">
</span><span class="cx"> RefPtr<MediaConstraint> mediaConstraint;
</span><del>- if (sourceType == RealtimeMediaSource::Audio) {
- switch (constraintType) {
- case MediaConstraintType::SampleRate:
- case MediaConstraintType::SampleSize:
- mediaConstraint = createIntConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
- break;
- case MediaConstraintType::Volume:
- mediaConstraint = createDoubleConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
- break;
- case MediaConstraintType::EchoCancellation:
- mediaConstraint = createBooleanConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
- break;
- case MediaConstraintType::DeviceId:
- case MediaConstraintType::GroupId:
- mediaConstraint = createStringConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
- break;
- default:
- LOG(Media, "parseMediaTrackConstraintSetForKey() - ignoring unsupported constraint '%s' for audio.", name.utf8().data());
- mediaConstraint = nullptr;
- break;
- }
- } else if (sourceType == RealtimeMediaSource::Video) {
- switch (constraintType) {
- case MediaConstraintType::Width:
- case MediaConstraintType::Height:
- mediaConstraint = createIntConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
- break;
- case MediaConstraintType::AspectRatio:
- case MediaConstraintType::FrameRate:
- mediaConstraint = createDoubleConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
- break;
- case MediaConstraintType::FacingMode:
- case MediaConstraintType::DeviceId:
- case MediaConstraintType::GroupId:
- mediaConstraint = createStringConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
- break;
- default:
- LOG(Media, "parseMediaTrackConstraintSetForKey() - ignoring unsupported constraint '%s' for video.", name.utf8().data());
- mediaConstraint = nullptr;
- break;
- }
- }
</del><ins>+ switch (constraintType) {
+ case MediaConstraintType::Width:
+ case MediaConstraintType::Height:
+ case MediaConstraintType::SampleRate:
+ case MediaConstraintType::SampleSize:
+ mediaConstraint = createIntConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
+ break;
</ins><span class="cx">
</span><del>- if (!mediaConstraint)
- return;
</del><ins>+ case MediaConstraintType::AspectRatio:
+ case MediaConstraintType::FrameRate:
+ case MediaConstraintType::Volume:
+ mediaConstraint = createDoubleConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
+ break;
</ins><span class="cx">
</span><ins>+ case MediaConstraintType::EchoCancellation:
+ mediaConstraint = createBooleanConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
+ break;
+
+ case MediaConstraintType::FacingMode:
+ case MediaConstraintType::DeviceId:
+ case MediaConstraintType::GroupId:
+ mediaConstraint = createStringConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
+ break;
+
+ case MediaConstraintType::Unknown:
+ LOG(Media, "parseMediaTrackConstraintSetForKey() - found unsupported constraint '%s'.", name.utf8().data());
+ mediaConstraint = UnknownConstraint::create(name, constraintType);
+ break;
+ }
+
</ins><span class="cx"> map.add(name, WTFMove(mediaConstraint));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static void parseAdvancedConstraints(const Dictionary& mediaTrackConstraints, Vector<MediaTrackConstraintSetMap>& advancedConstraints, RealtimeMediaSource::Type sourceType)
</del><ins>+static void parseAdvancedConstraints(const Dictionary& mediaTrackConstraints, Vector<MediaTrackConstraintSetMap>& advancedConstraints)
</ins><span class="cx"> {
</span><span class="cx"> ArrayValue sequenceOfMediaTrackConstraintSets;
</span><span class="cx"> if (!mediaTrackConstraints.get("advanced", sequenceOfMediaTrackConstraintSets) || sequenceOfMediaTrackConstraintSets.isUndefinedOrNull()) {
</span><span class="lines">@@ -333,7 +317,7 @@
</span><span class="cx"> Vector<String> localKeys;
</span><span class="cx"> mediaTrackConstraintSet.getOwnPropertyNames(localKeys);
</span><span class="cx"> for (auto& localKey : localKeys)
</span><del>- parseMediaTrackConstraintSetForKey(mediaTrackConstraintSet, localKey, map, ConstraintSetType::Advanced, sourceType);
</del><ins>+ parseMediaTrackConstraintSetForKey(mediaTrackConstraintSet, localKey, map, ConstraintSetType::Advanced);
</ins><span class="cx">
</span><span class="cx"> if (!map.isEmpty())
</span><span class="cx"> advancedConstraints.append(WTFMove(map));
</span><span class="lines">@@ -340,7 +324,7 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static void parseConstraints(const Dictionary& mediaTrackConstraints, MediaTrackConstraintSetMap& mandatoryConstraints, Vector<MediaTrackConstraintSetMap>& advancedConstraints, RealtimeMediaSource::Type sourceType)
</del><ins>+void parseMediaConstraintsDictionary(const Dictionary& mediaTrackConstraints, MediaTrackConstraintSetMap& mandatoryConstraints, Vector<MediaTrackConstraintSetMap>& advancedConstraints)
</ins><span class="cx"> {
</span><span class="cx"> if (mediaTrackConstraints.isUndefinedOrNull())
</span><span class="cx"> return;
</span><span class="lines">@@ -350,9 +334,9 @@
</span><span class="cx">
</span><span class="cx"> for (auto& key : keys) {
</span><span class="cx"> if (key == "advanced")
</span><del>- parseAdvancedConstraints(mediaTrackConstraints, advancedConstraints, sourceType);
</del><ins>+ parseAdvancedConstraints(mediaTrackConstraints, advancedConstraints);
</ins><span class="cx"> else
</span><del>- parseMediaTrackConstraintSetForKey(mediaTrackConstraints, key, mandatoryConstraints, ConstraintSetType::Mandatory, sourceType);
</del><ins>+ parseMediaTrackConstraintSetForKey(mediaTrackConstraints, key, mandatoryConstraints, ConstraintSetType::Mandatory);
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -372,7 +356,7 @@
</span><span class="cx">
</span><span class="cx"> Dictionary audioConstraintsDictionary;
</span><span class="cx"> if (constraintsDictionary.get("audio", audioConstraintsDictionary) && !audioConstraintsDictionary.isUndefinedOrNull()) {
</span><del>- parseConstraints(audioConstraintsDictionary, mandatoryAudioConstraints, advancedAudioConstraints, RealtimeMediaSource::Audio);
</del><ins>+ parseMediaConstraintsDictionary(audioConstraintsDictionary, mandatoryAudioConstraints, advancedAudioConstraints);
</ins><span class="cx"> areAudioConstraintsValid = true;
</span><span class="cx"> } else
</span><span class="cx"> constraintsDictionary.get("audio", areAudioConstraintsValid);
</span><span class="lines">@@ -383,7 +367,7 @@
</span><span class="cx">
</span><span class="cx"> Dictionary videoConstraintsDictionary;
</span><span class="cx"> if (constraintsDictionary.get("video", videoConstraintsDictionary) && !videoConstraintsDictionary.isUndefinedOrNull()) {
</span><del>- parseConstraints(videoConstraintsDictionary, mandatoryVideoConstraints, advancedVideoConstraints, RealtimeMediaSource::Video);
</del><ins>+ parseMediaConstraintsDictionary(videoConstraintsDictionary, mandatoryVideoConstraints, advancedVideoConstraints);
</ins><span class="cx"> areVideoConstraintsValid = true;
</span><span class="cx"> } else
</span><span class="cx"> constraintsDictionary.get("video", areVideoConstraintsValid);
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSMediaDevicesCustomh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.h (0 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.h         (rev 0)
+++ trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+/*
+ * Copyright (C) 2016 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.
+ */
+
+#pragma once
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "MediaConstraints.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class Dictionary;
+
+void parseMediaConstraintsDictionary(const Dictionary&, MediaTrackConstraintSetMap&, Vector<MediaTrackConstraintSetMap>&);
+
+}
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSMediaStreamTrackCustomcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSMediaStreamTrackCustom.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSMediaStreamTrackCustom.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/bindings/js/JSMediaStreamTrackCustom.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -28,10 +28,14 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx">
</span><ins>+#include "Dictionary.h"
</ins><span class="cx"> #include "ExceptionCode.h"
</span><span class="cx"> #include "JSDOMBinding.h"
</span><ins>+#include "JSMediaDevicesCustom.h"
+#include "MediaConstraintsImpl.h"
</ins><span class="cx"> #include "MediaSourceSettings.h"
</span><span class="cx"> #include "MediaStreamTrack.h"
</span><ins>+#include "WebCoreJSClientData.h"
</ins><span class="cx"> #include <runtime/JSObject.h>
</span><span class="cx"> #include <runtime/ObjectConstructor.h>
</span><span class="cx">
</span><span class="lines">@@ -57,7 +61,7 @@
</span><span class="cx"> object->putDirect(state.vm(), Identifier::fromString(&state, "width"), jsNumber(settings->width()), DontDelete | ReadOnly);
</span><span class="cx"> if (settings->supportsHeight())
</span><span class="cx"> object->putDirect(state.vm(), Identifier::fromString(&state, "height"), jsNumber(settings->height()), DontDelete | ReadOnly);
</span><del>- if (settings->supportsAspectRatio())
</del><ins>+ if (settings->supportsAspectRatio() && settings->aspectRatio())
</ins><span class="cx"> object->putDirect(state.vm(), Identifier::fromString(&state, "aspectRatio"), jsDoubleNumber(settings->aspectRatio()), DontDelete | ReadOnly);
</span><span class="cx"> if (settings->supportsFrameRate())
</span><span class="cx"> object->putDirect(state.vm(), Identifier::fromString(&state, "frameRate"), jsDoubleNumber(settings->frameRate()), DontDelete | ReadOnly);
</span><span class="lines">@@ -90,8 +94,8 @@
</span><span class="cx"> object->putDirect(state.vm(), Identifier::fromString(&state, "min"), jsNumber(min.asDouble));
</span><span class="cx"> object->putDirect(state.vm(), Identifier::fromString(&state, "max"), jsNumber(max.asDouble));
</span><span class="cx"> } else {
</span><del>- object->putDirect(state.vm(), Identifier::fromString(&state, "min"), jsNumber(min.asULong));
- object->putDirect(state.vm(), Identifier::fromString(&state, "max"), jsNumber(max.asULong));
</del><ins>+ object->putDirect(state.vm(), Identifier::fromString(&state, "min"), jsNumber(min.asInt));
+ object->putDirect(state.vm(), Identifier::fromString(&state, "max"), jsNumber(max.asInt));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> return object;
</span><span class="lines">@@ -100,7 +104,7 @@
</span><span class="cx"> if (value.type() == CapabilityValueOrRange::Double)
</span><span class="cx"> return jsNumber(value.value().asDouble);
</span><span class="cx">
</span><del>- return jsNumber(value.value().asULong);
</del><ins>+ return jsNumber(value.value().asInt);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> JSC::JSValue JSMediaStreamTrack::getCapabilities(ExecState& state)
</span><span class="lines">@@ -162,6 +166,38 @@
</span><span class="cx"> return object;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+JSValue JSMediaStreamTrack::applyConstraints(ExecState& state)
+{
+ MediaTrackConstraintSetMap mandatoryConstraints;
+ Vector<MediaTrackConstraintSetMap> advancedConstraints;
+ bool valid = false;
+
+ if (state.argumentCount() >= 1) {
+ JSValue argument = state.uncheckedArgument(0);
+
+ JSVMClientData& clientData = *static_cast<JSVMClientData*>(state.vm().clientData);
+ putDirect(state.vm(), clientData.builtinNames().mediaStreamTrackConstraintsPrivateName(), argument, DontEnum);
+
+ auto constraintsDictionary = Dictionary(&state, argument);
+ if (!constraintsDictionary.isUndefinedOrNull())
+ parseMediaConstraintsDictionary(constraintsDictionary, mandatoryConstraints, advancedConstraints);
+ valid = !advancedConstraints.isEmpty() || !mandatoryConstraints.isEmpty();
+ }
+
+ JSC::JSPromiseDeferred* promiseDeferred = JSC::JSPromiseDeferred::create(&state, globalObject());
+ auto constraints = MediaConstraintsImpl::create(WTFMove(mandatoryConstraints), WTFMove(advancedConstraints), valid);
+ wrapped().applyConstraints(WTFMove(constraints), DeferredWrapper::create(&state, globalObject(), promiseDeferred));
+
+ return promiseDeferred->promise();
+}
+
+JSValue JSMediaStreamTrack::getConstraints(ExecState& state)
+{
+ JSVMClientData& clientData = *static_cast<JSVMClientData*>(state.vm().clientData);
+ JSValue result = getDirect(state.vm(), clientData.builtinNames().mediaStreamTrackConstraintsPrivateName());
+ return !result.isEmpty() ? result : jsUndefined();
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsWebCoreBuiltinNamesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -58,6 +58,7 @@
</span><span class="cx"> macro(localStreams) \
</span><span class="cx"> macro(makeThisTypeError) \
</span><span class="cx"> macro(makeGetterTypeError) \
</span><ins>+ macro(mediaStreamTrackConstraints) \
</ins><span class="cx"> macro(operations) \
</span><span class="cx"> macro(ownerReadableStream) \
</span><span class="cx"> macro(privateGetStats) \
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -1001,7 +1001,8 @@
</span><span class="cx"> // https://bugs.webkit.org/show_bug.cgi?id=124896
</span><span class="cx">
</span><span class="cx"> m_mediaStreamSrcObject = mediaStream;
</span><del>- setSrc(DOMURL::createPublicURL(context, mediaStream));
</del><ins>+ if (mediaStream)
+ setSrc(DOMURL::createPublicURL(context, mediaStream));
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaStreamAVFObjCmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -312,6 +312,7 @@
</span><span class="cx"> m_playing = true;
</span><span class="cx"> m_haveEverPlayed = true;
</span><span class="cx"> scheduleDeferredTask([this] {
</span><ins>+ updateDisplayMode();
</ins><span class="cx"> updateReadyState();
</span><span class="cx"> });
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamMediaConstraintscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/MediaConstraints.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/MediaConstraints.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/MediaConstraints.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -46,19 +46,19 @@
</span><span class="cx"> case MediaConstraintType::Height:
</span><span class="cx"> case MediaConstraintType::SampleRate:
</span><span class="cx"> case MediaConstraintType::SampleSize:
</span><del>- return IntConstraint::create(constraintType);
</del><ins>+ return IntConstraint::create(name, constraintType);
</ins><span class="cx"> case MediaConstraintType::AspectRatio:
</span><span class="cx"> case MediaConstraintType::FrameRate:
</span><span class="cx"> case MediaConstraintType::Volume:
</span><del>- return DoubleConstraint::create(constraintType);
</del><ins>+ return DoubleConstraint::create(name, constraintType);
</ins><span class="cx"> case MediaConstraintType::EchoCancellation:
</span><del>- return BooleanConstraint::create(constraintType);
</del><ins>+ return BooleanConstraint::create(name, constraintType);
</ins><span class="cx"> case MediaConstraintType::FacingMode:
</span><span class="cx"> case MediaConstraintType::DeviceId:
</span><span class="cx"> case MediaConstraintType::GroupId:
</span><del>- return StringConstraint::create(constraintType);
</del><ins>+ return StringConstraint::create(name, constraintType);
</ins><span class="cx"> case MediaConstraintType::Unknown:
</span><del>- return nullptr;
</del><ins>+ return UnknownConstraint::create(name, constraintType);
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -121,6 +121,21 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+const String& StringConstraint::find(std::function<bool(ConstraintType, const String&)> filter) const
+{
+ for (auto& constraint : m_exact) {
+ if (filter(ConstraintType::ExactConstraint, constraint))
+ return constraint;
+ }
+
+ for (auto& constraint : m_ideal) {
+ if (filter(ConstraintType::IdealConstraint, constraint))
+ return constraint;
+ }
+
+ return emptyString();
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+}
+
</ins><span class="cx"> #endif // ENABLE(MEDIA_STREAM)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamMediaConstraintsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/MediaConstraints.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/MediaConstraints.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/MediaConstraints.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -45,6 +45,8 @@
</span><span class="cx"> public:
</span><span class="cx"> static RefPtr<MediaConstraint> create(const String& name);
</span><span class="cx">
</span><ins>+ enum class ConstraintType { ExactConstraint, IdealConstraint, MinConstraint, MaxConstraint };
+
</ins><span class="cx"> virtual ~MediaConstraint() { };
</span><span class="cx"> virtual bool isEmpty() const = 0;
</span><span class="cx"> virtual bool isMandatory() const = 0;
</span><span class="lines">@@ -53,11 +55,15 @@
</span><span class="cx"> virtual bool getMax(int&) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="cx"> virtual bool getExact(int&) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="cx"> virtual bool getIdeal(int&) const { ASSERT_NOT_REACHED(); return false; }
</span><ins>+ virtual bool validForRange(int, int) const { ASSERT_NOT_REACHED(); return false; }
+ virtual int find(std::function<bool(ConstraintType, int)>) const { ASSERT_NOT_REACHED(); return 0; }
</ins><span class="cx">
</span><span class="cx"> virtual bool getMin(double&) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="cx"> virtual bool getMax(double&) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="cx"> virtual bool getExact(double&) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="cx"> virtual bool getIdeal(double&) const { ASSERT_NOT_REACHED(); return false; }
</span><ins>+ virtual bool validForRange(double, double) const { ASSERT_NOT_REACHED(); return false; }
+ virtual double find(std::function<bool(ConstraintType, double)>) const { ASSERT_NOT_REACHED(); return 0; }
</ins><span class="cx">
</span><span class="cx"> virtual bool getMin(bool&) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="cx"> virtual bool getMax(bool&) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="lines">@@ -68,16 +74,20 @@
</span><span class="cx"> virtual bool getMax(Vector<String>&) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="cx"> virtual bool getExact(Vector<String>&) const { ASSERT_NOT_REACHED(); return false; }
</span><span class="cx"> virtual bool getIdeal(Vector<String>&) const { ASSERT_NOT_REACHED(); return false; }
</span><ins>+ virtual const String& find(std::function<bool(ConstraintType, const String&)>) const { ASSERT_NOT_REACHED(); return emptyString(); }
</ins><span class="cx">
</span><span class="cx"> MediaConstraintType type() const { return m_type; }
</span><ins>+ const String& name() const { return m_name; }
</ins><span class="cx">
</span><span class="cx"> protected:
</span><del>- explicit MediaConstraint(MediaConstraintType type)
- : m_type(type)
</del><ins>+ explicit MediaConstraint(const String& name, MediaConstraintType type)
+ : m_name(name)
+ , m_type(type)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> private:
</span><ins>+ String m_name;
</ins><span class="cx"> MediaConstraintType m_type;
</span><span class="cx"> };
</span><span class="cx">
</span><span class="lines">@@ -124,9 +134,42 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ bool validForRange(ValueType rangeMin, ValueType rangeMax) const final {
+ if (isEmpty())
+ return false;
+
+ if (m_exact && (m_exact.value() < rangeMin || m_exact.value() > rangeMax))
+ return false;
+
+ if (m_min && m_min.value() > rangeMax)
+ return false;
+
+ if (m_max && m_max.value() < rangeMin)
+ return false;
+
+ return true;
+ }
+
+ ValueType find(std::function<bool(ConstraintType, ValueType)> function) const final {
+ if (m_min && function(ConstraintType::MinConstraint, m_min.value()))
+ return m_min.value();
+
+ if (m_max && function(ConstraintType::MaxConstraint, m_max.value()))
+ return m_max.value();
+
+ if (m_exact && function(ConstraintType::ExactConstraint, m_exact.value()))
+ return m_exact.value();
+
+ if (m_ideal && function(ConstraintType::IdealConstraint, m_ideal.value()))
+ return m_ideal.value();
+
+ return 0;
+ }
+
+
</ins><span class="cx"> protected:
</span><del>- explicit NumericConstraint(MediaConstraintType type)
- : MediaConstraint(type)
</del><ins>+ explicit NumericConstraint(const String& name, MediaConstraintType type)
+ : MediaConstraint(name, type)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -139,11 +182,11 @@
</span><span class="cx">
</span><span class="cx"> class IntConstraint final : public NumericConstraint<int> {
</span><span class="cx"> public:
</span><del>- static Ref<IntConstraint> create(MediaConstraintType type) { return adoptRef(*new IntConstraint(type)); }
</del><ins>+ static Ref<IntConstraint> create(const String& name, MediaConstraintType type) { return adoptRef(*new IntConstraint(name, type)); }
</ins><span class="cx">
</span><span class="cx"> private:
</span><del>- explicit IntConstraint(MediaConstraintType type)
- : NumericConstraint<int>(type)
</del><ins>+ explicit IntConstraint(const String& name, MediaConstraintType type)
+ : NumericConstraint<int>(name, type)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> };
</span><span class="lines">@@ -150,11 +193,11 @@
</span><span class="cx">
</span><span class="cx"> class DoubleConstraint final : public NumericConstraint<double> {
</span><span class="cx"> public:
</span><del>- static Ref<DoubleConstraint> create(MediaConstraintType type) { return adoptRef(*new DoubleConstraint(type)); }
</del><ins>+ static Ref<DoubleConstraint> create(const String& name, MediaConstraintType type) { return adoptRef(*new DoubleConstraint(name, type)); }
</ins><span class="cx">
</span><span class="cx"> private:
</span><del>- explicit DoubleConstraint(MediaConstraintType type)
- : NumericConstraint<double>(type)
</del><ins>+ explicit DoubleConstraint(const String& name, MediaConstraintType type)
+ : NumericConstraint<double>(name, type)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> };
</span><span class="lines">@@ -161,7 +204,7 @@
</span><span class="cx">
</span><span class="cx"> class BooleanConstraint final : public MediaConstraint {
</span><span class="cx"> public:
</span><del>- static Ref<BooleanConstraint> create(MediaConstraintType type) { return adoptRef(*new BooleanConstraint(type)); }
</del><ins>+ static Ref<BooleanConstraint> create(const String& name, MediaConstraintType type) { return adoptRef(*new BooleanConstraint(name, type)); }
</ins><span class="cx">
</span><span class="cx"> void setExact(bool value) { m_exact = value; }
</span><span class="cx"> void setIdeal(bool value) { m_ideal = value; }
</span><span class="lines">@@ -173,18 +216,18 @@
</span><span class="cx"> bool isMandatory() const final { return bool(m_exact); }
</span><span class="cx">
</span><span class="cx"> private:
</span><del>- explicit BooleanConstraint(MediaConstraintType type)
- : MediaConstraint(type)
</del><ins>+ explicit BooleanConstraint(const String& name, MediaConstraintType type)
+ : MediaConstraint(name, type)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><del>- Optional<bool> m_exact { false };
- Optional<bool> m_ideal { false };
</del><ins>+ Optional<bool> m_exact;
+ Optional<bool> m_ideal;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> class StringConstraint final : public MediaConstraint {
</span><span class="cx"> public:
</span><del>- static Ref<StringConstraint> create(MediaConstraintType type) { return adoptRef(*new StringConstraint(type)); }
</del><ins>+ static Ref<StringConstraint> create(const String& name, MediaConstraintType type) { return adoptRef(*new StringConstraint(name, type)); }
</ins><span class="cx">
</span><span class="cx"> void setExact(const String&);
</span><span class="cx"> void appendExact(const String&);
</span><span class="lines">@@ -197,9 +240,11 @@
</span><span class="cx"> bool isEmpty() const final { return m_exact.isEmpty() && m_ideal.isEmpty(); }
</span><span class="cx"> bool isMandatory() const final { return !m_exact.isEmpty(); }
</span><span class="cx">
</span><ins>+ const String& find(std::function<bool(ConstraintType, const String&)>) const override;
+
</ins><span class="cx"> private:
</span><del>- explicit StringConstraint(MediaConstraintType type)
- : MediaConstraint(type)
</del><ins>+ explicit StringConstraint(const String& name, MediaConstraintType type)
+ : MediaConstraint(name, type)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -207,6 +252,20 @@
</span><span class="cx"> Vector<String> m_ideal;
</span><span class="cx"> };
</span><span class="cx">
</span><ins>+class UnknownConstraint final : public MediaConstraint {
+public:
+ static Ref<UnknownConstraint> create(const String& name, MediaConstraintType type) { return adoptRef(*new UnknownConstraint(name, type)); }
+
+ bool isEmpty() const final { return true; }
+ bool isMandatory() const final { return false; }
+
+private:
+ explicit UnknownConstraint(const String& name, MediaConstraintType type)
+ : MediaConstraint(name, type)
+ {
+ }
+};
+
</ins><span class="cx"> using MediaTrackConstraintSetMap = HashMap<String, RefPtr<MediaConstraint>>;
</span><span class="cx">
</span><span class="cx"> class MediaConstraints : public RefCounted<MediaConstraints> {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamMediaStreamTrackPrivatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -172,10 +172,9 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void MediaStreamTrackPrivate::applyConstraints(const MediaConstraints&)
</del><ins>+void MediaStreamTrackPrivate::applyConstraints(const MediaConstraints& constraints, RealtimeMediaSource::SuccessHandler successHandler, RealtimeMediaSource::FailureHandler failureHandler)
</ins><span class="cx"> {
</span><del>- // FIXME: apply the new constraints to the track
- // https://bugs.webkit.org/show_bug.cgi?id=122428
</del><ins>+ m_source->applyConstraints(constraints, successHandler, failureHandler);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> AudioSourceProvider* MediaStreamTrackPrivate::audioSourceProvider()
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamMediaStreamTrackPrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -91,7 +91,7 @@
</span><span class="cx"> RefPtr<RealtimeMediaSourceCapabilities> capabilities() const;
</span><span class="cx">
</span><span class="cx"> RefPtr<MediaConstraints> constraints() const;
</span><del>- void applyConstraints(const MediaConstraints&);
</del><ins>+ void applyConstraints(const MediaConstraints&, RealtimeMediaSource::SuccessHandler, RealtimeMediaSource::FailureHandler);
</ins><span class="cx">
</span><span class="cx"> AudioSourceProvider* audioSourceProvider();
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeMediaSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -36,13 +36,18 @@
</span><span class="cx"> #if ENABLE(MEDIA_STREAM)
</span><span class="cx"> #include "RealtimeMediaSource.h"
</span><span class="cx">
</span><ins>+#include "MediaConstraints.h"
+#include "NotImplemented.h"
</ins><span class="cx"> #include "RealtimeMediaSourceCapabilities.h"
</span><span class="cx"> #include "UUID.h"
</span><ins>+#include <wtf/MainThread.h>
+#include <wtf/text/StringHash.h>
</ins><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> RealtimeMediaSource::RealtimeMediaSource(const String& id, Type type, const String& name)
</span><del>- : m_id(id)
</del><ins>+ : m_weakPtrFactory(this)
+ , m_id(id)
</ins><span class="cx"> , m_type(type)
</span><span class="cx"> , m_name(name)
</span><span class="cx"> {
</span><span class="lines">@@ -51,6 +56,7 @@
</span><span class="cx"> if (m_id.isEmpty())
</span><span class="cx"> m_id = createCanonicalUUIDString();
</span><span class="cx"> m_persistentID = m_id;
</span><ins>+ m_suppressNotifications = false;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void RealtimeMediaSource::reset()
</span><span class="lines">@@ -92,8 +98,18 @@
</span><span class="cx">
</span><span class="cx"> void RealtimeMediaSource::settingsDidChange()
</span><span class="cx"> {
</span><del>- for (auto& observer : m_observers)
- observer->sourceSettingsChanged();
</del><ins>+ ASSERT(isMainThread());
+
+ if (m_pendingSettingsDidChangeNotification || m_suppressNotifications)
+ return;
+
+ m_pendingSettingsDidChangeNotification = true;
+
+ scheduleDeferredTask([this] {
+ m_pendingSettingsDidChangeNotification = false;
+ for (auto& observer : m_observers)
+ observer->sourceSettingsChanged();
+ });
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void RealtimeMediaSource::mediaDataUpdated(MediaSample& mediaSample)
</span><span class="lines">@@ -134,6 +150,418 @@
</span><span class="cx"> stop(callingObserver);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+RealtimeMediaSource::ConstraintSupport RealtimeMediaSource::supportsConstraint(const MediaConstraint& constraint)
+{
+ RealtimeMediaSourceCapabilities& capabilities = *this->capabilities();
+
+ switch (constraint.type()) {
+ case MediaConstraintType::Width: {
+ if (!capabilities.supportsWidth())
+ return ConstraintSupport::Ignored;
+
+ auto widthRange = capabilities.width();
+ return constraint.validForRange(widthRange.rangeMin().asInt, widthRange.rangeMax().asInt) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+ break;
+ }
+
+ case MediaConstraintType::Height: {
+ if (!capabilities.supportsHeight())
+ return ConstraintSupport::Ignored;
+
+ auto heightRange = capabilities.height();
+ return constraint.validForRange(heightRange.rangeMin().asInt, heightRange.rangeMax().asInt) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+ break;
+ }
+
+ case MediaConstraintType::FrameRate: {
+ if (!capabilities.supportsFrameRate())
+ return ConstraintSupport::Ignored;
+
+ auto rateRange = capabilities.frameRate();
+ return constraint.validForRange(rateRange.rangeMin().asDouble, rateRange.rangeMax().asDouble) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+ break;
+ }
+
+ case MediaConstraintType::AspectRatio: {
+ if (!capabilities.supportsAspectRatio())
+ return ConstraintSupport::Ignored;
+
+ auto range = capabilities.aspectRatio();
+ return constraint.validForRange(range.rangeMin().asDouble, range.rangeMax().asDouble) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+ break;
+ }
+
+ case MediaConstraintType::Volume: {
+ if (!capabilities.supportsVolume())
+ return ConstraintSupport::Ignored;
+
+ auto range = capabilities.volume();
+ return constraint.validForRange(range.rangeMin().asDouble, range.rangeMax().asDouble) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+ break;
+ }
+
+ case MediaConstraintType::SampleRate: {
+ if (!capabilities.supportsSampleRate())
+ return ConstraintSupport::Ignored;
+
+ auto range = capabilities.sampleRate();
+ return constraint.validForRange(range.rangeMin().asDouble, range.rangeMax().asDouble) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+ break;
+ }
+
+ case MediaConstraintType::SampleSize: {
+ if (!capabilities.supportsSampleSize())
+ return ConstraintSupport::Ignored;
+
+ auto range = capabilities.sampleSize();
+ return constraint.validForRange(range.rangeMin().asDouble, range.rangeMax().asDouble) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+ break;
+ }
+
+ case MediaConstraintType::FacingMode: {
+ if (!capabilities.supportsFacingMode())
+ return ConstraintSupport::Ignored;
+
+ ConstraintSupport support = ConstraintSupport::Ignored;
+ auto& supportedModes = capabilities.facingMode();
+ std::function<bool(MediaConstraint::ConstraintType, const String&)> filter = [supportedModes, &support](MediaConstraint::ConstraintType type, const String& modeString) {
+ if (type == MediaConstraint::ConstraintType::ExactConstraint)
+ support = ConstraintSupport::Unsupported;
+
+ auto mode = RealtimeMediaSourceSettings::videoFacingModeEnum(modeString);
+ for (auto& supportedMode : supportedModes) {
+ if (supportedMode == mode) {
+ support = ConstraintSupport::Supported;
+ break;
+ }
+ }
+
+ return type == MediaConstraint::ConstraintType::ExactConstraint ? true : false;
+ };
+
+ constraint.find(filter);
+ return support;
+ break;
+ }
+
+ case MediaConstraintType::EchoCancellation:
+ if (!capabilities.supportsEchoCancellation())
+ return ConstraintSupport::Ignored;
+
+ if (capabilities.echoCancellation() == RealtimeMediaSourceCapabilities::EchoCancellation::ReadOnly)
+ return constraint.isMandatory() ? ConstraintSupport::Unsupported : ConstraintSupport::Ignored;
+
+ return ConstraintSupport::Supported;
+ break;
+
+ case MediaConstraintType::DeviceId: {
+ if (!capabilities.supportsDeviceId())
+ return ConstraintSupport::Ignored;
+
+ ConstraintSupport support = ConstraintSupport::Ignored;
+ std::function<bool(MediaConstraint::ConstraintType, const String&)> filter = [this, &support](MediaConstraint::ConstraintType type, const String& idString) {
+ if (type != MediaConstraint::ConstraintType::ExactConstraint)
+ return false; // Keep looking.
+
+ support = idString == m_id ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+ return false;
+ };
+
+ constraint.find(filter);
+ return support;
+ break;
+ }
+
+ case MediaConstraintType::GroupId: {
+ if (!capabilities.supportsDeviceId())
+ return ConstraintSupport::Ignored;
+
+ ConstraintSupport support = ConstraintSupport::Ignored;
+ String groupId = settings().groupId();
+ std::function<bool(MediaConstraint::ConstraintType, const String&)> filter = [groupId, &support](MediaConstraint::ConstraintType type, const String& idString) {
+ if (type != MediaConstraint::ConstraintType::ExactConstraint)
+ return false; // Keep looking.
+
+ support = idString == groupId ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
+ return false;
+ };
+
+ constraint.find(filter);
+ return support;
+ break;
+ }
+
+ case MediaConstraintType::Unknown:
+ // Unknown (or unsupported) constraints should be ignored.
+ break;
+ }
+
+ return ConstraintSupport::Ignored;
+}
+
+
+template <typename T>
+T value(const MediaConstraint& constraint, T rangeMin, T rangeMax)
+{
+ T result;
+
+ if (constraint.getExact(result)) {
+ ASSERT(result >= rangeMin && result <= rangeMax);
+ return result;
+ }
+
+ if (constraint.getIdeal(result)) {
+ if (result < rangeMin)
+ result = rangeMin;
+ else if (result > rangeMax)
+ result = rangeMax;
+
+ return result;
+ }
+
+ if (constraint.getMin(result) && result > rangeMax)
+ return false;
+
+ if (constraint.getMax(result) && result < rangeMin)
+ return false;
+
+ return result;
+}
+
+
+void RealtimeMediaSource::applyConstraint(const MediaConstraint& constraint)
+{
+ RealtimeMediaSourceCapabilities& capabilities = *this->capabilities();
+ switch (constraint.type()) {
+ case MediaConstraintType::Width: {
+ if (!capabilities.supportsWidth())
+ return;
+
+ auto widthRange = capabilities.width();
+ setWidth(value(constraint, widthRange.rangeMin().asInt, widthRange.rangeMax().asInt));
+ break;
+ }
+
+ case MediaConstraintType::Height: {
+ if (!capabilities.supportsHeight())
+ return;
+
+ auto heightRange = capabilities.height();
+ setHeight(value(constraint, heightRange.rangeMin().asInt, heightRange.rangeMax().asInt));
+ break;
+ }
+
+ case MediaConstraintType::FrameRate: {
+ if (!capabilities.supportsFrameRate())
+ return;
+
+ auto rateRange = capabilities.frameRate();
+ setFrameRate(value(constraint, rateRange.rangeMin().asDouble, rateRange.rangeMax().asDouble));
+ break;
+ }
+
+ case MediaConstraintType::AspectRatio: {
+ if (!capabilities.supportsAspectRatio())
+ return;
+
+ auto range = capabilities.aspectRatio();
+ setAspectRatio(value(constraint, range.rangeMin().asDouble, range.rangeMax().asDouble));
+ break;
+ }
+
+ case MediaConstraintType::Volume: {
+ if (!capabilities.supportsVolume())
+ return;
+
+ auto range = capabilities.volume();
+ // std::pair<T, T> valuesForRange(constraint, range.rangeMin().asDouble, range.rangeMax().asDouble)
+ setVolume(value(constraint, range.rangeMin().asDouble, range.rangeMax().asDouble));
+ break;
+ }
+
+ case MediaConstraintType::SampleRate: {
+ if (!capabilities.supportsSampleRate())
+ return;
+
+ auto range = capabilities.sampleRate();
+ setSampleRate(value(constraint, range.rangeMin().asDouble, range.rangeMax().asDouble));
+ break;
+ }
+
+ case MediaConstraintType::SampleSize: {
+ if (!capabilities.supportsSampleSize())
+ return;
+
+ auto range = capabilities.sampleSize();
+ setSampleSize(value(constraint, range.rangeMin().asDouble, range.rangeMax().asDouble));
+ break;
+ }
+
+ case MediaConstraintType::EchoCancellation:
+ if (!capabilities.supportsEchoCancellation())
+ return;
+
+ bool setting;
+ if (constraint.getExact(setting) || constraint.getIdeal(setting))
+ setEchoCancellation(setting);
+ break;
+
+ case MediaConstraintType::FacingMode: {
+ if (!capabilities.supportsFacingMode())
+ return;
+
+ auto& supportedModes = capabilities.facingMode();
+ std::function<bool(MediaConstraint::ConstraintType, const String&)> filter = [supportedModes](MediaConstraint::ConstraintType, const String& modeString) {
+ auto mode = RealtimeMediaSourceSettings::videoFacingModeEnum(modeString);
+ for (auto& supportedMode : supportedModes) {
+ if (mode == supportedMode)
+ return true;
+ }
+ return false;
+ };
+
+ auto modeString = constraint.find(filter);
+ if (!modeString.isEmpty())
+ setFacingMode(RealtimeMediaSourceSettings::videoFacingModeEnum(modeString));
+ break;
+ }
+
+ case MediaConstraintType::DeviceId:
+ case MediaConstraintType::GroupId:
+ // There is nothing to do here, neither can be changed.
+ break;
+
+ case MediaConstraintType::Unknown:
+ break;
+ }
+}
+
+void RealtimeMediaSource::applyConstraints(const MediaConstraints& constraints, SuccessHandler successHandler, FailureHandler failureHandler)
+{
+ ASSERT(constraints.isValid());
+
+ auto& mandatoryConstraints = constraints.mandatoryConstraints();
+ for (auto& nameConstraintPair : mandatoryConstraints) {
+ auto& constraint = *nameConstraintPair.value;
+ if (supportsConstraint(constraint) == ConstraintSupport::Unsupported) {
+ failureHandler(constraint.name(), "Constraint not supported");
+ return;
+ }
+ }
+
+ for (auto& nameConstraintPair : mandatoryConstraints)
+ applyConstraint(*nameConstraintPair.value);
+
+ successHandler();
+}
+
+void RealtimeMediaSource::setWidth(int width)
+{
+ if (width == m_size.width())
+ return;
+
+ int height = m_aspectRatio ? width / m_aspectRatio : m_size.height();
+ if (!applySize(IntSize(width, height)))
+ return;
+
+ m_size.setWidth(width);
+ if (m_aspectRatio)
+ m_size.setHeight(width / m_aspectRatio);
+
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::setHeight(int height)
+{
+ if (height == m_size.height())
+ return;
+
+ int width = m_aspectRatio ? height * m_aspectRatio : m_size.width();
+ if (!applySize(IntSize(width, height)))
+ return;
+
+ if (m_aspectRatio)
+ m_size.setWidth(width);
+ m_size.setHeight(height);
+
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::setFrameRate(double rate)
+{
+ if (m_frameRate == rate || !applyFrameRate(rate))
+ return;
+
+ m_frameRate = rate;
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::setAspectRatio(double ratio)
+{
+ if (m_aspectRatio == ratio || !applyAspectRatio(ratio))
+ return;
+
+ m_aspectRatio = ratio;
+ m_size.setHeight(m_size.width() / ratio);
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::setFacingMode(RealtimeMediaSourceSettings::VideoFacingMode mode)
+{
+ if (m_facingMode == mode || !applyFacingMode(mode))
+ return;
+
+ m_facingMode = mode;
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::setVolume(double volume)
+{
+ if (m_volume == volume || !applyVolume(volume))
+ return;
+
+ m_volume = volume;
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::setSampleRate(double rate)
+{
+ if (m_sampleRate == rate || !applySampleRate(rate))
+ return;
+
+ m_sampleRate = rate;
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::setSampleSize(double size)
+{
+ if (m_sampleSize == size || !applySampleSize(size))
+ return;
+
+ m_sampleSize = size;
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::setEchoCancellation(bool echoCancellation)
+{
+ if (m_echoCancellation == echoCancellation || !applyEchoCancellation(echoCancellation))
+ return;
+
+ m_echoCancellation = echoCancellation;
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::scheduleDeferredTask(std::function<void()>&& function)
+{
+ ASSERT(function);
+ callOnMainThread([weakThis = createWeakPtr(), function = WTFMove(function)] {
+ if (!weakThis)
+ return;
+
+ function();
+ });
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(MEDIA_STREAM)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -42,8 +42,10 @@
</span><span class="cx"> #include "MediaSample.h"
</span><span class="cx"> #include "PlatformLayer.h"
</span><span class="cx"> #include "RealtimeMediaSourceCapabilities.h"
</span><ins>+#include <wtf/Lock.h>
</ins><span class="cx"> #include <wtf/RefCounted.h>
</span><span class="cx"> #include <wtf/Vector.h>
</span><ins>+#include <wtf/WeakPtr.h>
</ins><span class="cx"> #include <wtf/text/WTFString.h>
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -50,7 +52,6 @@
</span><span class="cx">
</span><span class="cx"> class FloatRect;
</span><span class="cx"> class GraphicsContext;
</span><del>-class MediaConstraints;
</del><span class="cx"> class MediaStreamPrivate;
</span><span class="cx"> class RealtimeMediaSourceSettings;
</span><span class="cx">
</span><span class="lines">@@ -90,7 +91,12 @@
</span><span class="cx">
</span><span class="cx"> virtual RefPtr<RealtimeMediaSourceCapabilities> capabilities() = 0;
</span><span class="cx"> virtual const RealtimeMediaSourceSettings& settings() = 0;
</span><del>- void settingsDidChange();
</del><ins>+
+ using SuccessHandler = std::function<void()>;
+ using FailureHandler = std::function<void(const String& badConstraint, const String& errorString)>;
+ void applyConstraints(const MediaConstraints&, SuccessHandler, FailureHandler);
+
+ virtual void settingsDidChange();
</ins><span class="cx"> void mediaDataUpdated(MediaSample&);
</span><span class="cx">
</span><span class="cx"> bool stopped() const { return m_stopped; }
</span><span class="lines">@@ -122,23 +128,76 @@
</span><span class="cx"> virtual RefPtr<Image> currentFrameImage() { return nullptr; }
</span><span class="cx"> virtual void paintCurrentFrameInContext(GraphicsContext&, const FloatRect&) { }
</span><span class="cx">
</span><ins>+ void setWidth(int);
+ void setHeight(int);
+ const IntSize& size() const { return m_size; }
+ virtual bool applySize(const IntSize&) { return false; }
+
+ double frameRate() const { return m_frameRate; }
+ void setFrameRate(double);
+ virtual bool applyFrameRate(double) { return false; }
+
+ double aspectRatio() const { return m_aspectRatio; }
+ void setAspectRatio(double);
+ virtual bool applyAspectRatio(double) { return false; }
+
+ RealtimeMediaSourceSettings::VideoFacingMode facingMode() const { return m_facingMode; }
+ void setFacingMode(RealtimeMediaSourceSettings::VideoFacingMode);
+ virtual bool applyFacingMode(RealtimeMediaSourceSettings::VideoFacingMode) { return false; }
+
+ double volume() const { return m_volume; }
+ void setVolume(double);
+ virtual bool applyVolume(double) { return false; }
+
+ double sampleRate() const { return m_sampleRate; }
+ void setSampleRate(double);
+ virtual bool applySampleRate(double) { return false; }
+
+ double sampleSize() const { return m_sampleSize; }
+ void setSampleSize(double);
+ virtual bool applySampleSize(double) { return false; }
+
+ bool echoCancellation() const { return m_echoCancellation; }
+ void setEchoCancellation(bool);
+ virtual bool applyEchoCancellation(bool) { return false; }
+
</ins><span class="cx"> protected:
</span><span class="cx"> RealtimeMediaSource(const String& id, Type, const String& name);
</span><span class="cx">
</span><ins>+ void scheduleDeferredTask(std::function<void()>&&);
+
</ins><span class="cx"> bool m_muted { false };
</span><span class="cx">
</span><span class="cx"> private:
</span><ins>+ WeakPtr<RealtimeMediaSource> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
+
+ enum ConstraintSupport { Ignored, Supported, Unsupported };
+ ConstraintSupport supportsConstraint(const MediaConstraint&);
+ void applyConstraint(const MediaConstraint&);
+
+ WeakPtrFactory<RealtimeMediaSource> m_weakPtrFactory;
+ Lock m_lock;
+
</ins><span class="cx"> String m_id;
</span><span class="cx"> String m_persistentID;
</span><span class="cx"> Type m_type;
</span><span class="cx"> String m_name;
</span><del>- bool m_stopped { false };
</del><span class="cx"> Vector<Observer*> m_observers;
</span><ins>+ IntSize m_size;
+ double m_frameRate { 30 };
+ double m_aspectRatio { 0 };
+ double m_volume { 1 };
+ double m_sampleRate { 0 };
+ double m_sampleSize { 0 };
+ unsigned m_fitnessScore { 0 };
+ RealtimeMediaSourceSettings::VideoFacingMode m_facingMode { RealtimeMediaSourceSettings::User};
</ins><span class="cx">
</span><ins>+ bool m_echoCancellation { false };
+ bool m_stopped { false };
</ins><span class="cx"> bool m_readonly { false };
</span><span class="cx"> bool m_remote { false };
</span><del>-
- unsigned m_fitnessScore { 0 };
</del><ins>+ bool m_pendingSettingsDidChangeNotification { false };
+ bool m_suppressNotifications { true };
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceCapabilitiesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCapabilities.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCapabilities.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCapabilities.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -48,7 +48,7 @@
</span><span class="cx"> Type type() const { return m_type; }
</span><span class="cx">
</span><span class="cx"> union ValueUnion {
</span><del>- unsigned long asULong;
</del><ins>+ int asInt;
</ins><span class="cx"> double asDouble;
</span><span class="cx"> };
</span><span class="cx">
</span><span class="lines">@@ -63,10 +63,10 @@
</span><span class="cx"> m_minOrValue.asDouble = value;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- CapabilityValueOrRange(unsigned long value)
</del><ins>+ CapabilityValueOrRange(int value)
</ins><span class="cx"> : m_type(ULong)
</span><span class="cx"> {
</span><del>- m_minOrValue.asULong = value;
</del><ins>+ m_minOrValue.asInt = value;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> CapabilityValueOrRange(double min, double max)
</span><span class="lines">@@ -76,11 +76,11 @@
</span><span class="cx"> m_max.asDouble = max;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- CapabilityValueOrRange(unsigned long min, unsigned long max)
</del><ins>+ CapabilityValueOrRange(int min, int max)
</ins><span class="cx"> : m_type(ULongRange)
</span><span class="cx"> {
</span><del>- m_minOrValue.asULong = min;
- m_max.asULong = max;
</del><ins>+ m_minOrValue.asInt = min;
+ m_max.asInt = max;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> const ValueUnion& rangeMin() const
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceSettingscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -37,22 +37,40 @@
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><del>-const AtomicString& RealtimeMediaSourceSettings::facingMode(RealtimeMediaSourceSettings::VideoFacingMode mode)
</del><ins>+static const AtomicString& userFacing()
</ins><span class="cx"> {
</span><span class="cx"> static NeverDestroyed<AtomicString> userFacing("user", AtomicString::ConstructFromLiteral);
</span><ins>+ return userFacing;
+}
+static const AtomicString& environmentFacing()
+{
</ins><span class="cx"> static NeverDestroyed<AtomicString> environmentFacing("environment", AtomicString::ConstructFromLiteral);
</span><ins>+ return environmentFacing;
+}
+
+static const AtomicString& leftFacing()
+{
</ins><span class="cx"> static NeverDestroyed<AtomicString> leftFacing("left", AtomicString::ConstructFromLiteral);
</span><ins>+ return leftFacing;
+}
+
+static const AtomicString& rightFacing()
+{
</ins><span class="cx"> static NeverDestroyed<AtomicString> rightFacing("right", AtomicString::ConstructFromLiteral);
</span><del>-
</del><ins>+ return rightFacing;
+}
+
+const AtomicString& RealtimeMediaSourceSettings::facingMode(RealtimeMediaSourceSettings::VideoFacingMode mode)
+{
</ins><span class="cx"> switch (mode) {
</span><span class="cx"> case RealtimeMediaSourceSettings::User:
</span><del>- return userFacing;
</del><ins>+ return userFacing();
</ins><span class="cx"> case RealtimeMediaSourceSettings::Environment:
</span><del>- return environmentFacing;
</del><ins>+ return environmentFacing();
</ins><span class="cx"> case RealtimeMediaSourceSettings::Left:
</span><del>- return leftFacing;
</del><ins>+ return leftFacing();
</ins><span class="cx"> case RealtimeMediaSourceSettings::Right:
</span><del>- return rightFacing;
</del><ins>+ return rightFacing();
</ins><span class="cx"> case RealtimeMediaSourceSettings::Unknown:
</span><span class="cx"> return emptyAtom;
</span><span class="cx"> }
</span><span class="lines">@@ -61,6 +79,20 @@
</span><span class="cx"> return emptyAtom;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+RealtimeMediaSourceSettings::VideoFacingMode RealtimeMediaSourceSettings::videoFacingModeEnum(const String& mode)
+{
+ if (mode == userFacing())
+ return RealtimeMediaSourceSettings::User;
+ if (mode == environmentFacing())
+ return RealtimeMediaSourceSettings::Environment;
+ if (mode == leftFacing())
+ return RealtimeMediaSourceSettings::Left;
+ if (mode == rightFacing())
+ return RealtimeMediaSourceSettings::Right;
+
+ return RealtimeMediaSourceSettings::Unknown;
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(MEDIA_STREAM)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreamRealtimeMediaSourceSettingsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -42,6 +42,8 @@
</span><span class="cx">
</span><span class="cx"> static const AtomicString& facingMode(RealtimeMediaSourceSettings::VideoFacingMode);
</span><span class="cx">
</span><ins>+ static RealtimeMediaSourceSettings::VideoFacingMode videoFacingModeEnum(const String&);
+
</ins><span class="cx"> explicit RealtimeMediaSourceSettings()
</span><span class="cx"> {
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVAudioCaptureSourcemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.mm (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.mm        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.mm        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -80,7 +80,7 @@
</span><span class="cx"> void AVAudioCaptureSource::initializeCapabilities(RealtimeMediaSourceCapabilities& capabilities)
</span><span class="cx"> {
</span><span class="cx"> // FIXME: finish this implementation - https://webkit.org/b/122430
</span><del>- capabilities.setVolume(CapabilityValueOrRange(0, 1.0));
</del><ins>+ capabilities.setVolume(CapabilityValueOrRange(0.0, 1.0));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void AVAudioCaptureSource::initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints& supportedConstraints)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVMediaCaptureSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -33,7 +33,6 @@
</span><span class="cx"> #include "Timer.h"
</span><span class="cx"> #include <wtf/Function.h>
</span><span class="cx"> #include <wtf/RetainPtr.h>
</span><del>-#include <wtf/WeakPtr.h>
</del><span class="cx">
</span><span class="cx"> OBJC_CLASS AVCaptureAudioDataOutput;
</span><span class="cx"> OBJC_CLASS AVCaptureConnection;
</span><span class="lines">@@ -63,8 +62,6 @@
</span><span class="cx"> void stopProducingData() override;
</span><span class="cx"> bool isProducingData() const override { return m_isRunning; }
</span><span class="cx">
</span><del>- WeakPtr<AVMediaCaptureSource> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
-
</del><span class="cx"> protected:
</span><span class="cx"> AVMediaCaptureSource(AVCaptureDevice*, const AtomicString&, RealtimeMediaSource::Type, PassRefPtr<MediaConstraints>);
</span><span class="cx">
</span><span class="lines">@@ -86,8 +83,6 @@
</span><span class="cx"> void setVideoSampleBufferDelegate(AVCaptureVideoDataOutput*);
</span><span class="cx"> void setAudioSampleBufferDelegate(AVCaptureAudioDataOutput*);
</span><span class="cx">
</span><del>- void scheduleDeferredTask(Function<void ()>&&);
-
</del><span class="cx"> private:
</span><span class="cx"> void setupSession();
</span><span class="cx"> void reset() override;
</span><span class="lines">@@ -94,7 +89,6 @@
</span><span class="cx">
</span><span class="cx"> RealtimeMediaSourceSettings m_currentSettings;
</span><span class="cx"> RealtimeMediaSourceSupportedConstraints m_supportedConstraints;
</span><del>- WeakPtrFactory<AVMediaCaptureSource> m_weakPtrFactory;
</del><span class="cx"> RetainPtr<WebCoreAVMediaCaptureSourceObserver> m_objcObserver;
</span><span class="cx"> RefPtr<MediaConstraints> m_constraints;
</span><span class="cx"> RefPtr<RealtimeMediaSourceCapabilities> m_capabilities;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVMediaCaptureSourcemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -124,7 +124,6 @@
</span><span class="cx">
</span><span class="cx"> AVMediaCaptureSource::AVMediaCaptureSource(AVCaptureDeviceTypedef* device, const AtomicString& id, RealtimeMediaSource::Type type, PassRefPtr<MediaConstraints> constraints)
</span><span class="cx"> : RealtimeMediaSource(id, type, emptyString())
</span><del>- , m_weakPtrFactory(this)
</del><span class="cx"> , m_objcObserver(adoptNS([[WebCoreAVMediaCaptureSourceObserver alloc] initWithCallback:this]))
</span><span class="cx"> , m_constraints(constraints)
</span><span class="cx"> , m_device(device)
</span><span class="lines">@@ -239,17 +238,6 @@
</span><span class="cx"> [audioOutput setSampleBufferDelegate:m_objcObserver.get() queue:globaAudioCaptureSerialQueue()];
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void AVMediaCaptureSource::scheduleDeferredTask(Function<void ()>&& function)
-{
- ASSERT(function);
- callOnMainThread([weakThis = createWeakPtr(), function = WTFMove(function)] {
- if (!weakThis)
- return;
-
- function();
- });
-}
-
</del><span class="cx"> AudioSourceProvider* AVMediaCaptureSource::audioSourceProvider()
</span><span class="cx"> {
</span><span class="cx"> ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVVideoCaptureSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -57,10 +57,12 @@
</span><span class="cx">
</span><span class="cx"> void updateSettings(RealtimeMediaSourceSettings&) override;
</span><span class="cx">
</span><ins>+ bool applySize(const IntSize&) override;
+ bool applyFrameRate(double) override;
+
</ins><span class="cx"> void initializeCapabilities(RealtimeMediaSourceCapabilities&) override;
</span><span class="cx"> void initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints&) override;
</span><span class="cx">
</span><del>- bool applyConstraints(MediaConstraints*);
</del><span class="cx"> bool setFrameRateConstraint(double minFrameRate, double maxFrameRate);
</span><span class="cx">
</span><span class="cx"> bool updateFramerate(CMSampleBufferRef);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmediastreammacAVVideoCaptureSourcemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -128,91 +128,64 @@
</span><span class="cx"> settings.setAspectRatio(static_cast<float>(m_width) / m_height);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-bool AVVideoCaptureSource::setFrameRateConstraint(double minFrameRate, double maxFrameRate)
</del><ins>+bool AVVideoCaptureSource::applySize(const IntSize& size)
</ins><span class="cx"> {
</span><del>- AVFrameRateRange *bestFrameRateRange = 0;
-
- for (AVFrameRateRange *frameRateRange in [[device() activeFormat] videoSupportedFrameRateRanges]) {
- if (!maxFrameRate) {
- if (minFrameRate == [frameRateRange minFrameRate])
- bestFrameRateRange = frameRateRange;
- } else if (minFrameRate >= [frameRateRange minFrameRate] && maxFrameRate <= [frameRateRange maxFrameRate]) {
- if (CMTIME_COMPARE_INLINE([frameRateRange minFrameDuration], >, [bestFrameRateRange minFrameDuration]))
- bestFrameRateRange = frameRateRange;
- }
- }
-
- if (!bestFrameRateRange) {
- LOG(Media, "AVVideoCaptureSource::setFrameRateConstraint(%p), frame rate range %f..%f not supported by video device", this, minFrameRate, maxFrameRate);
</del><ins>+ NSString *preset = AVCaptureSessionInfo(session()).bestSessionPresetForVideoDimensions(size.width(), size.height());
+ if (!preset || ![session() canSetSessionPreset:preset]) {
+ LOG(Media, "AVVideoCaptureSource::applySize%p), unable find or set preset for width: %i, height: %i", this, size.width(), size.height());
</ins><span class="cx"> return false;
</span><span class="cx"> }
</span><del>-
</del><ins>+
</ins><span class="cx"> NSError *error = nil;
</span><span class="cx"> @try {
</span><del>- if ([device() lockForConfiguration:&error]) {
- [device() setActiveVideoMinFrameDuration:[bestFrameRateRange minFrameDuration]];
- if (maxFrameRate)
- [device() setActiveVideoMaxFrameDuration:[bestFrameRateRange maxFrameDuration]];
- [device() unlockForConfiguration];
- }
</del><ins>+ [session() setSessionPreset:preset];
+
</ins><span class="cx"> } @catch(NSException *exception) {
</span><del>- LOG(Media, "AVVideoCaptureSource::setFrameRateConstraint(%p), exception thrown configuring device: <%s> %s", this, [[exception name] UTF8String], [[exception reason] UTF8String]);
</del><ins>+ LOG(Media, "AVVideoCaptureSource::applySize(%p), exception thrown configuring device: <%s> %s", this, [[exception name] UTF8String], [[exception reason] UTF8String]);
</ins><span class="cx"> return false;
</span><span class="cx"> }
</span><del>-
</del><ins>+
</ins><span class="cx"> if (error) {
</span><del>- LOG(Media, "AVVideoCaptureSource::setFrameRateConstraint(%p), failed to lock video device for configuration: %s", this, [[error localizedDescription] UTF8String]);
</del><ins>+ LOG(Media, "AVVideoCaptureSource::applySize(%p), failed to lock video device for configuration: %s", this, [[error localizedDescription] UTF8String]);
</ins><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- LOG(Media, "AVVideoCaptureSource::setFrameRateConstraint(%p) - set frame rate range to %f..%f", this, minFrameRate, maxFrameRate);
</del><ins>+ LOG(Media, "AVVideoCaptureSource::applySize(%p) - set frame size to %i x %i", this, size.width(), size.height());
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-bool AVVideoCaptureSource::applyConstraints(MediaConstraints* constraints)
</del><ins>+bool AVVideoCaptureSource::applyFrameRate(double rate)
</ins><span class="cx"> {
</span><del>- ASSERT(constraints);
</del><ins>+ AVFrameRateRange *bestFrameRateRange = 0;
+ for (AVFrameRateRange *frameRateRange in [[device() activeFormat] videoSupportedFrameRateRanges]) {
+ if (rate >= [frameRateRange minFrameRate] && rate <= [frameRateRange maxFrameRate]) {
+ if (!bestFrameRateRange || CMTIME_COMPARE_INLINE([frameRateRange minFrameDuration], >, [bestFrameRateRange minFrameDuration]))
+ bestFrameRateRange = frameRateRange;
+ }
+ }
</ins><span class="cx">
</span><del>- // FIXME: Below needs to be refactored for https://bugs.webkit.org/show_bug.cgi?id=160579.
</del><ins>+ if (!bestFrameRateRange) {
+ LOG(Media, "AVVideoCaptureSource::applyFrameRate(%p), frame rate %f not supported by video device", this, rate);
+ return false;
+ }
</ins><span class="cx">
</span><del>- auto& mandatoryConstraints = constraints->mandatoryConstraints();
- int intValue;
-
- String widthConstraintName = RealtimeMediaSourceSupportedConstraints::nameForConstraint(MediaConstraintType::Width);
- auto widthConstraint = mandatoryConstraints.get(widthConstraintName);
- Optional<int> width;
- if (widthConstraint && widthConstraint->getExact(intValue))
- width = intValue;
-
- String heightConstraintName = RealtimeMediaSourceSupportedConstraints::nameForConstraint(MediaConstraintType::Height);
- auto heightConstraint = mandatoryConstraints.get(heightConstraintName);
- Optional<int> height;
- if (heightConstraint && heightConstraint->getExact(intValue))
- height = intValue;
-
- if (width && height) {
- NSString *preset = AVCaptureSessionInfo(session()).bestSessionPresetForVideoDimensions(width.value(), height.value());
- if (!preset || ![session() canSetSessionPreset:preset]) {
- LOG(Media, "AVVideoCaptureSource::applyConstraints(%p), unable find or set preset for width: %i, height: %i", this, width.value(), height.value());
- return false;
</del><ins>+ NSError *error = nil;
+ @try {
+ if ([device() lockForConfiguration:&error]) {
+ [device() setActiveVideoMinFrameDuration:[bestFrameRateRange minFrameDuration]];
+ [device() unlockForConfiguration];
</ins><span class="cx"> }
</span><del>-
- [session() setSessionPreset:preset];
</del><ins>+ } @catch(NSException *exception) {
+ LOG(Media, "AVVideoCaptureSource::applyFrameRate(%p), exception thrown configuring device: <%s> %s", this, [[exception name] UTF8String], [[exception reason] UTF8String]);
+ return false;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- String frameRateConstraintName = RealtimeMediaSourceSupportedConstraints::nameForConstraint(MediaConstraintType::FrameRate);
- auto frameRateConstraint = mandatoryConstraints.get(frameRateConstraintName);
-
- Optional<double> frameRate;
- double doubleValue;
- if (frameRateConstraint && frameRateConstraint->getExact(doubleValue))
- frameRate = doubleValue;
-
- if (frameRate && !setFrameRateConstraint(frameRate.value(), 0)) {
- LOG(Media, "AVVideoCaptureSource::applyConstraints(%p), unable set frame rate to %f", this, frameRate.value());
</del><ins>+ if (error) {
+ LOG(Media, "AVVideoCaptureSource::applyFrameRate(%p), failed to lock video device for configuration: %s", this, [[error localizedDescription] UTF8String]);
</ins><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ LOG(Media, "AVVideoCaptureSource::applyFrameRate(%p) - set frame rate range to %f", this, rate);
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -227,9 +200,6 @@
</span><span class="cx">
</span><span class="cx"> [session() addInput:videoIn.get()];
</span><span class="cx">
</span><del>- if (constraints())
- applyConstraints(constraints());
-
</del><span class="cx"> RetainPtr<AVCaptureVideoDataOutputType> videoOutput = adoptNS([allocAVCaptureVideoDataOutputInstance() init]);
</span><span class="cx"> RetainPtr<NSDictionary> settingsDictionary = adoptNS([[NSDictionary alloc] initWithObjectsAndKeys:
</span><span class="cx"> [NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockMockRealtimeAudioSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -59,12 +59,13 @@
</span><span class="cx">
</span><span class="cx"> void MockRealtimeAudioSource::updateSettings(RealtimeMediaSourceSettings& settings)
</span><span class="cx"> {
</span><del>- settings.setVolume(50);
</del><ins>+ settings.setVolume(volume());
+ settings.setEchoCancellation(echoCancellation());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void MockRealtimeAudioSource::initializeCapabilities(RealtimeMediaSourceCapabilities& capabilities)
</span><span class="cx"> {
</span><del>- capabilities.setVolume(CapabilityValueOrRange(0, 1.0));
</del><ins>+ capabilities.setVolume(CapabilityValueOrRange(0.0, 1.0));
</ins><span class="cx"> capabilities.setEchoCancellation(RealtimeMediaSourceCapabilities::EchoCancellation::ReadWrite);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockMockRealtimeAudioSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -51,6 +51,12 @@
</span><span class="cx"> MockRealtimeAudioSource(const String& name = ASCIILiteral("Mock audio device"));
</span><span class="cx">
</span><span class="cx"> private:
</span><ins>+
+ bool applyVolume(double) override { return true; }
+ bool applySampleRate(double) override { return true; }
+ bool applySampleSize(double) override { return true; }
+ bool applyEchoCancellation(bool) override { return true; }
+
</ins><span class="cx"> void updateSettings(RealtimeMediaSourceSettings&) override;
</span><span class="cx"> void initializeCapabilities(RealtimeMediaSourceCapabilities&) override;
</span><span class="cx"> void initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints&) override;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockMockRealtimeMediaSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -124,7 +124,6 @@
</span><span class="cx"> return m_supportedConstraints;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(MEDIA_STREAM)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockMockRealtimeMediaSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -37,8 +37,6 @@
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><del>-class FloatRect;
-class GraphicsContext;
</del><span class="cx"> class TrackSourceInfo;
</span><span class="cx">
</span><span class="cx"> class MockRealtimeMediaSource : public RealtimeMediaSource {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockMockRealtimeVideoSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -65,6 +65,7 @@
</span><span class="cx"> : MockRealtimeMediaSource(createCanonicalUUIDString(), RealtimeMediaSource::Video, name)
</span><span class="cx"> , m_timer(RunLoop::current(), this, &MockRealtimeVideoSource::generateFrame)
</span><span class="cx"> {
</span><ins>+ setFrameRate(30);
</ins><span class="cx"> m_dashWidths.reserveInitialCapacity(2);
</span><span class="cx"> m_dashWidths.uncheckedAppend(6);
</span><span class="cx"> m_dashWidths.uncheckedAppend(6);
</span><span class="lines">@@ -73,11 +74,13 @@
</span><span class="cx"> void MockRealtimeVideoSource::startProducingData()
</span><span class="cx"> {
</span><span class="cx"> MockRealtimeMediaSource::startProducingData();
</span><del>- if (m_size.isEmpty())
- setSize(IntSize(640, 480));
</del><ins>+ if (size().isEmpty()) {
+ setWidth(640);
+ setHeight(480);
+ }
</ins><span class="cx">
</span><span class="cx"> m_startTime = monotonicallyIncreasingTime();
</span><del>- m_timer.startRepeating(std::chrono::milliseconds(lround(1000 / m_frameRate)));
</del><ins>+ m_timer.startRepeating(std::chrono::milliseconds(lround(1000 / frameRate())));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void MockRealtimeVideoSource::stopProducingData()
</span><span class="lines">@@ -98,11 +101,13 @@
</span><span class="cx">
</span><span class="cx"> void MockRealtimeVideoSource::updateSettings(RealtimeMediaSourceSettings& settings)
</span><span class="cx"> {
</span><del>- settings.setFacingMode(RealtimeMediaSourceSettings::User);
- settings.setFrameRate(m_frameRate);
- settings.setWidth(m_size.width());
- settings.setHeight(m_size.height());
- settings.setAspectRatio(static_cast<float>(m_size.width()) / m_size.height());
</del><ins>+ settings.setFacingMode(facingMode());
+ settings.setFrameRate(frameRate());
+ IntSize size = this->size();
+ settings.setWidth(size.width());
+ settings.setHeight(size.height());
+ if (aspectRatio())
+ settings.setAspectRatio(aspectRatio());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void MockRealtimeVideoSource::initializeCapabilities(RealtimeMediaSourceCapabilities& capabilities)
</span><span class="lines">@@ -109,8 +114,8 @@
</span><span class="cx"> {
</span><span class="cx"> capabilities.addFacingMode(RealtimeMediaSourceSettings::User);
</span><span class="cx"> capabilities.addFacingMode(RealtimeMediaSourceSettings::Environment);
</span><del>- capabilities.setWidth(CapabilityValueOrRange(320UL, 1920UL));
- capabilities.setHeight(CapabilityValueOrRange(240UL, 1080UL));
</del><ins>+ capabilities.setWidth(CapabilityValueOrRange(320, 1920));
+ capabilities.setHeight(CapabilityValueOrRange(240, 1080));
</ins><span class="cx"> capabilities.setFrameRate(CapabilityValueOrRange(15.0, 60.0));
</span><span class="cx"> capabilities.setAspectRatio(CapabilityValueOrRange(4 / 3.0, 16 / 9.0));
</span><span class="cx"> }
</span><span class="lines">@@ -124,26 +129,19 @@
</span><span class="cx"> supportedConstraints.setSupportsFacingMode(true);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void MockRealtimeVideoSource::setFrameRate(float rate)
</del><ins>+bool MockRealtimeVideoSource::applyFrameRate(double rate)
</ins><span class="cx"> {
</span><del>- if (m_frameRate == rate)
- return;
-
- m_frameRate = rate;
</del><span class="cx"> if (m_timer.isActive())
</span><del>- m_timer.startRepeating(std::chrono::milliseconds(lround(1000 / m_frameRate)));
</del><ins>+ m_timer.startRepeating(std::chrono::milliseconds(lround(1000 / rate)));
</ins><span class="cx">
</span><del>- settingsDidChange();
</del><ins>+ updatePlatformLayer();
+ updateSampleBuffer();
+ return true;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void MockRealtimeVideoSource::setSize(const IntSize& size)
</del><ins>+bool MockRealtimeVideoSource::applySize(const IntSize& size)
</ins><span class="cx"> {
</span><del>- if (size == m_size)
- return;
-
- m_size = size;
-
- m_baseFontSize = m_size.height() * .08;
</del><ins>+ m_baseFontSize = size.height() * .08;
</ins><span class="cx"> FontCascadeDescription fontDescription;
</span><span class="cx"> fontDescription.setOneFamily("Courier");
</span><span class="cx"> fontDescription.setSpecifiedSize(m_baseFontSize);
</span><span class="lines">@@ -168,13 +166,13 @@
</span><span class="cx"> m_imageBuffer = nullptr;
</span><span class="cx"> updatePlatformLayer();
</span><span class="cx">
</span><del>- settingsDidChange();
</del><ins>+ return true;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void MockRealtimeVideoSource::drawAnimation(GraphicsContext& context)
</span><span class="cx"> {
</span><del>- float radius = m_size.width() * .09;
- FloatPoint location(m_size.width() * .8, m_size.height() * .3);
</del><ins>+ float radius = size().width() * .09;
+ FloatPoint location(size().width() * .8, size().height() * .3);
</ins><span class="cx">
</span><span class="cx"> m_path.clear();
</span><span class="cx"> m_path.moveTo(location);
</span><span class="lines">@@ -184,7 +182,7 @@
</span><span class="cx"> context.setFillRule(RULE_NONZERO);
</span><span class="cx"> context.fillPath(m_path);
</span><span class="cx">
</span><del>- float endAngle = piFloat * (((fmod(m_frameNumber, m_frameRate) + 0.5) * (2.0 / m_frameRate)) + 1);
</del><ins>+ float endAngle = piFloat * (((fmod(m_frameNumber, frameRate()) + 0.5) * (2.0 / frameRate())) + 1);
</ins><span class="cx"> m_path.clear();
</span><span class="cx"> m_path.moveTo(location);
</span><span class="cx"> m_path.addArc(location, radius, 1.5 * piFloat, endAngle, false);
</span><span class="lines">@@ -202,11 +200,12 @@
</span><span class="cx"> static const RGBA32 red = 0xffff0000;
</span><span class="cx"> static const RGBA32 green = 0xff008000;
</span><span class="cx">
</span><del>- float boxSize = m_size.width() * .035;
- float boxTop = m_size.height() * .6;
</del><ins>+ IntSize size = this->size();
+ float boxSize = size.width() * .035;
+ float boxTop = size.height() * .6;
</ins><span class="cx">
</span><span class="cx"> m_path.clear();
</span><del>- FloatRect frameRect(2, 2, m_size.width() - 3, m_size.height() - 3);
</del><ins>+ FloatRect frameRect(2, 2, size.width() - 3, size.height() - 3);
</ins><span class="cx"> context.setStrokeColor(Color::white);
</span><span class="cx"> context.setStrokeThickness(3);
</span><span class="cx"> context.setLineDash(m_dashWidths, 0);
</span><span class="lines">@@ -217,7 +216,7 @@
</span><span class="cx"> context.setLineDash(DashArray(), 0);
</span><span class="cx"> m_path.clear();
</span><span class="cx"> m_path.moveTo(FloatPoint(0, boxTop + boxSize));
</span><del>- m_path.addLineTo(FloatPoint(m_size.width(), boxTop + boxSize));
</del><ins>+ m_path.addLineTo(FloatPoint(size.width(), boxTop + boxSize));
</ins><span class="cx"> m_path.closeSubpath();
</span><span class="cx"> context.setStrokeColor(Color::white);
</span><span class="cx"> context.setStrokeThickness(2);
</span><span class="lines">@@ -264,7 +263,8 @@
</span><span class="cx"> unsigned minutes = seconds / 60 % 60;
</span><span class="cx"> unsigned hours = minutes / 60 % 60;
</span><span class="cx">
</span><del>- FloatPoint timeLocation(m_size.width() * .05, m_size.height() * .15);
</del><ins>+ IntSize size = this->size();
+ FloatPoint timeLocation(size.width() * .05, size.height() * .15);
</ins><span class="cx"> context.setFillColor(Color::white);
</span><span class="cx"> context.setTextDrawingMode(TextModeFill);
</span><span class="cx"> String string = String::format("%02u:%02u:%02u.%03u", hours, minutes, seconds, milliseconds % 1000);
</span><span class="lines">@@ -274,16 +274,16 @@
</span><span class="cx"> timeLocation.move(0, m_baseFontSize);
</span><span class="cx"> context.drawText(m_timeFont, TextRun((StringView(string))), timeLocation);
</span><span class="cx">
</span><del>- FloatPoint statsLocation(m_size.width() * .65, m_size.height() * .75);
- string = String::format("Frame rate: %ufps", m_frameRate);
</del><ins>+ FloatPoint statsLocation(size.width() * .65, size.height() * .75);
+ string = String::format("Frame rate: %ffps", frameRate());
</ins><span class="cx"> context.drawText(m_statsFont, TextRun((StringView(string))), statsLocation);
</span><span class="cx">
</span><del>- string = String::format("Size: %u x %u", m_size.width(), m_size.height());
</del><ins>+ string = String::format("Size: %u x %u", size.width(), size.height());
</ins><span class="cx"> statsLocation.move(0, m_statsFontSize);
</span><span class="cx"> context.drawText(m_statsFont, TextRun((StringView(string))), statsLocation);
</span><span class="cx">
</span><span class="cx"> const char* camera;
</span><del>- switch (settings().facingMode()) {
</del><ins>+ switch (facingMode()) {
</ins><span class="cx"> case RealtimeMediaSourceSettings::User:
</span><span class="cx"> camera = "User facing";
</span><span class="cx"> break;
</span><span class="lines">@@ -304,7 +304,7 @@
</span><span class="cx"> statsLocation.move(0, m_statsFontSize);
</span><span class="cx"> context.drawText(m_statsFont, TextRun((StringView(string))), statsLocation);
</span><span class="cx">
</span><del>- FloatPoint bipBopLocation(m_size.width() * .6, m_size.height() * .6);
</del><ins>+ FloatPoint bipBopLocation(size.width() * .6, size.height() * .6);
</ins><span class="cx"> unsigned frameMod = m_frameNumber % 60;
</span><span class="cx"> if (frameMod <= 15) {
</span><span class="cx"> context.setFillColor(Color::gray);
</span><span class="lines">@@ -319,11 +319,16 @@
</span><span class="cx">
</span><span class="cx"> void MockRealtimeVideoSource::generateFrame()
</span><span class="cx"> {
</span><del>- GraphicsContext& context = imageBuffer()->context();
</del><ins>+ ImageBuffer* buffer = imageBuffer();
+ if (!buffer)
+ return;
+
+ GraphicsContext& context = buffer->context();
</ins><span class="cx"> GraphicsContextStateSaver stateSaver(context);
</span><span class="cx">
</span><del>- FloatRect frameRect(FloatPoint(), m_size);
- context.fillRect(FloatRect(FloatPoint(), m_size), Color::black);
</del><ins>+ IntSize size = this->size();
+ FloatRect frameRect(FloatPoint(), size);
+ context.fillRect(FloatRect(FloatPoint(), size), Color::black);
</ins><span class="cx">
</span><span class="cx"> drawText(context);
</span><span class="cx"> drawAnimation(context);
</span><span class="lines">@@ -338,7 +343,7 @@
</span><span class="cx"> if (m_imageBuffer)
</span><span class="cx"> return m_imageBuffer.get();
</span><span class="cx">
</span><del>- m_imageBuffer = ImageBuffer::create(m_size, Unaccelerated);
</del><ins>+ m_imageBuffer = ImageBuffer::create(size(), Unaccelerated);
</ins><span class="cx"> if (!m_imageBuffer)
</span><span class="cx"> return nullptr;
</span><span class="cx">
</span><span class="lines">@@ -368,7 +373,6 @@
</span><span class="cx"> return m_imageBuffer->copyImage(DontCopyBackingStore);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(MEDIA_STREAM)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmockMockRealtimeVideoSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.h (205347 => 205348)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.h        2016-09-02 17:28:00 UTC (rev 205347)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.h        2016-09-02 17:36:29 UTC (rev 205348)
</span><span class="lines">@@ -51,11 +51,6 @@
</span><span class="cx">
</span><span class="cx"> virtual ~MockRealtimeVideoSource() { }
</span><span class="cx">
</span><del>- void setSize(const IntSize&);
- const IntSize& size() const { return m_size; }
-
- void setFrameRate(float);
-
</del><span class="cx"> protected:
</span><span class="cx"> MockRealtimeVideoSource(const String& name = ASCIILiteral("Mock video device"));
</span><span class="cx"> virtual void updatePlatformLayer() const { }
</span><span class="lines">@@ -70,13 +65,18 @@
</span><span class="cx"> void initializeCapabilities(RealtimeMediaSourceCapabilities&) override;
</span><span class="cx"> void initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints&) override;
</span><span class="cx">
</span><del>- void startProducingData() override;
- void stopProducingData() override;
</del><ins>+ void startProducingData() final;
+ void stopProducingData() final;
</ins><span class="cx">
</span><span class="cx"> void drawAnimation(GraphicsContext&);
</span><span class="cx"> void drawText(GraphicsContext&);
</span><span class="cx"> void drawBoxes(GraphicsContext&);
</span><span class="cx">
</span><ins>+ bool applySize(const IntSize&) override;
+ bool applyFrameRate(double) override;
+ bool applyFacingMode(RealtimeMediaSourceSettings::VideoFacingMode) override { return true; }
+ bool applyAspectRatio(double) override { return true; }
+
</ins><span class="cx"> PlatformLayer* platformLayer() const override { return nullptr; }
</span><span class="cx"> RefPtr<Image> currentFrameImage() override;
</span><span class="cx"> void paintCurrentFrameInContext(GraphicsContext&, const FloatRect&) override;
</span><span class="lines">@@ -94,7 +94,6 @@
</span><span class="cx">
</span><span class="cx"> mutable std::unique_ptr<ImageBuffer> m_imageBuffer;
</span><span class="cx">
</span><del>- IntSize m_size;
</del><span class="cx"> Path m_path;
</span><span class="cx"> DashArray m_dashWidths;
</span><span class="cx">
</span><span class="lines">@@ -101,7 +100,6 @@
</span><span class="cx"> double m_startTime { NAN };
</span><span class="cx"> double m_elapsedTime { 0 };
</span><span class="cx">
</span><del>- unsigned m_frameRate { 30 };
</del><span class="cx"> unsigned m_frameNumber { 0 };
</span><span class="cx">
</span><span class="cx"> RunLoop::Timer<MockRealtimeVideoSource> m_timer;
</span></span></pre>
</div>
</div>
</body>
</html>