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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 return pair.second->GetState() != kStateEmpty; | 53 return pair.second->GetState() != kStateEmpty; |
54 } | 54 } |
55 | 55 |
56 void FrameList::InsertFrame(VCMFrameBuffer* frame) { | 56 void FrameList::InsertFrame(VCMFrameBuffer* frame) { |
57 insert(rbegin().base(), FrameListPair(frame->TimeStamp(), frame)); | 57 insert(rbegin().base(), FrameListPair(frame->TimeStamp(), frame)); |
58 } | 58 } |
59 | 59 |
60 VCMFrameBuffer* FrameList::PopFrame(uint32_t timestamp) { | 60 VCMFrameBuffer* FrameList::PopFrame(uint32_t timestamp) { |
61 FrameList::iterator it = find(timestamp); | 61 FrameList::iterator it = find(timestamp); |
62 if (it == end()) | 62 if (it == end()) |
63 return NULL; | 63 return nullptr; |
64 VCMFrameBuffer* frame = it->second; | 64 VCMFrameBuffer* frame = it->second; |
65 erase(it); | 65 erase(it); |
66 return frame; | 66 return frame; |
67 } | 67 } |
68 | 68 |
69 VCMFrameBuffer* FrameList::Front() const { | 69 VCMFrameBuffer* FrameList::Front() const { |
70 return begin()->second; | 70 return begin()->second; |
71 } | 71 } |
72 | 72 |
73 VCMFrameBuffer* FrameList::Back() const { | 73 VCMFrameBuffer* FrameList::Back() const { |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 } | 524 } |
525 } | 525 } |
526 | 526 |
527 *timestamp = oldest_frame->TimeStamp(); | 527 *timestamp = oldest_frame->TimeStamp(); |
528 return true; | 528 return true; |
529 } | 529 } |
530 | 530 |
531 VCMEncodedFrame* VCMJitterBuffer::ExtractAndSetDecode(uint32_t timestamp) { | 531 VCMEncodedFrame* VCMJitterBuffer::ExtractAndSetDecode(uint32_t timestamp) { |
532 CriticalSectionScoped cs(crit_sect_); | 532 CriticalSectionScoped cs(crit_sect_); |
533 if (!running_) { | 533 if (!running_) { |
534 return NULL; | 534 return nullptr; |
535 } | 535 } |
536 // Extract the frame with the desired timestamp. | 536 // Extract the frame with the desired timestamp. |
537 VCMFrameBuffer* frame = decodable_frames_.PopFrame(timestamp); | 537 VCMFrameBuffer* frame = decodable_frames_.PopFrame(timestamp); |
538 bool continuous = true; | 538 bool continuous = true; |
539 if (!frame) { | 539 if (!frame) { |
540 frame = incomplete_frames_.PopFrame(timestamp); | 540 frame = incomplete_frames_.PopFrame(timestamp); |
541 if (frame) | 541 if (frame) |
542 continuous = last_decoded_state_.ContinuousFrame(frame); | 542 continuous = last_decoded_state_.ContinuousFrame(frame); |
543 else | 543 else |
544 return NULL; | 544 return nullptr; |
545 } | 545 } |
546 TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", timestamp, "Extract"); | 546 TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", timestamp, "Extract"); |
547 // Frame pulled out from jitter buffer, update the jitter estimate. | 547 // Frame pulled out from jitter buffer, update the jitter estimate. |
548 const bool retransmitted = (frame->GetNackCount() > 0); | 548 const bool retransmitted = (frame->GetNackCount() > 0); |
549 if (retransmitted) { | 549 if (retransmitted) { |
550 if (WaitForRetransmissions()) | 550 if (WaitForRetransmissions()) |
551 jitter_estimate_.FrameNacked(); | 551 jitter_estimate_.FrameNacked(); |
552 } else if (frame->Length() > 0) { | 552 } else if (frame->Length() > 0) { |
553 // Ignore retransmitted and empty frames. | 553 // Ignore retransmitted and empty frames. |
554 if (waiting_for_completion_.latest_packet_time >= 0) { | 554 if (waiting_for_completion_.latest_packet_time >= 0) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 CriticalSectionScoped cs(crit_sect_); | 586 CriticalSectionScoped cs(crit_sect_); |
587 VCMFrameBuffer* frame_buffer = static_cast<VCMFrameBuffer*>(frame); | 587 VCMFrameBuffer* frame_buffer = static_cast<VCMFrameBuffer*>(frame); |
588 RecycleFrameBuffer(frame_buffer); | 588 RecycleFrameBuffer(frame_buffer); |
589 } | 589 } |
590 | 590 |
591 // Gets frame to use for this timestamp. If no match, get empty frame. | 591 // Gets frame to use for this timestamp. If no match, get empty frame. |
592 VCMFrameBufferEnum VCMJitterBuffer::GetFrame(const VCMPacket& packet, | 592 VCMFrameBufferEnum VCMJitterBuffer::GetFrame(const VCMPacket& packet, |
593 VCMFrameBuffer** frame, | 593 VCMFrameBuffer** frame, |
594 FrameList** frame_list) { | 594 FrameList** frame_list) { |
595 *frame = incomplete_frames_.PopFrame(packet.timestamp); | 595 *frame = incomplete_frames_.PopFrame(packet.timestamp); |
596 if (*frame != NULL) { | 596 if (*frame != nullptr) { |
597 *frame_list = &incomplete_frames_; | 597 *frame_list = &incomplete_frames_; |
598 return kNoError; | 598 return kNoError; |
599 } | 599 } |
600 *frame = decodable_frames_.PopFrame(packet.timestamp); | 600 *frame = decodable_frames_.PopFrame(packet.timestamp); |
601 if (*frame != NULL) { | 601 if (*frame != nullptr) { |
602 *frame_list = &decodable_frames_; | 602 *frame_list = &decodable_frames_; |
603 return kNoError; | 603 return kNoError; |
604 } | 604 } |
605 | 605 |
606 *frame_list = NULL; | 606 *frame_list = nullptr; |
607 // No match, return empty frame. | 607 // No match, return empty frame. |
608 *frame = GetEmptyFrame(); | 608 *frame = GetEmptyFrame(); |
609 if (*frame == NULL) { | 609 if (*frame == nullptr) { |
610 // No free frame! Try to reclaim some... | 610 // No free frame! Try to reclaim some... |
611 LOG(LS_WARNING) << "Unable to get empty frame; Recycling."; | 611 LOG(LS_WARNING) << "Unable to get empty frame; Recycling."; |
612 bool found_key_frame = RecycleFramesUntilKeyFrame(); | 612 bool found_key_frame = RecycleFramesUntilKeyFrame(); |
613 *frame = GetEmptyFrame(); | 613 *frame = GetEmptyFrame(); |
614 RTC_CHECK(*frame); | 614 RTC_CHECK(*frame); |
615 if (!found_key_frame) { | 615 if (!found_key_frame) { |
616 RecycleFrameBuffer(*frame); | 616 RecycleFrameBuffer(*frame); |
617 return kFlushIndicator; | 617 return kFlushIndicator; |
618 } | 618 } |
619 } | 619 } |
(...skipping 18 matching lines...) Expand all Loading... |
638 ++num_packets_; | 638 ++num_packets_; |
639 if (num_packets_ == 1) { | 639 if (num_packets_ == 1) { |
640 time_first_packet_ms_ = clock_->TimeInMilliseconds(); | 640 time_first_packet_ms_ = clock_->TimeInMilliseconds(); |
641 } | 641 } |
642 // Does this packet belong to an old frame? | 642 // Does this packet belong to an old frame? |
643 if (last_decoded_state_.IsOldPacket(&packet)) { | 643 if (last_decoded_state_.IsOldPacket(&packet)) { |
644 // Account only for media packets. | 644 // Account only for media packets. |
645 if (packet.sizeBytes > 0) { | 645 if (packet.sizeBytes > 0) { |
646 num_discarded_packets_++; | 646 num_discarded_packets_++; |
647 num_consecutive_old_packets_++; | 647 num_consecutive_old_packets_++; |
648 if (stats_callback_ != NULL) | 648 if (stats_callback_ != nullptr) |
649 stats_callback_->OnDiscardedPacketsUpdated(num_discarded_packets_); | 649 stats_callback_->OnDiscardedPacketsUpdated(num_discarded_packets_); |
650 } | 650 } |
651 // Update last decoded sequence number if the packet arrived late and | 651 // Update last decoded sequence number if the packet arrived late and |
652 // belongs to a frame with a timestamp equal to the last decoded | 652 // belongs to a frame with a timestamp equal to the last decoded |
653 // timestamp. | 653 // timestamp. |
654 last_decoded_state_.UpdateOldPacket(&packet); | 654 last_decoded_state_.UpdateOldPacket(&packet); |
655 DropPacketsFromNackList(last_decoded_state_.sequence_num()); | 655 DropPacketsFromNackList(last_decoded_state_.sequence_num()); |
656 | 656 |
657 // Also see if this old packet made more incomplete frames continuous. | 657 // Also see if this old packet made more incomplete frames continuous. |
658 FindAndInsertContinuousFramesWithState(last_decoded_state_); | 658 FindAndInsertContinuousFramesWithState(last_decoded_state_); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 90 * kMaxDiscontinuousFramesTime) { | 784 90 * kMaxDiscontinuousFramesTime) { |
785 return kFlushIndicator; | 785 return kFlushIndicator; |
786 } | 786 } |
787 } | 787 } |
788 break; | 788 break; |
789 } | 789 } |
790 case kNoError: | 790 case kNoError: |
791 case kOutOfBoundsPacket: | 791 case kOutOfBoundsPacket: |
792 case kDuplicatePacket: { | 792 case kDuplicatePacket: { |
793 // Put back the frame where it came from. | 793 // Put back the frame where it came from. |
794 if (frame_list != NULL) { | 794 if (frame_list != nullptr) { |
795 frame_list->InsertFrame(frame); | 795 frame_list->InsertFrame(frame); |
796 } else { | 796 } else { |
797 RecycleFrameBuffer(frame); | 797 RecycleFrameBuffer(frame); |
798 } | 798 } |
799 ++num_duplicated_packets_; | 799 ++num_duplicated_packets_; |
800 break; | 800 break; |
801 } | 801 } |
802 case kFlushIndicator: | 802 case kFlushIndicator: |
803 RecycleFrameBuffer(frame); | 803 RecycleFrameBuffer(frame); |
804 return kFlushIndicator; | 804 return kFlushIndicator; |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1026 void VCMJitterBuffer::SetDecodeErrorMode(VCMDecodeErrorMode error_mode) { | 1026 void VCMJitterBuffer::SetDecodeErrorMode(VCMDecodeErrorMode error_mode) { |
1027 CriticalSectionScoped cs(crit_sect_); | 1027 CriticalSectionScoped cs(crit_sect_); |
1028 decode_error_mode_ = error_mode; | 1028 decode_error_mode_ = error_mode; |
1029 } | 1029 } |
1030 | 1030 |
1031 VCMFrameBuffer* VCMJitterBuffer::NextFrame() const { | 1031 VCMFrameBuffer* VCMJitterBuffer::NextFrame() const { |
1032 if (!decodable_frames_.empty()) | 1032 if (!decodable_frames_.empty()) |
1033 return decodable_frames_.Front(); | 1033 return decodable_frames_.Front(); |
1034 if (!incomplete_frames_.empty()) | 1034 if (!incomplete_frames_.empty()) |
1035 return incomplete_frames_.Front(); | 1035 return incomplete_frames_.Front(); |
1036 return NULL; | 1036 return nullptr; |
1037 } | 1037 } |
1038 | 1038 |
1039 bool VCMJitterBuffer::UpdateNackList(uint16_t sequence_number) { | 1039 bool VCMJitterBuffer::UpdateNackList(uint16_t sequence_number) { |
1040 if (nack_mode_ == kNoNack) { | 1040 if (nack_mode_ == kNoNack) { |
1041 return true; | 1041 return true; |
1042 } | 1042 } |
1043 // Make sure we don't add packets which are already too old to be decoded. | 1043 // Make sure we don't add packets which are already too old to be decoded. |
1044 if (!last_decoded_state_.in_initial_state()) { | 1044 if (!last_decoded_state_.in_initial_state()) { |
1045 latest_received_sequence_number_ = LatestSequenceNumber( | 1045 latest_received_sequence_number_ = LatestSequenceNumber( |
1046 latest_received_sequence_number_, last_decoded_state_.sequence_num()); | 1046 latest_received_sequence_number_, last_decoded_state_.sequence_num()); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 | 1124 |
1125 void VCMJitterBuffer::RegisterStatsCallback( | 1125 void VCMJitterBuffer::RegisterStatsCallback( |
1126 VCMReceiveStatisticsCallback* callback) { | 1126 VCMReceiveStatisticsCallback* callback) { |
1127 CriticalSectionScoped cs(crit_sect_); | 1127 CriticalSectionScoped cs(crit_sect_); |
1128 stats_callback_ = callback; | 1128 stats_callback_ = callback; |
1129 } | 1129 } |
1130 | 1130 |
1131 VCMFrameBuffer* VCMJitterBuffer::GetEmptyFrame() { | 1131 VCMFrameBuffer* VCMJitterBuffer::GetEmptyFrame() { |
1132 if (free_frames_.empty()) { | 1132 if (free_frames_.empty()) { |
1133 if (!TryToIncreaseJitterBufferSize()) { | 1133 if (!TryToIncreaseJitterBufferSize()) { |
1134 return NULL; | 1134 return nullptr; |
1135 } | 1135 } |
1136 } | 1136 } |
1137 VCMFrameBuffer* frame = free_frames_.front(); | 1137 VCMFrameBuffer* frame = free_frames_.front(); |
1138 free_frames_.pop_front(); | 1138 free_frames_.pop_front(); |
1139 return frame; | 1139 return frame; |
1140 } | 1140 } |
1141 | 1141 |
1142 bool VCMJitterBuffer::TryToIncreaseJitterBufferSize() { | 1142 bool VCMJitterBuffer::TryToIncreaseJitterBufferSize() { |
1143 if (max_number_of_frames_ >= kMaxNumberOfFrames) | 1143 if (max_number_of_frames_ >= kMaxNumberOfFrames) |
1144 return false; | 1144 return false; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1197 if (frame.IsSessionComplete()) { | 1197 if (frame.IsSessionComplete()) { |
1198 if (frame.FrameType() == kVideoFrameKey) { | 1198 if (frame.FrameType() == kVideoFrameKey) { |
1199 ++receive_statistics_.key_frames; | 1199 ++receive_statistics_.key_frames; |
1200 if (receive_statistics_.key_frames == 1) { | 1200 if (receive_statistics_.key_frames == 1) { |
1201 LOG(LS_INFO) << "Received first complete key frame"; | 1201 LOG(LS_INFO) << "Received first complete key frame"; |
1202 } | 1202 } |
1203 } else { | 1203 } else { |
1204 ++receive_statistics_.delta_frames; | 1204 ++receive_statistics_.delta_frames; |
1205 } | 1205 } |
1206 | 1206 |
1207 if (stats_callback_ != NULL) | 1207 if (stats_callback_ != nullptr) |
1208 stats_callback_->OnFrameCountsUpdated(receive_statistics_); | 1208 stats_callback_->OnFrameCountsUpdated(receive_statistics_); |
1209 } | 1209 } |
1210 } | 1210 } |
1211 | 1211 |
1212 void VCMJitterBuffer::UpdateAveragePacketsPerFrame(int current_number_packets) { | 1212 void VCMJitterBuffer::UpdateAveragePacketsPerFrame(int current_number_packets) { |
1213 if (frame_counter_ > kFastConvergeThreshold) { | 1213 if (frame_counter_ > kFastConvergeThreshold) { |
1214 average_packets_per_frame_ = | 1214 average_packets_per_frame_ = |
1215 average_packets_per_frame_ * (1 - kNormalConvergeMultiplier) + | 1215 average_packets_per_frame_ * (1 - kNormalConvergeMultiplier) + |
1216 current_number_packets * kNormalConvergeMultiplier; | 1216 current_number_packets * kNormalConvergeMultiplier; |
1217 } else if (frame_counter_ > 0) { | 1217 } else if (frame_counter_ > 0) { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1301 } | 1301 } |
1302 return true; | 1302 return true; |
1303 } | 1303 } |
1304 | 1304 |
1305 void VCMJitterBuffer::RecycleFrameBuffer(VCMFrameBuffer* frame) { | 1305 void VCMJitterBuffer::RecycleFrameBuffer(VCMFrameBuffer* frame) { |
1306 frame->Reset(); | 1306 frame->Reset(); |
1307 free_frames_.push_back(frame); | 1307 free_frames_.push_back(frame); |
1308 } | 1308 } |
1309 | 1309 |
1310 } // namespace webrtc | 1310 } // namespace webrtc |
OLD | NEW |