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

Side by Side Diff: webrtc/common_video/h264/profile_level_id.cc

Issue 2459633002: Add functionality for parsing H264 profile-level-id (Closed)
Patch Set: Fix include order in common_video.gyp 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
(Empty)
1 /*
2 * Copyright (c) 2016 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 #include "webrtc/common_video/h264/profile_level_id.h"
12
13 #include <cstdlib>
14 #include <cstring>
15
16 namespace {
17
18 // For level_idc=11 and profile_idc=0x42, 0x4D, or 0x58, the constraint set3
19 // flag specifies if level 1b or level 1.1 is used.
20 const uint8_t kConstraintSet3Flag = 0x10;
21
22 // Convert a string of 8 characters into a byte where the positions containing
23 // character c will have their bit set. For example, c = 'x', str = "x1xx0000"
24 // will return 0b10110000. constexpr is used so that the pattern table in
25 // kProfilePatterns is statically initialized.
26 constexpr uint8_t ByteMaskString(char c, const char (&str)[9]) {
27 return (str[0] == c) << 7
28 | (str[1] == c) << 6
29 | (str[2] == c) << 5
30 | (str[3] == c) << 4
31 | (str[4] == c) << 3
32 | (str[5] == c) << 2
33 | (str[6] == c) << 1
34 | (str[7] == c) << 0;
35 }
36
37 // Class for matching bit patterns such as "x1xx0000" where 'x' is allowed to be
38 // either 0 or 1.
39 class BitPattern {
40 public:
41 constexpr BitPattern(const char (&str)[9])
42 : mask_(~ByteMaskString('x', str)),
43 masked_value_(ByteMaskString('1', str)) {}
44
45 bool IsMatch(uint8_t value) const { return masked_value_ == (value & mask_); }
46
47 private:
48 const uint8_t mask_;
49 const uint8_t masked_value_;
50 };
51
52 // Table for converting between profile_idc/profile_iop to H264::Profile.
53 struct ProfilePattern {
54 const uint8_t profile_idc;
55 const BitPattern profile_iop;
56 const webrtc::H264::Profile profile;
57 };
58
59 // This is from https://tools.ietf.org/html/rfc6184#section-8.1.
60 constexpr ProfilePattern kProfilePatterns[] = {
61 {0x42, BitPattern("x1xx0000"), webrtc::H264::kProfileConstrainedBaseline},
62 {0x4D, BitPattern("1xxx0000"), webrtc::H264::kProfileConstrainedBaseline},
63 {0x58, BitPattern("11xx0000"), webrtc::H264::kProfileConstrainedBaseline},
64 {0x42, BitPattern("x0xx0000"), webrtc::H264::kProfileBaseline},
65 {0x58, BitPattern("10xx0000"), webrtc::H264::kProfileBaseline},
66 {0x4D, BitPattern("0x0x0000"), webrtc::H264::kProfileMain},
67 {0x64, BitPattern("00000000"), webrtc::H264::kProfileHigh},
68 {0x64, BitPattern("00001100"), webrtc::H264::kProfileConstrainedHigh}};
69
70 } // anonymous namespace
71
72 namespace webrtc {
73 namespace H264 {
74
75 rtc::Optional<ProfileLevelId> ParseProfileLevelId(const char* str) {
76 // The string should consist of 3 bytes in hexadecimal format.
77 if (strlen(str) != 6u)
78 return rtc::Optional<ProfileLevelId>();
79 const uint32_t profile_level_id_numeric = strtol(str, nullptr, 16);
80 if (profile_level_id_numeric == 0)
81 return rtc::Optional<ProfileLevelId>();
82
83 // Separate into three bytes.
84 const uint8_t level_idc =
85 static_cast<uint8_t>(profile_level_id_numeric & 0xFF);
86 const uint8_t profile_iop =
87 static_cast<uint8_t>((profile_level_id_numeric >> 8) & 0xFF);
88 const uint8_t profile_idc =
89 static_cast<uint8_t>((profile_level_id_numeric >> 16) & 0xFF);
90
91 // Parse level based on level_idc and constraint set 3 flag.
92 Level level;
93 switch (level_idc) {
94 case kLevel1_1:
95 level = (profile_iop & kConstraintSet3Flag) != 0 ? kLevel1_b : kLevel1_1;
96 break;
97 case kLevel1:
98 case kLevel1_2:
99 case kLevel1_3:
100 case kLevel2:
101 case kLevel2_1:
102 case kLevel2_2:
103 case kLevel3:
104 case kLevel3_1:
105 case kLevel3_2:
106 case kLevel4:
107 case kLevel4_1:
108 case kLevel4_2:
109 case kLevel5:
110 case kLevel5_1:
111 case kLevel5_2:
112 level = static_cast<Level>(level_idc);
113 break;
114 default:
115 // Unrecognized level_idc.
116 return rtc::Optional<ProfileLevelId>();
117 }
118
119 // Parse profile_idc/profile_iop into a Profile enum.
120 for (const ProfilePattern& pattern : kProfilePatterns) {
121 if (profile_idc == pattern.profile_idc &&
122 pattern.profile_iop.IsMatch(profile_iop)) {
123 return rtc::Optional<ProfileLevelId>({pattern.profile, level});
124 }
125 }
126
127 // Unrecognized profile_idc/profile_iop combination.
128 return rtc::Optional<ProfileLevelId>();
129 }
130
131 } // namespace H264
132 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/common_video/h264/profile_level_id.h ('k') | webrtc/common_video/h264/profile_level_id_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698