Shaka Packager SDK
Loading...
Searching...
No Matches
avc_decoder_configuration_record.cc
1// Copyright 2015 Google LLC. All rights reserved.
2//
3// Use of this source code is governed by a BSD-style
4// license that can be found in the LICENSE file or at
5// https://developers.google.com/open-source/licenses/bsd
6
7#include <packager/media/codecs/avc_decoder_configuration_record.h>
8
9#include <absl/strings/ascii.h>
10#include <absl/strings/escaping.h>
11
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>
17
18namespace shaka {
19namespace media {
20
21AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord() = default;
22
23AVCDecoderConfigurationRecord::~AVCDecoderConfigurationRecord() = default;
24
25bool AVCDecoderConfigurationRecord::ParseInternal() {
26 // See ISO 14496-15 sec 5.3.3.1.2
27 BufferReader reader(data(), data_size());
28
29 RCHECK(reader.Read1(&version_) && version_ == 1 &&
30 reader.Read1(&profile_indication_) &&
31 reader.Read1(&profile_compatibility_) && reader.Read1(&avc_level_));
32
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.";
37 return false;
38 }
39 set_nalu_length_size((length_size_minus_one & 0x3) + 1);
40
41 uint8_t num_sps;
42 RCHECK(reader.Read1(&num_sps));
43 num_sps &= 0x1f;
44 if (num_sps < 1) {
45 VLOG(1) << "No SPS found.";
46 }
47
48 for (uint8_t i = 0; i < num_sps; i++) {
49 uint16_t size = 0;
50 RCHECK(reader.Read2(&size));
51 const uint8_t* nalu_data = reader.data() + reader.pos();
52 RCHECK(reader.SkipBytes(size));
53
54 Nalu nalu;
55 RCHECK(nalu.Initialize(Nalu::kH264, nalu_data, size));
56 RCHECK(nalu.type() == Nalu::H264_SPS);
58
59 if (i == 0) {
60 // It is unlikely to have more than one SPS in practice. Also there's
61 // no way to change the {coded,pixel}_{width,height} dynamically from
62 // VideoStreamInfo.
63 int sps_id = 0;
64 H264Parser parser;
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_,
70 &pixel_height_));
71 }
72 }
73
74 uint8_t pps_count;
75 RCHECK(reader.Read1(&pps_count));
76 for (uint8_t i = 0; i < pps_count; i++) {
77 uint16_t size = 0;
78 RCHECK(reader.Read2(&size));
79 const uint8_t* nalu_data = reader.data() + reader.pos();
80 RCHECK(reader.SkipBytes(size));
81
82 Nalu nalu;
83 RCHECK(nalu.Initialize(Nalu::kH264, nalu_data, size));
84 RCHECK(nalu.type() == Nalu::H264_PPS);
86 }
87
88 if (profile_indication_ == 100 || profile_indication_ == 110 ||
89 profile_indication_ == 122 || profile_indication_ == 144) {
90
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";
95 return true;
96 }
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++) {
101 uint16_t size = 0;
102 RCHECK(reader.Read2(&size));
103 const uint8_t* nalu_data = reader.data() + reader.pos();
104 RCHECK(reader.SkipBytes(size));
105
106 Nalu nalu;
107 RCHECK(nalu.Initialize(Nalu::kH264, nalu_data, size));
108 RCHECK(nalu.type() == Nalu::H264_SPSExtension);
109 AddNalu(nalu);
110 }
111 }
112 return true;
113}
114
116 FourCC codec_fourcc) const {
117 return GetCodecString(codec_fourcc, profile_indication_,
118 profile_compatibility_, avc_level_);
119}
120
122 FourCC codec_fourcc,
123 uint8_t profile_indication,
124 uint8_t profile_compatibility,
125 uint8_t avc_level) {
126 const uint8_t bytes[] = {profile_indication, profile_compatibility,
127 avc_level};
128 return FourCCToString(codec_fourcc) + "." +
129 absl::AsciiStrToLower(absl::BytesToHexString(
130 byte_array_to_string_view(bytes, std::size(bytes))));
131}
132
133} // namespace media
134} // namespace shaka
void AddNalu(const Nalu &nalu)
Adds the given Nalu to the configuration.
void set_transfer_characteristics(uint8_t transfer_characteristics)
Sets the transfer characteristics.
void set_nalu_length_size(uint8_t nalu_length_size)
Sets the size of the NAL unit length field.
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.