Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: webrtc/examples/objc/AppRTCMobile/ARDSDPUtils.m

Issue 2520933002: iOS AppRTCMobile: Fix SDP video codec reordering for multiple H264 profiles (Closed)
Patch Set: Rename h264Desc Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | webrtc/examples/objc/AppRTCMobile/tests/ARDAppClientTest.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #import "ARDSDPUtils.h" 11 #import "ARDSDPUtils.h"
12 12
13 #import "WebRTC/RTCLogging.h" 13 #import "WebRTC/RTCLogging.h"
14 #import "WebRTC/RTCSessionDescription.h" 14 #import "WebRTC/RTCSessionDescription.h"
15 15
16 @implementation ARDSDPUtils 16 @implementation ARDSDPUtils
17 17
18 + (RTCSessionDescription *) 18 + (RTCSessionDescription *)
19 descriptionForDescription:(RTCSessionDescription *)description 19 descriptionForDescription:(RTCSessionDescription *)description
20 preferredVideoCodec:(NSString *)codec { 20 preferredVideoCodec:(NSString *)codec {
21 NSString *sdpString = description.sdp; 21 NSString *sdpString = description.sdp;
22 NSString *lineSeparator = @"\n"; 22 NSString *lineSeparator = @"\n";
23 NSString *mLineSeparator = @" "; 23 NSString *mLineSeparator = @" ";
24 // Copied from PeerConnectionClient.java. 24 // Copied from PeerConnectionClient.java.
25 // TODO(tkchin): Move this to a shared C++ file. 25 // TODO(tkchin): Move this to a shared C++ file.
26 NSMutableArray *lines = 26 NSMutableArray *lines =
27 [NSMutableArray arrayWithArray: 27 [NSMutableArray arrayWithArray:
28 [sdpString componentsSeparatedByString:lineSeparator]]; 28 [sdpString componentsSeparatedByString:lineSeparator]];
29 // Find the line starting with "m=video".
29 NSInteger mLineIndex = -1; 30 NSInteger mLineIndex = -1;
30 NSString *codecRtpMap = nil; 31 for (NSInteger i = 0; i < lines.count; ++i) {
32 if ([lines[i] hasPrefix:@"m=video"]) {
33 mLineIndex = i;
34 break;
35 }
36 }
37 if (mLineIndex == -1) {
38 RTCLog(@"No m=video line, so can't prefer %@", codec);
39 return description;
40 }
41 // An array with all payload types with name |codec|. The payload types are
42 // integers in the range 96-127, but they are stored as strings here.
43 NSMutableArray *codecPayloadTypes = [[NSMutableArray alloc] init];
31 // a=rtpmap:<payload type> <encoding name>/<clock rate> 44 // a=rtpmap:<payload type> <encoding name>/<clock rate>
32 // [/<encoding parameters>] 45 // [/<encoding parameters>]
33 NSString *pattern = 46 NSString *pattern =
34 [NSString stringWithFormat:@"^a=rtpmap:(\\d+) %@(/\\d+)+[\r]?$", codec]; 47 [NSString stringWithFormat:@"^a=rtpmap:(\\d+) %@(/\\d+)+[\r]?$", codec];
35 NSRegularExpression *regex = 48 NSRegularExpression *regex =
36 [NSRegularExpression regularExpressionWithPattern:pattern 49 [NSRegularExpression regularExpressionWithPattern:pattern
37 options:0 50 options:0
38 error:nil]; 51 error:nil];
39 for (NSInteger i = 0; (i < lines.count) && (mLineIndex == -1 || !codecRtpMap); 52 for (NSString *line in lines) {
40 ++i) {
41 NSString *line = lines[i];
42 if ([line hasPrefix:@"m=video"]) {
43 mLineIndex = i;
44 continue;
45 }
46 NSTextCheckingResult *codecMatches = 53 NSTextCheckingResult *codecMatches =
47 [regex firstMatchInString:line 54 [regex firstMatchInString:line
48 options:0 55 options:0
49 range:NSMakeRange(0, line.length)]; 56 range:NSMakeRange(0, line.length)];
50 if (codecMatches) { 57 if (codecMatches) {
51 codecRtpMap = 58 [codecPayloadTypes
52 [line substringWithRange:[codecMatches rangeAtIndex:1]]; 59 addObject:[line substringWithRange:[codecMatches rangeAtIndex:1]]];
53 continue;
54 } 60 }
55 } 61 }
56 if (mLineIndex == -1) { 62 if ([codecPayloadTypes count] == 0) {
57 RTCLog(@"No m=video line, so can't prefer %@", codec); 63 RTCLog(@"No payload types with name %@", codec);
58 return description;
59 }
60 if (!codecRtpMap) {
61 RTCLog(@"No rtpmap for %@", codec);
62 return description; 64 return description;
63 } 65 }
64 NSArray *origMLineParts = 66 NSArray *origMLineParts =
65 [lines[mLineIndex] componentsSeparatedByString:mLineSeparator]; 67 [lines[mLineIndex] componentsSeparatedByString:mLineSeparator];
66 if (origMLineParts.count > 3) { 68 // The format of ML should be: m=<media> <port> <proto> <fmt> ...
67 NSMutableArray *newMLineParts = 69 const int kHeaderLength = 3;
68 [NSMutableArray arrayWithCapacity:origMLineParts.count]; 70 if (origMLineParts.count <= kHeaderLength) {
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]); 71 RTCLogWarning(@"Wrong SDP media description format: %@", lines[mLineIndex]);
72 return description;
86 } 73 }
74 // Split the line into header and payloadTypes.
75 NSRange headerRange = NSMakeRange(0, kHeaderLength);
76 NSRange payloadRange =
77 NSMakeRange(kHeaderLength, origMLineParts.count - kHeaderLength);
78 NSArray *header = [origMLineParts subarrayWithRange:headerRange];
79 NSMutableArray *payloadTypes = [NSMutableArray
80 arrayWithArray:[origMLineParts subarrayWithRange:payloadRange]];
81 // Reconstruct the line with |codecPayloadTypes| moved to the beginning of the
82 // payload types.
83 NSMutableArray *newMLineParts = [NSMutableArray arrayWithCapacity:origMLinePar ts.count];
84 [newMLineParts addObjectsFromArray:header];
85 [newMLineParts addObjectsFromArray:codecPayloadTypes];
86 [payloadTypes removeObjectsInArray:codecPayloadTypes];
87 [newMLineParts addObjectsFromArray:payloadTypes];
88
89 NSString *newMLine = [newMLineParts componentsJoinedByString:mLineSeparator];
90 [lines replaceObjectAtIndex:mLineIndex
91 withObject:newMLine];
92
87 NSString *mangledSdpString = [lines componentsJoinedByString:lineSeparator]; 93 NSString *mangledSdpString = [lines componentsJoinedByString:lineSeparator];
88 return [[RTCSessionDescription alloc] initWithType:description.type 94 return [[RTCSessionDescription alloc] initWithType:description.type
89 sdp:mangledSdpString]; 95 sdp:mangledSdpString];
90 } 96 }
91 97
92 @end 98 @end
OLDNEW
« no previous file with comments | « no previous file | webrtc/examples/objc/AppRTCMobile/tests/ARDAppClientTest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698