Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /** | 1 /** |
| 2 * Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * See |setSdpDefaultCodec|. | 8 * See |setSdpDefaultCodec|. |
| 9 */ | 9 */ |
| 10 function setSdpDefaultAudioCodec(sdp, codec) { | 10 function setSdpDefaultAudioCodec(sdp, codec) { |
| 11 return setSdpDefaultCodec(sdp, 'audio', codec); | 11 return setSdpDefaultCodec(sdp, 'audio', codec, false /* preferHwCodec */); |
| 12 } | 12 } |
| 13 | 13 |
| 14 /** | 14 /** |
| 15 * See |setSdpDefaultCodec|. | 15 * See |setSdpDefaultCodec|. |
| 16 */ | 16 */ |
| 17 function setSdpDefaultVideoCodec(sdp, codec) { | 17 function setSdpDefaultVideoCodec(sdp, codec, preferHwCodec) { |
| 18 return setSdpDefaultCodec(sdp, 'video', codec); | 18 return setSdpDefaultCodec(sdp, 'video', codec, preferHwCodec); |
| 19 } | 19 } |
| 20 | 20 |
| 21 /** | 21 /** |
| 22 * Returns a modified version of |sdp| where the opus DTX flag has been | 22 * Returns a modified version of |sdp| where the opus DTX flag has been |
| 23 * enabled. | 23 * enabled. |
| 24 */ | 24 */ |
| 25 function setOpusDtxEnabled(sdp) { | 25 function setOpusDtxEnabled(sdp) { |
| 26 var sdpLines = splitSdpLines(sdp); | 26 var sdpLines = splitSdpLines(sdp); |
| 27 | 27 |
| 28 // Get default audio codec | 28 // Get default audio codec |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 48 } else { | 48 } else { |
| 49 // Modify the line to enable Opus Dtx. | 49 // Modify the line to enable Opus Dtx. |
| 50 sdpLines[fmtLineNo] += ';usedtx=1' | 50 sdpLines[fmtLineNo] += ';usedtx=1' |
| 51 } | 51 } |
| 52 return mergeSdpLines(sdpLines); | 52 return mergeSdpLines(sdpLines); |
| 53 } | 53 } |
| 54 | 54 |
| 55 /** | 55 /** |
| 56 * Returns a modified version of |sdp| where the |codec| has been promoted to be | 56 * Returns a modified version of |sdp| where the |codec| has been promoted to be |
| 57 * the default codec, i.e. the codec whose ID is first in the list of codecs on | 57 * the default codec, i.e. the codec whose ID is first in the list of codecs on |
| 58 * the 'm=|type|' line, where |type| is 'audio' or 'video'. | 58 * the 'm=|type|' line, where |type| is 'audio' or 'video'. If |preferHwCodec| |
| 59 * is true, it will select the last codec with the given name, and if false, it | |
| 60 * will select the first codec with the given name. | |
|
emircan
2017/08/02 03:42:22
Can you also note that HW codecs are after SW code
magjed_chromium
2017/08/02 08:51:15
Done.
| |
| 59 * @private | 61 * @private |
| 60 */ | 62 */ |
| 61 function setSdpDefaultCodec(sdp, type, codec) { | 63 function setSdpDefaultCodec(sdp, type, codec, preferHwCodec) { |
| 62 var sdpLines = splitSdpLines(sdp); | 64 var sdpLines = splitSdpLines(sdp); |
| 63 | 65 |
| 64 // Find codec ID, e.g. 100 for 'VP8' if 'a=rtpmap:100 VP8/9000'. | 66 // Find codec ID, e.g. 100 for 'VP8' if 'a=rtpmap:100 VP8/9000'. |
| 65 var codecId = findRtpmapId(sdpLines, codec); | 67 var codecId = findRtpmapId(sdpLines, codec, preferHwCodec); |
| 66 if (codecId === null) { | 68 if (codecId === null) { |
| 67 failure('setSdpDefaultCodec', | 69 failure('setSdpDefaultCodec', |
| 68 'Unknown ID for |codec| = \'' + codec + '\'.'); | 70 'Unknown ID for |codec| = \'' + codec + '\'.'); |
| 69 } | 71 } |
| 70 | 72 |
| 71 // Find 'm=|type|' line, e.g. 'm=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116'. | 73 // Find 'm=|type|' line, e.g. 'm=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116'. |
| 72 var mLineNo = findLine(sdpLines, 'm=' + type); | 74 var mLineNo = findLine(sdpLines, 'm=' + type); |
| 73 if (mLineNo === null) { | 75 if (mLineNo === null) { |
| 74 failure('setSdpDefaultCodec', | 76 failure('setSdpDefaultCodec', |
| 75 '\'m=' + type + '\' line missing from |sdp|.'); | 77 '\'m=' + type + '\' line missing from |sdp|.'); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 122 if (defaultCodec === null) { | 124 if (defaultCodec === null) { |
| 123 failure('getSdpDefaultCodec', | 125 failure('getSdpDefaultCodec', |
| 124 'Unknown codec name for default codec ' + defaultCodecId + '.'); | 126 'Unknown codec name for default codec ' + defaultCodecId + '.'); |
| 125 } | 127 } |
| 126 return defaultCodec; | 128 return defaultCodec; |
| 127 } | 129 } |
| 128 | 130 |
| 129 /** | 131 /** |
| 130 * Searches through all |sdpLines| for the 'a=rtpmap:' line for the codec of | 132 * Searches through all |sdpLines| for the 'a=rtpmap:' line for the codec of |
| 131 * the specified name, returning its ID as an int if found, or null otherwise. | 133 * the specified name, returning its ID as an int if found, or null otherwise. |
| 132 * |codec| is the case-sensitive name of the codec. | 134 * |codec| is the case-sensitive name of the codec. If |searchBackwards| |
| 135 * is true, it will return the last such ID, and if false, it will return the | |
| 136 * first such ID. | |
| 133 * For example, if |sdpLines| contains 'a=rtpmap:100 VP8/9000' and |codec| is | 137 * For example, if |sdpLines| contains 'a=rtpmap:100 VP8/9000' and |codec| is |
| 134 * 'VP8', this function returns 100. | 138 * 'VP8', this function returns 100. |
| 135 * @private | 139 * @private |
| 136 */ | 140 */ |
| 137 function findRtpmapId(sdpLines, codec) { | 141 function findRtpmapId(sdpLines, codec, searchBackwards) { |
| 138 var lineNo = findRtpmapLine(sdpLines, codec); | 142 var lineNo = findRtpmapLine(sdpLines, codec, searchBackwards); |
| 139 if (lineNo === null) | 143 if (lineNo === null) |
| 140 return null; | 144 return null; |
| 141 // Parse <id> from 'a=rtpmap:<id> <codec>/<rate>'. | 145 // Parse <id> from 'a=rtpmap:<id> <codec>/<rate>'. |
| 142 var id = sdpLines[lineNo].substring(9, sdpLines[lineNo].indexOf(' ')); | 146 var id = sdpLines[lineNo].substring(9, sdpLines[lineNo].indexOf(' ')); |
| 143 return parseInt(id); | 147 return parseInt(id); |
| 144 } | 148 } |
| 145 | 149 |
| 146 /** | 150 /** |
| 147 * Searches through all |sdpLines| for the 'a=rtpmap:' line for the codec of | 151 * Searches through all |sdpLines| for the 'a=rtpmap:' line for the codec of |
| 148 * the specified codec ID, returning its name if found, or null otherwise. | 152 * the specified codec ID, returning its name if found, or null otherwise. |
| 149 * For example, if |sdpLines| contains 'a=rtpmap:100 VP8/9000' and |id| is 100, | 153 * For example, if |sdpLines| contains 'a=rtpmap:100 VP8/9000' and |id| is 100, |
| 150 * this function returns 'VP8'. | 154 * this function returns 'VP8'. |
| 151 * @private | 155 * @private |
| 152 */ | 156 */ |
| 153 function findRtpmapCodec(sdpLines, id) { | 157 function findRtpmapCodec(sdpLines, id) { |
| 154 var lineNo = findRtpmapLine(sdpLines, id); | 158 var lineNo = findRtpmapLine(sdpLines, id); |
| 155 if (lineNo === null) | 159 if (lineNo === null) |
| 156 return null; | 160 return null; |
| 157 // Parse <codec> from 'a=rtpmap:<id> <codec>/<rate>'. | 161 // Parse <codec> from 'a=rtpmap:<id> <codec>/<rate>'. |
| 158 var from = sdpLines[lineNo].indexOf(' '); | 162 var from = sdpLines[lineNo].indexOf(' '); |
| 159 var to = sdpLines[lineNo].indexOf('/', from); | 163 var to = sdpLines[lineNo].indexOf('/', from); |
| 160 if (from === null || to === null || from + 1 >= to) | 164 if (from === null || to === null || from + 1 >= to) |
| 161 failure('findRtpmapCodec', ''); | 165 failure('findRtpmapCodec', ''); |
| 162 return sdpLines[lineNo].substring(from + 1, to); | 166 return sdpLines[lineNo].substring(from + 1, to); |
| 163 } | 167 } |
| 164 | 168 |
| 165 /** | 169 /** |
| 166 * Finds the first 'a=rtpmap:' line from |sdpLines| that contains |contains| and | 170 * Finds a 'a=rtpmap:' line from |sdpLines| that contains |contains| and returns |
| 167 * returns its line index, or null if no such line was found. |contains| may be | 171 * its line index, or null if no such line was found. |contains| may be the |
| 168 * the codec ID, codec name or bitrate. An 'a=rtpmap:' line looks like this: | 172 * codec ID, codec name or bitrate. If |searchBackwards| is true, it will return |
|
emircan
2017/08/02 03:42:21
Replace |searchBackwards| with |lastInstance|
magjed_chromium
2017/08/02 08:51:15
Done.
| |
| 169 * 'a=rtpmap:<id> <codec>/<rate>'. | 173 * the last such line index, and if false, it will return the first such line |
| 174 * index. | |
| 175 * An 'a=rtpmap:' line looks like this: 'a=rtpmap:<id> <codec>/<rate>'. | |
| 170 */ | 176 */ |
| 171 function findRtpmapLine(sdpLines, contains) { | 177 function findRtpmapLine(sdpLines, contains, searchBackwards) { |
| 172 for (var i = 0; i < sdpLines.length; i++) { | 178 if (searchBackwards === true) { |
| 173 // Is 'a=rtpmap:' line containing |contains| string? | 179 for (var i = sdpLines.length - 1; i >= 0 ; i--) { |
| 174 if (sdpLines[i].startsWith('a=rtpmap:') && | 180 if (isRtpmapLine(sdpLines[i], contains)) |
| 175 sdpLines[i].indexOf(contains) != -1) { | 181 return i; |
| 176 // Expecting pattern 'a=rtpmap:<id> <codec>/<rate>'. | 182 } |
| 177 var pattern = new RegExp('a=rtpmap:(\\d+) \\w+\\/\\d+'); | 183 } else { |
| 178 if (!sdpLines[i].match(pattern)) | 184 for (var i = 0; i < sdpLines.length; i++) { |
| 179 failure('findRtpmapLine', 'Unexpected "a=rtpmap:" pattern.'); | 185 if (isRtpmapLine(sdpLines[i], contains)) |
| 180 // Return line index. | 186 return i; |
| 181 return i; | |
| 182 } | 187 } |
| 183 } | 188 } |
| 184 return null; | 189 return null; |
| 185 } | 190 } |
| 186 | 191 |
| 187 /** | 192 /** |
| 193 * Returns true if |sdpLine| contains |contains| and is of pattern | |
| 194 * 'a=rtpmap:<id> <codec>/<rate>'. | |
| 195 */ | |
| 196 function isRtpmapLine(sdpLine, contains) { | |
| 197 // Is 'a=rtpmap:' line containing |contains| string? | |
| 198 if (sdpLine.startsWith('a=rtpmap:') && | |
| 199 sdpLine.indexOf(contains) != -1) { | |
| 200 // Expecting pattern 'a=rtpmap:<id> <codec>/<rate>'. | |
| 201 var pattern = new RegExp('a=rtpmap:(\\d+) \\w+\\/\\d+'); | |
| 202 if (!sdpLine.match(pattern)) | |
| 203 failure('isRtpmapLine', 'Unexpected "a=rtpmap:" pattern.'); | |
| 204 return true; | |
| 205 } | |
| 206 return false; | |
| 207 } | |
| 208 | |
| 209 /** | |
| 188 * Finds the fmtp line in |sdpLines| for the given |codecId|, and returns its | 210 * Finds the fmtp line in |sdpLines| for the given |codecId|, and returns its |
| 189 * line number. The line starts with 'a=fmtp:<codecId>'. | 211 * line number. The line starts with 'a=fmtp:<codecId>'. |
| 190 * @private | 212 * @private |
| 191 */ | 213 */ |
| 192 function findFmtpLine(sdpLines, codecId) { | 214 function findFmtpLine(sdpLines, codecId) { |
| 193 return findLine(sdpLines, 'a=fmtp:' + codecId); | 215 return findLine(sdpLines, 'a=fmtp:' + codecId); |
| 194 | 216 |
| 195 } | 217 } |
| 196 | 218 |
| 197 /** | 219 /** |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 } | 267 } |
| 246 | 268 |
| 247 /** @private */ | 269 /** @private */ |
| 248 function findLine(lines, lineStartsWith, startingLine = 0) { | 270 function findLine(lines, lineStartsWith, startingLine = 0) { |
| 249 for (var i = startingLine; i < lines.length; i++) { | 271 for (var i = startingLine; i < lines.length; i++) { |
| 250 if (lines[i].startsWith(lineStartsWith)) | 272 if (lines[i].startsWith(lineStartsWith)) |
| 251 return i; | 273 return i; |
| 252 } | 274 } |
| 253 return null; | 275 return null; |
| 254 } | 276 } |
| OLD | NEW |