Changeset 206445 in webkit


Ignore:
Timestamp:
Sep 27, 2016, 10:58:44 AM (9 years ago)
Author:
eric.carlson@apple.com
Message:

[MediaStream] Restructure MediaConstraints classes
https://bugs.webkit.org/show_bug.cgi?id=162571

Reviewed by Jer Noble.

No new tests, no functional changes.

  • Modules/mediastream/MediaConstraintsImpl.cpp:

(WebCore::MediaConstraintsImpl::initialize): Deleted, no longer used.

  • Modules/mediastream/MediaConstraintsImpl.h:
  • bindings/js/JSMediaDevicesCustom.cpp:

(WebCore::createStringConstraint): Return Optional<> instead of RefPtr<>.
(WebCore::createBooleanConstraint): Ditto.
(WebCore::createDoubleConstraint): Ditto.
(WebCore::createIntConstraint): Ditto.
(WebCore::parseMediaTrackConstraintSetForKey): Deal with above change.

  • platform/mediastream/CaptureDeviceManager.cpp:

(CaptureDeviceManager::verifyConstraintsForMediaType): Use constraints.mandatoryConstraints.filter

instead of direct enumeration.

(CaptureDeviceManager::sessionSupportsConstraint): Use downcast<>.
(CaptureDeviceManager::isSupportedFrameRate): Ditto.

  • platform/mediastream/MediaConstraints.cpp:

(WebCore::StringConstraint::find): Lose the ConstraintType parameter.
(WebCore::StringConstraint::merge): Use downcast<>.
(WebCore::FlattenedConstraint::set): Use ConstraintHolder.
(WebCore::FlattenedConstraint::merge): Ditto.
(WebCore::MediaTrackConstraintSetMap::forEach): New.
(WebCore::MediaTrackConstraintSetMap::filter): Ditto.
(WebCore::MediaTrackConstraintSetMap::isEmpty): Ditto.
(WebCore::MediaTrackConstraintSetMap::set): Ditto.
(WebCore::MediaConstraint::copy): Deleted.
(WebCore::IntConstraint::copy): Deleted.
(WebCore::DoubleConstraint::copy): Deleted.
(WebCore::BooleanConstraint::copy): Deleted.
(WebCore::StringConstraint::copy): Deleted.

  • platform/mediastream/MediaConstraints.h:

(WebCore::MediaConstraint::MediaConstraint):
(WebCore::MediaConstraint::isEmpty):
(WebCore::MediaConstraint::isMandatory):
(WebCore::MediaConstraint::merge):
(WebCore::MediaConstraint::isInt):
(WebCore::MediaConstraint::isDouble):
(WebCore::MediaConstraint::isBoolean):
(WebCore::MediaConstraint::isString):
(WebCore::MediaConstraint::dataType):
(WebCore::MediaConstraint::constraintType):
(WebCore::NumericConstraint::getMin):
(WebCore::NumericConstraint::getMax):
(WebCore::NumericConstraint::getExact):
(WebCore::NumericConstraint::getIdeal):
(WebCore::NumericConstraint::fitnessDistance):
(WebCore::NumericConstraint::validForRange):
(WebCore::NumericConstraint::find):
(WebCore::NumericConstraint::NumericConstraint):
(WebCore::NumericConstraint::innerMerge):
(WebCore::FlattenedConstraint::isEmpty):
(WebCore::FlattenedConstraint::iterator::iterator):
(WebCore::FlattenedConstraint::iterator::operator*):
(WebCore::FlattenedConstraint::iterator::operator++):
(WebCore::FlattenedConstraint::iterator::operator==):
(WebCore::FlattenedConstraint::iterator::operator!=):
(WebCore::FlattenedConstraint::begin):
(WebCore::FlattenedConstraint::end):
(WebCore::FlattenedConstraint::ConstraintHolder::create):
(WebCore::FlattenedConstraint::ConstraintHolder::~ConstraintHolder):
(WebCore::FlattenedConstraint::ConstraintHolder::constraint):
(WebCore::FlattenedConstraint::ConstraintHolder::dataType):
(WebCore::FlattenedConstraint::ConstraintHolder::constraintType):
(WebCore::FlattenedConstraint::ConstraintHolder::ConstraintHolder):
(WebCore::MediaConstraint::getMin): Deleted.
(WebCore::MediaConstraint::getMax): Deleted.
(WebCore::MediaConstraint::getExact): Deleted.
(WebCore::MediaConstraint::getIdeal): Deleted.
(WebCore::MediaConstraint::validForRange): Deleted.
(WebCore::MediaConstraint::find): Deleted.
(WebCore::MediaConstraint::fitnessDistance): Deleted.
(WebCore::MediaConstraint::type): Deleted.

  • platform/mediastream/RealtimeMediaSource.cpp:

(WebCore::RealtimeMediaSource::fitnessDistance): Use downcast<>.
(WebCore::applyNumericConstraint):
(WebCore::RealtimeMediaSource::applyConstraint): Ditto.
(WebCore::RealtimeMediaSource::selectSettings): Ditto. Use constraints.mandatoryConstraints.filter

instead of direct enumeration.

(WebCore::RealtimeMediaSource::applyConstraints):
(WebCore::RealtimeMediaSource::setSampleRate): Sample rate is an int, not a double.
(WebCore::RealtimeMediaSource::setSampleSize): Sample size is also an int.

  • platform/mediastream/RealtimeMediaSource.h:
  • platform/mediastream/mac/AVCaptureDeviceManager.mm:

(WebCore::AVCaptureDeviceManager::sessionSupportsConstraint): Use downcast<>.

  • platform/mock/MediaConstraintsMock.cpp:

(WebCore::isIntMediaConstraintSatisfiable): Use downcast<>.
(WebCore::isDoubleMediaConstraintSatisfiable): Ditto.
(WebCore::isBooleanMediaConstraintSatisfiable): Ditto.
(WebCore::isStringMediaConstraintSatisfiable):
(WebCore::isSatisfiable):
(WebCore::MediaConstraintsMock::verifyConstraints): Use constraints.mandatoryConstraints.filter

instead of direct enumeration.

  • platform/mock/MediaConstraintsMock.h:
  • platform/mock/MockRealtimeAudioSource.h:
  • platform/mock/MockRealtimeMediaSourceCenter.cpp:

(WebCore::MockRealtimeMediaSourceCenter::createMediaStream):

Location:
trunk/Source/WebCore
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r206444 r206445  
     12016-09-27  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [MediaStream] Restructure MediaConstraints classes
     4        https://bugs.webkit.org/show_bug.cgi?id=162571
     5
     6        Reviewed by Jer Noble.
     7
     8        No new tests, no functional changes.
     9
     10        * Modules/mediastream/MediaConstraintsImpl.cpp:
     11        (WebCore::MediaConstraintsImpl::initialize): Deleted, no longer used.
     12        * Modules/mediastream/MediaConstraintsImpl.h:
     13
     14        * bindings/js/JSMediaDevicesCustom.cpp:
     15        (WebCore::createStringConstraint): Return Optional<> instead of RefPtr<>.
     16        (WebCore::createBooleanConstraint): Ditto.
     17        (WebCore::createDoubleConstraint): Ditto.
     18        (WebCore::createIntConstraint): Ditto.
     19        (WebCore::parseMediaTrackConstraintSetForKey): Deal with above change.
     20
     21        * platform/mediastream/CaptureDeviceManager.cpp:
     22        (CaptureDeviceManager::verifyConstraintsForMediaType): Use constraints.mandatoryConstraints.filter
     23          instead of direct enumeration.
     24        (CaptureDeviceManager::sessionSupportsConstraint): Use downcast<>.
     25        (CaptureDeviceManager::isSupportedFrameRate): Ditto.
     26
     27        * platform/mediastream/MediaConstraints.cpp:
     28        (WebCore::StringConstraint::find): Lose the ConstraintType parameter.
     29        (WebCore::StringConstraint::merge): Use downcast<>.
     30        (WebCore::FlattenedConstraint::set): Use ConstraintHolder.
     31        (WebCore::FlattenedConstraint::merge): Ditto.
     32        (WebCore::MediaTrackConstraintSetMap::forEach): New.
     33        (WebCore::MediaTrackConstraintSetMap::filter): Ditto.
     34        (WebCore::MediaTrackConstraintSetMap::isEmpty): Ditto.
     35        (WebCore::MediaTrackConstraintSetMap::set): Ditto.
     36        (WebCore::MediaConstraint::copy): Deleted.
     37        (WebCore::IntConstraint::copy): Deleted.
     38        (WebCore::DoubleConstraint::copy): Deleted.
     39        (WebCore::BooleanConstraint::copy): Deleted.
     40        (WebCore::StringConstraint::copy): Deleted.
     41        * platform/mediastream/MediaConstraints.h:
     42        (WebCore::MediaConstraint::MediaConstraint):
     43        (WebCore::MediaConstraint::isEmpty):
     44        (WebCore::MediaConstraint::isMandatory):
     45        (WebCore::MediaConstraint::merge):
     46        (WebCore::MediaConstraint::isInt):
     47        (WebCore::MediaConstraint::isDouble):
     48        (WebCore::MediaConstraint::isBoolean):
     49        (WebCore::MediaConstraint::isString):
     50        (WebCore::MediaConstraint::dataType):
     51        (WebCore::MediaConstraint::constraintType):
     52        (WebCore::NumericConstraint::getMin):
     53        (WebCore::NumericConstraint::getMax):
     54        (WebCore::NumericConstraint::getExact):
     55        (WebCore::NumericConstraint::getIdeal):
     56        (WebCore::NumericConstraint::fitnessDistance):
     57        (WebCore::NumericConstraint::validForRange):
     58        (WebCore::NumericConstraint::find):
     59        (WebCore::NumericConstraint::NumericConstraint):
     60        (WebCore::NumericConstraint::innerMerge):
     61        (WebCore::FlattenedConstraint::isEmpty):
     62        (WebCore::FlattenedConstraint::iterator::iterator):
     63        (WebCore::FlattenedConstraint::iterator::operator*):
     64        (WebCore::FlattenedConstraint::iterator::operator++):
     65        (WebCore::FlattenedConstraint::iterator::operator==):
     66        (WebCore::FlattenedConstraint::iterator::operator!=):
     67        (WebCore::FlattenedConstraint::begin):
     68        (WebCore::FlattenedConstraint::end):
     69        (WebCore::FlattenedConstraint::ConstraintHolder::create):
     70        (WebCore::FlattenedConstraint::ConstraintHolder::~ConstraintHolder):
     71        (WebCore::FlattenedConstraint::ConstraintHolder::constraint):
     72        (WebCore::FlattenedConstraint::ConstraintHolder::dataType):
     73        (WebCore::FlattenedConstraint::ConstraintHolder::constraintType):
     74        (WebCore::FlattenedConstraint::ConstraintHolder::ConstraintHolder):
     75        (WebCore::MediaConstraint::getMin): Deleted.
     76        (WebCore::MediaConstraint::getMax): Deleted.
     77        (WebCore::MediaConstraint::getExact): Deleted.
     78        (WebCore::MediaConstraint::getIdeal): Deleted.
     79        (WebCore::MediaConstraint::validForRange): Deleted.
     80        (WebCore::MediaConstraint::find): Deleted.
     81        (WebCore::MediaConstraint::fitnessDistance): Deleted.
     82        (WebCore::MediaConstraint::type): Deleted.
     83
     84        * platform/mediastream/RealtimeMediaSource.cpp:
     85        (WebCore::RealtimeMediaSource::fitnessDistance): Use downcast<>.
     86        (WebCore::applyNumericConstraint):
     87        (WebCore::RealtimeMediaSource::applyConstraint): Ditto.
     88        (WebCore::RealtimeMediaSource::selectSettings): Ditto. Use constraints.mandatoryConstraints.filter
     89          instead of direct enumeration.
     90        (WebCore::RealtimeMediaSource::applyConstraints):
     91        (WebCore::RealtimeMediaSource::setSampleRate): Sample rate is an int, not a double.
     92        (WebCore::RealtimeMediaSource::setSampleSize): Sample size is also an int.
     93        * platform/mediastream/RealtimeMediaSource.h:
     94
     95        * platform/mediastream/mac/AVCaptureDeviceManager.mm:
     96        (WebCore::AVCaptureDeviceManager::sessionSupportsConstraint): Use downcast<>.
     97
     98        * platform/mock/MediaConstraintsMock.cpp:
     99        (WebCore::isIntMediaConstraintSatisfiable): Use downcast<>.
     100        (WebCore::isDoubleMediaConstraintSatisfiable): Ditto.
     101        (WebCore::isBooleanMediaConstraintSatisfiable): Ditto.
     102        (WebCore::isStringMediaConstraintSatisfiable):
     103        (WebCore::isSatisfiable):
     104        (WebCore::MediaConstraintsMock::verifyConstraints): Use constraints.mandatoryConstraints.filter
     105          instead of direct enumeration.
     106        * platform/mock/MediaConstraintsMock.h:
     107
     108        * platform/mock/MockRealtimeAudioSource.h:
     109        * platform/mock/MockRealtimeMediaSourceCenter.cpp:
     110        (WebCore::MockRealtimeMediaSourceCenter::createMediaStream):
     111
    11122016-09-27  Wenson Hsieh  <wenson_hsieh@apple.com>
    2113
  • trunk/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.cpp

    r204516 r206445  
    4747}
    4848
    49 // FIXME: Remove after https://bugs.webkit.org/show_bug.cgi?id=160579
    50 void MediaConstraintsImpl::initialize(const Dictionary& constraints)
    51 {
    52     if (constraints.isUndefinedOrNull())
    53         return;
    54 }
    55 
    5649Ref<MediaConstraintsImpl> MediaConstraintsImpl::create(MediaTrackConstraintSetMap&& mandatoryConstraints, Vector<MediaTrackConstraintSetMap>&& advancedConstraints, bool isValid)
    5750{
  • trunk/Source/WebCore/Modules/mediastream/MediaConstraintsImpl.h

    r204516 r206445  
    4949
    5050    virtual ~MediaConstraintsImpl();
    51     void initialize(const Dictionary&);
    5251
    5352    const MediaTrackConstraintSetMap& mandatoryConstraints() const final { return m_mandatoryConstraints; }
  • trunk/Source/WebCore/bindings/js/JSMediaDevicesCustom.cpp

    r206252 r206445  
    5959}
    6060
    61 static RefPtr<StringConstraint> createStringConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
    62 {
    63     auto constraint = StringConstraint::create(name, type);
     61static Optional<StringConstraint> createStringConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
     62{
     63    auto constraint = StringConstraint(name, type);
    6464
    6565    // Dictionary constraint value.
     
    7272            String exactStringValue;
    7373            if (dictionaryValue.get("exact", exactStringValue))
    74                 constraint->setExact(exactStringValue);
     74                constraint.setExact(exactStringValue);
    7575        }
    7676
     
    8181            String idealStringValue;
    8282            if (!dictionaryValue.get("ideal", idealStringValue))
    83                 constraint->setIdeal(idealStringValue);
    84         }
    85 
    86         if (constraint->isEmpty()) {
     83                constraint.setIdeal(idealStringValue);
     84        }
     85
     86        if (constraint.isEmpty()) {
    8787            LOG(Media, "createStringConstraint() - ignoring string constraint '%s' with dictionary value since it has no valid or supported key/value pairs.", name.utf8().data());
    88             return nullptr;
     88            return Nullopt;
    8989        }
    9090       
     
    9797        initializeStringConstraintWithList(constraint, &StringConstraint::appendIdeal, arrayValue);
    9898
    99         if (constraint->isEmpty()) {
     99        if (constraint.isEmpty()) {
    100100            LOG(Media, "createStringConstraint() - ignoring string constraint '%s' with array value since it is empty.", name.utf8().data());
    101             return nullptr;
     101            return Nullopt;
    102102        }
    103103
     
    109109    if (mediaTrackConstraintSet.get(name, value)) {
    110110        if (constraintSetType == ConstraintSetType::Mandatory)
    111             constraint->setIdeal(value);
     111            constraint.setIdeal(value);
    112112        else
    113             constraint->setExact(value);
     113            constraint.setExact(value);
    114114       
    115115        return WTFMove(constraint);
     
    118118    // Invalid constraint value.
    119119    LOG(Media, "createStringConstraint() - ignoring string constraint '%s' since it has neither a dictionary nor sequence nor scalar value.", name.utf8().data());
    120     return nullptr;
    121 }
    122 
    123 static RefPtr<BooleanConstraint> createBooleanConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
    124 {
    125     auto constraint = BooleanConstraint::create(name, type);
     120    return Nullopt;
     121}
     122
     123static Optional<BooleanConstraint> createBooleanConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
     124{
     125    auto constraint = BooleanConstraint(name, type);
    126126
    127127    // Dictionary constraint value.
     
    130130        bool exactValue;
    131131        if (dictionaryValue.get("exact", exactValue))
    132             constraint->setExact(exactValue);
     132            constraint.setExact(exactValue);
    133133
    134134        bool idealValue;
    135135        if (dictionaryValue.get("ideal", idealValue))
    136             constraint->setIdeal(idealValue);
    137 
    138         if (constraint->isEmpty()) {
     136            constraint.setIdeal(idealValue);
     137
     138        if (constraint.isEmpty()) {
    139139            LOG(Media, "createBooleanConstraint() - ignoring boolean constraint '%s' with dictionary value since it has no valid or supported key/value pairs.", name.utf8().data());
    140             return nullptr;
     140            return Nullopt;
    141141        }
    142142
     
    148148    if (mediaTrackConstraintSet.get(name, value)) {
    149149        if (constraintSetType == ConstraintSetType::Mandatory)
    150             constraint->setIdeal(value);
     150            constraint.setIdeal(value);
    151151        else
    152             constraint->setExact(value);
     152            constraint.setExact(value);
    153153       
    154154        return WTFMove(constraint);
     
    157157    // Invalid constraint value.
    158158    LOG(Media, "createBooleanConstraint() - ignoring boolean constraint '%s' since it has neither a dictionary nor scalar value.", name.utf8().data());
    159     return nullptr;
    160 }
    161 
    162 static RefPtr<DoubleConstraint> createDoubleConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
    163 {
    164     auto constraint = DoubleConstraint::create(name, type);
     159    return Nullopt;
     160}
     161
     162static Optional<DoubleConstraint> createDoubleConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
     163{
     164    auto constraint = DoubleConstraint(name, type);
    165165
    166166    // Dictionary constraint value.
     
    169169        double minValue;
    170170        if (dictionaryValue.get("min", minValue))
    171             constraint->setMin(minValue);
     171            constraint.setMin(minValue);
    172172
    173173        double maxValue;
    174174        if (dictionaryValue.get("max", maxValue))
    175             constraint->setMax(maxValue);
     175            constraint.setMax(maxValue);
    176176
    177177        double exactValue;
    178178        if (dictionaryValue.get("exact", exactValue))
    179             constraint->setExact(exactValue);
     179            constraint.setExact(exactValue);
    180180
    181181        double idealValue;
    182182        if (dictionaryValue.get("ideal", idealValue))
    183             constraint->setIdeal(idealValue);
    184 
    185         if (constraint->isEmpty()) {
     183            constraint.setIdeal(idealValue);
     184
     185        if (constraint.isEmpty()) {
    186186            LOG(Media, "createDoubleConstraint() - ignoring double constraint '%s' with dictionary value since it has no valid or supported key/value pairs.", name.utf8().data());
    187             return nullptr;
     187            return Nullopt;
    188188        }
    189189
     
    195195    if (mediaTrackConstraintSet.get(name, value)) {
    196196        if (constraintSetType == ConstraintSetType::Mandatory)
    197             constraint->setIdeal(value);
     197            constraint.setIdeal(value);
    198198        else
    199             constraint->setExact(value);
     199            constraint.setExact(value);
    200200       
    201201        return WTFMove(constraint);
     
    204204    // Invalid constraint value.
    205205    LOG(Media, "createDoubleConstraint() - ignoring double constraint '%s' since it has neither a dictionary nor scalar value.", name.utf8().data());
    206     return nullptr;
    207 }
    208 
    209 static RefPtr<IntConstraint> createIntConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
    210 {
    211     auto constraint = IntConstraint::create(name, type);
     206    return Nullopt;
     207}
     208
     209static Optional<IntConstraint> createIntConstraint(const Dictionary& mediaTrackConstraintSet, const String& name, MediaConstraintType type, ConstraintSetType constraintSetType)
     210{
     211    auto constraint = IntConstraint(name, type);
    212212
    213213    // Dictionary constraint value.
     
    216216        int minValue;
    217217        if (dictionaryValue.get("min", minValue))
    218             constraint->setMin(minValue);
     218            constraint.setMin(minValue);
    219219
    220220        int maxValue;
    221221        if (dictionaryValue.get("max", maxValue))
    222             constraint->setMax(maxValue);
     222            constraint.setMax(maxValue);
    223223
    224224        int exactValue;
    225225        if (dictionaryValue.get("exact", exactValue))
    226             constraint->setExact(exactValue);
     226            constraint.setExact(exactValue);
    227227
    228228        int idealValue;
    229229        if (dictionaryValue.get("ideal", idealValue))
    230             constraint->setIdeal(idealValue);
    231 
    232         if (constraint->isEmpty()) {
     230            constraint.setIdeal(idealValue);
     231
     232        if (constraint.isEmpty()) {
    233233            LOG(Media, "createIntConstraint() - ignoring long constraint '%s' with dictionary value since it has no valid or supported key/value pairs.", name.utf8().data());
    234             return nullptr;
     234            return Nullopt;
    235235        }
    236236
     
    242242    if (mediaTrackConstraintSet.get(name, value)) {
    243243        if (constraintSetType == ConstraintSetType::Mandatory)
    244             constraint->setIdeal(value);
     244            constraint.setIdeal(value);
    245245        else
    246             constraint->setExact(value);
     246            constraint.setExact(value);
    247247       
    248248        return WTFMove(constraint);
     
    251251    // Invalid constraint value.
    252252    LOG(Media, "createIntConstraint() - ignoring long constraint '%s' since it has neither a dictionary nor scalar value.", name.utf8().data());
    253     return nullptr;
     253    return Nullopt;
    254254}
    255255
     
    257257{
    258258    MediaConstraintType constraintType = RealtimeMediaSourceSupportedConstraints::constraintFromName(name);
    259 
    260     RefPtr<MediaConstraint> mediaConstraint;
    261259    switch (constraintType) {
    262260    case MediaConstraintType::Width:
     261        map.set(constraintType, createIntConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType));
     262        break;
    263263    case MediaConstraintType::Height:
     264        map.set(constraintType, createIntConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType));
     265        break;
    264266    case MediaConstraintType::SampleRate:
     267        map.set(constraintType, createIntConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType));
     268        break;
    265269    case MediaConstraintType::SampleSize:
    266         mediaConstraint = createIntConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
     270        map.set(constraintType, createIntConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType));
    267271        break;
    268272
    269273    case MediaConstraintType::AspectRatio:
     274        map.set(constraintType, createDoubleConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType));
     275        break;
    270276    case MediaConstraintType::FrameRate:
     277        map.set(constraintType, createDoubleConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType));
     278        break;
    271279    case MediaConstraintType::Volume:
    272         mediaConstraint = createDoubleConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
     280        map.set(constraintType, createDoubleConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType));
    273281        break;
    274282
    275283    case MediaConstraintType::EchoCancellation:
    276         mediaConstraint = createBooleanConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
     284        map.set(constraintType, createBooleanConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType));
    277285        break;
    278286
    279287    case MediaConstraintType::FacingMode:
     288        map.set(constraintType, createStringConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType));
     289        break;
    280290    case MediaConstraintType::DeviceId:
     291        map.set(constraintType, createStringConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType));
     292        break;
    281293    case MediaConstraintType::GroupId:
    282         mediaConstraint = createStringConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType);
     294        map.set(constraintType, createStringConstraint(mediaTrackConstraintSet, name, constraintType, constraintSetType));
    283295        break;
    284296
    285297    case MediaConstraintType::Unknown:
    286         LOG(Media, "parseMediaTrackConstraintSetForKey() - found unsupported constraint '%s'.", name.utf8().data());
    287         mediaConstraint = UnknownConstraint::create(name, constraintType);
    288         break;
    289     }
    290    
    291     map.add(name, WTFMove(mediaConstraint));
     298        LOG(Media, "parseMediaTrackConstraintSetForKey() - ignoring unsupported constraint '%s'.", name.utf8().data());
     299        return;
     300    }
    292301}
    293302
  • trunk/Source/WebCore/platform/mediastream/CaptureDeviceManager.cpp

    r205929 r206445  
    7373bool CaptureDeviceManager::verifyConstraintsForMediaType(RealtimeMediaSource::Type type, const MediaConstraints& constraints, const CaptureSessionInfo* session, String& invalidConstraint)
    7474{
    75     auto& mandatoryConstraints = constraints.mandatoryConstraints();
    76     for (auto& nameConstraintPair : mandatoryConstraints) {
    77         if (sessionSupportsConstraint(session, type, *nameConstraintPair.value))
    78             continue;
    79 
    80         invalidConstraint = nameConstraintPair.key;
     75    invalidConstraint = emptyString();
     76    constraints.mandatoryConstraints().filter([&](const MediaConstraint& constraint) {
     77        if (!sessionSupportsConstraint(session, type, constraint)) {
     78            invalidConstraint = constraint.name();
     79            return true;
     80        }
     81
    8182        return false;
    82     }
    83 
    84     return true;
     83    });
     84
     85    return invalidConstraint.isEmpty();
     86
    8587}
    8688
     
    154156{
    155157    const RealtimeMediaSourceSupportedConstraints& supportedConstraints = RealtimeMediaSourceCenter::singleton().supportedConstraints();
    156     MediaConstraintType constraintType = constraint.type();
     158    MediaConstraintType constraintType = constraint.constraintType();
    157159    if (!supportedConstraints.supportsConstraint(constraintType))
    158160        return false;
     
    177179        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=160793. Handle sequence of facingMode constraints.
    178180        Vector<String> exactFacingMode;
    179         if (!constraint.getExact(exactFacingMode))
     181        if (!downcast<const StringConstraint>(constraint).getExact(exactFacingMode))
    180182            return false;
    181183
     
    193195
    194196    int min = 0;
    195     if (constraint.getMin(min))
     197    if (downcast<const IntConstraint>(constraint).getMin(min))
    196198        isSupported &= min > 60;
    197199
    198200    int max = 60;
    199     if (constraint.getMax(max))
     201    if (downcast<const IntConstraint>(constraint).getMax(max))
    200202        isSupported &= max < min;
    201203
    202204    int exact;
    203     if (constraint.getExact(exact))
     205    if (downcast<const IntConstraint>(constraint).getExact(exact))
    204206        isSupported &= (exact < min || exact > max);
    205207
  • trunk/Source/WebCore/platform/mediastream/MediaConstraints.cpp

    r205965 r206445  
    3535#include "RealtimeMediaSourceCenter.h"
    3636#include "RealtimeMediaSourceSupportedConstraints.h"
     37#include <wtf/StdLibExtras.h>
    3738
    3839namespace WebCore {
    39 
    40 Ref<MediaConstraint> MediaConstraint::create(const String& name)
    41 {
    42     MediaConstraintType constraintType = RealtimeMediaSourceSupportedConstraints::constraintFromName(name);
    43 
    44     switch (constraintType) {
    45     case MediaConstraintType::Width:
    46     case MediaConstraintType::Height:
    47     case MediaConstraintType::SampleRate:
    48     case MediaConstraintType::SampleSize:
    49         return IntConstraint::create(name, constraintType);
    50     case MediaConstraintType::AspectRatio:
    51     case MediaConstraintType::FrameRate:
    52     case MediaConstraintType::Volume:
    53         return DoubleConstraint::create(name, constraintType);
    54     case MediaConstraintType::EchoCancellation:
    55         return BooleanConstraint::create(name, constraintType);
    56     case MediaConstraintType::FacingMode:
    57     case MediaConstraintType::DeviceId:
    58     case MediaConstraintType::GroupId:
    59         return StringConstraint::create(name, constraintType);
    60     case MediaConstraintType::Unknown:
    61         return UnknownConstraint::create(name, constraintType);
    62     }
    63 
    64     ASSERT_NOT_REACHED();
    65     return MediaConstraint::create(String());
    66 }
    67 
    68 Ref<MediaConstraint> MediaConstraint::copy() const
    69 {
    70     return MediaConstraint::create(name());
    71 }
    72 
    73 Ref<MediaConstraint> IntConstraint::copy() const
    74 {
    75     auto copy = IntConstraint::create(name(), type());
    76     copy->m_min = m_min;
    77     copy->m_max = m_max;
    78     copy->m_exact = m_exact;
    79     copy->m_ideal = m_ideal;
    80 
    81     return copy.leakRef();
    82 }
    83 
    84 Ref<MediaConstraint> DoubleConstraint::copy() const
    85 {
    86     auto copy = DoubleConstraint::create(name(), type());
    87     copy->m_min = m_min;
    88     copy->m_max = m_max;
    89     copy->m_exact = m_exact;
    90     copy->m_ideal = m_ideal;
    91    
    92     return copy.leakRef();
    93 }
    94 
    95 Ref<MediaConstraint> BooleanConstraint::copy() const
    96 {
    97     auto copy = BooleanConstraint::create(name(), type());
    98     copy->m_exact = m_exact;
    99     copy->m_ideal = m_ideal;
    100 
    101     return copy.leakRef();
    102 }
    103 
    104 Ref<MediaConstraint> StringConstraint::copy() const
    105 {
    106     auto copy = StringConstraint::create(name(), type());
    107     copy->m_exact = m_exact;
    108     copy->m_ideal = m_ideal;
    109 
    110     return copy.leakRef();
    111 }
    11240
    11341bool BooleanConstraint::getExact(bool& exact) const
     
    17098}
    17199
    172 const String& StringConstraint::find(std::function<bool(ConstraintType, const String&)> filter) const
     100const String& StringConstraint::find(std::function<bool(const String&)> filter) const
    173101{
    174102    for (auto& constraint : m_exact) {
    175         if (filter(ConstraintType::ExactConstraint, constraint))
     103        if (filter(constraint))
    176104            return constraint;
    177105    }
    178106
    179107    for (auto& constraint : m_ideal) {
    180         if (filter(ConstraintType::IdealConstraint, constraint))
     108        if (filter(constraint))
    181109            return constraint;
    182110    }
     
    223151void StringConstraint::merge(const MediaConstraint& other)
    224152{
     153    ASSERT(other.isString());
     154    const StringConstraint& typedOther = downcast<StringConstraint>(other);
     155
    225156    if (other.isEmpty())
    226157        return;
    227158
    228159    Vector<String> values;
    229     if (other.getExact(values)) {
     160    if (typedOther.getExact(values)) {
    230161        if (m_exact.isEmpty())
    231162            m_exact = values;
     
    238169    }
    239170
    240     if (other.getIdeal(values)) {
     171    if (typedOther.getIdeal(values)) {
    241172        if (m_ideal.isEmpty())
    242173            m_ideal = values;
     
    252183void FlattenedConstraint::set(const MediaConstraint& constraint)
    253184{
    254     for (auto existingConstraint : m_constraints) {
    255         if (existingConstraint->type() == constraint.type()) {
    256             existingConstraint = constraint.copy();
     185    for (auto& variant : m_variants) {
     186        if (variant.constraintType() == constraint.constraintType())
     187            return;
     188    }
     189
     190    append(constraint);
     191}
     192
     193void FlattenedConstraint::merge(const MediaConstraint& constraint)
     194{
     195    for (auto& variant : *this) {
     196        if (variant.constraintType() != constraint.constraintType())
     197            continue;
     198
     199        switch (variant.dataType()) {
     200        case MediaConstraint::DataType::Integer:
     201            ASSERT(constraint.isInt());
     202            downcast<const IntConstraint>(variant).merge(downcast<const IntConstraint>(constraint));
     203            return;
     204        case MediaConstraint::DataType::Double:
     205            ASSERT(constraint.isDouble());
     206            downcast<const DoubleConstraint>(variant).merge(downcast<const DoubleConstraint>(constraint));
     207            return;
     208        case MediaConstraint::DataType::Boolean:
     209            ASSERT(constraint.isBoolean());
     210            downcast<const BooleanConstraint>(variant).merge(downcast<const BooleanConstraint>(constraint));
     211            return;
     212        case MediaConstraint::DataType::String:
     213            ASSERT(constraint.isString());
     214            downcast<const StringConstraint>(variant).merge(downcast<const StringConstraint>(constraint));
     215            return;
     216        case MediaConstraint::DataType::None:
     217            ASSERT_NOT_REACHED();
    257218            return;
    258219        }
    259220    }
    260221
    261     m_constraints.append(constraint.copy());
    262 }
    263 
    264 void FlattenedConstraint::merge(const MediaConstraint& constraint)
    265 {
    266     for (auto existingConstraint : m_constraints) {
    267         if (existingConstraint->type() == constraint.type()) {
    268             existingConstraint->merge(constraint);
    269             return;
    270         }
    271     }
    272 
    273     m_constraints.append(constraint.copy());
     222    append(constraint);
     223}
     224
     225void FlattenedConstraint::append(const MediaConstraint& constraint)
     226{
     227#ifndef NDEBUG
     228    ++m_generation;
     229#endif
     230
     231    m_variants.append(ConstraintHolder::create(constraint));
     232
     233}
     234
     235void MediaTrackConstraintSetMap::forEach(std::function<void(const MediaConstraint&)> callback) const
     236{
     237    if (m_width && !m_width->isEmpty())
     238        callback(*m_width);
     239    if (m_height && !m_height->isEmpty())
     240        callback(*m_height);
     241    if (m_sampleRate && !m_sampleRate->isEmpty())
     242        callback(*m_sampleRate);
     243    if (m_sampleSize && !m_sampleSize->isEmpty())
     244        callback(*m_sampleSize);
     245
     246    if (m_aspectRatio && !m_aspectRatio->isEmpty())
     247        callback(*m_aspectRatio);
     248    if (m_frameRate && !m_frameRate->isEmpty())
     249        callback(*m_frameRate);
     250    if (m_volume && !m_volume->isEmpty())
     251        callback(*m_volume);
     252
     253    if (m_echoCancellation && !m_echoCancellation->isEmpty())
     254        callback(*m_echoCancellation);
     255
     256    if (m_facingMode && !m_facingMode->isEmpty())
     257        callback(*m_facingMode);
     258    if (m_deviceId && !m_deviceId->isEmpty())
     259        callback(*m_deviceId);
     260    if (m_groupId && !m_groupId->isEmpty())
     261        callback(*m_groupId);
     262}
     263
     264void MediaTrackConstraintSetMap::filter(std::function<bool(const MediaConstraint&)> callback) const
     265{
     266    if (m_width && !m_width->isEmpty() && callback(*m_width))
     267        return;
     268    if (m_height && !m_height->isEmpty() && callback(*m_height))
     269        return;
     270    if (m_sampleRate && !m_sampleRate->isEmpty() && callback(*m_sampleRate))
     271        return;
     272    if (m_sampleSize && !m_sampleSize->isEmpty() && callback(*m_sampleSize))
     273        return;
     274
     275    if (m_aspectRatio && !m_aspectRatio->isEmpty() && callback(*m_aspectRatio))
     276        return;
     277    if (m_frameRate && !m_frameRate->isEmpty() && callback(*m_frameRate))
     278        return;
     279    if (m_volume && !m_volume->isEmpty() && callback(*m_volume))
     280        return;
     281
     282    if (m_echoCancellation && !m_echoCancellation->isEmpty() && callback(*m_echoCancellation))
     283        return;
     284
     285    if (m_facingMode && !m_facingMode->isEmpty() && callback(*m_facingMode))
     286        return;
     287    if (m_deviceId && !m_deviceId->isEmpty() && callback(*m_deviceId))
     288        return;
     289    if (m_groupId && !m_groupId->isEmpty() && callback(*m_groupId))
     290        return;
     291}
     292
     293bool MediaTrackConstraintSetMap::isEmpty() const
     294{
     295    return (!m_width || m_width->isEmpty())
     296        && (!m_height || m_height->isEmpty())
     297        && (!m_sampleRate || m_sampleRate->isEmpty())
     298        && (!m_sampleSize || m_sampleSize->isEmpty())
     299        && (!m_aspectRatio || m_aspectRatio->isEmpty())
     300        && (!m_frameRate || m_frameRate->isEmpty())
     301        && (!m_volume || m_volume->isEmpty())
     302        && (!m_echoCancellation || m_echoCancellation->isEmpty())
     303        && (!m_facingMode || m_facingMode->isEmpty())
     304        && (!m_deviceId || m_deviceId->isEmpty())
     305        && (!m_groupId || m_groupId->isEmpty());
     306}
     307
     308void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, Optional<IntConstraint>&& constraint)
     309{
     310    switch (constraintType) {
     311    case MediaConstraintType::Width:
     312        m_width = WTFMove(constraint);
     313        break;
     314    case MediaConstraintType::Height:
     315        m_height = WTFMove(constraint);
     316        break;
     317    case MediaConstraintType::SampleRate:
     318        m_sampleRate = WTFMove(constraint);
     319        break;
     320    case MediaConstraintType::SampleSize:
     321        m_sampleSize = WTFMove(constraint);
     322        break;
     323
     324    case MediaConstraintType::AspectRatio:
     325    case MediaConstraintType::FrameRate:
     326    case MediaConstraintType::Volume:
     327    case MediaConstraintType::EchoCancellation:
     328    case MediaConstraintType::FacingMode:
     329    case MediaConstraintType::DeviceId:
     330    case MediaConstraintType::GroupId:
     331    case MediaConstraintType::Unknown:
     332        ASSERT_NOT_REACHED();
     333        break;
     334    }
     335}
     336
     337void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, Optional<DoubleConstraint>&& constraint)
     338{
     339    switch (constraintType) {
     340    case MediaConstraintType::AspectRatio:
     341        m_aspectRatio = WTFMove(constraint);
     342        break;
     343    case MediaConstraintType::FrameRate:
     344        m_frameRate = WTFMove(constraint);
     345        break;
     346    case MediaConstraintType::Volume:
     347        m_volume = WTFMove(constraint);
     348        break;
     349
     350    case MediaConstraintType::Width:
     351    case MediaConstraintType::Height:
     352    case MediaConstraintType::SampleRate:
     353    case MediaConstraintType::SampleSize:
     354    case MediaConstraintType::EchoCancellation:
     355    case MediaConstraintType::FacingMode:
     356    case MediaConstraintType::DeviceId:
     357    case MediaConstraintType::GroupId:
     358    case MediaConstraintType::Unknown:
     359        ASSERT_NOT_REACHED();
     360        break;
     361    }
     362}
     363
     364void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, Optional<BooleanConstraint>&& constraint)
     365{
     366    switch (constraintType) {
     367    case MediaConstraintType::EchoCancellation:
     368        m_echoCancellation = WTFMove(constraint);
     369        break;
     370
     371    case MediaConstraintType::Width:
     372    case MediaConstraintType::Height:
     373    case MediaConstraintType::SampleRate:
     374    case MediaConstraintType::SampleSize:
     375    case MediaConstraintType::AspectRatio:
     376    case MediaConstraintType::FrameRate:
     377    case MediaConstraintType::Volume:
     378    case MediaConstraintType::FacingMode:
     379    case MediaConstraintType::DeviceId:
     380    case MediaConstraintType::GroupId:
     381    case MediaConstraintType::Unknown:
     382        ASSERT_NOT_REACHED();
     383        break;
     384    }
     385}
     386
     387void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, Optional<StringConstraint>&& constraint)
     388{
     389    switch (constraintType) {
     390    case MediaConstraintType::FacingMode:
     391        m_facingMode = WTFMove(constraint);
     392        break;
     393    case MediaConstraintType::DeviceId:
     394        m_deviceId = WTFMove(constraint);
     395        break;
     396    case MediaConstraintType::GroupId:
     397        m_groupId = WTFMove(constraint);
     398        break;
     399
     400    case MediaConstraintType::Width:
     401    case MediaConstraintType::Height:
     402    case MediaConstraintType::SampleRate:
     403    case MediaConstraintType::SampleSize:
     404    case MediaConstraintType::AspectRatio:
     405    case MediaConstraintType::FrameRate:
     406    case MediaConstraintType::Volume:
     407    case MediaConstraintType::EchoCancellation:
     408    case MediaConstraintType::Unknown:
     409        ASSERT_NOT_REACHED();
     410        break;
     411    }
    274412}
    275413
  • trunk/Source/WebCore/platform/mediastream/MediaConstraints.h

    r205574 r206445  
    3939#include <wtf/HashMap.h>
    4040#include <wtf/RefCounted.h>
     41#include <wtf/Variant.h>
    4142#include <wtf/text/StringHash.h>
    4243#include <wtf/text/WTFString.h>
     
    4445namespace WebCore {
    4546
    46 class MediaConstraint : public RefCounted<MediaConstraint> {
    47 public:
    48     static Ref<MediaConstraint> create(const String&);
    49 
    50     enum class ConstraintType { ExactConstraint, IdealConstraint, MinConstraint, MaxConstraint };
     47class MediaConstraint {
     48public:
     49    enum class DataType { None, Integer, Double, Boolean, String };
    5150
    5251    virtual ~MediaConstraint() { };
    5352
    54     virtual Ref<MediaConstraint> copy() const;
    55     virtual bool isEmpty() const = 0;
    56     virtual bool isMandatory() const = 0;
    57 
    58     virtual bool getMin(int&) const { ASSERT_NOT_REACHED(); return false; }
    59     virtual bool getMax(int&) const { ASSERT_NOT_REACHED(); return false; }
    60     virtual bool getExact(int&) const { ASSERT_NOT_REACHED(); return false; }
    61     virtual bool getIdeal(int&) const { ASSERT_NOT_REACHED(); return false; }
    62     virtual bool validForRange(int, int) const { ASSERT_NOT_REACHED(); return false; }
    63     virtual int find(std::function<bool(ConstraintType, int)>) const { ASSERT_NOT_REACHED(); return 0; }
    64     virtual double fitnessDistance(int, int) const { ASSERT_NOT_REACHED(); return 0; }
    65 
    66     virtual bool getMin(double&) const { ASSERT_NOT_REACHED(); return false; }
    67     virtual bool getMax(double&) const { ASSERT_NOT_REACHED(); return false; }
    68     virtual bool getExact(double&) const { ASSERT_NOT_REACHED(); return false; }
    69     virtual bool getIdeal(double&) const { ASSERT_NOT_REACHED(); return false; }
    70     virtual bool validForRange(double, double) const { ASSERT_NOT_REACHED(); return false; }
    71     virtual double find(std::function<bool(ConstraintType, double)>) const { ASSERT_NOT_REACHED(); return 0; }
    72     virtual double fitnessDistance(double, double) const { ASSERT_NOT_REACHED(); return 0; }
    73 
    74     virtual bool getMin(bool&) const { ASSERT_NOT_REACHED(); return false; }
    75     virtual bool getMax(bool&) const { ASSERT_NOT_REACHED(); return false; }
    76     virtual bool getExact(bool&) const { ASSERT_NOT_REACHED(); return false; }
    77     virtual bool getIdeal(bool&) const { ASSERT_NOT_REACHED(); return false; }
    78     virtual double fitnessDistance(bool) const { ASSERT_NOT_REACHED(); return 0; }
    79 
    80     virtual bool getMin(Vector<String>&) const { ASSERT_NOT_REACHED(); return false; }
    81     virtual bool getMax(Vector<String>&) const { ASSERT_NOT_REACHED(); return false; }
    82     virtual bool getExact(Vector<String>&) const { ASSERT_NOT_REACHED(); return false; }
    83     virtual bool getIdeal(Vector<String>&) const { ASSERT_NOT_REACHED(); return false; }
    84     virtual const String& find(std::function<bool(ConstraintType, const String&)>) const { ASSERT_NOT_REACHED(); return emptyString(); }
    85 
    86     virtual double fitnessDistance(const String&) const { ASSERT_NOT_REACHED(); return 0; }
    87     virtual double fitnessDistance(const Vector<String>&) const { ASSERT_NOT_REACHED(); return 0; }
    88 
    89     virtual void merge(const MediaConstraint&) { ASSERT_NOT_REACHED(); }
    90 
    91     MediaConstraintType type() const { return m_type; }
     53    virtual bool isEmpty() const { return true; }
     54    virtual bool isMandatory() const { return false; }
     55    virtual void merge(const MediaConstraint&) { }
     56
     57    bool isInt() const { return m_dataType == DataType::Integer; }
     58    bool isDouble() const { return m_dataType == DataType::Double; }
     59    bool isBoolean() const { return m_dataType == DataType::Boolean; }
     60    bool isString() const { return m_dataType == DataType::String; }
     61
     62    DataType dataType() const { return m_dataType; }
     63    MediaConstraintType constraintType() const { return m_constraintType; }
    9264    const String& name() const { return m_name; }
    9365
    9466protected:
    95     explicit MediaConstraint(const String& name, MediaConstraintType type)
     67    explicit MediaConstraint(const AtomicString& name, MediaConstraintType constraintType, DataType dataType)
    9668        : m_name(name)
    97         , m_type(type)
    98     {
    99     }
     69        , m_constraintType(constraintType)
     70        , m_dataType(dataType)
     71    {
     72    }
     73
    10074
    10175private:
    102     String m_name;
    103     MediaConstraintType m_type;
     76    AtomicString m_name;
     77    MediaConstraintType m_constraintType;
     78    DataType m_dataType;
    10479};
    10580
     
    10782class NumericConstraint : public MediaConstraint {
    10883public:
    109     bool isEmpty() const override { return !m_min && !m_max && !m_exact && !m_ideal; }
    110     bool isMandatory() const override { return m_min || m_max || m_exact; }
    111 
    11284    void setMin(ValueType value) { m_min = value; }
    11385    void setMax(ValueType value) { m_max = value; }
     
    11587    void setIdeal(ValueType value) { m_ideal = value; }
    11688
    117     bool getMin(ValueType& min) const final {
     89    bool getMin(ValueType& min) const
     90    {
    11891        if (!m_min)
    11992            return false;
     
    12396    }
    12497
    125     bool getMax(ValueType& max) const final {
     98    bool getMax(ValueType& max) const
     99    {
    126100        if (!m_max)
    127101            return false;
     
    131105    }
    132106
    133     bool getExact(ValueType& exact) const final {
     107    bool getExact(ValueType& exact) const
     108    {
    134109        if (!m_exact)
    135110            return false;
     
    139114    }
    140115
    141     bool getIdeal(ValueType& ideal) const final {
     116    bool getIdeal(ValueType& ideal) const
     117    {
    142118        if (!m_ideal)
    143119            return false;
     
    155131    }
    156132
    157     double fitnessDistance(ValueType rangeMin, ValueType rangeMax) const final {
     133    double fitnessDistance(ValueType rangeMin, ValueType rangeMax) const
     134    {
    158135        // https://w3c.github.io/mediacapture-main/#dfn-applyconstraints
    159136        // 1. If the constraint is not supported by the browser, the fitness distance is 0.
     
    190167    }
    191168
    192     void merge(const MediaConstraint& other) final {
     169    bool validForRange(ValueType rangeMin, ValueType rangeMax) const
     170    {
     171        if (isEmpty())
     172            return false;
     173
     174        if (m_exact) {
     175            const ValueType exact = m_exact.value();
     176            if (exact < rangeMin && !nearlyEqual(exact, rangeMin))
     177                return false;
     178            if (exact > rangeMax && !nearlyEqual(exact, rangeMax))
     179                return false;
     180        }
     181
     182        if (m_min) {
     183            const ValueType constraintMin = m_min.value();
     184            if (constraintMin > rangeMax && !nearlyEqual(constraintMin, rangeMax))
     185                return false;
     186        }
     187
     188
     189        if (m_max) {
     190            const ValueType constraintMax = m_max.value();
     191            if (constraintMax < rangeMin && !nearlyEqual(constraintMax, rangeMin))
     192                return false;
     193        }
     194
     195        return true;
     196    }
     197
     198    ValueType find(std::function<bool(ValueType)> function) const
     199    {
     200        if (m_min && function(m_min.value()))
     201            return m_min.value();
     202
     203        if (m_max && function(m_max.value()))
     204            return m_max.value();
     205
     206        if (m_exact && function(m_exact.value()))
     207            return m_exact.value();
     208
     209        if (m_ideal && function(m_ideal.value()))
     210            return m_ideal.value();
     211
     212        return 0;
     213    }
     214
     215    bool isEmpty() const override { return !m_min && !m_max && !m_exact && !m_ideal; }
     216    bool isMandatory() const override { return m_min || m_max || m_exact; }
     217
     218protected:
     219    explicit NumericConstraint(const AtomicString& name, MediaConstraintType type, DataType dataType)
     220        : MediaConstraint(name, type, dataType)
     221    {
     222    }
     223
     224    void innerMerge(const NumericConstraint& other)
     225    {
    193226        if (other.isEmpty())
    194227            return;
     
    215248    }
    216249
    217     bool validForRange(ValueType rangeMin, ValueType rangeMax) const final {
    218         if (isEmpty())
    219             return false;
    220 
    221         if (m_exact) {
    222             const ValueType exact = m_exact.value();
    223             if (exact < rangeMin && !nearlyEqual(exact, rangeMin))
    224                 return false;
    225             if (exact > rangeMax && !nearlyEqual(exact, rangeMax))
    226                 return false;
    227         }
    228 
    229         if (m_min) {
    230             const ValueType constraintMin = m_min.value();
    231             if (constraintMin > rangeMax && !nearlyEqual(constraintMin, rangeMax))
    232                 return false;
    233         }
    234 
    235 
    236         if (m_max) {
    237             const ValueType constraintMax = m_max.value();
    238             if (constraintMax < rangeMin && !nearlyEqual(constraintMax, rangeMin))
    239                 return false;
    240         }
    241 
    242         return true;
    243     }
    244 
    245     ValueType find(std::function<bool(ConstraintType, ValueType)> function) const final {
    246         if (m_min && function(ConstraintType::MinConstraint, m_min.value()))
    247             return m_min.value();
    248 
    249         if (m_max && function(ConstraintType::MaxConstraint, m_max.value()))
    250             return m_max.value();
    251 
    252         if (m_exact && function(ConstraintType::ExactConstraint, m_exact.value()))
    253             return m_exact.value();
    254 
    255         if (m_ideal && function(ConstraintType::IdealConstraint, m_ideal.value()))
    256             return m_ideal.value();
    257 
    258         return 0;
    259     }
    260    
    261 
    262 protected:
    263     explicit NumericConstraint(const String& name, MediaConstraintType type)
    264         : MediaConstraint(name, type)
    265     {
    266     }
    267 
    268250    Optional<ValueType> m_min;
    269251    Optional<ValueType> m_max;
     
    274256class IntConstraint final : public NumericConstraint<int> {
    275257public:
    276     static Ref<IntConstraint> create(const String& name, MediaConstraintType type) { return adoptRef(*new IntConstraint(name, type)); }
    277 
    278     Ref<MediaConstraint> copy() const final;
    279 
    280 private:
    281     explicit IntConstraint(const String& name, MediaConstraintType type)
    282         : NumericConstraint<int>(name, type)
    283     {
     258    explicit IntConstraint(const AtomicString& name, MediaConstraintType type)
     259        : NumericConstraint<int>(name, type, DataType::Integer)
     260    {
     261    }
     262
     263    void merge(const MediaConstraint& other) final {
     264        ASSERT(other.isInt());
     265        NumericConstraint::innerMerge(downcast<const IntConstraint>(other));
    284266    }
    285267};
     
    287269class DoubleConstraint final : public NumericConstraint<double> {
    288270public:
    289     static Ref<DoubleConstraint> create(const String& name, MediaConstraintType type) { return adoptRef(*new DoubleConstraint(name, type)); }
    290 
    291     Ref<MediaConstraint> copy() const final;
    292 
    293 private:
    294     explicit DoubleConstraint(const String& name, MediaConstraintType type)
    295         : NumericConstraint<double>(name, type)
    296     {
     271    explicit DoubleConstraint(const AtomicString& name, MediaConstraintType type)
     272        : NumericConstraint<double>(name, type, DataType::Double)
     273    {
     274    }
     275
     276    void merge(const MediaConstraint& other) final {
     277        ASSERT(other.isDouble());
     278        NumericConstraint::innerMerge(downcast<DoubleConstraint>(other));
    297279    }
    298280};
     
    300282class BooleanConstraint final : public MediaConstraint {
    301283public:
    302     static Ref<BooleanConstraint> create(const String& name, MediaConstraintType type) { return adoptRef(*new BooleanConstraint(name, type)); }
    303 
    304     Ref<MediaConstraint> copy() const final;
     284    explicit BooleanConstraint(const AtomicString& name, MediaConstraintType type)
     285        : MediaConstraint(name, type, DataType::Boolean)
     286    {
     287    }
    305288
    306289    void setExact(bool value) { m_exact = value; }
    307290    void setIdeal(bool value) { m_ideal = value; }
    308291
    309     bool getExact(bool&) const final;
    310     bool getIdeal(bool&) const final;
    311 
    312     bool isEmpty() const final { return !m_exact && !m_ideal; };
    313     bool isMandatory() const final { return bool(m_exact); }
    314 
    315     double fitnessDistance(bool value) const final {
     292    bool getExact(bool&) const;
     293    bool getIdeal(bool&) const;
     294
     295    double fitnessDistance(bool value) const
     296    {
    316297        // https://w3c.github.io/mediacapture-main/#dfn-applyconstraints
    317298        // 1. If the constraint is not supported by the browser, the fitness distance is 0.
     
    336317
    337318    void merge(const MediaConstraint& other) final {
    338         if (other.isEmpty())
     319        ASSERT(other.isBoolean());
     320        const BooleanConstraint& typedOther = downcast<BooleanConstraint>(other);
     321
     322        if (typedOther.isEmpty())
    339323            return;
    340324
    341325        bool value;
    342         if (other.getExact(value))
     326        if (typedOther.getExact(value))
    343327            m_exact = value;
    344328
    345         if (other.getIdeal(value)) {
     329        if (typedOther.getIdeal(value)) {
    346330            if (!m_ideal || (value && !m_ideal.value()))
    347331                m_ideal = value;
     
    349333    }
    350334
     335    bool isEmpty() const final { return !m_exact && !m_ideal; };
     336    bool isMandatory() const final { return bool(m_exact); }
     337
    351338private:
    352     explicit BooleanConstraint(const String& name, MediaConstraintType type)
    353         : MediaConstraint(name, type)
    354     {
    355     }
    356 
    357339    Optional<bool> m_exact;
    358340    Optional<bool> m_ideal;
     
    361343class StringConstraint final : public MediaConstraint {
    362344public:
    363     static Ref<StringConstraint> create(const String& name, MediaConstraintType type) { return adoptRef(*new StringConstraint(name, type)); }
    364 
    365     Ref<MediaConstraint> copy() const final;
     345    explicit StringConstraint(const AtomicString& name, MediaConstraintType type)
     346        : MediaConstraint(name, type, DataType::String)
     347    {
     348    }
    366349
    367350    void setExact(const String&);
     
    370353    void appendIdeal(const String&);
    371354
    372     bool getExact(Vector<String>&) const final;
    373     bool getIdeal(Vector<String>&) const final;
     355    bool getExact(Vector<String>&) const;
     356    bool getIdeal(Vector<String>&) const;
     357
     358    double fitnessDistance(const String&) const;
     359    double fitnessDistance(const Vector<String>&) const;
     360
     361    const String& find(std::function<bool(const String&)>) const;
     362    void merge(const MediaConstraint&) final;
    374363
    375364    bool isEmpty() const final { return m_exact.isEmpty() && m_ideal.isEmpty(); }
    376365    bool isMandatory() const final { return !m_exact.isEmpty(); }
    377366
    378     double fitnessDistance(const String&) const final;
    379     double fitnessDistance(const Vector<String>&) const final;
    380 
    381     const String& find(std::function<bool(ConstraintType, const String&)>) const final;
    382     void merge(const MediaConstraint&) final;
    383 
    384367private:
    385     explicit StringConstraint(const String& name, MediaConstraintType type)
    386         : MediaConstraint(name, type)
    387     {
    388     }
    389 
    390368    Vector<String> m_exact;
    391369    Vector<String> m_ideal;
     
    394372class UnknownConstraint final : public MediaConstraint {
    395373public:
    396     static Ref<UnknownConstraint> create(const String& name, MediaConstraintType type) { return adoptRef(*new UnknownConstraint(name, type)); }
    397 
     374    explicit UnknownConstraint(const AtomicString& name, MediaConstraintType type)
     375        : MediaConstraint(name, type, DataType::None)
     376    {
     377    }
     378
     379private:
    398380    bool isEmpty() const final { return true; }
    399381    bool isMandatory() const final { return false; }
     382    void merge(const MediaConstraint&) final { }
     383};
     384
     385class MediaTrackConstraintSetMap {
     386public:
     387    void forEach(std::function<void(const MediaConstraint&)>) const;
     388    void filter(std::function<bool(const MediaConstraint&)>) const;
     389    bool isEmpty() const;
     390
     391    void set(MediaConstraintType, Optional<IntConstraint>&&);
     392    void set(MediaConstraintType, Optional<DoubleConstraint>&&);
     393    void set(MediaConstraintType, Optional<BooleanConstraint>&&);
     394    void set(MediaConstraintType, Optional<StringConstraint>&&);
    400395
    401396private:
    402     explicit UnknownConstraint(const String& name, MediaConstraintType type)
    403         : MediaConstraint(name, type)
    404     {
    405     }
    406 };
    407 
    408 using MediaTrackConstraintSetMap = HashMap<String, RefPtr<MediaConstraint>>;
     397    Optional<IntConstraint> m_width;
     398    Optional<IntConstraint> m_height;
     399    Optional<IntConstraint> m_sampleRate;
     400    Optional<IntConstraint> m_sampleSize;
     401
     402    Optional<DoubleConstraint> m_aspectRatio;
     403    Optional<DoubleConstraint> m_frameRate;
     404    Optional<DoubleConstraint> m_volume;
     405
     406    Optional<BooleanConstraint> m_echoCancellation;
     407
     408    Optional<StringConstraint> m_facingMode;
     409    Optional<StringConstraint> m_deviceId;
     410    Optional<StringConstraint> m_groupId;
     411};
    409412
    410413class FlattenedConstraint {
    411414public:
    412     typedef Vector<RefPtr<MediaConstraint>>::const_iterator const_iterator;
    413415
    414416    void set(const MediaConstraint&);
    415417    void merge(const MediaConstraint&);
    416     bool isEmpty() const { return m_constraints.isEmpty(); }
    417 
    418     const_iterator begin() const { return m_constraints.begin(); }
    419     const_iterator end() const { return m_constraints.end(); }
     418    void append(const MediaConstraint&);
     419    bool isEmpty() const { return m_variants.isEmpty(); }
     420
     421    class iterator {
     422    public:
     423        iterator(const FlattenedConstraint* constraint, size_t index)
     424            : m_constraint(constraint)
     425            , m_index(index)
     426#ifndef NDEBUG
     427            , m_generation(constraint->m_generation)
     428#endif
     429        {
     430        }
     431
     432        MediaConstraint& operator*() const
     433        {
     434            return m_constraint->m_variants.at(m_index).constraint();
     435        }
     436
     437        iterator& operator++()
     438        {
     439#ifndef NDEBUG
     440            ASSERT(m_generation == m_constraint->m_generation);
     441#endif
     442            m_index++;
     443            return *this;
     444        }
     445
     446        bool operator==(const iterator& other) const { return m_index == other.m_index; }
     447        bool operator!=(const iterator& other) const { return !(*this == other); }
     448
     449    private:
     450        const FlattenedConstraint* m_constraint { nullptr };
     451        size_t m_index { 0 };
     452#ifndef NDEBUG
     453        int m_generation { 0 };
     454#endif
     455    };
     456
     457    const iterator begin() const { return iterator(this, 0); }
     458    const iterator end() const { return iterator(this, m_variants.size()); }
    420459
    421460private:
    422 
    423     Vector<RefPtr<MediaConstraint>> m_constraints;
     461    class ConstraintHolder {
     462    public:
     463        static ConstraintHolder& create(const MediaConstraint& value) { return *new ConstraintHolder(value); }
     464
     465        ~ConstraintHolder()
     466        {
     467            switch (dataType()) {
     468            case MediaConstraint::DataType::Integer:
     469                delete m_value.asInteger;
     470                break;
     471            case MediaConstraint::DataType::Double:
     472                delete m_value.asDouble;
     473                break;
     474            case MediaConstraint::DataType::Boolean:
     475                delete m_value.asBoolean;
     476                break;
     477            case MediaConstraint::DataType::String:
     478                delete m_value.asString;
     479                break;
     480            case MediaConstraint::DataType::None:
     481                ASSERT_NOT_REACHED();
     482                break;
     483            }
     484
     485#ifndef NDEBUG
     486            m_value.asRaw = reinterpret_cast<MediaConstraint*>(0xbbadbeef);
     487#endif
     488        }
     489
     490        MediaConstraint& constraint() const { return *m_value.asRaw; }
     491        MediaConstraint::DataType dataType() const { return constraint().dataType(); }
     492        MediaConstraintType constraintType() const { return constraint().constraintType(); }
     493
     494    private:
     495        explicit ConstraintHolder(const MediaConstraint& value)
     496        {
     497            switch (value.dataType()) {
     498            case MediaConstraint::DataType::Integer:
     499                m_value.asInteger = new IntConstraint(downcast<const IntConstraint>(value));
     500                break;
     501            case MediaConstraint::DataType::Double:
     502                m_value.asDouble = new DoubleConstraint(downcast<DoubleConstraint>(value));
     503                break;
     504            case MediaConstraint::DataType::Boolean:
     505                m_value.asBoolean = new BooleanConstraint(downcast<BooleanConstraint>(value));
     506                break;
     507            case MediaConstraint::DataType::String:
     508                m_value.asString = new StringConstraint(downcast<StringConstraint>(value));
     509                break;
     510            case MediaConstraint::DataType::None:
     511                ASSERT_NOT_REACHED();
     512                break;
     513            }
     514        }
     515       
     516        union {
     517            MediaConstraint* asRaw;
     518            IntConstraint* asInteger;
     519            DoubleConstraint* asDouble;
     520            BooleanConstraint* asBoolean;
     521            StringConstraint* asString;
     522        } m_value;
     523    };
     524
     525    Vector<ConstraintHolder> m_variants;
     526#ifndef NDEBUG
     527    int m_generation { 0 };
     528#endif
    424529};
    425530
     
    438543} // namespace WebCore
    439544
     545#define SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(ConstraintType, predicate) \
     546SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ConstraintType) \
     547static bool isType(const WebCore::MediaConstraint& constraint) { return constraint.predicate; } \
     548SPECIALIZE_TYPE_TRAITS_END()
     549
     550SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(IntConstraint, isInt())
     551SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(DoubleConstraint, isDouble())
     552SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(StringConstraint, isString())
     553SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(BooleanConstraint, isBoolean())
     554
    440555#endif // ENABLE(MEDIA_STREAM)
    441556
  • trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp

    r205574 r206445  
    151151}
    152152
     153#if 1
    153154double RealtimeMediaSource::fitnessDistance(const MediaConstraint& constraint)
    154155{
    155156    RealtimeMediaSourceCapabilities& capabilities = *this->capabilities();
    156157
    157     switch (constraint.type()) {
     158    switch (constraint.constraintType()) {
    158159    case MediaConstraintType::Width: {
     160        ASSERT(constraint.isInt());
    159161        if (!capabilities.supportsWidth())
    160162            return 0;
    161163
    162164        auto range = capabilities.width();
    163         return constraint.fitnessDistance(range.rangeMin().asInt, range.rangeMax().asInt);
     165        return downcast<IntConstraint>(constraint).fitnessDistance(range.rangeMin().asInt, range.rangeMax().asInt);
    164166        break;
    165167    }
    166168
    167169    case MediaConstraintType::Height: {
     170        ASSERT(constraint.isInt());
    168171        if (!capabilities.supportsHeight())
    169172            return 0;
    170173
    171174        auto range = capabilities.height();
    172         return constraint.fitnessDistance(range.rangeMin().asInt, range.rangeMax().asInt);
     175        return downcast<IntConstraint>(constraint).fitnessDistance(range.rangeMin().asInt, range.rangeMax().asInt);
    173176        break;
    174177    }
    175178
    176179    case MediaConstraintType::FrameRate: {
     180        ASSERT(constraint.isDouble());
    177181        if (!capabilities.supportsFrameRate())
    178182            return 0;
    179183
    180184        auto range = capabilities.frameRate();
    181         return constraint.fitnessDistance(range.rangeMin().asDouble, range.rangeMax().asDouble);
     185        return downcast<DoubleConstraint>(constraint).fitnessDistance(range.rangeMin().asDouble, range.rangeMax().asDouble);
    182186        break;
    183187    }
    184188
    185189    case MediaConstraintType::AspectRatio: {
     190        ASSERT(constraint.isDouble());
    186191        if (!capabilities.supportsAspectRatio())
    187192            return 0;
    188193
    189194        auto range = capabilities.aspectRatio();
    190         return constraint.fitnessDistance(range.rangeMin().asDouble, range.rangeMax().asDouble);
     195        return downcast<DoubleConstraint>(constraint).fitnessDistance(range.rangeMin().asDouble, range.rangeMax().asDouble);
    191196        break;
    192197    }
    193198
    194199    case MediaConstraintType::Volume: {
     200        ASSERT(constraint.isDouble());
    195201        if (!capabilities.supportsVolume())
    196202            return 0;
    197203
    198204        auto range = capabilities.volume();
    199         return constraint.fitnessDistance(range.rangeMin().asDouble, range.rangeMax().asDouble);
     205        return downcast<DoubleConstraint>(constraint).fitnessDistance(range.rangeMin().asDouble, range.rangeMax().asDouble);
    200206        break;
    201207    }
    202208
    203209    case MediaConstraintType::SampleRate: {
     210        ASSERT(constraint.isInt());
    204211        if (!capabilities.supportsSampleRate())
    205212            return 0;
    206213
    207214        auto range = capabilities.sampleRate();
    208         return constraint.fitnessDistance(range.rangeMin().asDouble, range.rangeMax().asDouble);
     215        return downcast<IntConstraint>(constraint).fitnessDistance(range.rangeMin().asInt, range.rangeMax().asInt);
    209216        break;
    210217    }
    211218
    212219    case MediaConstraintType::SampleSize: {
     220        ASSERT(constraint.isInt());
    213221        if (!capabilities.supportsSampleSize())
    214222            return 0;
    215223
    216224        auto range = capabilities.sampleSize();
    217         return constraint.fitnessDistance(range.rangeMin().asDouble, range.rangeMax().asDouble);
     225        return downcast<IntConstraint>(constraint).fitnessDistance(range.rangeMin().asInt, range.rangeMax().asInt);
    218226        break;
    219227    }
    220228
    221229    case MediaConstraintType::FacingMode: {
     230        ASSERT(constraint.isString());
    222231        if (!capabilities.supportsFacingMode())
    223232            return 0;
     
    228237        for (auto& mode : modes)
    229238            supportedModes.append(RealtimeMediaSourceSettings::facingMode(mode));
    230         return constraint.fitnessDistance(supportedModes);
     239        return downcast<StringConstraint>(constraint).fitnessDistance(supportedModes);
    231240        break;
    232241    }
    233242
    234243    case MediaConstraintType::EchoCancellation: {
     244        ASSERT(constraint.isBoolean());
    235245        if (!capabilities.supportsEchoCancellation())
    236246            return 0;
    237247
    238248        bool echoCancellationReadWrite = capabilities.echoCancellation() == RealtimeMediaSourceCapabilities::EchoCancellation::ReadWrite;
    239         return constraint.fitnessDistance(echoCancellationReadWrite);
     249        return downcast<BooleanConstraint>(constraint).fitnessDistance(echoCancellationReadWrite);
    240250        break;
    241251    }
    242252
    243253    case MediaConstraintType::DeviceId: {
     254        ASSERT(constraint.isString());
    244255        if (!capabilities.supportsDeviceId())
    245256            return 0;
    246257
    247         return constraint.fitnessDistance(m_id);
     258        return downcast<StringConstraint>(constraint).fitnessDistance(m_id);
    248259        break;
    249260    }
    250261
    251262    case MediaConstraintType::GroupId: {
     263        ASSERT(constraint.isString());
    252264        if (!capabilities.supportsDeviceId())
    253265            return 0;
    254266
    255         return constraint.fitnessDistance(settings().groupId());
     267        return downcast<StringConstraint>(constraint).fitnessDistance(settings().groupId());
    256268        break;
    257269    }
     
    264276    return 0;
    265277}
     278#endif
    266279
    267280template <typename ValueType>
    268 static void applyNumericConstraint(const MediaConstraint& constraint, ValueType current, ValueType capabilityMin, ValueType capabilityMax, RealtimeMediaSource* source, void (RealtimeMediaSource::*function)(ValueType))
     281static void applyNumericConstraint(const NumericConstraint<ValueType>& constraint, ValueType current, ValueType capabilityMin, ValueType capabilityMax, RealtimeMediaSource* source, void (RealtimeMediaSource::*applier)(ValueType))
    269282{
    270283    ValueType value;
     
    274287    if (constraint.getExact(value)) {
    275288        ASSERT(constraint.validForRange(capabilityMin, capabilityMax));
    276         (source->*function)(value);
     289        (source->*applier)(value);
    277290        return;
    278291    }
     
    303316
    304317    if (value != current)
    305         (source->*function)(value);
     318        (source->*applier)(value);
    306319}
    307320
     
    309322{
    310323    RealtimeMediaSourceCapabilities& capabilities = *this->capabilities();
    311     switch (constraint.type()) {
     324    switch (constraint.constraintType()) {
    312325    case MediaConstraintType::Width: {
     326        ASSERT(constraint.isInt());
    313327        if (!capabilities.supportsWidth())
    314328            return;
    315329
    316330        auto range = capabilities.width();
    317         applyNumericConstraint(constraint, size().width(), range.rangeMin().asInt, range.rangeMax().asInt, this, &RealtimeMediaSource::setWidth);
     331        applyNumericConstraint(downcast<IntConstraint>(constraint), size().width(), range.rangeMin().asInt, range.rangeMax().asInt, this, &RealtimeMediaSource::setWidth);
    318332        break;
    319333    }
    320334
    321335    case MediaConstraintType::Height: {
     336        ASSERT(constraint.isInt());
    322337        if (!capabilities.supportsHeight())
    323338            return;
    324339
    325340        auto range = capabilities.height();
    326         applyNumericConstraint(constraint, size().height(), range.rangeMin().asInt, range.rangeMax().asInt, this, &RealtimeMediaSource::setHeight);
     341        applyNumericConstraint(downcast<IntConstraint>(constraint), size().height(), range.rangeMin().asInt, range.rangeMax().asInt, this, &RealtimeMediaSource::setHeight);
    327342        break;
    328343    }
    329344
    330345    case MediaConstraintType::FrameRate: {
     346        ASSERT(constraint.isDouble());
    331347        if (!capabilities.supportsFrameRate())
    332348            return;
    333349
    334350        auto range = capabilities.frameRate();
    335         applyNumericConstraint(constraint, frameRate(), range.rangeMin().asDouble, range.rangeMax().asDouble, this, &RealtimeMediaSource::setFrameRate);
     351        applyNumericConstraint(downcast<DoubleConstraint>(constraint), frameRate(), range.rangeMin().asDouble, range.rangeMax().asDouble, this, &RealtimeMediaSource::setFrameRate);
    336352        break;
    337353    }
    338354
    339355    case MediaConstraintType::AspectRatio: {
     356        ASSERT(constraint.isDouble());
    340357        if (!capabilities.supportsAspectRatio())
    341358            return;
    342359
    343360        auto range = capabilities.aspectRatio();
    344         applyNumericConstraint(constraint, aspectRatio(), range.rangeMin().asDouble, range.rangeMax().asDouble, this, &RealtimeMediaSource::setAspectRatio);
     361        applyNumericConstraint(downcast<DoubleConstraint>(constraint), aspectRatio(), range.rangeMin().asDouble, range.rangeMax().asDouble, this, &RealtimeMediaSource::setAspectRatio);
    345362        break;
    346363    }
    347364
    348365    case MediaConstraintType::Volume: {
     366        ASSERT(constraint.isDouble());
    349367        if (!capabilities.supportsVolume())
    350368            return;
    351369
    352370        auto range = capabilities.volume();
    353         applyNumericConstraint(constraint, volume(), range.rangeMin().asDouble, range.rangeMax().asDouble, this, &RealtimeMediaSource::setVolume);
     371        applyNumericConstraint(downcast<DoubleConstraint>(constraint), volume(), range.rangeMin().asDouble, range.rangeMax().asDouble, this, &RealtimeMediaSource::setVolume);
    354372        break;
    355373    }
    356374
    357375    case MediaConstraintType::SampleRate: {
     376        ASSERT(constraint.isInt());
    358377        if (!capabilities.supportsSampleRate())
    359378            return;
    360379
    361380        auto range = capabilities.sampleRate();
    362         applyNumericConstraint(constraint, sampleRate(), range.rangeMin().asDouble, range.rangeMax().asDouble, this, &RealtimeMediaSource::setSampleRate);
     381        applyNumericConstraint(downcast<IntConstraint>(constraint), sampleRate(), range.rangeMin().asInt, range.rangeMax().asInt, this, &RealtimeMediaSource::setSampleRate);
    363382        break;
    364383    }
    365384
    366385    case MediaConstraintType::SampleSize: {
     386        ASSERT(constraint.isInt());
    367387        if (!capabilities.supportsSampleSize())
    368388            return;
    369389
    370390        auto range = capabilities.sampleSize();
    371         applyNumericConstraint(constraint, sampleSize(), range.rangeMin().asDouble, range.rangeMax().asDouble, this, &RealtimeMediaSource::setSampleSize);
    372         break;
    373     }
    374 
    375     case MediaConstraintType::EchoCancellation:
     391        applyNumericConstraint(downcast<IntConstraint>(constraint), sampleSize(), range.rangeMin().asInt, range.rangeMax().asInt, this, &RealtimeMediaSource::setSampleSize);
     392        break;
     393    }
     394
     395    case MediaConstraintType::EchoCancellation: {
     396        ASSERT(constraint.isBoolean());
    376397        if (!capabilities.supportsEchoCancellation())
    377398            return;
    378399
    379400        bool setting;
    380         if (constraint.getExact(setting) || constraint.getIdeal(setting))
     401        const BooleanConstraint& boolConstraint = downcast<BooleanConstraint>(constraint);
     402        if (boolConstraint.getExact(setting) || boolConstraint.getIdeal(setting))
    381403            setEchoCancellation(setting);
    382404        break;
     405    }
    383406
    384407    case MediaConstraintType::FacingMode: {
     408        ASSERT(constraint.isString());
    385409        if (!capabilities.supportsFacingMode())
    386410            return;
    387411
    388412        auto& supportedModes = capabilities.facingMode();
    389         std::function<bool(MediaConstraint::ConstraintType, const String&)> filter = [supportedModes](MediaConstraint::ConstraintType, const String& modeString) {
     413        auto filter = [supportedModes](const String& modeString) {
    390414            auto mode = RealtimeMediaSourceSettings::videoFacingModeEnum(modeString);
    391415            for (auto& supportedMode : supportedModes) {
     
    396420        };
    397421
    398         auto modeString = constraint.find(filter);
     422        auto modeString = downcast<StringConstraint>(constraint).find(filter);
    399423        if (!modeString.isEmpty())
    400424            setFacingMode(RealtimeMediaSourceSettings::videoFacingModeEnum(modeString));
     
    404428    case MediaConstraintType::DeviceId:
    405429    case MediaConstraintType::GroupId:
     430        ASSERT(constraint.isString());
    406431        // There is nothing to do here, neither can be changed.
    407432        break;
     
    432457    //    properties as ideal values. Let candidates be the set of settings dictionaries for which the fitness
    433458    //    distance is finite.
    434     auto& mandatoryConstraints = constraints.mandatoryConstraints();
    435     for (auto& nameConstraintPair : mandatoryConstraints) {
    436         const auto& constraint = nameConstraintPair.value;
    437         if (fitnessDistance(*constraint) == std::numeric_limits<double>::infinity()) {
    438             failedConstraint = constraint->name();
    439             return false;
     459
     460    failedConstraint = emptyString();
     461    constraints.mandatoryConstraints().filter([&](const MediaConstraint& constraint) {
     462        if (fitnessDistance(constraint) == std::numeric_limits<double>::infinity()) {
     463            failedConstraint = constraint.name();
     464            return true;
    440465        }
    441466
    442         candidates.set(*constraint);
    443     }
     467        candidates.set(constraint);
     468        return false;
     469    });
     470
     471    if (!failedConstraint.isEmpty())
     472        return false;
    444473
    445474    // 4. If candidates is empty, return undefined as the result of the SelectSettings() algorithm.
     
    454483    Vector<std::pair<double, MediaTrackConstraintSetMap>> supportedConstraints;
    455484    double minimumDistance = std::numeric_limits<double>::infinity();
     485
    456486    for (const auto& advancedConstraint : constraints.advancedConstraints()) {
    457487        double constraintDistance = 0;
    458488        bool supported = false;
    459         for (auto& nameConstraintPair : advancedConstraint) {
    460             double distance = fitnessDistance(*nameConstraintPair.value);
     489
     490        advancedConstraint.forEach([&](const MediaConstraint& constraint) {
     491            double distance = fitnessDistance(constraint);
    461492            constraintDistance += distance;
    462493            if (distance != std::numeric_limits<double>::infinity())
    463494                supported = true;
    464         }
     495        });
    465496
    466497        if (constraintDistance < minimumDistance)
     
    477508    //    The UA should use the one with the smallest fitness distance, as calculated in step 3.
    478509    if (minimumDistance != std::numeric_limits<double>::infinity()) {
    479         supportedConstraints.removeAllMatching( [&] (std::pair<double, MediaTrackConstraintSetMap> pair) -> bool {
     510        supportedConstraints.removeAllMatching([&](std::pair<double, MediaTrackConstraintSetMap> pair) -> bool {
    480511            return pair.first > minimumDistance;
    481512        });
     
    483514        if (!supportedConstraints.isEmpty()) {
    484515            auto& advancedConstraint = supportedConstraints[0].second;
    485             for (auto& nameConstraintPair : advancedConstraint)
    486                 candidates.merge(*nameConstraintPair.value);
     516            advancedConstraint.forEach([&](const MediaConstraint& constraint) {
     517                candidates.merge(constraint);
     518            });
    487519        }
    488520    }
     
    491523}
    492524
    493 
    494525void RealtimeMediaSource::applyConstraints(const MediaConstraints& constraints, SuccessHandler successHandler, FailureHandler failureHandler)
    495526{
     
    497528
    498529    FlattenedConstraint candidates;
    499 
    500530    String failedConstraint;
    501531    if (!selectSettings(constraints, candidates, failedConstraint)) {
     
    504534    }
    505535
    506     for (auto constraint : candidates)
    507         applyConstraint(*constraint);
     536    for (auto& variant : candidates)
     537        applyConstraint(variant);
    508538
    509539    successHandler();
     
    579609}
    580610
    581 void RealtimeMediaSource::setSampleRate(double rate)
     611void RealtimeMediaSource::setSampleRate(int rate)
    582612{
    583613    if (m_sampleRate == rate || !applySampleRate(rate))
     
    588618}
    589619
    590 void RealtimeMediaSource::setSampleSize(double size)
     620void RealtimeMediaSource::setSampleSize(int size)
    591621{
    592622    if (m_sampleSize == size || !applySampleSize(size))
  • trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h

    r205574 r206445  
    149149    virtual bool applyVolume(double) { return false; }
    150150
    151     double sampleRate() const { return m_sampleRate; }
    152     void setSampleRate(double);
    153     virtual bool applySampleRate(double) { return false; }
    154 
    155     double sampleSize() const { return m_sampleSize; }
    156     void setSampleSize(double);
    157     virtual bool applySampleSize(double) { return false; }
     151    int sampleRate() const { return m_sampleRate; }
     152    void setSampleRate(int);
     153    virtual bool applySampleRate(int) { return false; }
     154
     155    int sampleSize() const { return m_sampleSize; }
     156    void setSampleSize(int);
     157    virtual bool applySampleSize(int) { return false; }
    158158
    159159    bool echoCancellation() const { return m_echoCancellation; }
     
    171171    WeakPtr<RealtimeMediaSource> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
    172172
    173     bool supportsConstraints(const MediaTrackConstraintSetMap&);
    174173    bool selectSettings(const MediaConstraints&, FlattenedConstraint&, String&);
    175174    double fitnessDistance(const MediaConstraint&);
  • trunk/Source/WebCore/platform/mediastream/mac/AVCaptureDeviceManager.mm

    r205929 r206445  
    268268{
    269269    const RealtimeMediaSourceSupportedConstraints& supportedConstraints = RealtimeMediaSourceCenter::singleton().supportedConstraints();
    270     MediaConstraintType constraintType = constraint.type();
     270    MediaConstraintType constraintType = constraint.constraintType();
    271271    if (!supportedConstraints.supportsConstraint(constraintType))
    272272        return false;
     
    280280            // FIXME: https://bugs.webkit.org/show_bug.cgi?id=160578. Support min, max constraints.
    281281            int exact;
    282             if (!constraint.getExact(exact))
     282            if (!downcast<const IntConstraint>(constraint).getExact(exact))
    283283                return false;
    284284
     
    289289            // FIXME: https://bugs.webkit.org/show_bug.cgi?id=160578. Support min, max constraints.
    290290            int exact;
    291             if (!constraint.getExact(exact))
     291            if (!downcast<const IntConstraint>(constraint).getExact(exact))
    292292                return false;
    293293
  • trunk/Source/WebCore/platform/mock/MediaConstraintsMock.cpp

    r204595 r206445  
    4444
    4545    int min = floor;
    46     if (constraint.getMin(min) && min > ceiling)
     46    if (downcast<const IntConstraint>(constraint).getMin(min) && min > ceiling)
    4747        return false;
    4848
    4949    int max = ceiling;
    50     if (constraint.getMax(max) && max < min)
     50    if (downcast<const IntConstraint>(constraint).getMax(max) && max < min)
    5151        return false;
    5252
    5353    int exact;
    54     if (constraint.getExact(exact) && (exact < min || exact > max))
     54    if (downcast<const IntConstraint>(constraint).getExact(exact) && (exact < min || exact > max))
    5555        return false;
    5656
     
    6464
    6565    double min = floor;
    66     if (constraint.getMin(min) && min > ceiling)
     66    if (downcast<const DoubleConstraint>(constraint).getMin(min) && min > ceiling)
    6767        return false;
    6868
    6969    double max = ceiling;
    70     if (constraint.getMax(max) && max < min)
     70    if (downcast<const DoubleConstraint>(constraint).getMax(max) && max < min)
    7171        return false;
    7272
    7373    double exact;
    74     if (constraint.getExact(exact) && (exact < min || exact > max))
     74    if (downcast<const DoubleConstraint>(constraint).getExact(exact) && (exact < min || exact > max))
    7575        return false;
    7676
     
    8181{
    8282    bool exact;
    83     if (constraint.getExact(exact))
     83    if (downcast<const BooleanConstraint>(constraint).getExact(exact))
    8484        return exact;
    8585
     
    9090{
    9191    Vector<String> exact;
    92     if (constraint.getExact(exact)) {
     92    if (downcast<const StringConstraint>(constraint).getExact(exact)) {
    9393        for (auto& constraintValue : exact) {
    9494            if (constraintValue.find("invalid") != notFound)
     
    102102static bool isSatisfiable(RealtimeMediaSource::Type type, const MediaConstraint& constraint)
    103103{
    104     MediaConstraintType constraintType = constraint.type();
     104    MediaConstraintType constraintType = constraint.constraintType();
    105105
    106106    if (type == RealtimeMediaSource::Audio) {
     
    125125}
    126126
    127 const String& MediaConstraintsMock::verifyConstraints(RealtimeMediaSource::Type type, const MediaConstraints& constraints)
     127const String MediaConstraintsMock::verifyConstraints(RealtimeMediaSource::Type type, const MediaConstraints& constraints)
    128128{
    129     auto& mandatoryConstraints = constraints.mandatoryConstraints();
    130     for (auto& nameConstraintPair : mandatoryConstraints) {
    131         if (!isSatisfiable(type, *nameConstraintPair.value))
    132             return nameConstraintPair.key;
    133     }
     129    String invalidConstraint = emptyString();
     130    constraints.mandatoryConstraints().filter([&](const MediaConstraint& constraint) {
     131        if (!isSatisfiable(type, constraint)) {
     132            invalidConstraint = constraint.name();
     133            return true;
     134        }
    134135
    135     return emptyString();
     136        return false;
     137    });
     138
     139    return invalidConstraint;
     140
    136141}
    137142
  • trunk/Source/WebCore/platform/mock/MediaConstraintsMock.h

    r204516 r206445  
    4040class MediaConstraintsMock {
    4141public:
    42     static const String& verifyConstraints(RealtimeMediaSource::Type, const MediaConstraints&);
     42    static const String verifyConstraints(RealtimeMediaSource::Type, const MediaConstraints&);
    4343};
    4444
  • trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.h

    r205348 r206445  
    5454
    5555    bool applyVolume(double) override { return true; }
    56     bool applySampleRate(double) override { return true; }
    57     bool applySampleSize(double) override { return true; }
     56    bool applySampleRate(int) override { return true; }
     57    bool applySampleSize(int) override { return true; }
    5858    bool applyEchoCancellation(bool) override { return true; }
    5959
  • trunk/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp

    r205929 r206445  
    110110
    111111    if (audioConstraints.isValid()) {
    112         const String& invalidQuery = MediaConstraintsMock::verifyConstraints(RealtimeMediaSource::Audio, audioConstraints);
     112        const String invalidQuery = MediaConstraintsMock::verifyConstraints(RealtimeMediaSource::Audio, audioConstraints);
    113113        if (!invalidQuery.isEmpty()) {
    114114            client->failedToCreateStreamWithConstraintsError(invalidQuery);
     
    121121
    122122    if (videoConstraints.isValid()) {
    123         const String& invalidQuery = MediaConstraintsMock::verifyConstraints(RealtimeMediaSource::Video, videoConstraints);
     123        const String invalidQuery = MediaConstraintsMock::verifyConstraints(RealtimeMediaSource::Video, videoConstraints);
    124124        if (!invalidQuery.isEmpty()) {
    125125            client->failedToCreateStreamWithConstraintsError(invalidQuery);
Note: See TracChangeset for help on using the changeset viewer.