Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /** | |
| 2 * Copyright 2016 The Chromium Authors. All rights reserved. | |
| 3 * Use of this source code is governed by a BSD-style license that can be | |
| 4 * found in the LICENSE file. | |
| 5 */ | |
| 6 | |
| 7 /** | |
| 8 * See |setSdpDefaultCodec|. | |
| 9 */ | |
| 10 function setSdpDefaultAudioCodec(sdp, codec) { | |
| 11 return setSdpDefaultCodec(sdp, 'audio', codec); | |
| 12 } | |
| 13 | |
| 14 /** | |
| 15 * See |setSdpDefaultCodec|. | |
| 16 */ | |
| 17 function setSdpDefaultVideoCodec(sdp, codec) { | |
| 18 return setSdpDefaultCodec(sdp, 'video', codec); | |
| 19 } | |
| 20 | |
| 21 /** | |
| 22 * Returns a modified version of |sdp| where the |codec| has been promoted to be | |
| 23 * the default codec, i.e. the codec whose ID is first in the list of codecs on | |
| 24 * the 'm=|type|' line, where |type| is 'audio' or 'video'. | |
| 25 * @private | |
| 26 */ | |
| 27 function setSdpDefaultCodec(sdp, type, codec) { | |
| 28 var sdpLines = splitSdpLines(sdp); | |
| 29 | |
| 30 // Find codec ID, e.g. 100 for 'VP8' if 'a=rtpmap:100 VP8/9000'. | |
| 31 var codecId = findRtpmapId(sdpLines, codec); | |
| 32 if (codecId === null) { | |
| 33 failure_('sdpPreferCodec', 'Unknown ID for |codec| = \'' + codec + '\'.'); | |
|
phoglund_chromium
2016/02/01 14:20:44
This function is undefined. use failTest defined h
hbos_chromium
2016/02/02 14:07:19
Moved success_ and failure_ to test_functions.js a
| |
| 34 } | |
| 35 | |
| 36 // Find 'm=|type|' line, e.g. 'm=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116'. | |
| 37 var mLineNo = findLine(sdpLines, 'm=' + type); | |
| 38 if (mLineNo === null) { | |
| 39 failure_('setSdpDefaultCodec', | |
| 40 '\'m=' + type + '\' line missing from |sdp|.'); | |
| 41 } | |
| 42 | |
| 43 // Modify video line to use the desired codec as the default. | |
| 44 sdpLines[mLineNo] = setMLineDefaultCodec(sdpLines[mLineNo], codecId); | |
| 45 return mergeSdpLines(sdpLines); | |
| 46 } | |
| 47 | |
| 48 /** | |
| 49 * See |getSdpDefaultCodec|. | |
| 50 */ | |
| 51 function getSdpDefaultAudioCodec(sdp) { | |
| 52 return getSdpDefaultCodec(sdp, 'audio'); | |
| 53 } | |
| 54 | |
| 55 /** | |
| 56 * See |getSdpDefaultCodec|. | |
| 57 */ | |
| 58 function getSdpDefaultVideoCodec(sdp) { | |
| 59 return getSdpDefaultCodec(sdp, 'video'); | |
| 60 } | |
| 61 | |
| 62 /** | |
| 63 * Gets the default codec according to the |sdp|, i.e. the name of the codec | |
| 64 * whose ID is first in the list of codecs on the 'm=|type|' line, where |type| | |
| 65 * is 'audio' or 'video'. | |
| 66 * @private | |
| 67 */ | |
| 68 function getSdpDefaultCodec(sdp, type) { | |
| 69 var sdpLines = splitSdpLines(sdp); | |
| 70 | |
| 71 // Find 'm=|type|' line, e.g. 'm=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116'. | |
| 72 var mLineNo = findLine(sdpLines, 'm=' + type); | |
| 73 if (mLineNo === null) { | |
| 74 failure_('getSdpDefaultCodec', | |
| 75 '\'m=' + type + '\' line missing from |sdp|.'); | |
| 76 } | |
| 77 | |
| 78 // The default codec's ID. | |
| 79 var defaultCodecId = getMLineDefaultCodec(sdpLines[mLineNo]); | |
| 80 if (defaultCodecId === null) { | |
| 81 failure_('getSdpDefaultCodec', | |
| 82 '\'m=' + type + '\' line contains no codecs.'); | |
| 83 } | |
| 84 | |
| 85 // Find codec name, e.g. 'VP8' for 100 if 'a=rtpmap:100 VP8/9000'. | |
| 86 var defaultCodec = findRtpmapCodec(sdpLines, defaultCodecId); | |
| 87 if (defaultCodec === null) { | |
| 88 failure_('getSdpDefaultCodec', | |
| 89 'Unknown codec name for default codec ' + defaultCodecId + '.'); | |
| 90 } | |
| 91 return defaultCodec; | |
| 92 } | |
| 93 | |
| 94 /** | |
| 95 * Searches through all |sdpLines| for the 'a=rtpmap:' line for the codec of | |
| 96 * the specified name, returning its ID as an int if found, or null otherwise. | |
| 97 * |codec| is the case-sensitive name of the codec. | |
| 98 * For example, if |sdpLines| contains 'a=rtpmap:100 VP8/9000' and |codec| is | |
| 99 * 'VP8', this function returns 100. | |
| 100 * @private | |
| 101 */ | |
| 102 function findRtpmapId(sdpLines, codec) { | |
| 103 var lineNo = findRtpmapLine(sdpLines, codec); | |
| 104 if (lineNo === null) | |
| 105 return null; | |
| 106 // Parse <id> from 'a=rtpmap:<id> <codec>/<rate>'. | |
| 107 var id = sdpLines[lineNo].substring(9, sdpLines[lineNo].indexOf(' ')); | |
| 108 return parseInt(id); | |
| 109 } | |
| 110 | |
| 111 /** | |
| 112 * Searches through all |sdpLines| for the 'a=rtpmap:' line for the codec of | |
| 113 * the specified codec ID, returning its name if found, or null otherwise. | |
| 114 * For example, if |sdpLines| contains 'a=rtpmap:100 VP8/9000' and |id| is 100, | |
| 115 * this function returns 'VP8'. | |
| 116 * @private | |
| 117 */ | |
| 118 function findRtpmapCodec(sdpLines, id) { | |
| 119 var lineNo = findRtpmapLine(sdpLines, id); | |
| 120 if (lineNo === null) | |
| 121 return null; | |
| 122 // Parse <codec> from 'a=rtpmap:<id> <codec>/<rate>'. | |
| 123 var from = sdpLines[lineNo].indexOf(' '); | |
| 124 var to = sdpLines[lineNo].indexOf('/', from); | |
| 125 if (from === null || to === null || from + 1 >= to) | |
| 126 failure_('findRtpmapCodec', ''); | |
| 127 return sdpLines[lineNo].substring(from + 1, to); | |
| 128 } | |
| 129 | |
| 130 /** | |
| 131 * Finds the first 'a=rtpmap:' line from |sdpLines| that contains |contains| and | |
| 132 * returns its line index, or null if no such line was found. |contains| may be | |
| 133 * the codec ID, codec name or bitrate. An 'a=rtpmap:' line looks like this: | |
| 134 * 'a=rtpmap:<id> <codec>/<rate>'. | |
| 135 */ | |
| 136 function findRtpmapLine(sdpLines, contains) { | |
| 137 for (var i = 0; i < sdpLines.length; i++) { | |
| 138 // Is 'a=rtpmap:' line containing |contains| string? | |
| 139 if (sdpLines[i].startsWith('a=rtpmap:') && | |
| 140 sdpLines[i].indexOf(contains) != -1) { | |
| 141 // Expecting pattern 'a=rtpmap:<id> <codec>/<rate>'. | |
| 142 var pattern = new RegExp('a=rtpmap:(\\d+) \\w+\\/\\d+'); | |
| 143 if (!sdpLines[i].match(pattern)) | |
| 144 failure_('findRtpmapLine', 'Unexpected "a=rtpmap:" pattern.'); | |
| 145 // Return line index. | |
| 146 return i; | |
| 147 } | |
| 148 } | |
| 149 return null; | |
| 150 } | |
| 151 | |
| 152 /** | |
| 153 * Returns a modified version of |mLine| that has |codecId| first in the list of | |
| 154 * codec IDs. For example, setMLineDefaultCodec( | |
| 155 * 'm=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116 117 96', 107) | |
| 156 * Returns: | |
| 157 * 'm=video 9 UDP/TLS/RTP/SAVPF 107 100 101 116 117 96' | |
| 158 * @private | |
| 159 */ | |
| 160 function setMLineDefaultCodec(mLine, codecId) { | |
| 161 var elements = mLine.split(' '); | |
| 162 | |
| 163 // Copy first three elements, codec order starts on fourth. | |
| 164 var newLine = elements.slice(0, 3); | |
| 165 | |
| 166 // Put target |codecId| first and copy the rest. | |
| 167 newLine.push(codecId); | |
| 168 for (var i = 3; i < elements.length; i++) { | |
| 169 if (elements[i] != codecId) | |
| 170 newLine.push(elements[i]); | |
| 171 } | |
| 172 | |
| 173 return newLine.join(' '); | |
| 174 } | |
| 175 | |
| 176 /** | |
| 177 * Returns the default codec's ID from the |mLine|, or null if the codec list is | |
| 178 * empty. The default codec is the codec whose ID is first in the list of codec | |
| 179 * IDs on the |mLine|. For example, getMLineDefaultCodec( | |
| 180 * 'm=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116 117 96') | |
| 181 * Returns: | |
| 182 * 100 | |
| 183 * @private | |
| 184 */ | |
| 185 function getMLineDefaultCodec(mLine) { | |
| 186 var elements = mLine.split(' '); | |
| 187 if (elements.length < 4) | |
| 188 return null; | |
| 189 return parseInt(elements[3]); | |
| 190 } | |
| 191 | |
| 192 /** @private */ | |
| 193 function splitSdpLines(sdp) { | |
| 194 return sdp.split('\r\n'); | |
| 195 } | |
| 196 | |
| 197 /** @private */ | |
| 198 function mergeSdpLines(sdpLines) { | |
| 199 return sdpLines.join('\r\n'); | |
| 200 } | |
| 201 | |
| 202 /** @private */ | |
| 203 function findLine(lines, startsWith) { | |
| 204 for (var i = 0; i < lines.length; i++) { | |
| 205 if (lines[i].startsWith(startsWith)) | |
| 206 return i; | |
| 207 } | |
| 208 return null; | |
| 209 } | |
| OLD | NEW |