1 /*
2 * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10 #include "modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.h"
11
12 #include <memory>
13 #include <utility>
14 #include <vector>
15
16 #include "api/transport/rtp/dependency_descriptor.h"
17 #include "rtc_base/bit_buffer.h"
18 #include "rtc_base/checks.h"
19
20 namespace webrtc {
21
RtpDependencyDescriptorReader(rtc::ArrayView<const uint8_t> raw_data,const FrameDependencyStructure * structure,DependencyDescriptor * descriptor)22 RtpDependencyDescriptorReader::RtpDependencyDescriptorReader(
23 rtc::ArrayView<const uint8_t> raw_data,
24 const FrameDependencyStructure* structure,
25 DependencyDescriptor* descriptor)
26 : descriptor_(descriptor), buffer_(raw_data.data(), raw_data.size()) {
27 RTC_DCHECK(descriptor);
28
29 ReadMandatoryFields();
30 if (raw_data.size() > 3)
31 ReadExtendedFields();
32
33 structure_ = descriptor->attached_structure
34 ? descriptor->attached_structure.get()
35 : structure;
36 if (structure_ == nullptr || parsing_failed_) {
37 parsing_failed_ = true;
38 return;
39 }
40 if (active_decode_targets_present_flag_) {
41 descriptor->active_decode_targets_bitmask =
42 ReadBits(structure_->num_decode_targets);
43 }
44
45 ReadFrameDependencyDefinition();
46 }
47
ReadBits(size_t bit_count)48 uint32_t RtpDependencyDescriptorReader::ReadBits(size_t bit_count) {
49 uint32_t value = 0;
50 if (!buffer_.ReadBits(&value, bit_count))
51 parsing_failed_ = true;
52 return value;
53 }
54
ReadNonSymmetric(size_t num_values)55 uint32_t RtpDependencyDescriptorReader::ReadNonSymmetric(size_t num_values) {
56 uint32_t value = 0;
57 if (!buffer_.ReadNonSymmetric(&value, num_values))
58 parsing_failed_ = true;
59 return value;
60 }
61
ReadTemplateDependencyStructure()62 void RtpDependencyDescriptorReader::ReadTemplateDependencyStructure() {
63 descriptor_->attached_structure =
64 std::make_unique<FrameDependencyStructure>();
65 descriptor_->attached_structure->structure_id = ReadBits(6);
66 descriptor_->attached_structure->num_decode_targets = ReadBits(5) + 1;
67
68 ReadTemplateLayers();
69 ReadTemplateDtis();
70 ReadTemplateFdiffs();
71 ReadTemplateChains();
72
73 uint32_t has_resolutions = ReadBits(1);
74 if (has_resolutions)
75 ReadResolutions();
76 }
77
ReadTemplateLayers()78 void RtpDependencyDescriptorReader::ReadTemplateLayers() {
79 enum NextLayerIdc : uint32_t {
80 kSameLayer = 0,
81 kNextTemporalLayer = 1,
82 kNextSpatialLayer = 2,
83 kNoMoreTemplates = 3,
84 };
85 std::vector<FrameDependencyTemplate> templates;
86
87 int temporal_id = 0;
88 int spatial_id = 0;
89 NextLayerIdc next_layer_idc;
90 do {
91 if (templates.size() == DependencyDescriptor::kMaxTemplates) {
92 parsing_failed_ = true;
93 break;
94 }
95 templates.emplace_back();
96 FrameDependencyTemplate& last_template = templates.back();
97 last_template.temporal_id = temporal_id;
98 last_template.spatial_id = spatial_id;
99
100 next_layer_idc = static_cast<NextLayerIdc>(ReadBits(2));
101 if (next_layer_idc == kNextTemporalLayer) {
102 temporal_id++;
103 if (temporal_id >= DependencyDescriptor::kMaxTemporalIds) {
104 parsing_failed_ = true;
105 break;
106 }
107 } else if (next_layer_idc == kNextSpatialLayer) {
108 temporal_id = 0;
109 spatial_id++;
110 if (spatial_id >= DependencyDescriptor::kMaxSpatialIds) {
111 parsing_failed_ = true;
112 break;
113 }
114 }
115 } while (next_layer_idc != kNoMoreTemplates && !parsing_failed_);
116
117 descriptor_->attached_structure->templates = std::move(templates);
118 }
119
ReadTemplateDtis()120 void RtpDependencyDescriptorReader::ReadTemplateDtis() {
121 FrameDependencyStructure* structure = descriptor_->attached_structure.get();
122 for (FrameDependencyTemplate& current_template : structure->templates) {
123 current_template.decode_target_indications.resize(
124 structure->num_decode_targets);
125 for (int i = 0; i < structure->num_decode_targets; ++i) {
126 current_template.decode_target_indications[i] =
127 static_cast<DecodeTargetIndication>(ReadBits(2));
128 }
129 }
130 }
131
ReadTemplateFdiffs()132 void RtpDependencyDescriptorReader::ReadTemplateFdiffs() {
133 for (FrameDependencyTemplate& current_template :
134 descriptor_->attached_structure->templates) {
135 for (uint32_t fdiff_follows = ReadBits(1); fdiff_follows;
136 fdiff_follows = ReadBits(1)) {
137 uint32_t fdiff_minus_one = ReadBits(4);
138 current_template.frame_diffs.push_back(fdiff_minus_one + 1);
139 }
140 }
141 }
142
ReadTemplateChains()143 void RtpDependencyDescriptorReader::ReadTemplateChains() {
144 FrameDependencyStructure* structure = descriptor_->attached_structure.get();
145 structure->num_chains = ReadNonSymmetric(structure->num_decode_targets + 1);
146 if (structure->num_chains == 0)
147 return;
148 for (int i = 0; i < structure->num_decode_targets; ++i) {
149 uint32_t protected_by_chain = ReadNonSymmetric(structure->num_chains);
150 structure->decode_target_protected_by_chain.push_back(protected_by_chain);
151 }
152 for (FrameDependencyTemplate& frame_template : structure->templates) {
153 for (int chain_id = 0; chain_id < structure->num_chains; ++chain_id) {
154 frame_template.chain_diffs.push_back(ReadBits(4));
155 }
156 }
157 }
158
ReadResolutions()159 void RtpDependencyDescriptorReader::ReadResolutions() {
160 FrameDependencyStructure* structure = descriptor_->attached_structure.get();
161 // The way templates are bitpacked, they are always ordered by spatial_id.
162 int spatial_layers = structure->templates.back().spatial_id + 1;
163 structure->resolutions.reserve(spatial_layers);
164 for (int sid = 0; sid < spatial_layers; ++sid) {
165 uint16_t width_minus_1 = ReadBits(16);
166 uint16_t height_minus_1 = ReadBits(16);
167 structure->resolutions.emplace_back(width_minus_1 + 1, height_minus_1 + 1);
168 }
169 }
170
ReadMandatoryFields()171 void RtpDependencyDescriptorReader::ReadMandatoryFields() {
172 descriptor_->first_packet_in_frame = ReadBits(1);
173 descriptor_->last_packet_in_frame = ReadBits(1);
174 frame_dependency_template_id_ = ReadBits(6);
175 descriptor_->frame_number = ReadBits(16);
176 }
177
ReadExtendedFields()178 void RtpDependencyDescriptorReader::ReadExtendedFields() {
179 bool template_dependency_structure_present_flag = ReadBits(1);
180 active_decode_targets_present_flag_ = ReadBits(1);
181 custom_dtis_flag_ = ReadBits(1);
182 custom_fdiffs_flag_ = ReadBits(1);
183 custom_chains_flag_ = ReadBits(1);
184 if (template_dependency_structure_present_flag) {
185 ReadTemplateDependencyStructure();
186 RTC_DCHECK(descriptor_->attached_structure);
187 descriptor_->active_decode_targets_bitmask =
188 (uint64_t{1} << descriptor_->attached_structure->num_decode_targets) -
189 1;
190 }
191 }
192
ReadFrameDependencyDefinition()193 void RtpDependencyDescriptorReader::ReadFrameDependencyDefinition() {
194 size_t template_index =
195 (frame_dependency_template_id_ + DependencyDescriptor::kMaxTemplates -
196 structure_->structure_id) %
197 DependencyDescriptor::kMaxTemplates;
198
199 if (template_index >= structure_->templates.size()) {
200 parsing_failed_ = true;
201 return;
202 }
203
204 // Copy all the fields from the matching template
205 descriptor_->frame_dependencies = structure_->templates[template_index];
206
207 if (custom_dtis_flag_)
208 ReadFrameDtis();
209 if (custom_fdiffs_flag_)
210 ReadFrameFdiffs();
211 if (custom_chains_flag_)
212 ReadFrameChains();
213
214 if (structure_->resolutions.empty()) {
215 descriptor_->resolution = absl::nullopt;
216 } else {
217 // Format guarantees that if there were resolutions in the last structure,
218 // then each spatial layer got one.
219 RTC_DCHECK_LE(descriptor_->frame_dependencies.spatial_id,
220 structure_->resolutions.size());
221 descriptor_->resolution =
222 structure_->resolutions[descriptor_->frame_dependencies.spatial_id];
223 }
224 }
225
ReadFrameDtis()226 void RtpDependencyDescriptorReader::ReadFrameDtis() {
227 RTC_DCHECK_EQ(
228 descriptor_->frame_dependencies.decode_target_indications.size(),
229 structure_->num_decode_targets);
230 for (auto& dti : descriptor_->frame_dependencies.decode_target_indications) {
231 dti = static_cast<DecodeTargetIndication>(ReadBits(2));
232 }
233 }
234
ReadFrameFdiffs()235 void RtpDependencyDescriptorReader::ReadFrameFdiffs() {
236 descriptor_->frame_dependencies.frame_diffs.clear();
237 for (uint32_t next_fdiff_size = ReadBits(2); next_fdiff_size > 0;
238 next_fdiff_size = ReadBits(2)) {
239 uint32_t fdiff_minus_one = ReadBits(4 * next_fdiff_size);
240 descriptor_->frame_dependencies.frame_diffs.push_back(fdiff_minus_one + 1);
241 }
242 }
243
ReadFrameChains()244 void RtpDependencyDescriptorReader::ReadFrameChains() {
245 RTC_DCHECK_EQ(descriptor_->frame_dependencies.chain_diffs.size(),
246 structure_->num_chains);
247 for (auto& chain_diff : descriptor_->frame_dependencies.chain_diffs) {
248 chain_diff = ReadBits(8);
249 }
250 }
251
252 } // namespace webrtc
253