| <!doctype html> | 
 | <meta charset=utf-8> | 
 | <title>RTCRtpTransceiver.prototype.setCodecPreferences</title> | 
 | <script src="/resources/testharness.js"></script> | 
 | <script src="/resources/testharnessreport.js"></script> | 
 | <script> | 
 |  'use strict'; | 
 |  | 
 |  // Test is based on the following editor draft: | 
 |  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html | 
 |  | 
 |  /* | 
 |  5.4. RTCRtpTransceiver Interface | 
 |  interface RTCRtpTransceiver { | 
 |  ... | 
 |  void setCodecPreferences(sequence<RTCRtpCodecCapability> codecs); | 
 |  }; | 
 |  | 
 |  setCodecPreferences | 
 |  - Setting codecs to an empty sequence resets codec preferences to any | 
 |  default value. | 
 |  | 
 |  - The codecs sequence passed into setCodecPreferences can only contain | 
 |  codecs that are returned by RTCRtpSender.getCapabilities(kind) or | 
 |  RTCRtpReceiver.getCapabilities(kind), where kind is the kind of the | 
 |  RTCRtpTransceiver on which the method is called. Additionally, the | 
 |  RTCRtpCodecParameters dictionary members cannot be modified. If | 
 |  codecs does not fulfill these requirements, the user agent MUST throw | 
 |  an InvalidModificationError. | 
 |  */ | 
 |  | 
 |  test(() => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  const transceiver = pc.addTransceiver('audio'); | 
 |  const capabilities = RTCRtpSender.getCapabilities('audio'); | 
 |  transceiver.setCodecPreferences(capabilities.codecs); | 
 |  | 
 |  }, `setCodecPreferences() on audio transceiver with codecs returned from RTCRtpSender.getCapabilities('audio') should succeed`); | 
 |  | 
 |  test(() => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  const transceiver = pc.addTransceiver('video'); | 
 |  const capabilities = RTCRtpReceiver.getCapabilities('video'); | 
 |  transceiver.setCodecPreferences(capabilities.codecs); | 
 |  | 
 |  }, `setCodecPreferences() on video transceiver with codecs returned from RTCRtpReceiver.getCapabilities('video') should succeed`); | 
 |  | 
 |  test(() => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  const transceiver = pc.addTransceiver('audio'); | 
 |  const capabilities1 = RTCRtpSender.getCapabilities('audio'); | 
 |  const capabilities2 = RTCRtpReceiver.getCapabilities('audio'); | 
 |  transceiver.setCodecPreferences([...capabilities1.codecs, ... capabilities2.codecs]); | 
 |  | 
 |  }, `setCodecPreferences() with both sender receiver codecs combined should succeed`); | 
 |  | 
 |  test(() => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  const transceiver = pc.addTransceiver('audio'); | 
 |  transceiver.setCodecPreferences([]); | 
 |  | 
 |  }, `setCodecPreferences([]) should succeed`); | 
 |  | 
 |  test(() => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  const transceiver = pc.addTransceiver('audio'); | 
 |  const capabilities = RTCRtpSender.getCapabilities('audio'); | 
 |  const { codecs } = capabilities; | 
 |  | 
 |  if(codecs.length >= 2) { | 
 |  const tmp = codecs[0]; | 
 |  codecs[0] = codecs[1]; | 
 |  codecs[1] = tmp; | 
 |  } | 
 |  | 
 |  transceiver.setCodecPreferences(codecs); | 
 |  | 
 |  }, `setCodecPreferences() with reordered codecs should succeed`); | 
 |  | 
 |  test(() => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  const transceiver = pc.addTransceiver('audio'); | 
 |  const capabilities = RTCRtpSender.getCapabilities('video'); | 
 |  assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(capabilities.codecs)); | 
 |  | 
 |  }, `setCodecPreferences() on audio transceiver with codecs returned from getCapabilities('video') should throw InvalidModificationError`); | 
 |  | 
 |  test(() => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  const transceiver = pc.addTransceiver('audio'); | 
 |  const codecs = [{ | 
 |  mimeType: 'data', | 
 |  clockRate: 2000, | 
 |  channels: 2, | 
 |  sdpFmtpLine: '0-15' | 
 |  }]; | 
 |  | 
 |  assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(codecs)); | 
 |  | 
 |  }, `setCodecPreferences() with user defined codec with invalid mimeType should throw InvalidModificationError`); | 
 |  | 
 |  test(() => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  const transceiver = pc.addTransceiver('audio'); | 
 |  const codecs = [{ | 
 |  mimeType: 'audio/piepiper', | 
 |  clockRate: 2000, | 
 |  channels: 2, | 
 |  sdpFmtpLine: '0-15' | 
 |  }]; | 
 |  | 
 |  assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(codecs)); | 
 |  | 
 |  }, `setCodecPreferences() with user defined codec should throw InvalidModificationError`); | 
 |  | 
 |  test(() => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  const transceiver = pc.addTransceiver('audio'); | 
 |  const capabilities = RTCRtpSender.getCapabilities('audio'); | 
 |  const codecs = [ | 
 |  ...capabilities.codecs, | 
 |  { | 
 |  mimeType: 'audio/piepiper', | 
 |  clockRate: 2000, | 
 |  channels: 2, | 
 |  sdpFmtpLine: '0-15' | 
 |  }]; | 
 |  | 
 |  assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(codecs)); | 
 |  | 
 |  }, `setCodecPreferences() with user defined codec together with codecs returned from getCapabilities() should throw InvalidModificationError`); | 
 |  | 
 |  test(() => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  const transceiver = pc.addTransceiver('audio'); | 
 |  const capabilities = RTCRtpSender.getCapabilities('audio'); | 
 |  const codecs = [capabilities.codecs[0]]; | 
 |  codecs[0].clockRate = codecs[0].clockRate / 2; | 
 |  | 
 |  assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(codecs)); | 
 |  | 
 |  }, `setCodecPreferences() with modified codec clock rate should throw InvalidModificationError`); | 
 |  | 
 |  test(() => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  const transceiver = pc.addTransceiver('audio'); | 
 |  const capabilities = RTCRtpSender.getCapabilities('audio'); | 
 |  const codecs = [capabilities.codecs[0]]; | 
 |  codecs[0].channels = codecs[0].channels + 11; | 
 |  | 
 |  assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(codecs)); | 
 |  | 
 |  }, `setCodecPreferences() with modified codec channel count should throw InvalidModificationError`); | 
 |  | 
 |  test(() => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  const transceiver = pc.addTransceiver('audio'); | 
 |  const capabilities = RTCRtpSender.getCapabilities('audio'); | 
 |  const codecs = [capabilities.codecs[0]]; | 
 |  codecs[0].sdpFmtpLine = "modifiedparameter=1"; | 
 |  | 
 |  assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(codecs)); | 
 |  | 
 |  }, `setCodecPreferences() with modified codec parameters should throw InvalidModificationError`); | 
 |  | 
 |  test(() => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  const transceiver = pc.addTransceiver('audio'); | 
 |  const capabilities = RTCRtpSender.getCapabilities('audio'); | 
 |  | 
 |  const { codecs } = capabilities; | 
 |  assert_greater_than(codecs.length, 0, | 
 |  'Expect at least one codec available'); | 
 |  | 
 |  const [ codec ] = codecs; | 
 |  const { channels=2 } = codec; | 
 |  codec.channels = channels+1; | 
 |  | 
 |  assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(codecs)); | 
 |  | 
 |  }, `setCodecPreferences() with modified codecs returned from getCapabilities() should throw InvalidModificationError`); | 
 |  | 
 |  </script> |