Changeset 205348 in webkit


Ignore:
Timestamp:
Sep 2, 2016 10:36:29 AM (8 years ago)
Author:
eric.carlson@apple.com
Message:

[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.
Location:
trunk
Files:
6 added
31 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r205340 r205348  
     12016-09-02  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [MediaStream] applyConstraints pt. 1 - mandatory constraints
     4        https://bugs.webkit.org/show_bug.cgi?id=161469
     5        <rdar://problem/28109325>
     6
     7        Reviewed by Jer Noble.
     8
     9        * fast/mediastream/apply-constraints-audio-expected.txt: Added.
     10        * fast/mediastream/apply-constraints-audio.html: Added.
     11        * fast/mediastream/apply-constraints-video-expected.txt: Added.
     12        * fast/mediastream/apply-constraints-video.html: Added.
     13        * fast/mediastream/resources/apply-constraints-utils.js: Added.
     14
    1152016-09-01  Ryosuke Niwa  <rniwa@webkit.org>
    216
  • trunk/Source/WebCore/ChangeLog

    r205347 r205348  
     12016-09-02  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [MediaStream] applyConstraints pt. 1 - mandatory constraints
     4        https://bugs.webkit.org/show_bug.cgi?id=161469
     5        <rdar://problem/28109325>
     6
     7        Reviewed by Jer Noble.
     8
     9        Tests: fast/mediastream/apply-constraints-audio.html
     10               fast/mediastream/apply-constraints-video.html
     11
     12        * Modules/mediastream/MediaStreamTrack.cpp:
     13        (WebCore::MediaStreamTrack::MediaStreamTrack): Initialize the weak pointer factory.
     14        (WebCore::MediaStreamTrack::applyConstraints): Make it work.
     15        * Modules/mediastream/MediaStreamTrack.h:
     16        * Modules/mediastream/MediaStreamTrack.idl:
     17
     18        * WebCore.xcodeproj/project.pbxproj: Add JSMediaDevicesCustom.h.
     19
     20        * bindings/js/JSMediaDevicesCustom.cpp:
     21        (WebCore::createStringConstraint): Add name parameter.
     22        (WebCore::createBooleanConstraint): Ditto.
     23        (WebCore::createDoubleConstraint): Ditto.
     24        (WebCore::createIntConstraint): Ditto.
     25        (WebCore::parseMediaTrackConstraintSetForKey): Drop type parameter because we don't need to
     26          filter by source media type.
     27        (WebCore::parseAdvancedConstraints): Ditto.
     28        (WebCore::parseMediaConstraintsDictionary): Renamed from parseConstraints.
     29        (WebCore::JSMediaDevices::getUserMedia): Don't throw exceptions, always return a promise.
     30        (WebCore::parseConstraints): Deleted.
     31        * bindings/js/JSMediaDevicesCustom.h: Added.
     32
     33        * bindings/js/JSMediaStreamTrackCustom.cpp:
     34        (WebCore::JSMediaStreamTrack::getSettings): Don't include aspect ratio if the value is 0.
     35        (WebCore::capabilityValue): asULong -> asInt.
     36        (WebCore::JSMediaStreamTrack::applyConstraints): New.
     37        (WebCore::JSMediaStreamTrack::getConstraints): New.
     38
     39        * bindings/js/WebCoreBuiltinNames.h: Add "mediaStreamTrackConstraints".
     40
     41        * html/HTMLMediaElement.cpp:
     42        (WebCore::HTMLMediaElement::setSrcObject): Drive by fix: don't call DOMURL::createPublicURL(null).
     43
     44        * platform/mediastream/MediaConstraints.cpp:
     45        (WebCore::MediaConstraint::create): Pass name to constructors.
     46        (WebCore::StringConstraint::find): New.
     47        * platform/mediastream/MediaConstraints.h:
     48
     49        * platform/mediastream/MediaStreamTrackPrivate.cpp:
     50        (WebCore::MediaStreamTrackPrivate::applyConstraints): Add callback parameters.
     51        * platform/mediastream/MediaStreamTrackPrivate.h:
     52
     53        * platform/mediastream/RealtimeMediaSource.cpp:
     54        (WebCore::RealtimeMediaSource::RealtimeMediaSource): Initialize weak pointer factory.
     55        (WebCore::RealtimeMediaSource::settingsDidChange): Don't call observers immediately so we can
     56         coalesce multiple changes in the same runloop cycle.
     57        (WebCore::RealtimeMediaSource::supportsConstraint): New.
     58        (WebCore::value): Return the most appropriate value from a numeric constraint.
     59        (WebCore::RealtimeMediaSource::applyConstraint): New, apply one constraint.
     60        (WebCore::RealtimeMediaSource::applyConstraints): New, validate and apply constraints.
     61        (WebCore::RealtimeMediaSource::setWidth): New.
     62        (WebCore::RealtimeMediaSource::setHeight): New.
     63        (WebCore::RealtimeMediaSource::setFrameRate): New.
     64        (WebCore::RealtimeMediaSource::setAspectRatio): New.
     65        (WebCore::RealtimeMediaSource::setFacingMode): New.
     66        (WebCore::RealtimeMediaSource::setVolume): New.
     67        (WebCore::RealtimeMediaSource::setSampleRate): New.
     68        (WebCore::RealtimeMediaSource::setSampleSize): New.
     69        (WebCore::RealtimeMediaSource::setEchoCancellation) New.:
     70        (WebCore::RealtimeMediaSource::scheduleDeferredTask): New.
     71        * platform/mediastream/RealtimeMediaSource.h:
     72
     73        * platform/mediastream/RealtimeMediaSourceCapabilities.h:
     74        (WebCore::CapabilityValueOrRange::CapabilityValueOrRange): "unsigned long" -> "int"
     75
     76        * platform/mediastream/RealtimeMediaSourceSettings.cpp:
     77        (WebCore::userFacing): New.
     78        (WebCore::environmentFacing): New.
     79        (WebCore::leftFacing): New.
     80        (WebCore::rightFacing): New.
     81        (WebCore::RealtimeMediaSourceSettings::facingMode):
     82        (WebCore::RealtimeMediaSourceSettings::videoFacingModeEnum):
     83        * platform/mediastream/RealtimeMediaSourceSettings.h:
     84
     85        * platform/mediastream/mac/AVAudioCaptureSource.mm:
     86        (WebCore::AVAudioCaptureSource::initializeCapabilities): Volume range is 0.0 .. 1.0.
     87
     88        * platform/mediastream/mac/AVMediaCaptureSource.h:
     89        (WebCore::AVMediaCaptureSource::createWeakPtr): Deleted.
     90        * platform/mediastream/mac/AVMediaCaptureSource.mm:
     91        (WebCore::AVMediaCaptureSource::AVMediaCaptureSource): Don't need the weak ptr factory, it is
     92          in the base class.
     93        (WebCore::AVMediaCaptureSource::scheduleDeferredTask): Deleted.
     94
     95        * platform/mediastream/mac/AVVideoCaptureSource.h:
     96        * platform/mediastream/mac/AVVideoCaptureSource.mm:
     97        (WebCore::AVVideoCaptureSource::applySize): New.
     98        (WebCore::AVVideoCaptureSource::applyFrameRate): New.
     99        (WebCore::AVVideoCaptureSource::setupCaptureSession):
     100        (WebCore::AVVideoCaptureSource::setFrameRateConstraint): Deleted.
     101        (WebCore::AVVideoCaptureSource::applyConstraints): Deleted.
     102
     103        * platform/mock/MockRealtimeAudioSource.cpp:
     104        (WebCore::MockRealtimeAudioSource::updateSettings): Set volume and echoCancellation to the
     105          current values.
     106        (WebCore::MockRealtimeAudioSource::initializeCapabilities): Volume takes a float, not an int.
     107        * platform/mock/MockRealtimeAudioSource.h:
     108
     109        * platform/mock/MockRealtimeMediaSource.cpp: Minor cleanup.
     110        * platform/mock/MockRealtimeMediaSource.h:
     111
     112        * platform/mock/MockRealtimeVideoSource.cpp:
     113        (WebCore::MockRealtimeVideoSource::MockRealtimeVideoSource): Initialize frame rate.
     114        (WebCore::MockRealtimeVideoSource::startProducingData): m_size -> size().
     115        (WebCore::MockRealtimeVideoSource::updateSettings): Use accessors because instance variables
     116          have been moved to the base class.
     117        (WebCore::MockRealtimeVideoSource::initializeCapabilities): Ditto.
     118        (WebCore::MockRealtimeVideoSource::applyFrameRate): New.
     119        (WebCore::MockRealtimeVideoSource::applySize):
     120        (WebCore::MockRealtimeVideoSource::drawAnimation):
     121        (WebCore::MockRealtimeVideoSource::drawBoxes):
     122        (WebCore::MockRealtimeVideoSource::drawText):
     123        (WebCore::MockRealtimeVideoSource::generateFrame):
     124        (WebCore::MockRealtimeVideoSource::imageBuffer):
     125        (WebCore::MockRealtimeVideoSource::setFrameRate): Deleted.
     126        (WebCore::MockRealtimeVideoSource::setSize): Deleted.
     127        * platform/mock/MockRealtimeVideoSource.h:
     128        (WebCore::MockRealtimeVideoSource::size): Deleted.
     129
    11302016-09-02  Brady Eidson  <beidson@apple.com>
    2131
  • trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp

    r204516 r205348  
    3636#include "ExceptionCode.h"
    3737#include "ExceptionCodePlaceholder.h"
     38#include "JSOverconstrainedError.h"
    3839#include "MediaConstraintsImpl.h"
    3940#include "MediaSourceSettings.h"
     
    4243#include "MediaTrackConstraints.h"
    4344#include "NotImplemented.h"
     45#include "OverconstrainedError.h"
    4446#include "ScriptExecutionContext.h"
    4547#include <wtf/NeverDestroyed.h>
     
    5355
    5456MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack)
    55     : RefCounted()
    56     , ActiveDOMObject(&context)
     57    : ActiveDOMObject(&context)
    5758    , m_private(privateTrack)
     59    , m_weakPtrFactory(this)
    5860{
    5961    suspendIfNeeded();
     
    168170}
    169171
    170 void MediaStreamTrack::applyConstraints(const Dictionary& constraints)
    171 {
    172     // FIXME: Implement correctly. https://bugs.webkit.org/show_bug.cgi?id=160579
    173 
    174     m_constraints->initialize(constraints);
    175     m_private->applyConstraints(*m_constraints);
    176 }
    177 
    178 void MediaStreamTrack::applyConstraints(const MediaConstraints&)
    179 {
    180     // FIXME: apply the new constraints to the track
    181     // https://bugs.webkit.org/show_bug.cgi?id=122428
     172void MediaStreamTrack::applyConstraints(Ref<MediaConstraints>&& constraints, ApplyConstraintsPromise&& promise)
     173{
     174    if (!constraints->isValid()) {
     175        promise.reject(TypeError);
     176        return;
     177    }
     178
     179    m_constraints = WTFMove(constraints);
     180    m_promise = WTFMove(promise);
     181
     182    applyConstraints(*m_constraints);
     183}
     184
     185void MediaStreamTrack::applyConstraints(const MediaConstraints& constraints)
     186{
     187    auto weakThis = createWeakPtr();
     188    std::function<void(const String&, const String&)> failureHandler = [weakThis](const String& failedConstraint, const String& message) {
     189        if (!weakThis || !weakThis->m_promise)
     190            return;
     191
     192        weakThis->m_promise->reject(OverconstrainedError::create(failedConstraint, message).get());
     193    };
     194
     195    std::function<void()> successHandler = [weakThis]() {
     196        if (!weakThis || !weakThis->m_promise)
     197            return;
     198
     199        weakThis->m_promise->resolve(nullptr);
     200    };
     201
     202    m_private->applyConstraints(constraints, successHandler, failureHandler);
    182203}
    183204
  • trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h

    r200361 r205348  
    3232#include "ActiveDOMObject.h"
    3333#include "EventTarget.h"
     34#include "JSDOMPromise.h"
    3435#include "MediaStreamTrackPrivate.h"
    3536#include "RealtimeMediaSource.h"
    3637#include "ScriptWrappable.h"
     38#include <wtf/Optional.h>
    3739#include <wtf/RefPtr.h>
    3840#include <wtf/Vector.h>
     41#include <wtf/WeakPtr.h>
    3942#include <wtf/text/WTFString.h>
    4043
     
    4245
    4346class AudioSourceProvider;
    44 class Dictionary;
    45 class MediaConstraintsImpl;
     47class MediaConstraints;
    4648class MediaSourceSettings;
    4749class MediaTrackConstraints;
     
    8082    RefPtr<MediaSourceSettings> getSettings() const;
    8183    RefPtr<RealtimeMediaSourceCapabilities> getCapabilities() const;
    82     void applyConstraints(const Dictionary&);
     84
     85    using ApplyConstraintsPromise = DOMPromise<std::nullptr_t>;
     86    void applyConstraints(Ref<MediaConstraints>&&, ApplyConstraintsPromise&&);
    8387    void applyConstraints(const MediaConstraints&);
    8488
     
    119123    void trackEnabledChanged(MediaStreamTrackPrivate&) override;
    120124
     125    WeakPtr<MediaStreamTrack> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
     126
    121127    Vector<Observer*> m_observers;
    122128    Ref<MediaStreamTrackPrivate> m_private;
    123129
    124     RefPtr<MediaConstraintsImpl> m_constraints;
     130    RefPtr<MediaConstraints> m_constraints;
     131    Optional<ApplyConstraintsPromise> m_promise;
     132    WeakPtrFactory<MediaStreamTrack> m_weakPtrFactory;
    125133
    126134    bool m_ended { false };
  • trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl

    r202551 r205348  
    4848    [ImplementedAs=stopProducingData] void stop();
    4949
    50     MediaTrackConstraints getConstraints();
     50    [Custom] MediaTrackConstraints getConstraints();
    5151    [Custom] MediaSourceSettings getSettings();
    5252    [Custom] MediaTrackCapabilities getCapabilities();
    53     void applyConstraints(Dictionary constraints);
     53    [Custom] Promise applyConstraints(Dictionary? constraints);
    5454
    5555    attribute EventHandler onoverconstrained;
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r205333 r205348  
    140140                07297FA81C1881C5003F0735 /* UserMediaPermissionCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 07297FA61C1881C5003F0735 /* UserMediaPermissionCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
    141141                072A70401D6E8F6200DF0AFC /* OverconstrainedErrorEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 072A703E1D6E8F6200DF0AFC /* OverconstrainedErrorEvent.h */; };
     142                072A70431D7396B300DF0AFC /* JSMediaDevicesCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = 072A70421D7396B200DF0AFC /* JSMediaDevicesCustom.h */; };
    142143                072AE1E5183C0741000A5988 /* PluginReplacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 072AE1DF183C0741000A5988 /* PluginReplacement.h */; settings = {ATTRIBUTES = (Private, ); }; };
    143144                072AE1E6183C0741000A5988 /* QuickTimePluginReplacement.mm in Sources */ = {isa = PBXBuildFile; fileRef = 072AE1E0183C0741000A5988 /* QuickTimePluginReplacement.mm */; };
     
    69446945                072A703E1D6E8F6200DF0AFC /* OverconstrainedErrorEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OverconstrainedErrorEvent.h; sourceTree = "<group>"; };
    69456946                072A703F1D6E8F6200DF0AFC /* OverconstrainedErrorEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = OverconstrainedErrorEvent.idl; sourceTree = "<group>"; };
     6947                072A70421D7396B200DF0AFC /* JSMediaDevicesCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMediaDevicesCustom.h; sourceTree = "<group>"; };
    69466948                072AE1DF183C0741000A5988 /* PluginReplacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PluginReplacement.h; sourceTree = "<group>"; };
    69476949                072AE1E0183C0741000A5988 /* QuickTimePluginReplacement.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = QuickTimePluginReplacement.mm; sourceTree = "<group>"; };
     
    2109721099                                BCE1C43F0D9830F4003B02F2 /* JSLocationCustom.cpp */,
    2109821100                                1B88DD121D5AD3B200E3B7A4 /* JSMediaDevicesCustom.cpp */,
     21101                                072A70421D7396B200DF0AFC /* JSMediaDevicesCustom.h */,
    2109921102                                AD726FE716D9F204003A4E6D /* JSMediaListCustom.h */,
    2110021103                                07C59B6D17F794F6000FBCBB /* JSMediaStreamTrackCustom.cpp */,
     
    2628226285                                E48944A3180B57D800F165D8 /* SimpleLineLayout.h in Headers */,
    2628326286                                585D6E041A1A792E00FA4F12 /* SimpleLineLayoutFlowContents.h in Headers */,
     26287                                072A70431D7396B300DF0AFC /* JSMediaDevicesCustom.h in Headers */,
    2628426288                                E4E9B11D1814569C003ACCDF /* SimpleLineLayoutFunctions.h in Headers */,
    2628526289                                E4E9B1191810916F003ACCDF /* SimpleLineLayoutResolver.h in Headers */,
  • trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.cpp

    r205257 r205348  
    2525
    2626#include "config.h"
    27 #include "JSMediaDevices.h"
     27#include "JSMediaDevicesCustom.h"
    2828
    2929#if ENABLE(MEDIA_STREAM)
     
    3232#include "Dictionary.h"
    3333#include "ExceptionCode.h"
     34#include "JSMediaDevices.h"
    3435#include "Logging.h"
    35 #include "MediaConstraints.h"
    3636#include "MediaConstraintsImpl.h"
    3737#include "RealtimeMediaSourceCenter.h"
     
    6161static RefPtr<StringConstraint> createStringConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
    6262{
    63     auto constraint = StringConstraint::create(type);
     63    auto constraint = StringConstraint::create(name, type);
    6464
    6565    // Dictionary constraint value.
     
    123123static RefPtr<BooleanConstraint> createBooleanConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
    124124{
    125     auto constraint = BooleanConstraint::create(type);
     125    auto constraint = BooleanConstraint::create(name, type);
    126126
    127127    // Dictionary constraint value.
     
    162162static RefPtr<DoubleConstraint> createDoubleConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
    163163{
    164     auto constraint = DoubleConstraint::create(type);
     164    auto constraint = DoubleConstraint::create(name, type);
    165165
    166166    // Dictionary constraint value.
     
    209209static RefPtr<IntConstraint> createIntConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
    210210{
    211     auto constraint = IntConstraint::create(type);
     211    auto constraint = IntConstraint::create(name, type);
    212212
    213213    // Dictionary constraint value.
     
    254254}
    255255
    256 static void parseMediaTrackConstraintSetForKey(const Dictionary& mediaTrackConstraintSet, const String& name, MediaTrackConstraintSetMap& map, ConstraintSetType constraintSetType, RealtimeMediaSource::Type sourceType)
     256static void parseMediaTrackConstraintSetForKey(const Dictionary& mediaTrackConstraintSet, const String& name, MediaTrackConstraintSetMap& map, ConstraintSetType constraintSetType)
    257257{
    258258    MediaConstraintType constraintType = RealtimeMediaSourceSupportedConstraints::constraintFromName(name);
    259259
    260260    RefPtr<MediaConstraint> mediaConstraint;
    261     if (sourceType == RealtimeMediaSource::Audio) {
    262         switch (constraintType) {
    263         case MediaConstraintType::SampleRate:
    264         case MediaConstraintType::SampleSize:
    265             mediaConstraint = createIntConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
    266             break;
    267         case MediaConstraintType::Volume:
    268             mediaConstraint = createDoubleConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
    269             break;
    270         case MediaConstraintType::EchoCancellation:
    271             mediaConstraint = createBooleanConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
    272             break;
    273         case MediaConstraintType::DeviceId:
    274         case MediaConstraintType::GroupId:
    275             mediaConstraint = createStringConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
    276             break;
    277         default:
    278             LOG(Media, "parseMediaTrackConstraintSetForKey() - ignoring unsupported constraint '%s' for audio.", name.utf8().data());
    279             mediaConstraint = nullptr;
    280             break;
    281         }
    282     } else if (sourceType == RealtimeMediaSource::Video) {
    283         switch (constraintType) {
    284         case MediaConstraintType::Width:
    285         case MediaConstraintType::Height:
    286             mediaConstraint = createIntConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
    287             break;
    288         case MediaConstraintType::AspectRatio:
    289         case MediaConstraintType::FrameRate:
    290             mediaConstraint = createDoubleConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
    291             break;
    292         case MediaConstraintType::FacingMode:
    293         case MediaConstraintType::DeviceId:
    294         case MediaConstraintType::GroupId:
    295             mediaConstraint = createStringConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
    296             break;
    297         default:
    298             LOG(Media, "parseMediaTrackConstraintSetForKey() - ignoring unsupported constraint '%s' for video.", name.utf8().data());
    299             mediaConstraint = nullptr;
    300             break;
    301         }
    302     }
    303 
    304     if (!mediaConstraint)
    305         return;
    306 
     261    switch (constraintType) {
     262    case MediaConstraintType::Width:
     263    case MediaConstraintType::Height:
     264    case MediaConstraintType::SampleRate:
     265    case MediaConstraintType::SampleSize:
     266        mediaConstraint = createIntConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
     267        break;
     268
     269    case MediaConstraintType::AspectRatio:
     270    case MediaConstraintType::FrameRate:
     271    case MediaConstraintType::Volume:
     272        mediaConstraint = createDoubleConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
     273        break;
     274
     275    case MediaConstraintType::EchoCancellation:
     276        mediaConstraint = createBooleanConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
     277        break;
     278
     279    case MediaConstraintType::FacingMode:
     280    case MediaConstraintType::DeviceId:
     281    case MediaConstraintType::GroupId:
     282        mediaConstraint = createStringConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
     283        break;
     284
     285    case MediaConstraintType::Unknown:
     286        LOG(Media, "parseMediaTrackConstraintSetForKey() - found unsupported constraint '%s'.", name.utf8().data());
     287        mediaConstraint = UnknownConstraint::create(name, constraintType);
     288        break;
     289    }
     290   
    307291    map.add(name, WTFMove(mediaConstraint));
    308292}
    309293
    310 static void parseAdvancedConstraints(const Dictionary& mediaTrackConstraints, Vector<MediaTrackConstraintSetMap>& advancedConstraints, RealtimeMediaSource::Type sourceType)
     294static void parseAdvancedConstraints(const Dictionary& mediaTrackConstraints, Vector<MediaTrackConstraintSetMap>& advancedConstraints)
    311295{
    312296    ArrayValue sequenceOfMediaTrackConstraintSets;
     
    334318        mediaTrackConstraintSet.getOwnPropertyNames(localKeys);
    335319        for (auto& localKey : localKeys)
    336             parseMediaTrackConstraintSetForKey(mediaTrackConstraintSet, localKey, map, ConstraintSetType::Advanced, sourceType);
     320            parseMediaTrackConstraintSetForKey(mediaTrackConstraintSet, localKey, map, ConstraintSetType::Advanced);
    337321
    338322        if (!map.isEmpty())
     
    341325}
    342326
    343 static void parseConstraints(const Dictionary& mediaTrackConstraints, MediaTrackConstraintSetMap& mandatoryConstraints, Vector<MediaTrackConstraintSetMap>& advancedConstraints, RealtimeMediaSource::Type sourceType)
     327void parseMediaConstraintsDictionary(const Dictionary& mediaTrackConstraints, MediaTrackConstraintSetMap& mandatoryConstraints, Vector<MediaTrackConstraintSetMap>& advancedConstraints)
    344328{
    345329    if (mediaTrackConstraints.isUndefinedOrNull())
     
    351335    for (auto& key : keys) {
    352336        if (key == "advanced")
    353             parseAdvancedConstraints(mediaTrackConstraints, advancedConstraints, sourceType);
    354         else
    355             parseMediaTrackConstraintSetForKey(mediaTrackConstraints, key, mandatoryConstraints, ConstraintSetType::Mandatory, sourceType);
     337            parseAdvancedConstraints(mediaTrackConstraints, advancedConstraints);
     338        else
     339            parseMediaTrackConstraintSetForKey(mediaTrackConstraints, key, mandatoryConstraints, ConstraintSetType::Mandatory);
    356340    }
    357341}
     
    373357    Dictionary audioConstraintsDictionary;
    374358    if (constraintsDictionary.get("audio", audioConstraintsDictionary) && !audioConstraintsDictionary.isUndefinedOrNull()) {
    375         parseConstraints(audioConstraintsDictionary, mandatoryAudioConstraints, advancedAudioConstraints, RealtimeMediaSource::Audio);
     359        parseMediaConstraintsDictionary(audioConstraintsDictionary, mandatoryAudioConstraints, advancedAudioConstraints);
    376360        areAudioConstraintsValid = true;
    377361    } else
     
    384368    Dictionary videoConstraintsDictionary;
    385369    if (constraintsDictionary.get("video", videoConstraintsDictionary) && !videoConstraintsDictionary.isUndefinedOrNull()) {
    386         parseConstraints(videoConstraintsDictionary, mandatoryVideoConstraints, advancedVideoConstraints, RealtimeMediaSource::Video);
     370        parseMediaConstraintsDictionary(videoConstraintsDictionary, mandatoryVideoConstraints, advancedVideoConstraints);
    387371        areVideoConstraintsValid = true;
    388372    } else
  • trunk/Source/WebCore/bindings/js/JSMediaStreamTrackCustom.cpp

    r205198 r205348  
    2929#if ENABLE(MEDIA_STREAM)
    3030
     31#include "Dictionary.h"
    3132#include "ExceptionCode.h"
    3233#include "JSDOMBinding.h"
     34#include "JSMediaDevicesCustom.h"
     35#include "MediaConstraintsImpl.h"
    3336#include "MediaSourceSettings.h"
    3437#include "MediaStreamTrack.h"
     38#include "WebCoreJSClientData.h"
    3539#include <runtime/JSObject.h>
    3640#include <runtime/ObjectConstructor.h>
     
    5862    if (settings->supportsHeight())
    5963        object->putDirect(state.vm(), Identifier::fromString(&state, "height"), jsNumber(settings->height()), DontDelete | ReadOnly);
    60     if (settings->supportsAspectRatio())
     64    if (settings->supportsAspectRatio() && settings->aspectRatio())
    6165        object->putDirect(state.vm(), Identifier::fromString(&state, "aspectRatio"), jsDoubleNumber(settings->aspectRatio()), DontDelete | ReadOnly);
    6266    if (settings->supportsFrameRate())
     
    9195            object->putDirect(state.vm(), Identifier::fromString(&state, "max"), jsNumber(max.asDouble));
    9296        } else {
    93             object->putDirect(state.vm(), Identifier::fromString(&state, "min"), jsNumber(min.asULong));
    94             object->putDirect(state.vm(), Identifier::fromString(&state, "max"), jsNumber(max.asULong));
     97            object->putDirect(state.vm(), Identifier::fromString(&state, "min"), jsNumber(min.asInt));
     98            object->putDirect(state.vm(), Identifier::fromString(&state, "max"), jsNumber(max.asInt));
    9599        }
    96100
     
    101105        return jsNumber(value.value().asDouble);
    102106
    103     return jsNumber(value.value().asULong);
     107    return jsNumber(value.value().asInt);
    104108}
    105109
     
    163167}
    164168
     169JSValue JSMediaStreamTrack::applyConstraints(ExecState& state)
     170{
     171    MediaTrackConstraintSetMap mandatoryConstraints;
     172    Vector<MediaTrackConstraintSetMap> advancedConstraints;
     173    bool valid = false;
     174
     175    if (state.argumentCount() >= 1) {
     176        JSValue argument = state.uncheckedArgument(0);
     177
     178        JSVMClientData& clientData = *static_cast<JSVMClientData*>(state.vm().clientData);
     179        putDirect(state.vm(), clientData.builtinNames().mediaStreamTrackConstraintsPrivateName(), argument, DontEnum);
     180
     181        auto constraintsDictionary = Dictionary(&state, argument);
     182        if (!constraintsDictionary.isUndefinedOrNull())
     183            parseMediaConstraintsDictionary(constraintsDictionary, mandatoryConstraints, advancedConstraints);
     184        valid = !advancedConstraints.isEmpty() || !mandatoryConstraints.isEmpty();
     185    }
     186
     187    JSC::JSPromiseDeferred* promiseDeferred = JSC::JSPromiseDeferred::create(&state, globalObject());
     188    auto constraints = MediaConstraintsImpl::create(WTFMove(mandatoryConstraints), WTFMove(advancedConstraints), valid);
     189    wrapped().applyConstraints(WTFMove(constraints), DeferredWrapper::create(&state, globalObject(), promiseDeferred));
     190
     191    return promiseDeferred->promise();
     192}
     193
     194JSValue JSMediaStreamTrack::getConstraints(ExecState& state)
     195{
     196    JSVMClientData& clientData = *static_cast<JSVMClientData*>(state.vm().clientData);
     197    JSValue result = getDirect(state.vm(), clientData.builtinNames().mediaStreamTrackConstraintsPrivateName());
     198    return !result.isEmpty() ? result : jsUndefined();
     199}
     200
    165201} // namespace WebCore
    166202
  • trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h

    r205289 r205348  
    5959    macro(makeThisTypeError) \
    6060    macro(makeGetterTypeError) \
     61    macro(mediaStreamTrackConstraints) \
    6162    macro(operations) \
    6263    macro(ownerReadableStream) \
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r204989 r205348  
    10021002
    10031003    m_mediaStreamSrcObject = mediaStream;
    1004     setSrc(DOMURL::createPublicURL(context, mediaStream));
     1004    if (mediaStream)
     1005        setSrc(DOMURL::createPublicURL(context, mediaStream));
    10051006}
    10061007#endif
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm

    r203901 r205348  
    313313    m_haveEverPlayed = true;
    314314    scheduleDeferredTask([this] {
     315        updateDisplayMode();
    315316        updateReadyState();
    316317    });
  • trunk/Source/WebCore/platform/mediastream/MediaConstraints.cpp

    r204847 r205348  
    4747    case MediaConstraintType::SampleRate:
    4848    case MediaConstraintType::SampleSize:
    49         return IntConstraint::create(constraintType);
     49        return IntConstraint::create(name, constraintType);
    5050    case MediaConstraintType::AspectRatio:
    5151    case MediaConstraintType::FrameRate:
    5252    case MediaConstraintType::Volume:
    53         return DoubleConstraint::create(constraintType);
     53        return DoubleConstraint::create(name, constraintType);
    5454    case MediaConstraintType::EchoCancellation:
    55         return BooleanConstraint::create(constraintType);
     55        return BooleanConstraint::create(name, constraintType);
    5656    case MediaConstraintType::FacingMode:
    5757    case MediaConstraintType::DeviceId:
    5858    case MediaConstraintType::GroupId:
    59         return StringConstraint::create(constraintType);
     59        return StringConstraint::create(name, constraintType);
    6060    case MediaConstraintType::Unknown:
    61         return nullptr;
     61        return UnknownConstraint::create(name, constraintType);
    6262    }
    6363}
     
    122122}
    123123
     124const String& StringConstraint::find(std::function<bool(ConstraintType, const String&)> filter) const
     125{
     126    for (auto& constraint : m_exact) {
     127        if (filter(ConstraintType::ExactConstraint, constraint))
     128            return constraint;
     129    }
     130
     131    for (auto& constraint : m_ideal) {
     132        if (filter(ConstraintType::IdealConstraint, constraint))
     133            return constraint;
     134    }
     135   
     136    return emptyString();
     137}
     138
    124139}
    125140
  • trunk/Source/WebCore/platform/mediastream/MediaConstraints.h

    r204847 r205348  
    4646    static RefPtr<MediaConstraint> create(const String& name);
    4747
     48    enum class ConstraintType { ExactConstraint, IdealConstraint, MinConstraint, MaxConstraint };
     49
    4850    virtual ~MediaConstraint() { };
    4951    virtual bool isEmpty() const = 0;
     
    5456    virtual bool getExact(int&) const { ASSERT_NOT_REACHED(); return false; }
    5557    virtual bool getIdeal(int&) const { ASSERT_NOT_REACHED(); return false; }
     58    virtual bool validForRange(int, int) const { ASSERT_NOT_REACHED(); return false; }
     59    virtual int find(std::function<bool(ConstraintType, int)>) const { ASSERT_NOT_REACHED(); return 0; }
    5660
    5761    virtual bool getMin(double&) const { ASSERT_NOT_REACHED(); return false; }
     
    5963    virtual bool getExact(double&) const { ASSERT_NOT_REACHED(); return false; }
    6064    virtual bool getIdeal(double&) const { ASSERT_NOT_REACHED(); return false; }
     65    virtual bool validForRange(double, double) const { ASSERT_NOT_REACHED(); return false; }
     66    virtual double find(std::function<bool(ConstraintType, double)>) const { ASSERT_NOT_REACHED(); return 0; }
    6167
    6268    virtual bool getMin(bool&) const { ASSERT_NOT_REACHED(); return false; }
     
    6975    virtual bool getExact(Vector<String>&) const { ASSERT_NOT_REACHED(); return false; }
    7076    virtual bool getIdeal(Vector<String>&) const { ASSERT_NOT_REACHED(); return false; }
     77    virtual const String& find(std::function<bool(ConstraintType, const String&)>) const { ASSERT_NOT_REACHED(); return emptyString(); }
    7178
    7279    MediaConstraintType type() const { return m_type; }
     80    const String& name() const { return m_name; }
    7381
    7482protected:
    75     explicit MediaConstraint(MediaConstraintType type)
    76         : m_type(type)
    77     {
    78     }
    79 
    80 private:
     83    explicit MediaConstraint(const String& name, MediaConstraintType type)
     84        : m_name(name)
     85        , m_type(type)
     86    {
     87    }
     88
     89private:
     90    String m_name;
    8191    MediaConstraintType m_type;
    8292};
     
    125135    }
    126136
     137    bool validForRange(ValueType rangeMin, ValueType rangeMax) const final {
     138        if (isEmpty())
     139            return false;
     140
     141        if (m_exact && (m_exact.value() < rangeMin || m_exact.value() > rangeMax))
     142            return false;
     143
     144        if (m_min && m_min.value() > rangeMax)
     145            return false;
     146
     147        if (m_max && m_max.value() < rangeMin)
     148            return false;
     149
     150        return true;
     151    }
     152
     153    ValueType find(std::function<bool(ConstraintType, ValueType)> function) const final {
     154        if (m_min && function(ConstraintType::MinConstraint, m_min.value()))
     155            return m_min.value();
     156
     157        if (m_max && function(ConstraintType::MaxConstraint, m_max.value()))
     158            return m_max.value();
     159
     160        if (m_exact && function(ConstraintType::ExactConstraint, m_exact.value()))
     161            return m_exact.value();
     162
     163        if (m_ideal && function(ConstraintType::IdealConstraint, m_ideal.value()))
     164            return m_ideal.value();
     165
     166        return 0;
     167    }
     168   
     169
    127170protected:
    128     explicit NumericConstraint(MediaConstraintType type)
    129         : MediaConstraint(type)
     171    explicit NumericConstraint(const String& name, MediaConstraintType type)
     172        : MediaConstraint(name, type)
    130173    {
    131174    }
     
    140183class IntConstraint final : public NumericConstraint<int> {
    141184public:
    142     static Ref<IntConstraint> create(MediaConstraintType type) { return adoptRef(*new IntConstraint(type)); }
    143 
    144 private:
    145     explicit IntConstraint(MediaConstraintType type)
    146         : NumericConstraint<int>(type)
     185    static Ref<IntConstraint> create(const String& name, MediaConstraintType type) { return adoptRef(*new IntConstraint(name, type)); }
     186
     187private:
     188    explicit IntConstraint(const String& name, MediaConstraintType type)
     189        : NumericConstraint<int>(name, type)
    147190    {
    148191    }
     
    151194class DoubleConstraint final : public NumericConstraint<double> {
    152195public:
    153     static Ref<DoubleConstraint> create(MediaConstraintType type) { return adoptRef(*new DoubleConstraint(type)); }
    154 
    155 private:
    156     explicit DoubleConstraint(MediaConstraintType type)
    157         : NumericConstraint<double>(type)
     196    static Ref<DoubleConstraint> create(const String& name, MediaConstraintType type) { return adoptRef(*new DoubleConstraint(name, type)); }
     197
     198private:
     199    explicit DoubleConstraint(const String& name, MediaConstraintType type)
     200        : NumericConstraint<double>(name, type)
    158201    {
    159202    }
     
    162205class BooleanConstraint final : public MediaConstraint {
    163206public:
    164     static Ref<BooleanConstraint> create(MediaConstraintType type) { return adoptRef(*new BooleanConstraint(type)); }
     207    static Ref<BooleanConstraint> create(const String& name, MediaConstraintType type) { return adoptRef(*new BooleanConstraint(name, type)); }
    165208
    166209    void setExact(bool value) { m_exact = value; }
     
    174217
    175218private:
    176     explicit BooleanConstraint(MediaConstraintType type)
    177         : MediaConstraint(type)
    178     {
    179     }
    180 
    181     Optional<bool> m_exact { false };
    182     Optional<bool> m_ideal { false };
     219    explicit BooleanConstraint(const String& name, MediaConstraintType type)
     220        : MediaConstraint(name, type)
     221    {
     222    }
     223
     224    Optional<bool> m_exact;
     225    Optional<bool> m_ideal;
    183226};
    184227
    185228class StringConstraint final : public MediaConstraint {
    186229public:
    187     static Ref<StringConstraint> create(MediaConstraintType type) { return adoptRef(*new StringConstraint(type)); }
     230    static Ref<StringConstraint> create(const String& name, MediaConstraintType type) { return adoptRef(*new StringConstraint(name, type)); }
    188231
    189232    void setExact(const String&);
     
    198241    bool isMandatory() const final { return !m_exact.isEmpty(); }
    199242
    200 private:
    201     explicit StringConstraint(MediaConstraintType type)
    202         : MediaConstraint(type)
     243    const String& find(std::function<bool(ConstraintType, const String&)>) const override;
     244
     245private:
     246    explicit StringConstraint(const String& name, MediaConstraintType type)
     247        : MediaConstraint(name, type)
    203248    {
    204249    }
     
    206251    Vector<String> m_exact;
    207252    Vector<String> m_ideal;
     253};
     254
     255class UnknownConstraint final : public MediaConstraint {
     256public:
     257    static Ref<UnknownConstraint> create(const String& name, MediaConstraintType type) { return adoptRef(*new UnknownConstraint(name, type)); }
     258
     259    bool isEmpty() const final { return true; }
     260    bool isMandatory() const final { return false; }
     261
     262private:
     263    explicit UnknownConstraint(const String& name, MediaConstraintType type)
     264        : MediaConstraint(name, type)
     265    {
     266    }
    208267};
    209268
  • trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp

    r204466 r205348  
    173173}
    174174
    175 void MediaStreamTrackPrivate::applyConstraints(const MediaConstraints&)
    176 {
    177     // FIXME: apply the new constraints to the track
    178     // https://bugs.webkit.org/show_bug.cgi?id=122428
     175void MediaStreamTrackPrivate::applyConstraints(const MediaConstraints& constraints, RealtimeMediaSource::SuccessHandler successHandler, RealtimeMediaSource::FailureHandler failureHandler)
     176{
     177    m_source->applyConstraints(constraints, successHandler, failureHandler);
    179178}
    180179
  • trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h

    r203739 r205348  
    9292
    9393    RefPtr<MediaConstraints> constraints() const;
    94     void applyConstraints(const MediaConstraints&);
     94    void applyConstraints(const MediaConstraints&, RealtimeMediaSource::SuccessHandler, RealtimeMediaSource::FailureHandler);
    9595
    9696    AudioSourceProvider* audioSourceProvider();
  • trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp

    r203739 r205348  
    3737#include "RealtimeMediaSource.h"
    3838
     39#include "MediaConstraints.h"
     40#include "NotImplemented.h"
    3941#include "RealtimeMediaSourceCapabilities.h"
    4042#include "UUID.h"
     43#include <wtf/MainThread.h>
     44#include <wtf/text/StringHash.h>
    4145
    4246namespace WebCore {
    4347
    4448RealtimeMediaSource::RealtimeMediaSource(const String& id, Type type, const String& name)
    45     : m_id(id)
     49    : m_weakPtrFactory(this)
     50    , m_id(id)
    4651    , m_type(type)
    4752    , m_name(name)
     
    5257        m_id = createCanonicalUUIDString();
    5358    m_persistentID = m_id;
     59    m_suppressNotifications = false;
    5460}
    5561
     
    9399void RealtimeMediaSource::settingsDidChange()
    94100{
    95     for (auto& observer : m_observers)
    96         observer->sourceSettingsChanged();
     101    ASSERT(isMainThread());
     102
     103    if (m_pendingSettingsDidChangeNotification || m_suppressNotifications)
     104        return;
     105
     106    m_pendingSettingsDidChangeNotification = true;
     107
     108    scheduleDeferredTask([this] {
     109        m_pendingSettingsDidChangeNotification = false;
     110        for (auto& observer : m_observers)
     111            observer->sourceSettingsChanged();
     112    });
    97113}
    98114
     
    135151}
    136152
     153RealtimeMediaSource::ConstraintSupport RealtimeMediaSource::supportsConstraint(const MediaConstraint& constraint)
     154{
     155    RealtimeMediaSourceCapabilities& capabilities = *this->capabilities();
     156
     157    switch (constraint.type()) {
     158    case MediaConstraintType::Width: {
     159        if (!capabilities.supportsWidth())
     160            return ConstraintSupport::Ignored;
     161
     162        auto widthRange = capabilities.width();
     163        return constraint.validForRange(widthRange.rangeMin().asInt, widthRange.rangeMax().asInt) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
     164        break;
     165    }
     166
     167    case MediaConstraintType::Height: {
     168        if (!capabilities.supportsHeight())
     169            return ConstraintSupport::Ignored;
     170
     171        auto heightRange = capabilities.height();
     172        return constraint.validForRange(heightRange.rangeMin().asInt, heightRange.rangeMax().asInt) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
     173        break;
     174    }
     175
     176    case MediaConstraintType::FrameRate: {
     177        if (!capabilities.supportsFrameRate())
     178            return ConstraintSupport::Ignored;
     179
     180        auto rateRange = capabilities.frameRate();
     181        return constraint.validForRange(rateRange.rangeMin().asDouble, rateRange.rangeMax().asDouble) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
     182        break;
     183    }
     184
     185    case MediaConstraintType::AspectRatio: {
     186        if (!capabilities.supportsAspectRatio())
     187            return ConstraintSupport::Ignored;
     188
     189        auto range = capabilities.aspectRatio();
     190        return constraint.validForRange(range.rangeMin().asDouble, range.rangeMax().asDouble) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
     191        break;
     192    }
     193
     194    case MediaConstraintType::Volume: {
     195        if (!capabilities.supportsVolume())
     196            return ConstraintSupport::Ignored;
     197
     198        auto range = capabilities.volume();
     199        return constraint.validForRange(range.rangeMin().asDouble, range.rangeMax().asDouble) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
     200        break;
     201    }
     202
     203    case MediaConstraintType::SampleRate: {
     204        if (!capabilities.supportsSampleRate())
     205            return ConstraintSupport::Ignored;
     206
     207        auto range = capabilities.sampleRate();
     208        return constraint.validForRange(range.rangeMin().asDouble, range.rangeMax().asDouble) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
     209        break;
     210    }
     211
     212    case MediaConstraintType::SampleSize: {
     213        if (!capabilities.supportsSampleSize())
     214            return ConstraintSupport::Ignored;
     215
     216        auto range = capabilities.sampleSize();
     217        return constraint.validForRange(range.rangeMin().asDouble, range.rangeMax().asDouble) ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
     218        break;
     219    }
     220
     221    case MediaConstraintType::FacingMode: {
     222        if (!capabilities.supportsFacingMode())
     223            return ConstraintSupport::Ignored;
     224
     225        ConstraintSupport support = ConstraintSupport::Ignored;
     226        auto& supportedModes = capabilities.facingMode();
     227        std::function<bool(MediaConstraint::ConstraintType, const String&)> filter = [supportedModes, &support](MediaConstraint::ConstraintType type, const String& modeString) {
     228            if (type == MediaConstraint::ConstraintType::ExactConstraint)
     229                support = ConstraintSupport::Unsupported;
     230
     231            auto mode = RealtimeMediaSourceSettings::videoFacingModeEnum(modeString);
     232            for (auto& supportedMode : supportedModes) {
     233                if (supportedMode == mode) {
     234                    support = ConstraintSupport::Supported;
     235                    break;
     236                }
     237            }
     238
     239            return type == MediaConstraint::ConstraintType::ExactConstraint ? true : false;
     240        };
     241
     242        constraint.find(filter);
     243        return support;
     244        break;
     245    }
     246
     247    case MediaConstraintType::EchoCancellation:
     248        if (!capabilities.supportsEchoCancellation())
     249            return ConstraintSupport::Ignored;
     250
     251        if (capabilities.echoCancellation() == RealtimeMediaSourceCapabilities::EchoCancellation::ReadOnly)
     252            return constraint.isMandatory() ? ConstraintSupport::Unsupported : ConstraintSupport::Ignored;
     253
     254        return ConstraintSupport::Supported;
     255        break;
     256
     257    case MediaConstraintType::DeviceId: {
     258        if (!capabilities.supportsDeviceId())
     259            return ConstraintSupport::Ignored;
     260
     261        ConstraintSupport support = ConstraintSupport::Ignored;
     262        std::function<bool(MediaConstraint::ConstraintType, const String&)> filter = [this, &support](MediaConstraint::ConstraintType type, const String& idString) {
     263            if (type != MediaConstraint::ConstraintType::ExactConstraint)
     264                return false; // Keep looking.
     265
     266            support = idString == m_id ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
     267            return false;
     268        };
     269
     270        constraint.find(filter);
     271        return support;
     272        break;
     273    }
     274
     275    case MediaConstraintType::GroupId: {
     276        if (!capabilities.supportsDeviceId())
     277            return ConstraintSupport::Ignored;
     278
     279        ConstraintSupport support = ConstraintSupport::Ignored;
     280        String groupId = settings().groupId();
     281        std::function<bool(MediaConstraint::ConstraintType, const String&)> filter = [groupId, &support](MediaConstraint::ConstraintType type, const String& idString) {
     282            if (type != MediaConstraint::ConstraintType::ExactConstraint)
     283                return false; // Keep looking.
     284
     285            support = idString == groupId ? ConstraintSupport::Supported : ConstraintSupport::Unsupported;
     286            return false;
     287        };
     288
     289        constraint.find(filter);
     290        return support;
     291        break;
     292    }
     293
     294    case MediaConstraintType::Unknown:
     295        // Unknown (or unsupported) constraints should be ignored.
     296        break;
     297    }
     298
     299    return ConstraintSupport::Ignored;
     300}
     301
     302
     303template <typename T>
     304T value(const MediaConstraint& constraint, T rangeMin, T rangeMax)
     305{
     306    T result;
     307
     308    if (constraint.getExact(result)) {
     309        ASSERT(result >= rangeMin && result <= rangeMax);
     310        return result;
     311    }
     312
     313    if (constraint.getIdeal(result)) {
     314        if (result < rangeMin)
     315            result = rangeMin;
     316        else if (result > rangeMax)
     317            result = rangeMax;
     318
     319        return result;
     320    }
     321
     322    if (constraint.getMin(result) && result > rangeMax)
     323        return false;
     324
     325    if (constraint.getMax(result) && result < rangeMin)
     326        return false;
     327   
     328    return result;
     329}
     330
     331
     332void RealtimeMediaSource::applyConstraint(const MediaConstraint& constraint)
     333{
     334    RealtimeMediaSourceCapabilities& capabilities = *this->capabilities();
     335    switch (constraint.type()) {
     336    case MediaConstraintType::Width: {
     337        if (!capabilities.supportsWidth())
     338            return;
     339
     340        auto widthRange = capabilities.width();
     341        setWidth(value(constraint, widthRange.rangeMin().asInt, widthRange.rangeMax().asInt));
     342        break;
     343    }
     344
     345    case MediaConstraintType::Height: {
     346        if (!capabilities.supportsHeight())
     347            return;
     348
     349        auto heightRange = capabilities.height();
     350        setHeight(value(constraint, heightRange.rangeMin().asInt, heightRange.rangeMax().asInt));
     351        break;
     352    }
     353
     354    case MediaConstraintType::FrameRate: {
     355        if (!capabilities.supportsFrameRate())
     356            return;
     357
     358        auto rateRange = capabilities.frameRate();
     359        setFrameRate(value(constraint, rateRange.rangeMin().asDouble, rateRange.rangeMax().asDouble));
     360        break;
     361    }
     362
     363    case MediaConstraintType::AspectRatio: {
     364        if (!capabilities.supportsAspectRatio())
     365            return;
     366
     367        auto range = capabilities.aspectRatio();
     368        setAspectRatio(value(constraint, range.rangeMin().asDouble, range.rangeMax().asDouble));
     369        break;
     370    }
     371
     372    case MediaConstraintType::Volume: {
     373        if (!capabilities.supportsVolume())
     374            return;
     375
     376        auto range = capabilities.volume();
     377        // std::pair<T, T> valuesForRange(constraint, range.rangeMin().asDouble, range.rangeMax().asDouble)
     378        setVolume(value(constraint, range.rangeMin().asDouble, range.rangeMax().asDouble));
     379        break;
     380    }
     381
     382    case MediaConstraintType::SampleRate: {
     383        if (!capabilities.supportsSampleRate())
     384            return;
     385
     386        auto range = capabilities.sampleRate();
     387        setSampleRate(value(constraint, range.rangeMin().asDouble, range.rangeMax().asDouble));
     388        break;
     389    }
     390
     391    case MediaConstraintType::SampleSize: {
     392        if (!capabilities.supportsSampleSize())
     393            return;
     394
     395        auto range = capabilities.sampleSize();
     396        setSampleSize(value(constraint, range.rangeMin().asDouble, range.rangeMax().asDouble));
     397        break;
     398    }
     399
     400    case MediaConstraintType::EchoCancellation:
     401        if (!capabilities.supportsEchoCancellation())
     402            return;
     403
     404        bool setting;
     405        if (constraint.getExact(setting) || constraint.getIdeal(setting))
     406            setEchoCancellation(setting);
     407        break;
     408
     409    case MediaConstraintType::FacingMode: {
     410        if (!capabilities.supportsFacingMode())
     411            return;
     412
     413        auto& supportedModes = capabilities.facingMode();
     414        std::function<bool(MediaConstraint::ConstraintType, const String&)> filter = [supportedModes](MediaConstraint::ConstraintType, const String& modeString) {
     415            auto mode = RealtimeMediaSourceSettings::videoFacingModeEnum(modeString);
     416            for (auto& supportedMode : supportedModes) {
     417                if (mode == supportedMode)
     418                    return true;
     419            }
     420            return false;
     421        };
     422
     423        auto modeString = constraint.find(filter);
     424        if (!modeString.isEmpty())
     425            setFacingMode(RealtimeMediaSourceSettings::videoFacingModeEnum(modeString));
     426        break;
     427    }
     428
     429    case MediaConstraintType::DeviceId:
     430    case MediaConstraintType::GroupId:
     431        // There is nothing to do here, neither can be changed.
     432        break;
     433
     434    case MediaConstraintType::Unknown:
     435        break;
     436    }
     437}
     438
     439void RealtimeMediaSource::applyConstraints(const MediaConstraints& constraints, SuccessHandler successHandler, FailureHandler failureHandler)
     440{
     441    ASSERT(constraints.isValid());
     442
     443    auto& mandatoryConstraints = constraints.mandatoryConstraints();
     444    for (auto& nameConstraintPair : mandatoryConstraints) {
     445        auto& constraint = *nameConstraintPair.value;
     446        if (supportsConstraint(constraint) == ConstraintSupport::Unsupported) {
     447            failureHandler(constraint.name(), "Constraint not supported");
     448            return;
     449        }
     450    }
     451
     452    for (auto& nameConstraintPair : mandatoryConstraints)
     453        applyConstraint(*nameConstraintPair.value);
     454
     455    successHandler();
     456}
     457
     458void RealtimeMediaSource::setWidth(int width)
     459{
     460    if (width == m_size.width())
     461        return;
     462
     463    int height = m_aspectRatio ? width / m_aspectRatio : m_size.height();
     464    if (!applySize(IntSize(width, height)))
     465        return;
     466
     467    m_size.setWidth(width);
     468    if (m_aspectRatio)
     469        m_size.setHeight(width / m_aspectRatio);
     470
     471    settingsDidChange();
     472}
     473
     474void RealtimeMediaSource::setHeight(int height)
     475{
     476    if (height == m_size.height())
     477        return;
     478
     479    int width = m_aspectRatio ? height * m_aspectRatio : m_size.width();
     480    if (!applySize(IntSize(width, height)))
     481        return;
     482
     483    if (m_aspectRatio)
     484        m_size.setWidth(width);
     485    m_size.setHeight(height);
     486
     487    settingsDidChange();
     488}
     489
     490void RealtimeMediaSource::setFrameRate(double rate)
     491{
     492    if (m_frameRate == rate || !applyFrameRate(rate))
     493        return;
     494
     495    m_frameRate = rate;
     496    settingsDidChange();
     497}
     498
     499void RealtimeMediaSource::setAspectRatio(double ratio)
     500{
     501    if (m_aspectRatio == ratio || !applyAspectRatio(ratio))
     502        return;
     503
     504    m_aspectRatio = ratio;
     505    m_size.setHeight(m_size.width() / ratio);
     506    settingsDidChange();
     507}
     508
     509void RealtimeMediaSource::setFacingMode(RealtimeMediaSourceSettings::VideoFacingMode mode)
     510{
     511    if (m_facingMode == mode || !applyFacingMode(mode))
     512        return;
     513
     514    m_facingMode = mode;
     515    settingsDidChange();
     516}
     517
     518void RealtimeMediaSource::setVolume(double volume)
     519{
     520    if (m_volume == volume || !applyVolume(volume))
     521        return;
     522
     523    m_volume = volume;
     524    settingsDidChange();
     525}
     526
     527void RealtimeMediaSource::setSampleRate(double rate)
     528{
     529    if (m_sampleRate == rate || !applySampleRate(rate))
     530        return;
     531
     532    m_sampleRate = rate;
     533    settingsDidChange();
     534}
     535
     536void RealtimeMediaSource::setSampleSize(double size)
     537{
     538    if (m_sampleSize == size || !applySampleSize(size))
     539        return;
     540
     541    m_sampleSize = size;
     542    settingsDidChange();
     543}
     544
     545void RealtimeMediaSource::setEchoCancellation(bool echoCancellation)
     546{
     547    if (m_echoCancellation == echoCancellation || !applyEchoCancellation(echoCancellation))
     548        return;
     549
     550    m_echoCancellation = echoCancellation;
     551    settingsDidChange();
     552}
     553
     554void RealtimeMediaSource::scheduleDeferredTask(std::function<void()>&& function)
     555{
     556    ASSERT(function);
     557    callOnMainThread([weakThis = createWeakPtr(), function = WTFMove(function)] {
     558        if (!weakThis)
     559            return;
     560
     561        function();
     562    });
     563}
     564
    137565} // namespace WebCore
    138566
  • trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h

    r203739 r205348  
    4343#include "PlatformLayer.h"
    4444#include "RealtimeMediaSourceCapabilities.h"
     45#include <wtf/Lock.h>
    4546#include <wtf/RefCounted.h>
    4647#include <wtf/Vector.h>
     48#include <wtf/WeakPtr.h>
    4749#include <wtf/text/WTFString.h>
    4850
     
    5153class FloatRect;
    5254class GraphicsContext;
    53 class MediaConstraints;
    5455class MediaStreamPrivate;
    5556class RealtimeMediaSourceSettings;
     
    9192    virtual RefPtr<RealtimeMediaSourceCapabilities> capabilities() = 0;
    9293    virtual const RealtimeMediaSourceSettings& settings() = 0;
    93     void settingsDidChange();
     94
     95    using SuccessHandler = std::function<void()>;
     96    using FailureHandler = std::function<void(const String& badConstraint, const String& errorString)>;
     97    void applyConstraints(const MediaConstraints&, SuccessHandler, FailureHandler);
     98
     99    virtual void settingsDidChange();
    94100    void mediaDataUpdated(MediaSample&);
    95101   
     
    123129    virtual void paintCurrentFrameInContext(GraphicsContext&, const FloatRect&) { }
    124130
     131    void setWidth(int);
     132    void setHeight(int);
     133    const IntSize& size() const { return m_size; }
     134    virtual bool applySize(const IntSize&) { return false; }
     135
     136    double frameRate() const { return m_frameRate; }
     137    void setFrameRate(double);
     138    virtual bool applyFrameRate(double) { return false; }
     139
     140    double aspectRatio() const { return m_aspectRatio; }
     141    void setAspectRatio(double);
     142    virtual bool applyAspectRatio(double) { return false; }
     143
     144    RealtimeMediaSourceSettings::VideoFacingMode facingMode() const { return m_facingMode; }
     145    void setFacingMode(RealtimeMediaSourceSettings::VideoFacingMode);
     146    virtual bool applyFacingMode(RealtimeMediaSourceSettings::VideoFacingMode) { return false; }
     147
     148    double volume() const { return m_volume; }
     149    void setVolume(double);
     150    virtual bool applyVolume(double) { return false; }
     151
     152    double sampleRate() const { return m_sampleRate; }
     153    void setSampleRate(double);
     154    virtual bool applySampleRate(double) { return false; }
     155
     156    double sampleSize() const { return m_sampleSize; }
     157    void setSampleSize(double);
     158    virtual bool applySampleSize(double) { return false; }
     159
     160    bool echoCancellation() const { return m_echoCancellation; }
     161    void setEchoCancellation(bool);
     162    virtual bool applyEchoCancellation(bool) { return false; }
     163
    125164protected:
    126165    RealtimeMediaSource(const String& id, Type, const String& name);
    127166
     167    void scheduleDeferredTask(std::function<void()>&&);
     168
    128169    bool m_muted { false };
    129170
    130171private:
     172    WeakPtr<RealtimeMediaSource> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
     173
     174    enum ConstraintSupport { Ignored, Supported, Unsupported };
     175    ConstraintSupport supportsConstraint(const MediaConstraint&);
     176    void applyConstraint(const MediaConstraint&);
     177
     178    WeakPtrFactory<RealtimeMediaSource> m_weakPtrFactory;
     179    Lock m_lock;
     180
    131181    String m_id;
    132182    String m_persistentID;
    133183    Type m_type;
    134184    String m_name;
     185    Vector<Observer*> m_observers;
     186    IntSize m_size;
     187    double m_frameRate { 30 };
     188    double m_aspectRatio { 0 };
     189    double m_volume { 1 };
     190    double m_sampleRate { 0 };
     191    double m_sampleSize { 0 };
     192    unsigned m_fitnessScore { 0 };
     193    RealtimeMediaSourceSettings::VideoFacingMode m_facingMode { RealtimeMediaSourceSettings::User};
     194
     195    bool m_echoCancellation { false };
    135196    bool m_stopped { false };
    136     Vector<Observer*> m_observers;
    137 
    138197    bool m_readonly { false };
    139198    bool m_remote { false };
    140    
    141     unsigned m_fitnessScore { 0 };
     199    bool m_pendingSettingsDidChangeNotification { false };
     200    bool m_suppressNotifications { true };
    142201};
    143202
  • trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceCapabilities.h

    r193389 r205348  
    4949
    5050    union ValueUnion {
    51         unsigned long asULong;
     51        int asInt;
    5252        double asDouble;
    5353    };
     
    6464    }
    6565
    66     CapabilityValueOrRange(unsigned long value)
     66    CapabilityValueOrRange(int value)
    6767        : m_type(ULong)
    6868    {
    69         m_minOrValue.asULong = value;
     69        m_minOrValue.asInt = value;
    7070    }
    7171
     
    7777    }
    7878   
    79     CapabilityValueOrRange(unsigned long min, unsigned long max)
     79    CapabilityValueOrRange(int min, int max)
    8080        : m_type(ULongRange)
    8181    {
    82         m_minOrValue.asULong = min;
    83         m_max.asULong = max;
     82        m_minOrValue.asInt = min;
     83        m_max.asInt = max;
    8484    }
    8585
  • trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.cpp

    r192954 r205348  
    3838namespace WebCore {
    3939
     40static const AtomicString& userFacing()
     41{
     42    static NeverDestroyed<AtomicString> userFacing("user", AtomicString::ConstructFromLiteral);
     43    return userFacing;
     44}
     45static const AtomicString& environmentFacing()
     46{
     47    static NeverDestroyed<AtomicString> environmentFacing("environment", AtomicString::ConstructFromLiteral);
     48    return environmentFacing;
     49}
     50
     51static const AtomicString& leftFacing()
     52{
     53    static NeverDestroyed<AtomicString> leftFacing("left", AtomicString::ConstructFromLiteral);
     54    return leftFacing;
     55}
     56
     57static const AtomicString& rightFacing()
     58{
     59    static NeverDestroyed<AtomicString> rightFacing("right", AtomicString::ConstructFromLiteral);
     60    return rightFacing;
     61}
     62
    4063const AtomicString& RealtimeMediaSourceSettings::facingMode(RealtimeMediaSourceSettings::VideoFacingMode mode)
    4164{
    42     static NeverDestroyed<AtomicString> userFacing("user", AtomicString::ConstructFromLiteral);
    43     static NeverDestroyed<AtomicString> environmentFacing("environment", AtomicString::ConstructFromLiteral);
    44     static NeverDestroyed<AtomicString> leftFacing("left", AtomicString::ConstructFromLiteral);
    45     static NeverDestroyed<AtomicString> rightFacing("right", AtomicString::ConstructFromLiteral);
    46    
    4765    switch (mode) {
    4866    case RealtimeMediaSourceSettings::User:
    49         return userFacing;
     67        return userFacing();
    5068    case RealtimeMediaSourceSettings::Environment:
    51         return environmentFacing;
     69        return environmentFacing();
    5270    case RealtimeMediaSourceSettings::Left:
    53         return leftFacing;
     71        return leftFacing();
    5472    case RealtimeMediaSourceSettings::Right:
    55         return rightFacing;
     73        return rightFacing();
    5674    case RealtimeMediaSourceSettings::Unknown:
    5775        return emptyAtom;
     
    6280}
    6381
     82RealtimeMediaSourceSettings::VideoFacingMode RealtimeMediaSourceSettings::videoFacingModeEnum(const String& mode)
     83{
     84    if (mode == userFacing())
     85        return RealtimeMediaSourceSettings::User;
     86    if (mode == environmentFacing())
     87        return RealtimeMediaSourceSettings::Environment;
     88    if (mode == leftFacing())
     89        return RealtimeMediaSourceSettings::Left;
     90    if (mode == rightFacing())
     91        return RealtimeMediaSourceSettings::Right;
     92
     93    return RealtimeMediaSourceSettings::Unknown;
     94}
     95
    6496} // namespace WebCore
    6597
  • trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h

    r193389 r205348  
    4242
    4343    static const AtomicString& facingMode(RealtimeMediaSourceSettings::VideoFacingMode);
     44
     45    static RealtimeMediaSourceSettings::VideoFacingMode videoFacingModeEnum(const String&);
    4446
    4547    explicit RealtimeMediaSourceSettings()
  • trunk/Source/WebCore/platform/mediastream/mac/AVAudioCaptureSource.mm

    r203904 r205348  
    8181{
    8282    // FIXME: finish this implementation - https://webkit.org/b/122430
    83     capabilities.setVolume(CapabilityValueOrRange(0, 1.0));
     83    capabilities.setVolume(CapabilityValueOrRange(0.0, 1.0));
    8484}
    8585
  • trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.h

    r202439 r205348  
    3434#include <wtf/Function.h>
    3535#include <wtf/RetainPtr.h>
    36 #include <wtf/WeakPtr.h>
    3736
    3837OBJC_CLASS AVCaptureAudioDataOutput;
     
    6463    bool isProducingData() const override { return m_isRunning; }
    6564
    66     WeakPtr<AVMediaCaptureSource> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
    67 
    6865protected:
    6966    AVMediaCaptureSource(AVCaptureDevice*, const AtomicString&, RealtimeMediaSource::Type, PassRefPtr<MediaConstraints>);
     
    8784    void setAudioSampleBufferDelegate(AVCaptureAudioDataOutput*);
    8885
    89     void scheduleDeferredTask(Function<void ()>&&);
    90 
    9186private:
    9287    void setupSession();
     
    9590    RealtimeMediaSourceSettings m_currentSettings;
    9691    RealtimeMediaSourceSupportedConstraints m_supportedConstraints;
    97     WeakPtrFactory<AVMediaCaptureSource> m_weakPtrFactory;
    9892    RetainPtr<WebCoreAVMediaCaptureSourceObserver> m_objcObserver;
    9993    RefPtr<MediaConstraints> m_constraints;
  • trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm

    r204466 r205348  
    125125AVMediaCaptureSource::AVMediaCaptureSource(AVCaptureDeviceTypedef* device, const AtomicString& id, RealtimeMediaSource::Type type, PassRefPtr<MediaConstraints> constraints)
    126126    : RealtimeMediaSource(id, type, emptyString())
    127     , m_weakPtrFactory(this)
    128127    , m_objcObserver(adoptNS([[WebCoreAVMediaCaptureSourceObserver alloc] initWithCallback:this]))
    129128    , m_constraints(constraints)
     
    238237{
    239238    [audioOutput setSampleBufferDelegate:m_objcObserver.get() queue:globaAudioCaptureSerialQueue()];
    240 }
    241 
    242 void AVMediaCaptureSource::scheduleDeferredTask(Function<void ()>&& function)
    243 {
    244     ASSERT(function);
    245     callOnMainThread([weakThis = createWeakPtr(), function = WTFMove(function)] {
    246         if (!weakThis)
    247             return;
    248 
    249         function();
    250     });
    251239}
    252240
  • trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.h

    r204516 r205348  
    5858    void updateSettings(RealtimeMediaSourceSettings&) override;
    5959
     60    bool applySize(const IntSize&) override;
     61    bool applyFrameRate(double) override;
     62
    6063    void initializeCapabilities(RealtimeMediaSourceCapabilities&) override;
    6164    void initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints&) override;
    6265
    63     bool applyConstraints(MediaConstraints*);
    6466    bool setFrameRateConstraint(double minFrameRate, double maxFrameRate);
    6567
  • trunk/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm

    r204595 r205348  
    129129}
    130130
    131 bool AVVideoCaptureSource::setFrameRateConstraint(double minFrameRate, double maxFrameRate)
     131bool AVVideoCaptureSource::applySize(const IntSize& size)
     132{
     133    NSString *preset = AVCaptureSessionInfo(session()).bestSessionPresetForVideoDimensions(size.width(), size.height());
     134    if (!preset || ![session() canSetSessionPreset:preset]) {
     135        LOG(Media, "AVVideoCaptureSource::applySize%p), unable find or set preset for width: %i, height: %i", this, size.width(), size.height());
     136        return false;
     137    }
     138
     139    NSError *error = nil;
     140    @try {
     141        [session() setSessionPreset:preset];
     142
     143    } @catch(NSException *exception) {
     144        LOG(Media, "AVVideoCaptureSource::applySize(%p), exception thrown configuring device: <%s> %s", this, [[exception name] UTF8String], [[exception reason] UTF8String]);
     145        return false;
     146    }
     147
     148    if (error) {
     149        LOG(Media, "AVVideoCaptureSource::applySize(%p), failed to lock video device for configuration: %s", this, [[error localizedDescription] UTF8String]);
     150        return false;
     151    }
     152
     153    LOG(Media, "AVVideoCaptureSource::applySize(%p) - set frame size to %i x %i", this, size.width(), size.height());
     154    return true;
     155}
     156
     157bool AVVideoCaptureSource::applyFrameRate(double rate)
    132158{
    133159    AVFrameRateRange *bestFrameRateRange = 0;
    134 
    135160    for (AVFrameRateRange *frameRateRange in [[device() activeFormat] videoSupportedFrameRateRanges]) {
    136         if (!maxFrameRate) {
    137             if (minFrameRate == [frameRateRange minFrameRate])
    138                 bestFrameRateRange = frameRateRange;
    139         } else if (minFrameRate >= [frameRateRange minFrameRate] && maxFrameRate <= [frameRateRange maxFrameRate]) {
    140             if (CMTIME_COMPARE_INLINE([frameRateRange minFrameDuration], >, [bestFrameRateRange minFrameDuration]))
     161        if (rate >= [frameRateRange minFrameRate] && rate <= [frameRateRange maxFrameRate]) {
     162            if (!bestFrameRateRange || CMTIME_COMPARE_INLINE([frameRateRange minFrameDuration], >, [bestFrameRateRange minFrameDuration]))
    141163                bestFrameRateRange = frameRateRange;
    142164        }
    143165    }
    144    
     166
    145167    if (!bestFrameRateRange) {
    146         LOG(Media, "AVVideoCaptureSource::setFrameRateConstraint(%p), frame rate range %f..%f not supported by video device", this, minFrameRate, maxFrameRate);
    147         return false;
    148     }
    149    
     168        LOG(Media, "AVVideoCaptureSource::applyFrameRate(%p), frame rate %f not supported by video device", this, rate);
     169        return false;
     170    }
     171
    150172    NSError *error = nil;
    151173    @try {
    152174        if ([device() lockForConfiguration:&error]) {
    153175            [device() setActiveVideoMinFrameDuration:[bestFrameRateRange minFrameDuration]];
    154             if (maxFrameRate)
    155                 [device() setActiveVideoMaxFrameDuration:[bestFrameRateRange maxFrameDuration]];
    156176            [device() unlockForConfiguration];
    157177        }
    158178    } @catch(NSException *exception) {
    159         LOG(Media, "AVVideoCaptureSource::setFrameRateConstraint(%p), exception thrown configuring device: <%s> %s", this, [[exception name] UTF8String], [[exception reason] UTF8String]);
    160         return false;
    161     }
    162    
     179        LOG(Media, "AVVideoCaptureSource::applyFrameRate(%p), exception thrown configuring device: <%s> %s", this, [[exception name] UTF8String], [[exception reason] UTF8String]);
     180        return false;
     181    }
     182
    163183    if (error) {
    164         LOG(Media, "AVVideoCaptureSource::setFrameRateConstraint(%p), failed to lock video device for configuration: %s", this, [[error localizedDescription] UTF8String]);
    165         return false;
    166     }
    167 
    168     LOG(Media, "AVVideoCaptureSource::setFrameRateConstraint(%p) - set frame rate range to %f..%f", this, minFrameRate, maxFrameRate);
    169     return true;
    170 }
    171 
    172 bool AVVideoCaptureSource::applyConstraints(MediaConstraints* constraints)
    173 {
    174     ASSERT(constraints);
    175 
    176     // FIXME: Below needs to be refactored for https://bugs.webkit.org/show_bug.cgi?id=160579.
    177 
    178     auto& mandatoryConstraints = constraints->mandatoryConstraints();
    179     int intValue;
    180 
    181     String widthConstraintName = RealtimeMediaSourceSupportedConstraints::nameForConstraint(MediaConstraintType::Width);
    182     auto widthConstraint = mandatoryConstraints.get(widthConstraintName);
    183     Optional<int> width;
    184     if (widthConstraint && widthConstraint->getExact(intValue))
    185         width = intValue;
    186 
    187     String heightConstraintName = RealtimeMediaSourceSupportedConstraints::nameForConstraint(MediaConstraintType::Height);
    188     auto heightConstraint = mandatoryConstraints.get(heightConstraintName);
    189     Optional<int> height;
    190     if (heightConstraint && heightConstraint->getExact(intValue))
    191         height = intValue;
    192    
    193     if (width && height) {
    194         NSString *preset = AVCaptureSessionInfo(session()).bestSessionPresetForVideoDimensions(width.value(), height.value());
    195         if (!preset || ![session() canSetSessionPreset:preset]) {
    196             LOG(Media, "AVVideoCaptureSource::applyConstraints(%p), unable find or set preset for width: %i, height: %i", this, width.value(), height.value());
    197             return false;
    198         }
    199 
    200         [session() setSessionPreset:preset];
    201     }
    202 
    203     String frameRateConstraintName = RealtimeMediaSourceSupportedConstraints::nameForConstraint(MediaConstraintType::FrameRate);
    204     auto frameRateConstraint = mandatoryConstraints.get(frameRateConstraintName);
    205 
    206     Optional<double> frameRate;
    207     double doubleValue;
    208     if (frameRateConstraint && frameRateConstraint->getExact(doubleValue))
    209         frameRate = doubleValue;
    210 
    211     if (frameRate && !setFrameRateConstraint(frameRate.value(), 0)) {
    212         LOG(Media, "AVVideoCaptureSource::applyConstraints(%p), unable set frame rate to %f", this, frameRate.value());
    213         return false;
    214     }
    215 
     184        LOG(Media, "AVVideoCaptureSource::applyFrameRate(%p), failed to lock video device for configuration: %s", this, [[error localizedDescription] UTF8String]);
     185        return false;
     186    }
     187
     188    LOG(Media, "AVVideoCaptureSource::applyFrameRate(%p) - set frame rate range to %f", this, rate);
    216189    return true;
    217190}
     
    227200
    228201    [session() addInput:videoIn.get()];
    229 
    230     if (constraints())
    231         applyConstraints(constraints());
    232202
    233203    RetainPtr<AVCaptureVideoDataOutputType> videoOutput = adoptNS([allocAVCaptureVideoDataOutputInstance() init]);
  • trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp

    r201549 r205348  
    6060void MockRealtimeAudioSource::updateSettings(RealtimeMediaSourceSettings& settings)
    6161{
    62     settings.setVolume(50);
     62    settings.setVolume(volume());
     63    settings.setEchoCancellation(echoCancellation());
    6364}
    6465
    6566void MockRealtimeAudioSource::initializeCapabilities(RealtimeMediaSourceCapabilities& capabilities)
    6667{
    67     capabilities.setVolume(CapabilityValueOrRange(0, 1.0));
     68    capabilities.setVolume(CapabilityValueOrRange(0.0, 1.0));
    6869    capabilities.setEchoCancellation(RealtimeMediaSourceCapabilities::EchoCancellation::ReadWrite);
    6970}
  • trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.h

    r204466 r205348  
    5252
    5353private:
     54
     55    bool applyVolume(double) override { return true; }
     56    bool applySampleRate(double) override { return true; }
     57    bool applySampleSize(double) override { return true; }
     58    bool applyEchoCancellation(bool) override { return true; }
     59
    5460    void updateSettings(RealtimeMediaSourceSettings&) override;
    5561    void initializeCapabilities(RealtimeMediaSourceCapabilities&) override;
  • trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp

    r194397 r205348  
    125125}
    126126
    127 
    128127} // namespace WebCore
    129128
  • trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.h

    r204466 r205348  
    3838namespace WebCore {
    3939
    40 class FloatRect;
    41 class GraphicsContext;
    4240class TrackSourceInfo;
    4341
  • trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp

    r204654 r205348  
    6666    , m_timer(RunLoop::current(), this, &MockRealtimeVideoSource::generateFrame)
    6767{
     68    setFrameRate(30);
    6869    m_dashWidths.reserveInitialCapacity(2);
    6970    m_dashWidths.uncheckedAppend(6);
     
    7475{
    7576    MockRealtimeMediaSource::startProducingData();
    76     if (m_size.isEmpty())
    77         setSize(IntSize(640, 480));
     77    if (size().isEmpty()) {
     78        setWidth(640);
     79        setHeight(480);
     80    }
    7881
    7982    m_startTime = monotonicallyIncreasingTime();
    80     m_timer.startRepeating(std::chrono::milliseconds(lround(1000 / m_frameRate)));
     83    m_timer.startRepeating(std::chrono::milliseconds(lround(1000 / frameRate())));
    8184}
    8285
     
    99102void MockRealtimeVideoSource::updateSettings(RealtimeMediaSourceSettings& settings)
    100103{
    101     settings.setFacingMode(RealtimeMediaSourceSettings::User);
    102     settings.setFrameRate(m_frameRate);
    103     settings.setWidth(m_size.width());
    104     settings.setHeight(m_size.height());
    105     settings.setAspectRatio(static_cast<float>(m_size.width()) / m_size.height());
     104    settings.setFacingMode(facingMode());
     105    settings.setFrameRate(frameRate());
     106    IntSize size = this->size();
     107    settings.setWidth(size.width());
     108    settings.setHeight(size.height());
     109    if (aspectRatio())
     110        settings.setAspectRatio(aspectRatio());
    106111}
    107112
     
    110115    capabilities.addFacingMode(RealtimeMediaSourceSettings::User);
    111116    capabilities.addFacingMode(RealtimeMediaSourceSettings::Environment);
    112     capabilities.setWidth(CapabilityValueOrRange(320UL, 1920UL));
    113     capabilities.setHeight(CapabilityValueOrRange(240UL, 1080UL));
     117    capabilities.setWidth(CapabilityValueOrRange(320, 1920));
     118    capabilities.setHeight(CapabilityValueOrRange(240, 1080));
    114119    capabilities.setFrameRate(CapabilityValueOrRange(15.0, 60.0));
    115120    capabilities.setAspectRatio(CapabilityValueOrRange(4 / 3.0, 16 / 9.0));
     
    125130}
    126131
    127 void MockRealtimeVideoSource::setFrameRate(float rate)
    128 {
    129     if (m_frameRate == rate)
    130         return;
    131 
    132     m_frameRate = rate;
     132bool MockRealtimeVideoSource::applyFrameRate(double rate)
     133{
    133134    if (m_timer.isActive())
    134         m_timer.startRepeating(std::chrono::milliseconds(lround(1000 / m_frameRate)));
    135 
    136     settingsDidChange();
    137 }
    138 
    139 void MockRealtimeVideoSource::setSize(const IntSize& size)
    140 {
    141     if (size == m_size)
    142         return;
    143 
    144     m_size = size;
    145 
    146     m_baseFontSize = m_size.height() * .08;
     135        m_timer.startRepeating(std::chrono::milliseconds(lround(1000 / rate)));
     136
     137    updatePlatformLayer();
     138    updateSampleBuffer();
     139    return true;
     140}
     141
     142bool MockRealtimeVideoSource::applySize(const IntSize& size)
     143{
     144    m_baseFontSize = size.height() * .08;
    147145    FontCascadeDescription fontDescription;
    148146    fontDescription.setOneFamily("Courier");
     
    169167    updatePlatformLayer();
    170168
    171     settingsDidChange();
     169    return true;
    172170}
    173171
    174172void MockRealtimeVideoSource::drawAnimation(GraphicsContext& context)
    175173{
    176     float radius = m_size.width() * .09;
    177     FloatPoint location(m_size.width() * .8, m_size.height() * .3);
     174    float radius = size().width() * .09;
     175    FloatPoint location(size().width() * .8, size().height() * .3);
    178176
    179177    m_path.clear();
     
    185183    context.fillPath(m_path);
    186184
    187     float endAngle = piFloat * (((fmod(m_frameNumber, m_frameRate) + 0.5) * (2.0 / m_frameRate)) + 1);
     185    float endAngle = piFloat * (((fmod(m_frameNumber, frameRate()) + 0.5) * (2.0 / frameRate())) + 1);
    188186    m_path.clear();
    189187    m_path.moveTo(location);
     
    203201    static const RGBA32 green = 0xff008000;
    204202
    205     float boxSize = m_size.width() * .035;
    206     float boxTop = m_size.height() * .6;
    207 
    208     m_path.clear();
    209     FloatRect frameRect(2, 2, m_size.width() - 3, m_size.height() - 3);
     203    IntSize size = this->size();
     204    float boxSize = size.width() * .035;
     205    float boxTop = size.height() * .6;
     206
     207    m_path.clear();
     208    FloatRect frameRect(2, 2, size.width() - 3, size.height() - 3);
    210209    context.setStrokeColor(Color::white);
    211210    context.setStrokeThickness(3);
     
    218217    m_path.clear();
    219218    m_path.moveTo(FloatPoint(0, boxTop + boxSize));
    220     m_path.addLineTo(FloatPoint(m_size.width(), boxTop + boxSize));
     219    m_path.addLineTo(FloatPoint(size.width(), boxTop + boxSize));
    221220    m_path.closeSubpath();
    222221    context.setStrokeColor(Color::white);
     
    265264    unsigned hours = minutes / 60 % 60;
    266265
    267     FloatPoint timeLocation(m_size.width() * .05, m_size.height() * .15);
     266    IntSize size = this->size();
     267    FloatPoint timeLocation(size.width() * .05, size.height() * .15);
    268268    context.setFillColor(Color::white);
    269269    context.setTextDrawingMode(TextModeFill);
     
    275275    context.drawText(m_timeFont, TextRun((StringView(string))), timeLocation);
    276276
    277     FloatPoint statsLocation(m_size.width() * .65, m_size.height() * .75);
    278     string = String::format("Frame rate: %ufps", m_frameRate);
     277    FloatPoint statsLocation(size.width() * .65, size.height() * .75);
     278    string = String::format("Frame rate: %ffps", frameRate());
    279279    context.drawText(m_statsFont, TextRun((StringView(string))), statsLocation);
    280280
    281     string = String::format("Size: %u x %u", m_size.width(), m_size.height());
     281    string = String::format("Size: %u x %u", size.width(), size.height());
    282282    statsLocation.move(0, m_statsFontSize);
    283283    context.drawText(m_statsFont, TextRun((StringView(string))), statsLocation);
    284284
    285285    const char* camera;
    286     switch (settings().facingMode()) {
     286    switch (facingMode()) {
    287287    case RealtimeMediaSourceSettings::User:
    288288        camera = "User facing";
     
    305305    context.drawText(m_statsFont, TextRun((StringView(string))), statsLocation);
    306306
    307     FloatPoint bipBopLocation(m_size.width() * .6, m_size.height() * .6);
     307    FloatPoint bipBopLocation(size.width() * .6, size.height() * .6);
    308308    unsigned frameMod = m_frameNumber % 60;
    309309    if (frameMod <= 15) {
     
    320320void MockRealtimeVideoSource::generateFrame()
    321321{
    322     GraphicsContext& context = imageBuffer()->context();
     322    ImageBuffer* buffer = imageBuffer();
     323    if (!buffer)
     324        return;
     325
     326    GraphicsContext& context = buffer->context();
    323327    GraphicsContextStateSaver stateSaver(context);
    324328
    325     FloatRect frameRect(FloatPoint(), m_size);
    326     context.fillRect(FloatRect(FloatPoint(), m_size), Color::black);
     329    IntSize size = this->size();
     330    FloatRect frameRect(FloatPoint(), size);
     331    context.fillRect(FloatRect(FloatPoint(), size), Color::black);
    327332
    328333    drawText(context);
     
    339344        return m_imageBuffer.get();
    340345
    341     m_imageBuffer = ImageBuffer::create(m_size, Unaccelerated);
     346    m_imageBuffer = ImageBuffer::create(size(), Unaccelerated);
    342347    if (!m_imageBuffer)
    343348        return nullptr;
     
    369374}
    370375
    371 
    372376} // namespace WebCore
    373377
  • trunk/Source/WebCore/platform/mock/MockRealtimeVideoSource.h

    r203739 r205348  
    5252    virtual ~MockRealtimeVideoSource() { }
    5353
    54     void setSize(const IntSize&);
    55     const IntSize& size() const { return m_size; }
    56 
    57     void setFrameRate(float);
    58 
    5954protected:
    6055    MockRealtimeVideoSource(const String& name = ASCIILiteral("Mock video device"));
     
    7166    void initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints&) override;
    7267
    73     void startProducingData() override;
    74     void stopProducingData() override;
     68    void startProducingData() final;
     69    void stopProducingData() final;
    7570
    7671    void drawAnimation(GraphicsContext&);
    7772    void drawText(GraphicsContext&);
    7873    void drawBoxes(GraphicsContext&);
     74
     75    bool applySize(const IntSize&) override;
     76    bool applyFrameRate(double) override;
     77    bool applyFacingMode(RealtimeMediaSourceSettings::VideoFacingMode) override { return true; }
     78    bool applyAspectRatio(double) override { return true; }
    7979
    8080    PlatformLayer* platformLayer() const override { return nullptr; }
     
    9595    mutable std::unique_ptr<ImageBuffer> m_imageBuffer;
    9696
    97     IntSize m_size;
    9897    Path m_path;
    9998    DashArray m_dashWidths;
     
    102101    double m_elapsedTime { 0 };
    103102
    104     unsigned m_frameRate { 30 };
    105103    unsigned m_frameNumber { 0 };
    106104
Note: See TracChangeset for help on using the changeset viewer.