Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(197)

Side by Side Diff: webrtc/modules/video_coding/jitter_buffer.cc

Issue 1778503002: Experiment for the nack module. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 #include "webrtc/modules/video_coding/jitter_buffer.h" 10 #include "webrtc/modules/video_coding/jitter_buffer.h"
(...skipping 10 matching lines...) Expand all
21 #include "webrtc/modules/video_coding/include/video_coding.h" 21 #include "webrtc/modules/video_coding/include/video_coding.h"
22 #include "webrtc/modules/video_coding/frame_buffer.h" 22 #include "webrtc/modules/video_coding/frame_buffer.h"
23 #include "webrtc/modules/video_coding/inter_frame_delay.h" 23 #include "webrtc/modules/video_coding/inter_frame_delay.h"
24 #include "webrtc/modules/video_coding/internal_defines.h" 24 #include "webrtc/modules/video_coding/internal_defines.h"
25 #include "webrtc/modules/video_coding/jitter_buffer_common.h" 25 #include "webrtc/modules/video_coding/jitter_buffer_common.h"
26 #include "webrtc/modules/video_coding/jitter_estimator.h" 26 #include "webrtc/modules/video_coding/jitter_estimator.h"
27 #include "webrtc/modules/video_coding/packet.h" 27 #include "webrtc/modules/video_coding/packet.h"
28 #include "webrtc/system_wrappers/include/clock.h" 28 #include "webrtc/system_wrappers/include/clock.h"
29 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" 29 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
30 #include "webrtc/system_wrappers/include/event_wrapper.h" 30 #include "webrtc/system_wrappers/include/event_wrapper.h"
31 #include "webrtc/system_wrappers/include/field_trial.h"
31 #include "webrtc/system_wrappers/include/metrics.h" 32 #include "webrtc/system_wrappers/include/metrics.h"
32 33
33 namespace webrtc { 34 namespace webrtc {
34
35 // Interval for updating SS data. 35 // Interval for updating SS data.
36 static const uint32_t kSsCleanupIntervalSec = 60; 36 static const uint32_t kSsCleanupIntervalSec = 60;
37 37
38 // Use this rtt if no value has been reported. 38 // Use this rtt if no value has been reported.
39 static const int64_t kDefaultRtt = 200; 39 static const int64_t kDefaultRtt = 200;
40 40
41 // Request a keyframe if no continuous frame has been received for this 41 // Request a keyframe if no continuous frame has been received for this
42 // number of milliseconds and NACKs are disabled. 42 // number of milliseconds and NACKs are disabled.
43 static const int64_t kMaxDiscontinuousFramesTime = 1000; 43 static const int64_t kMaxDiscontinuousFramesTime = 1000;
44 44
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 if (Find(frame_it.second->TimeStamp(), &ss_it)) { 208 if (Find(frame_it.second->TimeStamp(), &ss_it)) {
209 if (gof_idx >= ss_it->second.num_frames_in_gof) { 209 if (gof_idx >= ss_it->second.num_frames_in_gof) {
210 continue; // Assume corresponding SS not yet received. 210 continue; // Assume corresponding SS not yet received.
211 } 211 }
212 frame_it.second->SetGofInfo(ss_it->second, gof_idx); 212 frame_it.second->SetGofInfo(ss_it->second, gof_idx);
213 } 213 }
214 } 214 }
215 } 215 }
216 216
217 VCMJitterBuffer::VCMJitterBuffer(Clock* clock, 217 VCMJitterBuffer::VCMJitterBuffer(Clock* clock,
218 std::unique_ptr<EventWrapper> event) 218 std::unique_ptr<EventWrapper> event,
219 ProcessThread* module_process_thread,
220 NackSender* nack_sender,
221 KeyFrameRequestSender* keyframe_request_sender)
219 : clock_(clock), 222 : clock_(clock),
220 running_(false), 223 running_(false),
221 crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), 224 crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
222 frame_event_(std::move(event)), 225 frame_event_(std::move(event)),
223 max_number_of_frames_(kStartNumberOfFrames), 226 max_number_of_frames_(kStartNumberOfFrames),
224 free_frames_(), 227 free_frames_(),
225 decodable_frames_(), 228 decodable_frames_(),
226 incomplete_frames_(), 229 incomplete_frames_(),
227 last_decoded_state_(), 230 last_decoded_state_(),
228 first_packet_since_reset_(true), 231 first_packet_since_reset_(true),
(...skipping 13 matching lines...) Expand all
242 rtt_ms_(kDefaultRtt), 245 rtt_ms_(kDefaultRtt),
243 nack_mode_(kNoNack), 246 nack_mode_(kNoNack),
244 low_rtt_nack_threshold_ms_(-1), 247 low_rtt_nack_threshold_ms_(-1),
245 high_rtt_nack_threshold_ms_(-1), 248 high_rtt_nack_threshold_ms_(-1),
246 missing_sequence_numbers_(SequenceNumberLessThan()), 249 missing_sequence_numbers_(SequenceNumberLessThan()),
247 max_nack_list_size_(0), 250 max_nack_list_size_(0),
248 max_packet_age_to_nack_(0), 251 max_packet_age_to_nack_(0),
249 max_incomplete_time_ms_(0), 252 max_incomplete_time_ms_(0),
250 decode_error_mode_(kNoErrors), 253 decode_error_mode_(kNoErrors),
251 average_packets_per_frame_(0.0f), 254 average_packets_per_frame_(0.0f),
252 frame_counter_(0) { 255 frame_counter_(0),
256 module_process_thread_(module_process_thread) {
257 if (field_trial::FindFullName("WebRTC-NewVideoJitterBuffer") == "Enabled") {
258 RTC_DCHECK(module_process_thread);
259 RTC_DCHECK(nack_sender);
260 RTC_DCHECK(keyframe_request_sender);
261
262 nack_module_.reset(
263 new NackModule(clock, nack_sender, keyframe_request_sender));
stefan-webrtc 2016/03/10 14:20:40 Set in initializer list instead so that you can ma
philipel 2016/03/10 16:39:27 Can't do that since we have to check first if we a
stefan-webrtc 2016/03/10 17:06:29 You can still do it: nack_module_(IsInExperiment(
philipel 2016/03/11 09:24:14 Ok, it is possible, but don't you think it would b
stefan-webrtc 2016/03/11 09:57:11 I think that's fine, just break it out to a static
philipel 2016/03/11 10:12:59 Done.
264 module_process_thread_->RegisterModule(nack_module_.get());
265 }
253 for (int i = 0; i < kStartNumberOfFrames; i++) 266 for (int i = 0; i < kStartNumberOfFrames; i++)
254 free_frames_.push_back(new VCMFrameBuffer()); 267 free_frames_.push_back(new VCMFrameBuffer());
255 } 268 }
256 269
257 VCMJitterBuffer::~VCMJitterBuffer() { 270 VCMJitterBuffer::~VCMJitterBuffer() {
258 Stop(); 271 Stop();
259 for (UnorderedFrameList::iterator it = free_frames_.begin(); 272 for (UnorderedFrameList::iterator it = free_frames_.begin();
260 it != free_frames_.end(); ++it) { 273 it != free_frames_.end(); ++it) {
261 delete *it; 274 delete *it;
262 } 275 }
263 for (FrameList::iterator it = incomplete_frames_.begin(); 276 for (FrameList::iterator it = incomplete_frames_.begin();
264 it != incomplete_frames_.end(); ++it) { 277 it != incomplete_frames_.end(); ++it) {
265 delete it->second; 278 delete it->second;
266 } 279 }
267 for (FrameList::iterator it = decodable_frames_.begin(); 280 for (FrameList::iterator it = decodable_frames_.begin();
268 it != decodable_frames_.end(); ++it) { 281 it != decodable_frames_.end(); ++it) {
269 delete it->second; 282 delete it->second;
270 } 283 }
284 if (field_trial::FindFullName("WebRTC-NewVideoJitterBuffer") == "Enabled")
stefan-webrtc 2016/03/10 14:20:40 if (nack_module_) instead, here and all places bel
philipel 2016/03/10 16:39:27 Done.
285 module_process_thread_->DeRegisterModule(nack_module_.get());
271 delete crit_sect_; 286 delete crit_sect_;
272 } 287 }
273 288
274 void VCMJitterBuffer::UpdateHistograms() { 289 void VCMJitterBuffer::UpdateHistograms() {
275 if (num_packets_ <= 0 || !running_) { 290 if (num_packets_ <= 0 || !running_) {
276 return; 291 return;
277 } 292 }
278 int64_t elapsed_sec = 293 int64_t elapsed_sec =
279 (clock_->TimeInMilliseconds() - time_first_packet_ms_) / 1000; 294 (clock_->TimeInMilliseconds() - time_first_packet_ms_) / 1000;
280 if (elapsed_sec < metrics::kMinRunTimeInSeconds) { 295 if (elapsed_sec < metrics::kMinRunTimeInSeconds) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 first_packet_since_reset_ = true; 337 first_packet_since_reset_ = true;
323 rtt_ms_ = kDefaultRtt; 338 rtt_ms_ = kDefaultRtt;
324 last_decoded_state_.Reset(); 339 last_decoded_state_.Reset();
325 } 340 }
326 341
327 void VCMJitterBuffer::Stop() { 342 void VCMJitterBuffer::Stop() {
328 crit_sect_->Enter(); 343 crit_sect_->Enter();
329 UpdateHistograms(); 344 UpdateHistograms();
330 running_ = false; 345 running_ = false;
331 last_decoded_state_.Reset(); 346 last_decoded_state_.Reset();
347 if (field_trial::FindFullName("WebRTC-NewVideoJitterBuffer") == "Enabled")
348 nack_module_->Stop();
332 349
333 // Make sure all frames are free and reset. 350 // Make sure all frames are free and reset.
334 for (FrameList::iterator it = decodable_frames_.begin(); 351 for (FrameList::iterator it = decodable_frames_.begin();
335 it != decodable_frames_.end(); ++it) { 352 it != decodable_frames_.end(); ++it) {
336 free_frames_.push_back(it->second); 353 free_frames_.push_back(it->second);
337 } 354 }
338 for (FrameList::iterator it = incomplete_frames_.begin(); 355 for (FrameList::iterator it = incomplete_frames_.begin();
339 it != incomplete_frames_.end(); ++it) { 356 it != incomplete_frames_.end(); ++it) {
340 free_frames_.push_back(it->second); 357 free_frames_.push_back(it->second);
341 } 358 }
342 for (UnorderedFrameList::iterator it = free_frames_.begin(); 359 for (UnorderedFrameList::iterator it = free_frames_.begin();
343 it != free_frames_.end(); ++it) { 360 it != free_frames_.end(); ++it) {
344 (*it)->Reset(); 361 (*it)->Reset();
345 } 362 }
346 decodable_frames_.clear(); 363 decodable_frames_.clear();
347 incomplete_frames_.clear(); 364 incomplete_frames_.clear();
348 crit_sect_->Leave(); 365 crit_sect_->Leave();
349 // Make sure we wake up any threads waiting on these events. 366 // Make sure we wake up any threads waiting on these events.
350 frame_event_->Set(); 367 frame_event_->Set();
351 } 368 }
352 369
353 bool VCMJitterBuffer::Running() const { 370 bool VCMJitterBuffer::Running() const {
354 CriticalSectionScoped cs(crit_sect_); 371 CriticalSectionScoped cs(crit_sect_);
355 return running_; 372 return running_;
356 } 373 }
357 374
358 void VCMJitterBuffer::Flush() { 375 void VCMJitterBuffer::Flush() {
stefan-webrtc 2016/03/10 14:20:40 Notify the nack module about the fact that we no l
philipel 2016/03/10 16:39:28 Done.
359 CriticalSectionScoped cs(crit_sect_); 376 CriticalSectionScoped cs(crit_sect_);
360 decodable_frames_.Reset(&free_frames_); 377 decodable_frames_.Reset(&free_frames_);
361 incomplete_frames_.Reset(&free_frames_); 378 incomplete_frames_.Reset(&free_frames_);
362 last_decoded_state_.Reset(); // TODO(mikhal): sync reset. 379 last_decoded_state_.Reset(); // TODO(mikhal): sync reset.
363 num_consecutive_old_packets_ = 0; 380 num_consecutive_old_packets_ = 0;
364 // Also reset the jitter and delay estimates 381 // Also reset the jitter and delay estimates
365 jitter_estimate_.Reset(); 382 jitter_estimate_.Reset();
366 inter_frame_delay_.Reset(clock_->TimeInMilliseconds()); 383 inter_frame_delay_.Reset(clock_->TimeInMilliseconds());
367 waiting_for_completion_.frame_size = 0; 384 waiting_for_completion_.frame_size = 0;
368 waiting_for_completion_.timestamp = 0; 385 waiting_for_completion_.timestamp = 0;
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 // decoder. Propagates the missing_frame bit. 615 // decoder. Propagates the missing_frame bit.
599 frame->PrepareForDecode(continuous); 616 frame->PrepareForDecode(continuous);
600 617
601 // We have a frame - update the last decoded state and nack list. 618 // We have a frame - update the last decoded state and nack list.
602 last_decoded_state_.SetState(frame); 619 last_decoded_state_.SetState(frame);
603 DropPacketsFromNackList(last_decoded_state_.sequence_num()); 620 DropPacketsFromNackList(last_decoded_state_.sequence_num());
604 621
605 if ((*frame).IsSessionComplete()) 622 if ((*frame).IsSessionComplete())
606 UpdateAveragePacketsPerFrame(frame->NumPackets()); 623 UpdateAveragePacketsPerFrame(frame->NumPackets());
607 624
608 return frame; 625 return frame;
stefan-webrtc 2016/03/10 14:20:40 If we extract a frame for decoding I think we shou
philipel 2016/03/10 16:39:28 Better to do it here since this is the actual poin
609 } 626 }
610 627
611 // Release frame when done with decoding. Should never be used to release 628 // Release frame when done with decoding. Should never be used to release
612 // frames from within the jitter buffer. 629 // frames from within the jitter buffer.
613 void VCMJitterBuffer::ReleaseFrame(VCMEncodedFrame* frame) { 630 void VCMJitterBuffer::ReleaseFrame(VCMEncodedFrame* frame) {
614 CriticalSectionScoped cs(crit_sect_); 631 CriticalSectionScoped cs(crit_sect_);
615 VCMFrameBuffer* frame_buffer = static_cast<VCMFrameBuffer*>(frame); 632 VCMFrameBuffer* frame_buffer = static_cast<VCMFrameBuffer*>(frame);
616 if (frame_buffer) { 633 if (frame_buffer) {
617 free_frames_.push_back(frame_buffer); 634 free_frames_.push_back(frame_buffer);
618 } 635 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 const VCMFrameBuffer* frame_buffer = 675 const VCMFrameBuffer* frame_buffer =
659 static_cast<const VCMFrameBuffer*>(frame); 676 static_cast<const VCMFrameBuffer*>(frame);
660 *retransmitted = (frame_buffer->GetNackCount() > 0); 677 *retransmitted = (frame_buffer->GetNackCount() > 0);
661 return frame_buffer->LatestPacketTimeMs(); 678 return frame_buffer->LatestPacketTimeMs();
662 } 679 }
663 680
664 VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet, 681 VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet,
665 bool* retransmitted) { 682 bool* retransmitted) {
666 CriticalSectionScoped cs(crit_sect_); 683 CriticalSectionScoped cs(crit_sect_);
667 684
685 if (field_trial::FindFullName("WebRTC-NewVideoJitterBuffer") == "Enabled")
686 nack_module_->OnReceivedPacket(packet);
687
668 ++num_packets_; 688 ++num_packets_;
669 if (num_packets_ == 1) { 689 if (num_packets_ == 1) {
670 time_first_packet_ms_ = clock_->TimeInMilliseconds(); 690 time_first_packet_ms_ = clock_->TimeInMilliseconds();
671 } 691 }
672 // Does this packet belong to an old frame? 692 // Does this packet belong to an old frame?
673 if (last_decoded_state_.IsOldPacket(&packet)) { 693 if (last_decoded_state_.IsOldPacket(&packet)) {
674 // Account only for media packets. 694 // Account only for media packets.
675 if (packet.sizeBytes > 0) { 695 if (packet.sizeBytes > 0) {
676 num_discarded_packets_++; 696 num_discarded_packets_++;
677 num_consecutive_old_packets_++; 697 num_consecutive_old_packets_++;
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 // when waiting for retransmissions. 940 // when waiting for retransmissions.
921 rtt_mult = 0.0f; 941 rtt_mult = 0.0f;
922 } 942 }
923 return jitter_estimate_.GetJitterEstimate(rtt_mult); 943 return jitter_estimate_.GetJitterEstimate(rtt_mult);
924 } 944 }
925 945
926 void VCMJitterBuffer::UpdateRtt(int64_t rtt_ms) { 946 void VCMJitterBuffer::UpdateRtt(int64_t rtt_ms) {
927 CriticalSectionScoped cs(crit_sect_); 947 CriticalSectionScoped cs(crit_sect_);
928 rtt_ms_ = rtt_ms; 948 rtt_ms_ = rtt_ms;
929 jitter_estimate_.UpdateRtt(rtt_ms); 949 jitter_estimate_.UpdateRtt(rtt_ms);
950 if (field_trial::FindFullName("WebRTC-NewVideoJitterBuffer") == "Enabled")
951 nack_module_->UpdateRtt(rtt_ms);
930 } 952 }
931 953
932 void VCMJitterBuffer::SetNackMode(VCMNackMode mode, 954 void VCMJitterBuffer::SetNackMode(VCMNackMode mode,
933 int64_t low_rtt_nack_threshold_ms, 955 int64_t low_rtt_nack_threshold_ms,
934 int64_t high_rtt_nack_threshold_ms) { 956 int64_t high_rtt_nack_threshold_ms) {
935 CriticalSectionScoped cs(crit_sect_); 957 CriticalSectionScoped cs(crit_sect_);
936 nack_mode_ = mode; 958 nack_mode_ = mode;
937 if (mode == kNoNack) { 959 if (mode == kNoNack) {
938 missing_sequence_numbers_.clear(); 960 missing_sequence_numbers_.clear();
939 } 961 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 if (rit == incomplete_frames_.rend()) { 1057 if (rit == incomplete_frames_.rend()) {
1036 // Request a key frame if we don't have one already. 1058 // Request a key frame if we don't have one already.
1037 *request_key_frame = true; 1059 *request_key_frame = true;
1038 return std::vector<uint16_t>(); 1060 return std::vector<uint16_t>();
1039 } else { 1061 } else {
1040 // Skip to the last key frame. If it's incomplete we will start 1062 // Skip to the last key frame. If it's incomplete we will start
1041 // NACKing it. 1063 // NACKing it.
1042 // Note that the estimated low sequence number is correct for VP8 1064 // Note that the estimated low sequence number is correct for VP8
1043 // streams because only the first packet of a key frame is marked. 1065 // streams because only the first packet of a key frame is marked.
1044 last_decoded_state_.Reset(); 1066 last_decoded_state_.Reset();
1045 DropPacketsFromNackList(EstimatedLowSequenceNumber(*rit->second)); 1067 DropPacketsFromNackList(EstimatedLowSequenceNumber(*rit->second));
stefan-webrtc 2016/03/10 14:20:40 If we should run this code despite using the nack
philipel 2016/03/10 16:39:27 No, this is logic related to the old nack behavior
1046 } 1068 }
1047 } 1069 }
1048 } 1070 }
stefan-webrtc 2016/03/10 14:20:40 Should we really run lines 1017-1070 if using the
philipel 2016/03/10 16:39:27 Yes, the GetNackList interface does more than just
stefan-webrtc 2016/03/10 17:06:29 Ok, comment on why we don't return earlier to avoi
philipel 2016/03/11 09:24:14 Expanded my comment. This code won't be necessary
1071 // The experiment is running, the nack module will send Nacks.
1072 if (field_trial::FindFullName("WebRTC-NewVideoJitterBuffer") == "Enabled")
1073 return std::vector<uint16_t>();
1074
1049 std::vector<uint16_t> nack_list(missing_sequence_numbers_.begin(), 1075 std::vector<uint16_t> nack_list(missing_sequence_numbers_.begin(),
1050 missing_sequence_numbers_.end()); 1076 missing_sequence_numbers_.end());
1051 return nack_list; 1077 return nack_list;
1052 } 1078 }
1053 1079
1054 void VCMJitterBuffer::SetDecodeErrorMode(VCMDecodeErrorMode error_mode) { 1080 void VCMJitterBuffer::SetDecodeErrorMode(VCMDecodeErrorMode error_mode) {
1055 CriticalSectionScoped cs(crit_sect_); 1081 CriticalSectionScoped cs(crit_sect_);
1056 decode_error_mode_ = error_mode; 1082 decode_error_mode_ = error_mode;
1057 } 1083 }
1058 1084
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 } 1363 }
1338 // Evaluate if the RTT is higher than |high_rtt_nack_threshold_ms_|, and in 1364 // Evaluate if the RTT is higher than |high_rtt_nack_threshold_ms_|, and in
1339 // that case we don't wait for retransmissions. 1365 // that case we don't wait for retransmissions.
1340 if (high_rtt_nack_threshold_ms_ >= 0 && 1366 if (high_rtt_nack_threshold_ms_ >= 0 &&
1341 rtt_ms_ >= high_rtt_nack_threshold_ms_) { 1367 rtt_ms_ >= high_rtt_nack_threshold_ms_) {
1342 return false; 1368 return false;
1343 } 1369 }
1344 return true; 1370 return true;
1345 } 1371 }
1346 } // namespace webrtc 1372 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698