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 20 matching lines...) Expand all Loading... | |
31 #include "webrtc/system_wrappers/include/metrics.h" | 31 #include "webrtc/system_wrappers/include/metrics.h" |
32 | 32 |
33 namespace webrtc { | 33 namespace webrtc { |
34 | 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 | |
42 // number of milliseconds and NACKs are disabled. | |
43 static const int64_t kMaxDiscontinuousFramesTime = 10000; | |
44 | |
41 typedef std::pair<uint32_t, VCMFrameBuffer*> FrameListPair; | 45 typedef std::pair<uint32_t, VCMFrameBuffer*> FrameListPair; |
42 | 46 |
43 bool IsKeyFrame(FrameListPair pair) { | 47 bool IsKeyFrame(FrameListPair pair) { |
44 return pair.second->FrameType() == kVideoFrameKey; | 48 return pair.second->FrameType() == kVideoFrameKey; |
45 } | 49 } |
46 | 50 |
47 bool HasNonEmptyState(FrameListPair pair) { | 51 bool HasNonEmptyState(FrameListPair pair) { |
48 return pair.second->GetState() != kStateEmpty; | 52 return pair.second->GetState() != kStateEmpty; |
49 } | 53 } |
50 | 54 |
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
520 if (!running_) { | 524 if (!running_) { |
521 return false; | 525 return false; |
522 } | 526 } |
523 if (decode_error_mode_ == kNoErrors) { | 527 if (decode_error_mode_ == kNoErrors) { |
524 // No point to continue, as we are not decoding with errors. | 528 // No point to continue, as we are not decoding with errors. |
525 return false; | 529 return false; |
526 } | 530 } |
527 | 531 |
528 CleanUpOldOrEmptyFrames(); | 532 CleanUpOldOrEmptyFrames(); |
529 | 533 |
534 VCMFrameBuffer* oldest_frame; | |
530 if (decodable_frames_.empty()) { | 535 if (decodable_frames_.empty()) { |
531 return false; | 536 if (nack_mode_ != kNoNack || incomplete_frames_.empty()) { |
532 } | 537 return false; |
533 VCMFrameBuffer* oldest_frame = decodable_frames_.Front(); | 538 } |
534 // If we have exactly one frame in the buffer, release it only if it is | 539 oldest_frame = incomplete_frames_.Front(); |
535 // complete. We know decodable_frames_ is not empty due to the previous | 540 RTC_DCHECK(oldest_frame->GetState() != kStateComplete); |
536 // check. | 541 // Last frame will only be removed from buffer if it is complete. |
537 if (decodable_frames_.size() == 1 && incomplete_frames_.empty() | 542 if (incomplete_frames_.size() == 1 || |
538 && oldest_frame->GetState() != kStateComplete) { | 543 oldest_frame->GetState() != kStateDecodable) { |
539 return false; | 544 return false; |
545 } | |
546 } else { | |
547 oldest_frame = decodable_frames_.Front(); | |
548 // If we have exactly one frame in the buffer, release it only if it is | |
549 // complete. We know decodable_frames_ is not empty due to the previous | |
550 // check. | |
551 if (decodable_frames_.size() == 1 && incomplete_frames_.empty() | |
552 && oldest_frame->GetState() != kStateComplete) { | |
stefan-webrtc
2015/11/16 17:52:15
Can we end up here without oldest_frame being comp
joachim
2015/11/16 21:58:11
Well, the condition was like that before, I just m
stefan-webrtc
2015/11/18 00:02:17
Acknowledged.
| |
553 return false; | |
554 } | |
540 } | 555 } |
541 | 556 |
542 *timestamp = oldest_frame->TimeStamp(); | 557 *timestamp = oldest_frame->TimeStamp(); |
543 return true; | 558 return true; |
544 } | 559 } |
545 | 560 |
546 VCMEncodedFrame* VCMJitterBuffer::ExtractAndSetDecode(uint32_t timestamp) { | 561 VCMEncodedFrame* VCMJitterBuffer::ExtractAndSetDecode(uint32_t timestamp) { |
547 CriticalSectionScoped cs(crit_sect_); | 562 CriticalSectionScoped cs(crit_sect_); |
548 if (!running_) { | 563 if (!running_) { |
549 return NULL; | 564 return NULL; |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
750 packet.frameType != kVideoFrameKey) { | 765 packet.frameType != kVideoFrameKey) { |
751 buffer_state = kFlushIndicator; | 766 buffer_state = kFlushIndicator; |
752 } | 767 } |
753 | 768 |
754 latest_received_sequence_number_ = LatestSequenceNumber( | 769 latest_received_sequence_number_ = LatestSequenceNumber( |
755 latest_received_sequence_number_, packet.seqNum); | 770 latest_received_sequence_number_, packet.seqNum); |
756 } | 771 } |
757 } | 772 } |
758 | 773 |
759 // Is the frame already in the decodable list? | 774 // Is the frame already in the decodable list? |
760 bool continuous = IsContinuous(*frame); | 775 bool continuous = IsContinuous(*frame, false); |
776 bool continuous_for_decoding; | |
777 if (continuous && | |
778 (decode_error_mode_ != kWithErrors || nack_mode_ != kNoNack)) { | |
779 // If NACKs are enabled missing data will be handled through them so it's | |
780 // fine to always assume frames that are continuous for decoding below. | |
781 continuous_for_decoding = true; | |
stefan-webrtc
2015/11/16 17:52:15
Does this make sure that we actually wait for the
joachim
2015/11/16 21:58:11
I don't think so as the behavior for enabled NACKs
| |
782 } else { | |
783 continuous_for_decoding = IsContinuous(*frame, true); | |
stefan-webrtc
2015/11/16 17:52:15
Does this mean we require frames to be complete al
joachim
2015/11/16 21:58:11
For "decode_error_mode_ == kWithErrors", the actua
stefan-webrtc
2015/11/18 00:02:17
I'm trying to understand when and why it is necess
joachim
2015/11/18 00:35:14
The problem is, that with ignore_error_mode = true
joachim
2015/11/18 00:50:26
Btw, I did some more testing and you are right: if
stefan-webrtc
2015/11/18 20:51:57
Yes, but doesn't that mean that we don't decode wi
stefan-webrtc
2015/11/18 20:51:57
I'd say the common case is NACKs enabled and decod
joachim
2015/11/18 23:46:07
Acknowledged.
joachim
2015/11/18 23:46:07
Hmm. With the latest changes, decoding with errors
stefan-webrtc
2015/11/18 23:51:03
Right. What behavior is it that you want? We typic
stefan-webrtc
2015/11/19 00:04:17
I see, maybe if you increase the framerate (decrea
stefan-webrtc
2015/11/19 00:06:54
OK, in that case I suggest that we clean up the "d
joachim
2015/11/19 00:44:50
Another possibility would be to enable NACK for th
| |
784 } | |
761 switch (buffer_state) { | 785 switch (buffer_state) { |
762 case kGeneralError: | 786 case kGeneralError: |
763 case kTimeStampError: | 787 case kTimeStampError: |
764 case kSizeError: { | 788 case kSizeError: { |
765 free_frames_.push_back(frame); | 789 free_frames_.push_back(frame); |
766 break; | 790 break; |
767 } | 791 } |
768 case kCompleteSession: { | 792 case kCompleteSession: { |
769 if (previous_state != kStateDecodable && | 793 if (previous_state != kStateDecodable && |
770 previous_state != kStateComplete) { | 794 previous_state != kStateComplete) { |
771 CountFrame(*frame); | 795 CountFrame(*frame); |
772 if (continuous) { | 796 if (continuous) { |
773 // Signal that we have a complete session. | 797 // Signal that we have a complete session. |
774 frame_event_->Set(); | 798 frame_event_->Set(); |
775 } | 799 } |
776 } | 800 } |
777 FALLTHROUGH(); | 801 FALLTHROUGH(); |
778 } | 802 } |
779 // Note: There is no break here - continuing to kDecodableSession. | 803 // Note: There is no break here - continuing to kDecodableSession. |
780 case kDecodableSession: { | 804 case kDecodableSession: { |
781 *retransmitted = (frame->GetNackCount() > 0); | 805 *retransmitted = (frame->GetNackCount() > 0); |
782 if (continuous) { | 806 if (continuous && continuous_for_decoding) { |
783 decodable_frames_.InsertFrame(frame); | 807 decodable_frames_.InsertFrame(frame); |
784 FindAndInsertContinuousFrames(*frame); | 808 FindAndInsertContinuousFrames(*frame); |
785 } else { | 809 } else { |
786 incomplete_frames_.InsertFrame(frame); | 810 incomplete_frames_.InsertFrame(frame); |
811 // If NACKs are enabled, keyframes are triggered by |GetNackList|. | |
812 if (nack_mode_ == kNoNack && continuous && !continuous_for_decoding && | |
813 NonContinuousOrIncompleteDuration() > | |
814 90 * kMaxDiscontinuousFramesTime) { | |
815 return kFlushIndicator; | |
816 } | |
787 } | 817 } |
788 break; | 818 break; |
789 } | 819 } |
790 case kIncomplete: { | 820 case kIncomplete: { |
791 if (frame->GetState() == kStateEmpty && | 821 if (frame->GetState() == kStateEmpty && |
792 last_decoded_state_.UpdateEmptyFrame(frame)) { | 822 last_decoded_state_.UpdateEmptyFrame(frame)) { |
793 free_frames_.push_back(frame); | 823 free_frames_.push_back(frame); |
794 return kNoError; | 824 return kNoError; |
795 } else { | 825 } else { |
796 incomplete_frames_.InsertFrame(frame); | 826 incomplete_frames_.InsertFrame(frame); |
827 // If NACKs are enabled, keyframes are triggered by |GetNackList|. | |
828 if (nack_mode_ == kNoNack && NonContinuousOrIncompleteDuration() > | |
829 90 * kMaxDiscontinuousFramesTime) { | |
830 return kFlushIndicator; | |
831 } | |
797 } | 832 } |
798 break; | 833 break; |
799 } | 834 } |
800 case kNoError: | 835 case kNoError: |
801 case kOutOfBoundsPacket: | 836 case kOutOfBoundsPacket: |
802 case kDuplicatePacket: { | 837 case kDuplicatePacket: { |
803 // Put back the frame where it came from. | 838 // Put back the frame where it came from. |
804 if (frame_list != NULL) { | 839 if (frame_list != NULL) { |
805 frame_list->InsertFrame(frame); | 840 frame_list->InsertFrame(frame); |
806 } else { | 841 } else { |
807 free_frames_.push_back(frame); | 842 free_frames_.push_back(frame); |
808 } | 843 } |
809 ++num_duplicated_packets_; | 844 ++num_duplicated_packets_; |
810 break; | 845 break; |
811 } | 846 } |
812 case kFlushIndicator: | 847 case kFlushIndicator: |
813 free_frames_.push_back(frame); | 848 free_frames_.push_back(frame); |
814 return kFlushIndicator; | 849 return kFlushIndicator; |
815 default: assert(false); | 850 default: assert(false); |
816 } | 851 } |
817 return buffer_state; | 852 return buffer_state; |
818 } | 853 } |
819 | 854 |
820 bool VCMJitterBuffer::IsContinuousInState(const VCMFrameBuffer& frame, | 855 bool VCMJitterBuffer::IsContinuousInState(const VCMFrameBuffer& frame, |
821 const VCMDecodingState& decoding_state) const { | 856 const VCMDecodingState& decoding_state, bool ignore_error_mode) const { |
822 if (decode_error_mode_ == kWithErrors) | 857 if (!ignore_error_mode && decode_error_mode_ == kWithErrors) { |
823 return true; | 858 return true; |
859 } | |
860 | |
824 // Is this frame (complete or decodable) and continuous? | 861 // Is this frame (complete or decodable) and continuous? |
825 // kStateDecodable will never be set when decode_error_mode_ is false | 862 // kStateDecodable will never be set when decode_error_mode_ is false |
826 // as SessionInfo determines this state based on the error mode (and frame | 863 // as SessionInfo determines this state based on the error mode (and frame |
827 // completeness). | 864 // completeness). |
828 return (frame.GetState() == kStateComplete || | 865 return (frame.GetState() == kStateComplete || |
829 frame.GetState() == kStateDecodable) && | 866 frame.GetState() == kStateDecodable) && |
830 decoding_state.ContinuousFrame(&frame); | 867 decoding_state.ContinuousFrame(&frame); |
831 } | 868 } |
832 | 869 |
833 bool VCMJitterBuffer::IsContinuous(const VCMFrameBuffer& frame) const { | 870 bool VCMJitterBuffer::IsContinuous(const VCMFrameBuffer& frame, |
834 if (IsContinuousInState(frame, last_decoded_state_)) { | 871 bool ignore_error_mode) const { |
872 if (IsContinuousInState(frame, last_decoded_state_, ignore_error_mode)) { | |
835 return true; | 873 return true; |
836 } | 874 } |
837 VCMDecodingState decoding_state; | 875 VCMDecodingState decoding_state; |
838 decoding_state.CopyFrom(last_decoded_state_); | 876 decoding_state.CopyFrom(last_decoded_state_); |
839 for (FrameList::const_iterator it = decodable_frames_.begin(); | 877 for (FrameList::const_iterator it = decodable_frames_.begin(); |
840 it != decodable_frames_.end(); ++it) { | 878 it != decodable_frames_.end(); ++it) { |
841 VCMFrameBuffer* decodable_frame = it->second; | 879 VCMFrameBuffer* decodable_frame = it->second; |
842 if (IsNewerTimestamp(decodable_frame->TimeStamp(), frame.TimeStamp())) { | 880 if (IsNewerTimestamp(decodable_frame->TimeStamp(), frame.TimeStamp())) { |
843 break; | 881 break; |
844 } | 882 } |
845 decoding_state.SetState(decodable_frame); | 883 decoding_state.SetState(decodable_frame); |
846 if (IsContinuousInState(frame, decoding_state)) { | 884 if (IsContinuousInState(frame, decoding_state, ignore_error_mode)) { |
847 return true; | 885 return true; |
848 } | 886 } |
849 } | 887 } |
850 return false; | 888 return false; |
851 } | 889 } |
852 | 890 |
853 void VCMJitterBuffer::FindAndInsertContinuousFrames( | 891 void VCMJitterBuffer::FindAndInsertContinuousFrames( |
854 const VCMFrameBuffer& new_frame) { | 892 const VCMFrameBuffer& new_frame) { |
855 VCMDecodingState decoding_state; | 893 VCMDecodingState decoding_state; |
856 decoding_state.CopyFrom(last_decoded_state_); | 894 decoding_state.CopyFrom(last_decoded_state_); |
(...skipping 13 matching lines...) Expand all Loading... | |
870 // 1. Continuous base or sync layer. | 908 // 1. Continuous base or sync layer. |
871 // 2. The end of the list was reached. | 909 // 2. The end of the list was reached. |
872 for (FrameList::iterator it = incomplete_frames_.begin(); | 910 for (FrameList::iterator it = incomplete_frames_.begin(); |
873 it != incomplete_frames_.end();) { | 911 it != incomplete_frames_.end();) { |
874 VCMFrameBuffer* frame = it->second; | 912 VCMFrameBuffer* frame = it->second; |
875 if (IsNewerTimestamp(original_decoded_state.time_stamp(), | 913 if (IsNewerTimestamp(original_decoded_state.time_stamp(), |
876 frame->TimeStamp())) { | 914 frame->TimeStamp())) { |
877 ++it; | 915 ++it; |
878 continue; | 916 continue; |
879 } | 917 } |
880 if (IsContinuousInState(*frame, decoding_state)) { | 918 if (IsContinuousInState(*frame, decoding_state, false)) { |
881 decodable_frames_.InsertFrame(frame); | 919 decodable_frames_.InsertFrame(frame); |
882 incomplete_frames_.erase(it++); | 920 incomplete_frames_.erase(it++); |
883 decoding_state.SetState(frame); | 921 decoding_state.SetState(frame); |
884 } else if (frame->TemporalId() <= 0) { | 922 } else if (frame->TemporalId() <= 0) { |
885 break; | 923 break; |
886 } else { | 924 } else { |
887 ++it; | 925 ++it; |
888 } | 926 } |
889 } | 927 } |
890 } | 928 } |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1318 } | 1356 } |
1319 // Evaluate if the RTT is higher than |high_rtt_nack_threshold_ms_|, and in | 1357 // Evaluate if the RTT is higher than |high_rtt_nack_threshold_ms_|, and in |
1320 // that case we don't wait for retransmissions. | 1358 // that case we don't wait for retransmissions. |
1321 if (high_rtt_nack_threshold_ms_ >= 0 && | 1359 if (high_rtt_nack_threshold_ms_ >= 0 && |
1322 rtt_ms_ >= high_rtt_nack_threshold_ms_) { | 1360 rtt_ms_ >= high_rtt_nack_threshold_ms_) { |
1323 return false; | 1361 return false; |
1324 } | 1362 } |
1325 return true; | 1363 return true; |
1326 } | 1364 } |
1327 } // namespace webrtc | 1365 } // namespace webrtc |
OLD | NEW |