xref: /aosp_15_r20/external/webrtc/modules/rtp_rtcp/source/rtp_dependency_descriptor_reader.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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