blob: 3a8a578dc68fccf47cab303d315866749a494893 [file] [log] [blame]
Zeke Chin71f6f442015-06-29 14:34:58 -07001/*
Donald E Curtisa8736442015-08-05 15:48:13 -07002 * Copyright 2015 The WebRTC Project Authors. All rights reserved.
Zeke Chin71f6f442015-06-29 14:34:58 -07003 *
Donald E Curtisa8736442015-08-05 15:48:13 -07004 * 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.
Zeke Chin71f6f442015-06-29 14:34:58 -07009 */
10
11#import "ARDSDPUtils.h"
12
tkchin9eeb6242016-04-27 01:54:20 -070013#import "WebRTC/RTCLogging.h"
14#import "WebRTC/RTCSessionDescription.h"
Zeke Chin71f6f442015-06-29 14:34:58 -070015
16@implementation ARDSDPUtils
17
18+ (RTCSessionDescription *)
19 descriptionForDescription:(RTCSessionDescription *)description
20 preferredVideoCodec:(NSString *)codec {
hjon79858f82016-03-13 22:08:26 -070021 NSString *sdpString = description.sdp;
Zeke Chin71f6f442015-06-29 14:34:58 -070022 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]];
Zeke Chin2d3b7e22015-07-14 12:55:44 -070029 NSInteger mLineIndex = -1;
Zeke Chin71f6f442015-06-29 14:34:58 -070030 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) {
tkchinc3f46a92015-07-23 12:50:55 -070057 RTCLog(@"No m=video line, so can't prefer %@", codec);
Zeke Chin71f6f442015-06-29 14:34:58 -070058 return description;
59 }
60 if (!codecRtpMap) {
tkchinc3f46a92015-07-23 12:50:55 -070061 RTCLog(@"No rtpmap for %@", codec);
Zeke Chin71f6f442015-06-29 14:34:58 -070062 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 {
tkchinc3f46a92015-07-23 12:50:55 -070085 RTCLogWarning(@"Wrong SDP media description format: %@", lines[mLineIndex]);
Zeke Chin71f6f442015-06-29 14:34:58 -070086 }
87 NSString *mangledSdpString = [lines componentsJoinedByString:lineSeparator];
88 return [[RTCSessionDescription alloc] initWithType:description.type
89 sdp:mangledSdpString];
90}
91
92@end