| Index: chrome/test/data/webrtc/munge_sdp.js
|
| diff --git a/chrome/test/data/webrtc/munge_sdp.js b/chrome/test/data/webrtc/munge_sdp.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..9a8a37e6d78a754b5c195dc119360c131b5711e1
|
| --- /dev/null
|
| +++ b/chrome/test/data/webrtc/munge_sdp.js
|
| @@ -0,0 +1,209 @@
|
| +/**
|
| + * Copyright 2016 The Chromium Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +/**
|
| + * See |setSdpDefaultCodec|.
|
| + */
|
| +function setSdpDefaultAudioCodec(sdp, codec) {
|
| + return setSdpDefaultCodec(sdp, 'audio', codec);
|
| +}
|
| +
|
| +/**
|
| + * See |setSdpDefaultCodec|.
|
| + */
|
| +function setSdpDefaultVideoCodec(sdp, codec) {
|
| + return setSdpDefaultCodec(sdp, 'video', codec);
|
| +}
|
| +
|
| +/**
|
| + * Returns a modified version of |sdp| where the |codec| has been promoted to be
|
| + * the default codec, i.e. the codec whose ID is first in the list of codecs on
|
| + * the 'm=|type|' line, where |type| is 'audio' or 'video'.
|
| + * @private
|
| + */
|
| +function setSdpDefaultCodec(sdp, type, codec) {
|
| + var sdpLines = splitSdpLines(sdp);
|
| +
|
| + // Find codec ID, e.g. 100 for 'VP8' if 'a=rtpmap:100 VP8/9000'.
|
| + var codecId = findRtpmapId(sdpLines, codec);
|
| + if (codecId === null) {
|
| + failure('sdpPreferCodec', 'Unknown ID for |codec| = \'' + codec + '\'.');
|
| + }
|
| +
|
| + // Find 'm=|type|' line, e.g. 'm=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116'.
|
| + var mLineNo = findLine(sdpLines, 'm=' + type);
|
| + if (mLineNo === null) {
|
| + failure('setSdpDefaultCodec',
|
| + '\'m=' + type + '\' line missing from |sdp|.');
|
| + }
|
| +
|
| + // Modify video line to use the desired codec as the default.
|
| + sdpLines[mLineNo] = setMLineDefaultCodec(sdpLines[mLineNo], codecId);
|
| + return mergeSdpLines(sdpLines);
|
| +}
|
| +
|
| +/**
|
| + * See |getSdpDefaultCodec|.
|
| + */
|
| +function getSdpDefaultAudioCodec(sdp) {
|
| + return getSdpDefaultCodec(sdp, 'audio');
|
| +}
|
| +
|
| +/**
|
| + * See |getSdpDefaultCodec|.
|
| + */
|
| +function getSdpDefaultVideoCodec(sdp) {
|
| + return getSdpDefaultCodec(sdp, 'video');
|
| +}
|
| +
|
| +/**
|
| + * Gets the default codec according to the |sdp|, i.e. the name of the codec
|
| + * whose ID is first in the list of codecs on the 'm=|type|' line, where |type|
|
| + * is 'audio' or 'video'.
|
| + * @private
|
| + */
|
| +function getSdpDefaultCodec(sdp, type) {
|
| + var sdpLines = splitSdpLines(sdp);
|
| +
|
| + // Find 'm=|type|' line, e.g. 'm=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116'.
|
| + var mLineNo = findLine(sdpLines, 'm=' + type);
|
| + if (mLineNo === null) {
|
| + failure('getSdpDefaultCodec',
|
| + '\'m=' + type + '\' line missing from |sdp|.');
|
| + }
|
| +
|
| + // The default codec's ID.
|
| + var defaultCodecId = getMLineDefaultCodec(sdpLines[mLineNo]);
|
| + if (defaultCodecId === null) {
|
| + failure('getSdpDefaultCodec',
|
| + '\'m=' + type + '\' line contains no codecs.');
|
| + }
|
| +
|
| + // Find codec name, e.g. 'VP8' for 100 if 'a=rtpmap:100 VP8/9000'.
|
| + var defaultCodec = findRtpmapCodec(sdpLines, defaultCodecId);
|
| + if (defaultCodec === null) {
|
| + failure('getSdpDefaultCodec',
|
| + 'Unknown codec name for default codec ' + defaultCodecId + '.');
|
| + }
|
| + return defaultCodec;
|
| +}
|
| +
|
| +/**
|
| + * Searches through all |sdpLines| for the 'a=rtpmap:' line for the codec of
|
| + * the specified name, returning its ID as an int if found, or null otherwise.
|
| + * |codec| is the case-sensitive name of the codec.
|
| + * For example, if |sdpLines| contains 'a=rtpmap:100 VP8/9000' and |codec| is
|
| + * 'VP8', this function returns 100.
|
| + * @private
|
| + */
|
| +function findRtpmapId(sdpLines, codec) {
|
| + var lineNo = findRtpmapLine(sdpLines, codec);
|
| + if (lineNo === null)
|
| + return null;
|
| + // Parse <id> from 'a=rtpmap:<id> <codec>/<rate>'.
|
| + var id = sdpLines[lineNo].substring(9, sdpLines[lineNo].indexOf(' '));
|
| + return parseInt(id);
|
| +}
|
| +
|
| +/**
|
| + * Searches through all |sdpLines| for the 'a=rtpmap:' line for the codec of
|
| + * the specified codec ID, returning its name if found, or null otherwise.
|
| + * For example, if |sdpLines| contains 'a=rtpmap:100 VP8/9000' and |id| is 100,
|
| + * this function returns 'VP8'.
|
| + * @private
|
| + */
|
| +function findRtpmapCodec(sdpLines, id) {
|
| + var lineNo = findRtpmapLine(sdpLines, id);
|
| + if (lineNo === null)
|
| + return null;
|
| + // Parse <codec> from 'a=rtpmap:<id> <codec>/<rate>'.
|
| + var from = sdpLines[lineNo].indexOf(' ');
|
| + var to = sdpLines[lineNo].indexOf('/', from);
|
| + if (from === null || to === null || from + 1 >= to)
|
| + failure('findRtpmapCodec', '');
|
| + return sdpLines[lineNo].substring(from + 1, to);
|
| +}
|
| +
|
| +/**
|
| + * Finds the first 'a=rtpmap:' line from |sdpLines| that contains |contains| and
|
| + * returns its line index, or null if no such line was found. |contains| may be
|
| + * the codec ID, codec name or bitrate. An 'a=rtpmap:' line looks like this:
|
| + * 'a=rtpmap:<id> <codec>/<rate>'.
|
| + */
|
| +function findRtpmapLine(sdpLines, contains) {
|
| + for (var i = 0; i < sdpLines.length; i++) {
|
| + // Is 'a=rtpmap:' line containing |contains| string?
|
| + if (sdpLines[i].startsWith('a=rtpmap:') &&
|
| + sdpLines[i].indexOf(contains) != -1) {
|
| + // Expecting pattern 'a=rtpmap:<id> <codec>/<rate>'.
|
| + var pattern = new RegExp('a=rtpmap:(\\d+) \\w+\\/\\d+');
|
| + if (!sdpLines[i].match(pattern))
|
| + failure('findRtpmapLine', 'Unexpected "a=rtpmap:" pattern.');
|
| + // Return line index.
|
| + return i;
|
| + }
|
| + }
|
| + return null;
|
| +}
|
| +
|
| +/**
|
| + * Returns a modified version of |mLine| that has |codecId| first in the list of
|
| + * codec IDs. For example, setMLineDefaultCodec(
|
| + * 'm=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116 117 96', 107)
|
| + * Returns:
|
| + * 'm=video 9 UDP/TLS/RTP/SAVPF 107 100 101 116 117 96'
|
| + * @private
|
| + */
|
| +function setMLineDefaultCodec(mLine, codecId) {
|
| + var elements = mLine.split(' ');
|
| +
|
| + // Copy first three elements, codec order starts on fourth.
|
| + var newLine = elements.slice(0, 3);
|
| +
|
| + // Put target |codecId| first and copy the rest.
|
| + newLine.push(codecId);
|
| + for (var i = 3; i < elements.length; i++) {
|
| + if (elements[i] != codecId)
|
| + newLine.push(elements[i]);
|
| + }
|
| +
|
| + return newLine.join(' ');
|
| +}
|
| +
|
| +/**
|
| + * Returns the default codec's ID from the |mLine|, or null if the codec list is
|
| + * empty. The default codec is the codec whose ID is first in the list of codec
|
| + * IDs on the |mLine|. For example, getMLineDefaultCodec(
|
| + * 'm=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116 117 96')
|
| + * Returns:
|
| + * 100
|
| + * @private
|
| + */
|
| +function getMLineDefaultCodec(mLine) {
|
| + var elements = mLine.split(' ');
|
| + if (elements.length < 4)
|
| + return null;
|
| + return parseInt(elements[3]);
|
| +}
|
| +
|
| +/** @private */
|
| +function splitSdpLines(sdp) {
|
| + return sdp.split('\r\n');
|
| +}
|
| +
|
| +/** @private */
|
| +function mergeSdpLines(sdpLines) {
|
| + return sdpLines.join('\r\n');
|
| +}
|
| +
|
| +/** @private */
|
| +function findLine(lines, startsWith) {
|
| + for (var i = 0; i < lines.length; i++) {
|
| + if (lines[i].startsWith(startsWith))
|
| + return i;
|
| + }
|
| + return null;
|
| +}
|
|
|