blob: 715c1dd068144402b0969713d9db96b00d40031c [file] [log] [blame]
philipel02447bc2016-05-13 06:01:03 -07001/*
2 * Copyright (c) 2016 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef MODULES_VIDEO_CODING_RTP_FRAME_REFERENCE_FINDER_H_
12#define MODULES_VIDEO_CODING_RTP_FRAME_REFERENCE_FINDER_H_
philipel02447bc2016-05-13 06:01:03 -070013
14#include <array>
Yves Gerey665174f2018-06-19 15:03:05 +020015#include <deque>
philipel02447bc2016-05-13 06:01:03 -070016#include <map>
kwibergfd8be342016-05-14 19:44:11 -070017#include <memory>
philipel02447bc2016-05-13 06:01:03 -070018#include <set>
19#include <utility>
20
Niels Möller834a5542019-09-23 10:31:16 +020021#include "modules/include/module_common_types_public.h"
philipel2837edc2018-10-02 13:55:47 +020022#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h"
Niels Möller834a5542019-09-23 10:31:16 +020023#include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
Steve Anton10542f22019-01-11 09:11:00 -080024#include "rtc_base/critical_section.h"
Bjorn Tereliusa194e582017-10-25 13:07:09 +020025#include "rtc_base/numerics/sequence_number_util.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "rtc_base/thread_annotations.h"
philipel02447bc2016-05-13 06:01:03 -070027
28namespace webrtc {
29namespace video_coding {
30
philipele7c891f2018-02-22 14:35:06 +010031class EncodedFrame;
philipel02447bc2016-05-13 06:01:03 -070032class RtpFrameObject;
philipel17deeb42016-08-11 15:09:26 +020033
34// A complete frame is a frame which has received all its packets and all its
35// references are known.
36class OnCompleteFrameCallback {
37 public:
38 virtual ~OnCompleteFrameCallback() {}
philipele7c891f2018-02-22 14:35:06 +010039 virtual void OnCompleteFrame(std::unique_ptr<EncodedFrame> frame) = 0;
philipel17deeb42016-08-11 15:09:26 +020040};
philipel02447bc2016-05-13 06:01:03 -070041
42class RtpFrameReferenceFinder {
43 public:
44 explicit RtpFrameReferenceFinder(OnCompleteFrameCallback* frame_callback);
philipel7acc4a42019-09-26 11:25:52 +020045 explicit RtpFrameReferenceFinder(OnCompleteFrameCallback* frame_callback,
46 int64_t picture_id_offset);
Mirko Bonadei8fdcac32018-08-28 16:30:18 +020047 ~RtpFrameReferenceFinder();
philipel463d3012016-09-09 03:32:44 -070048
49 // Manage this frame until:
50 // - We have all information needed to determine its references, after
51 // which |frame_callback_| is called with the completed frame, or
philipelafcf7f52017-04-26 08:17:35 -070052 // - We have too many stashed frames (determined by |kMaxStashedFrames|)
philipel463d3012016-09-09 03:32:44 -070053 // so we drop this frame, or
54 // - It gets cleared by ClearTo, which also means we drop it.
philipel02447bc2016-05-13 06:01:03 -070055 void ManageFrame(std::unique_ptr<RtpFrameObject> frame);
philipel463d3012016-09-09 03:32:44 -070056
57 // Notifies that padding has been received, which the reference finder
58 // might need to calculate the references of a frame.
philipel9b2ce6b2016-07-05 05:04:46 -070059 void PaddingReceived(uint16_t seq_num);
philipel02447bc2016-05-13 06:01:03 -070060
philipel463d3012016-09-09 03:32:44 -070061 // Clear all stashed frames that include packets older than |seq_num|.
62 void ClearTo(uint16_t seq_num);
63
philipel02447bc2016-05-13 06:01:03 -070064 private:
philipelfd5a20f2016-11-15 00:57:57 -080065 static const uint16_t kPicIdLength = 1 << 15;
philipel02447bc2016-05-13 06:01:03 -070066 static const uint8_t kMaxTemporalLayers = 5;
philipelfd5a20f2016-11-15 00:57:57 -080067 static const int kMaxLayerInfo = 50;
Sergey Silkin52233a32018-07-31 14:30:54 +020068 static const int kMaxStashedFrames = 100;
philipelfd5a20f2016-11-15 00:57:57 -080069 static const int kMaxNotYetReceivedFrames = 100;
70 static const int kMaxGofSaved = 50;
philipel9b2ce6b2016-07-05 05:04:46 -070071 static const int kMaxPaddingAge = 100;
philipel02447bc2016-05-13 06:01:03 -070072
philipelafcf7f52017-04-26 08:17:35 -070073 enum FrameDecision { kStash, kHandOff, kDrop };
philipelc9b27d52016-07-15 06:50:27 -070074
75 struct GofInfo {
76 GofInfo(GofInfoVP9* gof, uint16_t last_picture_id)
77 : gof(gof), last_picture_id(last_picture_id) {}
78 GofInfoVP9* gof;
79 uint16_t last_picture_id;
80 };
81
philipel9b2ce6b2016-07-05 05:04:46 -070082 // Find the relevant group of pictures and update its "last-picture-id-with
83 // padding" sequence number.
philipel7acc4a42019-09-26 11:25:52 +020084 void UpdateLastPictureIdWithPadding(uint16_t seq_num);
philipel9b2ce6b2016-07-05 05:04:46 -070085
philipelafcf7f52017-04-26 08:17:35 -070086 // Retry stashed frames until no more complete frames are found.
philipel7acc4a42019-09-26 11:25:52 +020087 void RetryStashedFrames();
philipel02447bc2016-05-13 06:01:03 -070088
philipel7acc4a42019-09-26 11:25:52 +020089 void HandOffFrame(std::unique_ptr<RtpFrameObject> frame);
90
91 FrameDecision ManageFrameInternal(RtpFrameObject* frame);
philipelafcf7f52017-04-26 08:17:35 -070092
philipel2837edc2018-10-02 13:55:47 +020093 FrameDecision ManageFrameGeneric(RtpFrameObject* frame,
philipel7acc4a42019-09-26 11:25:52 +020094 const RtpGenericFrameDescriptor& descriptor);
philipeldabfcae2018-09-25 12:54:37 +020095
96 // Find references for frames with no or very limited information in the
97 // descriptor. If |picture_id| is unspecified then packet sequence numbers
98 // will be used to determine the references of the frames.
philipel7acc4a42019-09-26 11:25:52 +020099 FrameDecision ManageFramePidOrSeqNum(RtpFrameObject* frame, int picture_id);
philipel02447bc2016-05-13 06:01:03 -0700100
philipelafcf7f52017-04-26 08:17:35 -0700101 // Find references for Vp8 frames
philipel7acc4a42019-09-26 11:25:52 +0200102 FrameDecision ManageFrameVp8(RtpFrameObject* frame);
philipelafcf7f52017-04-26 08:17:35 -0700103
104 // Updates necessary layer info state used to determine frame references for
105 // Vp8.
philipel1610f942017-12-12 13:58:31 +0100106 void UpdateLayerInfoVp8(RtpFrameObject* frame,
philipel57ec6852018-07-03 18:09:32 +0200107 int64_t unwrapped_tl0,
philipel7acc4a42019-09-26 11:25:52 +0200108 uint8_t temporal_idx);
philipel02447bc2016-05-13 06:01:03 -0700109
110 // Find references for Vp9 frames
philipel7acc4a42019-09-26 11:25:52 +0200111 FrameDecision ManageFrameVp9(RtpFrameObject* frame);
philipel02447bc2016-05-13 06:01:03 -0700112
113 // Check if we are missing a frame necessary to determine the references
114 // for this frame.
philipel7acc4a42019-09-26 11:25:52 +0200115 bool MissingRequiredFrameVp9(uint16_t picture_id, const GofInfo& info);
philipel02447bc2016-05-13 06:01:03 -0700116
117 // Updates which frames that have been received. If there is a gap,
118 // missing frames will be added to |missing_frames_for_layer_| or
119 // if this is an already missing frame then it will be removed.
philipel7acc4a42019-09-26 11:25:52 +0200120 void FrameReceivedVp9(uint16_t picture_id, GofInfo* info);
philipel02447bc2016-05-13 06:01:03 -0700121
122 // Check if there is a frame with the up-switch flag set in the interval
123 // (|pid_ref|, |picture_id|) with temporal layer smaller than |temporal_idx|.
124 bool UpSwitchInIntervalVp9(uint16_t picture_id,
125 uint8_t temporal_idx,
philipel7acc4a42019-09-26 11:25:52 +0200126 uint16_t pid_ref);
philipel02447bc2016-05-13 06:01:03 -0700127
philipelafcf7f52017-04-26 08:17:35 -0700128 // Unwrap |frame|s picture id and its references to 16 bits.
philipel7acc4a42019-09-26 11:25:52 +0200129 void UnwrapPictureIds(RtpFrameObject* frame);
philipel02447bc2016-05-13 06:01:03 -0700130
Johnny Leebc7f41b2019-05-01 14:41:32 -0400131 // Find references for H264 frames
philipel7acc4a42019-09-26 11:25:52 +0200132 FrameDecision ManageFrameH264(RtpFrameObject* frame);
Johnny Leebc7f41b2019-05-01 14:41:32 -0400133
134 // Update "last-picture-id-with-padding" sequence number for H264.
philipel7acc4a42019-09-26 11:25:52 +0200135 void UpdateLastPictureIdWithPaddingH264();
Johnny Leebc7f41b2019-05-01 14:41:32 -0400136
137 // Update H264 layer info state used to determine frame references.
138 void UpdateLayerInfoH264(RtpFrameObject* frame,
139 int64_t unwrapped_tl0,
philipel7acc4a42019-09-26 11:25:52 +0200140 uint8_t temporal_idx);
Johnny Leebc7f41b2019-05-01 14:41:32 -0400141
142 // Update H264 state for decodeable frames.
143 void UpdateDataH264(RtpFrameObject* frame,
144 int64_t unwrapped_tl0,
philipel7acc4a42019-09-26 11:25:52 +0200145 uint8_t temporal_idx);
Johnny Leebc7f41b2019-05-01 14:41:32 -0400146
philipel9b2ce6b2016-07-05 05:04:46 -0700147 // For every group of pictures, hold two sequence numbers. The first being
148 // the sequence number of the last packet of the last completed frame, and
149 // the second being the sequence number of the last packet of the last
150 // completed frame advanced by any potential continuous packets of padding.
151 std::map<uint16_t,
152 std::pair<uint16_t, uint16_t>,
153 DescendingSeqNumComp<uint16_t>>
philipel7acc4a42019-09-26 11:25:52 +0200154 last_seq_num_gop_;
philipel02447bc2016-05-13 06:01:03 -0700155
156 // Save the last picture id in order to detect when there is a gap in frames
157 // that have not yet been fully received.
philipel7acc4a42019-09-26 11:25:52 +0200158 int last_picture_id_;
philipel02447bc2016-05-13 06:01:03 -0700159
philipel9b2ce6b2016-07-05 05:04:46 -0700160 // Padding packets that have been received but that are not yet continuous
161 // with any group of pictures.
philipel7acc4a42019-09-26 11:25:52 +0200162 std::set<uint16_t, DescendingSeqNumComp<uint16_t>> stashed_padding_;
philipel9b2ce6b2016-07-05 05:04:46 -0700163
philipel02447bc2016-05-13 06:01:03 -0700164 // Frames earlier than the last received frame that have not yet been
165 // fully received.
166 std::set<uint16_t, DescendingSeqNumComp<uint16_t, kPicIdLength>>
philipel7acc4a42019-09-26 11:25:52 +0200167 not_yet_received_frames_;
philipel02447bc2016-05-13 06:01:03 -0700168
Johnny Leebc7f41b2019-05-01 14:41:32 -0400169 // Sequence numbers of frames earlier than the last received frame that
170 // have not yet been fully received.
philipel7acc4a42019-09-26 11:25:52 +0200171 std::set<uint16_t, DescendingSeqNumComp<uint16_t>> not_yet_received_seq_num_;
Johnny Leebc7f41b2019-05-01 14:41:32 -0400172
philipel02447bc2016-05-13 06:01:03 -0700173 // Frames that have been fully received but didn't have all the information
174 // needed to determine their references.
philipel7acc4a42019-09-26 11:25:52 +0200175 std::deque<std::unique_ptr<RtpFrameObject>> stashed_frames_;
philipel02447bc2016-05-13 06:01:03 -0700176
177 // Holds the information about the last completed frame for a given temporal
philipel57ec6852018-07-03 18:09:32 +0200178 // layer given an unwrapped Tl0 picture index.
philipel7acc4a42019-09-26 11:25:52 +0200179 std::map<int64_t, std::array<int64_t, kMaxTemporalLayers>> layer_info_;
philipel02447bc2016-05-13 06:01:03 -0700180
181 // Where the current scalability structure is in the
182 // |scalability_structures_| array.
183 uint8_t current_ss_idx_;
184
185 // Holds received scalability structures.
philipel7acc4a42019-09-26 11:25:52 +0200186 std::array<GofInfoVP9, kMaxGofSaved> scalability_structures_;
philipel02447bc2016-05-13 06:01:03 -0700187
philipel57ec6852018-07-03 18:09:32 +0200188 // Holds the the Gof information for a given unwrapped TL0 picture index.
philipel7acc4a42019-09-26 11:25:52 +0200189 std::map<int64_t, GofInfo> gof_info_;
philipel02447bc2016-05-13 06:01:03 -0700190
191 // Keep track of which picture id and which temporal layer that had the
192 // up switch flag set.
philipelc9b27d52016-07-15 06:50:27 -0700193 std::map<uint16_t, uint8_t, DescendingSeqNumComp<uint16_t, kPicIdLength>>
philipel7acc4a42019-09-26 11:25:52 +0200194 up_switch_;
philipel02447bc2016-05-13 06:01:03 -0700195
196 // For every temporal layer, keep a set of which frames that are missing.
197 std::array<std::set<uint16_t, DescendingSeqNumComp<uint16_t, kPicIdLength>>,
198 kMaxTemporalLayers>
philipel7acc4a42019-09-26 11:25:52 +0200199 missing_frames_for_layer_;
philipel02447bc2016-05-13 06:01:03 -0700200
philipel463d3012016-09-09 03:32:44 -0700201 // How far frames have been cleared by sequence number. A frame will be
202 // cleared if it contains a packet with a sequence number older than
203 // |cleared_to_seq_num_|.
philipel7acc4a42019-09-26 11:25:52 +0200204 int cleared_to_seq_num_;
philipel463d3012016-09-09 03:32:44 -0700205
philipel02447bc2016-05-13 06:01:03 -0700206 OnCompleteFrameCallback* frame_callback_;
philipeld4fac692017-09-04 07:03:46 -0700207
philipel7acc4a42019-09-26 11:25:52 +0200208 SeqNumUnwrapper<uint16_t> generic_frame_id_unwrapper_;
philipeldabfcae2018-09-25 12:54:37 +0200209
philipeld4fac692017-09-04 07:03:46 -0700210 // Unwrapper used to unwrap generic RTP streams. In a generic stream we derive
211 // a picture id from the packet sequence number.
philipel7acc4a42019-09-26 11:25:52 +0200212 SeqNumUnwrapper<uint16_t> rtp_seq_num_unwrapper_;
philipeld4fac692017-09-04 07:03:46 -0700213
214 // Unwrapper used to unwrap VP8/VP9 streams which have their picture id
215 // specified.
philipel7acc4a42019-09-26 11:25:52 +0200216 SeqNumUnwrapper<uint16_t, kPicIdLength> unwrapper_;
philipel57ec6852018-07-03 18:09:32 +0200217
philipel7acc4a42019-09-26 11:25:52 +0200218 SeqNumUnwrapper<uint8_t> tl0_unwrapper_;
219
220 const int64_t picture_id_offset_;
philipel02447bc2016-05-13 06:01:03 -0700221};
222
223} // namespace video_coding
224} // namespace webrtc
225
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200226#endif // MODULES_VIDEO_CODING_RTP_FRAME_REFERENCE_FINDER_H_