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

Side by Side Diff: webrtc/modules/video_coding/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 condition for fetching from incomplete_frames_. Created 5 years, 1 month 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
« no previous file with comments | « no previous file | webrtc/modules/video_coding/jitter_buffer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/jitter_buffer.h" 10 #include "webrtc/modules/video_coding/jitter_buffer.h"
(...skipping 20 matching lines...) Expand all
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | webrtc/modules/video_coding/jitter_buffer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698