blob: f51b6ec89801cafd412b3a65d5979b100c9078f0 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
stefan@webrtc.org29794612012-02-08 08:58:55 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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 */
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020010#include "modules/video_coding/jitter_buffer.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000011
stefan@webrtc.org29794612012-02-08 08:58:55 +000012#include <algorithm>
philipel83f831a2016-03-12 03:30:23 -080013#include <limits>
agalusza@google.comd818dcb2013-07-29 21:48:11 +000014#include <utility>
stefan@webrtc.org29794612012-02-08 08:58:55 +000015
Evan Shrubsolee9126c12022-03-07 14:50:51 +010016#include "api/units/timestamp.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/video_coding/frame_buffer.h"
18#include "modules/video_coding/include/video_coding.h"
19#include "modules/video_coding/inter_frame_delay.h"
20#include "modules/video_coding/internal_defines.h"
21#include "modules/video_coding/jitter_buffer_common.h"
22#include "modules/video_coding/jitter_estimator.h"
23#include "modules/video_coding/packet.h"
24#include "rtc_base/checks.h"
25#include "rtc_base/logging.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020026#include "system_wrappers/include/clock.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000027
niklase@google.com470e71d2011-07-07 08:21:25 +000028namespace webrtc {
mflodman@webrtc.org7c894b72012-11-26 12:40:15 +000029// Use this rtt if no value has been reported.
pkasting@chromium.org16825b12015-01-12 21:51:21 +000030static const int64_t kDefaultRtt = 200;
mflodman@webrtc.org7c894b72012-11-26 12:40:15 +000031
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +000032typedef std::pair<uint32_t, VCMFrameBuffer*> FrameListPair;
niklase@google.com470e71d2011-07-07 08:21:25 +000033
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +000034bool IsKeyFrame(FrameListPair pair) {
Niels Möller8f7ce222019-03-21 15:43:58 +010035 return pair.second->FrameType() == VideoFrameType::kVideoFrameKey;
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +000036}
stefan@webrtc.org29794612012-02-08 08:58:55 +000037
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +000038bool HasNonEmptyState(FrameListPair pair) {
39 return pair.second->GetState() != kStateEmpty;
stefan@webrtc.orga64300a2013-03-04 15:24:40 +000040}
41
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +000042void FrameList::InsertFrame(VCMFrameBuffer* frame) {
Niels Möller23775882018-08-16 10:24:12 +020043 insert(rbegin().base(), FrameListPair(frame->Timestamp(), frame));
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +000044}
45
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +000046VCMFrameBuffer* FrameList::PopFrame(uint32_t timestamp) {
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +000047 FrameList::iterator it = find(timestamp);
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +000048 if (it == end())
49 return NULL;
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +000050 VCMFrameBuffer* frame = it->second;
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +000051 erase(it);
52 return frame;
53}
54
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +000055VCMFrameBuffer* FrameList::Front() const {
56 return begin()->second;
57}
58
59VCMFrameBuffer* FrameList::Back() const {
60 return rbegin()->second;
61}
62
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +000063int FrameList::RecycleFramesUntilKeyFrame(FrameList::iterator* key_frame_it,
64 UnorderedFrameList* free_frames) {
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +000065 int drop_count = 0;
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +000066 FrameList::iterator it = begin();
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +000067 while (!empty()) {
68 // Throw at least one frame.
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +000069 it->second->Reset();
70 free_frames->push_back(it->second);
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +000071 erase(it++);
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +000072 ++drop_count;
Niels Möller8f7ce222019-03-21 15:43:58 +010073 if (it != end() &&
74 it->second->FrameType() == VideoFrameType::kVideoFrameKey) {
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +000075 *key_frame_it = it;
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +000076 return drop_count;
77 }
78 }
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +000079 *key_frame_it = end();
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +000080 return drop_count;
81}
82
pbos@webrtc.org4f16c872014-11-24 09:06:48 +000083void FrameList::CleanUpOldOrEmptyFrames(VCMDecodingState* decoding_state,
philipel9d3ab612015-12-21 04:12:39 -080084 UnorderedFrameList* free_frames) {
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +000085 while (!empty()) {
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +000086 VCMFrameBuffer* oldest_frame = Front();
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +000087 bool remove_frame = false;
88 if (oldest_frame->GetState() == kStateEmpty && size() > 1) {
89 // This frame is empty, try to update the last decoded state and drop it
90 // if successful.
91 remove_frame = decoding_state->UpdateEmptyFrame(oldest_frame);
92 } else {
93 remove_frame = decoding_state->IsOldFrame(oldest_frame);
94 }
95 if (!remove_frame) {
96 break;
97 }
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +000098 free_frames->push_back(oldest_frame);
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +000099 erase(begin());
100 }
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000101}
102
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000103void FrameList::Reset(UnorderedFrameList* free_frames) {
104 while (!empty()) {
105 begin()->second->Reset();
106 free_frames->push_back(begin()->second);
107 erase(begin());
108 }
109}
110
Qiang Chend4cec152015-06-19 09:17:00 -0700111VCMJitterBuffer::VCMJitterBuffer(Clock* clock,
Niels Möllerdb64d992019-03-29 14:30:53 +0100112 std::unique_ptr<EventWrapper> event)
stefan@webrtc.org34c5da62014-04-11 14:08:35 +0000113 : clock_(clock),
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000114 running_(false),
kwiberg0eb15ed2015-12-17 03:04:15 -0800115 frame_event_(std::move(event)),
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000116 max_number_of_frames_(kStartNumberOfFrames),
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000117 free_frames_(),
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000118 decodable_frames_(),
119 incomplete_frames_(),
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000120 last_decoded_state_(),
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000121 first_packet_since_reset_(true),
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000122 num_consecutive_old_packets_(0),
asapersson@webrtc.org96dc6852014-11-03 14:40:38 +0000123 num_packets_(0),
124 num_duplicated_packets_(0),
sprang@webrtc.org70e2d112014-09-24 14:06:56 +0000125 jitter_estimate_(clock),
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000126 missing_sequence_numbers_(SequenceNumberLessThan()),
sprang22691e02016-07-13 10:57:07 -0700127 latest_received_sequence_number_(0),
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +0000128 max_nack_list_size_(0),
129 max_packet_age_to_nack_(0),
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000130 max_incomplete_time_ms_(0),
agalusza@google.comd818dcb2013-07-29 21:48:11 +0000131 average_packets_per_frame_(0.0f),
philipel85130292016-07-06 16:10:31 +0200132 frame_counter_(0) {
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000133 for (int i = 0; i < kStartNumberOfFrames; i++)
134 free_frames_.push_back(new VCMFrameBuffer());
niklase@google.com470e71d2011-07-07 08:21:25 +0000135}
136
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000137VCMJitterBuffer::~VCMJitterBuffer() {
138 Stop();
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000139 for (UnorderedFrameList::iterator it = free_frames_.begin();
140 it != free_frames_.end(); ++it) {
141 delete *it;
142 }
143 for (FrameList::iterator it = incomplete_frames_.begin();
144 it != incomplete_frames_.end(); ++it) {
145 delete it->second;
146 }
147 for (FrameList::iterator it = decodable_frames_.begin();
148 it != decodable_frames_.end(); ++it) {
149 delete it->second;
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000150 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000151}
152
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000153void VCMJitterBuffer::Start() {
Markus Handell6deec382020-07-07 12:17:12 +0200154 MutexLock lock(&mutex_);
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000155 running_ = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000156
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000157 num_consecutive_old_packets_ = 0;
asapersson@webrtc.org96dc6852014-11-03 14:40:38 +0000158 num_packets_ = 0;
159 num_duplicated_packets_ = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000160
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000161 // Start in a non-signaled state.
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000162 waiting_for_completion_.frame_size = 0;
163 waiting_for_completion_.timestamp = 0;
164 waiting_for_completion_.latest_packet_time = -1;
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000165 first_packet_since_reset_ = true;
mikhal@webrtc.org8392cd92013-04-25 21:30:50 +0000166 last_decoded_state_.Reset();
sprang22691e02016-07-13 10:57:07 -0700167
168 decodable_frames_.Reset(&free_frames_);
169 incomplete_frames_.Reset(&free_frames_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000170}
171
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000172void VCMJitterBuffer::Stop() {
Markus Handell6deec382020-07-07 12:17:12 +0200173 MutexLock lock(&mutex_);
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000174 running_ = false;
175 last_decoded_state_.Reset();
asaperssona9455ab2015-07-31 06:10:09 -0700176
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000177 // Make sure we wake up any threads waiting on these events.
stefan@webrtc.org2baf5f52013-03-13 08:46:25 +0000178 frame_event_->Set();
niklase@google.com470e71d2011-07-07 08:21:25 +0000179}
180
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000181bool VCMJitterBuffer::Running() const {
Markus Handell6deec382020-07-07 12:17:12 +0200182 MutexLock lock(&mutex_);
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000183 return running_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000184}
185
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000186void VCMJitterBuffer::Flush() {
Markus Handell6deec382020-07-07 12:17:12 +0200187 MutexLock lock(&mutex_);
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000188 decodable_frames_.Reset(&free_frames_);
189 incomplete_frames_.Reset(&free_frames_);
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000190 last_decoded_state_.Reset(); // TODO(mikhal): sync reset.
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000191 num_consecutive_old_packets_ = 0;
192 // Also reset the jitter and delay estimates
193 jitter_estimate_.Reset();
Evan Shrubsolee9126c12022-03-07 14:50:51 +0100194 inter_frame_delay_.Reset();
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000195 waiting_for_completion_.frame_size = 0;
196 waiting_for_completion_.timestamp = 0;
197 waiting_for_completion_.latest_packet_time = -1;
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000198 first_packet_since_reset_ = true;
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000199 missing_sequence_numbers_.clear();
niklase@google.com470e71d2011-07-07 08:21:25 +0000200}
201
asapersson@webrtc.org96dc6852014-11-03 14:40:38 +0000202int VCMJitterBuffer::num_packets() const {
Markus Handell6deec382020-07-07 12:17:12 +0200203 MutexLock lock(&mutex_);
asapersson@webrtc.org96dc6852014-11-03 14:40:38 +0000204 return num_packets_;
205}
206
207int VCMJitterBuffer::num_duplicated_packets() const {
Markus Handell6deec382020-07-07 12:17:12 +0200208 MutexLock lock(&mutex_);
asapersson@webrtc.org96dc6852014-11-03 14:40:38 +0000209 return num_duplicated_packets_;
210}
211
Artem Titovdcd7fc72021-08-09 13:02:57 +0200212// Returns immediately or a `max_wait_time_ms` ms event hang waiting for a
213// complete frame, `max_wait_time_ms` decided by caller.
isheriff6b4b5f32016-06-08 00:24:21 -0700214VCMEncodedFrame* VCMJitterBuffer::NextCompleteFrame(uint32_t max_wait_time_ms) {
Markus Handell6deec382020-07-07 12:17:12 +0200215 MutexLock lock(&mutex_);
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000216 if (!running_) {
isheriff6b4b5f32016-06-08 00:24:21 -0700217 return nullptr;
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000218 }
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000219 CleanUpOldOrEmptyFrames();
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000220
agalusza@google.comd177c102013-08-08 01:12:33 +0000221 if (decodable_frames_.empty() ||
222 decodable_frames_.Front()->GetState() != kStateComplete) {
philipel9d3ab612015-12-21 04:12:39 -0800223 const int64_t end_wait_time_ms =
224 clock_->TimeInMilliseconds() + max_wait_time_ms;
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000225 int64_t wait_time_ms = max_wait_time_ms;
226 while (wait_time_ms > 0) {
Markus Handell6deec382020-07-07 12:17:12 +0200227 mutex_.Unlock();
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000228 const EventTypeWrapper ret =
philipel9d3ab612015-12-21 04:12:39 -0800229 frame_event_->Wait(static_cast<uint32_t>(wait_time_ms));
Markus Handell6deec382020-07-07 12:17:12 +0200230 mutex_.Lock();
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000231 if (ret == kEventSignaled) {
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000232 // Are we shutting down the jitter buffer?
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000233 if (!running_) {
isheriff6b4b5f32016-06-08 00:24:21 -0700234 return nullptr;
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000235 }
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000236 // Finding oldest frame ready for decoder.
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000237 CleanUpOldOrEmptyFrames();
agalusza@google.comd177c102013-08-08 01:12:33 +0000238 if (decodable_frames_.empty() ||
239 decodable_frames_.Front()->GetState() != kStateComplete) {
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000240 wait_time_ms = end_wait_time_ms - clock_->TimeInMilliseconds();
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000241 } else {
242 break;
243 }
244 } else {
mikhal@webrtc.org9c7685f2013-05-07 16:07:52 +0000245 break;
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000246 }
247 }
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000248 }
agalusza@google.comd177c102013-08-08 01:12:33 +0000249 if (decodable_frames_.empty() ||
250 decodable_frames_.Front()->GetState() != kStateComplete) {
isheriff6b4b5f32016-06-08 00:24:21 -0700251 return nullptr;
mikhal@webrtc.orgdc3cd212013-04-25 20:27:04 +0000252 }
Markus Handell6deec382020-07-07 12:17:12 +0200253 return decodable_frames_.Front();
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000254}
255
mikhal@webrtc.org759b0412013-05-07 16:36:00 +0000256VCMEncodedFrame* VCMJitterBuffer::ExtractAndSetDecode(uint32_t timestamp) {
Markus Handell6deec382020-07-07 12:17:12 +0200257 MutexLock lock(&mutex_);
mikhal@webrtc.org759b0412013-05-07 16:36:00 +0000258 if (!running_) {
259 return NULL;
260 }
261 // Extract the frame with the desired timestamp.
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000262 VCMFrameBuffer* frame = decodable_frames_.PopFrame(timestamp);
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000263 bool continuous = true;
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000264 if (!frame) {
265 frame = incomplete_frames_.PopFrame(timestamp);
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000266 if (frame)
267 continuous = last_decoded_state_.ContinuousFrame(frame);
268 else
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000269 return NULL;
mikhal@webrtc.org759b0412013-05-07 16:36:00 +0000270 }
mikhal@webrtc.orgcb20a5b2013-05-15 17:10:44 +0000271 // Frame pulled out from jitter buffer, update the jitter estimate.
mikhal@webrtc.org759b0412013-05-07 16:36:00 +0000272 const bool retransmitted = (frame->GetNackCount() > 0);
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000273 if (retransmitted) {
Niels Möller691f62c2019-04-11 15:27:17 +0200274 jitter_estimate_.FrameNacked();
Niels Möllerf0eee002018-11-28 16:31:29 +0100275 } else if (frame->size() > 0) {
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000276 // Ignore retransmitted and empty frames.
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000277 if (waiting_for_completion_.latest_packet_time >= 0) {
278 UpdateJitterEstimate(waiting_for_completion_, true);
279 }
mikhal@webrtc.orgcb20a5b2013-05-15 17:10:44 +0000280 if (frame->GetState() == kStateComplete) {
281 UpdateJitterEstimate(*frame, false);
282 } else {
283 // Wait for this one to get complete.
Niels Möllerf0eee002018-11-28 16:31:29 +0100284 waiting_for_completion_.frame_size = frame->size();
philipel9d3ab612015-12-21 04:12:39 -0800285 waiting_for_completion_.latest_packet_time = frame->LatestPacketTimeMs();
Niels Möller23775882018-08-16 10:24:12 +0200286 waiting_for_completion_.timestamp = frame->Timestamp();
mikhal@webrtc.orgcb20a5b2013-05-15 17:10:44 +0000287 }
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000288 }
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000289
290 // The state must be changed to decoding before cleaning up zero sized
291 // frames to avoid empty frames being cleaned up and then given to the
mikhal@webrtc.orgcb20a5b2013-05-15 17:10:44 +0000292 // decoder. Propagates the missing_frame bit.
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000293 frame->PrepareForDecode(continuous);
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000294
mikhal@webrtc.orgcb20a5b2013-05-15 17:10:44 +0000295 // We have a frame - update the last decoded state and nack list.
mikhal@webrtc.org759b0412013-05-07 16:36:00 +0000296 last_decoded_state_.SetState(frame);
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000297 DropPacketsFromNackList(last_decoded_state_.sequence_num());
agalusza@google.comd818dcb2013-07-29 21:48:11 +0000298
philipel1b0d5432020-10-28 15:50:15 +0100299 UpdateAveragePacketsPerFrame(frame->NumPackets());
agalusza@google.comd818dcb2013-07-29 21:48:11 +0000300
mikhal@webrtc.org759b0412013-05-07 16:36:00 +0000301 return frame;
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000302}
303
304// Release frame when done with decoding. Should never be used to release
305// frames from within the jitter buffer.
306void VCMJitterBuffer::ReleaseFrame(VCMEncodedFrame* frame) {
sprang22691e02016-07-13 10:57:07 -0700307 RTC_CHECK(frame != nullptr);
Markus Handell6deec382020-07-07 12:17:12 +0200308 MutexLock lock(&mutex_);
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000309 VCMFrameBuffer* frame_buffer = static_cast<VCMFrameBuffer*>(frame);
sprang22691e02016-07-13 10:57:07 -0700310 RecycleFrameBuffer(frame_buffer);
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000311}
312
niklase@google.com470e71d2011-07-07 08:21:25 +0000313// Gets frame to use for this timestamp. If no match, get empty frame.
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000314VCMFrameBufferEnum VCMJitterBuffer::GetFrame(const VCMPacket& packet,
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000315 VCMFrameBuffer** frame,
316 FrameList** frame_list) {
317 *frame = incomplete_frames_.PopFrame(packet.timestamp);
318 if (*frame != NULL) {
319 *frame_list = &incomplete_frames_;
320 return kNoError;
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000321 }
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000322 *frame = decodable_frames_.PopFrame(packet.timestamp);
323 if (*frame != NULL) {
324 *frame_list = &decodable_frames_;
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000325 return kNoError;
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000326 }
mikhal@webrtc.org3c5a9242013-09-03 20:45:36 +0000327
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000328 *frame_list = NULL;
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000329 // No match, return empty frame.
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000330 *frame = GetEmptyFrame();
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000331 if (*frame == NULL) {
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000332 // No free frame! Try to reclaim some...
Mirko Bonadei675513b2017-11-09 11:09:25 +0100333 RTC_LOG(LS_WARNING) << "Unable to get empty frame; Recycling.";
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000334 bool found_key_frame = RecycleFramesUntilKeyFrame();
335 *frame = GetEmptyFrame();
sprang22691e02016-07-13 10:57:07 -0700336 RTC_CHECK(*frame);
stefan@webrtc.org34c5da62014-04-11 14:08:35 +0000337 if (!found_key_frame) {
sprang22691e02016-07-13 10:57:07 -0700338 RecycleFrameBuffer(*frame);
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000339 return kFlushIndicator;
stefan@webrtc.org34c5da62014-04-11 14:08:35 +0000340 }
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000341 }
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000342 (*frame)->Reset();
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000343 return kNoError;
niklase@google.com470e71d2011-07-07 08:21:25 +0000344}
345
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000346int64_t VCMJitterBuffer::LastPacketTime(const VCMEncodedFrame* frame,
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000347 bool* retransmitted) const {
Mirko Bonadei25ab3222021-07-08 20:08:20 +0200348 RTC_DCHECK(retransmitted);
Markus Handell6deec382020-07-07 12:17:12 +0200349 MutexLock lock(&mutex_);
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000350 const VCMFrameBuffer* frame_buffer =
351 static_cast<const VCMFrameBuffer*>(frame);
352 *retransmitted = (frame_buffer->GetNackCount() > 0);
353 return frame_buffer->LatestPacketTimeMs();
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000354}
355
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000356VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet,
357 bool* retransmitted) {
Markus Handell6deec382020-07-07 12:17:12 +0200358 MutexLock lock(&mutex_);
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000359
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000360 ++num_packets_;
361 // Does this packet belong to an old frame?
362 if (last_decoded_state_.IsOldPacket(&packet)) {
363 // Account only for media packets.
364 if (packet.sizeBytes > 0) {
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000365 num_consecutive_old_packets_++;
366 }
367 // Update last decoded sequence number if the packet arrived late and
368 // belongs to a frame with a timestamp equal to the last decoded
369 // timestamp.
370 last_decoded_state_.UpdateOldPacket(&packet);
371 DropPacketsFromNackList(last_decoded_state_.sequence_num());
372
Noah Richardse4cb4e92015-05-22 14:03:00 -0700373 // Also see if this old packet made more incomplete frames continuous.
374 FindAndInsertContinuousFramesWithState(last_decoded_state_);
375
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000376 if (num_consecutive_old_packets_ > kMaxConsecutiveOldPackets) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100377 RTC_LOG(LS_WARNING)
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000378 << num_consecutive_old_packets_
379 << " consecutive old packets received. Flushing the jitter buffer.";
380 Flush();
381 return kFlushIndicator;
382 }
383 return kOldPacket;
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000384 }
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000385
asapersson9a4cd872015-10-23 00:27:14 -0700386 num_consecutive_old_packets_ = 0;
387
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000388 VCMFrameBuffer* frame;
389 FrameList* frame_list;
390 const VCMFrameBufferEnum error = GetFrame(packet, &frame, &frame_list);
391 if (error != kNoError)
392 return error;
393
Evan Shrubsolee9126c12022-03-07 14:50:51 +0100394 Timestamp now = clock_->CurrentTime();
mikhal@webrtc.org3c5a9242013-09-03 20:45:36 +0000395 // We are keeping track of the first and latest seq numbers, and
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000396 // the number of wraps to be able to calculate how many packets we expect.
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000397 if (first_packet_since_reset_) {
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000398 // Now it's time to start estimating jitter
399 // reset the delay estimate.
Evan Shrubsolee9126c12022-03-07 14:50:51 +0100400 inter_frame_delay_.Reset();
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000401 }
402
403 // Empty packets may bias the jitter estimate (lacking size component),
404 // therefore don't let empty packet trigger the following updates:
Niels Möllerabbc50e2019-04-24 09:41:16 +0200405 if (packet.video_header.frame_type != VideoFrameType::kEmptyFrame) {
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000406 if (waiting_for_completion_.timestamp == packet.timestamp) {
407 // This can get bad if we have a lot of duplicate packets,
408 // we will then count some packet multiple times.
409 waiting_for_completion_.frame_size += packet.sizeBytes;
Evan Shrubsolee9126c12022-03-07 14:50:51 +0100410 waiting_for_completion_.latest_packet_time = now.ms();
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000411 } else if (waiting_for_completion_.latest_packet_time >= 0 &&
Evan Shrubsolee9126c12022-03-07 14:50:51 +0100412 waiting_for_completion_.latest_packet_time + 2000 <= now.ms()) {
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000413 // A packet should never be more than two seconds late
414 UpdateJitterEstimate(waiting_for_completion_, true);
415 waiting_for_completion_.latest_packet_time = -1;
416 waiting_for_completion_.frame_size = 0;
417 waiting_for_completion_.timestamp = 0;
418 }
419 }
420
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000421 VCMFrameBufferStateEnum previous_state = frame->GetState();
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000422 // Insert packet.
agalusza@google.comd818dcb2013-07-29 21:48:11 +0000423 FrameData frame_data;
Niels Möller50150a12019-04-16 16:11:09 +0200424 frame_data.rtt_ms = kDefaultRtt;
agalusza@google.comd818dcb2013-07-29 21:48:11 +0000425 frame_data.rolling_average_packets_per_frame = average_packets_per_frame_;
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000426 VCMFrameBufferEnum buffer_state =
Evan Shrubsolee9126c12022-03-07 14:50:51 +0100427 frame->InsertPacket(packet, now.ms(), frame_data);
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000428
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000429 if (buffer_state > 0) {
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000430 if (first_packet_since_reset_) {
431 latest_received_sequence_number_ = packet.seqNum;
432 first_packet_since_reset_ = false;
433 } else {
434 if (IsPacketRetransmitted(packet)) {
435 frame->IncrementNackCount();
436 }
pbos@webrtc.orgebb467f2014-05-19 15:28:02 +0000437 if (!UpdateNackList(packet.seqNum) &&
Niels Möllerabbc50e2019-04-24 09:41:16 +0200438 packet.video_header.frame_type != VideoFrameType::kVideoFrameKey) {
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000439 buffer_state = kFlushIndicator;
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000440 }
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000441
philipel9d3ab612015-12-21 04:12:39 -0800442 latest_received_sequence_number_ =
443 LatestSequenceNumber(latest_received_sequence_number_, packet.seqNum);
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000444 }
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000445 }
mikhal@webrtc.org3c5a9242013-09-03 20:45:36 +0000446
447 // Is the frame already in the decodable list?
mikhal@webrtc.org3c5a9242013-09-03 20:45:36 +0000448 bool continuous = IsContinuous(*frame);
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000449 switch (buffer_state) {
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000450 case kGeneralError:
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000451 case kTimeStampError:
452 case kSizeError: {
sprang22691e02016-07-13 10:57:07 -0700453 RecycleFrameBuffer(frame);
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000454 break;
455 }
456 case kCompleteSession: {
Niels Möller375b3462019-01-10 15:35:56 +0100457 if (previous_state != kStateComplete) {
mikhal@webrtc.org3c5a9242013-09-03 20:45:36 +0000458 if (continuous) {
459 // Signal that we have a complete session.
460 frame_event_->Set();
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000461 }
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000462 }
Niels Möller375b3462019-01-10 15:35:56 +0100463
mikhal@webrtc.org3c5a9242013-09-03 20:45:36 +0000464 *retransmitted = (frame->GetNackCount() > 0);
mikhal@webrtc.org3c5a9242013-09-03 20:45:36 +0000465 if (continuous) {
mikhal@webrtc.org3c5a9242013-09-03 20:45:36 +0000466 decodable_frames_.InsertFrame(frame);
467 FindAndInsertContinuousFrames(*frame);
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000468 } else {
mikhal@webrtc.org3c5a9242013-09-03 20:45:36 +0000469 incomplete_frames_.InsertFrame(frame);
470 }
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000471 break;
472 }
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000473 case kIncomplete: {
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000474 if (frame->GetState() == kStateEmpty &&
475 last_decoded_state_.UpdateEmptyFrame(frame)) {
sprang22691e02016-07-13 10:57:07 -0700476 RecycleFrameBuffer(frame);
mikhal@webrtc.org3c5a9242013-09-03 20:45:36 +0000477 return kNoError;
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000478 } else {
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000479 incomplete_frames_.InsertFrame(frame);
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000480 }
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000481 break;
482 }
483 case kNoError:
mikhal@webrtc.orgf31a47a2013-08-26 17:10:11 +0000484 case kOutOfBoundsPacket:
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000485 case kDuplicatePacket: {
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000486 // Put back the frame where it came from.
487 if (frame_list != NULL) {
488 frame_list->InsertFrame(frame);
489 } else {
sprang22691e02016-07-13 10:57:07 -0700490 RecycleFrameBuffer(frame);
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000491 }
asapersson@webrtc.org96dc6852014-11-03 14:40:38 +0000492 ++num_duplicated_packets_;
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000493 break;
494 }
stefan@webrtc.org3417eb42013-05-21 15:25:53 +0000495 case kFlushIndicator:
sprang22691e02016-07-13 10:57:07 -0700496 RecycleFrameBuffer(frame);
mikhal@webrtc.org3c5a9242013-09-03 20:45:36 +0000497 return kFlushIndicator;
philipel9d3ab612015-12-21 04:12:39 -0800498 default:
Artem Titovd3251962021-11-15 16:57:07 +0100499 RTC_DCHECK_NOTREACHED();
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000500 }
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000501 return buffer_state;
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000502}
503
philipel9d3ab612015-12-21 04:12:39 -0800504bool VCMJitterBuffer::IsContinuousInState(
505 const VCMFrameBuffer& frame,
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000506 const VCMDecodingState& decoding_state) const {
Niels Möller375b3462019-01-10 15:35:56 +0100507 // Is this frame complete and continuous?
508 return (frame.GetState() == kStateComplete) &&
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000509 decoding_state.ContinuousFrame(&frame);
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000510}
511
512bool VCMJitterBuffer::IsContinuous(const VCMFrameBuffer& frame) const {
513 if (IsContinuousInState(frame, last_decoded_state_)) {
514 return true;
515 }
516 VCMDecodingState decoding_state;
517 decoding_state.CopyFrom(last_decoded_state_);
518 for (FrameList::const_iterator it = decodable_frames_.begin();
philipel9d3ab612015-12-21 04:12:39 -0800519 it != decodable_frames_.end(); ++it) {
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +0000520 VCMFrameBuffer* decodable_frame = it->second;
Niels Möller23775882018-08-16 10:24:12 +0200521 if (IsNewerTimestamp(decodable_frame->Timestamp(), frame.Timestamp())) {
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000522 break;
523 }
524 decoding_state.SetState(decodable_frame);
525 if (IsContinuousInState(frame, decoding_state)) {
526 return true;
527 }
528 }
529 return false;
530}
531
532void VCMJitterBuffer::FindAndInsertContinuousFrames(
533 const VCMFrameBuffer& new_frame) {
534 VCMDecodingState decoding_state;
535 decoding_state.CopyFrom(last_decoded_state_);
536 decoding_state.SetState(&new_frame);
Noah Richardse4cb4e92015-05-22 14:03:00 -0700537 FindAndInsertContinuousFramesWithState(decoding_state);
538}
539
540void VCMJitterBuffer::FindAndInsertContinuousFramesWithState(
541 const VCMDecodingState& original_decoded_state) {
542 // Copy original_decoded_state so we can move the state forward with each
543 // decodable frame we find.
544 VCMDecodingState decoding_state;
545 decoding_state.CopyFrom(original_decoded_state);
546
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000547 // When temporal layers are available, we search for a complete or decodable
548 // frame until we hit one of the following:
549 // 1. Continuous base or sync layer.
550 // 2. The end of the list was reached.
551 for (FrameList::iterator it = incomplete_frames_.begin();
philipel9d3ab612015-12-21 04:12:39 -0800552 it != incomplete_frames_.end();) {
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +0000553 VCMFrameBuffer* frame = it->second;
Noah Richardse4cb4e92015-05-22 14:03:00 -0700554 if (IsNewerTimestamp(original_decoded_state.time_stamp(),
Niels Möller23775882018-08-16 10:24:12 +0200555 frame->Timestamp())) {
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000556 ++it;
557 continue;
558 }
559 if (IsContinuousInState(*frame, decoding_state)) {
560 decodable_frames_.InsertFrame(frame);
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +0000561 incomplete_frames_.erase(it++);
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000562 decoding_state.SetState(frame);
563 } else if (frame->TemporalId() <= 0) {
564 break;
565 } else {
566 ++it;
567 }
568 }
569}
570
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000571uint32_t VCMJitterBuffer::EstimatedJitterMs() {
Markus Handell6deec382020-07-07 12:17:12 +0200572 MutexLock lock(&mutex_);
Niels Möller691f62c2019-04-11 15:27:17 +0200573 const double rtt_mult = 1.0f;
Evan Shrubsole13e42a82022-03-07 13:21:51 +0100574 return jitter_estimate_.GetJitterEstimate(rtt_mult, absl::nullopt).ms();
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000575}
576
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +0000577void VCMJitterBuffer::SetNackSettings(size_t max_nack_list_size,
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000578 int max_packet_age_to_nack,
579 int max_incomplete_time_ms) {
Markus Handell6deec382020-07-07 12:17:12 +0200580 MutexLock lock(&mutex_);
Mirko Bonadei25ab3222021-07-08 20:08:20 +0200581 RTC_DCHECK_GE(max_packet_age_to_nack, 0);
582 RTC_DCHECK_GE(max_incomplete_time_ms_, 0);
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +0000583 max_nack_list_size_ = max_nack_list_size;
584 max_packet_age_to_nack_ = max_packet_age_to_nack;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000585 max_incomplete_time_ms_ = max_incomplete_time_ms;
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +0000586}
587
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000588int VCMJitterBuffer::NonContinuousOrIncompleteDuration() {
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000589 if (incomplete_frames_.empty()) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000590 return 0;
591 }
Niels Möller23775882018-08-16 10:24:12 +0200592 uint32_t start_timestamp = incomplete_frames_.Front()->Timestamp();
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000593 if (!decodable_frames_.empty()) {
Niels Möller23775882018-08-16 10:24:12 +0200594 start_timestamp = decodable_frames_.Back()->Timestamp();
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000595 }
Niels Möller23775882018-08-16 10:24:12 +0200596 return incomplete_frames_.Back()->Timestamp() - start_timestamp;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000597}
598
599uint16_t VCMJitterBuffer::EstimatedLowSequenceNumber(
600 const VCMFrameBuffer& frame) const {
Mirko Bonadei25ab3222021-07-08 20:08:20 +0200601 RTC_DCHECK_GE(frame.GetLowSeqNum(), 0);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000602 if (frame.HaveFirstPacket())
603 return frame.GetLowSeqNum();
hclam@chromium.orgfe307e12013-05-16 21:19:59 +0000604
605 // This estimate is not accurate if more than one packet with lower sequence
606 // number is lost.
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000607 return frame.GetLowSeqNum() - 1;
608}
609
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700610std::vector<uint16_t> VCMJitterBuffer::GetNackList(bool* request_key_frame) {
Markus Handell6deec382020-07-07 12:17:12 +0200611 MutexLock lock(&mutex_);
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000612 *request_key_frame = false;
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000613 if (last_decoded_state_.in_initial_state()) {
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000614 VCMFrameBuffer* next_frame = NextFrame();
Niels Möller8f7ce222019-03-21 15:43:58 +0100615 const bool first_frame_is_key =
616 next_frame &&
617 next_frame->FrameType() == VideoFrameType::kVideoFrameKey &&
618 next_frame->HaveFirstPacket();
stefan@webrtc.org885cd132013-04-16 09:38:26 +0000619 if (!first_frame_is_key) {
philipel9d3ab612015-12-21 04:12:39 -0800620 bool have_non_empty_frame =
621 decodable_frames_.end() != find_if(decodable_frames_.begin(),
622 decodable_frames_.end(),
623 HasNonEmptyState);
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000624 if (!have_non_empty_frame) {
philipel9d3ab612015-12-21 04:12:39 -0800625 have_non_empty_frame =
626 incomplete_frames_.end() != find_if(incomplete_frames_.begin(),
627 incomplete_frames_.end(),
628 HasNonEmptyState);
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000629 }
stefan@webrtc.org885cd132013-04-16 09:38:26 +0000630 bool found_key_frame = RecycleFramesUntilKeyFrame();
631 if (!found_key_frame) {
632 *request_key_frame = have_non_empty_frame;
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700633 return std::vector<uint16_t>();
stefan@webrtc.org885cd132013-04-16 09:38:26 +0000634 }
635 }
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000636 }
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000637 if (TooLargeNackList()) {
638 *request_key_frame = !HandleTooLargeNackList();
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000639 }
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000640 if (max_incomplete_time_ms_ > 0) {
641 int non_continuous_incomplete_duration =
642 NonContinuousOrIncompleteDuration();
643 if (non_continuous_incomplete_duration > 90 * max_incomplete_time_ms_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100644 RTC_LOG_F(LS_WARNING) << "Too long non-decodable duration: "
645 << non_continuous_incomplete_duration << " > "
646 << 90 * max_incomplete_time_ms_;
philipel9d3ab612015-12-21 04:12:39 -0800647 FrameList::reverse_iterator rit = find_if(
648 incomplete_frames_.rbegin(), incomplete_frames_.rend(), IsKeyFrame);
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000649 if (rit == incomplete_frames_.rend()) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000650 // Request a key frame if we don't have one already.
651 *request_key_frame = true;
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700652 return std::vector<uint16_t>();
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000653 } else {
654 // Skip to the last key frame. If it's incomplete we will start
655 // NACKing it.
hclam@chromium.orgfe307e12013-05-16 21:19:59 +0000656 // Note that the estimated low sequence number is correct for VP8
657 // streams because only the first packet of a key frame is marked.
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000658 last_decoded_state_.Reset();
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +0000659 DropPacketsFromNackList(EstimatedLowSequenceNumber(*rit->second));
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000660 }
661 }
662 }
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700663 std::vector<uint16_t> nack_list(missing_sequence_numbers_.begin(),
664 missing_sequence_numbers_.end());
665 return nack_list;
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000666}
667
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000668VCMFrameBuffer* VCMJitterBuffer::NextFrame() const {
669 if (!decodable_frames_.empty())
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +0000670 return decodable_frames_.Front();
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000671 if (!incomplete_frames_.empty())
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +0000672 return incomplete_frames_.Front();
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000673 return NULL;
674}
675
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000676bool VCMJitterBuffer::UpdateNackList(uint16_t sequence_number) {
stefan@webrtc.org4d2f5de2013-04-09 18:24:41 +0000677 // Make sure we don't add packets which are already too old to be decoded.
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000678 if (!last_decoded_state_.in_initial_state()) {
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000679 latest_received_sequence_number_ = LatestSequenceNumber(
philipel9d3ab612015-12-21 04:12:39 -0800680 latest_received_sequence_number_, last_decoded_state_.sequence_num());
stefan@webrtc.org4d2f5de2013-04-09 18:24:41 +0000681 }
stefan@webrtc.org7bc465b2013-04-11 17:48:02 +0000682 if (IsNewerSequenceNumber(sequence_number,
683 latest_received_sequence_number_)) {
stefan@webrtc.org4d2f5de2013-04-09 18:24:41 +0000684 // Push any missing sequence numbers to the NACK list.
685 for (uint16_t i = latest_received_sequence_number_ + 1;
stefan@webrtc.orga5dee332013-05-07 11:11:17 +0000686 IsNewerSequenceNumber(sequence_number, i); ++i) {
stefan@webrtc.org4d2f5de2013-04-09 18:24:41 +0000687 missing_sequence_numbers_.insert(missing_sequence_numbers_.end(), i);
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000688 }
stefan@webrtc.org4d2f5de2013-04-09 18:24:41 +0000689 if (TooLargeNackList() && !HandleTooLargeNackList()) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100690 RTC_LOG(LS_WARNING) << "Requesting key frame due to too large NACK list.";
stefan@webrtc.org4d2f5de2013-04-09 18:24:41 +0000691 return false;
692 }
693 if (MissingTooOldPacket(sequence_number) &&
694 !HandleTooOldPackets(sequence_number)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100695 RTC_LOG(LS_WARNING)
696 << "Requesting key frame due to missing too old packets";
stefan@webrtc.org4d2f5de2013-04-09 18:24:41 +0000697 return false;
698 }
699 } else {
700 missing_sequence_numbers_.erase(sequence_number);
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000701 }
702 return true;
703}
704
705bool VCMJitterBuffer::TooLargeNackList() const {
706 return missing_sequence_numbers_.size() > max_nack_list_size_;
707}
708
709bool VCMJitterBuffer::HandleTooLargeNackList() {
710 // Recycle frames until the NACK list is small enough. It is likely cheaper to
711 // request a key frame than to retransmit this many missing packets.
Mirko Bonadei675513b2017-11-09 11:09:25 +0100712 RTC_LOG_F(LS_WARNING) << "NACK list has grown too large: "
713 << missing_sequence_numbers_.size() << " > "
714 << max_nack_list_size_;
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000715 bool key_frame_found = false;
stefan@webrtc.org4d2f5de2013-04-09 18:24:41 +0000716 while (TooLargeNackList()) {
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000717 key_frame_found = RecycleFramesUntilKeyFrame();
718 }
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000719 return key_frame_found;
720}
721
722bool VCMJitterBuffer::MissingTooOldPacket(
723 uint16_t latest_sequence_number) const {
724 if (missing_sequence_numbers_.empty()) {
725 return false;
726 }
philipel9d3ab612015-12-21 04:12:39 -0800727 const uint16_t age_of_oldest_missing_packet =
728 latest_sequence_number - *missing_sequence_numbers_.begin();
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000729 // Recycle frames if the NACK list contains too old sequence numbers as
730 // the packets may have already been dropped by the sender.
731 return age_of_oldest_missing_packet > max_packet_age_to_nack_;
732}
733
734bool VCMJitterBuffer::HandleTooOldPackets(uint16_t latest_sequence_number) {
735 bool key_frame_found = false;
philipel9d3ab612015-12-21 04:12:39 -0800736 const uint16_t age_of_oldest_missing_packet =
737 latest_sequence_number - *missing_sequence_numbers_.begin();
Mirko Bonadei675513b2017-11-09 11:09:25 +0100738 RTC_LOG_F(LS_WARNING) << "NACK list contains too old sequence numbers: "
739 << age_of_oldest_missing_packet << " > "
740 << max_packet_age_to_nack_;
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000741 while (MissingTooOldPacket(latest_sequence_number)) {
742 key_frame_found = RecycleFramesUntilKeyFrame();
743 }
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000744 return key_frame_found;
745}
746
747void VCMJitterBuffer::DropPacketsFromNackList(
748 uint16_t last_decoded_sequence_number) {
749 // Erase all sequence numbers from the NACK list which we won't need any
750 // longer.
philipel9d3ab612015-12-21 04:12:39 -0800751 missing_sequence_numbers_.erase(
752 missing_sequence_numbers_.begin(),
753 missing_sequence_numbers_.upper_bound(last_decoded_sequence_number));
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000754}
755
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000756VCMFrameBuffer* VCMJitterBuffer::GetEmptyFrame() {
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000757 if (free_frames_.empty()) {
758 if (!TryToIncreaseJitterBufferSize()) {
759 return NULL;
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000760 }
761 }
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000762 VCMFrameBuffer* frame = free_frames_.front();
763 free_frames_.pop_front();
764 return frame;
765}
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000766
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000767bool VCMJitterBuffer::TryToIncreaseJitterBufferSize() {
768 if (max_number_of_frames_ >= kMaxNumberOfFrames)
769 return false;
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000770 free_frames_.push_back(new VCMFrameBuffer());
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000771 ++max_number_of_frames_;
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000772 return true;
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000773}
774
775// Recycle oldest frames up to a key frame, used if jitter buffer is completely
776// full.
777bool VCMJitterBuffer::RecycleFramesUntilKeyFrame() {
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000778 // First release incomplete frames, and only release decodable frames if there
779 // are no incomplete ones.
780 FrameList::iterator key_frame_it;
781 bool key_frame_found = false;
782 int dropped_frames = 0;
783 dropped_frames += incomplete_frames_.RecycleFramesUntilKeyFrame(
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000784 &key_frame_it, &free_frames_);
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000785 key_frame_found = key_frame_it != incomplete_frames_.end();
786 if (dropped_frames == 0) {
787 dropped_frames += decodable_frames_.RecycleFramesUntilKeyFrame(
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000788 &key_frame_it, &free_frames_);
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000789 key_frame_found = key_frame_it != decodable_frames_.end();
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000790 }
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000791 if (key_frame_found) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100792 RTC_LOG(LS_INFO) << "Found key frame while dropping frames.";
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000793 // Reset last decoded state to make sure the next frame decoded is a key
794 // frame, and start NACKing from here.
795 last_decoded_state_.Reset();
stefan@webrtc.org50fb4af2013-06-17 07:33:58 +0000796 DropPacketsFromNackList(EstimatedLowSequenceNumber(*key_frame_it->second));
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000797 } else if (decodable_frames_.empty()) {
stefan@webrtc.org4cf1a8a2013-06-27 15:20:14 +0000798 // All frames dropped. Reset the decoding state and clear missing sequence
799 // numbers as we're starting fresh.
800 last_decoded_state_.Reset();
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000801 missing_sequence_numbers_.clear();
edjee@google.com79b02892013-04-04 19:43:34 +0000802 }
stefan@webrtc.orgc8b29a22013-06-17 07:13:16 +0000803 return key_frame_found;
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000804}
805
agalusza@google.comd818dcb2013-07-29 21:48:11 +0000806void VCMJitterBuffer::UpdateAveragePacketsPerFrame(int current_number_packets) {
807 if (frame_counter_ > kFastConvergeThreshold) {
philipel9d3ab612015-12-21 04:12:39 -0800808 average_packets_per_frame_ =
809 average_packets_per_frame_ * (1 - kNormalConvergeMultiplier) +
810 current_number_packets * kNormalConvergeMultiplier;
agalusza@google.comd818dcb2013-07-29 21:48:11 +0000811 } else if (frame_counter_ > 0) {
philipel9d3ab612015-12-21 04:12:39 -0800812 average_packets_per_frame_ =
813 average_packets_per_frame_ * (1 - kFastConvergeMultiplier) +
814 current_number_packets * kFastConvergeMultiplier;
agalusza@google.comd818dcb2013-07-29 21:48:11 +0000815 frame_counter_++;
816 } else {
817 average_packets_per_frame_ = current_number_packets;
818 frame_counter_++;
819 }
820}
821
Artem Titovdcd7fc72021-08-09 13:02:57 +0200822// Must be called under the critical section `mutex_`.
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000823void VCMJitterBuffer::CleanUpOldOrEmptyFrames() {
pbos@webrtc.org4f16c872014-11-24 09:06:48 +0000824 decodable_frames_.CleanUpOldOrEmptyFrames(&last_decoded_state_,
825 &free_frames_);
826 incomplete_frames_.CleanUpOldOrEmptyFrames(&last_decoded_state_,
827 &free_frames_);
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000828 if (!last_decoded_state_.in_initial_state()) {
829 DropPacketsFromNackList(last_decoded_state_.sequence_num());
830 }
mikhal@webrtc.org832caca2011-12-13 21:15:05 +0000831}
832
Artem Titovdcd7fc72021-08-09 13:02:57 +0200833// Must be called from within `mutex_`.
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000834bool VCMJitterBuffer::IsPacketRetransmitted(const VCMPacket& packet) const {
stefan@webrtc.orga64300a2013-03-04 15:24:40 +0000835 return missing_sequence_numbers_.find(packet.seqNum) !=
philipel9d3ab612015-12-21 04:12:39 -0800836 missing_sequence_numbers_.end();
niklase@google.com470e71d2011-07-07 08:21:25 +0000837}
838
Artem Titovdcd7fc72021-08-09 13:02:57 +0200839// Must be called under the critical section `mutex_`. Should never be
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000840// called with retransmitted frames, they must be filtered out before this
841// function is called.
842void VCMJitterBuffer::UpdateJitterEstimate(const VCMJitterSample& sample,
843 bool incomplete_frame) {
844 if (sample.latest_packet_time == -1) {
845 return;
846 }
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000847 UpdateJitterEstimate(sample.latest_packet_time, sample.timestamp,
848 sample.frame_size, incomplete_frame);
849}
850
Markus Handell6deec382020-07-07 12:17:12 +0200851// Must be called under the critical section mutex_. Should never be
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000852// called with retransmitted frames, they must be filtered out before this
853// function is called.
854void VCMJitterBuffer::UpdateJitterEstimate(const VCMFrameBuffer& frame,
855 bool incomplete_frame) {
856 if (frame.LatestPacketTimeMs() == -1) {
857 return;
858 }
859 // No retransmitted frames should be a part of the jitter
860 // estimate.
Niels Möller23775882018-08-16 10:24:12 +0200861 UpdateJitterEstimate(frame.LatestPacketTimeMs(), frame.Timestamp(),
Niels Möllerf0eee002018-11-28 16:31:29 +0100862 frame.size(), incomplete_frame);
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000863}
864
Artem Titovdcd7fc72021-08-09 13:02:57 +0200865// Must be called under the critical section `mutex_`. Should never be
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000866// called with retransmitted frames, they must be filtered out before this
867// function is called.
philipel9d3ab612015-12-21 04:12:39 -0800868void VCMJitterBuffer::UpdateJitterEstimate(int64_t latest_packet_time_ms,
869 uint32_t timestamp,
870 unsigned int frame_size,
871 bool incomplete_frame) {
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000872 if (latest_packet_time_ms == -1) {
873 return;
874 }
Evan Shrubsolee9126c12022-03-07 14:50:51 +0100875 auto frame_delay = inter_frame_delay_.CalculateDelay(
876 timestamp, Timestamp::Millis(latest_packet_time_ms));
877
878 bool not_reordered = frame_delay.has_value();
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000879 // Filter out frames which have been reordered in time by the network
880 if (not_reordered) {
881 // Update the jitter estimate with the new samples
Evan Shrubsolee9126c12022-03-07 14:50:51 +0100882 jitter_estimate_.UpdateEstimate(*frame_delay, DataSize::Bytes(frame_size),
Evan Shrubsole13e42a82022-03-07 13:21:51 +0100883 incomplete_frame);
stefan@webrtc.org912981f2012-10-12 07:04:52 +0000884 }
885}
886
sprang22691e02016-07-13 10:57:07 -0700887void VCMJitterBuffer::RecycleFrameBuffer(VCMFrameBuffer* frame) {
888 frame->Reset();
889 free_frames_.push_back(frame);
890}
891
stefan@webrtc.org932ab182011-11-29 11:33:31 +0000892} // namespace webrtc