<!doctype html>
<meta charset=utf-8>
<title>RTCRtpTransceiver.prototype.setCodecPreferences</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./third_party/sdp/sdp.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.
   */
  /*
   * Chromium note: this requires build bots with H264 support. See
   *   https://bugs.chromium.org/p/chromium/issues/detail?id=840659
   * for details on how to enable support.
   */

  test((t) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    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((t) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    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((t) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    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((t) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const transceiver = pc.addTransceiver('audio');
    transceiver.setCodecPreferences([]);
  }, `setCodecPreferences([]) should succeed`);

  test((t) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    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((t) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const transceiver = pc.addTransceiver('video');
    const capabilities = RTCRtpSender.getCapabilities('video');
    const { codecs } = capabilities;
    // This test verifies that the mandatory VP8 codec is present
    // and can be set.
    let tried = false;
    codecs.forEach(codec => {
      if (codec.mimeType.toLowerCase() === 'video/vp8') {
        transceiver.setCodecPreferences([codecs[0]]);
        tried = true;
      }
    });
    assert_true(tried, 'VP8 video codec was found and tried');
  }, `setCodecPreferences() with only VP8 should succeed`);

  test(() => {
    const pc = new RTCPeerConnection();
    const transceiver = pc.addTransceiver('video');
    const capabilities = RTCRtpSender.getCapabilities('video');
    const { codecs } = capabilities;
    // This test verifies that the mandatory H264 codec is present
    // and can be set.
    let tried = false;
    codecs.forEach(codec => {
      if (codec.mimeType.toLowerCase() === 'video/h264') {
        transceiver.setCodecPreferences([codecs[0]]);
        tried = true;
      }
    });
    assert_true(tried, 'H264 video codec was found and tried');
  }, `setCodecPreferences() with only H264 should succeed`);

  async function getRTPMapLinesWithCodecAsFirst(firstCodec)
  {
     const capabilities = RTCRtpSender.getCapabilities('video').codecs;
     capabilities.forEach((codec, idx) => {
       if (codec.mimeType === firstCodec) {
          capabilities.splice(idx, 1);
          capabilities.unshift(codec);
       }
     });

     const pc = new RTCPeerConnection();
     const transceiver = pc.addTransceiver('video');
     transceiver.setCodecPreferences(capabilities);
     const offer = await pc.createOffer();

     return offer.sdp.split('\r\n').filter(line => line.indexOf("a=rtpmap") === 0);
  }

  promise_test(async () => {
    const lines = await getRTPMapLinesWithCodecAsFirst('video/H264');

    assert_greater_than(lines.length, 1);
    assert_true(lines[0].indexOf("H264") !== -1, "H264 should be the first codec");
  }, `setCodecPreferences() should allow setting H264 as first codec`);

  promise_test(async () => {
    const lines = await getRTPMapLinesWithCodecAsFirst('video/VP8');

    assert_greater_than(lines.length, 1);
    assert_true(lines[0].indexOf("VP8") !== -1, "VP8 should be the first codec");
  }, `setCodecPreferences() should allow setting VP8 as first codec`);

  test((t) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    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((t) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    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((t) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    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((t) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    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((t) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    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((t) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    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((t) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    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((t) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    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`);

  promise_test(async (t) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const transceiver = pc.addTransceiver('audio');
    const {codecs} = RTCRtpSender.getCapabilities('audio');
    // Reorder codecs, put PCMU/PCMA first.
    let firstCodec;
    let i;
    for (i = 0; i < codecs.length; i++) {
      const codec = codecs[i];
      if (codec.mimeType === 'audio/PCMU' || codec.mimeType === 'audio/PCMA') {
        codecs.splice(i, 1);
        codecs.unshift(codec);
        firstCodec = codec.mimeType.substr(6);
        break;
      }
    }
    assert_not_equals(firstCodec, undefined, 'PCMU or PCMA codec not found');
    transceiver.setCodecPreferences(codecs);

    const offer = await pc.createOffer();
    const mediaSection = SDPUtils.getMediaSections(offer.sdp)[0];
    const rtpParameters = SDPUtils.parseRtpParameters(mediaSection);
    assert_equals(rtpParameters.codecs[0].name, firstCodec);
  }, `setCodecPreferences() modifies the order of audio codecs in createOffer`);

  promise_test(async (t) => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const transceiver = pc.addTransceiver('video');
    const {codecs} = RTCRtpSender.getCapabilities('video');
    // Reorder codecs, swap H264 and VP8.
    let vp8 = -1;
    let h264 = -1;
    let firstCodec;
    let i;
    for (i = 0; i < codecs.length; i++) {
      const codec = codecs[i];
      if (codec.mimeType === 'video/VP8') {
        vp8 = i;
        if (h264 !== -1) {
          codecs[vp8] = codecs[h264];
          codecs[h264] = codec;
          firstCodec = 'VP8';
          break;
        }
      }
      if (codec.mimeType === 'video/H264') {
        h264 = i;
        if (vp8 !== -1) {
          codecs[h264] = codecs[vp8];
          codecs[vp8] = codec;
          firstCodec = 'H264';
          break;
        }
      }
    }
    assert_not_equals(firstCodec, undefined, 'VP8 and H264 codecs not found');
    transceiver.setCodecPreferences(codecs);

    const offer = await pc.createOffer();
    const mediaSection = SDPUtils.getMediaSections(offer.sdp)[0];
    const rtpParameters = SDPUtils.parseRtpParameters(mediaSection);
    assert_equals(rtpParameters.codecs[0].name, firstCodec);
  }, `setCodecPreferences() modifies the order of video codecs in createOffer`);

 </script>
