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