Bug 1033833 - Update CreateOffer/Answer API to spec - no longer takes constraints but a dictionary. r=smaug, r=abr
authorJan-Ivar Bruaroey <jib@mozilla.com>
Thu, 10 Jul 2014 14:31:25 -0400
changeset 217163 870f07d03e2a857dac2df44aad6e9f41203cd6ab
parent 217162 248b8863ee1c8c23e8eceeeb627f832c819c878c
child 217164 4c72ab9bc7016f4e6b3d5035c4cca22117d0e9d5
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, abr
bugs1033833
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1033833 - Update CreateOffer/Answer API to spec - no longer takes constraints but a dictionary. r=smaug, r=abr
dom/media/PeerConnection.js
dom/media/tests/mochitest/pc.js
dom/media/tests/mochitest/test_dataChannel_noOffer.html
dom/media/tests/mochitest/test_peerConnection_bug834153.html
dom/media/tests/mochitest/test_peerConnection_bug835370.html
dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html
dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html
dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html
dom/webidl/PeerConnectionImpl.webidl
dom/webidl/PeerConnectionObserver.webidl
dom/webidl/RTCPeerConnection.webidl
media/webrtc/signaling/include/CC_Call.h
media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.h
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
media/webrtc/signaling/src/sipcc/core/ccapp/CCProvider.h
media/webrtc/signaling/src/sipcc/core/ccapp/cc_call_feature.c
media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_call.c
media/webrtc/signaling/src/sipcc/core/ccapp/ccprovider.c
media/webrtc/signaling/src/sipcc/core/gsm/fsmdef.c
media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c
media/webrtc/signaling/src/sipcc/core/gsm/h/gsm_sdp.h
media/webrtc/signaling/src/sipcc/core/includes/ccapi.h
media/webrtc/signaling/src/sipcc/core/includes/sessionTypes.h
media/webrtc/signaling/src/sipcc/include/cc_call_feature.h
media/webrtc/signaling/src/sipcc/include/cc_constants.h
media/webrtc/signaling/src/sipcc/include/ccapi_call.h
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCall.cpp
media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCall.h
media/webrtc/signaling/test/signaling_unittests.cpp
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -460,60 +460,16 @@ RTCPeerConnection.prototype = {
     if (rtcConfig.iceServers) {
       let len = rtcConfig.iceServers.length;
       for (let i=0; i < len; i++) {
         mustValidateServer (rtcConfig.iceServers[i], errorMsg);
       }
     }
   },
 
-  /**
-   * MediaConstraints look like this:
-   *
-   * {
-   *   mandatory: {"OfferToReceiveAudio": true, "OfferToReceiveVideo": true },
-   *   optional: [{"VoiceActivityDetection": true}, {"FooBar": 10}]
-   * }
-   *
-   * WebIDL normalizes the top structure for us, but the mandatory constraints
-   * member comes in as a raw object so we can detect unknown constraints. We
-   * compare its members against ones we support, and fail if not found.
-   */
-  _mustValidateConstraints: function(constraints, errorMsg) {
-    if (constraints.mandatory) {
-      let supported;
-      try {
-        // Passing the raw constraints.mandatory here validates its structure
-        supported = this._observer.getSupportedConstraints(constraints.mandatory);
-      } catch (e) {
-        throw new this._win.DOMError("", errorMsg + " - " + e.message);
-      }
-
-      for (let constraint of Object.keys(constraints.mandatory)) {
-        if (!(constraint in supported)) {
-          throw new this._win.DOMError("",
-              errorMsg + " - unknown mandatory constraint: " + constraint);
-        }
-      }
-    }
-    if (constraints.optional) {
-      let len = constraints.optional.length;
-      for (let i = 0; i < len; i++) {
-        let constraints_per_entry = 0;
-        for (let constraint in Object.keys(constraints.optional[i])) {
-          if (constraints_per_entry) {
-            throw new this._win.DOMError("", errorMsg +
-                " - optional constraint must be single key/value pair");
-          }
-          constraints_per_entry += 1;
-        }
-      }
-    }
-  },
-
   // Ideally, this should be of the form _checkState(state),
   // where the state is taken from an enumeration containing
   // the valid peer connection states defined in the WebRTC
   // spec. See Bug 831756.
   _checkClosed: function() {
     if (this._closed) {
       throw new this._win.DOMError("", "Peer connection is closed");
     }
@@ -569,72 +525,55 @@ RTCPeerConnection.prototype = {
   makeGetterSetterEH: function(name) {
     Object.defineProperty(this, name,
                           {
                             get:function()  { return this.getEH(name); },
                             set:function(h) { return this.setEH(name, h); }
                           });
   },
 
-  createOffer: function(onSuccess, onError, constraints) {
-    if (!constraints) {
-      constraints = {};
-    }
-    this._mustValidateConstraints(constraints, "createOffer passed invalid constraints");
-
+  createOffer: function(onSuccess, onError, options) {
+    options = options || {};
     this._queueOrRun({
       func: this._createOffer,
-      args: [onSuccess, onError, constraints],
+      args: [onSuccess, onError, options],
       wait: true
     });
   },
 
-  _createOffer: function(onSuccess, onError, constraints) {
+  _createOffer: function(onSuccess, onError, options) {
     this._onCreateOfferSuccess = onSuccess;
     this._onCreateOfferFailure = onError;
-    this._impl.createOffer(constraints);
+    this._impl.createOffer(options);
   },
 
-  _createAnswer: function(onSuccess, onError, constraints, provisional) {
+  _createAnswer: function(onSuccess, onError) {
     this._onCreateAnswerSuccess = onSuccess;
     this._onCreateAnswerFailure = onError;
 
     if (!this.remoteDescription) {
 
       this._observer.onCreateAnswerError(Ci.IPeerConnection.kInvalidState,
                                          "setRemoteDescription not called");
       return;
     }
 
     if (this.remoteDescription.type != "offer") {
 
       this._observer.onCreateAnswerError(Ci.IPeerConnection.kInvalidState,
                                          "No outstanding offer");
       return;
     }
-
-    // TODO: Implement provisional answer.
-
-    this._impl.createAnswer(constraints);
+    this._impl.createAnswer();
   },
 
-  createAnswer: function(onSuccess, onError, constraints, provisional) {
-    if (!constraints) {
-      constraints = {};
-    }
-
-    this._mustValidateConstraints(constraints, "createAnswer passed invalid constraints");
-
-    if (!provisional) {
-      provisional = false;
-    }
-
+  createAnswer: function(onSuccess, onError) {
     this._queueOrRun({
       func: this._createAnswer,
-      args: [onSuccess, onError, constraints, provisional],
+      args: [onSuccess, onError],
       wait: true
     });
   },
 
   setLocalDescription: function(desc, onSuccess, onError) {
     let type;
     switch (desc.type) {
       case "offer":
@@ -789,17 +728,17 @@ RTCPeerConnection.prototype = {
         this._gotIdentityAssertion(assertion);
       }
     };
 
     this._localIdp.getIdentityAssertion(this._impl.fingerprint,
                                         gotAssertion);
   },
 
-  updateIce: function(config, constraints) {
+  updateIce: function(config) {
     throw new this._win.DOMError("", "updateIce not yet implemented");
   },
 
   addIceCandidate: function(cand, onSuccess, onError) {
     if (!cand.candidate && !cand.sdpMLineIndex) {
       throw new this._win.DOMError("",
           "Invalid candidate passed to addIceCandidate!");
     }
@@ -810,32 +749,27 @@ RTCPeerConnection.prototype = {
   },
 
   _addIceCandidate: function(cand) {
     this._impl.addIceCandidate(cand.candidate, cand.sdpMid || "",
                                (cand.sdpMLineIndex === null) ? 0 :
                                  cand.sdpMLineIndex + 1);
   },
 
-  addStream: function(stream, constraints) {
-    if (!constraints) {
-      constraints = {};
-    }
-    this._mustValidateConstraints(constraints,
-                                  "addStream passed invalid constraints");
+  addStream: function(stream) {
     if (stream.currentTime === undefined) {
       throw new this._win.DOMError("", "Invalid stream passed to addStream!");
     }
     this._queueOrRun({ func: this._addStream,
-                       args: [stream, constraints],
+                       args: [stream],
                        wait: false });
   },
 
-  _addStream: function(stream, constraints) {
-    this._impl.addStream(stream, constraints);
+  _addStream: function(stream) {
+    this._impl.addStream(stream);
   },
 
   removeStream: function(stream) {
      // Bug 844295: Not implementing this functionality.
      throw new this._win.DOMError("", "removeStream not yet implemented");
   },
 
   getStreamById: function(id) {
@@ -1288,21 +1222,17 @@ PeerConnectionObserver.prototype = {
   foundIceCandidate: function(cand) {
     this.dispatchEvent(new this._dompc._win.RTCPeerConnectionIceEvent("icecandidate",
                                                                       { candidate: cand } ));
   },
 
   notifyDataChannel: function(channel) {
     this.dispatchEvent(new this._dompc._win.RTCDataChannelEvent("datachannel",
                                                                 { channel: channel }));
-  },
-
-  getSupportedConstraints: function(dict) {
-    return dict;
-  },
+  }
 };
 
 function RTCPeerConnectionStatic() {
 }
 RTCPeerConnectionStatic.prototype = {
   classDescription: "mozRTCPeerConnectionStatic",
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
                                          Ci.nsIDOMGlobalPropertyInitializer]),
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -754,20 +754,20 @@ function PCT_setMediaConstraints(constra
     this.pcRemote.constraints = constraintsRemote;
 };
 
 /**
  * Sets the media constraints used on a createOffer call in the test.
  *
  * @param {object} constraints the media constraints to use on createOffer
  */
-PeerConnectionTest.prototype.setOfferConstraints =
-function PCT_setOfferConstraints(constraints) {
+PeerConnectionTest.prototype.setOfferOptions =
+function PCT_setOfferOptions(options) {
   if (this.pcLocal)
-    this.pcLocal.offerConstraints = constraints;
+    this.pcLocal.offerOptions = options;
 };
 
 /**
  * Sets the remote description for the specified peer connection instance
  * and automatically handles the failure case.
  *
  * @param {PeerConnectionWrapper} peer
           The peer connection wrapper to run the command on
@@ -1357,17 +1357,17 @@ DataChannelWrapper.prototype = {
  *        Configuration for the peer connection instance
  */
 function PeerConnectionWrapper(label, configuration, h264) {
   this.configuration = configuration;
   this.label = label;
   this.whenCreated = Date.now();
 
   this.constraints = [ ];
-  this.offerConstraints = {};
+  this.offerOptions = {};
   this.streams = [ ];
   this.mediaCheckers = [ ];
 
   this.dataChannels = [ ];
 
   this.onAddStreamFired = false;
   this.addStreamCallbacks = {};
 
@@ -1632,17 +1632,17 @@ PeerConnectionWrapper.prototype = {
     this._pc.createOffer(function (offer) {
       info("Got offer: " + JSON.stringify(offer));
       self._last_offer = offer;
       if (self.h264) {
         isnot(offer.sdp.search("H264/90000"), -1, "H.264 should be present in the SDP offer");
         offer.sdp = removeVP8(offer.sdp);
       }
       onSuccess(offer);
-    }, generateErrorCallback(), this.offerConstraints);
+    }, generateErrorCallback(), this.offerOptions);
   },
 
   /**
    * Creates an answer and automatically handles the failure case.
    *
    * @param {function} onSuccess
    *        Callback to execute if the answer was created successfully
    */
--- a/dom/media/tests/mochitest/test_dataChannel_noOffer.html
+++ b/dom/media/tests/mochitest/test_dataChannel_noOffer.html
@@ -13,17 +13,17 @@
     bug: "856319",
     title: "Don't offer m=application unless createDataChannel is called first"
   });
 
   runNetworkTest(function () {
     var pc = new mozRTCPeerConnection();
 
     // necessary to circumvent bug 864109
-    var options = { mandatory: { OfferToReceiveAudio: true} };
+    var options = { offerToReceiveAudio: true };
 
     pc.createOffer(function (offer) {
       ok(!offer.sdp.contains("m=application"),
         "m=application is not contained in the SDP");
 
       networkTestFinished();
     }, generateErrorCallback(), options);
   });
--- a/dom/media/tests/mochitest/test_peerConnection_bug834153.html
+++ b/dom/media/tests/mochitest/test_peerConnection_bug834153.html
@@ -36,14 +36,14 @@
         pc1.close();
         pc2.close();
         networkTestFinished();
       }, function (err) {
         croak("createAnswer failed: " + err);
       });
     }, function (err) {
         croak("createOffer failed: " + err);
-    },  { mandatory: { OfferToReceiveAudio: true} });
+    },  { offerToReceiveAudio: true });
   });
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_peerConnection_bug835370.html
+++ b/dom/media/tests/mochitest/test_peerConnection_bug835370.html
@@ -27,34 +27,25 @@
     exception = null;
     try { pconnect.createOffer(step1, failed, 1); } catch (e) { exception = e; }
     ok(exception, "createOffer(step1, failed, 1) throws");
     exception = null;
     try { pconnects.createOffer(step1, failed, {}); } catch (e) { exception = e; }
     ok(!exception, "createOffer(step1, failed, {}) succeeds");
     exception = null;
     try {
-        pconnect.createOffer(step1, failed, { mandatory: { FooBar: true } });
+        pconnect.updateIce();
     } catch (e) {
-        ok(e.message.indexOf("FooBar") > 0, "createOffer has readable exceptions");
+        ok(e.message.indexOf("updateIce") >= 0, "PeerConnection.js has readable exceptions");
         exception = e;
     }
-    ok(exception, "createOffer(step1, failed, { mandatory: { FooBar: true } }) throws");
-    exception = null;
-    try { pconnects.createOffer(step1, failed, { optional: [] }); } catch (e) { exception = e; }
-    ok(!exception, "createOffer(step1, failed, { optional: [] }) succeeds");
+    ok(exception, "updateIce not yet implemented and throws");
     exception = null;
-    try { pconnect.createOffer(step1, failed, { optional: [1] }); } catch (e) { exception = e; }
-    ok(exception, "createOffer(step1, failed, { optional: [1] }) throws");
-    exception = null;
-    try { pconnect.createOffer(step1, failed, { optional: [{ OfferToReceiveVideo: false, OfferToReceiveAudio: true, }] }); } catch (e) { exception = e; }
-    ok(exception, "createOffer(step1, failed, { optional: [{ OfferToReceiveVideo: false, OfferToReceiveAudio: true, }] }) throws");
-    exception = null;
-    try { pconnects.createOffer(step1, failed, { mandatory: { OfferToReceiveVideo: false, OfferToReceiveAudio: true, MozDontOfferDataChannel: true}, optional: [{ VoiceActivityDetection: true }, { FooBar: "42"  }] }); } catch (e) { exception = e; }
-    ok(!exception, "createOffer(step1, failed, { mandatory: { OfferToReceiveVideo: false, OfferToReceiveAudio: true, MozDontOfferDataChannel: true}, optional: [{ VoiceActivityDetection: true }, { FooBar: \"42\"  }] }) succeeds");
+    try { pconnects.createOffer(step1, failed, { offerToReceiveVideo: false, offerToReceiveAudio: true, MozDontOfferDataChannel: true }); } catch (e) { exception = e; }
+    ok(!exception, "createOffer(step1, failed, { offerToReceiveVideo: false, offerToReceiveAudio: true, MozDontOfferDataChannel: true }) succeeds");
     pconnect.close();
     pconnects.close();
     pconnect = null;
     pconnects = null;
     networkTestFinished();
   });
 </script>
 </pre>
--- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html
+++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html
@@ -1,9 +1,9 @@
-<!DOCTYPE HTML>
+<!DOCTYPE HTML>
 <html>
 <head>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="head.js"></script>
   <script type="application/javascript" src="pc.js"></script>
   <script type="application/javascript" src="templates.js"></script>
   <script type="application/javascript" src="turnConfig.js"></script>
@@ -13,15 +13,15 @@
 <script type="application/javascript">
   createHTML({
     bug: "850275",
     title: "Simple offer media constraint test with audio"
   });
 
   runNetworkTest(function() {
     var test = new PeerConnectionTest();
-    test.setOfferConstraints({ mandatory: { OfferToReceiveAudio: true } });
+    test.setOfferOptions({ offerToReceiveAudio: true });
     test.run();
   });
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html
+++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html
@@ -1,9 +1,9 @@
-<!DOCTYPE HTML>
+<!DOCTYPE HTML>
 <html>
 <head>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="head.js"></script>
   <script type="application/javascript" src="pc.js"></script>
   <script type="application/javascript" src="templates.js"></script>
   <script type="application/javascript" src="turnConfig.js"></script>
@@ -13,15 +13,15 @@
 <script type="application/javascript">
   createHTML({
     bug: "850275",
     title: "Simple offer media constraint test with video"
   });
 
   runNetworkTest(function() {
     var test = new PeerConnectionTest();
-    test.setOfferConstraints({ mandatory: { OfferToReceiveVideo: true } });
+    test.setOfferOptions({ offerToReceiveVideo: true });
     test.run();
   });
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html
+++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html
@@ -1,9 +1,9 @@
-<!DOCTYPE HTML>
+<!DOCTYPE HTML>
 <html>
 <head>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript" src="head.js"></script>
   <script type="application/javascript" src="pc.js"></script>
   <script type="application/javascript" src="templates.js"></script>
   <script type="application/javascript" src="turnConfig.js"></script>
@@ -13,18 +13,18 @@
 <script type="application/javascript">
   createHTML({
     bug: "850275",
     title: "Simple offer media constraint test with video/audio"
   });
 
   runNetworkTest(function() {
     var test = new PeerConnectionTest();
-    test.setOfferConstraints({ mandatory: {
-      OfferToReceiveVideo: true,
-      OfferToReceiveAudio: true
-    }});
+    test.setOfferOptions({
+      offerToReceiveVideo: true,
+      offerToReceiveAudio: true
+    });
     test.run();
   });
 </script>
 </pre>
 </body>
 </html>
--- a/dom/webidl/PeerConnectionImpl.webidl
+++ b/dom/webidl/PeerConnectionImpl.webidl
@@ -20,33 +20,32 @@ interface nsISupports;
 interface PeerConnectionImpl  {
   /* Must be called first. Observer events dispatched on the thread provided */
   [Throws]
   void initialize(PeerConnectionObserver observer, Window window,
                   RTCConfiguration iceServers,
                   nsISupports thread);
   /* JSEP calls */
   [Throws]
-  void createOffer(optional MediaConstraintsInternal constraints);
+  void createOffer(optional RTCOfferOptions options);
   [Throws]
-  void createAnswer(optional MediaConstraintsInternal constraints);
+  void createAnswer();
   [Throws]
   void setLocalDescription(long action, DOMString sdp);
   [Throws]
   void setRemoteDescription(long action, DOMString sdp);
 
   /* Stats call, calls either |onGetStatsSuccess| or |onGetStatsError| on our
      observer. (see the |PeerConnectionObserver| interface) */
   [Throws]
   void getStats(MediaStreamTrack? selector);
 
   /* Adds the stream created by GetUserMedia */
   [Throws]
-  void addStream(MediaStream stream,
-                 optional MediaConstraintsInternal constraints);
+  void addStream(MediaStream stream);
   [Throws]
   void removeStream(MediaStream stream);
   [Throws]
   void closeStreams();
 
   sequence<MediaStream> getLocalStreams();
   sequence<MediaStream> getRemoteStreams();
 
--- a/dom/webidl/PeerConnectionObserver.webidl
+++ b/dom/webidl/PeerConnectionObserver.webidl
@@ -34,14 +34,9 @@ interface PeerConnectionObserver
   /* Notification of one of several types of state changed */
   void onStateChange(PCObserverStateType state);
 
   /* Changes to MediaStreams */
   void onAddStream(MediaStream stream);
   void onRemoveStream();
   void onAddTrack();
   void onRemoveTrack();
-
-  /* Helper function to access supported constraints defined in webidl. Needs to
-   * be in a separate webidl object we hold, so putting it here was convenient.
-   */
-  MediaConstraintSet getSupportedConstraints(optional MediaConstraintSet constraints);
 };
--- a/dom/webidl/RTCPeerConnection.webidl
+++ b/dom/webidl/RTCPeerConnection.webidl
@@ -47,89 +47,68 @@ dictionary RTCDataChannelInit {
 
   // these are deprecated due to renaming in the spec, but still supported for Fx22
   boolean outOfOrderAllowed; // now ordered, and the default changes to keep behavior the same
   unsigned short maxRetransmitNum; // now maxRetransmits
   boolean preset; // now negotiated
   unsigned short stream; // now id
 };
 
-// Misnomer dictionaries housing PeerConnection-specific constraints.
-//
-// Important! Do not ever add members that might need tracing (e.g. object)
-// to MediaConstraintSet or any dictionary marked XxxInternal here
-
-dictionary MediaConstraintSet {
-  boolean OfferToReceiveAudio;
-  boolean OfferToReceiveVideo;
+dictionary RTCOfferOptions {
+  long    offerToReceiveVideo;
+  long    offerToReceiveAudio;
   boolean MozDontOfferDataChannel;
   boolean MozBundleOnly;
 };
 
-// MediaConstraint = single-property-subset of MediaConstraintSet
-// Implemented as full set. Test Object.keys(pair).length == 1
-
-// typedef MediaConstraintSet MediaConstraint; // TODO: Bug 913053
-
-dictionary MediaConstraints {
-  object mandatory; // so we can see unknown + unsupported constraints
-  sequence<MediaConstraintSet> _optional; // a.k.a. MediaConstraint
-};
-
-dictionary MediaConstraintsInternal {
-  MediaConstraintSet mandatory; // holds only supported constraints
-  sequence<MediaConstraintSet> _optional; // a.k.a. MediaConstraint
-};
-
 interface RTCDataChannel;
 
 [Pref="media.peerconnection.enabled",
  JSImplementation="@mozilla.org/dom/peerconnection;1",
  Constructor (optional RTCConfiguration configuration,
               optional object? constraints)]
 // moz-prefixed until sufficiently standardized.
 interface mozRTCPeerConnection : EventTarget  {
   [Pref="media.peerconnection.identity.enabled"]
   void setIdentityProvider (DOMString provider,
                             optional DOMString protocol,
                             optional DOMString username);
   [Pref="media.peerconnection.identity.enabled"]
   void getIdentityAssertion();
   void createOffer (RTCSessionDescriptionCallback successCallback,
                     RTCPeerConnectionErrorCallback failureCallback,
-                    optional MediaConstraints constraints);
+                    optional RTCOfferOptions options);
   void createAnswer (RTCSessionDescriptionCallback successCallback,
-                     RTCPeerConnectionErrorCallback failureCallback,
-                     optional MediaConstraints constraints);
+                     RTCPeerConnectionErrorCallback failureCallback);
   void setLocalDescription (mozRTCSessionDescription description,
                             optional VoidFunction successCallback,
                             optional RTCPeerConnectionErrorCallback failureCallback);
   void setRemoteDescription (mozRTCSessionDescription description,
                              optional VoidFunction successCallback,
                              optional RTCPeerConnectionErrorCallback failureCallback);
   readonly attribute mozRTCSessionDescription? localDescription;
   readonly attribute mozRTCSessionDescription? remoteDescription;
   readonly attribute RTCSignalingState signalingState;
-  void updateIce (optional RTCConfiguration configuration,
-                  optional MediaConstraints constraints);
+  void updateIce (optional RTCConfiguration configuration);
   void addIceCandidate (mozRTCIceCandidate candidate,
                         optional VoidFunction successCallback,
                         optional RTCPeerConnectionErrorCallback failureCallback);
   readonly attribute RTCIceGatheringState iceGatheringState;
   readonly attribute RTCIceConnectionState iceConnectionState;
   [Pref="media.peerconnection.identity.enabled"]
   readonly attribute RTCIdentityAssertion? peerIdentity;
 
   [ChromeOnly]
   readonly attribute DOMString id;
 
+  RTCConfiguration      getConfiguration ();
   sequence<MediaStream> getLocalStreams ();
   sequence<MediaStream> getRemoteStreams ();
   MediaStream? getStreamById (DOMString streamId);
-  void addStream (MediaStream stream, optional MediaConstraints constraints);
+  void addStream (MediaStream stream);
   void removeStream (MediaStream stream);
   void close ();
   attribute EventHandler onnegotiationneeded;
   attribute EventHandler onicecandidate;
   attribute EventHandler onsignalingstatechange;
   attribute EventHandler onaddstream;
   attribute EventHandler onremovestream;
   attribute EventHandler oniceconnectionstatechange;
--- a/media/webrtc/signaling/include/CC_Call.h
+++ b/media/webrtc/signaling/include/CC_Call.h
@@ -273,30 +273,29 @@ namespace CSF
            @param [in] video_pref - video direction desired on call
            @param [in] digits - digits to be dialed. can be empty then this API simply goes offhook
            @param [in] ip address - the ip address of the peer to call
 
            @return void
           */
         virtual void originateP2PCall (cc_sdp_direction_t video_pref, const std::string & digits, const std::string & ip) = 0;
 
-        virtual void createOffer (cc_media_constraints_t* constraints, Timecard *) = 0;
+        virtual void createOffer (cc_media_options_t* options, Timecard *) = 0;
 
-        virtual void createAnswer(cc_media_constraints_t* constraints, Timecard *) = 0;
+        virtual void createAnswer(Timecard *) = 0;
 
         virtual void setLocalDescription(cc_jsep_action_t action, const std::string & sdp, Timecard *) = 0;
 
         virtual void setRemoteDescription(cc_jsep_action_t action, const std::string & sdp, Timecard *) = 0;
 
         virtual void setPeerConnection(const std::string& handle) = 0;
 
         virtual void addStream(cc_media_stream_id_t stream_id,
                                cc_media_track_id_t track_id,
-                               cc_media_type_t media_type,
-                               cc_media_constraints_t *constraints) = 0;
+                               cc_media_type_t media_type) = 0;
 
         virtual void removeStream(cc_media_stream_id_t stream_id, cc_media_track_id_t track_id, cc_media_type_t media_type) = 0;
 
         virtual const std::string& getPeerConnection() const = 0;
 
         virtual void addICECandidate(const std::string & candidate, const std::string & mid, unsigned short level, Timecard *) = 0;
 
     };
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.cpp
@@ -51,62 +51,58 @@ extern char ccAppReadyToStart;
 namespace mozilla {
 
 using namespace dom;
 
 // Convert constraints to C structures
 
 #ifdef MOZILLA_INTERNAL_API
 static void
-Apply(const Optional<bool> &aSrc, cc_boolean_constraint_t *aDst,
-      bool mandatory = false) {
-  if (aSrc.WasPassed() && (mandatory || !aDst->was_passed)) {
+Apply(const Optional<bool> &aSrc, cc_boolean_option_t *aDst) {
+  if (aSrc.WasPassed()) {
     aDst->was_passed = true;
     aDst->value = aSrc.Value();
-    aDst->mandatory = mandatory;
+  }
+}
+
+static void
+Apply(const Optional<int32_t> &aSrc, cc_boolean_option_t *aDst) {
+  if (aSrc.WasPassed()) {
+    aDst->was_passed = true;
+    aDst->value = !!aSrc.Value();
   }
 }
 #endif
 
-MediaConstraintsExternal::MediaConstraintsExternal() {
-  memset(&mConstraints, 0, sizeof(mConstraints));
+SipccOfferOptions::SipccOfferOptions() {
+  memset(&mOptions, 0, sizeof(mOptions));
 }
 
-MediaConstraintsExternal::MediaConstraintsExternal(
-    const MediaConstraintsInternal &aSrc) {
-  cc_media_constraints_t* c = &mConstraints;
+SipccOfferOptions::SipccOfferOptions(
+    const RTCOfferOptions &aSrc) {
+  cc_media_options_t* c = &mOptions;
   memset(c, 0, sizeof(*c));
 #ifdef MOZILLA_INTERNAL_API
-  Apply(aSrc.mMandatory.mOfferToReceiveAudio, &c->offer_to_receive_audio, true);
-  Apply(aSrc.mMandatory.mOfferToReceiveVideo, &c->offer_to_receive_video, true);
+  Apply(aSrc.mOfferToReceiveAudio, &c->offer_to_receive_audio);
+  Apply(aSrc.mOfferToReceiveVideo, &c->offer_to_receive_video);
   if (!Preferences::GetBool("media.peerconnection.video.enabled", true)) {
     c->offer_to_receive_video.was_passed = true;
     c->offer_to_receive_video.value = false;
   }
-  Apply(aSrc.mMandatory.mMozDontOfferDataChannel, &c->moz_dont_offer_datachannel,
-        true);
-  Apply(aSrc.mMandatory.mMozBundleOnly, &c->moz_bundle_only, true);
-  if (aSrc.mOptional.WasPassed()) {
-    const Sequence<MediaConstraintSet> &array = aSrc.mOptional.Value();
-    for (uint32_t i = 0; i < array.Length(); i++) {
-      Apply(array[i].mOfferToReceiveAudio, &c->offer_to_receive_audio);
-      Apply(array[i].mOfferToReceiveVideo, &c->offer_to_receive_video);
-      Apply(array[i].mMozDontOfferDataChannel, &c->moz_dont_offer_datachannel);
-      Apply(array[i].mMozBundleOnly, &c->moz_bundle_only);
-    }
-  }
+  Apply(aSrc.mMozDontOfferDataChannel, &c->moz_dont_offer_datachannel);
+  Apply(aSrc.mMozBundleOnly, &c->moz_bundle_only);
 #endif
 }
 
-cc_media_constraints_t*
-MediaConstraintsExternal::build() const {
-  cc_media_constraints_t* cc  = (cc_media_constraints_t*)
-    cpr_malloc(sizeof(cc_media_constraints_t));
+cc_media_options_t*
+SipccOfferOptions::build() const {
+  cc_media_options_t* cc  = (cc_media_options_t*)
+    cpr_malloc(sizeof(cc_media_options_t));
   if (cc) {
-    *cc = mConstraints;
+    *cc = mOptions;
   }
   return cc;
 }
 
 class PeerConnectionCtxShutdown : public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.h
@@ -24,25 +24,25 @@
 
 namespace mozilla {
 class PeerConnectionCtxShutdown;
 
 namespace dom {
 class WebrtcGlobalInformation;
 }
 
-// Unit-test helper, because cc_media_constraints_t is hard to forward-declare
+// Unit-test helper, because cc_media_options_t is hard to forward-declare
 
-class MediaConstraintsExternal {
+class SipccOfferOptions {
 public:
-  MediaConstraintsExternal();
-  MediaConstraintsExternal(const dom::MediaConstraintsInternal &aOther);
-  cc_media_constraints_t* build() const;
+  SipccOfferOptions();
+  SipccOfferOptions(const dom::RTCOfferOptions &aOther);
+  cc_media_options_t* build() const;
 protected:
-  cc_media_constraints_t mConstraints;
+  cc_media_options_t mOptions;
 };
 }
 
 namespace sipcc {
 
 class OnCallEventArgs {
 public:
   OnCallEventArgs(ccapi_call_event_e aCallEvent, CSF::CC_CallInfoPtr aInfo)
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -1078,17 +1078,17 @@ PeerConnectionImpl::CreateDataChannel(co
     nullptr, nullptr, aExternalNegotiated, aStream
   );
   NS_ENSURE_TRUE(dataChannel,NS_ERROR_FAILURE);
 
   CSFLogDebug(logTag, "%s: making DOMDataChannel", __FUNCTION__);
 
   if (!mHaveDataStream) {
     // XXX stream_id of 0 might confuse things...
-    mInternal->mCall->addStream(0, 2, DATA, 0);
+    mInternal->mCall->addStream(0, 2, DATA);
     mHaveDataStream = true;
   }
   nsIDOMDataChannel *retval;
   rv = NS_NewDOMDataChannel(dataChannel.forget(), mWindow, &retval);
   if (NS_FAILED(rv)) {
     return rv;
   }
   *aRetval = static_cast<nsDOMDataChannel*>(retval);
@@ -1165,55 +1165,47 @@ PeerConnectionImpl::NotifyDataChannel(al
                 WrapRunnableNM(NotifyDataChannel_m,
                                domchannel.get(),
                                pco),
                 NS_DISPATCH_NORMAL);
 #endif
 }
 
 NS_IMETHODIMP
-PeerConnectionImpl::CreateOffer(const MediaConstraintsInternal& aConstraints)
+PeerConnectionImpl::CreateOffer(const RTCOfferOptions& aOptions)
 {
-  return CreateOffer(MediaConstraintsExternal (aConstraints));
+  return CreateOffer(SipccOfferOptions(aOptions));
 }
 
 // Used by unit tests and the IDL CreateOffer.
 NS_IMETHODIMP
-PeerConnectionImpl::CreateOffer(const MediaConstraintsExternal& aConstraints)
+PeerConnectionImpl::CreateOffer(const SipccOfferOptions& aOptions)
 {
   PC_AUTO_ENTER_API_CALL(true);
 
   Timecard *tc = mTimeCard;
   mTimeCard = nullptr;
   STAMP_TIMECARD(tc, "Create Offer");
 
-  cc_media_constraints_t* cc_constraints = aConstraints.build();
-  NS_ENSURE_TRUE(cc_constraints, NS_ERROR_UNEXPECTED);
-  mInternal->mCall->createOffer(cc_constraints, tc);
+  cc_media_options_t* cc_options = aOptions.build();
+  NS_ENSURE_TRUE(cc_options, NS_ERROR_UNEXPECTED);
+  mInternal->mCall->createOffer(cc_options, tc);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-PeerConnectionImpl::CreateAnswer(const MediaConstraintsInternal& aConstraints)
-{
-  return CreateAnswer(MediaConstraintsExternal (aConstraints));
-}
-
-NS_IMETHODIMP
-PeerConnectionImpl::CreateAnswer(const MediaConstraintsExternal& aConstraints)
+PeerConnectionImpl::CreateAnswer()
 {
   PC_AUTO_ENTER_API_CALL(true);
 
   Timecard *tc = mTimeCard;
   mTimeCard = nullptr;
   STAMP_TIMECARD(tc, "Create Answer");
 
-  cc_media_constraints_t* cc_constraints = aConstraints.build();
-  NS_ENSURE_TRUE(cc_constraints, NS_ERROR_UNEXPECTED);
-  mInternal->mCall->createAnswer(cc_constraints, tc);
+  mInternal->mCall->createAnswer(tc);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PeerConnectionImpl::SetLocalDescription(int32_t aAction, const char* aSDP)
 {
   PC_AUTO_ENTER_API_CALL(true);
 
@@ -1421,25 +1413,17 @@ PeerConnectionImpl::PrincipalChanged(DOM
     mMedia->UpdateSinkIdentity_m(doc->NodePrincipal(), mPeerIdentity);
   } else {
     CSFLogInfo(logTag, "Can't update sink principal; document gone");
   }
 }
 #endif
 
 nsresult
-PeerConnectionImpl::AddStream(DOMMediaStream &aMediaStream,
-                              const MediaConstraintsInternal& aConstraints)
-{
-  return AddStream(aMediaStream, MediaConstraintsExternal(aConstraints));
-}
-
-nsresult
-PeerConnectionImpl::AddStream(DOMMediaStream &aMediaStream,
-                              const MediaConstraintsExternal& aConstraints)
+PeerConnectionImpl::AddStream(DOMMediaStream &aMediaStream)
 {
   PC_AUTO_ENTER_API_CALL(true);
 
   uint32_t hints = aMediaStream.GetHintContents();
 
   // XXX Remove this check once addStream has an error callback
   // available and/or we have plumbing to handle multiple
   // local audio streams.
@@ -1465,26 +1449,22 @@ PeerConnectionImpl::AddStream(DOMMediaSt
   if (NS_FAILED(res)) {
     return res;
   }
 
   aMediaStream.AddPrincipalChangeObserver(this);
 
   // TODO(ekr@rtfm.com): these integers should be the track IDs
   if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
-    cc_media_constraints_t* cc_constraints = aConstraints.build();
-    NS_ENSURE_TRUE(cc_constraints, NS_ERROR_UNEXPECTED);
-    mInternal->mCall->addStream(stream_id, 0, AUDIO, cc_constraints);
+    mInternal->mCall->addStream(stream_id, 0, AUDIO);
     mNumAudioStreams++;
   }
 
   if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
-    cc_media_constraints_t* cc_constraints = aConstraints.build();
-    NS_ENSURE_TRUE(cc_constraints, NS_ERROR_UNEXPECTED);
-    mInternal->mCall->addStream(stream_id, 1, VIDEO, cc_constraints);
+    mInternal->mCall->addStream(stream_id, 1, VIDEO);
     mNumVideoStreams++;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PeerConnectionImpl::RemoveStream(DOMMediaStream& aMediaStream) {
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -68,28 +68,28 @@ class MediaPipeline;
 #ifdef USE_FAKE_MEDIA_STREAMS
 typedef Fake_DOMMediaStream DOMMediaStream;
 #else
 class DOMMediaStream;
 #endif
 
 namespace dom {
 struct RTCConfiguration;
-struct MediaConstraintsInternal;
+struct RTCOfferOptions;
 class MediaStreamTrack;
 
 #ifdef USE_FAKE_PCOBSERVER
 typedef test::AFakePCObserver PeerConnectionObserver;
 typedef const char *PCObserverString;
 #else
 class PeerConnectionObserver;
 typedef NS_ConvertUTF8toUTF16 PCObserverString;
 #endif
 }
-class MediaConstraintsExternal;
+class SipccOfferOptions;
 }
 
 #if defined(__cplusplus) && __cplusplus >= 201103L
 typedef struct Timecard Timecard;
 #else
 #include "timecard.h"
 #endif
 
@@ -103,18 +103,17 @@ void func (__VA_ARGS__, rv)
 #define NS_IMETHODIMP_TO_ERRORRESULT_RETREF(resulttype, func, rv, ...) \
 NS_IMETHODIMP func(__VA_ARGS__, resulttype **result);                  \
 already_AddRefed<resulttype> func (__VA_ARGS__, rv)
 
 namespace sipcc {
 
 using mozilla::dom::PeerConnectionObserver;
 using mozilla::dom::RTCConfiguration;
-using mozilla::dom::MediaConstraintsInternal;
-using mozilla::MediaConstraintsExternal;
+using mozilla::dom::RTCOfferOptions;
 using mozilla::DOMMediaStream;
 using mozilla::NrIceCtx;
 using mozilla::NrIceMediaStream;
 using mozilla::DtlsIdentity;
 using mozilla::ErrorResult;
 using mozilla::NrIceStunServer;
 using mozilla::NrIceTurnServer;
 #ifdef MOZILLA_INTERNAL_API
@@ -209,23 +208,21 @@ class PeerConnectionImpl MOZ_FINAL : pub
 {
   struct Internal; // Avoid exposing c includes to bindings
 
 public:
   PeerConnectionImpl(const mozilla::dom::GlobalObject* aGlobal = nullptr);
 
   enum Error {
     kNoError                          = 0,
-    kInvalidConstraintsType           = 1,
     kInvalidCandidateType             = 2,
     kInvalidMediastreamTrack          = 3,
     kInvalidState                     = 4,
     kInvalidSessionDescription        = 5,
     kIncompatibleSessionDescription   = 6,
-    kIncompatibleConstraints          = 7,
     kIncompatibleMediaStreamTrack     = 8,
     kInternalError                    = 9
   };
 
   NS_DECL_THREADSAFE_ISUPPORTS
 
 #ifdef MOZILLA_INTERNAL_API
   virtual JSObject* WrapObject(JSContext* cx);
@@ -311,29 +308,28 @@ public:
   {
     nsresult r = Initialize(aObserver, &aWindow, nullptr, &aConfiguration, aThread);
     if (NS_FAILED(r)) {
       rv.Throw(r);
     }
   }
 
   NS_IMETHODIMP_TO_ERRORRESULT(CreateOffer, ErrorResult &rv,
-                               const MediaConstraintsInternal& aConstraints)
+                               const RTCOfferOptions& aOptions)
   {
-    rv = CreateOffer(aConstraints);
+    rv = CreateOffer(aOptions);
   }
 
-  NS_IMETHODIMP_TO_ERRORRESULT(CreateAnswer, ErrorResult &rv,
-                               const MediaConstraintsInternal& aConstraints)
+  NS_IMETHODIMP CreateAnswer();
+  void CreateAnswer(ErrorResult &rv)
   {
-    rv = CreateAnswer(aConstraints);
+    rv = CreateAnswer();
   }
 
-  NS_IMETHODIMP CreateOffer(const MediaConstraintsExternal& aConstraints);
-  NS_IMETHODIMP CreateAnswer(const MediaConstraintsExternal& aConstraints);
+  NS_IMETHODIMP CreateOffer(const mozilla::SipccOfferOptions& aConstraints);
 
   NS_IMETHODIMP SetLocalDescription (int32_t aAction, const char* aSDP);
 
   void SetLocalDescription (int32_t aAction, const nsAString& aSDP, ErrorResult &rv)
   {
     rv = SetLocalDescription(aAction, NS_ConvertUTF16toUTF8(aSDP).get());
   }
 
@@ -363,25 +359,21 @@ public:
   NS_IMETHODIMP CloseStreams();
 
   void CloseStreams(ErrorResult &rv)
   {
     rv = CloseStreams();
   }
 
   NS_IMETHODIMP_TO_ERRORRESULT(AddStream, ErrorResult &rv,
-                               DOMMediaStream& aMediaStream,
-                               const MediaConstraintsInternal& aConstraints)
+                               DOMMediaStream& aMediaStream)
   {
-    rv = AddStream(aMediaStream, aConstraints);
+    rv = AddStream(aMediaStream);
   }
 
-  nsresult AddStream(DOMMediaStream &aMediaStream,
-                     const MediaConstraintsExternal& aConstraints);
-
   NS_IMETHODIMP_TO_ERRORRESULT(RemoveStream, ErrorResult &rv,
                                DOMMediaStream& aMediaStream)
   {
     rv = RemoveStream(aMediaStream);
   }
 
 
   nsresult GetPeerIdentity(nsAString& peerIdentity)
@@ -664,17 +656,17 @@ private:
   // DTLS fingerprint
   std::string mFingerprint;
   std::string mRemoteFingerprint;
 
   // identity-related fields
   mozilla::RefPtr<DtlsIdentity> mIdentity;
 #ifdef MOZILLA_INTERNAL_API
   // The entity on the other end of the peer-to-peer connection;
-  // void if they are not yet identified, and no constraint has been set
+  // void if they are not yet identified, and no identity setting has been set
   nsAutoPtr<PeerIdentity> mPeerIdentity;
 #endif
   // Whether an app should be prevented from accessing media produced by the PC
   // If this is true, then media will not be sent until mPeerIdentity matches
   // local streams PeerIdentity; and remote streams are protected from content
   //
   // This can be false if mPeerIdentity is set, in the case where identity is
   // provided, but the media is not protected from the app on either side
--- a/media/webrtc/signaling/src/sipcc/core/ccapp/CCProvider.h
+++ b/media/webrtc/signaling/src/sipcc/core/ccapp/CCProvider.h
@@ -101,17 +101,17 @@ typedef struct cc_call_info_t_{
     cc_string_t   info_body;
     cc_call_log_t call_log;
     cc_boolean    audio_mute;
     cc_boolean    video_mute;
     cc_call_conference_Info_t call_conference;
     cc_string_t   sdp;
     unsigned int  media_stream_track_id;
     unsigned int  media_stream_id;
-    cc_media_constraints_t* cc_constraints;
+    cc_media_options_t* cc_options;
     string_t      candidate;
     Timecard *    timecard;
 } session_data_t;
 
 typedef enum {
     NO_ACTION=0,
     RESET_ACTION,
     RESTART_ACTION,
--- a/media/webrtc/signaling/src/sipcc/core/ccapp/cc_call_feature.c
+++ b/media/webrtc/signaling/src/sipcc/core/ccapp/cc_call_feature.c
@@ -100,30 +100,30 @@ cc_return_t cc_invokeFeature(cc_call_han
  */
 cc_return_t cc_invokeFeatureSDPMode(cc_call_handle_t call_handle,
                                     group_cc_feature_t featureId,
                                     cc_jsep_action_t action,
                                     cc_media_stream_id_t stream_id,
                                     cc_media_track_id_t track_id,
                                     cc_media_type_t media_type,
                                     uint16_t level,
-                                    cc_media_constraints_t *constraints,
+                                    cc_media_options_t *options,
                                     string_t data,
                                     string_t data1,
                                     Timecard *tc) {
     session_feature_t callFeature;
     unsigned int session_id = 0;
     callFeature.session_id = (SESSIONTYPE_CALLCONTROL << CC_SID_TYPE_SHIFT) + call_handle;
     callFeature.featureID = featureId;
     callFeature.featData.ccData.action = action;
     callFeature.featData.ccData.media_type = media_type;
     callFeature.featData.ccData.stream_id = stream_id;
     callFeature.featData.ccData.track_id = track_id;
     callFeature.featData.ccData.level = level;
-    callFeature.featData.ccData.constraints = constraints;
+    callFeature.featData.ccData.options = options;
     callFeature.featData.ccData.timecard = tc;
 
     CCAPP_DEBUG(DEB_F_PREFIX"cc_invokeFeatureSDPMode:sid=%d, line=%d, cid=%d, fid=%d, data=%s",
                         DEB_F_PREFIX_ARGS("cc_call_feature", "cc_invokeFeatureSDPMode"),
                         callFeature.session_id,
                         GET_LINE_ID(call_handle),
                         GET_CALL_ID(call_handle),
                         featureId,
@@ -287,115 +287,107 @@ cc_return_t CC_CallFeature_dial(cc_call_
     if (cpr_strcasecmp(numbers, "DIAL") == 0) {
 	    return cc_invokeFeature(call_handle, CC_FEATURE_DIAL, video_pref, numbers);
     }
 
 	return cc_invokeFeature(call_handle, CC_FEATURE_DIALSTR, video_pref, numbers);
 }
 
 cc_return_t CC_CallFeature_CreateOffer(cc_call_handle_t call_handle,
-                                       cc_media_constraints_t *constraints,
+                                       cc_media_options_t *options,
                                        Timecard *tc) {
     CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle),
                 GET_LINE_ID(call_handle), __FUNCTION__));
 
     return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_CREATEOFFER, JSEP_NO_ACTION,
-                                   0, 0, NO_STREAM, 0, constraints, NULL, NULL, tc);
+                                   0, 0, NO_STREAM, 0, options, NULL, NULL, tc);
 }
 
 cc_return_t CC_CallFeature_CreateAnswer(cc_call_handle_t call_handle,
-                                        cc_media_constraints_t *constraints,
                                         Timecard *tc) {
     CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle),
                 GET_LINE_ID(call_handle), __FUNCTION__));
 
     return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_CREATEANSWER, JSEP_NO_ACTION,
-                                   0, 0, NO_STREAM, 0, constraints, NULL, NULL, tc);
+                                   0, 0, NO_STREAM, 0, NULL, NULL, NULL, tc);
 }
 
 cc_return_t CC_CallFeature_SetLocalDescription(cc_call_handle_t call_handle,
                                                cc_jsep_action_t action,
                                                string_t sdp,
                                                Timecard *tc) {
-    cc_media_constraints_t *constraints = NULL;
     CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle),
             GET_LINE_ID(call_handle), __FUNCTION__));
 
     return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_SETLOCALDESC, action,
-                                   0, 0, NO_STREAM, 0, constraints, sdp, NULL, tc);
+                                   0, 0, NO_STREAM, 0, NULL, sdp, NULL, tc);
 }
 
 cc_return_t CC_CallFeature_SetRemoteDescription(cc_call_handle_t call_handle,
                                                 cc_jsep_action_t action,
                                                 string_t sdp,
                                                 Timecard *tc) {
-    cc_media_constraints_t *constraints = NULL;
     CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle),
             GET_LINE_ID(call_handle), __FUNCTION__));
 
     return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_SETREMOTEDESC, action,
-                                   0, 0, NO_STREAM, 0, constraints, sdp, NULL, tc);
+                                   0, 0, NO_STREAM, 0, NULL, sdp, NULL, tc);
 }
 
 cc_return_t CC_CallFeature_SetPeerConnection(cc_call_handle_t call_handle,cc_peerconnection_t pc) {
-    cc_media_constraints_t *constraints = NULL;
     CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle),
                 GET_LINE_ID(call_handle), __FUNCTION__));
 
     return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_SETPEERCONNECTION, JSEP_NO_ACTION,
-                                   0, 0, NO_STREAM, 0, constraints, pc, NULL, NULL);
+                                   0, 0, NO_STREAM, 0, NULL, pc, NULL, NULL);
 }
 
 cc_return_t CC_CallFeature_AddStream(cc_call_handle_t call_handle,
                                      cc_media_stream_id_t stream_id,
                                      cc_media_track_id_t track_id,
-                                     cc_media_type_t media_type,
-                                     cc_media_constraints_t *constraints) {
+                                     cc_media_type_t media_type) {
     CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle),
             GET_LINE_ID(call_handle), __FUNCTION__));
 
     return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_ADDSTREAM, JSEP_NO_ACTION,
-                                   stream_id, track_id, media_type, 0, constraints, NULL, NULL, NULL);
+                                   stream_id, track_id, media_type, 0, NULL, NULL, NULL, NULL);
 }
 
 cc_return_t CC_CallFeature_RemoveStream(cc_call_handle_t call_handle, cc_media_stream_id_t stream_id,
                                                cc_media_track_id_t track_id, cc_media_type_t media_type) {
 
-    cc_media_constraints_t *constraints = NULL;
     CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle),
                 GET_LINE_ID(call_handle), __FUNCTION__));
 
     return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_REMOVESTREAM, JSEP_NO_ACTION,
-                                   stream_id, track_id, media_type, 0, constraints, NULL, NULL, NULL);
+                                   stream_id, track_id, media_type, 0, NULL, NULL, NULL, NULL);
 }
 
 cc_return_t CC_CallFeature_AddICECandidate(cc_call_handle_t call_handle,
                                            const char* candidate,
                                            const char *mid,
                                            cc_level_t level,
                                            Timecard *tc) {
-    cc_media_constraints_t *constraints = NULL;
     CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle),
             GET_LINE_ID(call_handle), __FUNCTION__));
 
     return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_ADDICECANDIDATE, JSEP_NO_ACTION,
-                                   0, 0, NO_STREAM, (uint16_t)level, constraints, candidate, mid, tc);
+                                   0, 0, NO_STREAM, (uint16_t)level, NULL, candidate, mid, tc);
 }
 
 cc_return_t CC_CallFeature_FoundICECandidate(cc_call_handle_t call_handle,
 					     const char* candidate,
 					     const char *mid,
 					     cc_level_t level,
 					     Timecard *tc) {
-    cc_media_constraints_t *constraints = NULL;
     CCAPP_DEBUG(DEB_L_C_F_PREFIX, DEB_L_C_F_PREFIX_ARGS(SIP_CC_PROV, GET_CALL_ID(call_handle),
             GET_LINE_ID(call_handle), __FUNCTION__));
 
     return cc_invokeFeatureSDPMode(call_handle, CC_FEATURE_FOUNDICECANDIDATE, JSEP_NO_ACTION,
-                                   0, 0, NO_STREAM, (uint16_t)level, constraints, candidate, mid, tc);
+                                   0, 0, NO_STREAM, (uint16_t)level, NULL, candidate, mid, tc);
 }
 
 /**
  * Initiate a speed dial.
  * @param call handle
  * @param callid call id
  * @param speed dial numbers.
  * @return SUCCESS or FAILURE
--- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_call.c
+++ b/media/webrtc/signaling/src/sipcc/core/ccapp/ccapi_call.c
@@ -87,25 +87,24 @@ cc_lineid_t CCAPI_Call_getLine(cc_call_h
  * @param [in] digits - digits to be dialed
  * @return SUCCESS or FAILURE
  */
 cc_return_t CCAPI_Call_originateCall(cc_call_handle_t handle, cc_sdp_direction_t video_pref, cc_string_t digits){
 	return CC_CallFeature_dial(handle, video_pref, digits);
 }
 
 cc_return_t CCAPI_CreateOffer(cc_call_handle_t handle,
-                              cc_media_constraints_t *constraints,
+                              cc_media_options_t *options,
                               Timecard *tc) {
-    return CC_CallFeature_CreateOffer(handle, constraints, tc);
+    return CC_CallFeature_CreateOffer(handle, options, tc);
 }
 
 cc_return_t CCAPI_CreateAnswer(cc_call_handle_t handle,
-                               cc_media_constraints_t *constraints,
                                Timecard *tc) {
-    return CC_CallFeature_CreateAnswer(handle, constraints, tc);
+    return CC_CallFeature_CreateAnswer(handle, tc);
 }
 
 cc_return_t CCAPI_SetLocalDescription(cc_call_handle_t handle,
                                       cc_jsep_action_t action,
                                       cc_string_t sdp,
                                       Timecard *tc) {
     return CC_CallFeature_SetLocalDescription(handle, action, sdp, tc);
 }
@@ -119,20 +118,18 @@ cc_return_t CCAPI_SetRemoteDescription(c
 
 cc_return_t CCAPI_SetPeerConnection(cc_call_handle_t handle, cc_peerconnection_t pc) {
   return CC_CallFeature_SetPeerConnection(handle, pc);
 }
 
 cc_return_t CCAPI_AddStream(cc_call_handle_t handle,
                             cc_media_stream_id_t stream_id,
                             cc_media_track_id_t track_id,
-                            cc_media_type_t media_type,
-                            cc_media_constraints_t *constraints) {
-  return CC_CallFeature_AddStream(handle, stream_id, track_id, media_type,
-                                  constraints);
+                            cc_media_type_t media_type) {
+  return CC_CallFeature_AddStream(handle, stream_id, track_id, media_type);
 }
 
 cc_return_t CCAPI_RemoveStream(cc_call_handle_t handle, cc_media_stream_id_t stream_id, cc_media_track_id_t track_id, cc_media_type_t media_type) {
   return CC_CallFeature_RemoveStream(handle, stream_id, track_id, media_type);
 }
 
 cc_return_t CCAPI_AddICECandidate(cc_call_handle_t handle,
                                   cc_string_t candidate,
--- a/media/webrtc/signaling/src/sipcc/core/ccapp/ccprovider.c
+++ b/media/webrtc/signaling/src/sipcc/core/ccapp/ccprovider.c
@@ -659,22 +659,22 @@ processSessionEvent (line_t line_id, cal
          case CC_FEATURE_KEYPRESS:
              dp_int_update_keypress(line_id, call_id, (unsigned char)*data);
              break;
          case CC_FEATURE_BKSPACE:
              dp_int_update_keypress(line_id, call_id, BKSP_KEY);
              break;
          case CC_FEATURE_CREATEOFFER:
              STAMP_TIMECARD(timecard, "Processing create offer event");
-             featdata.session.constraints = ccData.constraints;
+             featdata.session.options = ccData.options;
              cc_createoffer (CC_SRC_UI, CC_SRC_GSM, call_id, (line_t)instance, CC_FEATURE_CREATEOFFER, &featdata, timecard);
              break;
          case CC_FEATURE_CREATEANSWER:
              STAMP_TIMECARD(timecard, "Processing create answer event");
-             featdata.session.constraints = ccData.constraints;
+             featdata.session.options = ccData.options;
              cc_createanswer (CC_SRC_UI, CC_SRC_GSM, call_id, (line_t)instance, CC_FEATURE_CREATEANSWER, data, &featdata, timecard);
              break;
          case CC_FEATURE_SETLOCALDESC:
              STAMP_TIMECARD(timecard, "Processing set local event");
              cc_setlocaldesc (CC_SRC_UI, CC_SRC_GSM, call_id, (line_t)instance, CC_FEATURE_SETLOCALDESC, ccData.action, data, &featdata, timecard);
              break;
          case CC_FEATURE_SETREMOTEDESC:
              STAMP_TIMECARD(timecard, "Processing set remote event");
@@ -690,17 +690,16 @@ processSessionEvent (line_t line_id, cal
            cc_int_feature2(CC_MSG_SETPEERCONNECTION, CC_SRC_UI, CC_SRC_GSM,
              call_id, (line_t)instance,
              CC_FEATURE_SETPEERCONNECTION, &featdata, NULL);
            break;
          case CC_FEATURE_ADDSTREAM:
            featdata.track.stream_id = ccData.stream_id;
            featdata.track.track_id = ccData.track_id;
            featdata.track.media_type = ccData.media_type;
-           featdata.track.constraints = ccData.constraints;
            cc_int_feature2(CC_MSG_ADDSTREAM, CC_SRC_UI, CC_SRC_GSM, call_id, (line_t)instance, CC_FEATURE_ADDSTREAM, &featdata, timecard);
            break;
          case CC_FEATURE_REMOVESTREAM:
            featdata.track.stream_id = ccData.stream_id;
            featdata.track.track_id = ccData.track_id;
            featdata.track.media_type = ccData.media_type;
            cc_int_feature2(CC_MSG_REMOVESTREAM, CC_SRC_UI, CC_SRC_GSM, call_id, (line_t)instance, CC_FEATURE_REMOVESTREAM, &featdata, timecard);
            break;
--- a/media/webrtc/signaling/src/sipcc/core/gsm/fsmdef.c
+++ b/media/webrtc/signaling/src/sipcc/core/gsm/fsmdef.c
@@ -1095,27 +1095,27 @@ fsmdef_set_per_media_local_hold_sdp (fsm
         if (FSM_CHK_FLAGS(media->hold, FSM_HOLD_LCL)) {
             /* set local hold to this media entry */
             gsmsdp_set_local_hold_sdp(dcb, media);
         }
     }
 }
 
 /**
- * This function deallocates a constraints structure
- *
- * @param[in]constraints - pointer to cc_media_constraints_t
+ * This function deallocates an options structure
+ *
+ * @param[in]options - pointer to cc_media_options_t
  * @return None
  */
 void
-fsmdef_free_constraints(cc_media_constraints_t *constraints) {
-    if (!constraints) {
+fsmdef_free_options(cc_media_options_t *options) {
+    if (!options) {
        return;
     }
-    cpr_free(constraints);
+    cpr_free(options);
 }
 
 void
 fsmdef_init_dcb (fsmdef_dcb_t *dcb, callid_t call_id,
                  fsmdef_call_types_t call_type,
                  string_t called_number, line_t line, fsm_fcb_t *fcb)
 {
     string_t calling_name;
@@ -3200,20 +3200,20 @@ fsmdef_ev_createoffer (sm_event_t *event
         return (SM_RC_END);
     }
 
     /* clean candidate list, since we are about to return the candidates */
     gsmsdp_clean_candidate_list(dcb);
 
     dcb->inbound = FALSE;
 
-    if (msg->data.session.constraints) {
-       gsmsdp_process_cap_constraints(dcb, msg->data.session.constraints);
-       fsmdef_free_constraints(msg->data.session.constraints);
-       msg->data.session.constraints = 0;
+    if (msg->data.session.options) {
+       gsmsdp_process_cap_options(dcb, msg->data.session.options);
+       fsmdef_free_options(msg->data.session.options);
+       msg->data.session.options = 0;
     }
 
     if (dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled ||
         dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled ||
         dcb->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled) {
       has_stream = TRUE;
     }
 
@@ -3364,22 +3364,16 @@ fsmdef_ev_createanswer (sm_event_t *even
         return (SM_RC_END);
     }
 
     /* clean candidate list, since we are about to return the candidates */
     gsmsdp_clean_candidate_list(dcb);
 
     dcb->inbound = TRUE;
 
-    if (msg->data.session.constraints) {
-       gsmsdp_process_cap_constraints(dcb, msg->data.session.constraints);
-       fsmdef_free_constraints(msg->data.session.constraints);
-       msg->data.session.constraints = 0;
-    }
-
     vcm_res = vcmGetIceParams(dcb->peerconnection, &ufrag, &ice_pwd);
     if (vcm_res) {
     	FSM_DEBUG_SM(DEB_F_PREFIX"vcmGetIceParams returned an error",
             DEB_F_PREFIX_ARGS(FSM, __FUNCTION__));
       ui_create_answer(evCreateAnswerError, fcb->state, line, call_id,
           dcb->caller_id.call_instance_id, strlib_empty(),
           msg->timecard,
           PC_INTERNAL_ERROR, "Could not get ICE parameters for answer");
@@ -4018,30 +4012,17 @@ fsmdef_ev_addstream(sm_event_t *event) {
             break;
     }
 
     if (cap_index != CC_INVALID_INDEX) {
         dcb->media_cap_tbl->cap[cap_index].enabled = TRUE;
         dcb->media_cap_tbl->cap[cap_index].support_direction = SDP_DIRECTION_SENDRECV;
         dcb->media_cap_tbl->cap[cap_index].pc_stream = msg->data.track.stream_id;
         dcb->media_cap_tbl->cap[cap_index].pc_track = msg->data.track.track_id;
-
-        if (msg->data.track.constraints &&
-            msg->data.track.constraints->moz_bundle_only.was_passed) {
-          dcb->media_cap_tbl->cap[cap_index].bundle_only =
-            msg->data.track.constraints->moz_bundle_only.value;
-        }
-    }
-
-    /* Free the constraints structure */
-    if (msg->data.track.constraints) {
-       fsmdef_free_constraints(msg->data.track.constraints);
-       msg->data.track.constraints = 0;
-    }
-
+    }
     return (SM_RC_END);
 }
 
 static sm_rcs_t
 fsmdef_ev_removestream(sm_event_t *event) {
     fsm_fcb_t           *fcb = (fsm_fcb_t *) event->data;
     fsmdef_dcb_t        *dcb = fcb->dcb;
     cc_causes_t         cause = CC_CAUSE_NORMAL;
--- a/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c
+++ b/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c
@@ -221,32 +221,32 @@ void gsmsdp_process_cap_constraint(cc_me
     cap->support_direction &= ~SDP_DIRECTION_FLAG_RECV;
   } else {
     cap->support_direction |= SDP_DIRECTION_FLAG_RECV;
     cap->enabled = TRUE;
   }
 }
 
 /*
- * Process constraints only related to media capabilities., i.e
+ * Process options only related to media capabilities., i.e
  * OfferToReceiveAudio, OfferToReceiveVideo
  */
-void gsmsdp_process_cap_constraints(fsmdef_dcb_t *dcb,
-                                    cc_media_constraints_t* constraints) {
-  if (constraints->offer_to_receive_audio.was_passed) {
+void gsmsdp_process_cap_options(fsmdef_dcb_t *dcb,
+                                    cc_media_options_t* options) {
+  if (options->offer_to_receive_audio.was_passed) {
     gsmsdp_process_cap_constraint(&dcb->media_cap_tbl->cap[CC_AUDIO_1],
-                                  constraints->offer_to_receive_audio.value);
+                                  options->offer_to_receive_audio.value);
   }
-  if (constraints->offer_to_receive_video.was_passed) {
+  if (options->offer_to_receive_video.was_passed) {
     gsmsdp_process_cap_constraint(&dcb->media_cap_tbl->cap[CC_VIDEO_1],
-                                  constraints->offer_to_receive_video.value);
+                                  options->offer_to_receive_video.value);
   }
-  if (constraints->moz_dont_offer_datachannel.was_passed) {
+  if (options->moz_dont_offer_datachannel.was_passed) {
     /* Hack to suppress data channel */
-    if (constraints->moz_dont_offer_datachannel.value) {
+    if (options->moz_dont_offer_datachannel.value) {
       dcb->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled = FALSE;
     }
   }
 }
 
 /**
  * Copy an fsmdef_media_t's payload list to its previous_sdp's payload list
  *
--- a/media/webrtc/signaling/src/sipcc/core/gsm/h/gsm_sdp.h
+++ b/media/webrtc/signaling/src/sipcc/core/gsm/h/gsm_sdp.h
@@ -114,18 +114,17 @@ extern boolean gsmsdp_handle_media_cap_c
 extern boolean gsmsdp_update_local_sdp_media_capability(fsmdef_dcb_t *dcb_p,
                                               boolean refresh, boolean hold);
 boolean is_gsmsdp_media_ip_updated_to_latest( fsmdef_dcb_t * dcb );
 
 cc_causes_t gsmsdp_check_ice_attributes_exist(fsm_fcb_t *fcb_p);
 cc_causes_t gsmsdp_install_peer_ice_attributes(fsm_fcb_t *fcb_p);
 cc_causes_t gsmsdp_configure_dtls_data_attributes(fsm_fcb_t *fcb_p);
 cc_causes_t gsmsdp_find_level_from_mid(fsmdef_dcb_t * dcb, const char * mid, uint16_t *level);
-void gsmsdp_process_cap_constraints(fsmdef_dcb_t *dcb,
-                                    cc_media_constraints_t* constraints);
+void gsmsdp_process_cap_options(fsmdef_dcb_t *dcb, cc_media_options_t* options);
 cc_causes_t
 gsmsdp_get_offered_media_types (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean *has_audio, boolean *has_video, boolean *has_data);
 fsmdef_media_t* gsmsdp_find_media_by_media_type(fsmdef_dcb_t *dcb, sdp_media_e 	media_type);
 
 extern void gsmsdp_set_ice_attribute (sdp_attr_e sdp_attr, uint16_t level,
                                       void *sdp_p, char *ice_attrib);
 extern void gsmsdp_clean_candidate_list(fsmdef_dcb_t *dcb);
 
--- a/media/webrtc/signaling/src/sipcc/core/includes/ccapi.h
+++ b/media/webrtc/signaling/src/sipcc/core/includes/ccapi.h
@@ -829,28 +829,27 @@ typedef struct cc_feature_data_cancel_t_
 typedef struct cc_feature_data_pc_t_ {
   char pc_handle[PC_HANDLE_SIZE];
 } cc_feature_data_pc_t;
 
 typedef struct cc_feature_data_track_t_ {
   cc_media_stream_id_t     stream_id;
   cc_media_track_id_t      track_id;
   cc_media_type_t          media_type;
-  cc_media_constraints_t  *constraints;
 } cc_feature_data_track_t;
 
 
 typedef struct cc_feature_candidate_t_ {
   uint16_t    level;
   char        candidate[CANDIDATE_SIZE];
   char        mid[MID_SIZE];
 } cc_feature_candidate_t;
 
 typedef struct cc_feature_session_t_ {
-  cc_media_constraints_t    *constraints;
+  cc_media_options_t *options;
 } cc_feature_session_t;
 
 
 typedef union cc_feature_data_t {
     cc_feature_data_newcall_t   newcall;
     cc_feature_data_xfer_t      xfer;
     cc_feature_data_ind_t       indication;
     cc_feature_data_endcall_t   endcall;
--- a/media/webrtc/signaling/src/sipcc/core/includes/sessionTypes.h
+++ b/media/webrtc/signaling/src/sipcc/core/includes/sessionTypes.h
@@ -48,17 +48,17 @@ typedef struct {
   string_t                  info;
   string_t                  info1;
   unsigned int              state;
   cc_jsep_action_t          action;
   cc_media_stream_id_t      stream_id;
   cc_media_track_id_t       track_id;
   cc_media_type_t           media_type;
   cc_level_t                level;
-  cc_media_constraints_t *  constraints;
+  cc_media_options_t *      options;
   Timecard *                timecard;
 } ccSession_feature_t;
 
 typedef struct {
   int          state;
   int          fsm_state;
   int          attr;
   int          inst;
--- a/media/webrtc/signaling/src/sipcc/include/cc_call_feature.h
+++ b/media/webrtc/signaling/src/sipcc/include/cc_call_feature.h
@@ -153,21 +153,20 @@ cc_return_t CC_CallFeature_backSpace(cc_
  * @param call_handle call handle
  * @param video_pref the sdp direction
  * @param numbers dialed string
  * @return SUCCESS or FAILURE
  */
 cc_return_t CC_CallFeature_dial(cc_call_handle_t call_handle, cc_sdp_direction_t video_pref, const cc_string_t numbers);
 
 cc_return_t CC_CallFeature_CreateOffer(cc_call_handle_t call_handle,
-                                       cc_media_constraints_t *constraints,
+                                       cc_media_options_t *options,
                                        Timecard *tc);
 
 cc_return_t CC_CallFeature_CreateAnswer(cc_call_handle_t call_handle,
-                                        cc_media_constraints_t *constraints,
                                         Timecard *tc);
 
 cc_return_t CC_CallFeature_SetLocalDescription(cc_call_handle_t call_handle,
                                                cc_jsep_action_t action,
                                                const char* sdp,
                                                Timecard *tc);
 
 cc_return_t CC_CallFeature_SetRemoteDescription(cc_call_handle_t call_handle,
@@ -175,18 +174,17 @@ cc_return_t CC_CallFeature_SetRemoteDesc
                                                 const char* sdp,
                                                 Timecard *tc);
 
 cc_return_t CC_CallFeature_SetPeerConnection(cc_call_handle_t call_handle, cc_peerconnection_t pc);
 
 cc_return_t CC_CallFeature_AddStream(cc_call_handle_t call_handle,
                                      cc_media_stream_id_t stream_id,
                                      cc_media_track_id_t id,
-                                     cc_media_type_t media_type,
-                                     cc_media_constraints_t *constraints);
+                                     cc_media_type_t media_type);
 
 cc_return_t CC_CallFeature_RemoveStream(cc_call_handle_t call_handle, cc_media_stream_id_t stream_id, cc_media_track_id_t id, cc_media_type_t media_type);
 
 cc_return_t CC_CallFeature_AddICECandidate(cc_call_handle_t call_handle,
                                            const char* candidate,
                                            const char *mid,
                                            cc_level_t level,
                                            Timecard *tc);
--- a/media/webrtc/signaling/src/sipcc/include/cc_constants.h
+++ b/media/webrtc/signaling/src/sipcc/include/cc_constants.h
@@ -573,20 +573,19 @@ typedef enum {
   VIDEO,
   DATA,
   TYPE_MAX
 } cc_media_type_t;
 
 typedef struct {
   cc_boolean was_passed;
   cc_boolean value;
-  cc_boolean mandatory;
-} cc_boolean_constraint_t;
+} cc_boolean_option_t;
 
 typedef struct {
-  cc_boolean_constraint_t offer_to_receive_audio;
-  cc_boolean_constraint_t offer_to_receive_video;
-  cc_boolean_constraint_t moz_dont_offer_datachannel;
-  cc_boolean_constraint_t moz_bundle_only;
-} cc_media_constraints_t;
+  cc_boolean_option_t offer_to_receive_audio;
+  cc_boolean_option_t offer_to_receive_video;
+  cc_boolean_option_t moz_dont_offer_datachannel;
+  cc_boolean_option_t moz_bundle_only;
+} cc_media_options_t;
 
 #endif /* _CC_CONSTANTS_H_ */
 
--- a/media/webrtc/signaling/src/sipcc/include/ccapi_call.h
+++ b/media/webrtc/signaling/src/sipcc/include/ccapi_call.h
@@ -50,21 +50,20 @@ cc_lineid_t CCAPI_Call_getLine(cc_call_h
  * @param [in] video_pref - video direction desired on call
  * @param [in] digits - digits to be dialed. can be empty then this API simply goes offhook
  * @return SUCCESS or FAILURE
  */
 cc_return_t CCAPI_Call_originateCall(cc_call_handle_t handle, cc_sdp_direction_t video_pref, cc_string_t digits);
 
 
 cc_return_t CCAPI_CreateOffer(cc_call_handle_t handle,
-                              cc_media_constraints_t *constraints,
+                              cc_media_options_t *options,
                               Timecard *tc);
 
 cc_return_t CCAPI_CreateAnswer(cc_call_handle_t handle,
-                               cc_media_constraints_t *constraints,
                                Timecard *tc);
 
 cc_return_t CCAPI_SetLocalDescription(cc_call_handle_t handle,
                                       cc_jsep_action_t action,
                                       cc_string_t sdp,
                                       Timecard *tc);
 
 cc_return_t CCAPI_SetRemoteDescription(cc_call_handle_t handle,
@@ -72,18 +71,17 @@ cc_return_t CCAPI_SetRemoteDescription(c
                                        cc_string_t sdp,
                                        Timecard *tc);
 
 cc_return_t CCAPI_SetPeerConnection(cc_call_handle_t handle, cc_peerconnection_t pc);
 
 cc_return_t CCAPI_AddStream(cc_call_handle_t handle,
                             cc_media_stream_id_t stream_id,
                             cc_media_track_id_t track_id,
-                            cc_media_type_t media_type,
-                            cc_media_constraints_t *constraints);
+                            cc_media_type_t media_type);
 
 cc_return_t CCAPI_RemoveStream(cc_call_handle_t handle, cc_media_stream_id_t stream_id, cc_media_track_id_t track_id, cc_media_type_t media_type);
 
 cc_return_t CCAPI_AddICECandidate(cc_call_handle_t handle,
                                   cc_string_t candidate,
                                   cc_string_t mid,
                                   cc_level_t level,
                                   Timecard *tc);
--- a/media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCall.cpp
+++ b/media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCall.cpp
@@ -527,26 +527,24 @@ void CC_SIPCCCall::originateP2PCall (cc_
 {
     CCAPI_Config_set_server_address(ip.c_str());
     CCAPI_Call_originateCall(callHandle, video_pref, digits.c_str());
 }
 
 /*
  * This method works asynchronously, is an onCallEvent with the resulting SDP
  */
-void CC_SIPCCCall::createOffer (cc_media_constraints_t *constraints,
-                                Timecard *tc) {
-    CCAPI_CreateOffer(callHandle, constraints, tc);
+void CC_SIPCCCall::createOffer (cc_media_options_t *options, Timecard *tc) {
+    CCAPI_CreateOffer(callHandle, options, tc);
 }
 /*
  * This method works asynchronously, there is onCallEvent with the resulting SDP
  */
-void CC_SIPCCCall::createAnswer (cc_media_constraints_t *constraints,
-                                 Timecard *tc) {
-    CCAPI_CreateAnswer(callHandle, constraints, tc);
+void CC_SIPCCCall::createAnswer (Timecard *tc) {
+    CCAPI_CreateAnswer(callHandle, tc);
 
 }
 
 void CC_SIPCCCall::setLocalDescription(cc_jsep_action_t action,
                                        const std::string & sdp,
                                        Timecard *tc) {
     CCAPI_SetLocalDescription(callHandle, action, sdp.c_str(), tc);
 }
@@ -566,19 +564,18 @@ void CC_SIPCCCall::setPeerConnection(con
 }
 
 const std::string& CC_SIPCCCall::getPeerConnection() const {
   return peerconnection;
 }
 
 void CC_SIPCCCall::addStream(cc_media_stream_id_t stream_id,
                              cc_media_track_id_t track_id,
-                             cc_media_type_t media_type,
-                             cc_media_constraints_t *constraints) {
-  CCAPI_AddStream(callHandle, stream_id, track_id, media_type, constraints);
+                             cc_media_type_t media_type) {
+  CCAPI_AddStream(callHandle, stream_id, track_id, media_type);
 }
 
 void CC_SIPCCCall::removeStream(cc_media_stream_id_t stream_id, cc_media_track_id_t track_id, cc_media_type_t media_type) {
   CCAPI_RemoveStream(callHandle, stream_id, track_id, media_type);
 }
 
 void CC_SIPCCCall::addICECandidate(const std::string & candidate,
                                    const std::string & mid,
--- a/media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCall.h
+++ b/media/webrtc/signaling/src/softphonewrapper/CC_SIPCCCall.h
@@ -113,26 +113,25 @@ namespace CSF
         virtual bool muteAudio();
         virtual bool unmuteAudio();
         virtual bool muteVideo();
         virtual bool unmuteVideo();
         virtual void addStream(int streamId, bool isVideo);
         virtual void removeStream(int streamId);
         virtual bool setVolume(int volume);
         virtual void originateP2PCall (cc_sdp_direction_t video_pref, const std::string & digits, const std::string & ip);
-        virtual void createOffer(cc_media_constraints_t *constraints, Timecard *);
-        virtual void createAnswer(cc_media_constraints_t *constraints, Timecard *);
+        virtual void createOffer(cc_media_options_t *options, Timecard *);
+        virtual void createAnswer(Timecard *);
         virtual void setLocalDescription(cc_jsep_action_t action, const std::string & sdp, Timecard *);
         virtual void setRemoteDescription(cc_jsep_action_t action, const std::string & sdp, Timecard *);
         virtual void setPeerConnection(const std::string& handle);
         virtual const std::string& getPeerConnection() const;
         virtual void addStream(cc_media_stream_id_t stream_id,
                                cc_media_track_id_t track_id,
-                               cc_media_type_t media_type,
-                               cc_media_constraints_t *constraints);
+                               cc_media_type_t media_type);
         virtual void removeStream(cc_media_stream_id_t stream_id, cc_media_track_id_t track_id, cc_media_type_t media_type);
         virtual CC_SIPCCCallMediaDataPtr getMediaData();
         virtual void addICECandidate(const std::string & candidate, const std::string & mid, unsigned short level, Timecard *);
 
     private:
         virtual bool setAudioMute(bool mute);
         virtual bool setVideoMute(bool mute);
 
--- a/media/webrtc/signaling/test/signaling_unittests.cpp
+++ b/media/webrtc/signaling/test/signaling_unittests.cpp
@@ -75,37 +75,36 @@ static std::string calleeName = "callee"
 
 std::string g_stun_server_address((char *)"23.21.150.121");
 uint16_t g_stun_server_port(3478);
 std::string kBogusSrflxAddress((char *)"192.0.2.1");
 uint16_t kBogusSrflxPort(1001);
 
 namespace sipcc {
 
-// We can't use mozilla/dom/MediaConstraintsBinding.h here because it uses
-// nsString, so we pass constraints in using MediaConstraintsExternal instead
-
-class MediaConstraints : public MediaConstraintsExternal {
+// We can't use webidl bindings here because it uses nsString,
+// so we pass options in using SipccOfferOptions instead
+
+  class OfferOptions : public mozilla::SipccOfferOptions {
 public:
-  void setBooleanConstraint(const char *namePtr, bool value, bool mandatory) {
-    cc_boolean_constraint_t &member (getMember(namePtr));
+  void setBooleanOption(const char *namePtr, bool value) {
+    cc_boolean_option_t &member (getMember(namePtr));
     member.was_passed = true;
     member.value = value;
-    member.mandatory = mandatory;
   }
 private:
-  cc_boolean_constraint_t &getMember(const char *namePtr) {
+  cc_boolean_option_t &getMember(const char *namePtr) {
     if (strcmp(namePtr, "OfferToReceiveAudio") == 0) {
-        return mConstraints.offer_to_receive_audio;
+        return mOptions.offer_to_receive_audio;
     }
     if (strcmp(namePtr, "OfferToReceiveVideo") == 0) {
-        return mConstraints.offer_to_receive_video;
+        return mOptions.offer_to_receive_video;
     }
     MOZ_ASSERT(false);
-    return mConstraints.moz_dont_offer_datachannel;
+    return mOptions.moz_dont_offer_datachannel;
   }
 };
 }
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 namespace test {
@@ -728,40 +727,39 @@ class PCDispatchWrapper : public nsSuppo
           aObserver, aWindow, aConfiguration, aThread, &rv),
         NS_DISPATCH_SYNC);
       rv = NS_OK;
     }
 
     return rv;
   }
 
-  NS_IMETHODIMP CreateOffer(const MediaConstraintsExternal& aConstraints) {
+  NS_IMETHODIMP CreateOffer(const SipccOfferOptions& aOptions) {
     nsresult rv;
 
     if (NS_IsMainThread()) {
-      rv = pc_->CreateOffer(aConstraints);
+      rv = pc_->CreateOffer(aOptions);
     } else {
       gMainThread->Dispatch(
         WrapRunnableRet(this, &PCDispatchWrapper::CreateOffer,
-          aConstraints, &rv),
+          aOptions, &rv),
         NS_DISPATCH_SYNC);
     }
 
     return rv;
   }
 
-  NS_IMETHODIMP CreateAnswer(const MediaConstraintsExternal& aConstraints) {
+  NS_IMETHODIMP CreateAnswer() {
     nsresult rv;
 
     if (NS_IsMainThread()) {
-      rv = pc_->CreateAnswer(aConstraints);
+      rv = pc_->CreateAnswer();
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::CreateAnswer,
-          aConstraints, &rv),
+        WrapRunnableRet(this, &PCDispatchWrapper::CreateAnswer, &rv),
         NS_DISPATCH_SYNC);
     }
 
     return rv;
   }
 
   NS_IMETHODIMP SetLocalDescription (int32_t aAction, const char* aSDP) {
     nsresult rv;
@@ -803,26 +801,24 @@ class PCDispatchWrapper : public nsSuppo
       gMainThread->Dispatch(
         WrapRunnableRet(this, &PCDispatchWrapper::AddIceCandidate,
           aCandidate, aMid, aLevel, &rv),
         NS_DISPATCH_SYNC);
     }
     return rv;
   }
 
-  NS_IMETHODIMP AddStream(DOMMediaStream *aMediaStream,
-    const MediaConstraintsExternal& aConstraints) {
+  NS_IMETHODIMP AddStream(DOMMediaStream *aMediaStream) {
     nsresult rv;
 
     if (NS_IsMainThread()) {
-      rv = pc_->AddStream(*aMediaStream, aConstraints);
+      rv = pc_->AddStream(*aMediaStream);
     } else {
       gMainThread->Dispatch(
-        WrapRunnableRet(this, &PCDispatchWrapper::AddStream,
-          aMediaStream, aConstraints, &rv),
+        WrapRunnableRet(this, &PCDispatchWrapper::AddStream, aMediaStream, &rv),
         NS_DISPATCH_SYNC);
     }
 
     return rv;
   }
 
   NS_IMETHODIMP RemoveStream(DOMMediaStream *aMediaStream) {
     nsresult rv;
@@ -1079,46 +1075,39 @@ class SignalingAgent {
     }
     return sdp;
   }
 
   // Adds a stream to the PeerConnection.
   void AddStream(uint32_t hint =
          DOMMediaStream::HINT_CONTENTS_AUDIO |
          DOMMediaStream::HINT_CONTENTS_VIDEO,
-       MediaStream *stream = nullptr,
-       sipcc::MediaConstraints *constraints = nullptr
-       ) {
-
-    sipcc::MediaConstraints noConstraints;
-    if (!constraints) {
-      constraints = &noConstraints;
-    }
+       MediaStream *stream = nullptr) {
 
     nsRefPtr<DOMMediaStream> domMediaStream;
     if (stream) {
       domMediaStream = new DOMMediaStream(stream);
     } else {
       domMediaStream = new DOMMediaStream();
     }
 
     domMediaStream->SetHintContents(hint);
-    ASSERT_EQ(pc->AddStream(domMediaStream, *constraints), NS_OK);
+    ASSERT_EQ(pc->AddStream(domMediaStream), NS_OK);
     domMediaStream_ = domMediaStream;
   }
 
 
   // Removes a stream from the PeerConnection. If the stream
   // parameter is absent, removes the stream that was most
   // recently added to the PeerConnection.
   void RemoveLastStreamAdded() {
     ASSERT_EQ(pc->RemoveStream(domMediaStream_), NS_OK);
   }
 
-  void CreateOffer(sipcc::MediaConstraints& constraints,
+  void CreateOffer(sipcc::OfferOptions& options,
                    uint32_t offerFlags, uint32_t sdpCheck,
                    PCImplSignalingState endState =
                      PCImplSignalingState::SignalingStable) {
 
     // Create a media stream as if it came from GUM
     Fake_AudioStreamSource *audio_stream =
       new Fake_AudioStreamSource();
 
@@ -1135,26 +1124,26 @@ class SignalingAgent {
     }
     if (offerFlags & OFFER_VIDEO) {
       aHintContents |= DOMMediaStream::HINT_CONTENTS_VIDEO;
     }
     AddStream(aHintContents, audio_stream);
 
     // Now call CreateOffer as JS would
     pObserver->state = TestObserver::stateNoResponse;
-    ASSERT_EQ(pc->CreateOffer(constraints), NS_OK);
+    ASSERT_EQ(pc->CreateOffer(options), NS_OK);
     ASSERT_TRUE_WAIT(pObserver->state != TestObserver::stateNoResponse,
                      kDefaultTimeout);
     ASSERT_EQ(pObserver->state, TestObserver::stateSuccess);
     SDPSanityCheck(pObserver->lastString, sdpCheck, true);
     ASSERT_EQ(signaling_state(), endState);
     offer_ = pObserver->lastString;
   }
 
-void CreateAnswer(sipcc::MediaConstraints& constraints, std::string offer,
+void CreateAnswer(std::string offer,
                     uint32_t offerAnswerFlags,
                     uint32_t sdpCheck = DONT_CHECK_AUDIO|
                                         DONT_CHECK_VIDEO|
                                         DONT_CHECK_DATA,
                     PCImplSignalingState endState =
                     PCImplSignalingState::SignalingHaveRemoteOffer) {
 
     uint32_t aHintContents = 0;
@@ -1164,45 +1153,45 @@ void CreateAnswer(sipcc::MediaConstraint
     if (offerAnswerFlags & ANSWER_VIDEO) {
       aHintContents |= DOMMediaStream::HINT_CONTENTS_VIDEO;
     }
     AddStream(aHintContents);
 
     // Decide if streams are disabled for offer or answer
     // then perform SDP checking based on which stream disabled
     pObserver->state = TestObserver::stateNoResponse;
-    ASSERT_EQ(pc->CreateAnswer(constraints), NS_OK);
+    ASSERT_EQ(pc->CreateAnswer(), NS_OK);
     ASSERT_TRUE_WAIT(pObserver->state != TestObserver::stateNoResponse,
                      kDefaultTimeout);
     ASSERT_EQ(pObserver->state, TestObserver::stateSuccess);
     SDPSanityCheck(pObserver->lastString, sdpCheck, false);
     ASSERT_EQ(signaling_state(), endState);
 
     answer_ = pObserver->lastString;
   }
 
   // At present, we use the hints field in a stream to find and
   // remove it. This only works if the specified hints flags are
   // unique among all streams in the PeerConnection. This is not
   // generally true, and will need significant revision once
   // multiple streams are supported.
-  void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints,
+  void CreateOfferRemoveStream(sipcc::OfferOptions& options,
                                uint32_t hints, uint32_t sdpCheck) {
 
     domMediaStream_->SetHintContents(hints);
 
     // This currently "removes" a stream that has the same audio/video
     // hints as were passed in.
     // When complete RemoveStream will remove and entire stream and its tracks
     // not just disable a track as this is currently doing
     ASSERT_EQ(pc->RemoveStream(domMediaStream_), NS_OK);
 
     // Now call CreateOffer as JS would
     pObserver->state = TestObserver::stateNoResponse;
-    ASSERT_EQ(pc->CreateOffer(constraints), NS_OK);
+    ASSERT_EQ(pc->CreateOffer(options), NS_OK);
     ASSERT_TRUE_WAIT(pObserver->state != TestObserver::stateNoResponse,
                      kDefaultTimeout);
     ASSERT_TRUE(pObserver->state == TestObserver::stateSuccess);
     SDPSanityCheck(pObserver->lastString, sdpCheck, true);
     offer_ = pObserver->lastString;
   }
 
   void SetRemote(TestObserver::Action action, std::string remote,
@@ -1645,130 +1634,124 @@ public:
   void WaitForGather() {
     a1_->WaitForGather();
     a2_->WaitForGather();
   }
 
   static void TearDownTestCase() {
   }
 
-  void CreateOffer(sipcc::MediaConstraints& constraints,
+  void CreateOffer(sipcc::OfferOptions& options,
                    uint32_t offerFlags, uint32_t sdpCheck) {
     EnsureInit();
-    a1_->CreateOffer(constraints, offerFlags, sdpCheck);
+    a1_->CreateOffer(options, offerFlags, sdpCheck);
   }
 
-  void CreateSetOffer(sipcc::MediaConstraints& constraints, uint32_t sdpCheck) {
+  void CreateSetOffer(sipcc::OfferOptions& options, uint32_t sdpCheck) {
     EnsureInit();
-    a1_->CreateOffer(constraints, OFFER_AV, sdpCheck);
+    a1_->CreateOffer(options, OFFER_AV, sdpCheck);
     a1_->SetLocal(TestObserver::OFFER, a1_->offer());
   }
 
-  void OfferAnswer(sipcc::MediaConstraints& aconstraints,
-                   sipcc::MediaConstraints& bconstraints,
+  void OfferAnswer(sipcc::OfferOptions& options,
                    uint32_t offerAnswerFlags,
                    bool finishAfterAnswer, uint32_t offerSdpCheck,
                    uint32_t answerSdpCheck) {
     EnsureInit();
-    a1_->CreateOffer(aconstraints, offerAnswerFlags, offerSdpCheck);
+    a1_->CreateOffer(options, offerAnswerFlags, offerSdpCheck);
     a1_->SetLocal(TestObserver::OFFER, a1_->offer());
     a2_->SetRemote(TestObserver::OFFER, a1_->offer());
-    a2_->CreateAnswer(bconstraints, a1_->offer(),
-                     offerAnswerFlags, answerSdpCheck);
+    a2_->CreateAnswer(a1_->offer(), offerAnswerFlags, answerSdpCheck);
     if(true == finishAfterAnswer) {
         a2_->SetLocal(TestObserver::ANSWER, a2_->answer());
         a1_->SetRemote(TestObserver::ANSWER, a2_->answer());
 
         ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
         ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
     }
   }
 
-  void OfferModifiedAnswer(sipcc::MediaConstraints& aconstraints,
-                           sipcc::MediaConstraints& bconstraints,
+  void OfferModifiedAnswer(sipcc::OfferOptions& options,
                            uint32_t offerSdpCheck, uint32_t answerSdpCheck) {
     EnsureInit();
-    a1_->CreateOffer(aconstraints, OFFER_AUDIO, offerSdpCheck);
+    a1_->CreateOffer(options, OFFER_AUDIO, offerSdpCheck);
     a1_->SetLocal(TestObserver::OFFER, a1_->offer());
     a2_->SetRemote(TestObserver::OFFER, a1_->offer());
-    a2_->CreateAnswer(bconstraints, a1_->offer(), OFFER_AUDIO | ANSWER_AUDIO,
-                     answerSdpCheck);
+    a2_->CreateAnswer(a1_->offer(), OFFER_AUDIO | ANSWER_AUDIO, answerSdpCheck);
     a2_->SetLocal(TestObserver::ANSWER, a2_->answer());
     ParsedSDP sdpWrapper(a2_->answer());
     sdpWrapper.ReplaceLine("m=audio", "m=audio 65375 RTP/SAVPF 109 8 101\r\n");
     sdpWrapper.AddLine("a=rtpmap:8 PCMA/8000\r\n");
     std::cout << "Modified SDP " << std::endl
               << indent(sdpWrapper.getSdp()) << std::endl;
     a1_->SetRemote(TestObserver::ANSWER, sdpWrapper.getSdp());
     ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
     ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
   }
 
-  void OfferAnswerTrickle(sipcc::MediaConstraints& aconstraints,
-                          sipcc::MediaConstraints& bconstraints,
+  void OfferAnswerTrickle(sipcc::OfferOptions& options,
                           uint32_t offerSdpCheck, uint32_t answerSdpCheck) {
     EnsureInit();
-    a1_->CreateOffer(aconstraints, OFFER_AV, offerSdpCheck);
+    a1_->CreateOffer(options, OFFER_AV, offerSdpCheck);
     a1_->SetLocal(TestObserver::OFFER, a1_->offer());
     ParsedSDP a1_offer(a1_->offer());
     a2_->SetRemote(TestObserver::OFFER, a1_offer.sdp_without_ice_);
-    a2_->CreateAnswer(bconstraints, a1_offer.sdp_without_ice_,
+    a2_->CreateAnswer(a1_offer.sdp_without_ice_,
                      OFFER_AV|ANSWER_AV, answerSdpCheck);
     a2_->SetLocal(TestObserver::ANSWER, a2_->answer());
     ParsedSDP a2_answer(a2_->answer());
     a1_->SetRemote(TestObserver::ANSWER, a2_answer.sdp_without_ice_);
     // Now set the trickle ICE candidates
     a1_->DoTrickleIce(a2_answer);
     a2_->DoTrickleIce(a1_offer);
     ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
     ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
   }
 
 
-  void OfferAnswerTrickleChrome(sipcc::MediaConstraints& aconstraints,
-                          sipcc::MediaConstraints& bconstraints,
+  void OfferAnswerTrickleChrome(sipcc::OfferOptions& options,
                           uint32_t offerSdpCheck, uint32_t answerSdpCheck) {
     EnsureInit();
-    a1_->CreateOffer(aconstraints, OFFER_AV, offerSdpCheck);
+    a1_->CreateOffer(options, OFFER_AV, offerSdpCheck);
     a1_->SetLocal(TestObserver::OFFER, a1_->offer());
     ParsedSDP a1_offer(a1_->offer());
     a2_->SetRemote(TestObserver::OFFER, a1_offer.sdp_without_ice_);
-    a2_->CreateAnswer(bconstraints, a1_offer.sdp_without_ice_,
+    a2_->CreateAnswer(a1_offer.sdp_without_ice_,
                      OFFER_AV|ANSWER_AV, answerSdpCheck);
     a2_->SetLocal(TestObserver::ANSWER, a2_->answer());
     ParsedSDP a2_answer(a2_->answer());
     a1_->SetRemote(TestObserver::ANSWER, a2_answer.sdp_without_ice_);
     // Now set the trickle ICE candidates
     a1_->DoTrickleIceChrome(a2_answer);
     a2_->DoTrickleIceChrome(a1_offer);
     ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
     ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
   }
 
-  void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints,
+  void CreateOfferRemoveStream(sipcc::OfferOptions& options,
                                uint32_t hints, uint32_t sdpCheck) {
     EnsureInit();
-    sipcc::MediaConstraints aconstraints;
-    aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-    aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-    a1_->CreateOffer(aconstraints, OFFER_AV, SHOULD_SENDRECV_AV );
-    a1_->CreateOfferRemoveStream(constraints, hints, sdpCheck);
+    sipcc::OfferOptions aoptions;
+    aoptions.setBooleanOption("OfferToReceiveAudio", true);
+    aoptions.setBooleanOption("OfferToReceiveVideo", true);
+    a1_->CreateOffer(aoptions, OFFER_AV, SHOULD_SENDRECV_AV );
+    a1_->CreateOfferRemoveStream(options, hints, sdpCheck);
   }
 
-  void CreateOfferAudioOnly(sipcc::MediaConstraints& constraints,
+  void CreateOfferAudioOnly(sipcc::OfferOptions& options,
                             uint32_t sdpCheck) {
     EnsureInit();
-    a1_->CreateOffer(constraints, OFFER_AUDIO, sdpCheck);
+    a1_->CreateOffer(options, OFFER_AUDIO, sdpCheck);
   }
 
-  void CreateOfferAddCandidate(sipcc::MediaConstraints& constraints,
+  void CreateOfferAddCandidate(sipcc::OfferOptions& options,
                                const char * candidate, const char * mid,
                                unsigned short level, uint32_t sdpCheck) {
     EnsureInit();
-    a1_->CreateOffer(constraints, OFFER_AV, sdpCheck);
+    a1_->CreateOffer(options, OFFER_AV, sdpCheck);
     a1_->AddIceCandidate(candidate, mid, level, true);
   }
 
   void AddIceCandidateEarly(const char * candidate, const char * mid,
                             unsigned short level) {
     EnsureInit();
     a1_->AddIceCandidate(candidate, mid, level, false);
   }
@@ -1797,19 +1780,19 @@ public:
       ASSERT_NE(0U, expected.count(*it2));
     }
   }
 
   void TestRtcpFb(const std::set<std::string>& feedback,
                   uint32_t rtcpFbFlags,
                   VideoSessionConduit::FrameRequestType frameRequestMethod) {
     EnsureInit();
-    sipcc::MediaConstraints constraints;
-
-    a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
+    sipcc::OfferOptions options;
+
+    a1_->CreateOffer(options, OFFER_AV, SHOULD_SENDRECV_AV);
     a1_->SetLocal(TestObserver::OFFER, a1_->offer());
 
     ParsedSDP sdpWrapper(a1_->offer());
 
     // Strip out any existing rtcp-fb lines
     sdpWrapper.DeleteAllLines("a=rtcp-fb:120");
 
     // Add rtcp-fb lines for the desired feedback types
@@ -1822,17 +1805,17 @@ public:
 
     std::cout << "Modified SDP " << std::endl
               << indent(sdpWrapper.getSdp()) << std::endl;
 
     // Double-check that the offered SDP matches what we expect
     CheckRtcpFbSdp(sdpWrapper.getSdp(), feedback);
 
     a2_->SetRemote(TestObserver::OFFER, sdpWrapper.getSdp());
-    a2_->CreateAnswer(constraints, sdpWrapper.getSdp(), OFFER_AV | ANSWER_AV);
+    a2_->CreateAnswer(sdpWrapper.getSdp(), OFFER_AV | ANSWER_AV);
 
     CheckRtcpFbSdp(a2_->answer(), feedback);
 
     a2_->SetLocal(TestObserver::ANSWER, a2_->answer());
     a1_->SetRemote(TestObserver::ANSWER, a2_->answer());
 
     ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
     ASSERT_TRUE_WAIT(a2_->IceCompleted() == true, kDefaultTimeout);
@@ -1964,380 +1947,332 @@ class FsFrPrefClearer {
 };
 
 TEST_F(SignalingTest, JustInit)
 {
 }
 
 TEST_F(SignalingTest, CreateSetOffer)
 {
-  sipcc::MediaConstraints constraints;
-  CreateSetOffer(constraints, SHOULD_SENDRECV_AV);
+  sipcc::OfferOptions options;
+  CreateSetOffer(options, SHOULD_SENDRECV_AV);
 }
 
-TEST_F(SignalingTest, CreateOfferAudioVideoConstraintUndefined)
+TEST_F(SignalingTest, CreateOfferAudioVideoOptionUndefined)
 {
-  sipcc::MediaConstraints constraints;
-  CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
+  sipcc::OfferOptions options;
+  CreateOffer(options, OFFER_AV, SHOULD_SENDRECV_AV);
 }
 
 TEST_F(SignalingTest, CreateOfferNoVideoStreamRecvVideo)
 {
-  sipcc::MediaConstraints constraints;
-  constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  CreateOffer(constraints, OFFER_AUDIO,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  CreateOffer(options, OFFER_AUDIO,
               SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO);
 }
 
 TEST_F(SignalingTest, CreateOfferNoAudioStreamRecvAudio)
 {
-  sipcc::MediaConstraints constraints;
-  constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  CreateOffer(constraints, OFFER_VIDEO,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  CreateOffer(options, OFFER_VIDEO,
               SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
 TEST_F(SignalingTest, CreateOfferNoVideoStream)
 {
-  sipcc::MediaConstraints constraints;
-  constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  constraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-  CreateOffer(constraints, OFFER_AUDIO,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", false);
+  CreateOffer(options, OFFER_AUDIO,
               SHOULD_SENDRECV_AUDIO | SHOULD_OMIT_VIDEO);
 }
 
 TEST_F(SignalingTest, CreateOfferNoAudioStream)
 {
-  sipcc::MediaConstraints constraints;
-  constraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
-  constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  CreateOffer(constraints, OFFER_VIDEO,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", false);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  CreateOffer(options, OFFER_VIDEO,
               SHOULD_OMIT_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
 TEST_F(SignalingTest, CreateOfferDontReceiveAudio)
 {
-  sipcc::MediaConstraints constraints;
-  constraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
-  constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  CreateOffer(constraints, OFFER_AV,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", false);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  CreateOffer(options, OFFER_AV,
               SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
 TEST_F(SignalingTest, CreateOfferDontReceiveVideo)
 {
-  sipcc::MediaConstraints constraints;
-  constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  constraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-  CreateOffer(constraints, OFFER_AV,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", false);
+  CreateOffer(options, OFFER_AV,
               SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO);
 }
 
 // XXX Disabled pending resolution of Bug 840728
 TEST_F(SignalingTest, DISABLED_CreateOfferRemoveAudioStream)
 {
-  sipcc::MediaConstraints constraints;
-  constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  CreateOfferRemoveStream(constraints, DOMMediaStream::HINT_CONTENTS_AUDIO,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  CreateOfferRemoveStream(options, DOMMediaStream::HINT_CONTENTS_AUDIO,
               SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
 // XXX Disabled pending resolution of Bug 840728
 TEST_F(SignalingTest, DISABLED_CreateOfferDontReceiveAudioRemoveAudioStream)
 {
-  sipcc::MediaConstraints constraints;
-  constraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
-  constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  CreateOfferRemoveStream(constraints, DOMMediaStream::HINT_CONTENTS_AUDIO,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", false);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  CreateOfferRemoveStream(options, DOMMediaStream::HINT_CONTENTS_AUDIO,
               SHOULD_SENDRECV_VIDEO);
 }
 
 // XXX Disabled pending resolution of Bug 840728
 TEST_F(SignalingTest, DISABLED_CreateOfferDontReceiveVideoRemoveVideoStream)
 {
-  sipcc::MediaConstraints constraints;
-  constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  constraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-  CreateOfferRemoveStream(constraints, DOMMediaStream::HINT_CONTENTS_VIDEO,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", false);
+  CreateOfferRemoveStream(options, DOMMediaStream::HINT_CONTENTS_VIDEO,
               SHOULD_SENDRECV_AUDIO);
 }
 
 TEST_F(SignalingTest, OfferAnswerNothingDisabled)
 {
-  sipcc::MediaConstraints constraints;
-  OfferAnswer(constraints, constraints, OFFER_AV | ANSWER_AV, false,
+  sipcc::OfferOptions options;
+  OfferAnswer(options, OFFER_AV | ANSWER_AV, false,
               SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
 }
 
 TEST_F(SignalingTest, OfferAnswerDontReceiveAudioOnOffer)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints answerconstraints;
-  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", false);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  OfferAnswer(options, OFFER_AV | ANSWER_AV,
               false, SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO,
               SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
 TEST_F(SignalingTest, OfferAnswerDontReceiveVideoOnOffer)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-  sipcc::MediaConstraints answerconstraints;
-  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", false);
+  OfferAnswer(options, OFFER_AV | ANSWER_AV,
               false, SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO,
               SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO);
 }
 
 TEST_F(SignalingTest, OfferAnswerDontReceiveAudioOnAnswer)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints answerconstraints;
-  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
-  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  OfferAnswer(options, OFFER_AV | ANSWER_AV,
               false, SHOULD_SENDRECV_AV,
               SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
 TEST_F(SignalingTest, OfferAnswerDontReceiveVideoOnAnswer)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints answerconstraints;
-  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  OfferAnswer(options, OFFER_AV | ANSWER_AV,
               false, SHOULD_SENDRECV_AV,
               SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO);
 }
 
 TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnOfferRecvAudio)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints answerconstraints;
-  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_VIDEO | ANSWER_AV,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  OfferAnswer(options, OFFER_VIDEO | ANSWER_AV,
               false, SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO,
               SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
 TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnOffer)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints answerconstraints;
-  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_VIDEO | ANSWER_AV,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", false);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  OfferAnswer(options, OFFER_VIDEO | ANSWER_AV,
               false, SHOULD_OMIT_AUDIO | SHOULD_SENDRECV_VIDEO,
               SHOULD_OMIT_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
 TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnOfferRecvVideo)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints answerconstraints;
-  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_AUDIO | ANSWER_AV,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  OfferAnswer(options, OFFER_AUDIO | ANSWER_AV,
               false, SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO,
               SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO);
 }
 
 TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnOffer)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-  sipcc::MediaConstraints answerconstraints;
-  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_AUDIO | ANSWER_AV,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", false);
+  OfferAnswer(options, OFFER_AUDIO | ANSWER_AV,
               false, SHOULD_SENDRECV_AUDIO | SHOULD_OMIT_VIDEO,
               SHOULD_SENDRECV_AUDIO | SHOULD_OMIT_VIDEO);
 }
 
 TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnAnswer)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints answerconstraints;
-  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_VIDEO,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  OfferAnswer(options, OFFER_AV | ANSWER_VIDEO,
               false, SHOULD_SENDRECV_AV,
               SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
 TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnAnswer)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints answerconstraints;
-  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AUDIO,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  OfferAnswer(options, OFFER_AV | ANSWER_AUDIO,
               false, SHOULD_SENDRECV_AV,
               SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO);
 }
 
 TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnAnswerDontReceiveVideoOnAnswer)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints answerconstraints;
-  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AUDIO,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  OfferAnswer(options, OFFER_AV | ANSWER_AUDIO,
               false, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AUDIO );
 }
 
 TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnAnswerDontReceiveAudioOnAnswer)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints answerconstraints;
-  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
-  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_VIDEO,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  OfferAnswer(options, OFFER_AV | ANSWER_VIDEO,
               false, SHOULD_SENDRECV_AV,
               SHOULD_REJECT_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
 TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnOfferDontReceiveAudioOnOffer)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints answerconstraints;
-  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_VIDEO | ANSWER_AV,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", false);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  OfferAnswer(options, OFFER_VIDEO | ANSWER_AV,
               false, SHOULD_SENDRECV_VIDEO, SHOULD_SENDRECV_VIDEO);
 }
 
 TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnOfferDontReceiveVideoOnOffer)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-  sipcc::MediaConstraints answerconstraints;
-  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_AUDIO | ANSWER_AV,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", false);
+  OfferAnswer(options, OFFER_AUDIO | ANSWER_AV,
               false, SHOULD_SENDRECV_AUDIO | SHOULD_OMIT_VIDEO,
               SHOULD_SENDRECV_AUDIO | SHOULD_OMIT_VIDEO);
 }
 
 TEST_F(SignalingTest, OfferAnswerDontReceiveAudioNoAudioStreamOnOfferDontReceiveVideoOnAnswer)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints answerconstraints;
-  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_VIDEO | ANSWER_AV,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", false);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  OfferAnswer(options, OFFER_VIDEO | ANSWER_AV,
               false, SHOULD_SENDRECV_VIDEO, SHOULD_SEND_VIDEO);
 }
 
 TEST_F(SignalingTest, CreateOfferAddCandidate)
 {
-  sipcc::MediaConstraints constraints;
-  CreateOfferAddCandidate(constraints, strSampleCandidate.c_str(),
+  sipcc::OfferOptions options;
+  CreateOfferAddCandidate(options, strSampleCandidate.c_str(),
                           strSampleMid.c_str(), nSamplelevel,
                           SHOULD_SENDRECV_AV);
 }
 
 TEST_F(SignalingTest, AddIceCandidateEarly)
 {
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
   AddIceCandidateEarly(strSampleCandidate.c_str(),
                        strSampleMid.c_str(), nSamplelevel);
 }
 
 // XXX adam@nostrum.com -- This test seems questionable; we need to think
 // through what actually needs to be tested here.
 TEST_F(SignalingTest, DISABLED_OfferAnswerReNegotiateOfferAnswerDontReceiveVideoNoVideoStream)
 {
-  sipcc::MediaConstraints aconstraints;
-  aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-
-  sipcc::MediaConstraints bconstraints;
-  bconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  bconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-
-  OfferAnswer(aconstraints, aconstraints, OFFER_AV | ANSWER_AV,
+  sipcc::OfferOptions aoptions;
+  aoptions.setBooleanOption("OfferToReceiveAudio", true);
+  aoptions.setBooleanOption("OfferToReceiveVideo", true);
+
+  sipcc::OfferOptions boptions;
+  boptions.setBooleanOption("OfferToReceiveAudio", true);
+  boptions.setBooleanOption("OfferToReceiveVideo", false);
+
+  OfferAnswer(aoptions, OFFER_AV | ANSWER_AV,
               false, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
-  OfferAnswer(bconstraints, bconstraints, OFFER_AUDIO | ANSWER_AV,
+  OfferAnswer(boptions, OFFER_AUDIO | ANSWER_AV,
               false, SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO,
               SHOULD_SENDRECV_AUDIO | SHOULD_INACTIVE_VIDEO);
 }
 
-TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnAnswerNoConstraints)
+TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnAnswerNoOptions)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints answerconstraints;
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_VIDEO,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  OfferAnswer(options, OFFER_AV | ANSWER_VIDEO,
               false, SHOULD_SENDRECV_AV,
               SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
-TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnAnswerNoConstraints)
+TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnAnswerNoOptions)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints answerconstraints;
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AUDIO,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  OfferAnswer(options, OFFER_AV | ANSWER_AUDIO,
               false, SHOULD_SENDRECV_AV,
               SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO);
 }
 
-TEST_F(SignalingTest, OfferAnswerDontAddAudioVideoStreamsOnAnswerNoConstraints)
+TEST_F(SignalingTest, OfferAnswerDontAddAudioVideoStreamsOnAnswerNoOptions)
 {
-  sipcc::MediaConstraints offerconstraints;
-  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints answerconstraints;
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_NONE,
+  sipcc::OfferOptions options;
+  options.setBooleanOption("OfferToReceiveAudio", true);
+  options.setBooleanOption("OfferToReceiveVideo", true);
+  OfferAnswer(options, OFFER_AV | ANSWER_NONE,
               false, SHOULD_SENDRECV_AV,
               SHOULD_RECV_AUDIO | SHOULD_RECV_VIDEO);
 }
 
 TEST_F(SignalingTest, FullCall)
 {
-  sipcc::MediaConstraints constraints;
-  OfferAnswer(constraints, constraints, OFFER_AV | ANSWER_AV,
+  sipcc::OfferOptions options;
+  OfferAnswer(options, OFFER_AV | ANSWER_AV,
               true, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
 
   // Wait for some data to get written
   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
 
   a1_->CloseSendStreams();
   a2_->CloseReceiveStreams();
@@ -2355,40 +2290,42 @@ TEST_F(SignalingTest, FullCall)
     PIPELINE_LOCAL | PIPELINE_SEND);
 
   // The first Remote pipeline gets stored at 1
   a2_->CheckMediaPipeline(0, 1, (fRtcpMux ?  PIPELINE_RTCP_MUX : 0));
 }
 
 TEST_F(SignalingTest, FullCallAudioOnly)
 {
-  sipcc::MediaConstraints constraints;
-  OfferAnswer(constraints, constraints, OFFER_AUDIO | ANSWER_AUDIO,
+  sipcc::OfferOptions options;
+  OfferAnswer(options, OFFER_AUDIO | ANSWER_AUDIO,
               true, SHOULD_SENDRECV_AUDIO, SHOULD_SENDRECV_AUDIO);
 
   // Wait for some data to get written
   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
 
   a1_->CloseSendStreams();
   a2_->CloseReceiveStreams();
   // Check that we wrote a bunch of data
   ASSERT_GE(a1_->GetPacketsSent(0), 40);
   //ASSERT_GE(a2_->GetPacketsSent(0), 40);
   //ASSERT_GE(a1_->GetPacketsReceived(0), 40);
   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
 }
 
-TEST_F(SignalingTest, FullCallAnswererRejectsVideo)
+// FIXME -- reject offered stream by .stop()ing the MST that was offered instead,
+// or by setting .active property to false on the created RTPReceiver object.
+TEST_F(SignalingTest, DISABLED_FullCallAnswererRejectsVideo)
 {
-  sipcc::MediaConstraints offerconstraints;
-  sipcc::MediaConstraints answerconstraints;
-  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AUDIO,
+  sipcc::OfferOptions offeroptions;
+  sipcc::OfferOptions answeroptions;
+  answeroptions.setBooleanOption("offerToReceiveAudio", true);
+  answeroptions.setBooleanOption("offerToReceiveVideo", false);
+  OfferAnswer(offeroptions, OFFER_AV | ANSWER_AUDIO,
               true, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AUDIO);
 
   // Wait for some data to get written
   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
 
   a1_->CloseSendStreams();
   a2_->CloseReceiveStreams();
@@ -2396,18 +2333,18 @@ TEST_F(SignalingTest, FullCallAnswererRe
   ASSERT_GE(a1_->GetPacketsSent(0), 40);
   //ASSERT_GE(a2_->GetPacketsSent(0), 40);
   //ASSERT_GE(a1_->GetPacketsReceived(0), 40);
   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
 }
 
 TEST_F(SignalingTest, FullCallVideoOnly)
 {
-  sipcc::MediaConstraints constraints;
-  OfferAnswer(constraints, constraints, OFFER_VIDEO | ANSWER_VIDEO,
+  sipcc::OfferOptions options;
+  OfferAnswer(options, OFFER_VIDEO | ANSWER_VIDEO,
               true, SHOULD_SENDRECV_VIDEO, SHOULD_SENDRECV_VIDEO);
 
   // If we could check for video packets, we would wait for some to be written
   // here. Since we can't, we don't.
   // ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
   //                 a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
 
   a1_->CloseSendStreams();
@@ -2421,46 +2358,44 @@ TEST_F(SignalingTest, FullCallVideoOnly)
   // ASSERT_GE(a1_->GetPacketsSent(0), 40);
   //ASSERT_GE(a2_->GetPacketsSent(0), 40);
   //ASSERT_GE(a1_->GetPacketsReceived(0), 40);
   // ASSERT_GE(a2_->GetPacketsReceived(0), 40);
 }
 
 TEST_F(SignalingTest, OfferModifiedAnswer)
 {
-  sipcc::MediaConstraints constraints;
-  OfferModifiedAnswer(constraints, constraints, SHOULD_SENDRECV_AUDIO,
-                      SHOULD_SENDRECV_AUDIO);
+  sipcc::OfferOptions options;
+  OfferModifiedAnswer(options, SHOULD_SENDRECV_AUDIO, SHOULD_SENDRECV_AUDIO);
   a1_->CloseSendStreams();
   a2_->CloseReceiveStreams();
 }
 
 TEST_F(SignalingTest, FullCallTrickle)
 {
-  sipcc::MediaConstraints constraints;
-  OfferAnswerTrickle(constraints, constraints,
-                     SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
+  sipcc::OfferOptions options;
+  OfferAnswerTrickle(options, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
 
   std::cerr << "ICE handshake completed" << std::endl;
 
   // Wait for some data to get written
   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
 
   a1_->CloseSendStreams();
   a2_->CloseReceiveStreams();
   ASSERT_GE(a1_->GetPacketsSent(0), 40);
   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
 }
 
 // Offer answer with trickle but with chrome-style candidates
 TEST_F(SignalingTest, FullCallTrickleChrome)
 {
-  sipcc::MediaConstraints constraints;
-  OfferAnswerTrickleChrome(constraints, constraints,
+  sipcc::OfferOptions options;
+  OfferAnswerTrickleChrome(options,
                            SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
 
   std::cerr << "ICE handshake completed" << std::endl;
 
   // Wait for some data to get written
   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
 
@@ -2470,25 +2405,25 @@ TEST_F(SignalingTest, FullCallTrickleChr
   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
 }
 
 // This test comes from Bug 810220
 TEST_F(SignalingTest, AudioOnlyG711Call)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
   const std::string& offer(strG711SdpOffer);
 
   std::cout << "Setting offer to:" << std::endl << indent(offer) << std::endl;
   a2_->SetRemote(TestObserver::OFFER, offer);
 
   std::cout << "Creating answer:" << std::endl;
-  a2_->CreateAnswer(constraints, offer, OFFER_AUDIO | ANSWER_AUDIO,
-                   DONT_CHECK_AUDIO | DONT_CHECK_VIDEO | DONT_CHECK_DATA);
+  a2_->CreateAnswer(offer, OFFER_AUDIO | ANSWER_AUDIO,
+                    DONT_CHECK_AUDIO | DONT_CHECK_VIDEO | DONT_CHECK_DATA);
 
   std::string answer = a2_->answer();
 
   // They didn't offer opus, so our answer shouldn't include it.
   ASSERT_EQ(answer.find(" opus/"), std::string::npos);
 
   // They also didn't offer video or application
   ASSERT_EQ(answer.find("video"), std::string::npos);
@@ -2502,17 +2437,16 @@ TEST_F(SignalingTest, AudioOnlyG711Call)
   ASSERT_NE(answer.find("\r\na=sendrecv"), std::string::npos);
 
 }
 
 TEST_F(SignalingTest, IncomingOfferIceLite)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
   std::string offer =
     "v=0\r\n"
     "o=- 1936463 1936463 IN IP4 148.147.200.251\r\n"
     "s=-\r\n"
     "c=IN IP4 148.147.200.251\r\n"
     "t=0 0\r\n"
     "a=ice-lite\r\n"
     "a=fingerprint:sha-1 "
@@ -2529,30 +2463,28 @@ TEST_F(SignalingTest, IncomingOfferIceLi
     "a=candidate:1661181211 1 udp 10 148.147.200.251 40014 typ host\r\n"
     "a=candidate:1661181211 2 udp 9 148.147.200.251 40015 typ host\r\n"
     "a=setup:actpass\r\n";
 
   std::cout << "Setting offer to:" << std::endl << indent(offer) << std::endl;
   a2_->SetRemote(TestObserver::OFFER, offer);
 
   std::cout << "Creating answer:" << std::endl;
-  a2_->CreateAnswer(constraints, offer, OFFER_AUDIO | ANSWER_AUDIO);
+  a2_->CreateAnswer(offer, OFFER_AUDIO | ANSWER_AUDIO);
   a2_->SetLocal(TestObserver::ANSWER, a2_->answer());
 
   ASSERT_EQ(a2_->pc->media()->ice_ctx()->GetControlling(),
             NrIceCtx::ICE_CONTROLLING);
 }
 
 // This test comes from Bug814038
 TEST_F(SignalingTest, ChromeOfferAnswer)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
-
   // This is captured SDP from an early interop attempt with Chrome.
   std::string offer =
     "v=0\r\n"
     "o=- 1713781661 2 IN IP4 127.0.0.1\r\n"
     "s=-\r\n"
     "t=0 0\r\n"
     "a=group:BUNDLE audio video\r\n"
 
@@ -2612,30 +2544,26 @@ TEST_F(SignalingTest, ChromeOfferAnswer)
     "a=ssrc:3012607008 mslabel:A5UL339RyGxT7zwgyF12BFqesxkmbUsaycp5\r\n"
     "a=ssrc:3012607008 label:A5UL339RyGxT7zwgyF12BFqesxkmbUsaycp5v0\r\n";
 
 
   std::cout << "Setting offer to:" << std::endl << indent(offer) << std::endl;
   a2_->SetRemote(TestObserver::OFFER, offer);
 
   std::cout << "Creating answer:" << std::endl;
-  a2_->CreateAnswer(constraints, offer, OFFER_AUDIO | ANSWER_AUDIO);
+  a2_->CreateAnswer(offer, OFFER_AUDIO | ANSWER_AUDIO);
 
   std::string answer = a2_->answer();
 }
 
 
 TEST_F(SignalingTest, FullChromeHandshake)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
-  constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-
   std::string offer = "v=0\r\n"
       "o=- 3835809413 2 IN IP4 127.0.0.1\r\n"
       "s=-\r\n"
       "t=0 0\r\n"
       "a=group:BUNDLE audio video\r\n"
       "a=msid-semantic: WMS ahheYQXHFU52slYMrWNtKUyHCtWZsOJgjlOH\r\n"
       "m=audio 1 RTP/SAVPF 103 104 111 0 8 107 106 105 13 126\r\n"
       "c=IN IP4 1.1.1.1\r\n"
@@ -2684,31 +2612,30 @@ TEST_F(SignalingTest, FullChromeHandshak
       "a=ssrc:3613537198 msid:ahheYQXHFU52slYMrWNtKUyHCtWZsOJgjlOH v0\r\n"
       "a=ssrc:3613537198 mslabel:ahheYQXHFU52slYMrWNtKUyHCtWZsOJgjlOH\r\n"
       "a=ssrc:3613537198 label:ahheYQXHFU52slYMrWNtKUyHCtWZsOJgjlOHv0\r\n";
 
   std::cout << "Setting offer to:" << std::endl << indent(offer) << std::endl;
   a2_->SetRemote(TestObserver::OFFER, offer);
 
   std::cout << "Creating answer:" << std::endl;
-  a2_->CreateAnswer(constraints, offer, OFFER_AUDIO | ANSWER_AUDIO);
+  a2_->CreateAnswer(offer, OFFER_AUDIO | ANSWER_AUDIO);
 
   std::cout << "Setting answer" << std::endl;
   a2_->SetLocal(TestObserver::ANSWER, a2_->answer());
 
   std::string answer = a2_->answer();
   ASSERT_NE(answer.find("111 opus/"), std::string::npos);
 }
 
 // Disabled pending resolution of bug 818640.
 TEST_F(SignalingTest, DISABLED_OfferAllDynamicTypes)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
   std::string offer;
   for (int i = 96; i < 128; i++)
   {
     std::stringstream ss;
     ss << i;
     std::cout << "Trying dynamic pt = " << i << std::endl;
     offer =
       "v=0\r\n"
@@ -2730,29 +2657,29 @@ TEST_F(SignalingTest, DISABLED_OfferAllD
 
       /*
       std::cout << "Setting offer to:" << std::endl
                 << indent(offer) << std::endl;
       */
       a2_->SetRemote(TestObserver::OFFER, offer);
 
       //std::cout << "Creating answer:" << std::endl;
-      a2_->CreateAnswer(constraints, offer, OFFER_AUDIO | ANSWER_AUDIO);
+      a2_->CreateAnswer(offer, OFFER_AUDIO | ANSWER_AUDIO);
 
       std::string answer = a2_->answer();
 
       ASSERT_NE(answer.find(ss.str() + " opus/"), std::string::npos);
   }
 
 }
 
 TEST_F(SignalingTest, OfferAnswerCheckDescriptions)
 {
-  sipcc::MediaConstraints constraints;
-  OfferAnswer(constraints, constraints, OFFER_AV | ANSWER_AV, true,
+  sipcc::OfferOptions options;
+  OfferAnswer(options, OFFER_AV | ANSWER_AV, true,
               SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
 
   std::cout << "Caller's Local Description: " << std::endl
             << indent(a1_->getLocalDescription()) << std::endl << std::endl;
 
   std::cout << "Caller's Remote Description: " << std::endl
             << indent(a1_->getRemoteDescription()) << std::endl << std::endl;
 
@@ -2764,18 +2691,18 @@ TEST_F(SignalingTest, OfferAnswerCheckDe
 
   // bug 1014486
   //ASSERT_EQ(a1_->getLocalDescription(),a2_->getRemoteDescription());
   ASSERT_EQ(a2_->getLocalDescription(),a1_->getRemoteDescription());
 }
 
 TEST_F(SignalingTest, CheckTrickleSdpChange)
 {
-  sipcc::MediaConstraints constraints;
-  OfferAnswerTrickle(constraints, constraints,
+  sipcc::OfferOptions options;
+  OfferAnswerTrickle(options,
                      SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
   std::cerr << "ICE handshake completed" << std::endl;
 
   a1_->CloseSendStreams();
   a2_->CloseReceiveStreams();
 
   std::cout << "Caller's Local Description: " << std::endl
             << indent(a1_->getLocalDescription()) << std::endl << std::endl;
@@ -2808,17 +2735,16 @@ TEST_F(SignalingTest, CheckTrickleSdpCha
   ASSERT_EQ(a2_->getLocalDescription(),a1_->getRemoteDescription());
   */
 }
 
 TEST_F(SignalingTest, ipAddrAnyOffer)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
   std::string offer =
     "v=0\r\n"
     "o=- 1 1 IN IP4 127.0.0.1\r\n"
     "s=-\r\n"
     "b=AS:64\r\n"
     "t=0 0\r\n"
     "a=fingerprint:sha-256 F3:FA:20:C0:CD:48:C4:5F:02:5F:A5:D3:21:D0:2D:48:"
       "7B:31:60:5C:5A:D8:0D:CD:78:78:6C:6D:CE:CC:0C:67\r\n"
@@ -2826,17 +2752,17 @@ TEST_F(SignalingTest, ipAddrAnyOffer)
     "c=IN IP4 0.0.0.0\r\n"
     "a=rtpmap:99 opus/48000/2\r\n"
     "a=ice-ufrag:cYuakxkEKH+RApYE\r\n"
     "a=ice-pwd:bwtpzLZD+3jbu8vQHvEa6Xuq\r\n"
     "a=sendrecv\r\n";
 
     a2_->SetRemote(TestObserver::OFFER, offer);
     ASSERT_TRUE(a2_->pObserver->state == TestObserver::stateSuccess);
-    a2_->CreateAnswer(constraints, offer, OFFER_AUDIO | ANSWER_AUDIO);
+    a2_->CreateAnswer(offer, OFFER_AUDIO | ANSWER_AUDIO);
     ASSERT_TRUE(a2_->pObserver->state == TestObserver::stateSuccess);
     std::string answer = a2_->answer();
     ASSERT_NE(answer.find("a=sendrecv"), std::string::npos);
 }
 
 static void CreateSDPForBigOTests(std::string& offer, const char *number) {
   offer =
     "v=0\r\n"
@@ -2899,18 +2825,18 @@ TEST_F(SignalingTest, BigOValuesTooBig)
                  PCImplSignalingState::SignalingStable);
   ASSERT_TRUE(a2_->pObserver->state == TestObserver::stateError);
 }
 
 TEST_F(SignalingTest, SetLocalAnswerInStable)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
-  CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  sipcc::OfferOptions options;
+  CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
 
   // The signaling state will remain "stable" because the
   // SetLocalDescription call fails.
   a1_->SetLocal(TestObserver::ANSWER, a1_->offer(), true,
                 PCImplSignalingState::SignalingStable);
   ASSERT_EQ(a1_->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kInvalidState);
 }
@@ -2922,130 +2848,130 @@ TEST_F(SignalingTest, SetRemoteAnswerInS
   // SetRemoteDescription call fails.
   a1_->SetRemote(TestObserver::ANSWER, strSampleSdpAudioVideoNoIce, true,
                 PCImplSignalingState::SignalingStable);
   ASSERT_EQ(a1_->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kInvalidState);
 }
 
 TEST_F(SignalingTest, SetLocalAnswerInHaveLocalOffer) {
-  sipcc::MediaConstraints constraints;
-  CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  sipcc::OfferOptions options;
+  CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
   a1_->SetLocal(TestObserver::OFFER, a1_->offer());
   ASSERT_EQ(a1_->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kNoError);
 
   // The signaling state will remain "have-local-offer" because the
   // SetLocalDescription call fails.
   a1_->SetLocal(TestObserver::ANSWER, a1_->offer(), true,
                 PCImplSignalingState::SignalingHaveLocalOffer);
   ASSERT_EQ(a1_->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kInvalidState);
 }
 
 TEST_F(SignalingTest, SetRemoteOfferInHaveLocalOffer) {
-  sipcc::MediaConstraints constraints;
-  CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  sipcc::OfferOptions options;
+  CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
   a1_->SetLocal(TestObserver::OFFER, a1_->offer());
   ASSERT_EQ(a1_->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kNoError);
 
   // The signaling state will remain "have-local-offer" because the
   // SetRemoteDescription call fails.
   a1_->SetRemote(TestObserver::OFFER, a1_->offer(), true,
                  PCImplSignalingState::SignalingHaveLocalOffer);
   ASSERT_EQ(a1_->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kInvalidState);
 }
 
 TEST_F(SignalingTest, SetLocalOfferInHaveRemoteOffer) {
-  sipcc::MediaConstraints constraints;
-  CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  sipcc::OfferOptions options;
+  CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
   a2_->SetRemote(TestObserver::OFFER, a1_->offer());
   ASSERT_EQ(a2_->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kNoError);
 
   // The signaling state will remain "have-remote-offer" because the
   // SetLocalDescription call fails.
   a2_->SetLocal(TestObserver::OFFER, a1_->offer(), true,
                 PCImplSignalingState::SignalingHaveRemoteOffer);
   ASSERT_EQ(a2_->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kInvalidState);
 }
 
 TEST_F(SignalingTest, SetRemoteAnswerInHaveRemoteOffer) {
-  sipcc::MediaConstraints constraints;
-  CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  sipcc::OfferOptions options;
+  CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
   a2_->SetRemote(TestObserver::OFFER, a1_->offer());
   ASSERT_EQ(a2_->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kNoError);
 
   // The signaling state will remain "have-remote-offer" because the
   // SetRemoteDescription call fails.
   a2_->SetRemote(TestObserver::ANSWER, a1_->offer(), true,
                PCImplSignalingState::SignalingHaveRemoteOffer);
   ASSERT_EQ(a2_->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kInvalidState);
 }
 
 // Disabled until the spec adds a failure callback to addStream
 TEST_F(SignalingTest, DISABLED_AddStreamInHaveLocalOffer) {
-  sipcc::MediaConstraints constraints;
-  CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  sipcc::OfferOptions options;
+  CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
   a1_->SetLocal(TestObserver::OFFER, a1_->offer());
   ASSERT_EQ(a1_->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kNoError);
   a1_->AddStream();
   ASSERT_EQ(a1_->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kInvalidState);
 }
 
 // Disabled until the spec adds a failure callback to removeStream
 TEST_F(SignalingTest, DISABLED_RemoveStreamInHaveLocalOffer) {
-  sipcc::MediaConstraints constraints;
-  CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  sipcc::OfferOptions options;
+  CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
   a1_->SetLocal(TestObserver::OFFER, a1_->offer());
   ASSERT_EQ(a1_->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kNoError);
   a1_->RemoveLastStreamAdded();
   ASSERT_EQ(a1_->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kInvalidState);
 }
 
 TEST_F(SignalingTest, AddCandidateInHaveLocalOffer) {
-  sipcc::MediaConstraints constraints;
-  CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  sipcc::OfferOptions options;
+  CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
   a1_->SetLocal(TestObserver::OFFER, a1_->offer());
   ASSERT_EQ(a1_->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kNoError);
   a1_->AddIceCandidate(strSampleCandidate.c_str(),
                       strSampleMid.c_str(), nSamplelevel, false);
   ASSERT_EQ(a1_->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kInvalidState);
 }
 
 TEST_F(SignalingAgentTest, CreateOffer) {
   CreateAgent();
-  sipcc::MediaConstraints constraints;
-  agent(0)->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  sipcc::OfferOptions options;
+  agent(0)->CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
   PR_Sleep(20000);
 }
 
 TEST_F(SignalingAgentTest, CreateOfferTrickleTestServer) {
   TestStunServer::GetInstance()->SetActive(false);
   TestStunServer::GetInstance()->SetResponseAddr(
       kBogusSrflxAddress, kBogusSrflxPort);
 
   CreateAgent(
       TestStunServer::GetInstance()->addr(),
       TestStunServer::GetInstance()->port(),
       false);
 
-  sipcc::MediaConstraints constraints;
-  agent(0)->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  sipcc::OfferOptions options;
+  agent(0)->CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
 
   // Verify that the bogus addr is not there.
   ASSERT_FALSE(agent(0)->OfferContains(kBogusSrflxAddress));
 
   // Now enable the STUN server.
   TestStunServer::GetInstance()->SetActive(true);
   agent(0)->WaitForGather();
 
@@ -3063,18 +2989,18 @@ TEST_F(SignalingAgentTest, CreateOfferSe
   TestStunServer::GetInstance()->SetResponseAddr(
       kBogusSrflxAddress, kBogusSrflxPort);
 
   CreateAgent(
       TestStunServer::GetInstance()->addr(),
       TestStunServer::GetInstance()->port(),
       false);
 
-  sipcc::MediaConstraints constraints;
-  agent(0)->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  sipcc::OfferOptions options;
+  agent(0)->CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
 
   // Verify that the bogus addr is not there.
   ASSERT_FALSE(agent(0)->OfferContains(kBogusSrflxAddress));
 
   // Now enable the STUN server.
   TestStunServer::GetInstance()->SetActive(true);
   agent(0)->WaitForGather();
 
@@ -3105,18 +3031,17 @@ TEST_F(SignalingAgentTest, CreateAnswerS
       false);
 
   std::string offer(strG711SdpOffer);
   agent(0)->SetRemote(TestObserver::OFFER, offer, true,
                  PCImplSignalingState::SignalingHaveRemoteOffer);
   ASSERT_EQ(agent(0)->pObserver->lastStatusCode,
             sipcc::PeerConnectionImpl::kNoError);
 
-  sipcc::MediaConstraints constraints;
-  agent(0)->CreateAnswer(constraints, offer, ANSWER_AUDIO, DONT_CHECK_AUDIO);
+  agent(0)->CreateAnswer(offer, ANSWER_AUDIO, DONT_CHECK_AUDIO);
 
   // Verify that the bogus addr is not there.
   ASSERT_FALSE(agent(0)->AnswerContains(kBogusSrflxAddress));
 
   // Now enable the STUN server.
   TestStunServer::GetInstance()->SetActive(true);
   agent(0)->WaitForGather();
 
@@ -3157,17 +3082,17 @@ TEST_F(SignalingAgentTest, CreateNoInit)
 
 /*
  * Test for Bug 843595
  */
 TEST_F(SignalingTest, missingUfrag)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
   std::string offer =
     "v=0\r\n"
     "o=Mozilla-SIPUA 2208 0 IN IP4 0.0.0.0\r\n"
     "s=SIP Call\r\n"
     "t=0 0\r\n"
     "a=ice-pwd:4450d5a4a5f097855c16fa079893be18\r\n"
     "a=fingerprint:sha-256 23:9A:2E:43:94:42:CF:46:68:FC:62:F9:F4:48:61:DB:"
       "2F:8C:C9:FF:6B:25:54:9D:41:09:EF:83:A8:19:FC:B6\r\n"
@@ -3199,38 +3124,38 @@ TEST_F(SignalingTest, missingUfrag)
     "m=application 54054 DTLS/SCTP 5000\r\n"
     "c=IN IP4 77.9.79.167\r\n"
     "a=fmtp:HuRUu]Dtcl\\zM,7(OmEU%O$gU]x/z\tD protocol=webrtc-datachannel;"
       "streams=16\r\n"
     "a=sendrecv\r\n";
 
   // Need to create an offer, since that's currently required by our
   // FSM. This may change in the future.
-  a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
+  a1_->CreateOffer(options, OFFER_AV, SHOULD_SENDRECV_AV);
   a1_->SetLocal(TestObserver::OFFER, offer, true);
   // We now detect the missing ICE parameters at SetRemoteDescription
   a2_->SetRemote(TestObserver::OFFER, offer, true,
                  PCImplSignalingState::SignalingStable);
   ASSERT_TRUE(a2_->pObserver->state == TestObserver::stateError);
 }
 
 TEST_F(SignalingTest, AudioOnlyCalleeNoRtcpMux)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
-
-  a1_->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  sipcc::OfferOptions options;
+
+  a1_->CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
   a1_->SetLocal(TestObserver::OFFER, a1_->offer(), false);
   ParsedSDP sdpWrapper(a1_->offer());
   sdpWrapper.DeleteLine("a=rtcp-mux");
   std::cout << "Modified SDP " << std::endl
             << indent(sdpWrapper.getSdp()) << std::endl;
   a2_->SetRemote(TestObserver::OFFER, sdpWrapper.getSdp(), false);
-  a2_->CreateAnswer(constraints, sdpWrapper.getSdp(),
+  a2_->CreateAnswer(sdpWrapper.getSdp(),
     OFFER_AUDIO | ANSWER_AUDIO);
   a2_->SetLocal(TestObserver::ANSWER, a2_->answer(), false);
   a1_->SetRemote(TestObserver::ANSWER, a2_->answer(), false);
 
   // Answer should not have a=rtcp-mux
   ASSERT_EQ(a2_->getLocalDescription().find("\r\na=rtcp-mux"),
             std::string::npos);
 
@@ -3255,26 +3180,26 @@ TEST_F(SignalingTest, AudioOnlyCalleeNoR
   // The first Remote pipeline gets stored at 1
   a2_->CheckMediaPipeline(0, 1, 0);
 }
 
 TEST_F(SignalingTest, FullCallAudioNoMuxVideoMux)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
-
-  a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
+  sipcc::OfferOptions options;
+
+  a1_->CreateOffer(options, OFFER_AV, SHOULD_SENDRECV_AV);
   a1_->SetLocal(TestObserver::OFFER, a1_->offer(), false);
   ParsedSDP sdpWrapper(a1_->offer());
   sdpWrapper.DeleteLine("a=rtcp-mux");
   std::cout << "Modified SDP " << std::endl
             << indent(sdpWrapper.getSdp()) << std::endl;
   a2_->SetRemote(TestObserver::OFFER, sdpWrapper.getSdp(), false);
-  a2_->CreateAnswer(constraints, sdpWrapper.getSdp(), OFFER_AV | ANSWER_AV);
+  a2_->CreateAnswer(sdpWrapper.getSdp(), OFFER_AV | ANSWER_AV);
   a2_->SetLocal(TestObserver::ANSWER, a2_->answer(), false);
   a1_->SetRemote(TestObserver::ANSWER, a2_->answer(), false);
 
   // Answer should have only one a=rtcp-mux line
   size_t match = a2_->getLocalDescription().find("\r\na=rtcp-mux");
   if (fRtcpMux) {
     ASSERT_NE(match, std::string::npos);
     match = a2_->getLocalDescription().find("\r\na=rtcp-mux", match + 1);
@@ -3310,18 +3235,18 @@ TEST_F(SignalingTest, FullCallAudioNoMux
   // Now check video mux.
   a2_->CheckMediaPipeline(0, 2, (fRtcpMux ?  PIPELINE_RTCP_MUX : 0) |
     PIPELINE_VIDEO | PIPELINE_RTCP_NACK, VideoSessionConduit::FrameRequestPli);
 }
 
 TEST_F(SignalingTest, RtcpFbInOffer)
 {
   EnsureInit();
-  sipcc::MediaConstraints constraints;
-  a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
+  sipcc::OfferOptions options;
+  a1_->CreateOffer(options, OFFER_AV, SHOULD_SENDRECV_AV);
   const char *expected[] = { "nack", "nack pli", "ccm fir" };
   CheckRtcpFbSdp(a1_->offer(), ARRAY_TO_SET(std::string, expected));
 }
 
 TEST_F(SignalingTest, RtcpFbInAnswer)
 {
   const char *feedbackTypes[] = { "nack", "nack pli", "ccm fir" };
   TestRtcpFb(ARRAY_TO_SET(std::string, feedbackTypes),
@@ -3386,35 +3311,35 @@ TEST_F(SignalingTest, RtcpFbNoFeedback)
 }
 
 // In this test we will change the offer SDP's a=setup value
 // from actpass to passive.  This will make the answer do active.
 TEST_F(SignalingTest, AudioCallForceDtlsRoles)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
   size_t match;
 
-  a1_->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  a1_->CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
 
   // By default the offer should give actpass
   std::string offer(a1_->offer());
   match = offer.find("\r\na=setup:actpass");
   ASSERT_NE(match, std::string::npos);
   // Now replace the actpass with passive so that the answer will
   // return active
   offer.replace(match, strlen("\r\na=setup:actpass"),
     "\r\na=setup:passive");
   std::cout << "Modified SDP " << std::endl
             << indent(offer) << std::endl;
 
   a1_->SetLocal(TestObserver::OFFER, offer.c_str(), false);
   a2_->SetRemote(TestObserver::OFFER, offer.c_str(), false);
-  a2_->CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
+  a2_->CreateAnswer(offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
 
   // Now the answer should contain a=setup:active
   std::string answer(a2_->answer());
   match = answer.find("\r\na=setup:active");
   ASSERT_NE(match, std::string::npos);
 
   // This should setup the DTLS with the same roles
   // as the regular tests above.
@@ -3436,35 +3361,35 @@ TEST_F(SignalingTest, AudioCallForceDtls
 }
 
 // In this test we will change the offer SDP's a=setup value
 // from actpass to active.  This will make the answer do passive
 TEST_F(SignalingTest, AudioCallReverseDtlsRoles)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
   size_t match;
 
-  a1_->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  a1_->CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
 
   // By default the offer should give actpass
   std::string offer(a1_->offer());
   match = offer.find("\r\na=setup:actpass");
   ASSERT_NE(match, std::string::npos);
   // Now replace the actpass with active so that the answer will
   // return passive
   offer.replace(match, strlen("\r\na=setup:actpass"),
     "\r\na=setup:active");
   std::cout << "Modified SDP " << std::endl
             << indent(offer) << std::endl;
 
   a1_->SetLocal(TestObserver::OFFER, offer.c_str(), false);
   a2_->SetRemote(TestObserver::OFFER, offer.c_str(), false);
-  a2_->CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
+  a2_->CreateAnswer(offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
 
   // Now the answer should contain a=setup:passive
   std::string answer(a2_->answer());
   match = answer.find("\r\na=setup:passive");
   ASSERT_NE(match, std::string::npos);
 
   // This should setup the DTLS with the opposite roles
   // than the regular tests above.
@@ -3487,28 +3412,28 @@ TEST_F(SignalingTest, AudioCallReverseDt
 
 // In this test we will change the answer SDP's a=setup value
 // from active to passive.  This will make both sides do
 // active and should not connect.
 TEST_F(SignalingTest, AudioCallMismatchDtlsRoles)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
   size_t match;
 
-  a1_->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  a1_->CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
 
   // By default the offer should give actpass
   std::string offer(a1_->offer());
   match = offer.find("\r\na=setup:actpass");
   ASSERT_NE(match, std::string::npos);
   a1_->SetLocal(TestObserver::OFFER, offer.c_str(), false);
   a2_->SetRemote(TestObserver::OFFER, offer.c_str(), false);
-  a2_->CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
+  a2_->CreateAnswer(offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
 
   // Now the answer should contain a=setup:active
   std::string answer(a2_->answer());
   match = answer.find("\r\na=setup:active");
   ASSERT_NE(match, std::string::npos);
 
   // Now replace the active with passive so that the offerer will
   // also do active.
@@ -3537,34 +3462,34 @@ TEST_F(SignalingTest, AudioCallMismatchD
 
 // In this test we will change the offer SDP's a=setup value
 // from actpass to garbage.  It should ignore the garbage value
 // and respond with setup:active
 TEST_F(SignalingTest, AudioCallGarbageSetup)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
   size_t match;
 
-  a1_->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  a1_->CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
 
   // By default the offer should give actpass
   std::string offer(a1_->offer());
   match = offer.find("\r\na=setup:actpass");
   ASSERT_NE(match, std::string::npos);
   // Now replace the actpass with a garbage value
   offer.replace(match, strlen("\r\na=setup:actpass"),
     "\r\na=setup:G4rb4g3V4lu3");
   std::cout << "Modified SDP " << std::endl
             << indent(offer) << std::endl;
 
   a1_->SetLocal(TestObserver::OFFER, offer.c_str(), false);
   a2_->SetRemote(TestObserver::OFFER, offer.c_str(), false);
-  a2_->CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
+  a2_->CreateAnswer(offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
 
   // Now the answer should contain a=setup:active
   std::string answer(a2_->answer());
   match = answer.find("\r\na=setup:active");
   ASSERT_NE(match, std::string::npos);
 
   // This should setup the DTLS with the same roles
   // as the regular tests above.
@@ -3586,33 +3511,33 @@ TEST_F(SignalingTest, AudioCallGarbageSe
 }
 
 // In this test we will change the offer SDP to remove the
 // a=setup line.  Answer should respond with a=setup:active.
 TEST_F(SignalingTest, AudioCallOfferNoSetupOrConnection)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
   size_t match;
 
-  a1_->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  a1_->CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
 
   // By default the offer should give setup:actpass
   std::string offer(a1_->offer());
   match = offer.find("\r\na=setup:actpass");
   ASSERT_NE(match, std::string::npos);
   // Remove the a=setup line
   offer.replace(match, strlen("\r\na=setup:actpass"), "");
   std::cout << "Modified SDP " << std::endl
             << indent(offer) << std::endl;
 
   a1_->SetLocal(TestObserver::OFFER, offer.c_str(), false);
   a2_->SetRemote(TestObserver::OFFER, offer.c_str(), false);
-  a2_->CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
+  a2_->CreateAnswer(offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
 
   // Now the answer should contain a=setup:active
   std::string answer(a2_->answer());
   match = answer.find("\r\na=setup:active");
   ASSERT_NE(match, std::string::npos);
 
   // This should setup the DTLS with the same roles
   // as the regular tests above.
@@ -3635,29 +3560,29 @@ TEST_F(SignalingTest, AudioCallOfferNoSe
 
 // In this test we will change the answer SDP to remove the
 // a=setup line.  ICE should still connect since active will
 // be assumed.
 TEST_F(SignalingTest, AudioCallAnswerNoSetupOrConnection)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
   size_t match;
 
-  a1_->CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
+  a1_->CreateOffer(options, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO);
 
   // By default the offer should give setup:actpass
   std::string offer(a1_->offer());
   match = offer.find("\r\na=setup:actpass");
   ASSERT_NE(match, std::string::npos);
 
   a1_->SetLocal(TestObserver::OFFER, offer.c_str(), false);
   a2_->SetRemote(TestObserver::OFFER, offer.c_str(), false);
-  a2_->CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
+  a2_->CreateAnswer(offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO);
 
   // Now the answer should contain a=setup:active
   std::string answer(a2_->answer());
   match = answer.find("\r\na=setup:active");
   ASSERT_NE(match, std::string::npos);
   // Remove the a=setup line
   answer.replace(match, strlen("\r\na=setup:active"), "");
   std::cout << "Modified SDP " << std::endl
@@ -3682,18 +3607,18 @@ TEST_F(SignalingTest, AudioCallAnswerNoS
   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
 }
 
 
 TEST_F(SignalingTest, FullCallRealTrickle)
 {
   wait_for_gather_ = false;
 
-  sipcc::MediaConstraints constraints;
-  OfferAnswer(constraints, constraints, OFFER_AV | ANSWER_AV,
+  sipcc::OfferOptions options;
+  OfferAnswer(options, OFFER_AV | ANSWER_AV,
               true, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
 
   // Wait for some data to get written
   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
 
   a1_->CloseSendStreams();
   a2_->CloseReceiveStreams();
@@ -3701,18 +3626,18 @@ TEST_F(SignalingTest, FullCallRealTrickl
   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
 }
 
 TEST_F(SignalingTest, FullCallRealTrickleTestServer)
 {
   wait_for_gather_ = false;
   SetTestStunServer();
 
-  sipcc::MediaConstraints constraints;
-  OfferAnswer(constraints, constraints, OFFER_AV | ANSWER_AV,
+  sipcc::OfferOptions options;
+  OfferAnswer(options, OFFER_AV | ANSWER_AV,
               true, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
 
   TestStunServer::GetInstance()->SetActive(true);
 
   // Wait for some data to get written
   ASSERT_TRUE_WAIT(a1_->GetPacketsSent(0) >= 40 &&
                    a2_->GetPacketsReceived(0) >= 40, kDefaultTimeout * 2);
 
@@ -3721,17 +3646,17 @@ TEST_F(SignalingTest, FullCallRealTrickl
   ASSERT_GE(a1_->GetPacketsSent(0), 40);
   ASSERT_GE(a2_->GetPacketsReceived(0), 40);
 }
 
 TEST_F(SignalingTest, hugeSdp)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
   std::string offer =
     "v=0\r\n"
     "o=- 1109973417102828257 2 IN IP4 127.0.0.1\r\n"
     "s=-\r\n"
     "t=0 0\r\n"
     "a=group:BUNDLE audio video\r\n"
     "a=msid-semantic: WMS 1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIP\r\n"
     "m=audio 32952 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126\r\n"
@@ -3813,103 +3738,103 @@ TEST_F(SignalingTest, hugeSdp)
     "a=rtcp-fb:100 goog-remb\r\n"
     "a=rtpmap:116 red/90000\r\n"
     "a=rtpmap:117 ulpfec/90000\r\n"
     "a=ssrc:54724160 cname:mKDNt7SQf6pwDlIn\r\n"
     "a=ssrc:54724160 msid:1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIP 1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIPv0\r\n"
     "a=ssrc:54724160 mslabel:1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIP\r\n"
     "a=ssrc:54724160 label:1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIPv0\r\n";
 
-  a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
+  a1_->CreateOffer(options, OFFER_AV, SHOULD_SENDRECV_AV);
   a1_->SetLocal(TestObserver::OFFER, offer, true);
 
   a2_->SetRemote(TestObserver::OFFER, offer, true);
   ASSERT_GE(a2_->getRemoteDescription().length(), 4096U);
-  a2_->CreateAnswer(constraints, offer, OFFER_AV);
+  a2_->CreateAnswer(offer, OFFER_AV);
 }
 
 // Test max_fs and max_fr prefs have proper impact on SDP offer
 TEST_F(SignalingTest, MaxFsFrInOffer)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
 
   nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
   ASSERT_TRUE(prefs);
   FsFrPrefClearer prefClearer(prefs);
 
   SetMaxFsFr(prefs, 300, 30);
 
-  a1_->CreateOffer(constraints, OFFER_AV, SHOULD_CHECK_AV);
+  a1_->CreateOffer(options, OFFER_AV, SHOULD_CHECK_AV);
 
   // Verify that SDP contains correct max-fs and max-fr
   CheckMaxFsFrSdp(a1_->offer(), 120, 300, 30);
 }
 
 // Test max_fs and max_fr prefs have proper impact on SDP answer
 TEST_F(SignalingTest, MaxFsFrInAnswer)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
 
   nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
   ASSERT_TRUE(prefs);
   FsFrPrefClearer prefClearer(prefs);
 
   // We don't want max_fs and max_fr prefs impact SDP at this moment
   SetMaxFsFr(prefs, 0, 0);
 
-  a1_->CreateOffer(constraints, OFFER_AV, SHOULD_CHECK_AV);
+  a1_->CreateOffer(options, OFFER_AV, SHOULD_CHECK_AV);
 
   // SDP should not contain max-fs and max-fr here
   CheckMaxFsFrSdp(a1_->offer(), 120, 0, 0);
 
   a2_->SetRemote(TestObserver::OFFER, a1_->offer());
 
   SetMaxFsFr(prefs, 600, 60);
 
-  a2_->CreateAnswer(constraints, a1_->offer(), OFFER_AV | ANSWER_AV);
+  a2_->CreateAnswer(a1_->offer(), OFFER_AV | ANSWER_AV);
 
   // Verify that SDP contains correct max-fs and max-fr
   CheckMaxFsFrSdp(a2_->answer(), 120, 600, 60);
 }
 
 // Test SDP offer has proper impact on callee's codec configuration
 TEST_F(SignalingTest, MaxFsFrCalleeCodec)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
 
   nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
   ASSERT_TRUE(prefs);
   FsFrPrefClearer prefClearer(prefs);
 
   // We don't want max_fs and max_fr prefs impact SDP at this moment
   SetMaxFsFr(prefs, 0, 0);
 
-  a1_->CreateOffer(constraints, OFFER_AV, SHOULD_CHECK_AV);
+  a1_->CreateOffer(options, OFFER_AV, SHOULD_CHECK_AV);
 
   ParsedSDP sdpWrapper(a1_->offer());
 
   sdpWrapper.ReplaceLine("a=rtpmap:120",
     "a=rtpmap:120 VP8/90000\r\na=fmtp:120 max-fs=300;max-fr=30\r\n");
 
   std::cout << "Modified SDP " << std::endl
             << indent(sdpWrapper.getSdp()) << std::endl;
 
   // Double confirm that SDP offer contains correct max-fs and max-fr
   CheckMaxFsFrSdp(sdpWrapper.getSdp(), 120, 300, 30);
 
   a1_->SetLocal(TestObserver::OFFER, sdpWrapper.getSdp());
   a2_->SetRemote(TestObserver::OFFER, sdpWrapper.getSdp());
 
-  a2_->CreateAnswer(constraints, sdpWrapper.getSdp(), OFFER_AV | ANSWER_AV);
+  a2_->CreateAnswer(sdpWrapper.getSdp(), OFFER_AV | ANSWER_AV);
 
   // SDP should not contain max-fs and max-fr here
   CheckMaxFsFrSdp(a2_->answer(), 120, 0, 0);
 
   a2_->SetLocal(TestObserver::ANSWER, a2_->answer());
   a1_->SetRemote(TestObserver::ANSWER, a2_->answer());
 
   ASSERT_TRUE_WAIT(a1_->IceCompleted() == true, kDefaultTimeout);
@@ -3930,30 +3855,30 @@ TEST_F(SignalingTest, MaxFsFrCalleeCodec
   ASSERT_EQ(video_conduit->SendingMaxFr(), (unsigned short) 30);
 }
 
 // Test SDP answer has proper impact on caller's codec configuration
 TEST_F(SignalingTest, MaxFsFrCallerCodec)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
 
   nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
   ASSERT_TRUE(prefs);
   FsFrPrefClearer prefClearer(prefs);
 
   // We don't want max_fs and max_fr prefs impact SDP at this moment
   SetMaxFsFr(prefs, 0, 0);
 
-  a1_->CreateOffer(constraints, OFFER_AV, SHOULD_CHECK_AV);
+  a1_->CreateOffer(options, OFFER_AV, SHOULD_CHECK_AV);
   a1_->SetLocal(TestObserver::OFFER, a1_->offer());
   a2_->SetRemote(TestObserver::OFFER, a1_->offer());
 
-  a2_->CreateAnswer(constraints, a1_->offer(), OFFER_AV | ANSWER_AV);
+  a2_->CreateAnswer(a1_->offer(), OFFER_AV | ANSWER_AV);
 
   ParsedSDP sdpWrapper(a2_->answer());
 
   sdpWrapper.ReplaceLine("a=rtpmap:120",
     "a=rtpmap:120 VP8/90000\r\na=fmtp:120 max-fs=600;max-fr=60\r\n");
 
   std::cout << "Modified SDP " << std::endl
             << indent(sdpWrapper.getSdp()) << std::endl;
@@ -3981,19 +3906,19 @@ TEST_F(SignalingTest, MaxFsFrCallerCodec
   ASSERT_EQ(video_conduit->SendingMaxFs(), (unsigned short) 600);
   ASSERT_EQ(video_conduit->SendingMaxFr(), (unsigned short) 60);
 }
 
 // Validate offer with multiple video codecs
 TEST_F(SignalingTest, ValidateMultipleVideoCodecsInOffer)
 {
   EnsureInit();
-  sipcc::MediaConstraints constraints;
-
-  a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
+  sipcc::OfferOptions options;
+
+  a1_->CreateOffer(options, OFFER_AV, SHOULD_SENDRECV_AV);
   std::string offer = a1_->offer();
 
   ASSERT_NE(offer.find("RTP/SAVPF 120 126 97"), std::string::npos);
   ASSERT_NE(offer.find("a=rtpmap:120 VP8/90000"), std::string::npos);
   ASSERT_NE(offer.find("a=rtpmap:126 H264/90000"), std::string::npos);
   ASSERT_NE(offer.find("a=rtpmap:97 H264/90000"), std::string::npos);
   ASSERT_NE(offer.find("a=fmtp:126 profile-level-id="), std::string::npos);
   ASSERT_NE(offer.find("a=fmtp:97 profile-level-id="), std::string::npos);
@@ -4008,20 +3933,20 @@ TEST_F(SignalingTest, ValidateMultipleVi
   ASSERT_NE(offer.find("a=rtcp-fb:97 ccm fir"), std::string::npos);
 }
 
 // Remove VP8 from offer and check that answer negotiates H264 P1 correctly
 TEST_F(SignalingTest, RemoveVP8FromOfferWithP1First)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
   size_t match;
 
-  a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
+  a1_->CreateOffer(options, OFFER_AV, SHOULD_SENDRECV_AV);
 
   // Remove VP8 from offer
   std::string offer = a1_->offer();
   offer.replace(match = offer.find("RTP/SAVPF 120"),
     strlen("RTP/SAVPF 126"), "RTP/SAVPF");
   ParsedSDP sdpWrapper(offer);
   sdpWrapper.DeleteAllLines("a=rtcp-fb:120");
   sdpWrapper.DeleteLine("a=rtpmap:120");
@@ -4029,18 +3954,18 @@ TEST_F(SignalingTest, RemoveVP8FromOffer
   std::cout << "Modified SDP " << std::endl
             << indent(sdpWrapper.getSdp()) << std::endl;
 
   // P1 should be offered first
   ASSERT_NE(offer.find("RTP/SAVPF 126"), std::string::npos);
 
   a1_->SetLocal(TestObserver::OFFER, sdpWrapper.getSdp());
   a2_->SetRemote(TestObserver::OFFER, sdpWrapper.getSdp(), false);
-  a2_->CreateAnswer(constraints, sdpWrapper.getSdp(),
-                   OFFER_AV|ANSWER_AV, SHOULD_SENDRECV_AV);
+  a2_->CreateAnswer(sdpWrapper.getSdp(),
+                    OFFER_AV|ANSWER_AV, SHOULD_SENDRECV_AV);
 
   std::string answer(a2_->answer());
 
   // Validate answer SDP
   ASSERT_NE(answer.find("RTP/SAVPF 126"), std::string::npos);
   ASSERT_NE(answer.find("a=rtpmap:126 H264/90000"), std::string::npos);
   ASSERT_NE(answer.find("a=rtcp-fb:126 nack"), std::string::npos);
   ASSERT_NE(answer.find("a=rtcp-fb:126 nack pli"), std::string::npos);
@@ -4052,20 +3977,20 @@ TEST_F(SignalingTest, RemoveVP8FromOffer
   ASSERT_EQ(answer.find("a=rtcp-fb:97"), std::string::npos);
 }
 
 // Insert H.264 before VP8 in Offer, check answer selects H.264
 TEST_F(SignalingTest, OfferWithH264BeforeVP8)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
   size_t match;
 
-  a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
+  a1_->CreateOffer(options, OFFER_AV, SHOULD_SENDRECV_AV);
 
   // Swap VP8 and P1 in offer
   std::string offer = a1_->offer();
   offer.replace(match = offer.find("RTP/SAVPF 120 126 97"),
     strlen("RTP/SAVPF 126 120 97"), "RTP/SAVPF 126 120 97");
 
   offer.replace(match = offer.find("a=rtpmap:126 H264/90000"),
     strlen("a=rtpmap:120 VP8/90000"), "a=rtpmap:120 VP8/90000");
@@ -4089,18 +4014,17 @@ TEST_F(SignalingTest, OfferWithH264Befor
   std::cout << "Modified SDP " << std::endl
             << indent(offer) << std::endl;
 
   // P1 should be offered first
   ASSERT_NE(offer.find("RTP/SAVPF 126 120 97"), std::string::npos);
 
   a1_->SetLocal(TestObserver::OFFER, offer);
   a2_->SetRemote(TestObserver::OFFER, offer, false);
-  a2_->CreateAnswer(constraints, offer,
-                   OFFER_AV|ANSWER_AV, SHOULD_SENDRECV_AV);
+  a2_->CreateAnswer(offer, OFFER_AV|ANSWER_AV, SHOULD_SENDRECV_AV);
 
   std::string answer(a2_->answer());
 
   // Validate answer SDP
   ASSERT_NE(answer.find("RTP/SAVPF 126"), std::string::npos);
   ASSERT_NE(answer.find("a=rtpmap:126 H264/90000"), std::string::npos);
   ASSERT_NE(answer.find("a=rtcp-fb:126 nack"), std::string::npos);
   ASSERT_NE(answer.find("a=rtcp-fb:126 nack pli"), std::string::npos);
@@ -4112,20 +4036,20 @@ TEST_F(SignalingTest, OfferWithH264Befor
   ASSERT_EQ(answer.find("a=rtcp-fb:97"), std::string::npos);
 }
 
 // Remove H.264 P1 and VP8 from offer, check answer negotiates H.264 P0
 TEST_F(SignalingTest, OfferWithOnlyH264P0)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
+  sipcc::OfferOptions options;
   size_t match;
 
-  a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
+  a1_->CreateOffer(options, OFFER_AV, SHOULD_SENDRECV_AV);
 
   // Remove VP8 from offer
   std::string offer = a1_->offer();
   offer.replace(match = offer.find("RTP/SAVPF 120 126"),
     strlen("RTP/SAVPF 120 126"), "RTP/SAVPF");
   ParsedSDP sdpWrapper(offer);
   sdpWrapper.DeleteAllLines("a=rtcp-fb:120");
   sdpWrapper.DeleteLine("a=rtpmap:120");
@@ -4141,18 +4065,17 @@ TEST_F(SignalingTest, OfferWithOnlyH264P
   ASSERT_EQ(offer.find("a=rtpmap:126 H264/90000"), std::string::npos);
   ASSERT_EQ(offer.find("a=rtpmap:120 VP8/90000"), std::string::npos);
 
   // P0 should be offered first
   ASSERT_NE(offer.find("RTP/SAVPF 97"), std::string::npos);
 
   a1_->SetLocal(TestObserver::OFFER, offer);
   a2_->SetRemote(TestObserver::OFFER, offer, false);
-  a2_->CreateAnswer(constraints, offer,
-                   OFFER_AV|ANSWER_AV, SHOULD_SENDRECV_AV);
+  a2_->CreateAnswer(offer, OFFER_AV|ANSWER_AV, SHOULD_SENDRECV_AV);
 
   std::string answer(a2_->answer());
 
   // validate answer SDP
   ASSERT_NE(answer.find("RTP/SAVPF 97"), std::string::npos);
   ASSERT_NE(answer.find("a=rtpmap:97 H264/90000"), std::string::npos);
   ASSERT_NE(answer.find("a=rtcp-fb:97 nack"), std::string::npos);
   ASSERT_NE(answer.find("a=rtcp-fb:97 nack pli"), std::string::npos);
@@ -4165,23 +4088,22 @@ TEST_F(SignalingTest, OfferWithOnlyH264P
 }
 
 // Test negotiating an answer which has only H.264 P1
 // Which means replace VP8 with H.264 P1 in answer
 TEST_F(SignalingTest, AnswerWithoutVP8)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
-
-  a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
+  sipcc::OfferOptions options;
+
+  a1_->CreateOffer(options, OFFER_AV, SHOULD_SENDRECV_AV);
   a1_->SetLocal(TestObserver::OFFER, a1_->offer());
   a2_->SetRemote(TestObserver::OFFER, a1_->offer(), false);
-  a2_->CreateAnswer(constraints, a1_->offer(),
-                   OFFER_AV|ANSWER_AV, SHOULD_SENDRECV_AV);
+  a2_->CreateAnswer(a1_->offer(), OFFER_AV|ANSWER_AV, SHOULD_SENDRECV_AV);
 
   std::string answer(a2_->answer());
 
   // Ensure answer has VP8
   ASSERT_NE(answer.find("\r\na=rtpmap:120 VP8/90000"), std::string::npos);
 
   // Replace VP8 with H.264 P1
   ParsedSDP sdpWrapper(a2_->answer());
@@ -4215,22 +4137,21 @@ TEST_F(SignalingTest, AnswerWithoutVP8)
   a2_->CloseReceiveStreams();
 }
 
 // Test using a non preferred dynamic video payload type on answer negotiation
 TEST_F(SignalingTest, UseNonPrefferedPayloadTypeOnAnswer)
 {
   EnsureInit();
 
-  sipcc::MediaConstraints constraints;
-  a1_->CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
+  sipcc::OfferOptions options;
+  a1_->CreateOffer(options, OFFER_AV, SHOULD_SENDRECV_AV);
   a1_->SetLocal(TestObserver::OFFER, a1_->offer());
   a2_->SetRemote(TestObserver::OFFER, a1_->offer(), false);
-  a2_->CreateAnswer(constraints, a1_->offer(),
-                   OFFER_AV|ANSWER_AV, SHOULD_SENDRECV_AV);
+  a2_->CreateAnswer(a1_->offer(), OFFER_AV|ANSWER_AV, SHOULD_SENDRECV_AV);
 
   std::string answer(a2_->answer());
 
   // Ensure answer has VP8
   ASSERT_NE(answer.find("\r\na=rtpmap:120 VP8/90000"), std::string::npos);
 
   // Replace VP8 Payload Type with a non preferred value
   answer.replace(answer.find("RTP/SAVPF 120"),