7 #include <packager/media/codecs/hevc_decoder_configuration_record.h>
9 #include <absl/log/check.h>
10 #include <absl/strings/escaping.h>
11 #include <absl/strings/str_format.h>
12 #include <absl/strings/str_join.h>
14 #include <packager/media/base/buffer_reader.h>
15 #include <packager/media/base/rcheck.h>
16 #include <packager/media/codecs/h265_parser.h>
17 #include <packager/utils/bytes_to_string_view.h>
25 std::string GeneralProfileSpaceAsString(uint8_t general_profile_space) {
26 switch (general_profile_space) {
36 LOG(WARNING) <<
"Unexpected general_profile_space "
37 << general_profile_space;
42 std::string TrimLeadingZeros(
const std::string& str) {
43 DCHECK_GT(str.size(), 0u);
44 for (
size_t i = 0; i < str.size(); ++i) {
45 if (str[i] ==
'0')
continue;
56 std::string ReverseBitsAndHexEncode(uint32_t x) {
57 x = ((x & 0x55555555) << 1) | ((x & 0xAAAAAAAA) >> 1);
58 x = ((x & 0x33333333) << 2) | ((x & 0xCCCCCCCC) >> 2);
59 x = ((x & 0x0F0F0F0F) << 4) | ((x & 0xF0F0F0F0) >> 4);
60 const uint8_t bytes[] = {
static_cast<uint8_t
>(x & 0xFF),
61 static_cast<uint8_t
>((x >> 8) & 0xFF),
62 static_cast<uint8_t
>((x >> 16) & 0xFF),
63 static_cast<uint8_t
>((x >> 24) & 0xFF)};
64 return TrimLeadingZeros(absl::BytesToHexString(
70 HEVCDecoderConfigurationRecord::HEVCDecoderConfigurationRecord() =
default;
72 HEVCDecoderConfigurationRecord::~HEVCDecoderConfigurationRecord() =
default;
74 bool HEVCDecoderConfigurationRecord::ParseInternal() {
77 uint8_t profile_indication = 0;
78 uint8_t length_size_minus_one = 0;
79 uint8_t num_of_arrays = 0;
80 RCHECK(reader.Read1(&version_) && version_ == 1 &&
81 reader.Read1(&profile_indication) &&
82 reader.Read4(&general_profile_compatibility_flags_) &&
83 reader.ReadToVector(&general_constraint_indicator_flags_, 6) &&
84 reader.Read1(&general_level_idc_) &&
85 reader.SkipBytes(8) &&
86 reader.Read1(&length_size_minus_one) &&
87 reader.Read1(&num_of_arrays));
89 general_profile_space_ = profile_indication >> 6;
90 RCHECK(general_profile_space_ <= 3u);
91 general_tier_flag_ = ((profile_indication >> 5) & 1) == 1;
92 general_profile_idc_ = profile_indication & 0x1f;
94 if ((length_size_minus_one & 0x3) == 2) {
95 LOG(ERROR) <<
"Invalid NALU length size.";
100 for (
int i = 0; i < num_of_arrays; i++) {
101 uint8_t nal_unit_type;
103 RCHECK(reader.Read1(&nal_unit_type));
104 nal_unit_type &= 0x3f;
105 RCHECK(reader.Read2(&num_nalus));
106 for (
int j = 0; j < num_nalus; j++) {
107 uint16_t nalu_length;
108 RCHECK(reader.Read2(&nalu_length));
109 uint64_t nalu_offset = reader.pos();
110 RCHECK(reader.SkipBytes(nalu_length));
113 RCHECK(
nalu.Initialize(Nalu::kH265,
data() + nalu_offset, nalu_length));
114 RCHECK(
nalu.
type() == nal_unit_type);
117 if (
nalu.
type() == Nalu::H265_SPS) {
120 RCHECK(parser.ParseSps(
nalu, &sps_id) == H265Parser::kOk);
122 parser.GetSps(sps_id)->vui_parameters.transfer_characteristics);
124 parser.GetSps(sps_id)->vui_parameters.color_primaries);
126 parser.GetSps(sps_id)->vui_parameters.matrix_coefficients);
136 FourCC codec_fourcc)
const {
138 std::vector<std::string> fields;
139 fields.push_back(FourCCToString(codec_fourcc));
140 fields.push_back(GeneralProfileSpaceAsString(general_profile_space_) +
141 absl::StrFormat(
"%d", general_profile_idc_));
143 ReverseBitsAndHexEncode(general_profile_compatibility_flags_));
144 fields.push_back((general_tier_flag_ ?
"H" :
"L") +
145 absl::StrFormat(
"%d", general_level_idc_));
148 std::vector<uint8_t> constraints = general_constraint_indicator_flags_;
149 size_t size = constraints.size();
150 for (; size > 0; --size) {
151 if (constraints[size - 1] != 0)
break;
153 constraints.resize(size);
154 for (uint8_t constraint : constraints)
155 fields.push_back(TrimLeadingZeros(
158 return absl::StrJoin(fields,
".");
All the methods that are virtual are virtual for mocking.
std::string_view byte_array_to_string_view(const uint8_t *bytes, size_t bytes_size)
Convert byte array to string_view.