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

Side by Side Diff: webrtc/modules/video_coding/jitter_buffer.cc

Issue 2146883002: Avoid race in VideoReceiveStream shutdown (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: JitterBuffer not resetting frame buffers on Stop Created 4 years, 5 months 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
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 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 : clock_(clock), 222 : clock_(clock),
223 running_(false), 223 running_(false),
224 crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), 224 crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
225 frame_event_(std::move(event)), 225 frame_event_(std::move(event)),
226 max_number_of_frames_(kStartNumberOfFrames), 226 max_number_of_frames_(kStartNumberOfFrames),
227 free_frames_(), 227 free_frames_(),
228 decodable_frames_(), 228 decodable_frames_(),
229 incomplete_frames_(), 229 incomplete_frames_(),
230 last_decoded_state_(), 230 last_decoded_state_(),
231 first_packet_since_reset_(true), 231 first_packet_since_reset_(true),
232 stats_callback_(NULL), 232 stats_callback_(nullptr),
233 incoming_frame_rate_(0), 233 incoming_frame_rate_(0),
234 incoming_frame_count_(0), 234 incoming_frame_count_(0),
235 time_last_incoming_frame_count_(0), 235 time_last_incoming_frame_count_(0),
236 incoming_bit_count_(0), 236 incoming_bit_count_(0),
237 incoming_bit_rate_(0), 237 incoming_bit_rate_(0),
238 num_consecutive_old_packets_(0), 238 num_consecutive_old_packets_(0),
239 num_packets_(0), 239 num_packets_(0),
240 num_duplicated_packets_(0), 240 num_duplicated_packets_(0),
241 num_discarded_packets_(0), 241 num_discarded_packets_(0),
242 time_first_packet_ms_(0), 242 time_first_packet_ms_(0),
243 jitter_estimate_(clock), 243 jitter_estimate_(clock),
244 inter_frame_delay_(clock_->TimeInMilliseconds()), 244 inter_frame_delay_(clock_->TimeInMilliseconds()),
245 rtt_ms_(kDefaultRtt), 245 rtt_ms_(kDefaultRtt),
246 nack_mode_(kNoNack), 246 nack_mode_(kNoNack),
247 low_rtt_nack_threshold_ms_(-1), 247 low_rtt_nack_threshold_ms_(-1),
248 high_rtt_nack_threshold_ms_(-1), 248 high_rtt_nack_threshold_ms_(-1),
249 missing_sequence_numbers_(SequenceNumberLessThan()), 249 missing_sequence_numbers_(SequenceNumberLessThan()),
250 latest_received_sequence_number_(0),
250 max_nack_list_size_(0), 251 max_nack_list_size_(0),
251 max_packet_age_to_nack_(0), 252 max_packet_age_to_nack_(0),
252 max_incomplete_time_ms_(0), 253 max_incomplete_time_ms_(0),
253 decode_error_mode_(kNoErrors), 254 decode_error_mode_(kNoErrors),
254 average_packets_per_frame_(0.0f), 255 average_packets_per_frame_(0.0f),
255 frame_counter_(0) { 256 frame_counter_(0) {
256 for (int i = 0; i < kStartNumberOfFrames; i++) 257 for (int i = 0; i < kStartNumberOfFrames; i++)
257 free_frames_.push_back(new VCMFrameBuffer()); 258 free_frames_.push_back(new VCMFrameBuffer());
258 } 259 }
259 260
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 num_discarded_packets_ = 0; 319 num_discarded_packets_ = 0;
319 time_first_packet_ms_ = 0; 320 time_first_packet_ms_ = 0;
320 321
321 // Start in a non-signaled state. 322 // Start in a non-signaled state.
322 waiting_for_completion_.frame_size = 0; 323 waiting_for_completion_.frame_size = 0;
323 waiting_for_completion_.timestamp = 0; 324 waiting_for_completion_.timestamp = 0;
324 waiting_for_completion_.latest_packet_time = -1; 325 waiting_for_completion_.latest_packet_time = -1;
325 first_packet_since_reset_ = true; 326 first_packet_since_reset_ = true;
326 rtt_ms_ = kDefaultRtt; 327 rtt_ms_ = kDefaultRtt;
327 last_decoded_state_.Reset(); 328 last_decoded_state_.Reset();
329
330 decodable_frames_.Reset(&free_frames_);
331 incomplete_frames_.Reset(&free_frames_);
328 } 332 }
329 333
330 void VCMJitterBuffer::Stop() { 334 void VCMJitterBuffer::Stop() {
331 crit_sect_->Enter(); 335 {
pbos-webrtc 2016/07/13 16:43:05 Remove the {}s, the time for calling event->set()
sprang_webrtc 2016/07/13 16:51:32 Done.
332 UpdateHistograms(); 336 CriticalSectionScoped cs(crit_sect_);
333 running_ = false; 337 UpdateHistograms();
334 last_decoded_state_.Reset(); 338 running_ = false;
335 339
336 // Make sure all frames are free and reset. 340 last_decoded_state_.Reset();
337 for (FrameList::iterator it = decodable_frames_.begin();
338 it != decodable_frames_.end(); ++it) {
339 free_frames_.push_back(it->second);
340 } 341 }
341 for (FrameList::iterator it = incomplete_frames_.begin(); 342
342 it != incomplete_frames_.end(); ++it) {
343 free_frames_.push_back(it->second);
344 }
345 for (UnorderedFrameList::iterator it = free_frames_.begin();
346 it != free_frames_.end(); ++it) {
347 (*it)->Reset();
348 }
349 decodable_frames_.clear();
350 incomplete_frames_.clear();
351 crit_sect_->Leave();
352 // Make sure we wake up any threads waiting on these events. 343 // Make sure we wake up any threads waiting on these events.
353 frame_event_->Set(); 344 frame_event_->Set();
354 } 345 }
355 346
356 bool VCMJitterBuffer::Running() const { 347 bool VCMJitterBuffer::Running() const {
357 CriticalSectionScoped cs(crit_sect_); 348 CriticalSectionScoped cs(crit_sect_);
358 return running_; 349 return running_;
359 } 350 }
360 351
361 void VCMJitterBuffer::Flush() { 352 void VCMJitterBuffer::Flush() {
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 578
588 if ((*frame).IsSessionComplete()) 579 if ((*frame).IsSessionComplete())
589 UpdateAveragePacketsPerFrame(frame->NumPackets()); 580 UpdateAveragePacketsPerFrame(frame->NumPackets());
590 581
591 return frame; 582 return frame;
592 } 583 }
593 584
594 // Release frame when done with decoding. Should never be used to release 585 // Release frame when done with decoding. Should never be used to release
595 // frames from within the jitter buffer. 586 // frames from within the jitter buffer.
596 void VCMJitterBuffer::ReleaseFrame(VCMEncodedFrame* frame) { 587 void VCMJitterBuffer::ReleaseFrame(VCMEncodedFrame* frame) {
588 RTC_CHECK(frame != nullptr);
597 CriticalSectionScoped cs(crit_sect_); 589 CriticalSectionScoped cs(crit_sect_);
598 VCMFrameBuffer* frame_buffer = static_cast<VCMFrameBuffer*>(frame); 590 VCMFrameBuffer* frame_buffer = static_cast<VCMFrameBuffer*>(frame);
599 if (frame_buffer) { 591 RecycleFrameBuffer(frame_buffer);
600 free_frames_.push_back(frame_buffer);
601 }
602 } 592 }
603 593
604 // Gets frame to use for this timestamp. If no match, get empty frame. 594 // Gets frame to use for this timestamp. If no match, get empty frame.
605 VCMFrameBufferEnum VCMJitterBuffer::GetFrame(const VCMPacket& packet, 595 VCMFrameBufferEnum VCMJitterBuffer::GetFrame(const VCMPacket& packet,
606 VCMFrameBuffer** frame, 596 VCMFrameBuffer** frame,
607 FrameList** frame_list) { 597 FrameList** frame_list) {
608 *frame = incomplete_frames_.PopFrame(packet.timestamp); 598 *frame = incomplete_frames_.PopFrame(packet.timestamp);
609 if (*frame != NULL) { 599 if (*frame != NULL) {
610 *frame_list = &incomplete_frames_; 600 *frame_list = &incomplete_frames_;
611 return kNoError; 601 return kNoError;
612 } 602 }
613 *frame = decodable_frames_.PopFrame(packet.timestamp); 603 *frame = decodable_frames_.PopFrame(packet.timestamp);
614 if (*frame != NULL) { 604 if (*frame != NULL) {
615 *frame_list = &decodable_frames_; 605 *frame_list = &decodable_frames_;
616 return kNoError; 606 return kNoError;
617 } 607 }
618 608
619 *frame_list = NULL; 609 *frame_list = NULL;
620 // No match, return empty frame. 610 // No match, return empty frame.
621 *frame = GetEmptyFrame(); 611 *frame = GetEmptyFrame();
622 if (*frame == NULL) { 612 if (*frame == NULL) {
623 // No free frame! Try to reclaim some... 613 // No free frame! Try to reclaim some...
624 LOG(LS_WARNING) << "Unable to get empty frame; Recycling."; 614 LOG(LS_WARNING) << "Unable to get empty frame; Recycling.";
625 bool found_key_frame = RecycleFramesUntilKeyFrame(); 615 bool found_key_frame = RecycleFramesUntilKeyFrame();
626 *frame = GetEmptyFrame(); 616 *frame = GetEmptyFrame();
627 assert(*frame); 617 RTC_CHECK(*frame);
628 if (!found_key_frame) { 618 if (!found_key_frame) {
629 free_frames_.push_back(*frame); 619 RecycleFrameBuffer(*frame);
630 return kFlushIndicator; 620 return kFlushIndicator;
631 } 621 }
632 } 622 }
633 (*frame)->Reset(); 623 (*frame)->Reset();
634 return kNoError; 624 return kNoError;
635 } 625 }
636 626
637 int64_t VCMJitterBuffer::LastPacketTime(const VCMEncodedFrame* frame, 627 int64_t VCMJitterBuffer::LastPacketTime(const VCMEncodedFrame* frame,
638 bool* retransmitted) const { 628 bool* retransmitted) const {
639 assert(retransmitted); 629 assert(retransmitted);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 LatestSequenceNumber(latest_received_sequence_number_, packet.seqNum); 736 LatestSequenceNumber(latest_received_sequence_number_, packet.seqNum);
747 } 737 }
748 } 738 }
749 739
750 // Is the frame already in the decodable list? 740 // Is the frame already in the decodable list?
751 bool continuous = IsContinuous(*frame); 741 bool continuous = IsContinuous(*frame);
752 switch (buffer_state) { 742 switch (buffer_state) {
753 case kGeneralError: 743 case kGeneralError:
754 case kTimeStampError: 744 case kTimeStampError:
755 case kSizeError: { 745 case kSizeError: {
756 free_frames_.push_back(frame); 746 RecycleFrameBuffer(frame);
757 break; 747 break;
758 } 748 }
759 case kCompleteSession: { 749 case kCompleteSession: {
760 if (previous_state != kStateDecodable && 750 if (previous_state != kStateDecodable &&
761 previous_state != kStateComplete) { 751 previous_state != kStateComplete) {
762 CountFrame(*frame); 752 CountFrame(*frame);
763 if (continuous) { 753 if (continuous) {
764 // Signal that we have a complete session. 754 // Signal that we have a complete session.
765 frame_event_->Set(); 755 frame_event_->Set();
766 } 756 }
(...skipping 13 matching lines...) Expand all
780 NonContinuousOrIncompleteDuration() > 770 NonContinuousOrIncompleteDuration() >
781 90 * kMaxDiscontinuousFramesTime) { 771 90 * kMaxDiscontinuousFramesTime) {
782 return kFlushIndicator; 772 return kFlushIndicator;
783 } 773 }
784 } 774 }
785 break; 775 break;
786 } 776 }
787 case kIncomplete: { 777 case kIncomplete: {
788 if (frame->GetState() == kStateEmpty && 778 if (frame->GetState() == kStateEmpty &&
789 last_decoded_state_.UpdateEmptyFrame(frame)) { 779 last_decoded_state_.UpdateEmptyFrame(frame)) {
790 free_frames_.push_back(frame); 780 RecycleFrameBuffer(frame);
791 return kNoError; 781 return kNoError;
792 } else { 782 } else {
793 incomplete_frames_.InsertFrame(frame); 783 incomplete_frames_.InsertFrame(frame);
794 // If NACKs are enabled, keyframes are triggered by |GetNackList|. 784 // If NACKs are enabled, keyframes are triggered by |GetNackList|.
795 if (nack_mode_ == kNoNack && 785 if (nack_mode_ == kNoNack &&
796 NonContinuousOrIncompleteDuration() > 786 NonContinuousOrIncompleteDuration() >
797 90 * kMaxDiscontinuousFramesTime) { 787 90 * kMaxDiscontinuousFramesTime) {
798 return kFlushIndicator; 788 return kFlushIndicator;
799 } 789 }
800 } 790 }
801 break; 791 break;
802 } 792 }
803 case kNoError: 793 case kNoError:
804 case kOutOfBoundsPacket: 794 case kOutOfBoundsPacket:
805 case kDuplicatePacket: { 795 case kDuplicatePacket: {
806 // Put back the frame where it came from. 796 // Put back the frame where it came from.
807 if (frame_list != NULL) { 797 if (frame_list != NULL) {
808 frame_list->InsertFrame(frame); 798 frame_list->InsertFrame(frame);
809 } else { 799 } else {
810 free_frames_.push_back(frame); 800 RecycleFrameBuffer(frame);
811 } 801 }
812 ++num_duplicated_packets_; 802 ++num_duplicated_packets_;
813 break; 803 break;
814 } 804 }
815 case kFlushIndicator: 805 case kFlushIndicator:
816 free_frames_.push_back(frame); 806 RecycleFrameBuffer(frame);
817 return kFlushIndicator; 807 return kFlushIndicator;
818 default: 808 default:
819 assert(false); 809 assert(false);
820 } 810 }
821 return buffer_state; 811 return buffer_state;
822 } 812 }
823 813
824 bool VCMJitterBuffer::IsContinuousInState( 814 bool VCMJitterBuffer::IsContinuousInState(
825 const VCMFrameBuffer& frame, 815 const VCMFrameBuffer& frame,
826 const VCMDecodingState& decoding_state) const { 816 const VCMDecodingState& decoding_state) const {
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
1308 } 1298 }
1309 // Evaluate if the RTT is higher than |high_rtt_nack_threshold_ms_|, and in 1299 // Evaluate if the RTT is higher than |high_rtt_nack_threshold_ms_|, and in
1310 // that case we don't wait for retransmissions. 1300 // that case we don't wait for retransmissions.
1311 if (high_rtt_nack_threshold_ms_ >= 0 && 1301 if (high_rtt_nack_threshold_ms_ >= 0 &&
1312 rtt_ms_ >= high_rtt_nack_threshold_ms_) { 1302 rtt_ms_ >= high_rtt_nack_threshold_ms_) {
1313 return false; 1303 return false;
1314 } 1304 }
1315 return true; 1305 return true;
1316 } 1306 }
1317 1307
1308 void VCMJitterBuffer::RecycleFrameBuffer(VCMFrameBuffer* frame) {
1309 frame->Reset();
1310 free_frames_.push_back(frame);
1311 }
1312
1318 } // namespace webrtc 1313 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698