Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |