chromium/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-applyConstraints-remoteVideoTrack.html

<!DOCTYPE html>
<html>
<head>
<title>RTCPeerConnection-ontrack</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<script>

const FRAME_RATE_ERROR = 0.5;
const SETTINGS_CHANGE_RATE = 0.8;

promise_test(async t => {
  const localPc = new RTCPeerConnection();
  t.add_cleanup(() => localPc.close());
  const remotePc = new RTCPeerConnection();
  t.add_cleanup(() => remotePc.close());

  const localStream = await navigator.mediaDevices.getUserMedia({video:true});
  const [localTrack] = localStream.getTracks();
  t.add_cleanup(() => localTrack.stop());
  let remoteTrack = null;
  let remoteStream = null;
  localPc.addTrack(localTrack, localStream);
  remotePc.ontrack = e => {
    remoteTrack = e.track;
    remoteStream = e.stream;
  };

  exchangeIceCandidates(localPc, remotePc);
  const offer = await localPc.createOffer();
  await localPc.setLocalDescription(offer);
  await remotePc.setRemoteDescription(offer);
  const answer = await remotePc.createAnswer();
  await remotePc.setLocalDescription(answer);
  await localPc.setRemoteDescription(answer);

  // Get initial settings once remote side starts receiving frames.
  const settings = await new Promise((resolve) => {
    const checkFirstFrameSettings = settings => 'frameRate' in settings;
    listenForFrame(remoteTrack, resolve, checkFirstFrameSettings);
  });

  const constraints = {
    frameRate: settings.frameRate * SETTINGS_CHANGE_RATE,
    width: settings.width * SETTINGS_CHANGE_RATE,
    height: settings.height * SETTINGS_CHANGE_RATE
  };
  remoteTrack.applyConstraints(constraints);

  // Wait for remote side to receive frames with constraints applied.
  await new Promise((resolve) => {
    const checkConstrainedSettings = settings =>
        settings.frameRate - constraints.frameRate <= FRAME_RATE_ERROR &&
        settings.width == constraints.width &&
        settings.height == constraints.height;
    listenForFrame(remoteTrack, resolve, checkConstrainedSettings);
  });
}, 'applyConstraints for remote video track.');

function listenForFrame(track, resolve, checkSettings) {
  const settings = track.getSettings();
  if (checkSettings(settings))
    resolve(settings);
  setTimeout(() => listenForFrame(track, resolve, checkSettings), 0);
}

function exchangeIceCandidates(pc1, pc2) {
  function doExchange(localPc, remotePc) {
    localPc.addEventListener('icecandidate', event => {
      const { candidate } = event;
      if(candidate && remotePc.signalingState !== 'closed') {
        remotePc.addIceCandidate(candidate);
      }
    });
  }
  doExchange(pc1, pc2);
  doExchange(pc2, pc1);
}

</script>
</body>
</html>