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/jitter_buffer.h" | 10 #include "webrtc/modules/video_coding/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 = 1000; |
| 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 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 if (!running_) { | 525 if (!running_) { |
522 return false; | 526 return false; |
523 } | 527 } |
524 if (decode_error_mode_ == kNoErrors) { | 528 if (decode_error_mode_ == kNoErrors) { |
525 // No point to continue, as we are not decoding with errors. | 529 // No point to continue, as we are not decoding with errors. |
526 return false; | 530 return false; |
527 } | 531 } |
528 | 532 |
529 CleanUpOldOrEmptyFrames(); | 533 CleanUpOldOrEmptyFrames(); |
530 | 534 |
| 535 VCMFrameBuffer* oldest_frame; |
531 if (decodable_frames_.empty()) { | 536 if (decodable_frames_.empty()) { |
532 return false; | 537 if (nack_mode_ != kNoNack || incomplete_frames_.size() <= 1) { |
533 } | 538 return false; |
534 VCMFrameBuffer* oldest_frame = decodable_frames_.Front(); | 539 } |
535 // If we have exactly one frame in the buffer, release it only if it is | 540 oldest_frame = incomplete_frames_.Front(); |
536 // complete. We know decodable_frames_ is not empty due to the previous | 541 // Frame will only be removed from buffer if it is complete (or decodable). |
537 // check. | 542 if (oldest_frame->GetState() < kStateComplete) { |
538 if (decodable_frames_.size() == 1 && incomplete_frames_.empty() | 543 return false; |
539 && oldest_frame->GetState() != kStateComplete) { | 544 } |
540 return false; | 545 } else { |
| 546 oldest_frame = decodable_frames_.Front(); |
| 547 // If we have exactly one frame in the buffer, release it only if it is |
| 548 // complete. We know decodable_frames_ is not empty due to the previous |
| 549 // check. |
| 550 if (decodable_frames_.size() == 1 && incomplete_frames_.empty() |
| 551 && oldest_frame->GetState() != kStateComplete) { |
| 552 return false; |
| 553 } |
541 } | 554 } |
542 | 555 |
543 *timestamp = oldest_frame->TimeStamp(); | 556 *timestamp = oldest_frame->TimeStamp(); |
544 return true; | 557 return true; |
545 } | 558 } |
546 | 559 |
547 VCMEncodedFrame* VCMJitterBuffer::ExtractAndSetDecode(uint32_t timestamp) { | 560 VCMEncodedFrame* VCMJitterBuffer::ExtractAndSetDecode(uint32_t timestamp) { |
548 CriticalSectionScoped cs(crit_sect_); | 561 CriticalSectionScoped cs(crit_sect_); |
549 if (!running_) { | 562 if (!running_) { |
550 return NULL; | 563 return NULL; |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
772 FALLTHROUGH(); | 785 FALLTHROUGH(); |
773 } | 786 } |
774 // Note: There is no break here - continuing to kDecodableSession. | 787 // Note: There is no break here - continuing to kDecodableSession. |
775 case kDecodableSession: { | 788 case kDecodableSession: { |
776 *retransmitted = (frame->GetNackCount() > 0); | 789 *retransmitted = (frame->GetNackCount() > 0); |
777 if (continuous) { | 790 if (continuous) { |
778 decodable_frames_.InsertFrame(frame); | 791 decodable_frames_.InsertFrame(frame); |
779 FindAndInsertContinuousFrames(*frame); | 792 FindAndInsertContinuousFrames(*frame); |
780 } else { | 793 } else { |
781 incomplete_frames_.InsertFrame(frame); | 794 incomplete_frames_.InsertFrame(frame); |
| 795 // If NACKs are enabled, keyframes are triggered by |GetNackList|. |
| 796 if (nack_mode_ == kNoNack && NonContinuousOrIncompleteDuration() > |
| 797 90 * kMaxDiscontinuousFramesTime) { |
| 798 return kFlushIndicator; |
| 799 } |
782 } | 800 } |
783 break; | 801 break; |
784 } | 802 } |
785 case kIncomplete: { | 803 case kIncomplete: { |
786 if (frame->GetState() == kStateEmpty && | 804 if (frame->GetState() == kStateEmpty && |
787 last_decoded_state_.UpdateEmptyFrame(frame)) { | 805 last_decoded_state_.UpdateEmptyFrame(frame)) { |
788 free_frames_.push_back(frame); | 806 free_frames_.push_back(frame); |
789 return kNoError; | 807 return kNoError; |
790 } else { | 808 } else { |
791 incomplete_frames_.InsertFrame(frame); | 809 incomplete_frames_.InsertFrame(frame); |
| 810 // If NACKs are enabled, keyframes are triggered by |GetNackList|. |
| 811 if (nack_mode_ == kNoNack && NonContinuousOrIncompleteDuration() > |
| 812 90 * kMaxDiscontinuousFramesTime) { |
| 813 return kFlushIndicator; |
| 814 } |
792 } | 815 } |
793 break; | 816 break; |
794 } | 817 } |
795 case kNoError: | 818 case kNoError: |
796 case kOutOfBoundsPacket: | 819 case kOutOfBoundsPacket: |
797 case kDuplicatePacket: { | 820 case kDuplicatePacket: { |
798 // Put back the frame where it came from. | 821 // Put back the frame where it came from. |
799 if (frame_list != NULL) { | 822 if (frame_list != NULL) { |
800 frame_list->InsertFrame(frame); | 823 frame_list->InsertFrame(frame); |
801 } else { | 824 } else { |
802 free_frames_.push_back(frame); | 825 free_frames_.push_back(frame); |
803 } | 826 } |
804 ++num_duplicated_packets_; | 827 ++num_duplicated_packets_; |
805 break; | 828 break; |
806 } | 829 } |
807 case kFlushIndicator: | 830 case kFlushIndicator: |
808 free_frames_.push_back(frame); | 831 free_frames_.push_back(frame); |
809 return kFlushIndicator; | 832 return kFlushIndicator; |
810 default: assert(false); | 833 default: assert(false); |
811 } | 834 } |
812 return buffer_state; | 835 return buffer_state; |
813 } | 836 } |
814 | 837 |
815 bool VCMJitterBuffer::IsContinuousInState(const VCMFrameBuffer& frame, | 838 bool VCMJitterBuffer::IsContinuousInState(const VCMFrameBuffer& frame, |
816 const VCMDecodingState& decoding_state) const { | 839 const VCMDecodingState& decoding_state) const { |
817 if (decode_error_mode_ == kWithErrors) | |
818 return true; | |
819 // Is this frame (complete or decodable) and continuous? | 840 // Is this frame (complete or decodable) and continuous? |
820 // kStateDecodable will never be set when decode_error_mode_ is false | 841 // kStateDecodable will never be set when decode_error_mode_ is false |
821 // as SessionInfo determines this state based on the error mode (and frame | 842 // as SessionInfo determines this state based on the error mode (and frame |
822 // completeness). | 843 // completeness). |
823 return (frame.GetState() == kStateComplete || | 844 return (frame.GetState() == kStateComplete || |
824 frame.GetState() == kStateDecodable) && | 845 frame.GetState() == kStateDecodable) && |
825 decoding_state.ContinuousFrame(&frame); | 846 decoding_state.ContinuousFrame(&frame); |
826 } | 847 } |
827 | 848 |
828 bool VCMJitterBuffer::IsContinuous(const VCMFrameBuffer& frame) const { | 849 bool VCMJitterBuffer::IsContinuous(const VCMFrameBuffer& frame) const { |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1313 } | 1334 } |
1314 // Evaluate if the RTT is higher than |high_rtt_nack_threshold_ms_|, and in | 1335 // Evaluate if the RTT is higher than |high_rtt_nack_threshold_ms_|, and in |
1315 // that case we don't wait for retransmissions. | 1336 // that case we don't wait for retransmissions. |
1316 if (high_rtt_nack_threshold_ms_ >= 0 && | 1337 if (high_rtt_nack_threshold_ms_ >= 0 && |
1317 rtt_ms_ >= high_rtt_nack_threshold_ms_) { | 1338 rtt_ms_ >= high_rtt_nack_threshold_ms_) { |
1318 return false; | 1339 return false; |
1319 } | 1340 } |
1320 return true; | 1341 return true; |
1321 } | 1342 } |
1322 } // namespace webrtc | 1343 } // namespace webrtc |
OLD | NEW |