Shaka Packager SDK
Loading...
Searching...
No Matches
es_descriptor.cc
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <packager/media/codecs/es_descriptor.h>
6
7#include <absl/log/check.h>
8
9#include <packager/media/base/bit_reader.h>
10#include <packager/media/base/buffer_writer.h>
11#include <packager/media/base/rcheck.h>
12
13namespace shaka {
14namespace media {
15namespace {
16
17// ISO/IEC 14496-1:2004 Section 7.2.6.6 Table 6: StreamType values.
18enum StreamType {
19 kForbiddenStreamType = 0x00,
20 kObjectDescriptorStreamType = 0x01,
21 kClockReferenceStreamType = 0x02,
22 kSceneDescriptionStreamType = 0x03,
23 kVisualStreamType = 0x04,
24 kAudioStreamType = 0x05,
25 kMPEG7StreamType = 0x06,
26 kIPMPStreamType = 0x07,
27 kObjectContentInfoStreamType = 0x08,
28 kMPEGJStreamType = 0x09,
29 kInteractionStream = 0x0A,
30 kIPMPToolStreamType = 0x0B,
31};
32
33// ISO/IEC 14496-1:2004 Section 7.3.2.3 Table 12: ISO SL Config Descriptor.
34enum SLPredefinedTags {
35 kSLPredefinedNull = 0x01,
36 kSLPredefinedMP4 = 0x02,
37};
38
39// The elementary stream size is specific by up to 4 bytes.
40// The MSB of a byte indicates if there are more bytes for the size.
41bool ReadDescriptorSize(BitReader* reader, size_t* size) {
42 uint8_t msb;
43 uint8_t byte;
44
45 *size = 0;
46
47 for (size_t i = 0; i < 4; ++i) {
48 RCHECK(reader->ReadBits(1, &msb));
49 RCHECK(reader->ReadBits(7, &byte));
50 *size = (*size << 7) + byte;
51
52 if (msb == 0)
53 break;
54 }
55
56 return true;
57}
58
59void WriteDescriptorSize(size_t size, BufferWriter* writer) {
60 std::vector<uint8_t> size_bytes;
61 while (size > 0) {
62 uint8_t byte = (size & 0x7F);
63 size >>= 7;
64 if (!size_bytes.empty())
65 byte |= 0x80;
66 size_bytes.push_back(byte);
67 }
68 for (auto iter = size_bytes.rbegin(); iter != size_bytes.rend(); iter++)
69 writer->AppendInt(*iter);
70}
71
72size_t CountDescriptorSize(size_t size) {
73 size_t num_bytes = 0;
74 while (size > 0) {
75 num_bytes++;
76 size >>= 7;
77 }
78 return num_bytes;
79}
80
81} // namespace
82
83bool BaseDescriptor::Parse(const std::vector<uint8_t>& data) {
84 BitReader reader(data.data(), data.size());
85 return Read(&reader);
86}
87
89 uint8_t tag;
90 RCHECK(reader->ReadBits(8, &tag));
91 if (tag != static_cast<uint8_t>(tag_)) {
92 LOG(ERROR) << "Expecting tag " << static_cast<int>(tag_) << ", but seeing "
93 << static_cast<int>(tag);
94 return false;
95 }
96 RCHECK(ReadDescriptorSize(reader, &data_size_));
97 return ReadData(reader);
98}
99
101 // Compute and update descriptor size.
102 size_t size = ComputeSize();
103 size_t buffer_size_before_write = writer->Size();
104
105 WriteInternal(writer);
106
107 DCHECK_EQ(size, writer->Size() - buffer_size_before_write);
108}
109
111 data_size_ = ComputeDataSize();
112 return 1 + CountDescriptorSize(data_size_) + data_size_;
113}
114
116 writer->AppendInt(static_cast<uint8_t>(tag_));
117 WriteDescriptorSize(data_size_, writer);
118}
119
120bool DecoderSpecificInfoDescriptor::ReadData(BitReader* reader) {
121 data_.resize(data_size());
122 for (uint8_t& data_entry : data_)
123 RCHECK(reader->ReadBits(8, &data_entry));
124 return true;
125}
126
127void DecoderSpecificInfoDescriptor::WriteInternal(BufferWriter* writer) {
128 WriteHeader(writer);
129 writer->AppendVector(data_);
130}
131
132size_t DecoderSpecificInfoDescriptor::ComputeDataSize() {
133 return data_.size();
134}
135
136bool DecoderConfigDescriptor::ReadData(BitReader* reader) {
137 const size_t start_pos = reader->bit_position();
138 RCHECK(reader->ReadBits(8, &object_type_));
139
140 int stream_type;
141 RCHECK(reader->ReadBits(6, &stream_type));
142 if (stream_type != kAudioStreamType) {
143 LOG(ERROR) << "Seeing non audio stream type " << stream_type;
144 return false;
145 }
146
147 RCHECK(reader->SkipBits(2)); // Skip |upStream| and |reserved|.
148 RCHECK(reader->ReadBits(24, &buffer_size_db_));
149 RCHECK(reader->ReadBits(32, &max_bitrate_));
150 RCHECK(reader->ReadBits(32, &avg_bitrate_));
151 const size_t fields_bits = reader->bit_position() - start_pos;
152
153 const size_t kBitsInByte = 8;
154 const bool has_child_tags = data_size() * kBitsInByte > fields_bits;
155 decoder_specific_info_descriptor_ = DecoderSpecificInfoDescriptor();
156 if (has_child_tags)
157 RCHECK(decoder_specific_info_descriptor_.Read(reader));
158
159 return true;
160}
161
162void DecoderConfigDescriptor::WriteInternal(BufferWriter* writer) {
163 WriteHeader(writer);
164
165 writer->AppendInt(static_cast<uint8_t>(object_type_));
166 // 6 bit stream type. The last bit is reserved with 1.
167 const uint8_t stream_type = (kAudioStreamType << 2) | 1;
168 writer->AppendInt(stream_type);
169 writer->AppendNBytes(buffer_size_db_, 3);
170 writer->AppendInt(max_bitrate_);
171 writer->AppendInt(avg_bitrate_);
172
173 if (!decoder_specific_info_descriptor_.data().empty())
174 decoder_specific_info_descriptor_.Write(writer);
175}
176
177size_t DecoderConfigDescriptor::ComputeDataSize() {
178 // object_type (1 byte), stream_type (1 byte), decoding_buffer_size (3 bytes),
179 // max_bitrate (4 bytes), avg_bitrate (4 bytes).
180 const size_t data_size_without_children = 1 + 1 + 3 + 4 + 4;
181 if (decoder_specific_info_descriptor_.data().empty())
182 return data_size_without_children;
183 return data_size_without_children +
184 decoder_specific_info_descriptor_.ComputeSize();
185}
186
187bool SLConfigDescriptor::ReadData(BitReader*) {
188 return true;
189}
190
191void SLConfigDescriptor::WriteInternal(BufferWriter* writer) {
192 WriteHeader(writer);
193 writer->AppendInt(static_cast<uint8_t>(kSLPredefinedMP4));
194}
195
196size_t SLConfigDescriptor::ComputeDataSize() {
197 return 1;
198}
199
200bool ESDescriptor::ReadData(BitReader* reader) {
201 bool stream_dependency_flag;
202 bool url_flag;
203 bool ocr_stream_flag;
204 RCHECK(reader->ReadBits(16, &esid_));
205 RCHECK(reader->ReadBits(1, &stream_dependency_flag));
206 RCHECK(reader->ReadBits(1, &url_flag));
207 RCHECK(!url_flag); // We don't support url flag
208 RCHECK(reader->ReadBits(1, &ocr_stream_flag));
209 RCHECK(reader->SkipBits(5)); // streamPriority
210
211 if (stream_dependency_flag)
212 RCHECK(reader->SkipBits(16)); // dependsOn_ES_ID
213 if (ocr_stream_flag)
214 RCHECK(reader->SkipBits(16)); // OCR_ES_Id
215
216 return decoder_config_descriptor_.Read(reader);
217 // Skip the parsing of |sl_config_descriptor_| intentionally as we do not care
218 // about the data.
219}
220
221void ESDescriptor::WriteInternal(BufferWriter* writer) {
222 WriteHeader(writer);
223
224 // According to ISO/IEC 14496-14:2018 Section 4.1.2,
225 // ES_ID is set to 0 when stored
226 const uint16_t kEsid = 0;
227 writer->AppendInt(kEsid);
228 const uint8_t kNoEsFlags = 0;
229 writer->AppendInt(kNoEsFlags);
230
231 decoder_config_descriptor_.Write(writer);
232 sl_config_descriptor_.Write(writer);
233}
234
235size_t ESDescriptor::ComputeDataSize() {
236 // esid (2 bytes), es_flags (1 byte).
237 const size_t data_size_without_children = 2 + 1;
238 return data_size_without_children + decoder_config_descriptor_.ComputeSize() +
239 sl_config_descriptor_.ComputeSize();
240}
241
242} // namespace media
243} // namespace shaka
bool Parse(const std::vector< uint8_t > &data)
void WriteHeader(BufferWriter *writer)
Write descriptor header.
bool Read(BitReader *reader)
void Write(BufferWriter *writer)
A class to read bit streams.
Definition bit_reader.h:20
bool ReadBits(size_t num_bits, T *out)
Definition bit_reader.h:38
All the methods that are virtual are virtual for mocking.