7#include <packager/media/codecs/avc_decoder_configuration_record.h>
13#include <absl/log/log.h>
14#include <absl/strings/ascii.h>
15#include <absl/strings/escaping.h>
17#include <packager/media/base/buffer_reader.h>
18#include <packager/media/base/fourccs.h>
19#include <packager/media/base/rcheck.h>
20#include <packager/media/codecs/h264_parser.h>
21#include <packager/media/codecs/nalu_reader.h>
22#include <packager/utils/bytes_to_string_view.h>
27AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord() =
default;
29AVCDecoderConfigurationRecord::~AVCDecoderConfigurationRecord() =
default;
31bool AVCDecoderConfigurationRecord::ParseInternal() {
35 RCHECK(reader.Read1(&version_) && version_ == 1 &&
36 reader.Read1(&profile_indication_) &&
37 reader.Read1(&profile_compatibility_) && reader.Read1(&avc_level_));
39 uint8_t length_size_minus_one;
40 RCHECK(reader.Read1(&length_size_minus_one));
41 if ((length_size_minus_one & 0x3) == 2) {
42 LOG(ERROR) <<
"Invalid NALU length size.";
48 RCHECK(reader.Read1(&num_sps));
51 VLOG(1) <<
"No SPS found.";
54 for (uint8_t i = 0; i < num_sps; i++) {
56 RCHECK(reader.Read2(&size));
57 const uint8_t* nalu_data = reader.data() + reader.pos();
58 RCHECK(reader.SkipBytes(size));
61 RCHECK(
nalu.Initialize(Nalu::kH264, nalu_data, size));
62 RCHECK(
nalu.
type() == Nalu::H264_SPS);
71 RCHECK(parser.ParseSps(
nalu, &sps_id) == H264Parser::kOk);
73 parser.GetSps(sps_id)->transfer_characteristics);
74 RCHECK(ExtractResolutionFromSps(*parser.GetSps(sps_id), &coded_width_,
75 &coded_height_, &pixel_width_,
81 RCHECK(reader.Read1(&pps_count));
82 for (uint8_t i = 0; i < pps_count; i++) {
84 RCHECK(reader.Read2(&size));
85 const uint8_t* nalu_data = reader.data() + reader.pos();
86 RCHECK(reader.SkipBytes(size));
89 RCHECK(
nalu.Initialize(Nalu::kH264, nalu_data, size));
90 RCHECK(
nalu.
type() == Nalu::H264_PPS);
94 if (profile_indication_ == 100 || profile_indication_ == 110 ||
95 profile_indication_ == 122 || profile_indication_ == 144) {
96 uint8_t sps_ext_count;
97 if (!reader.Read1(&chroma_format_) ||
98 !reader.Read1(&bit_depth_luma_minus8_) ||
99 !reader.Read1(&bit_depth_chroma_minus8_) ||
100 !reader.Read1(&sps_ext_count)) {
101 LOG(WARNING) <<
"Insufficient bits in bitstream for given AVC profile";
104 chroma_format_ &= 0x3;
105 bit_depth_luma_minus8_ &= 0x7;
106 bit_depth_chroma_minus8_ &= 0x7;
107 for (uint8_t i = 0; i < sps_ext_count; i++) {
109 RCHECK(reader.Read2(&size));
110 const uint8_t* nalu_data = reader.data() + reader.pos();
111 RCHECK(reader.SkipBytes(size));
114 RCHECK(
nalu.Initialize(Nalu::kH264, nalu_data, size));
115 RCHECK(
nalu.
type() == Nalu::H264_SPSExtension);
123 FourCC codec_fourcc)
const {
125 profile_compatibility_, avc_level_);
130 uint8_t profile_indication,
131 uint8_t profile_compatibility,
133 const uint8_t bytes[] = {profile_indication, profile_compatibility,
135 return FourCCToString(codec_fourcc) +
"." +
136 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.