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/bitstream_reader.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) {
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) {
37 buffer_.Invalidate();
38 return;
39 }
40 if (active_decode_targets_present_flag_) {
41 descriptor->active_decode_targets_bitmask =
42 buffer_.ReadBits(structure_->num_decode_targets);
43 }
44
45 ReadFrameDependencyDefinition();
46 }
47
ReadTemplateDependencyStructure()48 void RtpDependencyDescriptorReader::ReadTemplateDependencyStructure() {
49 descriptor_->attached_structure =
50 std::make_unique<FrameDependencyStructure>();
51 descriptor_->attached_structure->structure_id = buffer_.ReadBits(6);
52 descriptor_->attached_structure->num_decode_targets = buffer_.ReadBits(5) + 1;
53
54 ReadTemplateLayers();
55 ReadTemplateDtis();
56 ReadTemplateFdiffs();
57 ReadTemplateChains();
58
59 if (buffer_.Read<bool>())
60 ReadResolutions();
61 }
62
ReadTemplateLayers()63 void RtpDependencyDescriptorReader::ReadTemplateLayers() {
64 enum NextLayerIdc {
65 kSameLayer = 0,
66 kNextTemporalLayer = 1,
67 kNextSpatialLayer = 2,
68 kNoMoreTemplates = 3,
69 };
70 std::vector<FrameDependencyTemplate> templates;
71
72 int temporal_id = 0;
73 int spatial_id = 0;
74 NextLayerIdc next_layer_idc;
75 do {
76 if (templates.size() == DependencyDescriptor::kMaxTemplates) {
77 buffer_.Invalidate();
78 break;
79 }
80 templates.emplace_back();
81 FrameDependencyTemplate& last_template = templates.back();
82 last_template.temporal_id = temporal_id;
83 last_template.spatial_id = spatial_id;
84
85 next_layer_idc = static_cast<NextLayerIdc>(buffer_.ReadBits(2));
86 if (next_layer_idc == kNextTemporalLayer) {
87 temporal_id++;
88 if (temporal_id >= DependencyDescriptor::kMaxTemporalIds) {
89 buffer_.Invalidate();
90 break;
91 }
92 } else if (next_layer_idc == kNextSpatialLayer) {
93 temporal_id = 0;
94 spatial_id++;
95 if (spatial_id >= DependencyDescriptor::kMaxSpatialIds) {
96 buffer_.Invalidate();
97 break;
98 }
99 }
100 } while (next_layer_idc != kNoMoreTemplates && buffer_.Ok());
101
102 descriptor_->attached_structure->templates = std::move(templates);
103 }
104
ReadTemplateDtis()105 void RtpDependencyDescriptorReader::ReadTemplateDtis() {
106 FrameDependencyStructure* structure = descriptor_->attached_structure.get();
107 for (FrameDependencyTemplate& current_template : structure->templates) {
108 current_template.decode_target_indications.resize(
109 structure->num_decode_targets);
110 for (int i = 0; i < structure->num_decode_targets; ++i) {
111 current_template.decode_target_indications[i] =
112 static_cast<DecodeTargetIndication>(buffer_.ReadBits(2));
113 }
114 }
115 }
116
ReadTemplateFdiffs()117 void RtpDependencyDescriptorReader::ReadTemplateFdiffs() {
118 for (FrameDependencyTemplate& current_template :
119 descriptor_->attached_structure->templates) {
120 for (bool fdiff_follows = buffer_.Read<bool>(); fdiff_follows;
121 fdiff_follows = buffer_.Read<bool>()) {
122 uint64_t fdiff_minus_one = buffer_.ReadBits(4);
123 current_template.frame_diffs.push_back(fdiff_minus_one + 1);
124 }
125 }
126 }
127
ReadTemplateChains()128 void RtpDependencyDescriptorReader::ReadTemplateChains() {
129 FrameDependencyStructure* structure = descriptor_->attached_structure.get();
130 structure->num_chains =
131 buffer_.ReadNonSymmetric(structure->num_decode_targets + 1);
132 if (structure->num_chains == 0)
133 return;
134 for (int i = 0; i < structure->num_decode_targets; ++i) {
135 uint32_t protected_by_chain =
136 buffer_.ReadNonSymmetric(structure->num_chains);
137 structure->decode_target_protected_by_chain.push_back(protected_by_chain);
138 }
139 for (FrameDependencyTemplate& frame_template : structure->templates) {
140 for (int chain_id = 0; chain_id < structure->num_chains; ++chain_id) {
141 frame_template.chain_diffs.push_back(buffer_.ReadBits(4));
142 }
143 }
144 }
145
ReadResolutions()146 void RtpDependencyDescriptorReader::ReadResolutions() {
147 FrameDependencyStructure* structure = descriptor_->attached_structure.get();
148 // The way templates are bitpacked, they are always ordered by spatial_id.
149 int spatial_layers = structure->templates.back().spatial_id + 1;
150 structure->resolutions.reserve(spatial_layers);
151 for (int sid = 0; sid < spatial_layers; ++sid) {
152 uint16_t width_minus_1 = buffer_.Read<uint16_t>();
153 uint16_t height_minus_1 = buffer_.Read<uint16_t>();
154 structure->resolutions.emplace_back(width_minus_1 + 1, height_minus_1 + 1);
155 }
156 }
157
ReadMandatoryFields()158 void RtpDependencyDescriptorReader::ReadMandatoryFields() {
159 descriptor_->first_packet_in_frame = buffer_.Read<bool>();
160 descriptor_->last_packet_in_frame = buffer_.Read<bool>();
161 frame_dependency_template_id_ = buffer_.ReadBits(6);
162 descriptor_->frame_number = buffer_.Read<uint16_t>();
163 }
164
ReadExtendedFields()165 void RtpDependencyDescriptorReader::ReadExtendedFields() {
166 bool template_dependency_structure_present_flag = buffer_.Read<bool>();
167 active_decode_targets_present_flag_ = buffer_.Read<bool>();
168 custom_dtis_flag_ = buffer_.Read<bool>();
169 custom_fdiffs_flag_ = buffer_.Read<bool>();
170 custom_chains_flag_ = buffer_.Read<bool>();
171 if (template_dependency_structure_present_flag) {
172 ReadTemplateDependencyStructure();
173 RTC_DCHECK(descriptor_->attached_structure);
174 descriptor_->active_decode_targets_bitmask =
175 (uint64_t{1} << descriptor_->attached_structure->num_decode_targets) -
176 1;
177 }
178 }
179
ReadFrameDependencyDefinition()180 void RtpDependencyDescriptorReader::ReadFrameDependencyDefinition() {
181 size_t template_index =
182 (frame_dependency_template_id_ + DependencyDescriptor::kMaxTemplates -
183 structure_->structure_id) %
184 DependencyDescriptor::kMaxTemplates;
185
186 if (template_index >= structure_->templates.size()) {
187 buffer_.Invalidate();
188 return;
189 }
190
191 // Copy all the fields from the matching template
192 descriptor_->frame_dependencies = structure_->templates[template_index];
193
194 if (custom_dtis_flag_)
195 ReadFrameDtis();
196 if (custom_fdiffs_flag_)
197 ReadFrameFdiffs();
198 if (custom_chains_flag_)
199 ReadFrameChains();
200
201 if (structure_->resolutions.empty()) {
202 descriptor_->resolution = absl::nullopt;
203 } else {
204 // Format guarantees that if there were resolutions in the last structure,
205 // then each spatial layer got one.
206 RTC_DCHECK_LE(descriptor_->frame_dependencies.spatial_id,
207 structure_->resolutions.size());
208 descriptor_->resolution =
209 structure_->resolutions[descriptor_->frame_dependencies.spatial_id];
210 }
211 }
212
ReadFrameDtis()213 void RtpDependencyDescriptorReader::ReadFrameDtis() {
214 RTC_DCHECK_EQ(
215 descriptor_->frame_dependencies.decode_target_indications.size(),
216 structure_->num_decode_targets);
217 for (auto& dti : descriptor_->frame_dependencies.decode_target_indications) {
218 dti = static_cast<DecodeTargetIndication>(buffer_.ReadBits(2));
219 }
220 }
221
ReadFrameFdiffs()222 void RtpDependencyDescriptorReader::ReadFrameFdiffs() {
223 descriptor_->frame_dependencies.frame_diffs.clear();
224 for (uint64_t next_fdiff_size = buffer_.ReadBits(2); next_fdiff_size > 0;
225 next_fdiff_size = buffer_.ReadBits(2)) {
226 uint64_t fdiff_minus_one = buffer_.ReadBits(4 * next_fdiff_size);
227 descriptor_->frame_dependencies.frame_diffs.push_back(fdiff_minus_one + 1);
228 }
229 }
230
ReadFrameChains()231 void RtpDependencyDescriptorReader::ReadFrameChains() {
232 RTC_DCHECK_EQ(descriptor_->frame_dependencies.chain_diffs.size(),
233 structure_->num_chains);
234 for (auto& chain_diff : descriptor_->frame_dependencies.chain_diffs) {
235 chain_diff = buffer_.Read<uint8_t>();
236 }
237 }
238
239 } // namespace webrtc
240