7 #include "packager/media/filters/hevc_decoder_configuration.h"
9 #include "packager/base/strings/string_number_conversions.h"
10 #include "packager/base/strings/string_util.h"
11 #include "packager/media/base/buffer_reader.h"
12 #include "packager/media/base/rcheck.h"
20 std::string GeneralProfileSpaceAsString(uint8_t general_profile_space) {
21 switch (general_profile_space) {
31 LOG(WARNING) <<
"Unexpected general_profile_space "
32 << general_profile_space;
37 std::string TrimLeadingZeros(
const std::string& str) {
38 DCHECK_GT(str.size(), 0u);
39 for (
size_t i = 0; i < str.size(); ++i) {
40 if (str[i] ==
'0')
continue;
51 std::string ReverseBitsAndHexEncode(uint32_t x) {
52 x = ((x & 0x55555555) << 1) | ((x & 0xAAAAAAAA) >> 1);
53 x = ((x & 0x33333333) << 2) | ((x & 0xCCCCCCCC) >> 2);
54 x = ((x & 0x0F0F0F0F) << 4) | ((x & 0xF0F0F0F0) >> 4);
55 const uint8_t bytes[] = {
static_cast<uint8_t
>(x & 0xFF),
56 static_cast<uint8_t>((x >> 8) & 0xFF),
57 static_cast<uint8_t>((x >> 16) & 0xFF),
58 static_cast<uint8_t>((x >> 24) & 0xFF)};
59 return TrimLeadingZeros(base::HexEncode(bytes, arraysize(bytes)));
62 std::string CodecAsString(VideoCodec codec) {
69 LOG(WARNING) <<
"Unknown codec: " << codec;
76 HEVCDecoderConfiguration::HEVCDecoderConfiguration()
78 general_profile_space_(0),
79 general_tier_flag_(false),
80 general_profile_idc_(0),
81 general_profile_compatibility_flags_(0),
82 general_level_idc_(0) {}
84 HEVCDecoderConfiguration::~HEVCDecoderConfiguration() {}
86 bool HEVCDecoderConfiguration::ParseInternal() {
89 uint8_t profile_indication = 0;
90 uint8_t length_size_minus_one = 0;
91 uint8_t num_of_arrays = 0;
92 RCHECK(reader.Read1(&version_) && version_ == 1 &&
93 reader.Read1(&profile_indication) &&
94 reader.Read4(&general_profile_compatibility_flags_) &&
95 reader.ReadToVector(&general_constraint_indicator_flags_, 6) &&
96 reader.Read1(&general_level_idc_) &&
97 reader.SkipBytes(8) &&
98 reader.Read1(&length_size_minus_one) &&
99 reader.Read1(&num_of_arrays));
101 general_profile_space_ = profile_indication >> 6;
102 RCHECK(general_profile_space_ <= 3u);
103 general_tier_flag_ = ((profile_indication >> 5) & 1) == 1;
104 general_profile_idc_ = profile_indication & 0x1f;
106 if ((length_size_minus_one & 0x3) == 2) {
107 LOG(ERROR) <<
"Invalid NALU length size.";
112 for (
int i = 0; i < num_of_arrays; i++) {
113 uint8_t nal_unit_type;
115 RCHECK(reader.Read1(&nal_unit_type));
116 nal_unit_type &= 0x3f;
117 RCHECK(reader.Read2(&num_nalus));
118 for (
int j = 0; j < num_nalus; j++) {
119 uint16_t nalu_length;
120 RCHECK(reader.Read2(&nalu_length));
121 uint64_t nalu_offset = reader.pos();
122 RCHECK(reader.SkipBytes(nalu_length));
125 RCHECK(nalu.Initialize(Nalu::kH265,
data() + nalu_offset, nalu_length));
126 RCHECK(nalu.type() == nal_unit_type);
137 std::vector<std::string> fields;
138 fields.push_back(CodecAsString(codec));
139 fields.push_back(GeneralProfileSpaceAsString(general_profile_space_) +
140 base::IntToString(general_profile_idc_));
142 ReverseBitsAndHexEncode(general_profile_compatibility_flags_));
143 fields.push_back((general_tier_flag_ ?
"H" :
"L") +
144 base::IntToString(general_level_idc_));
147 std::vector<uint8_t> constraints = general_constraint_indicator_flags_;
148 size_t size = constraints.size();
149 for (; size > 0; --size) {
150 if (constraints[size - 1] != 0)
break;
152 constraints.resize(size);
153 for (uint8_t constraint : constraints)
154 fields.push_back(TrimLeadingZeros(base::HexEncode(&constraint, 1)));
156 return base::JoinString(fields,
".");