1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- /*
- * Copyright 2015 The WebRTC Project Authors. All rights reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
- #import "ARDSDPUtils.h"
- #import "WebRTC/RTCLogging.h"
- #import "WebRTC/RTCSessionDescription.h"
- @implementation ARDSDPUtils
- + (RTCSessionDescription *)
- descriptionForDescription:(RTCSessionDescription *)description
- preferredVideoCodec:(NSString *)codec {
- NSString *sdpString = description.sdp;
- NSString *lineSeparator = @"\n";
- NSString *mLineSeparator = @" ";
- // Copied from PeerConnectionClient.java.
- // TODO(tkchin): Move this to a shared C++ file.
- NSMutableArray *lines =
- [NSMutableArray arrayWithArray:
- [sdpString componentsSeparatedByString:lineSeparator]];
- // Find the line starting with "m=video".
- NSInteger mLineIndex = -1;
- for (NSInteger i = 0; i < lines.count; ++i) {
- if ([lines[i] hasPrefix:@"m=video"]) {
- mLineIndex = i;
- break;
- }
- }
- if (mLineIndex == -1) {
- RTCLog(@"No m=video line, so can't prefer %@", codec);
- return description;
- }
- // An array with all payload types with name |codec|. The payload types are
- // integers in the range 96-127, but they are stored as strings here.
- NSMutableArray *codecPayloadTypes = [[NSMutableArray alloc] init];
- // a=rtpmap:<payload type> <encoding name>/<clock rate>
- // [/<encoding parameters>]
- NSString *pattern =
- [NSString stringWithFormat:@"^a=rtpmap:(\\d+) %@(/\\d+)+[\r]?$", codec];
- NSRegularExpression *regex =
- [NSRegularExpression regularExpressionWithPattern:pattern
- options:0
- error:nil];
- for (NSString *line in lines) {
- NSTextCheckingResult *codecMatches =
- [regex firstMatchInString:line
- options:0
- range:NSMakeRange(0, line.length)];
- if (codecMatches) {
- [codecPayloadTypes
- addObject:[line substringWithRange:[codecMatches rangeAtIndex:1]]];
- }
- }
- if ([codecPayloadTypes count] == 0) {
- RTCLog(@"No payload types with name %@", codec);
- return description;
- }
- NSArray *origMLineParts =
- [lines[mLineIndex] componentsSeparatedByString:mLineSeparator];
- // The format of ML should be: m=<media> <port> <proto> <fmt> ...
- const int kHeaderLength = 3;
- if (origMLineParts.count <= kHeaderLength) {
- RTCLogWarning(@"Wrong SDP media description format: %@", lines[mLineIndex]);
- return description;
- }
- // Split the line into header and payloadTypes.
- NSRange headerRange = NSMakeRange(0, kHeaderLength);
- NSRange payloadRange =
- NSMakeRange(kHeaderLength, origMLineParts.count - kHeaderLength);
- NSArray *header = [origMLineParts subarrayWithRange:headerRange];
- NSMutableArray *payloadTypes = [NSMutableArray
- arrayWithArray:[origMLineParts subarrayWithRange:payloadRange]];
- // Reconstruct the line with |codecPayloadTypes| moved to the beginning of the
- // payload types.
- NSMutableArray *newMLineParts = [NSMutableArray arrayWithCapacity:origMLineParts.count];
- [newMLineParts addObjectsFromArray:header];
- [newMLineParts addObjectsFromArray:codecPayloadTypes];
- [payloadTypes removeObjectsInArray:codecPayloadTypes];
- [newMLineParts addObjectsFromArray:payloadTypes];
- NSString *newMLine = [newMLineParts componentsJoinedByString:mLineSeparator];
- [lines replaceObjectAtIndex:mLineIndex
- withObject:newMLine];
- NSString *mangledSdpString = [lines componentsJoinedByString:lineSeparator];
- return [[RTCSessionDescription alloc] initWithType:description.type
- sdp:mangledSdpString];
- }
- @end
|