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