dependency_descriptor.h (5451B)
1 /* 2 * Copyright (c) 2020 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 11 #ifndef API_TRANSPORT_RTP_DEPENDENCY_DESCRIPTOR_H_ 12 #define API_TRANSPORT_RTP_DEPENDENCY_DESCRIPTOR_H_ 13 14 #include <stdint.h> 15 16 #include <initializer_list> 17 #include <memory> 18 #include <optional> 19 #include <vector> 20 21 #include "absl/container/inlined_vector.h" 22 #include "absl/strings/string_view.h" 23 #include "api/video/render_resolution.h" 24 25 namespace webrtc { 26 // Structures to build and parse dependency descriptor as described in 27 // https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension 28 29 // Relationship of a frame to a Decode target. 30 enum class DecodeTargetIndication { 31 kNotPresent = 0, // DecodeTargetInfo symbol '-' 32 kDiscardable = 1, // DecodeTargetInfo symbol 'D' 33 kSwitch = 2, // DecodeTargetInfo symbol 'S' 34 kRequired = 3 // DecodeTargetInfo symbol 'R' 35 }; 36 37 struct FrameDependencyTemplate { 38 // Setters are named briefly to chain them when building the template. 39 FrameDependencyTemplate& S(int spatial_layer); 40 FrameDependencyTemplate& T(int temporal_layer); 41 FrameDependencyTemplate& Dtis(absl::string_view dtis); 42 FrameDependencyTemplate& FrameDiffs(std::initializer_list<int> diffs); 43 FrameDependencyTemplate& ChainDiffs(std::initializer_list<int> diffs); 44 45 friend bool operator==(const FrameDependencyTemplate& lhs, 46 const FrameDependencyTemplate& rhs) { 47 return lhs.spatial_id == rhs.spatial_id && 48 lhs.temporal_id == rhs.temporal_id && 49 lhs.decode_target_indications == rhs.decode_target_indications && 50 lhs.frame_diffs == rhs.frame_diffs && 51 lhs.chain_diffs == rhs.chain_diffs; 52 } 53 54 int spatial_id = 0; 55 int temporal_id = 0; 56 absl::InlinedVector<DecodeTargetIndication, 10> decode_target_indications; 57 absl::InlinedVector<int, 4> frame_diffs; 58 absl::InlinedVector<int, 4> chain_diffs; 59 }; 60 61 struct FrameDependencyStructure { 62 friend bool operator==(const FrameDependencyStructure& lhs, 63 const FrameDependencyStructure& rhs) { 64 return lhs.num_decode_targets == rhs.num_decode_targets && 65 lhs.num_chains == rhs.num_chains && 66 lhs.decode_target_protected_by_chain == 67 rhs.decode_target_protected_by_chain && 68 lhs.resolutions == rhs.resolutions && lhs.templates == rhs.templates; 69 } 70 71 int structure_id = 0; 72 int num_decode_targets = 0; 73 int num_chains = 0; 74 // If chains are used (num_chains > 0), maps decode target index into index of 75 // the chain protecting that target. 76 absl::InlinedVector<int, 10> decode_target_protected_by_chain; 77 absl::InlinedVector<RenderResolution, 4> resolutions; 78 std::vector<FrameDependencyTemplate> templates; 79 }; 80 81 class DependencyDescriptorMandatory { 82 public: 83 void set_frame_number(int frame_number) { frame_number_ = frame_number; } 84 int frame_number() const { return frame_number_; } 85 86 void set_template_id(int template_id) { template_id_ = template_id; } 87 int template_id() const { return template_id_; } 88 89 void set_first_packet_in_frame(bool first) { first_packet_in_frame_ = first; } 90 bool first_packet_in_frame() const { return first_packet_in_frame_; } 91 92 void set_last_packet_in_frame(bool last) { last_packet_in_frame_ = last; } 93 bool last_packet_in_frame() const { return last_packet_in_frame_; } 94 95 private: 96 int frame_number_; 97 int template_id_; 98 bool first_packet_in_frame_; 99 bool last_packet_in_frame_; 100 }; 101 102 struct DependencyDescriptor { 103 static constexpr int kMaxSpatialIds = 4; 104 static constexpr int kMaxTemporalIds = 8; 105 static constexpr int kMaxDecodeTargets = 32; 106 static constexpr int kMaxTemplates = 64; 107 108 bool first_packet_in_frame = true; 109 bool last_packet_in_frame = true; 110 int frame_number = 0; 111 FrameDependencyTemplate frame_dependencies; 112 std::optional<RenderResolution> resolution; 113 std::optional<uint32_t> active_decode_targets_bitmask; 114 std::unique_ptr<FrameDependencyStructure> attached_structure; 115 }; 116 117 // Below are implementation details. 118 namespace webrtc_impl { 119 absl::InlinedVector<DecodeTargetIndication, 10> StringToDecodeTargetIndications( 120 absl::string_view indication_symbols); 121 } // namespace webrtc_impl 122 123 inline FrameDependencyTemplate& FrameDependencyTemplate::S(int spatial_layer) { 124 this->spatial_id = spatial_layer; 125 return *this; 126 } 127 inline FrameDependencyTemplate& FrameDependencyTemplate::T(int temporal_layer) { 128 this->temporal_id = temporal_layer; 129 return *this; 130 } 131 inline FrameDependencyTemplate& FrameDependencyTemplate::Dtis( 132 absl::string_view dtis) { 133 this->decode_target_indications = 134 webrtc_impl::StringToDecodeTargetIndications(dtis); 135 return *this; 136 } 137 inline FrameDependencyTemplate& FrameDependencyTemplate::FrameDiffs( 138 std::initializer_list<int> diffs) { 139 this->frame_diffs.assign(diffs.begin(), diffs.end()); 140 return *this; 141 } 142 inline FrameDependencyTemplate& FrameDependencyTemplate::ChainDiffs( 143 std::initializer_list<int> diffs) { 144 this->chain_diffs.assign(diffs.begin(), diffs.end()); 145 return *this; 146 } 147 148 } // namespace webrtc 149 150 #endif // API_TRANSPORT_RTP_DEPENDENCY_DESCRIPTOR_H_