1/* 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#import "ARDSDPUtils.h" 12 13#import "RTCLogging.h" 14#import "RTCSessionDescription.h" 15 16@implementation ARDSDPUtils 17 18+ (RTCSessionDescription *) 19 descriptionForDescription:(RTCSessionDescription *)description 20 preferredVideoCodec:(NSString *)codec { 21 NSString *sdpString = description.description; 22 NSString *lineSeparator = @"\n"; 23 NSString *mLineSeparator = @" "; 24 // Copied from PeerConnectionClient.java. 25 // TODO(tkchin): Move this to a shared C++ file. 26 NSMutableArray *lines = 27 [NSMutableArray arrayWithArray: 28 [sdpString componentsSeparatedByString:lineSeparator]]; 29 NSInteger mLineIndex = -1; 30 NSString *codecRtpMap = nil; 31 // a=rtpmap:<payload type> <encoding name>/<clock rate> 32 // [/<encoding parameters>] 33 NSString *pattern = 34 [NSString stringWithFormat:@"^a=rtpmap:(\\d+) %@(/\\d+)+[\r]?$", codec]; 35 NSRegularExpression *regex = 36 [NSRegularExpression regularExpressionWithPattern:pattern 37 options:0 38 error:nil]; 39 for (NSInteger i = 0; (i < lines.count) && (mLineIndex == -1 || !codecRtpMap); 40 ++i) { 41 NSString *line = lines[i]; 42 if ([line hasPrefix:@"m=video"]) { 43 mLineIndex = i; 44 continue; 45 } 46 NSTextCheckingResult *codecMatches = 47 [regex firstMatchInString:line 48 options:0 49 range:NSMakeRange(0, line.length)]; 50 if (codecMatches) { 51 codecRtpMap = 52 [line substringWithRange:[codecMatches rangeAtIndex:1]]; 53 continue; 54 } 55 } 56 if (mLineIndex == -1) { 57 RTCLog(@"No m=video line, so can't prefer %@", codec); 58 return description; 59 } 60 if (!codecRtpMap) { 61 RTCLog(@"No rtpmap for %@", codec); 62 return description; 63 } 64 NSArray *origMLineParts = 65 [lines[mLineIndex] componentsSeparatedByString:mLineSeparator]; 66 if (origMLineParts.count > 3) { 67 NSMutableArray *newMLineParts = 68 [NSMutableArray arrayWithCapacity:origMLineParts.count]; 69 NSInteger origPartIndex = 0; 70 // Format is: m=<media> <port> <proto> <fmt> ... 71 [newMLineParts addObject:origMLineParts[origPartIndex++]]; 72 [newMLineParts addObject:origMLineParts[origPartIndex++]]; 73 [newMLineParts addObject:origMLineParts[origPartIndex++]]; 74 [newMLineParts addObject:codecRtpMap]; 75 for (; origPartIndex < origMLineParts.count; ++origPartIndex) { 76 if (![codecRtpMap isEqualToString:origMLineParts[origPartIndex]]) { 77 [newMLineParts addObject:origMLineParts[origPartIndex]]; 78 } 79 } 80 NSString *newMLine = 81 [newMLineParts componentsJoinedByString:mLineSeparator]; 82 [lines replaceObjectAtIndex:mLineIndex 83 withObject:newMLine]; 84 } else { 85 RTCLogWarning(@"Wrong SDP media description format: %@", lines[mLineIndex]); 86 } 87 NSString *mangledSdpString = [lines componentsJoinedByString:lineSeparator]; 88 return [[RTCSessionDescription alloc] initWithType:description.type 89 sdp:mangledSdpString]; 90} 91 92@end 93