7 #include <packager/media/codecs/avc_decoder_configuration_record.h>
9 #include <absl/strings/ascii.h>
10 #include <absl/strings/escaping.h>
12 #include <packager/macros/logging.h>
13 #include <packager/media/base/buffer_reader.h>
14 #include <packager/media/base/rcheck.h>
15 #include <packager/media/codecs/h264_parser.h>
16 #include <packager/utils/bytes_to_string_view.h>
21 AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord() =
default;
23 AVCDecoderConfigurationRecord::~AVCDecoderConfigurationRecord() =
default;
25 bool AVCDecoderConfigurationRecord::ParseInternal() {
29 RCHECK(reader.Read1(&version_) && version_ == 1 &&
30 reader.Read1(&profile_indication_) &&
31 reader.Read1(&profile_compatibility_) && reader.Read1(&avc_level_));
33 uint8_t length_size_minus_one;
34 RCHECK(reader.Read1(&length_size_minus_one));
35 if ((length_size_minus_one & 0x3) == 2) {
36 LOG(ERROR) <<
"Invalid NALU length size.";
42 RCHECK(reader.Read1(&num_sps));
45 VLOG(1) <<
"No SPS found.";
48 for (uint8_t i = 0; i < num_sps; i++) {
50 RCHECK(reader.Read2(&size));
51 const uint8_t* nalu_data = reader.data() + reader.pos();
52 RCHECK(reader.SkipBytes(size));
55 RCHECK(
nalu.Initialize(Nalu::kH264, nalu_data, size));
56 RCHECK(
nalu.
type() == Nalu::H264_SPS);
65 RCHECK(parser.ParseSps(
nalu, &sps_id) == H264Parser::kOk);
67 parser.GetSps(sps_id)->transfer_characteristics);
68 RCHECK(ExtractResolutionFromSps(*parser.GetSps(sps_id), &coded_width_,
69 &coded_height_, &pixel_width_,
75 RCHECK(reader.Read1(&pps_count));
76 for (uint8_t i = 0; i < pps_count; i++) {
78 RCHECK(reader.Read2(&size));
79 const uint8_t* nalu_data = reader.data() + reader.pos();
80 RCHECK(reader.SkipBytes(size));
83 RCHECK(
nalu.Initialize(Nalu::kH264, nalu_data, size));
84 RCHECK(
nalu.
type() == Nalu::H264_PPS);
88 if (profile_indication_ == 100 || profile_indication_ == 110 ||
89 profile_indication_ == 122 || profile_indication_ == 144) {
91 uint8_t sps_ext_count;
92 if (!reader.Read1(&chroma_format_) || !reader.Read1(&bit_depth_luma_minus8_) ||
93 !reader.Read1(&bit_depth_chroma_minus8_) || !reader.Read1(&sps_ext_count)) {
94 LOG(WARNING) <<
"Insufficient bits in bitstream for given AVC profile";
97 chroma_format_ &= 0x3;
98 bit_depth_luma_minus8_ &= 0x7;
99 bit_depth_chroma_minus8_ &= 0x7;
100 for (uint8_t i = 0; i < sps_ext_count; i++) {
102 RCHECK(reader.Read2(&size));
103 const uint8_t* nalu_data = reader.data() + reader.pos();
104 RCHECK(reader.SkipBytes(size));
107 RCHECK(
nalu.Initialize(Nalu::kH264, nalu_data, size));
108 RCHECK(
nalu.
type() == Nalu::H264_SPSExtension);
116 FourCC codec_fourcc)
const {
118 profile_compatibility_, avc_level_);
123 uint8_t profile_indication,
124 uint8_t profile_compatibility,
126 const uint8_t bytes[] = {profile_indication, profile_compatibility,
128 return FourCCToString(codec_fourcc) +
"." +
129 absl::AsciiStrToLower(absl::BytesToHexString(
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.