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

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

Issue 1211873004: Request keyframe if too many packets are missing and NACK is disabled. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Updated based on feedback Created 5 years, 3 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/main/source/jitter_buffer.h" 10 #include "webrtc/modules/video_coding/main/source/jitter_buffer.h"
(...skipping 15 matching lines...) Expand all
26 #include "webrtc/system_wrappers/interface/event_wrapper.h" 26 #include "webrtc/system_wrappers/interface/event_wrapper.h"
27 #include "webrtc/system_wrappers/interface/logging.h" 27 #include "webrtc/system_wrappers/interface/logging.h"
28 #include "webrtc/system_wrappers/interface/metrics.h" 28 #include "webrtc/system_wrappers/interface/metrics.h"
29 #include "webrtc/system_wrappers/interface/trace_event.h" 29 #include "webrtc/system_wrappers/interface/trace_event.h"
30 30
31 namespace webrtc { 31 namespace webrtc {
32 32
33 // Use this rtt if no value has been reported. 33 // Use this rtt if no value has been reported.
34 static const int64_t kDefaultRtt = 200; 34 static const int64_t kDefaultRtt = 200;
35 35
36 // Request a keyframe if no continuous frame has been received for this
37 // number of milliseconds and NACKs are disabled.
38 static const int64_t kMaxDiscontinuousFramesTime = 10000;
39
36 typedef std::pair<uint32_t, VCMFrameBuffer*> FrameListPair; 40 typedef std::pair<uint32_t, VCMFrameBuffer*> FrameListPair;
37 41
38 bool IsKeyFrame(FrameListPair pair) { 42 bool IsKeyFrame(FrameListPair pair) {
39 return pair.second->FrameType() == kVideoFrameKey; 43 return pair.second->FrameType() == kVideoFrameKey;
40 } 44 }
41 45
42 bool HasNonEmptyState(FrameListPair pair) { 46 bool HasNonEmptyState(FrameListPair pair) {
43 return pair.second->GetState() != kStateEmpty; 47 return pair.second->GetState() != kStateEmpty;
44 } 48 }
45 49
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 stats_callback_(NULL), 134 stats_callback_(NULL),
131 incoming_frame_rate_(0), 135 incoming_frame_rate_(0),
132 incoming_frame_count_(0), 136 incoming_frame_count_(0),
133 time_last_incoming_frame_count_(0), 137 time_last_incoming_frame_count_(0),
134 incoming_bit_count_(0), 138 incoming_bit_count_(0),
135 incoming_bit_rate_(0), 139 incoming_bit_rate_(0),
136 num_consecutive_old_packets_(0), 140 num_consecutive_old_packets_(0),
137 num_packets_(0), 141 num_packets_(0),
138 num_duplicated_packets_(0), 142 num_duplicated_packets_(0),
139 num_discarded_packets_(0), 143 num_discarded_packets_(0),
144 time_last_decodable_frame_(-1),
140 time_first_packet_ms_(0), 145 time_first_packet_ms_(0),
141 jitter_estimate_(clock), 146 jitter_estimate_(clock),
142 inter_frame_delay_(clock_->TimeInMilliseconds()), 147 inter_frame_delay_(clock_->TimeInMilliseconds()),
143 rtt_ms_(kDefaultRtt), 148 rtt_ms_(kDefaultRtt),
144 nack_mode_(kNoNack), 149 nack_mode_(kNoNack),
145 low_rtt_nack_threshold_ms_(-1), 150 low_rtt_nack_threshold_ms_(-1),
146 high_rtt_nack_threshold_ms_(-1), 151 high_rtt_nack_threshold_ms_(-1),
147 missing_sequence_numbers_(SequenceNumberLessThan()), 152 missing_sequence_numbers_(SequenceNumberLessThan()),
148 max_nack_list_size_(0), 153 max_nack_list_size_(0),
149 max_packet_age_to_nack_(0), 154 max_packet_age_to_nack_(0),
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 incoming_frame_rate_ = 0; 211 incoming_frame_rate_ = 0;
207 incoming_bit_count_ = 0; 212 incoming_bit_count_ = 0;
208 incoming_bit_rate_ = 0; 213 incoming_bit_rate_ = 0;
209 time_last_incoming_frame_count_ = clock_->TimeInMilliseconds(); 214 time_last_incoming_frame_count_ = clock_->TimeInMilliseconds();
210 receive_statistics_ = FrameCounts(); 215 receive_statistics_ = FrameCounts();
211 216
212 num_consecutive_old_packets_ = 0; 217 num_consecutive_old_packets_ = 0;
213 num_packets_ = 0; 218 num_packets_ = 0;
214 num_duplicated_packets_ = 0; 219 num_duplicated_packets_ = 0;
215 num_discarded_packets_ = 0; 220 num_discarded_packets_ = 0;
221 time_last_decodable_frame_ = -1;
216 time_first_packet_ms_ = 0; 222 time_first_packet_ms_ = 0;
217 223
218 // Start in a non-signaled state. 224 // Start in a non-signaled state.
219 waiting_for_completion_.frame_size = 0; 225 waiting_for_completion_.frame_size = 0;
220 waiting_for_completion_.timestamp = 0; 226 waiting_for_completion_.timestamp = 0;
221 waiting_for_completion_.latest_packet_time = -1; 227 waiting_for_completion_.latest_packet_time = -1;
222 first_packet_since_reset_ = true; 228 first_packet_since_reset_ = true;
223 rtt_ms_ = kDefaultRtt; 229 rtt_ms_ = kDefaultRtt;
224 last_decoded_state_.Reset(); 230 last_decoded_state_.Reset();
225 last_gof_valid_ = false; 231 last_gof_valid_ = false;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 return running_; 263 return running_;
258 } 264 }
259 265
260 void VCMJitterBuffer::Flush() { 266 void VCMJitterBuffer::Flush() {
261 CriticalSectionScoped cs(crit_sect_); 267 CriticalSectionScoped cs(crit_sect_);
262 decodable_frames_.Reset(&free_frames_); 268 decodable_frames_.Reset(&free_frames_);
263 incomplete_frames_.Reset(&free_frames_); 269 incomplete_frames_.Reset(&free_frames_);
264 last_decoded_state_.Reset(); // TODO(mikhal): sync reset. 270 last_decoded_state_.Reset(); // TODO(mikhal): sync reset.
265 last_gof_valid_ = false; 271 last_gof_valid_ = false;
266 num_consecutive_old_packets_ = 0; 272 num_consecutive_old_packets_ = 0;
273 time_last_decodable_frame_ = -1;
267 // Also reset the jitter and delay estimates 274 // Also reset the jitter and delay estimates
268 jitter_estimate_.Reset(); 275 jitter_estimate_.Reset();
269 inter_frame_delay_.Reset(clock_->TimeInMilliseconds()); 276 inter_frame_delay_.Reset(clock_->TimeInMilliseconds());
270 waiting_for_completion_.frame_size = 0; 277 waiting_for_completion_.frame_size = 0;
271 waiting_for_completion_.timestamp = 0; 278 waiting_for_completion_.timestamp = 0;
272 waiting_for_completion_.latest_packet_time = -1; 279 waiting_for_completion_.latest_packet_time = -1;
273 first_packet_since_reset_ = true; 280 first_packet_since_reset_ = true;
274 missing_sequence_numbers_.clear(); 281 missing_sequence_numbers_.clear();
275 } 282 }
276 283
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 packet.frameType != kVideoFrameKey) { 692 packet.frameType != kVideoFrameKey) {
686 buffer_state = kFlushIndicator; 693 buffer_state = kFlushIndicator;
687 } 694 }
688 695
689 latest_received_sequence_number_ = LatestSequenceNumber( 696 latest_received_sequence_number_ = LatestSequenceNumber(
690 latest_received_sequence_number_, packet.seqNum); 697 latest_received_sequence_number_, packet.seqNum);
691 } 698 }
692 } 699 }
693 700
694 // Is the frame already in the decodable list? 701 // Is the frame already in the decodable list?
695 bool continuous = IsContinuous(*frame); 702 bool continuous = IsContinuous(*frame, false);
703 bool continuous_for_decoding;
704 if (continuous &&
stefan-webrtc 2015/09/24 07:05:48 I think I'm starting to see what you want to do he
joachim 2015/09/24 08:52:46 Thanks, however with NACKs disabled and "decode_er
stefan-webrtc 2015/09/28 13:49:24 I see. In that case, would it make sense to only p
joachim 2015/11/05 23:48:01 I updated the code as you suggested, looks a lot c
705 (decode_error_mode_ != kWithErrors || nack_mode_ != kNoNack)) {
706 // If NACKs are enabled missing data will be handled through them so it's
707 // fine to always assume frames that are continuous for decoding below.
708 continuous_for_decoding = true;
709 time_last_decodable_frame_ = now_ms;
710 } else {
711 continuous_for_decoding = IsContinuous(*frame, true);
712 if (continuous_for_decoding) {
713 time_last_decodable_frame_ = now_ms;
714 }
715 }
696 switch (buffer_state) { 716 switch (buffer_state) {
697 case kGeneralError: 717 case kGeneralError:
698 case kTimeStampError: 718 case kTimeStampError:
699 case kSizeError: { 719 case kSizeError: {
700 free_frames_.push_back(frame); 720 free_frames_.push_back(frame);
701 break; 721 break;
702 } 722 }
703 case kCompleteSession: { 723 case kCompleteSession: {
704 if (previous_state != kStateDecodable && 724 if (previous_state != kStateDecodable &&
705 previous_state != kStateComplete) { 725 previous_state != kStateComplete) {
706 CountFrame(*frame); 726 CountFrame(*frame);
707 if (continuous) { 727 if (continuous) {
708 // Signal that we have a complete session. 728 // Signal that we have a complete session.
709 frame_event_->Set(); 729 frame_event_->Set();
710 } 730 }
711 } 731 }
712 FALLTHROUGH(); 732 FALLTHROUGH();
713 } 733 }
714 // Note: There is no break here - continuing to kDecodableSession. 734 // Note: There is no break here - continuing to kDecodableSession.
715 case kDecodableSession: { 735 case kDecodableSession: {
716 *retransmitted = (frame->GetNackCount() > 0); 736 *retransmitted = (frame->GetNackCount() > 0);
717 if (continuous) { 737 if (continuous) {
718 decodable_frames_.InsertFrame(frame); 738 decodable_frames_.InsertFrame(frame);
719 FindAndInsertContinuousFrames(*frame); 739 FindAndInsertContinuousFrames(*frame);
720 } else { 740 } else {
721 incomplete_frames_.InsertFrame(frame); 741 incomplete_frames_.InsertFrame(frame);
722 } 742 }
743 if (continuous &&
744 !continuous_for_decoding &&
745 TooManyDiscontinuousFrames(now_ms)) {
746 return kFlushIndicator;
747 }
723 break; 748 break;
724 } 749 }
725 case kIncomplete: { 750 case kIncomplete: {
726 if (frame->GetState() == kStateEmpty && 751 if (frame->GetState() == kStateEmpty &&
727 last_decoded_state_.UpdateEmptyFrame(frame)) { 752 last_decoded_state_.UpdateEmptyFrame(frame)) {
728 free_frames_.push_back(frame); 753 free_frames_.push_back(frame);
729 return kNoError; 754 return kNoError;
730 } else { 755 } else {
731 incomplete_frames_.InsertFrame(frame); 756 incomplete_frames_.InsertFrame(frame);
732 } 757 }
758 if (TooManyDiscontinuousFrames(now_ms)) {
759 return kFlushIndicator;
760 }
733 break; 761 break;
734 } 762 }
735 case kNoError: 763 case kNoError:
736 case kOutOfBoundsPacket: 764 case kOutOfBoundsPacket:
737 case kDuplicatePacket: { 765 case kDuplicatePacket: {
738 // Put back the frame where it came from. 766 // Put back the frame where it came from.
739 if (frame_list != NULL) { 767 if (frame_list != NULL) {
740 frame_list->InsertFrame(frame); 768 frame_list->InsertFrame(frame);
741 } else { 769 } else {
742 free_frames_.push_back(frame); 770 free_frames_.push_back(frame);
743 } 771 }
744 ++num_duplicated_packets_; 772 ++num_duplicated_packets_;
745 break; 773 break;
746 } 774 }
747 case kFlushIndicator: 775 case kFlushIndicator:
748 free_frames_.push_back(frame); 776 free_frames_.push_back(frame);
749 return kFlushIndicator; 777 return kFlushIndicator;
750 default: assert(false); 778 default: assert(false);
751 } 779 }
752 return buffer_state; 780 return buffer_state;
753 } 781 }
754 782
755 bool VCMJitterBuffer::IsContinuousInState(const VCMFrameBuffer& frame, 783 bool VCMJitterBuffer::IsContinuousInState(const VCMFrameBuffer& frame,
756 const VCMDecodingState& decoding_state) const { 784 const VCMDecodingState& decoding_state, bool ignore_error_mode) const {
757 if (decode_error_mode_ == kWithErrors) 785 if (!ignore_error_mode && decode_error_mode_ == kWithErrors) {
758 return true; 786 return true;
787 }
788
759 // Is this frame (complete or decodable) and continuous? 789 // Is this frame (complete or decodable) and continuous?
760 // kStateDecodable will never be set when decode_error_mode_ is false 790 // kStateDecodable will never be set when decode_error_mode_ is false
761 // as SessionInfo determines this state based on the error mode (and frame 791 // as SessionInfo determines this state based on the error mode (and frame
762 // completeness). 792 // completeness).
763 return (frame.GetState() == kStateComplete || 793 return (frame.GetState() == kStateComplete ||
764 frame.GetState() == kStateDecodable) && 794 frame.GetState() == kStateDecodable) &&
765 decoding_state.ContinuousFrame(&frame); 795 decoding_state.ContinuousFrame(&frame);
766 } 796 }
767 797
768 bool VCMJitterBuffer::IsContinuous(const VCMFrameBuffer& frame) const { 798 bool VCMJitterBuffer::IsContinuous(const VCMFrameBuffer& frame,
769 if (IsContinuousInState(frame, last_decoded_state_)) { 799 bool ignore_error_mode) const {
800 if (IsContinuousInState(frame, last_decoded_state_, ignore_error_mode)) {
770 return true; 801 return true;
771 } 802 }
772 VCMDecodingState decoding_state; 803 VCMDecodingState decoding_state;
773 decoding_state.CopyFrom(last_decoded_state_); 804 decoding_state.CopyFrom(last_decoded_state_);
774 for (FrameList::const_iterator it = decodable_frames_.begin(); 805 for (FrameList::const_iterator it = decodable_frames_.begin();
775 it != decodable_frames_.end(); ++it) { 806 it != decodable_frames_.end(); ++it) {
776 VCMFrameBuffer* decodable_frame = it->second; 807 VCMFrameBuffer* decodable_frame = it->second;
777 if (IsNewerTimestamp(decodable_frame->TimeStamp(), frame.TimeStamp())) { 808 if (IsNewerTimestamp(decodable_frame->TimeStamp(), frame.TimeStamp())) {
778 break; 809 break;
779 } 810 }
780 decoding_state.SetState(decodable_frame); 811 decoding_state.SetState(decodable_frame);
781 if (IsContinuousInState(frame, decoding_state)) { 812 if (IsContinuousInState(frame, decoding_state, ignore_error_mode)) {
782 return true; 813 return true;
783 } 814 }
784 } 815 }
785 return false; 816 return false;
786 } 817 }
787 818
788 void VCMJitterBuffer::FindAndInsertContinuousFrames( 819 void VCMJitterBuffer::FindAndInsertContinuousFrames(
789 const VCMFrameBuffer& new_frame) { 820 const VCMFrameBuffer& new_frame) {
790 VCMDecodingState decoding_state; 821 VCMDecodingState decoding_state;
791 decoding_state.CopyFrom(last_decoded_state_); 822 decoding_state.CopyFrom(last_decoded_state_);
(...skipping 13 matching lines...) Expand all
805 // 1. Continuous base or sync layer. 836 // 1. Continuous base or sync layer.
806 // 2. The end of the list was reached. 837 // 2. The end of the list was reached.
807 for (FrameList::iterator it = incomplete_frames_.begin(); 838 for (FrameList::iterator it = incomplete_frames_.begin();
808 it != incomplete_frames_.end();) { 839 it != incomplete_frames_.end();) {
809 VCMFrameBuffer* frame = it->second; 840 VCMFrameBuffer* frame = it->second;
810 if (IsNewerTimestamp(original_decoded_state.time_stamp(), 841 if (IsNewerTimestamp(original_decoded_state.time_stamp(),
811 frame->TimeStamp())) { 842 frame->TimeStamp())) {
812 ++it; 843 ++it;
813 continue; 844 continue;
814 } 845 }
815 if (IsContinuousInState(*frame, decoding_state)) { 846 if (IsContinuousInState(*frame, decoding_state, false)) {
816 decodable_frames_.InsertFrame(frame); 847 decodable_frames_.InsertFrame(frame);
817 incomplete_frames_.erase(it++); 848 incomplete_frames_.erase(it++);
818 decoding_state.SetState(frame); 849 decoding_state.SetState(frame);
819 } else if (frame->TemporalId() <= 0) { 850 } else if (frame->TemporalId() <= 0) {
820 break; 851 break;
821 } else { 852 } else {
822 ++it; 853 ++it;
823 } 854 }
824 } 855 }
825 } 856 }
826 857
858 bool VCMJitterBuffer::TooManyDiscontinuousFrames(int64_t now_ms) {
859 // If we didn't receive a continuous decodable frame for too long and
860 // can't report through NACKs to the sender, request a keyframe.
861 if (nack_mode_ == kNoNack &&
862 time_last_decodable_frame_ >= 0 &&
863 now_ms - time_last_decodable_frame_ > kMaxDiscontinuousFramesTime) {
864 // Update to current time so we don't request keyframes too often.
865 time_last_decodable_frame_ = now_ms;
866 return true;
867 }
868 return false;
869 }
870
827 uint32_t VCMJitterBuffer::EstimatedJitterMs() { 871 uint32_t VCMJitterBuffer::EstimatedJitterMs() {
828 CriticalSectionScoped cs(crit_sect_); 872 CriticalSectionScoped cs(crit_sect_);
829 // Compute RTT multiplier for estimation. 873 // Compute RTT multiplier for estimation.
830 // low_rtt_nackThresholdMs_ == -1 means no FEC. 874 // low_rtt_nackThresholdMs_ == -1 means no FEC.
831 double rtt_mult = 1.0f; 875 double rtt_mult = 1.0f;
832 if (low_rtt_nack_threshold_ms_ >= 0 && 876 if (low_rtt_nack_threshold_ms_ >= 0 &&
833 rtt_ms_ >= low_rtt_nack_threshold_ms_) { 877 rtt_ms_ >= low_rtt_nack_threshold_ms_) {
834 // For RTTs above low_rtt_nack_threshold_ms_ we don't apply extra delay 878 // For RTTs above low_rtt_nack_threshold_ms_ we don't apply extra delay
835 // when waiting for retransmissions. 879 // when waiting for retransmissions.
836 rtt_mult = 0.0f; 880 rtt_mult = 0.0f;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 bool found_key_frame = RecycleFramesUntilKeyFrame(); 973 bool found_key_frame = RecycleFramesUntilKeyFrame();
930 if (!found_key_frame) { 974 if (!found_key_frame) {
931 *request_key_frame = have_non_empty_frame; 975 *request_key_frame = have_non_empty_frame;
932 return std::vector<uint16_t>(); 976 return std::vector<uint16_t>();
933 } 977 }
934 } 978 }
935 } 979 }
936 if (TooLargeNackList()) { 980 if (TooLargeNackList()) {
937 *request_key_frame = !HandleTooLargeNackList(); 981 *request_key_frame = !HandleTooLargeNackList();
938 } 982 }
939 if (max_incomplete_time_ms_ > 0) { 983 if (max_incomplete_time_ms_ > 0) {
stefan-webrtc 2015/09/24 07:05:47 I wonder if what you really want to do is somethin
joachim 2015/09/24 08:52:46 Yes, that looks similar, see my other comment rega
940 int non_continuous_incomplete_duration = 984 int non_continuous_incomplete_duration =
941 NonContinuousOrIncompleteDuration(); 985 NonContinuousOrIncompleteDuration();
942 if (non_continuous_incomplete_duration > 90 * max_incomplete_time_ms_) { 986 if (non_continuous_incomplete_duration > 90 * max_incomplete_time_ms_) {
943 LOG_F(LS_WARNING) << "Too long non-decodable duration: " 987 LOG_F(LS_WARNING) << "Too long non-decodable duration: "
944 << non_continuous_incomplete_duration << " > " 988 << non_continuous_incomplete_duration << " > "
945 << 90 * max_incomplete_time_ms_; 989 << 90 * max_incomplete_time_ms_;
946 FrameList::reverse_iterator rit = find_if(incomplete_frames_.rbegin(), 990 FrameList::reverse_iterator rit = find_if(incomplete_frames_.rbegin(),
947 incomplete_frames_.rend(), IsKeyFrame); 991 incomplete_frames_.rend(), IsKeyFrame);
948 if (rit == incomplete_frames_.rend()) { 992 if (rit == incomplete_frames_.rend()) {
949 // Request a key frame if we don't have one already. 993 // Request a key frame if we don't have one already.
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 } 1297 }
1254 // Evaluate if the RTT is higher than |high_rtt_nack_threshold_ms_|, and in 1298 // Evaluate if the RTT is higher than |high_rtt_nack_threshold_ms_|, and in
1255 // that case we don't wait for retransmissions. 1299 // that case we don't wait for retransmissions.
1256 if (high_rtt_nack_threshold_ms_ >= 0 && 1300 if (high_rtt_nack_threshold_ms_ >= 0 &&
1257 rtt_ms_ >= high_rtt_nack_threshold_ms_) { 1301 rtt_ms_ >= high_rtt_nack_threshold_ms_) {
1258 return false; 1302 return false;
1259 } 1303 }
1260 return true; 1304 return true;
1261 } 1305 }
1262 } // namespace webrtc 1306 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/main/source/jitter_buffer.h ('k') | webrtc/video/end_to_end_tests.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698