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