Shaka Packager SDK
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 
13 namespace shaka {
14 namespace media {
15 namespace {
16 
17 // ISO/IEC 14496-1:2004 Section 7.2.6.6 Table 6: StreamType values.
18 enum 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.
34 enum 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.
41 bool 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 
59 void 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 
72 size_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 
83 bool 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 
120 bool 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 
127 void DecoderSpecificInfoDescriptor::WriteInternal(BufferWriter* writer) {
128  WriteHeader(writer);
129  writer->AppendVector(data_);
130 }
131 
132 size_t DecoderSpecificInfoDescriptor::ComputeDataSize() {
133  return data_.size();
134 }
135 
136 bool 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 
162 void 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 
177 size_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 
187 bool SLConfigDescriptor::ReadData(BitReader*) {
188  return true;
189 }
190 
191 void SLConfigDescriptor::WriteInternal(BufferWriter* writer) {
192  WriteHeader(writer);
193  writer->AppendInt(static_cast<uint8_t>(kSLPredefinedMP4));
194 }
195 
196 size_t SLConfigDescriptor::ComputeDataSize() {
197  return 1;
198 }
199 
200 bool 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 
221 void 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 
235 size_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.
Definition: crypto_flags.cc:66