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