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 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 636 | 636 |
| 637 if (buffer_state > 0) { | 637 if (buffer_state > 0) { |
| 638 incoming_bit_count_ += packet.sizeBytes << 3; | 638 incoming_bit_count_ += packet.sizeBytes << 3; |
| 639 if (first_packet_since_reset_) { | 639 if (first_packet_since_reset_) { |
| 640 latest_received_sequence_number_ = packet.seqNum; | 640 latest_received_sequence_number_ = packet.seqNum; |
| 641 first_packet_since_reset_ = false; | 641 first_packet_since_reset_ = false; |
| 642 } else { | 642 } else { |
| 643 if (IsPacketRetransmitted(packet)) { | 643 if (IsPacketRetransmitted(packet)) { |
| 644 frame->IncrementNackCount(); | 644 frame->IncrementNackCount(); |
| 645 } | 645 } |
| 646 if (!UpdateNackList(packet.seqNum) && | 646 if (!CoverSequenceUpTo(packet.seqNum) && |
| 647 packet.frameType != kVideoFrameKey) { | 647 packet.frameType != kVideoFrameKey) { |
| 648 buffer_state = kFlushIndicator; | 648 buffer_state = kFlushIndicator; |
| 649 } | 649 } |
| 650 | 650 |
| 651 latest_received_sequence_number_ = LatestSequenceNumber( | 651 latest_received_sequence_number_ = LatestSequenceNumber( |
| 652 latest_received_sequence_number_, packet.seqNum); | 652 latest_received_sequence_number_, packet.seqNum); |
| 653 } | 653 } |
| 654 } | 654 } |
| 655 | 655 |
| 656 // Is the frame already in the decodable list? | 656 // Is the frame already in the decodable list? |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 709 case kFlushIndicator: | 709 case kFlushIndicator: |
| 710 free_frames_.push_back(frame); | 710 free_frames_.push_back(frame); |
| 711 return kFlushIndicator; | 711 return kFlushIndicator; |
| 712 default: assert(false); | 712 default: assert(false); |
| 713 } | 713 } |
| 714 return buffer_state; | 714 return buffer_state; |
| 715 } | 715 } |
| 716 | 716 |
| 717 bool VCMJitterBuffer::IsContinuousInState(const VCMFrameBuffer& frame, | 717 bool VCMJitterBuffer::IsContinuousInState(const VCMFrameBuffer& frame, |
| 718 const VCMDecodingState& decoding_state) const { | 718 const VCMDecodingState& decoding_state) const { |
| 719 if (decode_error_mode_ == kWithErrors) | 719 if (decode_error_mode_ == kWithErrors) |
|
stefan-webrtc
2015/07/01 13:41:02
I think you have to take a look at how this stuff
| |
| 720 return true; | 720 return true; |
| 721 // Is this frame (complete or decodable) and continuous? | 721 // Is this frame (complete or decodable) and continuous? |
| 722 // kStateDecodable will never be set when decode_error_mode_ is false | 722 // kStateDecodable will never be set when decode_error_mode_ is false |
| 723 // as SessionInfo determines this state based on the error mode (and frame | 723 // as SessionInfo determines this state based on the error mode (and frame |
| 724 // completeness). | 724 // completeness). |
| 725 return (frame.GetState() == kStateComplete || | 725 return (frame.GetState() == kStateComplete || |
| 726 frame.GetState() == kStateDecodable) && | 726 frame.GetState() == kStateDecodable) && |
| 727 decoding_state.ContinuousFrame(&frame); | 727 decoding_state.ContinuousFrame(&frame); |
| 728 } | 728 } |
| 729 | 729 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 758 void VCMJitterBuffer::FindAndInsertContinuousFramesWithState( | 758 void VCMJitterBuffer::FindAndInsertContinuousFramesWithState( |
| 759 const VCMDecodingState& original_decoded_state) { | 759 const VCMDecodingState& original_decoded_state) { |
| 760 // Copy original_decoded_state so we can move the state forward with each | 760 // Copy original_decoded_state so we can move the state forward with each |
| 761 // decodable frame we find. | 761 // decodable frame we find. |
| 762 VCMDecodingState decoding_state; | 762 VCMDecodingState decoding_state; |
| 763 decoding_state.CopyFrom(original_decoded_state); | 763 decoding_state.CopyFrom(original_decoded_state); |
| 764 | 764 |
| 765 // When temporal layers are available, we search for a complete or decodable | 765 // When temporal layers are available, we search for a complete or decodable |
| 766 // frame until we hit one of the following: | 766 // frame until we hit one of the following: |
| 767 // 1. Continuous base or sync layer. | 767 // 1. Continuous base or sync layer. |
| 768 // 2. The end of the list was reached. | 768 // 2. The end of the list was reached. |
|
stefan-webrtc
2015/07/01 13:41:02
Note how this method takes temporal layers into ac
| |
| 769 for (FrameList::iterator it = incomplete_frames_.begin(); | 769 for (FrameList::iterator it = incomplete_frames_.begin(); |
| 770 it != incomplete_frames_.end();) { | 770 it != incomplete_frames_.end();) { |
| 771 VCMFrameBuffer* frame = it->second; | 771 VCMFrameBuffer* frame = it->second; |
| 772 if (IsNewerTimestamp(original_decoded_state.time_stamp(), | 772 if (IsNewerTimestamp(original_decoded_state.time_stamp(), |
| 773 frame->TimeStamp())) { | 773 frame->TimeStamp())) { |
| 774 ++it; | 774 ++it; |
| 775 continue; | 775 continue; |
| 776 } | 776 } |
| 777 if (IsContinuousInState(*frame, decoding_state)) { | 777 if (IsContinuousInState(*frame, decoding_state)) { |
| 778 decodable_frames_.InsertFrame(frame); | 778 decodable_frames_.InsertFrame(frame); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 932 } | 932 } |
| 933 | 933 |
| 934 VCMFrameBuffer* VCMJitterBuffer::NextFrame() const { | 934 VCMFrameBuffer* VCMJitterBuffer::NextFrame() const { |
| 935 if (!decodable_frames_.empty()) | 935 if (!decodable_frames_.empty()) |
| 936 return decodable_frames_.Front(); | 936 return decodable_frames_.Front(); |
| 937 if (!incomplete_frames_.empty()) | 937 if (!incomplete_frames_.empty()) |
| 938 return incomplete_frames_.Front(); | 938 return incomplete_frames_.Front(); |
| 939 return NULL; | 939 return NULL; |
| 940 } | 940 } |
| 941 | 941 |
| 942 bool VCMJitterBuffer::UpdateNackList(uint16_t sequence_number) { | 942 bool VCMJitterBuffer::CoverSequenceUpTo(uint16_t sequence_number) { |
| 943 if (nack_mode_ == kNoNack) { | |
| 944 return true; | |
| 945 } | |
| 946 // Make sure we don't add packets which are already too old to be decoded. | 943 // Make sure we don't add packets which are already too old to be decoded. |
| 947 if (!last_decoded_state_.in_initial_state()) { | 944 if (!last_decoded_state_.in_initial_state()) { |
| 948 latest_received_sequence_number_ = LatestSequenceNumber( | 945 latest_received_sequence_number_ = LatestSequenceNumber( |
| 949 latest_received_sequence_number_, | 946 latest_received_sequence_number_, |
| 950 last_decoded_state_.sequence_num()); | 947 last_decoded_state_.sequence_num()); |
| 951 } | 948 } |
| 952 if (IsNewerSequenceNumber(sequence_number, | 949 if (IsNewerSequenceNumber(sequence_number, |
| 953 latest_received_sequence_number_)) { | 950 latest_received_sequence_number_)) { |
| 951 if (nack_mode_ == kNoNack) { | |
| 952 // Packets missing but NACK disabled, request key frame. | |
|
stefan-webrtc
2015/07/01 13:41:02
This isn't a good way of handling lost packets sin
| |
| 953 return false; | |
| 954 } | |
| 954 // Push any missing sequence numbers to the NACK list. | 955 // Push any missing sequence numbers to the NACK list. |
| 955 for (uint16_t i = latest_received_sequence_number_ + 1; | 956 for (uint16_t i = latest_received_sequence_number_ + 1; |
| 956 IsNewerSequenceNumber(sequence_number, i); ++i) { | 957 IsNewerSequenceNumber(sequence_number, i); ++i) { |
| 957 missing_sequence_numbers_.insert(missing_sequence_numbers_.end(), i); | 958 missing_sequence_numbers_.insert(missing_sequence_numbers_.end(), i); |
| 958 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "AddNack", | 959 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "AddNack", |
| 959 "seqnum", i); | 960 "seqnum", i); |
| 960 } | 961 } |
| 961 if (TooLargeNackList() && !HandleTooLargeNackList()) { | 962 if (TooLargeNackList() && !HandleTooLargeNackList()) { |
| 962 LOG(LS_WARNING) << "Requesting key frame due to too large NACK list."; | 963 LOG(LS_WARNING) << "Requesting key frame due to too large NACK list."; |
| 963 return false; | 964 return false; |
| 964 } | 965 } |
| 965 if (MissingTooOldPacket(sequence_number) && | 966 if (MissingTooOldPacket(sequence_number) && |
| 966 !HandleTooOldPackets(sequence_number)) { | 967 !HandleTooOldPackets(sequence_number)) { |
| 967 LOG(LS_WARNING) << "Requesting key frame due to missing too old packets"; | 968 LOG(LS_WARNING) << "Requesting key frame due to missing too old packets"; |
| 968 return false; | 969 return false; |
| 969 } | 970 } |
| 970 } else { | 971 } else if (nack_mode_ != kNoNack) { |
| 971 missing_sequence_numbers_.erase(sequence_number); | 972 missing_sequence_numbers_.erase(sequence_number); |
| 972 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RemoveNack", | 973 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RemoveNack", |
| 973 "seqnum", sequence_number); | 974 "seqnum", sequence_number); |
| 974 } | 975 } |
| 975 return true; | 976 return true; |
| 976 } | 977 } |
| 977 | 978 |
| 978 bool VCMJitterBuffer::TooLargeNackList() const { | 979 bool VCMJitterBuffer::TooLargeNackList() const { |
| 979 return missing_sequence_numbers_.size() > max_nack_list_size_; | 980 return missing_sequence_numbers_.size() > max_nack_list_size_; |
| 980 } | 981 } |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1215 } | 1216 } |
| 1216 // Evaluate if the RTT is higher than |high_rtt_nack_threshold_ms_|, and in | 1217 // Evaluate if the RTT is higher than |high_rtt_nack_threshold_ms_|, and in |
| 1217 // that case we don't wait for retransmissions. | 1218 // that case we don't wait for retransmissions. |
| 1218 if (high_rtt_nack_threshold_ms_ >= 0 && | 1219 if (high_rtt_nack_threshold_ms_ >= 0 && |
| 1219 rtt_ms_ >= high_rtt_nack_threshold_ms_) { | 1220 rtt_ms_ >= high_rtt_nack_threshold_ms_) { |
| 1220 return false; | 1221 return false; |
| 1221 } | 1222 } |
| 1222 return true; | 1223 return true; |
| 1223 } | 1224 } |
| 1224 } // namespace webrtc | 1225 } // namespace webrtc |
| OLD | NEW |