Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "modules/mediastream/MediaConstraintsImpl.h" | 31 #include "modules/mediastream/MediaConstraintsImpl.h" |
| 32 | 32 |
| 33 #include "bindings/core/v8/ArrayValue.h" | 33 #include "bindings/core/v8/ArrayValue.h" |
| 34 #include "bindings/core/v8/Dictionary.h" | 34 #include "bindings/core/v8/Dictionary.h" |
| 35 #include "bindings/core/v8/ExceptionState.h" | 35 #include "bindings/core/v8/ExceptionState.h" |
| 36 #include "core/dom/ExceptionCode.h" | 36 #include "core/dom/ExceptionCode.h" |
| 37 #include "core/dom/ExecutionContext.h" | |
| 37 #include "core/frame/UseCounter.h" | 38 #include "core/frame/UseCounter.h" |
| 39 #include "core/inspector/ConsoleMessage.h" | |
| 38 #include "modules/mediastream/MediaTrackConstraintSet.h" | 40 #include "modules/mediastream/MediaTrackConstraintSet.h" |
| 39 #include "platform/Logging.h" | 41 #include "platform/Logging.h" |
| 40 #include "platform/RuntimeEnabledFeatures.h" | 42 #include "platform/RuntimeEnabledFeatures.h" |
| 41 #include "wtf/HashMap.h" | 43 #include "wtf/HashMap.h" |
| 42 #include "wtf/Vector.h" | 44 #include "wtf/Vector.h" |
| 43 #include "wtf/text/StringHash.h" | 45 #include "wtf/text/StringHash.h" |
| 44 | 46 |
| 45 namespace blink { | 47 namespace blink { |
| 46 | 48 |
| 47 namespace MediaConstraintsImpl { | 49 namespace MediaConstraintsImpl { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 const char kScreencastMinBitrate[] = "googScreencastMinBitrate"; | 118 const char kScreencastMinBitrate[] = "googScreencastMinBitrate"; |
| 117 const char kCpuOveruseDetection[] = "googCpuOveruseDetection"; | 119 const char kCpuOveruseDetection[] = "googCpuOveruseDetection"; |
| 118 const char kCpuUnderuseThreshold[] = "googCpuUnderuseThreshold"; | 120 const char kCpuUnderuseThreshold[] = "googCpuUnderuseThreshold"; |
| 119 const char kCpuOveruseThreshold[] = "googCpuOveruseThreshold"; | 121 const char kCpuOveruseThreshold[] = "googCpuOveruseThreshold"; |
| 120 const char kCpuUnderuseEncodeRsdThreshold[] = "googCpuUnderuseEncodeRsdThreshold "; | 122 const char kCpuUnderuseEncodeRsdThreshold[] = "googCpuUnderuseEncodeRsdThreshold "; |
| 121 const char kCpuOveruseEncodeRsdThreshold[] = "googCpuOveruseEncodeRsdThreshold"; | 123 const char kCpuOveruseEncodeRsdThreshold[] = "googCpuOveruseEncodeRsdThreshold"; |
| 122 const char kCpuOveruseEncodeUsage[] = "googCpuOveruseEncodeUsage"; | 124 const char kCpuOveruseEncodeUsage[] = "googCpuOveruseEncodeUsage"; |
| 123 const char kHighStartBitrate[] = "googHighStartBitrate"; | 125 const char kHighStartBitrate[] = "googHighStartBitrate"; |
| 124 const char kPayloadPadding[] = "googPayloadPadding"; | 126 const char kPayloadPadding[] = "googPayloadPadding"; |
| 125 // End of names from libjingle | 127 // End of names from libjingle |
| 128 // Names that have been used in the past, but should now be ignored. | |
| 129 // Kept around for backwards compatibility. | |
| 130 // https://crbug.com/579729 | |
| 131 const char kGoogLeakyBucket[] = "googLeakyBucket"; | |
| 132 const char kEnableAutoThrottling[] = "enableAutoThrottling"; | |
|
miu
2016/01/28 21:11:46
Please remove this one (enableAutoThrottling). Th
hta - Chromium
2016/01/29 06:59:51
I wondered where it came from... took it off your
| |
| 126 | 133 |
| 127 // Names used for testing. | 134 // Names used for testing. |
| 128 const char kTestConstraint1[] = "valid_and_supported_1"; | 135 const char kTestConstraint1[] = "valid_and_supported_1"; |
| 129 const char kTestConstraint2[] = "valid_and_supported_2"; | 136 const char kTestConstraint2[] = "valid_and_supported_2"; |
| 130 | 137 |
| 131 static bool parseMandatoryConstraintsDictionary(const Dictionary& mandatoryConst raintsDictionary, WebVector<WebMediaConstraint>& mandatory) | 138 static bool parseMandatoryConstraintsDictionary(const Dictionary& mandatoryConst raintsDictionary, WebVector<WebMediaConstraint>& mandatory) |
| 132 { | 139 { |
| 133 Vector<WebMediaConstraint> mandatoryConstraintsVector; | 140 Vector<WebMediaConstraint> mandatoryConstraintsVector; |
| 134 HashMap<String, String> mandatoryConstraintsHashMap; | 141 HashMap<String, String> mandatoryConstraintsHashMap; |
| 135 bool ok = mandatoryConstraintsDictionary.getOwnPropertiesAsStringHashMap(man datoryConstraintsHashMap); | 142 bool ok = mandatoryConstraintsDictionary.getOwnPropertiesAsStringHashMap(man datoryConstraintsHashMap); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 240 return true; | 247 return true; |
| 241 } | 248 } |
| 242 | 249 |
| 243 static bool toBoolean(const WebString& asWebString) | 250 static bool toBoolean(const WebString& asWebString) |
| 244 { | 251 { |
| 245 return asWebString.equals("true"); | 252 return asWebString.equals("true"); |
| 246 // TODO(hta): Check against "false" and return error if it's neither. | 253 // TODO(hta): Check against "false" and return error if it's neither. |
| 247 // https://crbug.com/576582 | 254 // https://crbug.com/576582 |
| 248 } | 255 } |
| 249 | 256 |
| 250 static void parseOldStyleNames(const WebVector<WebMediaConstraint>& oldNames, We bMediaTrackConstraintSet& result, MediaErrorState& errorState) | 257 static void parseOldStyleNames(ExecutionContext* context, const WebVector<WebMed iaConstraint>& oldNames, WebMediaTrackConstraintSet& result, MediaErrorState& er rorState) |
| 251 { | 258 { |
| 252 for (const WebMediaConstraint& constraint : oldNames) { | 259 for (const WebMediaConstraint& constraint : oldNames) { |
| 253 if (constraint.m_name.equals(kMinAspectRatio)) { | 260 if (constraint.m_name.equals(kMinAspectRatio)) { |
| 254 result.aspectRatio.setMin(atof(constraint.m_value.utf8().c_str())); | 261 result.aspectRatio.setMin(atof(constraint.m_value.utf8().c_str())); |
| 255 } else if (constraint.m_name.equals(kMaxAspectRatio)) { | 262 } else if (constraint.m_name.equals(kMaxAspectRatio)) { |
| 256 result.aspectRatio.setMax(atof(constraint.m_value.utf8().c_str())); | 263 result.aspectRatio.setMax(atof(constraint.m_value.utf8().c_str())); |
| 257 } else if (constraint.m_name.equals(kMaxWidth)) { | 264 } else if (constraint.m_name.equals(kMaxWidth)) { |
| 258 result.width.setMax(atoi(constraint.m_value.utf8().c_str())); | 265 result.width.setMax(atoi(constraint.m_value.utf8().c_str())); |
| 259 } else if (constraint.m_name.equals(kMinWidth)) { | 266 } else if (constraint.m_name.equals(kMinWidth)) { |
| 260 result.width.setMin(atoi(constraint.m_value.utf8().c_str())); | 267 result.width.setMin(atoi(constraint.m_value.utf8().c_str())); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 346 } else if (constraint.m_name.equals(kCpuUnderuseEncodeRsdThreshold)) { | 353 } else if (constraint.m_name.equals(kCpuUnderuseEncodeRsdThreshold)) { |
| 347 result.googCpuUnderuseEncodeRsdThreshold.setExact(atoi(constraint.m_ value.utf8().c_str())); | 354 result.googCpuUnderuseEncodeRsdThreshold.setExact(atoi(constraint.m_ value.utf8().c_str())); |
| 348 } else if (constraint.m_name.equals(kCpuOveruseEncodeRsdThreshold)) { | 355 } else if (constraint.m_name.equals(kCpuOveruseEncodeRsdThreshold)) { |
| 349 result.googCpuOveruseEncodeRsdThreshold.setExact(atoi(constraint.m_v alue.utf8().c_str())); | 356 result.googCpuOveruseEncodeRsdThreshold.setExact(atoi(constraint.m_v alue.utf8().c_str())); |
| 350 } else if (constraint.m_name.equals(kCpuOveruseEncodeUsage)) { | 357 } else if (constraint.m_name.equals(kCpuOveruseEncodeUsage)) { |
| 351 result.googCpuOveruseEncodeUsage.setExact(toBoolean(constraint.m_val ue)); | 358 result.googCpuOveruseEncodeUsage.setExact(toBoolean(constraint.m_val ue)); |
| 352 } else if (constraint.m_name.equals(kHighStartBitrate)) { | 359 } else if (constraint.m_name.equals(kHighStartBitrate)) { |
| 353 result.googHighStartBitrate.setExact(atoi(constraint.m_value.utf8(). c_str())); | 360 result.googHighStartBitrate.setExact(atoi(constraint.m_value.utf8(). c_str())); |
| 354 } else if (constraint.m_name.equals(kPayloadPadding)) { | 361 } else if (constraint.m_name.equals(kPayloadPadding)) { |
| 355 result.googPayloadPadding.setExact(toBoolean(constraint.m_value)); | 362 result.googPayloadPadding.setExact(toBoolean(constraint.m_value)); |
| 363 } else if (constraint.m_name.equals(kGoogLeakyBucket) | |
| 364 || constraint.m_name.equals(kEnableAutoThrottling)) { | |
| 365 context->addConsoleMessage(ConsoleMessage::create(DeprecationMessage Source, WarningMessageLevel, | |
| 366 "Obsolete constraint named " + String(constraint.m_name) | |
| 367 + " is ignored. Please stop using it.")); | |
| 356 } else if (constraint.m_name.equals(kTestConstraint1) | 368 } else if (constraint.m_name.equals(kTestConstraint1) |
| 357 || constraint.m_name.equals(kTestConstraint2)) { | 369 || constraint.m_name.equals(kTestConstraint2)) { |
| 358 // These constraints are only for testing parsing. | 370 // These constraints are only for testing parsing. |
| 359 // Values 0 and 1 are legal, all others are a ConstraintError. | 371 // Values 0 and 1 are legal, all others are a ConstraintError. |
| 360 if (!constraint.m_value.equals("0") && !constraint.m_value.equals("1 ")) | 372 if (!constraint.m_value.equals("0") && !constraint.m_value.equals("1 ")) { |
| 361 errorState.throwConstraintError("Illegal value for constraint", constraint.m_name); | 373 errorState.throwConstraintError("Illegal value for constraint", constraint.m_name); |
| 374 } | |
| 362 } else { | 375 } else { |
| 363 // TODO(hta): UMA stats for unknown constraints passed. | 376 // TODO(hta): UMA stats for unknown constraints passed. |
| 364 // https://crbug.com/576613 | 377 // https://crbug.com/576613 |
| 378 context->addConsoleMessage(ConsoleMessage::create(DeprecationMessage Source, ErrorMessageLevel, | |
| 379 "Unknown constraint named " + String(constraint.m_name) + " reje cted")); | |
| 365 WTF_LOG(Media, "Unknown constraint name detected"); | 380 WTF_LOG(Media, "Unknown constraint name detected"); |
| 366 errorState.throwConstraintError("Unknown name of constraint detected ", constraint.m_name); | 381 errorState.throwConstraintError("Unknown name of constraint detected ", constraint.m_name); |
| 367 } | 382 } |
| 368 } | 383 } |
| 369 } | 384 } |
| 370 | 385 |
| 371 static WebMediaConstraints createFromNamedConstraints(WebVector<WebMediaConstrai nt>& mandatory, const WebVector<WebMediaConstraint>& optional, MediaErrorState& errorState) | 386 static WebMediaConstraints createFromNamedConstraints(ExecutionContext* context, WebVector<WebMediaConstraint>& mandatory, const WebVector<WebMediaConstraint>& optional, MediaErrorState& errorState) |
| 372 { | 387 { |
| 373 WebMediaTrackConstraintSet basic; | 388 WebMediaTrackConstraintSet basic; |
| 374 WebMediaTrackConstraintSet advanced; | 389 WebMediaTrackConstraintSet advanced; |
| 375 WebMediaConstraints constraints; | 390 WebMediaConstraints constraints; |
| 376 parseOldStyleNames(mandatory, basic, errorState); | 391 parseOldStyleNames(context, mandatory, basic, errorState); |
| 377 if (errorState.hadException()) | 392 if (errorState.hadException()) |
| 378 return constraints; | 393 return constraints; |
| 379 // We ignore errors in optional constraints. | 394 // We ignore errors in optional constraints. |
| 380 MediaErrorState ignoredErrorState; | 395 MediaErrorState ignoredErrorState; |
| 381 parseOldStyleNames(optional, advanced, ignoredErrorState); | 396 parseOldStyleNames(context, optional, advanced, ignoredErrorState); |
| 382 WebVector<WebMediaTrackConstraintSet> advancedVector(&advanced, 1); | 397 WebVector<WebMediaTrackConstraintSet> advancedVector(&advanced, 1); |
| 383 // Use the 4-argument initializer until Chrome has been converted. | 398 // Use the 4-argument initializer until Chrome has been converted. |
| 384 constraints.initialize(optional, mandatory, basic, advancedVector); | 399 constraints.initialize(optional, mandatory, basic, advancedVector); |
| 385 return constraints; | 400 return constraints; |
| 386 } | 401 } |
| 387 | 402 |
| 388 // Deprecated. | 403 // Deprecated. |
| 389 WebMediaConstraints create(const ExecutionContext* context, const Dictionary& co nstraintsDictionary, MediaErrorState& errorState) | 404 WebMediaConstraints create(ExecutionContext* context, const Dictionary& constrai ntsDictionary, MediaErrorState& errorState) |
| 390 { | 405 { |
| 391 WebVector<WebMediaConstraint> optional; | 406 WebVector<WebMediaConstraint> optional; |
| 392 WebVector<WebMediaConstraint> mandatory; | 407 WebVector<WebMediaConstraint> mandatory; |
| 393 if (!parse(constraintsDictionary, optional, mandatory)) { | 408 if (!parse(constraintsDictionary, optional, mandatory)) { |
| 394 errorState.throwTypeError("Malformed constraints object."); | 409 errorState.throwTypeError("Malformed constraints object."); |
| 395 return WebMediaConstraints(); | 410 return WebMediaConstraints(); |
| 396 } | 411 } |
| 397 UseCounter::count(context, UseCounter::MediaStreamConstraintsFromDictionary) ; | 412 UseCounter::count(context, UseCounter::MediaStreamConstraintsFromDictionary) ; |
| 398 return createFromNamedConstraints(mandatory, optional, errorState); | 413 return createFromNamedConstraints(context, mandatory, optional, errorState); |
| 399 } | 414 } |
| 400 | 415 |
| 401 void copyLongConstraint(const ConstrainLongRange& blinkForm, LongConstraint& web Form) | 416 void copyLongConstraint(const ConstrainLongRange& blinkForm, LongConstraint& web Form) |
| 402 { | 417 { |
| 403 if (blinkForm.hasMin()) { | 418 if (blinkForm.hasMin()) { |
| 404 webForm.setMin(blinkForm.min()); | 419 webForm.setMin(blinkForm.min()); |
| 405 } | 420 } |
| 406 if (blinkForm.hasMax()) { | 421 if (blinkForm.hasMax()) { |
| 407 webForm.setMax(blinkForm.max()); | 422 webForm.setMax(blinkForm.max()); |
| 408 } | 423 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 486 copyLongConstraint(constraintsIn.channelCount(), constraintBuffer.channe lCount); | 501 copyLongConstraint(constraintsIn.channelCount(), constraintBuffer.channe lCount); |
| 487 } | 502 } |
| 488 if (constraintsIn.hasDeviceId()) { | 503 if (constraintsIn.hasDeviceId()) { |
| 489 copyStringConstraint(constraintsIn.deviceId(), constraintBuffer.deviceId ); | 504 copyStringConstraint(constraintsIn.deviceId(), constraintBuffer.deviceId ); |
| 490 } | 505 } |
| 491 if (constraintsIn.hasGroupId()) { | 506 if (constraintsIn.hasGroupId()) { |
| 492 copyStringConstraint(constraintsIn.groupId(), constraintBuffer.groupId); | 507 copyStringConstraint(constraintsIn.groupId(), constraintBuffer.groupId); |
| 493 } | 508 } |
| 494 } | 509 } |
| 495 | 510 |
| 496 WebMediaConstraints create(const ExecutionContext* context, const MediaTrackCons traintSet& constraintsIn, MediaErrorState& errorState) | 511 WebMediaConstraints create(ExecutionContext* context, const MediaTrackConstraint Set& constraintsIn, MediaErrorState& errorState) |
| 497 { | 512 { |
| 498 WebMediaConstraints constraints; | 513 WebMediaConstraints constraints; |
| 499 WebMediaTrackConstraintSet constraintBuffer; | 514 WebMediaTrackConstraintSet constraintBuffer; |
| 500 WebVector<WebMediaTrackConstraintSet> advancedBuffer; | 515 WebVector<WebMediaTrackConstraintSet> advancedBuffer; |
| 501 copyConstraints(constraintsIn, constraintBuffer); | 516 copyConstraints(constraintsIn, constraintBuffer); |
| 502 // TODO(hta): Add initialization of advanced constraints once present. | 517 // TODO(hta): Add initialization of advanced constraints once present. |
| 503 // https://crbug.com/253412 | 518 // https://crbug.com/253412 |
| 504 if (constraintsIn.hasOptional() || constraintsIn.hasMandatory()) { | 519 if (constraintsIn.hasOptional() || constraintsIn.hasMandatory()) { |
| 505 if (!constraintBuffer.isEmpty()) { | 520 if (!constraintBuffer.isEmpty()) { |
| 506 errorState.throwTypeError("Malformed constraint: Cannot use both opt ional/mandatory and specific constraints."); | 521 errorState.throwTypeError("Malformed constraint: Cannot use both opt ional/mandatory and specific constraints."); |
| 507 return WebMediaConstraints(); | 522 return WebMediaConstraints(); |
| 508 } | 523 } |
| 509 WebVector<WebMediaConstraint> optional; | 524 WebVector<WebMediaConstraint> optional; |
| 510 WebVector<WebMediaConstraint> mandatory; | 525 WebVector<WebMediaConstraint> mandatory; |
| 511 if (!parse(constraintsIn, optional, mandatory)) { | 526 if (!parse(constraintsIn, optional, mandatory)) { |
| 512 errorState.throwTypeError("Malformed constraints object."); | 527 errorState.throwTypeError("Malformed constraints object."); |
| 513 return WebMediaConstraints(); | 528 return WebMediaConstraints(); |
| 514 } | 529 } |
| 515 UseCounter::count(context, UseCounter::MediaStreamConstraintsNameValue); | 530 UseCounter::count(context, UseCounter::MediaStreamConstraintsNameValue); |
| 516 return createFromNamedConstraints(mandatory, optional, errorState); | 531 return createFromNamedConstraints(context, mandatory, optional, errorSta te); |
| 517 } | 532 } |
| 518 UseCounter::count(context, UseCounter::MediaStreamConstraintsConformant); | 533 UseCounter::count(context, UseCounter::MediaStreamConstraintsConformant); |
| 519 constraints.initialize(constraintBuffer, advancedBuffer); | 534 constraints.initialize(constraintBuffer, advancedBuffer); |
| 520 return constraints; | 535 return constraints; |
| 521 } | 536 } |
| 522 | 537 |
| 523 WebMediaConstraints create() | 538 WebMediaConstraints create() |
| 524 { | 539 { |
| 525 WebMediaConstraints constraints; | 540 WebMediaConstraints constraints; |
| 526 constraints.initialize(); | 541 constraints.initialize(); |
| 527 return constraints; | 542 return constraints; |
| 528 } | 543 } |
| 529 | 544 |
| 530 } // namespace MediaConstraintsImpl | 545 } // namespace MediaConstraintsImpl |
| 531 } // namespace blink | 546 } // namespace blink |
| OLD | NEW |