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  decoder_specific_info_descriptor_.Write(writer);
171 }
172 
173 size_t DecoderConfigDescriptor::ComputeDataSize() {
174  // object_type (1 byte), stream_type (1 byte), decoding_buffer_size (3 bytes),
175  // max_bitrate (4 bytes), avg_bitrate (4 bytes).
176  const size_t data_size_without_children = 1 + 1 + 3 + 4 + 4;
177  return data_size_without_children +
178  decoder_specific_info_descriptor_.ComputeSize();
179 }
180 
181 bool SLConfigDescriptor::ReadData(BitReader* reader) {
182  return true;
183 }
184 
185 void SLConfigDescriptor::WriteInternal(BufferWriter* writer) {
186  WriteHeader(writer);
187  writer->AppendInt(static_cast<uint8_t>(kSLPredefinedMP4));
188 }
189 
190 size_t SLConfigDescriptor::ComputeDataSize() {
191  return 1;
192 }
193 
194 bool ESDescriptor::ReadData(BitReader* reader) {
195  bool stream_dependency_flag;
196  bool url_flag;
197  bool ocr_stream_flag;
198  RCHECK(reader->ReadBits(16, &esid_));
199  RCHECK(reader->ReadBits(1, &stream_dependency_flag));
200  RCHECK(reader->ReadBits(1, &url_flag));
201  RCHECK(!url_flag); // We don't support url flag
202  RCHECK(reader->ReadBits(1, &ocr_stream_flag));
203  RCHECK(reader->SkipBits(5)); // streamPriority
204 
205  if (stream_dependency_flag)
206  RCHECK(reader->SkipBits(16)); // dependsOn_ES_ID
207  if (ocr_stream_flag)
208  RCHECK(reader->SkipBits(16)); // OCR_ES_Id
209 
210  return decoder_config_descriptor_.Read(reader);
211  // Skip the parsing of |sl_config_descriptor_| intentionally as we do not care
212  // about the data.
213 }
214 
215 void ESDescriptor::WriteInternal(BufferWriter* writer) {
216  WriteHeader(writer);
217 
218  writer->AppendInt(esid_);
219  const uint8_t kNoEsFlags = 0;
220  writer->AppendInt(kNoEsFlags);
221 
222  decoder_config_descriptor_.Write(writer);
223  sl_config_descriptor_.Write(writer);
224 }
225 
226 size_t ESDescriptor::ComputeDataSize() {
227  // esid (2 bytes), es_flags (1 byte).
228  const size_t data_size_without_children = 2 + 1;
229  return data_size_without_children + decoder_config_descriptor_.ComputeSize() +
230  sl_config_descriptor_.ComputeSize();
231 }
232 
233 } // namespace media
234 } // namespace shaka
bool ReadBits(size_t num_bits, T *out)
Definition: bit_reader.h:35
A class to read bit streams.
Definition: bit_reader.h:17
bool Read(BitReader *reader)
All the methods that are virtual are virtual for mocking.
void WriteHeader(BufferWriter *writer)
Write descriptor header.
size_t bit_position() const
Definition: bit_reader.h:94
void AppendNBytes(uint64_t v, size_t num_bytes)
bool SkipBits(size_t num_bits)
Definition: bit_reader.cc:24
void Write(BufferWriter *writer)
bool Parse(const std::vector< uint8_t > &data)