Initial Author of this Specification was Ian Hickson, Google Inc., with the following copyright statement:
© Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and Opera Software ASA. You are granted a license to use, reproduce and create derivative works of this document.
All subsequent changes since 26 July 2011 done by the W3C WebRTC Working Group and the Device APIs Working Group are under the following Copyright:
© 2011-2013 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved. Document use rules apply.
For the entire publication on the W3C site the liability and trademark rules apply.
This document is a temporary version that has deleted all sections except one. This allows the editors to get that section out to the working group and get comments on it before making the associated changes to the rest of the specification. Readers that need more context are advised to have a look at the previos version.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document is not complete. It is subject to major changes and, while early experimentations are encouraged, it is therefore not intended for implementation. The API is based on preliminary work done in the WHATWG.
This document was published by the Web Real-Time Communication Working Group and Device APIs Working Group as an Editor's Draft. If you wish to make comments regarding this document, please send them to public-media-capture@w3.org (subscribe, archives). All comments are welcome.
Publication as an Editor's Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures (Web Real-Time Communication Working Group, Device APIs Working Group) made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
The Constrainable interface allows its consumers to inspect and adjust
the properties of the object that implements it. It is broken out as a
separate interface so that it can be used in other specifications. The core
concept is that of a Capability, which consists of a property or feature of
an object and the set of its possible values, which may be specified either
as a range or as an enumeration. For example, a camera might be capable of
framerates (a property) between 20 and 50 frames per second (a range) and
may be able to be positioned (a property) facing towards the user, away
from the user, or to the left or right of the user (an enumerated set.) The
application can examine a Constrainable object's set of Capabilities via
the getCapabilities()
accessor.
The application can select the (range of) values it wants for an
object's Capabilities by means of one or more ConstraintSets and the
applyConstraints()
method. A ConstraintSet consists of the
names of one or more properties of the object plus the desired value (or a
range of desired values) for each of them. Each of those property/value
pairs can be considered to be an individual constraint. For example, the
application may set a ConstraintSet containing two constraints, the first
stating that the framerate of a camera be between 30 and 40 frames per
second (a range) and the second that the camera should be facing the user
(a specific value). ConstraintSets can be mandatory or optional. In the
case of optional ConstraintSets, the UA will consider the ConstraintSets in
the order in which they are specified, and will try to satisfy each one,
but will ignore a ConstraintSet if it cannot satisfy it. In the case of a
mandatory ConstraintSet, the UA will try to satisfy it, and will call the
errorCallback
if it cannot do so. For example, suppose that an
application applies three individual constraints, one stating that the
video aspect ratio should be 3 to 2 (height to width), the next that the
height should be 600 and the last that the width should be 500. Since these
constraints interact with each other (the aspect ratio affects the possible
values for height and width, and vice-versa) it is impossible to satisfy
all three of them, so if they are all contained in a mandatory
ConstraintSet, the UA will call the errorCallback
. However if
any one of the constraints is placed in an optional ConstraintSet, the
other two can be satisfied, so the UA will satisfy the two mandatory ones,
silently ignore the optional one, and call the
successCallback.
The ordering of optional ConstraintSets is significant. In the example
in the previous paragraph, suppose that aspect ratio constraint is part of
a mandatory ConstraintSet and that the height and width constraints are
part of separate optional ConstraintSets. If the height ConstraintSet is
specified first (and the other constraints in the ConstraintSet can also be
satisfied), then it will be satisfied and the width ConstraintSet will be
ignored. Thus the height will be set to 600 and the the width will be set
to 400. On the other hand, if width is specified before height, the width
ConstraintSet will be satisfied and the height ConstraintSet will be
ignored, resulting in width of 500 and height of 750. (Note that the
mandatory aspect ratio constraint is enforced in both cases.) The UA will
attempt to satisfy as many optional ConstraintSets as it can, even if some
of them cannot be satisfied and must therefore be ignored. Application
authors can therefore implement a backoff strategy by specifying multiple
optional ConstraintSets for the same property. For example, an application
might specify three optional ConstraintSets, the first asking for a
framerate greater than 500, the second asking for a framerate greater than
400, and the third asking for one greater than 300. If the UA is capable of
setting a framerate greater than 500, it will (and the subsequent two
ConstraintSets will be trivially satisfied.) However, if the UA cannot set
the framerate above 500, it will ignore that ConstraintSet and attempt to
set the framerate above 400. If that fails, it will then try to set it
above 300. If the UA cannot satisfy any of the three ConstraintSets, it
will set the framerate to any value it can get. If the developer wanted to
insist on 300 as a lower bound, he put that in a mandatory ConstraintSet.
In that case, the UA would fail altogether if it couldn't get a value over
300, but would choose a value over 500 if possible, then try for a value
over 400. An application may inspect the set of ConstraintSets currently in
effect via the getConstraints()
accessor.
The specific value that the UA chooses for a Capability is referred to
as a Setting. For example, if the application applies a ConstraintSet
specifying that the framerate must be at least 30 frames per second, and no
greater than 40, the Setting can be any intermediate value, e.g., 32, 35,
or 37 frames per second. The application can query the current settings of
the object's Capabilities via the getSettings()
accessor.
[NoInterfaceObject]
interface Constrainable {
Capabilities getCapabilities ();
Constraints
getConstraints ();
Settings getSettings ();
void applyConstraints (Constraints
constraints, VoidFunction successCallback, ConstraintErrorCallback
errorCallback);
attribute EventHandler onoverconstrained;
};
onoverconstrained
of type EventHandler, overconstrained
,
must be supported by all objects
implementing the Constrainable
interface.
The UA must raise a
MediaErrorEvent
named "overconstrained" if changing
circumstances at runtime result in the currently valid mandatory
ConstraintSet no longer being satisfied. This MediaErrorEvent
must contain a MediaError whose
name
is "overconstrainedError", and whose
constraintName
attribute is set to one of the mandatory
constraints that can no longer be satisfied. The message
attribute of the MediaError SHOULD contain a string that is useful
for debugging. The conditions under which this error might occur are
platform and application-specific. For example, the user might
physically manipulate a camera in a way that makes it impossible to
provide a resolution that satisfies the constraints. The UA MAY take
other actions as a result of the overconstrained situation.
applyConstraints
The applyConstraints() algorithm for applying constraints is stated below. Here are some preliminary definitions that are used in the statement of the algorithm:
When applyConstraints
is called, the UA must queue a task to run the following
steps:
getConstraints
.)errorCallback
, passing it a new
MediaError
with name
ConstraintNotSatisfied
and constraintName
set to any of the mandatory constraints that could not be
satisfied, and return. existingConstraints remain in
effect in this case.successCallback
. From this point on until applyConstraints() is
called successfully again, getConstraints() must return newConstraints. Note: the UA
MAY modify the values of one or more properties of
object at any time, as long as the resulting set of
values satisfy the current set of constraints.Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
constraints |
| ✘ | ✘ | A new constraint structure to apply to this object. |
successCallback | VoidFunction | ✘ | ✘ | Called if the mandatory ConstraintSet can be satisfied. |
errorCallback |
| ✘ | ✘ | Called if the mandatory ConstraintSet cannot be satisfied. |
void
getCapabilities
The getCapabilities() method returns the dictionary of the capabilities that the object supports.
It is possible that the underlying hardware may not exactly map
to the range defined in the registry entry. Where this is possible,
the entry should define how
to translate and scale the hardware's setting onto the values
defined in the entry. For example, suppose that a registry entry
defines a hypothetical fluxCapacitance capability that is defined
to be the range from -10 (min) to 10 (max), but there are common
hardware devices that support only values of "off" "medium" and
"full". The registry entry might specify that for such hardware,
the user agent should map the range value of -10 to "off", 10 to
"full", and 0 to "medium". It might also indicate that given a
ConstraintSet imposing a strict value of 3, the user agent should
attempt to set the value of "medium" on the hardware, and and that
getSettings()
should return a fluxCapacitance
of 0, since that is the value defined as corresponding to
"medium".
Capabilities
getConstraints
The getConstraints() method returns all the
ConstraintSets
that were applied to the object in the
last successful call of applyConstraints()
. The value
must contain only the
ConstraintSets that were successfully applied, and it must maintain the order that they were
specified in.
If no mandatory ConstraintSet has been defined, the
mandatory
field will not be present (it will be
undefined). If no optional ConstraintSets have been defined, the
optional
field will not be present (it will be
undefined). If neither optional nor mandatory ConstraintSets have
been created, the value will be null
.
Constraints
getSettings
applyConstraints()
. Note that the actual
setting of a property must be a
single value.Settings
callback ConstraintErrorCallback = void (MediaError
error);
ConstraintErrorCallback
Parameterserror
of type MediaError
MediaError
holding the mandatory constraint
that could not be satisfied.An example of Constraints that could be passed into
applyConstraints()
or returned as a value of
constraints
is below. It uses the properties defined
in the Track property registry.
{ "mandatory": { "width": { "min": 640 }, "height": { "min": 480 } }, "optional": [{ "width": 650 }, { "width": { "min": 650 } }, { "frameRate": 60 }, { "width": { "max": 800 } }, { "facingMode": "user" }] }
For each class/interface that implements Constrainable, there must be a corresponding registry that defines the constrainable properties of that class of object. The registry entries must contain the name of each property along with its set of legal values. The registry for MediaStreamTrack is defined below. The syntax for the specification of the set of legal values depends on the type of the values. In addition to the standard atomic types (boolean, long, float, DOMString), legal values include lists of any of the atomic types, plus min-max ranges, as defined below.
List values must be interpreted
as disjunctions. For example, if a property 'facingMode' for a camera is
defined as having legal values ["left", "right", "user", "environment"],
this means that 'facingMode' can have the value "left", the value
"right", the value "environment" or the value "user". Similarly
Constraints
restricting 'facingMode' to ["user", "left", "right"]
would mean that the UA should select a camera (or point the camera, if
that is possible) so that "facingMode" is either "user", "left", or
"right". This Constraint would thus request that the camera not be facing
away from the user, but would allow the UA to choose among the other
directions.
typedef PropertyValueSet DOMString[];
dictionary PropertyValueDoubleRange {
double max;
double min;
};
PropertyValueDoubleRange
Membersmax
of type doublemin
of type doubledictionary PropertyValueLongRange {
long max;
long min;
};
PropertyValueLongRange
Membersmax
of type longmin
of type longCapabilities are dictionary containing one or more
key-value pairs, where each key must be a constrainable property defined in the associated
registry, and each value must be
a subset of the set of values defined for that property in the registry.
The exact syntax of the value expression depends on the type of the
property but is of type
. The
Capabilities dictionary specifies the subset of the constrainable
properties and values from the registry that the UA supports. Note that a
UA may support only a subset of the
properties that are defined in the registry, and may support a subset of the set values for those
properties that it does support. Note that Capabilities are returned from
the UA to the application, and cannot be specified by the application.
However, the application can control the Settings that the UA chooses for
Capabilities by means of ConstraintSets.ConstraintValues
An example of a Capabilities dictionary is shown below. This example is not very realistic in that a browser would actually be required to support more settings that just these.
{ "frameRate": { "min": 1.0, "max": 60.0 }, "facingMode": ["user", "environment"] }
A Setting is a dictionary containing one or more key-value
pairs. It must contain each key
returned in getCapabilities()
. There must be a single value for each key and the value
must a member of the set defined
for that property by capabilities()
. The exact syntax of the
value expression depends on the type of the property. It will be a
DomString for properties of type PropertyValueSet, it will be a long for
properties of type PropertyValueLongRange , it will be a double for
properties of type PropertyValueDoubleRange. Thus the
Settings
dictionary contains the actual values that the UA
has chosen for the object's Capabilities.
An example of a Setting dictionary is shown below. This example is not very realistic in that a browser would actually be required to support more settings that just these.
{ "frameRate": 30.0, "facingMode": "user" }
dictionary Constraints {
ConstraintSet
? mandatory;
ConstraintSet
[] optional;
};
Constraints
Membersmandatory
of type ConstraintSet
, nullableThe set of constraints that the UA must satisfy or else call the
errorCallback
.
optional
of type array of ConstraintSet
The set of ConstraintSets that the UA should try to satisfy but may ignore if they cannot be satisfied. The order of
these ConstraintSets is significant. In particular, when they are
passed as an argument to applyConstraints
, the UA
must try to satisfy them in the
order that is specified. Thus if optional ConstraintSets C1 and C2
can be satisfied individually, but not together, then whichever of C1
and C2 is first in this list will be satisfied, and the other will
not. The UA must attempt to
satisfy all optional ConstraintSets in the list, even if some cannot
be satisfied. Thus, in the preceding example, if optional constraint
C3 is specified after C1 and C2, the UA will attempt to satisfy C3
even though C2 cannot be satisfied. Note that a given property name
may occur multiple times in these sets.
Each property of a ConstraintSet corresponds to a Capability and specifies a subset of its legal values. Applying a ConstraintSet instructs that UA to restrict the setting of the corresponding Capabilities to the specified values or ranges of values. A given property MAY occur both in the mandatory and the optional ConstraintSets list, and MAY occur more than once in the optional ConstraintSets list.
typedef (DOMString or long or double or boolean) ConstraintValue;
typedef (ConstraintValue
or PropertyValueSet or PropertyValueLongRange
or PropertyValueDoubleRange
) ConstraintValues;
[NoInterfaceObject]
interface ConstraintSet {
ConstraintValues
getter (DOMString name);
};
getter
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
name | DOMString | ✘ | ✘ |
ConstraintValues
In ECMAScript, ConstraintSet objects are represented using regular native objects with optional properties whose names represent constraint name. The conversion from an ECMAScript value, representing a ConstraintSet, to an IDL ConstraintSet must not fail if a property name in the ECMAScript value does not match any of the Capabilities of the Constrainable object.
In ECMAScript, all the properties of the ConstraintSet object are
optional; the developer may specify any of these properties when
creating the object. Note, however, that unknown property names will
result in a ConstraintSet that can not be satisfied, as described in
applyConstraints()
above.