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

Side by Side Diff: webrtc/common_types.cc

Issue 2459633002: Add functionality for parsing H264 profile-level-id (Closed)
Patch Set: 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
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 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 #include "webrtc/base/checks.h" 11 #include "webrtc/base/checks.h"
12 #include "webrtc/common_types.h" 12 #include "webrtc/common_types.h"
13 13
14 #include <stdlib.h>
14 #include <string.h> 15 #include <string.h>
15 16
17 namespace {
18
19 // For level_idc=11 and profile_idc=0x42, 0x4D, or 0x58, the constraint set3
20 // flag specifies if level 1b or level 1.1 is used.
21 const uint8_t kConstraintSet3Flag = 0x10;
22
23 // Convert a string of 8 characters into a byte where the positions containing
24 // character c will have their bit set. For example, c = 'x', str = "x1xx0000"
25 // will return 0b10110000. constexpr is used so that the pattern table in
26 // kProfilePatterns is statically initialized.
27 constexpr uint8_t ByteMaskString(char c, const char str[]) {
28 return (str[0] == c) << 7
hta-webrtc 2016/10/28 09:55:22 Can you insert a DCHECK that strlen(str) == 8? Thi
magjed_webrtc 2016/10/28 14:59:27 It's not possible to call non-constexpr functions
tommi 2016/10/28 15:02:20 as one more try, sizeof() == 9? or even specify t
29 | (str[1] == c) << 6
30 | (str[2] == c) << 5
31 | (str[3] == c) << 4
32 | (str[4] == c) << 3
33 | (str[5] == c) << 2
34 | (str[6] == c) << 1
35 | (str[7] == c) << 0;
36 }
37
38 // Class for matching bit patterns such as "x1xx0000" where 'x' is allowed to be
39 // either 0 or 1.
40 class BitPattern {
41 public:
42 constexpr BitPattern(const char str[])
43 : mask_(~ByteMaskString('x', str)),
44 masked_value_(ByteMaskString('1', str)) {}
45
46 bool isMatch(uint8_t value) const { return masked_value_ == (value & mask_); }
tommi 2016/10/28 10:09:47 nit: IsMatch
magjed_webrtc 2016/10/28 14:59:27 Done.
47
48 private:
49 const uint8_t mask_;
50 const uint8_t masked_value_;
51 };
52
53 // Table for converting between profile_idc/profile_iop to H264Profile.
54 struct ProfilePattern {
55 const uint8_t profile_idc;
56 const BitPattern profile_iop;
57 const webrtc::H264Profile profile;
58 };
59
60 // This is from https://tools.ietf.org/html/rfc6184#section-8.1.
61 const ProfilePattern kProfilePatterns[] = {
62 {0x42, BitPattern("x1xx0000"), webrtc::kProfileConstrainedBaseline},
63 {0x4D, BitPattern("1xxx0000"), webrtc::kProfileConstrainedBaseline},
64 {0x58, BitPattern("11xx0000"), webrtc::kProfileConstrainedBaseline},
65 {0x42, BitPattern("x0xx0000"), webrtc::kProfileBaseline},
66 {0x58, BitPattern("10xx0000"), webrtc::kProfileBaseline},
67 {0x4D, BitPattern("0x0x0000"), webrtc::kProfileMain},
68 {0x64, BitPattern("00000000"), webrtc::kProfileHigh},
69 {0x64, BitPattern("00001100"), webrtc::kProfileConstrainedHigh}};
70
71 } // anonymous namespace
72
16 namespace webrtc { 73 namespace webrtc {
17 74
18 StreamDataCounters::StreamDataCounters() : first_packet_time_ms(-1) {} 75 StreamDataCounters::StreamDataCounters() : first_packet_time_ms(-1) {}
19 76
20 RTPHeaderExtension::RTPHeaderExtension() 77 RTPHeaderExtension::RTPHeaderExtension()
21 : hasTransmissionTimeOffset(false), 78 : hasTransmissionTimeOffset(false),
22 transmissionTimeOffset(0), 79 transmissionTimeOffset(0),
23 hasAbsoluteSendTime(false), 80 hasAbsoluteSendTime(false),
24 absoluteSendTime(0), 81 absoluteSendTime(0),
25 hasTransportSequenceNumber(false), 82 hasTransportSequenceNumber(false),
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 VideoCodecH264* VideoCodec::H264() { 141 VideoCodecH264* VideoCodec::H264() {
85 RTC_DCHECK_EQ(codecType, kVideoCodecH264); 142 RTC_DCHECK_EQ(codecType, kVideoCodecH264);
86 return &codecSpecific.H264; 143 return &codecSpecific.H264;
87 } 144 }
88 145
89 const VideoCodecH264& VideoCodec::H264() const { 146 const VideoCodecH264& VideoCodec::H264() const {
90 RTC_DCHECK_EQ(codecType, kVideoCodecH264); 147 RTC_DCHECK_EQ(codecType, kVideoCodecH264);
91 return codecSpecific.H264; 148 return codecSpecific.H264;
92 } 149 }
93 150
151 rtc::Optional<H264ProfileLevelId> ParseH264ProfileLevelId(const char* str) {
hta-webrtc 2016/10/28 09:55:23 Same comment goes for this function.
magjed_webrtc 2016/10/28 14:59:27 I check the string length in this function and ret
152 // The string should consist of 3 bytes in hexadecimal format.
153 if (strlen(str) != 6u)
154 return rtc::Optional<H264ProfileLevelId>();
155 const long profile_level_id_numeric = strtol(str, nullptr, 16);
156 if (profile_level_id_numeric == 0)
157 return rtc::Optional<H264ProfileLevelId>();
158
159 // Separate into three bytes.
160 const uint8_t level_idc =
161 static_cast<uint8_t>(profile_level_id_numeric & 0xFF);
162 const uint8_t profile_iop =
163 static_cast<uint8_t>((profile_level_id_numeric >> 8) & 0xFF);
164 const uint8_t profile_idc =
165 static_cast<uint8_t>((profile_level_id_numeric >> 16) & 0xFF);
166
167 // Parse level based on level_idc and constraint set 3 flag.
168 H264Level level;
169 switch (level_idc) {
170 case kH264Level1_1:
171 level = (profile_iop & kConstraintSet3Flag) != 0 ? kH264Level1_b
172 : kH264Level1_1;
173 break;
174 case kH264Level1:
175 case kH264Level1_2:
176 case kH264Level1_3:
177 case kH264Level2:
178 case kH264Level2_1:
179 case kH264Level2_2:
180 case kH264Level3:
181 case kH264Level3_1:
182 case kH264Level3_2:
183 case kH264Level4:
184 case kH264Level4_1:
185 case kH264Level4_2:
186 case kH264Level5:
187 case kH264Level5_1:
188 case kH264Level5_2:
189 level = static_cast<H264Level>(level_idc);
190 break;
191 default:
192 // Unrecognized level_idc.
193 return rtc::Optional<H264ProfileLevelId>();
194 }
195
196 // Parse profile_idc/profile_iop into a H264Profile enum.
197 for (const ProfilePattern& pattern : kProfilePatterns) {
198 if (profile_idc == pattern.profile_idc &&
199 pattern.profile_iop.isMatch(profile_iop)) {
200 return rtc::Optional<H264ProfileLevelId>({pattern.profile, level});
201 }
202 }
203
204 // Unrecognized profile_idc/profile_iop combination.
205 return rtc::Optional<H264ProfileLevelId>();
206 }
207
94 } // namespace webrtc 208 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698