1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 102637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/modules/video_coding/main/source/jitter_buffer.h" 11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 123f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <assert.h> 133f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <algorithm> 1599199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com#include <utility> 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 172637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/modules/video_coding/main/interface/video_coding.h" 181bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org#include "webrtc/modules/video_coding/main/source/frame_buffer.h" 191bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org#include "webrtc/modules/video_coding/main/source/inter_frame_delay.h" 201bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org#include "webrtc/modules/video_coding/main/source/internal_defines.h" 211bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org#include "webrtc/modules/video_coding/main/source/jitter_buffer_common.h" 221bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org#include "webrtc/modules/video_coding/main/source/jitter_estimator.h" 231bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org#include "webrtc/modules/video_coding/main/source/packet.h" 241bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org#include "webrtc/system_wrappers/interface/clock.h" 251bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 262637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/system_wrappers/interface/event_wrapper.h" 27bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org#include "webrtc/system_wrappers/interface/logging.h" 28dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com#include "webrtc/system_wrappers/interface/trace_event.h" 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc { 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 3278696d33d7711eb8208400908237c384b235bf74mflodman@webrtc.org// Use this rtt if no value has been reported. 3306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.orgstatic const uint32_t kDefaultRtt = 200; 3478696d33d7711eb8208400908237c384b235bf74mflodman@webrtc.org 3567ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.orgtypedef std::pair<uint32_t, VCMFrameBuffer*> FrameListPair; 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 3767ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.orgbool IsKeyFrame(FrameListPair pair) { 3867ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org return pair.second->FrameType() == kVideoFrameKey; 3967ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org} 40884ff6992da0cea12dfc5611d276860a1893ccd8tnakamura@webrtc.org 4167ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.orgbool HasNonEmptyState(FrameListPair pair) { 4267ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org return pair.second->GetState() != kStateEmpty; 43bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org} 44bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org 45376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.orgvoid FrameList::InsertFrame(VCMFrameBuffer* frame) { 4667ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org insert(rbegin().base(), FrameListPair(frame->TimeStamp(), frame)); 47376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org} 48376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org 49376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.orgVCMFrameBuffer* FrameList::FindFrame(uint32_t timestamp) const { 5067ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org FrameList::const_iterator it = find(timestamp); 51376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (it == end()) 52376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return NULL; 5367ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org return it->second; 54376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org} 55376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org 56376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.orgVCMFrameBuffer* FrameList::PopFrame(uint32_t timestamp) { 5767ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org FrameList::iterator it = find(timestamp); 58376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (it == end()) 59376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return NULL; 6067ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org VCMFrameBuffer* frame = it->second; 61376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org erase(it); 62376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return frame; 63376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org} 64376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org 6567ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.orgVCMFrameBuffer* FrameList::Front() const { 6667ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org return begin()->second; 6767ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org} 6867ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org 6967ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.orgVCMFrameBuffer* FrameList::Back() const { 7067ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org return rbegin()->second; 7167ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org} 7267ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org 738148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.orgint FrameList::RecycleFramesUntilKeyFrame(FrameList::iterator* key_frame_it, 748148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org UnorderedFrameList* free_frames) { 75376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org int drop_count = 0; 7667ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org FrameList::iterator it = begin(); 77376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org while (!empty()) { 78376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // Throw at least one frame. 798148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org it->second->Reset(); 808148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org free_frames->push_back(it->second); 8167ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org erase(it++); 82376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org ++drop_count; 8367ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org if (it != end() && it->second->FrameType() == kVideoFrameKey) { 8467ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org *key_frame_it = it; 85376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return drop_count; 86376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 87376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 8867ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org *key_frame_it = end(); 89376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return drop_count; 90376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org} 91376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org 928148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.orgint FrameList::CleanUpOldOrEmptyFrames(VCMDecodingState* decoding_state, 938148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org UnorderedFrameList* free_frames) { 94376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org int drop_count = 0; 95376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org while (!empty()) { 9667ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org VCMFrameBuffer* oldest_frame = Front(); 97376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org bool remove_frame = false; 98376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (oldest_frame->GetState() == kStateEmpty && size() > 1) { 99376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // This frame is empty, try to update the last decoded state and drop it 100376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // if successful. 101376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org remove_frame = decoding_state->UpdateEmptyFrame(oldest_frame); 102376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } else { 103376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org remove_frame = decoding_state->IsOldFrame(oldest_frame); 104376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 105376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (!remove_frame) { 106376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org break; 107376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 1088148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org free_frames->push_back(oldest_frame); 109376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org ++drop_count; 110376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org TRACE_EVENT_INSTANT1("webrtc", "JB::OldOrEmptyFrameDropped", "timestamp", 111376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org oldest_frame->TimeStamp()); 112376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org erase(begin()); 113376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 114376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return drop_count; 115376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org} 116376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org 1178148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.orgvoid FrameList::Reset(UnorderedFrameList* free_frames) { 1188148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org while (!empty()) { 1198148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org begin()->second->Reset(); 1208148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org free_frames->push_back(begin()->second); 1218148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org erase(begin()); 1228148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org } 1238148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org} 1248148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org 1258fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.orgVCMJitterBuffer::VCMJitterBuffer(Clock* clock, EventFactory* event_factory) 1268edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org : clock_(clock), 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org running_(false), 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), 1292637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org frame_event_(event_factory->CreateEvent()), 1302637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org packet_event_(event_factory->CreateEvent()), 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org max_number_of_frames_(kStartNumberOfFrames), 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_buffers_(), 1338148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org free_frames_(), 134376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org decodable_frames_(), 135376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org incomplete_frames_(), 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org last_decoded_state_(), 1373740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org first_packet_since_reset_(true), 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_frame_rate_(0), 139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_frame_count_(0), 140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org time_last_incoming_frame_count_(0), 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_bit_count_(0), 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_bit_rate_(0), 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org drop_count_(0), 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_consecutive_old_frames_(0), 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_consecutive_old_packets_(0), 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_discarded_packets_(0), 1478fa619d50b6e966389da02c45df23ce1a68089cbsprang@webrtc.org jitter_estimate_(clock), 1481bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org inter_frame_delay_(clock_->TimeInMilliseconds()), 14978696d33d7711eb8208400908237c384b235bf74mflodman@webrtc.org rtt_ms_(kDefaultRtt), 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nack_mode_(kNoNack), 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org low_rtt_nack_threshold_ms_(-1), 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org high_rtt_nack_threshold_ms_(-1), 153bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org missing_sequence_numbers_(SequenceNumberLessThan()), 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nack_seq_nums_(), 1557fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org max_nack_list_size_(0), 1567fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org max_packet_age_to_nack_(0), 15706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org max_incomplete_time_ms_(0), 1587b2147f8975308f753380cf0248b84a733970a10agalusza@google.com decode_error_mode_(kNoErrors), 15999199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com average_packets_per_frame_(0.0f), 16099199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com frame_counter_(0) { 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(frame_buffers_, 0, sizeof(frame_buffers_)); 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int i = 0; i < kStartNumberOfFrames; i++) { 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_buffers_[i] = new VCMFrameBuffer(); 1658148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org free_frames_.push_back(frame_buffers_[i]); 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMJitterBuffer::~VCMJitterBuffer() { 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Stop(); 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int i = 0; i < kMaxNumberOfFrames; i++) { 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (frame_buffers_[i]) { 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete frame_buffers_[i]; 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete crit_sect_; 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMJitterBuffer::CopyFrom(const VCMJitterBuffer& rhs) { 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (this != &rhs) { 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org crit_sect_->Enter(); 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rhs.crit_sect_->Enter(); 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org running_ = rhs.running_; 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org max_number_of_frames_ = rhs.max_number_of_frames_; 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_frame_rate_ = rhs.incoming_frame_rate_; 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_frame_count_ = rhs.incoming_frame_count_; 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org time_last_incoming_frame_count_ = rhs.time_last_incoming_frame_count_; 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_bit_count_ = rhs.incoming_bit_count_; 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_bit_rate_ = rhs.incoming_bit_rate_; 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org drop_count_ = rhs.drop_count_; 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_consecutive_old_frames_ = rhs.num_consecutive_old_frames_; 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_consecutive_old_packets_ = rhs.num_consecutive_old_packets_; 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_discarded_packets_ = rhs.num_discarded_packets_; 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org jitter_estimate_ = rhs.jitter_estimate_; 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inter_frame_delay_ = rhs.inter_frame_delay_; 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org waiting_for_completion_ = rhs.waiting_for_completion_; 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtt_ms_ = rhs.rtt_ms_; 1983740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org first_packet_since_reset_ = rhs.first_packet_since_reset_; 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org last_decoded_state_ = rhs.last_decoded_state_; 2007b2147f8975308f753380cf0248b84a733970a10agalusza@google.com decode_error_mode_ = rhs.decode_error_mode_; 2017fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org assert(max_nack_list_size_ == rhs.max_nack_list_size_); 2027fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org assert(max_packet_age_to_nack_ == rhs.max_packet_age_to_nack_); 20306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org assert(max_incomplete_time_ms_ == rhs.max_incomplete_time_ms_); 2045fdd10a56c3d7dcf2ea3cb2cd1118f616b783d24sprang@webrtc.org receive_statistics_ = rhs.receive_statistics_; 2057fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org nack_seq_nums_.resize(rhs.nack_seq_nums_.size()); 206bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org missing_sequence_numbers_ = rhs.missing_sequence_numbers_; 207bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org latest_received_sequence_number_ = rhs.latest_received_sequence_number_; 20899199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com average_packets_per_frame_ = rhs.average_packets_per_frame_; 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int i = 0; i < kMaxNumberOfFrames; i++) { 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (frame_buffers_[i] != NULL) { 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete frame_buffers_[i]; 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame_buffers_[i] = NULL; 213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2158148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org free_frames_.clear(); 216376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org decodable_frames_.clear(); 21767ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org incomplete_frames_.clear(); 2188148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org int i = 0; 2198148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org for (UnorderedFrameList::const_iterator it = rhs.free_frames_.begin(); 2208148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org it != rhs.free_frames_.end(); ++it, ++i) { 2218148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org frame_buffers_[i] = new VCMFrameBuffer; 2228148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org free_frames_.push_back(frame_buffers_[i]); 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2248148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org CopyFrames(&decodable_frames_, rhs.decodable_frames_, &i); 2258148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org CopyFrames(&incomplete_frames_, rhs.incomplete_frames_, &i); 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rhs.crit_sect_->Leave(); 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org crit_sect_->Leave(); 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2318148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.orgvoid VCMJitterBuffer::CopyFrames(FrameList* to_list, 2328148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org const FrameList& from_list, int* index) { 2338148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org to_list->clear(); 2348148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org for (FrameList::const_iterator it = from_list.begin(); 2358148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org it != from_list.end(); ++it, ++*index) { 2368148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org frame_buffers_[*index] = new VCMFrameBuffer(*it->second); 2378148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org to_list->InsertFrame(frame_buffers_[*index]); 2388148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org } 2398148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org} 2408148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMJitterBuffer::Start() { 242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(crit_sect_); 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org running_ = true; 244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_frame_count_ = 0; 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_frame_rate_ = 0; 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_bit_count_ = 0; 247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_bit_rate_ = 0; 2481bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org time_last_incoming_frame_count_ = clock_->TimeInMilliseconds(); 2495fdd10a56c3d7dcf2ea3cb2cd1118f616b783d24sprang@webrtc.org receive_statistics_.clear(); 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_consecutive_old_frames_ = 0; 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_consecutive_old_packets_ = 0; 253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_discarded_packets_ = 0; 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Start in a non-signaled state. 2562637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org frame_event_->Reset(); 2572637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org packet_event_->Reset(); 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org waiting_for_completion_.frame_size = 0; 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org waiting_for_completion_.timestamp = 0; 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org waiting_for_completion_.latest_packet_time = -1; 2613740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org first_packet_since_reset_ = true; 26278696d33d7711eb8208400908237c384b235bf74mflodman@webrtc.org rtt_ms_ = kDefaultRtt; 263b47b7e077c86e3b02c4db99bdb4a2d2c0722b52bmikhal@webrtc.org last_decoded_state_.Reset(); 264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMJitterBuffer::Stop() { 267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org crit_sect_->Enter(); 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org running_ = false; 269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org last_decoded_state_.Reset(); 2708148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org free_frames_.clear(); 271376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org decodable_frames_.clear(); 272376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org incomplete_frames_.clear(); 2738148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org // Make sure all frames are reset and free. 274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int i = 0; i < kMaxNumberOfFrames; i++) { 275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (frame_buffers_[i] != NULL) { 2768148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org static_cast<VCMFrameBuffer*>(frame_buffers_[i])->Reset(); 2778148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org free_frames_.push_back(frame_buffers_[i]); 278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org crit_sect_->Leave(); 281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Make sure we wake up any threads waiting on these events. 2822637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org frame_event_->Set(); 2832637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org packet_event_->Set(); 284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMJitterBuffer::Running() const { 287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(crit_sect_); 288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return running_; 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMJitterBuffer::Flush() { 292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(crit_sect_); 2938148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org decodable_frames_.Reset(&free_frames_); 2948148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org incomplete_frames_.Reset(&free_frames_); 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org last_decoded_state_.Reset(); // TODO(mikhal): sync reset. 2962637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org frame_event_->Reset(); 2972637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org packet_event_->Reset(); 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_consecutive_old_frames_ = 0; 299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_consecutive_old_packets_ = 0; 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Also reset the jitter and delay estimates 301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org jitter_estimate_.Reset(); 3021bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org inter_frame_delay_.Reset(clock_->TimeInMilliseconds()); 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org waiting_for_completion_.frame_size = 0; 304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org waiting_for_completion_.timestamp = 0; 305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org waiting_for_completion_.latest_packet_time = -1; 3063740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org first_packet_since_reset_ = true; 307bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org missing_sequence_numbers_.clear(); 308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Get received key and delta frames 3115fdd10a56c3d7dcf2ea3cb2cd1118f616b783d24sprang@webrtc.orgstd::map<FrameType, uint32_t> VCMJitterBuffer::FrameStatistics() const { 312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(crit_sect_); 3135fdd10a56c3d7dcf2ea3cb2cd1118f616b783d24sprang@webrtc.org return receive_statistics_; 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VCMJitterBuffer::num_discarded_packets() const { 317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(crit_sect_); 318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return num_discarded_packets_; 319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Calculate framerate and bitrate. 322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMJitterBuffer::IncomingRateStatistics(unsigned int* framerate, 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned int* bitrate) { 324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(framerate); 325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(bitrate); 326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(crit_sect_); 3271bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org const int64_t now = clock_->TimeInMilliseconds(); 328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int64_t diff = now - time_last_incoming_frame_count_; 329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (diff < 1000 && incoming_frame_rate_ > 0 && incoming_bit_rate_ > 0) { 330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Make sure we report something even though less than 331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // 1 second has passed since last update. 332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *framerate = incoming_frame_rate_; 333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *bitrate = incoming_bit_rate_; 334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (incoming_frame_count_ != 0) { 335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We have received frame(s) since last call to this function 336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Prepare calculations 338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (diff <= 0) { 339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org diff = 1; 340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // we add 0.5f for rounding 342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float rate = 0.5f + ((incoming_frame_count_ * 1000.0f) / diff); 343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (rate < 1.0f) { 344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rate = 1.0f; 345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Calculate frame rate 348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Let r be rate. 349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // r(0) = 1000*framecount/delta_time. 350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // (I.e. frames per second since last calculation.) 351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // frame_rate = r(0)/2 + r(-1)/2 352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // (I.e. fr/s average this and the previous calculation.) 353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *framerate = (incoming_frame_rate_ + static_cast<unsigned int>(rate)) / 2; 354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_frame_rate_ = static_cast<unsigned int>(rate); 355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Calculate bit rate 357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (incoming_bit_count_ == 0) { 358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *bitrate = 0; 359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *bitrate = 10 * ((100 * incoming_bit_count_) / 361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org static_cast<unsigned int>(diff)); 362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_bit_rate_ = *bitrate; 364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset count 366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_frame_count_ = 0; 367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_bit_count_ = 0; 368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org time_last_incoming_frame_count_ = now; 369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // No frames since last call 3721bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org time_last_incoming_frame_count_ = clock_->TimeInMilliseconds(); 373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *framerate = 0; 3749137e98631a681a7b509102c55778c1cc797c334stefan@webrtc.org *bitrate = 0; 3759137e98631a681a7b509102c55778c1cc797c334stefan@webrtc.org incoming_frame_rate_ = 0; 376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_bit_rate_ = 0; 377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Answers the question: 381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Will the packet sequence be complete if the next frame is grabbed for 382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// decoding right now? That is, have we lost a frame between the last decoded 383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// frame and the next, or is the next 384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// frame missing one or more packets? 385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMJitterBuffer::CompleteSequenceWithNextFrame() { 386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(crit_sect_); 387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Finding oldest frame ready for decoder, check sequence number and size 388bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org CleanUpOldOrEmptyFrames(); 3897b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com if (!decodable_frames_.empty()) { 3907b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com if (decodable_frames_.Front()->GetState() == kStateComplete) { 3917b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com return true; 3927b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com } 3937b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com } else if (incomplete_frames_.size() <= 1) { 394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Frame not ready to be decoded. 395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return true; 396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 397376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return false; 398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Returns immediately or a |max_wait_time_ms| ms event hang waiting for a 401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// complete frame, |max_wait_time_ms| decided by caller. 402933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.orgbool VCMJitterBuffer::NextCompleteTimestamp( 403933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org uint32_t max_wait_time_ms, uint32_t* timestamp) { 4044123abfdc67265776ff6004a2e40fa08faeaccffmikhal@webrtc.org crit_sect_->Enter(); 405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!running_) { 406376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org crit_sect_->Leave(); 407933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org return false; 408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 409bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org CleanUpOldOrEmptyFrames(); 410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 4117b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com if (decodable_frames_.empty() || 4127b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com decodable_frames_.Front()->GetState() != kStateComplete) { 4131bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org const int64_t end_wait_time_ms = clock_->TimeInMilliseconds() + 4141bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org max_wait_time_ms; 415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int64_t wait_time_ms = max_wait_time_ms; 416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (wait_time_ms > 0) { 417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org crit_sect_->Leave(); 418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const EventTypeWrapper ret = 4192637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org frame_event_->Wait(static_cast<uint32_t>(wait_time_ms)); 420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org crit_sect_->Enter(); 421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (ret == kEventSignaled) { 422376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // Are we shutting down the jitter buffer? 423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!running_) { 424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org crit_sect_->Leave(); 425933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org return false; 426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 4278148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org // Finding oldest frame ready for decoder. 428bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org CleanUpOldOrEmptyFrames(); 4297b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com if (decodable_frames_.empty() || 4307b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com decodable_frames_.Front()->GetState() != kStateComplete) { 4311bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org wait_time_ms = end_wait_time_ms - clock_->TimeInMilliseconds(); 432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 4362fc86eea87c6441dbc4155b9bc365ce5d26a2788mikhal@webrtc.org break; 437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Inside |crit_sect_|. 440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 441376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // We already have a frame, reset the event. 4422637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org frame_event_->Reset(); 443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 4447b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com if (decodable_frames_.empty() || 4457b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com decodable_frames_.Front()->GetState() != kStateComplete) { 446376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org crit_sect_->Leave(); 447376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return false; 4488bf7456eb477062c2a0a0693c3fa99063d529ed9tnakamura@webrtc.org } 44967ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org *timestamp = decodable_frames_.Front()->TimeStamp(); 450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org crit_sect_->Leave(); 451933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org return true; 452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 454376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.orgbool VCMJitterBuffer::NextMaybeIncompleteTimestamp(uint32_t* timestamp) { 455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(crit_sect_); 456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!running_) { 457933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org return false; 458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 4597b2147f8975308f753380cf0248b84a733970a10agalusza@google.com if (decode_error_mode_ == kNoErrors) { 4601886a048dbe72297b469be699a9750ae4a986967mikhal@webrtc.org // No point to continue, as we are not decoding with errors. 461933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org return false; 462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 464bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org CleanUpOldOrEmptyFrames(); 465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 4667b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com if (decodable_frames_.empty()) { 467933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org return false; 468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 4697b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com VCMFrameBuffer* oldest_frame = decodable_frames_.Front(); 4707b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com // If we have exactly one frame in the buffer, release it only if it is 471e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org // complete. We know decodable_frames_ is not empty due to the previous 4727b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com // check. 4737b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com if (decodable_frames_.size() == 1 && incomplete_frames_.empty() 4747b2147f8975308f753380cf0248b84a733970a10agalusza@google.com && oldest_frame->GetState() != kStateComplete) { 475933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org return false; 476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 477933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org 478933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org *timestamp = oldest_frame->TimeStamp(); 479933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org return true; 480933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org} 481933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org 482933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.orgVCMEncodedFrame* VCMJitterBuffer::ExtractAndSetDecode(uint32_t timestamp) { 483933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org CriticalSectionScoped cs(crit_sect_); 484933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org if (!running_) { 485b47b7e077c86e3b02c4db99bdb4a2d2c0722b52bmikhal@webrtc.org return NULL; 486b47b7e077c86e3b02c4db99bdb4a2d2c0722b52bmikhal@webrtc.org } 487933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org // Extract the frame with the desired timestamp. 488376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org VCMFrameBuffer* frame = decodable_frames_.PopFrame(timestamp); 4898148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org bool continuous = true; 490376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (!frame) { 491376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org frame = incomplete_frames_.PopFrame(timestamp); 4928148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org if (frame) 4938148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org continuous = last_decoded_state_.ContinuousFrame(frame); 4948148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org else 495376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return NULL; 496933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org } 4979c0f14d2cd43e388b5136f0ced7951ee58610e86hclam@chromium.org TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", timestamp, "Extract"); 4989c946517600e79044a369a6866754c3c17be1024mikhal@webrtc.org // Frame pulled out from jitter buffer, update the jitter estimate. 499933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org const bool retransmitted = (frame->GetNackCount() > 0); 500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (retransmitted) { 501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org jitter_estimate_.FrameNacked(); 502933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org } else if (frame->Length() > 0) { 503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Ignore retransmitted and empty frames. 504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (waiting_for_completion_.latest_packet_time >= 0) { 505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateJitterEstimate(waiting_for_completion_, true); 506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 5079c946517600e79044a369a6866754c3c17be1024mikhal@webrtc.org if (frame->GetState() == kStateComplete) { 5089c946517600e79044a369a6866754c3c17be1024mikhal@webrtc.org UpdateJitterEstimate(*frame, false); 5099c946517600e79044a369a6866754c3c17be1024mikhal@webrtc.org } else { 5109c946517600e79044a369a6866754c3c17be1024mikhal@webrtc.org // Wait for this one to get complete. 5119c946517600e79044a369a6866754c3c17be1024mikhal@webrtc.org waiting_for_completion_.frame_size = frame->Length(); 5129c946517600e79044a369a6866754c3c17be1024mikhal@webrtc.org waiting_for_completion_.latest_packet_time = 5139c946517600e79044a369a6866754c3c17be1024mikhal@webrtc.org frame->LatestPacketTimeMs(); 5149c946517600e79044a369a6866754c3c17be1024mikhal@webrtc.org waiting_for_completion_.timestamp = frame->TimeStamp(); 5159c946517600e79044a369a6866754c3c17be1024mikhal@webrtc.org } 516dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com } 517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The state must be changed to decoding before cleaning up zero sized 519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // frames to avoid empty frames being cleaned up and then given to the 5209c946517600e79044a369a6866754c3c17be1024mikhal@webrtc.org // decoder. Propagates the missing_frame bit. 5218148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org frame->PrepareForDecode(continuous); 522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 5239c946517600e79044a369a6866754c3c17be1024mikhal@webrtc.org // We have a frame - update the last decoded state and nack list. 524933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org last_decoded_state_.SetState(frame); 525bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org DropPacketsFromNackList(last_decoded_state_.sequence_num()); 52699199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com 52799199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com if ((*frame).IsSessionComplete()) 52899199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com UpdateAveragePacketsPerFrame(frame->NumPackets()); 52999199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com 530933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org return frame; 531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Release frame when done with decoding. Should never be used to release 534b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// frames from within the jitter buffer. 535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMJitterBuffer::ReleaseFrame(VCMEncodedFrame* frame) { 536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(crit_sect_); 537b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VCMFrameBuffer* frame_buffer = static_cast<VCMFrameBuffer*>(frame); 5388148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org if (frame_buffer) { 5398148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org free_frames_.push_back(frame_buffer); 5408148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org } 541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Gets frame to use for this timestamp. If no match, get empty frame. 5443740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.orgVCMFrameBufferEnum VCMJitterBuffer::GetFrame(const VCMPacket& packet, 5453740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org VCMFrameBuffer** frame) { 546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Does this packet belong to an old frame? 547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (last_decoded_state_.IsOldPacket(&packet)) { 548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Account only for media packets. 549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (packet.sizeBytes > 0) { 550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_discarded_packets_++; 551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_consecutive_old_packets_++; 552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update last decoded sequence number if the packet arrived late and 554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // belongs to a frame with a timestamp equal to the last decoded 555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // timestamp. 556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org last_decoded_state_.UpdateOldPacket(&packet); 557bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org DropPacketsFromNackList(last_decoded_state_.sequence_num()); 558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (num_consecutive_old_packets_ > kMaxConsecutiveOldPackets) { 5608edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org LOG(LS_WARNING) << num_consecutive_old_packets_ << " consecutive old " 5618edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org "packets received. Flushing the jitter buffer."; 562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Flush(); 5633740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org return kFlushIndicator; 564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 5653740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org return kOldPacket; 566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_consecutive_old_packets_ = 0; 568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 569376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org *frame = incomplete_frames_.FindFrame(packet.timestamp); 5708148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org if (*frame) 571376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return kNoError; 572376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org *frame = decodable_frames_.FindFrame(packet.timestamp); 5738148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org if (*frame) 5743740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org return kNoError; 575098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org 576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // No match, return empty frame. 5773740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org *frame = GetEmptyFrame(); 5788148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org VCMFrameBufferEnum ret = kNoError; 5798148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org if (!*frame) { 5808148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org // No free frame! Try to reclaim some... 5818edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org LOG(LS_WARNING) << "Unable to get empty frame; Recycling."; 5828148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org bool found_key_frame = RecycleFramesUntilKeyFrame(); 5838148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org *frame = GetEmptyFrame(); 5848edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org assert(*frame); 5858edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org if (!found_key_frame) { 5868148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org ret = kFlushIndicator; 5878edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org } 588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 5898148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org (*frame)->Reset(); 5908148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org return ret; 591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 5933740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.orgint64_t VCMJitterBuffer::LastPacketTime(const VCMEncodedFrame* frame, 594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool* retransmitted) const { 595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(retransmitted); 596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(crit_sect_); 5973740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org const VCMFrameBuffer* frame_buffer = 5983740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org static_cast<const VCMFrameBuffer*>(frame); 5993740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org *retransmitted = (frame_buffer->GetNackCount() > 0); 6003740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org return frame_buffer->LatestPacketTimeMs(); 601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 6033740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.orgVCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet, 6043740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org bool* retransmitted) { 605b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(crit_sect_); 6068148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org 6073740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org VCMFrameBuffer* frame = NULL; 6083740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org const VCMFrameBufferEnum error = GetFrame(packet, &frame); 6098148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org if (error != kNoError && frame == NULL) { 6103740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org return error; 6113740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org } 612098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org int64_t now_ms = clock_->TimeInMilliseconds(); 613098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org // We are keeping track of the first and latest seq numbers, and 614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // the number of wraps to be able to calculate how many packets we expect. 6153740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org if (first_packet_since_reset_) { 616b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Now it's time to start estimating jitter 617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // reset the delay estimate. 618098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org inter_frame_delay_.Reset(now_ms); 619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 620376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (last_decoded_state_.IsOldPacket(&packet)) { 621376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // This packet belongs to an old, already decoded frame, we want to update 622376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // the last decoded sequence number. 623376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org last_decoded_state_.UpdateOldPacket(&packet); 624376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org drop_count_++; 625098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org // Flush if this happens consistently. 626376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org num_consecutive_old_frames_++; 627376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (num_consecutive_old_frames_ > kMaxConsecutiveOldFrames) { 6288edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org LOG(LS_WARNING) << num_consecutive_old_packets_ << " consecutive old " 6298edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org "frames received. Flushing the jitter buffer."; 630376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org Flush(); 631376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return kFlushIndicator; 632376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 633376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return kNoError; 634376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 635098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org 636376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org num_consecutive_old_frames_ = 0; 637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Empty packets may bias the jitter estimate (lacking size component), 639b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // therefore don't let empty packet trigger the following updates: 640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (packet.frameType != kFrameEmpty) { 641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (waiting_for_completion_.timestamp == packet.timestamp) { 642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // This can get bad if we have a lot of duplicate packets, 643b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // we will then count some packet multiple times. 644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org waiting_for_completion_.frame_size += packet.sizeBytes; 645b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org waiting_for_completion_.latest_packet_time = now_ms; 646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (waiting_for_completion_.latest_packet_time >= 0 && 647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org waiting_for_completion_.latest_packet_time + 2000 <= now_ms) { 648b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // A packet should never be more than two seconds late 649b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateJitterEstimate(waiting_for_completion_, true); 650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org waiting_for_completion_.latest_packet_time = -1; 651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org waiting_for_completion_.frame_size = 0; 652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org waiting_for_completion_.timestamp = 0; 653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 654b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 656376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org VCMFrameBufferStateEnum previous_state = frame->GetState(); 6573740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org // Insert packet. 6583740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org // Check for first packet. High sequence number will be -1 if neither an empty 6593740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org // packet nor a media packet has been inserted. 660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool first = (frame->GetHighSeqNum() == -1); 66199199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com FrameData frame_data; 66299199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com frame_data.rtt_ms = rtt_ms_; 66399199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com frame_data.rolling_average_packets_per_frame = average_packets_per_frame_; 664098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org VCMFrameBufferEnum buffer_return = frame->InsertPacket(packet, 665098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org now_ms, 666098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org decode_error_mode_, 667098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org frame_data); 6689c0f14d2cd43e388b5136f0ced7951ee58610e86hclam@chromium.org if (!frame->GetCountedFrame()) { 6699c0f14d2cd43e388b5136f0ced7951ee58610e86hclam@chromium.org TRACE_EVENT_ASYNC_BEGIN1("webrtc", "Video", frame->TimeStamp(), 6709c0f14d2cd43e388b5136f0ced7951ee58610e86hclam@chromium.org "timestamp", frame->TimeStamp()); 6719c0f14d2cd43e388b5136f0ced7951ee58610e86hclam@chromium.org } 672098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org 673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (buffer_return > 0) { 674b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_bit_count_ += packet.sizeBytes << 3; 6753740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org if (first_packet_since_reset_) { 6763740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org latest_received_sequence_number_ = packet.seqNum; 6773740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org first_packet_since_reset_ = false; 6783740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org } else { 6793740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org if (IsPacketRetransmitted(packet)) { 6803740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org frame->IncrementNackCount(); 6813740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org } 6825359a2e38f6ed614249150ecb522ae5f7e041da2pbos@webrtc.org if (!UpdateNackList(packet.seqNum) && 6835359a2e38f6ed614249150ecb522ae5f7e041da2pbos@webrtc.org packet.frameType != kVideoFrameKey) { 6843740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org buffer_return = kFlushIndicator; 6853740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org } 6863740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org latest_received_sequence_number_ = LatestSequenceNumber( 6873740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org latest_received_sequence_number_, packet.seqNum); 6883740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org } 689b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 690098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org 691098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org // Is the frame already in the decodable list? 692098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org bool update_decodable_list = (previous_state != kStateDecodable && 693098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org previous_state != kStateComplete); 694098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org bool continuous = IsContinuous(*frame); 695b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (buffer_return) { 6963740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org case kGeneralError: 697b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kTimeStampError: 698b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kSizeError: { 699098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org // This frame will be cleaned up later from the frame list. 7008148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org frame->Reset(); 701b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 702b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kCompleteSession: { 704098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org if (update_decodable_list) { 705098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org CountFrame(*frame); 706098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org frame->SetCountedFrame(true); 707098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org if (continuous) { 708098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org // Signal that we have a complete session. 709098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org frame_event_->Set(); 710098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org } 7119e8a66c236b96d53c6a70f93f7dc78f88ea52540mikhal@webrtc.org } 7129e8a66c236b96d53c6a70f93f7dc78f88ea52540mikhal@webrtc.org } 713098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org // Note: There is no break here - continuing to kDecodableSession. 7149e8a66c236b96d53c6a70f93f7dc78f88ea52540mikhal@webrtc.org case kDecodableSession: { 7153740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org *retransmitted = (frame->GetNackCount() > 0); 716b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Signal that we have a received packet. 7172637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org packet_event_->Set(); 718098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org if (!update_decodable_list) { 719098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org break; 720098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org } 721098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org if (continuous) { 722098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org if (!first) { 723098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org incomplete_frames_.PopFrame(packet.timestamp); 724098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org } 725098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org decodable_frames_.InsertFrame(frame); 726098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org FindAndInsertContinuousFrames(*frame); 727098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org } else if (first) { 728098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org incomplete_frames_.InsertFrame(frame); 729098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org } 730b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 732b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kIncomplete: { 733376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // No point in storing empty continuous frames. 734376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (frame->GetState() == kStateEmpty && 735376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org last_decoded_state_.UpdateEmptyFrame(frame)) { 7368148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org free_frames_.push_back(frame); 7378148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org frame->Reset(); 7388148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org frame = NULL; 739098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org return kNoError; 740376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } else if (first) { 741376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org incomplete_frames_.InsertFrame(frame); 742376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 7438148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org // Signal that we have received a packet. 7448148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org packet_event_->Set(); 745b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 746b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 747b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kNoError: 748d9416e60745ee0d91fac637eb7b43bd2c9765391mikhal@webrtc.org case kOutOfBoundsPacket: 749b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kDuplicatePacket: { 750b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 751b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 7523740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org case kFlushIndicator: 753098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org return kFlushIndicator; 754b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default: { 755b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(false && "JitterBuffer::InsertPacket: Undefined value"); 756b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 757b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 758098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org return buffer_return; 759b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 760b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 761376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.orgbool VCMJitterBuffer::IsContinuousInState(const VCMFrameBuffer& frame, 762376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org const VCMDecodingState& decoding_state) const { 763098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org if (decode_error_mode_ == kWithErrors) 764098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org return true; 7657b2147f8975308f753380cf0248b84a733970a10agalusza@google.com // Is this frame (complete or decodable) and continuous? 7667b2147f8975308f753380cf0248b84a733970a10agalusza@google.com // kStateDecodable will never be set when decode_error_mode_ is false 7677b2147f8975308f753380cf0248b84a733970a10agalusza@google.com // as SessionInfo determines this state based on the error mode (and frame 7687b2147f8975308f753380cf0248b84a733970a10agalusza@google.com // completeness). 769376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if ((frame.GetState() == kStateComplete || 7707b2147f8975308f753380cf0248b84a733970a10agalusza@google.com frame.GetState() == kStateDecodable) && 771376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org decoding_state.ContinuousFrame(&frame)) { 772376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return true; 773376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } else { 774376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return false; 775376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 776376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org} 777376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org 778376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.orgbool VCMJitterBuffer::IsContinuous(const VCMFrameBuffer& frame) const { 779376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (IsContinuousInState(frame, last_decoded_state_)) { 780376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return true; 781376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 782376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org VCMDecodingState decoding_state; 783376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org decoding_state.CopyFrom(last_decoded_state_); 784376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org for (FrameList::const_iterator it = decodable_frames_.begin(); 785376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org it != decodable_frames_.end(); ++it) { 78667ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org VCMFrameBuffer* decodable_frame = it->second; 787376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (IsNewerTimestamp(decodable_frame->TimeStamp(), frame.TimeStamp())) { 788376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org break; 789376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 790376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org decoding_state.SetState(decodable_frame); 791376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (IsContinuousInState(frame, decoding_state)) { 792376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return true; 793376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 794376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 795376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return false; 796376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org} 797376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org 798376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.orgvoid VCMJitterBuffer::FindAndInsertContinuousFrames( 799376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org const VCMFrameBuffer& new_frame) { 800376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org VCMDecodingState decoding_state; 801376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org decoding_state.CopyFrom(last_decoded_state_); 802376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org decoding_state.SetState(&new_frame); 803376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // When temporal layers are available, we search for a complete or decodable 804376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // frame until we hit one of the following: 805376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // 1. Continuous base or sync layer. 806376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // 2. The end of the list was reached. 807376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org for (FrameList::iterator it = incomplete_frames_.begin(); 808376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org it != incomplete_frames_.end();) { 80967ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org VCMFrameBuffer* frame = it->second; 810376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (IsNewerTimestamp(new_frame.TimeStamp(), frame->TimeStamp())) { 811376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org ++it; 812376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org continue; 813376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 814376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (IsContinuousInState(*frame, decoding_state)) { 815376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org decodable_frames_.InsertFrame(frame); 81667ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org incomplete_frames_.erase(it++); 817376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org decoding_state.SetState(frame); 818376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } else if (frame->TemporalId() <= 0) { 819376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org break; 820376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } else { 821376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org ++it; 822376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 823376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 824376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org} 825376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org 826d206d5ad989a4f1ea641beec1555e868ffb0b4e8mikhal@webrtc.orguint32_t VCMJitterBuffer::EstimatedJitterMs() { 827d206d5ad989a4f1ea641beec1555e868ffb0b4e8mikhal@webrtc.org CriticalSectionScoped cs(crit_sect_); 828d206d5ad989a4f1ea641beec1555e868ffb0b4e8mikhal@webrtc.org // Compute RTT multiplier for estimation. 829b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // low_rtt_nackThresholdMs_ == -1 means no FEC. 830b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double rtt_mult = 1.0f; 831bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org if (low_rtt_nack_threshold_ms_ >= 0 && 832bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org static_cast<int>(rtt_ms_) >= low_rtt_nack_threshold_ms_) { 833bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org // For RTTs above low_rtt_nack_threshold_ms_ we don't apply extra delay 834bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org // when waiting for retransmissions. 835b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtt_mult = 0.0f; 836b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 837d206d5ad989a4f1ea641beec1555e868ffb0b4e8mikhal@webrtc.org return jitter_estimate_.GetJitterEstimate(rtt_mult); 838b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 839b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 840b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMJitterBuffer::UpdateRtt(uint32_t rtt_ms) { 841b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(crit_sect_); 842b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtt_ms_ = rtt_ms; 843b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org jitter_estimate_.UpdateRtt(rtt_ms); 844b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 845b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 846b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMJitterBuffer::SetNackMode(VCMNackMode mode, 847b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int low_rtt_nack_threshold_ms, 848b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int high_rtt_nack_threshold_ms) { 849b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(crit_sect_); 850b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nack_mode_ = mode; 851bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org if (mode == kNoNack) { 852bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org missing_sequence_numbers_.clear(); 853bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org } 854b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(low_rtt_nack_threshold_ms >= -1 && high_rtt_nack_threshold_ms >= -1); 855b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(high_rtt_nack_threshold_ms == -1 || 856b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org low_rtt_nack_threshold_ms <= high_rtt_nack_threshold_ms); 857b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(low_rtt_nack_threshold_ms > -1 || high_rtt_nack_threshold_ms == -1); 858b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org low_rtt_nack_threshold_ms_ = low_rtt_nack_threshold_ms; 859b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org high_rtt_nack_threshold_ms_ = high_rtt_nack_threshold_ms; 86078696d33d7711eb8208400908237c384b235bf74mflodman@webrtc.org // Don't set a high start rtt if high_rtt_nack_threshold_ms_ is used, to not 86178696d33d7711eb8208400908237c384b235bf74mflodman@webrtc.org // disable NACK in hybrid mode. 86278696d33d7711eb8208400908237c384b235bf74mflodman@webrtc.org if (rtt_ms_ == kDefaultRtt && high_rtt_nack_threshold_ms_ != -1) { 86378696d33d7711eb8208400908237c384b235bf74mflodman@webrtc.org rtt_ms_ = 0; 86478696d33d7711eb8208400908237c384b235bf74mflodman@webrtc.org } 865bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org if (!WaitForRetransmissions()) { 866b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org jitter_estimate_.ResetNackCount(); 867b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 868b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 869b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 8707fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.orgvoid VCMJitterBuffer::SetNackSettings(size_t max_nack_list_size, 87106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org int max_packet_age_to_nack, 87206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org int max_incomplete_time_ms) { 8737fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org CriticalSectionScoped cs(crit_sect_); 8747fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org assert(max_packet_age_to_nack >= 0); 87506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org assert(max_incomplete_time_ms_ >= 0); 8767fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org max_nack_list_size_ = max_nack_list_size; 8777fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org max_packet_age_to_nack_ = max_packet_age_to_nack; 87806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org max_incomplete_time_ms_ = max_incomplete_time_ms; 8797fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org nack_seq_nums_.resize(max_nack_list_size_); 8807fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org} 8817fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org 882b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMNackMode VCMJitterBuffer::nack_mode() const { 883b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(crit_sect_); 884b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return nack_mode_; 885b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 886b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 88706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.orgint VCMJitterBuffer::NonContinuousOrIncompleteDuration() { 888376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (incomplete_frames_.empty()) { 88906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org return 0; 89006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org } 89167ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org uint32_t start_timestamp = incomplete_frames_.Front()->TimeStamp(); 892376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (!decodable_frames_.empty()) { 89367ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org start_timestamp = decodable_frames_.Back()->TimeStamp(); 894376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 89567ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org return incomplete_frames_.Back()->TimeStamp() - start_timestamp; 89606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org} 89706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org 89806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.orguint16_t VCMJitterBuffer::EstimatedLowSequenceNumber( 89906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const VCMFrameBuffer& frame) const { 90006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org assert(frame.GetLowSeqNum() >= 0); 90106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org if (frame.HaveFirstPacket()) 90206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org return frame.GetLowSeqNum(); 903673f50d0907f9c58cabc891c54175b3e0a8bd18fhclam@chromium.org 904673f50d0907f9c58cabc891c54175b3e0a8bd18fhclam@chromium.org // This estimate is not accurate if more than one packet with lower sequence 905673f50d0907f9c58cabc891c54175b3e0a8bd18fhclam@chromium.org // number is lost. 90606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org return frame.GetLowSeqNum() - 1; 90706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org} 90806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org 909bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.orguint16_t* VCMJitterBuffer::GetNackList(uint16_t* nack_list_size, 910bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org bool* request_key_frame) { 911b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(crit_sect_); 912bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org *request_key_frame = false; 913bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org if (nack_mode_ == kNoNack) { 914b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *nack_list_size = 0; 915b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return NULL; 916b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 917bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org if (last_decoded_state_.in_initial_state()) { 9187b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com VCMFrameBuffer* next_frame = NextFrame(); 9197b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com const bool first_frame_is_key = next_frame && 9207b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com next_frame->FrameType() == kVideoFrameKey && 9217b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com next_frame->HaveFirstPacket(); 922dd32d855fbfd8577bfb5d96df10d23ce28bfbacastefan@webrtc.org if (!first_frame_is_key) { 923376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org bool have_non_empty_frame = decodable_frames_.end() != find_if( 924376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org decodable_frames_.begin(), decodable_frames_.end(), 925376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org HasNonEmptyState); 926376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (!have_non_empty_frame) { 927376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org have_non_empty_frame = incomplete_frames_.end() != find_if( 928376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org incomplete_frames_.begin(), incomplete_frames_.end(), 929376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org HasNonEmptyState); 930376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 931dd32d855fbfd8577bfb5d96df10d23ce28bfbacastefan@webrtc.org bool found_key_frame = RecycleFramesUntilKeyFrame(); 932dd32d855fbfd8577bfb5d96df10d23ce28bfbacastefan@webrtc.org if (!found_key_frame) { 933dd32d855fbfd8577bfb5d96df10d23ce28bfbacastefan@webrtc.org *request_key_frame = have_non_empty_frame; 934dd32d855fbfd8577bfb5d96df10d23ce28bfbacastefan@webrtc.org *nack_list_size = 0; 935dd32d855fbfd8577bfb5d96df10d23ce28bfbacastefan@webrtc.org return NULL; 936dd32d855fbfd8577bfb5d96df10d23ce28bfbacastefan@webrtc.org } 937dd32d855fbfd8577bfb5d96df10d23ce28bfbacastefan@webrtc.org } 938b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 939bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org if (TooLargeNackList()) { 940bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org *request_key_frame = !HandleTooLargeNackList(); 941b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 94206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org if (max_incomplete_time_ms_ > 0) { 94306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org int non_continuous_incomplete_duration = 94406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org NonContinuousOrIncompleteDuration(); 94506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org if (non_continuous_incomplete_duration > 90 * max_incomplete_time_ms_) { 9468edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org LOG_F(LS_WARNING) << "Too long non-decodable duration: " 9478edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org << non_continuous_incomplete_duration << " > " 9488edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org << 90 * max_incomplete_time_ms_; 949376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org FrameList::reverse_iterator rit = find_if(incomplete_frames_.rbegin(), 95067ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org incomplete_frames_.rend(), IsKeyFrame); 951376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (rit == incomplete_frames_.rend()) { 95206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Request a key frame if we don't have one already. 95306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org *request_key_frame = true; 95406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org *nack_list_size = 0; 95506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org return NULL; 95606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org } else { 95706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Skip to the last key frame. If it's incomplete we will start 95806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // NACKing it. 959673f50d0907f9c58cabc891c54175b3e0a8bd18fhclam@chromium.org // Note that the estimated low sequence number is correct for VP8 960673f50d0907f9c58cabc891c54175b3e0a8bd18fhclam@chromium.org // streams because only the first packet of a key frame is marked. 96106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org last_decoded_state_.Reset(); 96267ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org DropPacketsFromNackList(EstimatedLowSequenceNumber(*rit->second)); 96306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org } 96406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org } 96506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org } 966bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org unsigned int i = 0; 967bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org SequenceNumberSet::iterator it = missing_sequence_numbers_.begin(); 968bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org for (; it != missing_sequence_numbers_.end(); ++it, ++i) { 969bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org nack_seq_nums_[i] = *it; 970bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org } 971bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org *nack_list_size = i; 972bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org return &nack_seq_nums_[0]; 973bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org} 974b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 9759e8a66c236b96d53c6a70f93f7dc78f88ea52540mikhal@webrtc.orgvoid VCMJitterBuffer::SetDecodeErrorMode(VCMDecodeErrorMode error_mode) { 9769e8a66c236b96d53c6a70f93f7dc78f88ea52540mikhal@webrtc.org CriticalSectionScoped cs(crit_sect_); 977098704346096e90c689fbebb2224ea5dd184fb46mikhal@webrtc.org decode_error_mode_ = error_mode; 9787b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com} 9797b0ab2addc0fb6e22515fc949b727cba5636fa64agalusza@google.com 980376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.orgVCMFrameBuffer* VCMJitterBuffer::NextFrame() const { 981376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (!decodable_frames_.empty()) 98267ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org return decodable_frames_.Front(); 983376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (!incomplete_frames_.empty()) 98467ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org return incomplete_frames_.Front(); 985376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return NULL; 986376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org} 987376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org 988bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.orgbool VCMJitterBuffer::UpdateNackList(uint16_t sequence_number) { 989bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org if (nack_mode_ == kNoNack) { 990bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org return true; 991bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org } 992378a92394289d3d1b5c3a2d678e70045525042f9stefan@webrtc.org // Make sure we don't add packets which are already too old to be decoded. 993bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org if (!last_decoded_state_.in_initial_state()) { 994bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org latest_received_sequence_number_ = LatestSequenceNumber( 995bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org latest_received_sequence_number_, 99642c7409229636a59e28814451bd49ada2c6803a1stefan@webrtc.org last_decoded_state_.sequence_num()); 997378a92394289d3d1b5c3a2d678e70045525042f9stefan@webrtc.org } 99842c7409229636a59e28814451bd49ada2c6803a1stefan@webrtc.org if (IsNewerSequenceNumber(sequence_number, 99942c7409229636a59e28814451bd49ada2c6803a1stefan@webrtc.org latest_received_sequence_number_)) { 1000378a92394289d3d1b5c3a2d678e70045525042f9stefan@webrtc.org // Push any missing sequence numbers to the NACK list. 1001378a92394289d3d1b5c3a2d678e70045525042f9stefan@webrtc.org for (uint16_t i = latest_received_sequence_number_ + 1; 100273631c91e43e7a4775bed078f195d6d6663486eastefan@webrtc.org IsNewerSequenceNumber(sequence_number, i); ++i) { 1003378a92394289d3d1b5c3a2d678e70045525042f9stefan@webrtc.org missing_sequence_numbers_.insert(missing_sequence_numbers_.end(), i); 100474472fe9852769d834e135bde1229c24ab844244hclam@chromium.org TRACE_EVENT_INSTANT1("webrtc", "AddNack", "seqnum", i); 1005b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1006378a92394289d3d1b5c3a2d678e70045525042f9stefan@webrtc.org if (TooLargeNackList() && !HandleTooLargeNackList()) { 10078edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org LOG(LS_WARNING) << "Requesting key frame due to too large NACK list."; 1008378a92394289d3d1b5c3a2d678e70045525042f9stefan@webrtc.org return false; 1009378a92394289d3d1b5c3a2d678e70045525042f9stefan@webrtc.org } 1010378a92394289d3d1b5c3a2d678e70045525042f9stefan@webrtc.org if (MissingTooOldPacket(sequence_number) && 1011378a92394289d3d1b5c3a2d678e70045525042f9stefan@webrtc.org !HandleTooOldPackets(sequence_number)) { 10128edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org LOG(LS_WARNING) << "Requesting key frame due to missing too old packets"; 1013378a92394289d3d1b5c3a2d678e70045525042f9stefan@webrtc.org return false; 1014378a92394289d3d1b5c3a2d678e70045525042f9stefan@webrtc.org } 1015378a92394289d3d1b5c3a2d678e70045525042f9stefan@webrtc.org } else { 1016378a92394289d3d1b5c3a2d678e70045525042f9stefan@webrtc.org missing_sequence_numbers_.erase(sequence_number); 101774472fe9852769d834e135bde1229c24ab844244hclam@chromium.org TRACE_EVENT_INSTANT1("webrtc", "RemoveNack", "seqnum", sequence_number); 1018b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1019bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org return true; 1020bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org} 1021b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1022bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.orgbool VCMJitterBuffer::TooLargeNackList() const { 1023bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org return missing_sequence_numbers_.size() > max_nack_list_size_; 1024bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org} 1025b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1026bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.orgbool VCMJitterBuffer::HandleTooLargeNackList() { 1027bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org // Recycle frames until the NACK list is small enough. It is likely cheaper to 1028bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org // request a key frame than to retransmit this many missing packets. 10298edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org LOG_F(LS_WARNING) << "NACK list has grown too large: " 10308edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org << missing_sequence_numbers_.size() << " > " 10318edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org << max_nack_list_size_; 1032bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org bool key_frame_found = false; 1033378a92394289d3d1b5c3a2d678e70045525042f9stefan@webrtc.org while (TooLargeNackList()) { 1034bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org key_frame_found = RecycleFramesUntilKeyFrame(); 1035bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org } 1036bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org return key_frame_found; 1037bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org} 10387fff32c808707eb6810d1057747069d7afce9939stefan@webrtc.org 1039bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.orgbool VCMJitterBuffer::MissingTooOldPacket( 1040bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org uint16_t latest_sequence_number) const { 1041bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org if (missing_sequence_numbers_.empty()) { 1042bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org return false; 1043b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1044bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org const uint16_t age_of_oldest_missing_packet = latest_sequence_number - 1045bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org *missing_sequence_numbers_.begin(); 1046bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org // Recycle frames if the NACK list contains too old sequence numbers as 1047bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org // the packets may have already been dropped by the sender. 1048bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org return age_of_oldest_missing_packet > max_packet_age_to_nack_; 1049bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org} 1050b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1051bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.orgbool VCMJitterBuffer::HandleTooOldPackets(uint16_t latest_sequence_number) { 1052bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org bool key_frame_found = false; 1053bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org const uint16_t age_of_oldest_missing_packet = latest_sequence_number - 1054bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org *missing_sequence_numbers_.begin(); 10558edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org LOG_F(LS_WARNING) << "NACK list contains too old sequence numbers: " 10568edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org << age_of_oldest_missing_packet << " > " 10578edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org << max_packet_age_to_nack_; 1058bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org while (MissingTooOldPacket(latest_sequence_number)) { 1059bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org key_frame_found = RecycleFramesUntilKeyFrame(); 1060bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org } 1061bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org return key_frame_found; 1062bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org} 1063b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1064bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.orgvoid VCMJitterBuffer::DropPacketsFromNackList( 1065bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org uint16_t last_decoded_sequence_number) { 1066bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org // Erase all sequence numbers from the NACK list which we won't need any 1067bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org // longer. 1068bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org missing_sequence_numbers_.erase(missing_sequence_numbers_.begin(), 1069bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org missing_sequence_numbers_.upper_bound( 1070bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org last_decoded_sequence_number)); 1071b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1072b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1073b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint64_t VCMJitterBuffer::LastDecodedTimestamp() const { 1074b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(crit_sect_); 1075b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return last_decoded_state_.time_stamp(); 1076b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1077b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 107806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.orgvoid VCMJitterBuffer::RenderBufferSize(uint32_t* timestamp_start, 107906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org uint32_t* timestamp_end) { 108006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org CriticalSectionScoped cs(crit_sect_); 108106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org CleanUpOldOrEmptyFrames(); 108206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org *timestamp_start = 0; 108306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org *timestamp_end = 0; 1084376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (decodable_frames_.empty()) { 108506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org return; 108606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org } 108767ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org *timestamp_start = decodable_frames_.Front()->TimeStamp(); 108867ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org *timestamp_end = decodable_frames_.Back()->TimeStamp(); 108940bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org} 109040bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 1091b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMFrameBuffer* VCMJitterBuffer::GetEmptyFrame() { 10928148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org if (free_frames_.empty()) { 10938148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org if (!TryToIncreaseJitterBufferSize()) { 10948148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org return NULL; 1095b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1096b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 10978148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org VCMFrameBuffer* frame = free_frames_.front(); 10988148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org free_frames_.pop_front(); 10998148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org return frame; 11008148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org} 1101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11028148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.orgbool VCMJitterBuffer::TryToIncreaseJitterBufferSize() { 11038148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org if (max_number_of_frames_ >= kMaxNumberOfFrames) 11048148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org return false; 11058148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org VCMFrameBuffer* new_frame = new VCMFrameBuffer(); 11068148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org frame_buffers_[max_number_of_frames_] = new_frame; 11078148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org free_frames_.push_back(new_frame); 11088148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org ++max_number_of_frames_; 11098148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org TRACE_COUNTER1("webrtc", "JBMaxFrames", max_number_of_frames_); 11108148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org return true; 1111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Recycle oldest frames up to a key frame, used if jitter buffer is completely 1114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// full. 1115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMJitterBuffer::RecycleFramesUntilKeyFrame() { 1116376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // First release incomplete frames, and only release decodable frames if there 1117376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // are no incomplete ones. 1118376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org FrameList::iterator key_frame_it; 1119376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org bool key_frame_found = false; 1120376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org int dropped_frames = 0; 1121376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org dropped_frames += incomplete_frames_.RecycleFramesUntilKeyFrame( 11228148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org &key_frame_it, &free_frames_); 1123376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org key_frame_found = key_frame_it != incomplete_frames_.end(); 1124376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (dropped_frames == 0) { 1125376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org dropped_frames += decodable_frames_.RecycleFramesUntilKeyFrame( 11268148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org &key_frame_it, &free_frames_); 1127376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org key_frame_found = key_frame_it != decodable_frames_.end(); 1128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1129376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org drop_count_ += dropped_frames; 1130376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org TRACE_EVENT_INSTANT0("webrtc", "JB::RecycleFramesUntilKeyFrame"); 1131376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (key_frame_found) { 11328edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org LOG(LS_INFO) << "Found key frame while dropping frames."; 1133376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // Reset last decoded state to make sure the next frame decoded is a key 1134376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // frame, and start NACKing from here. 1135376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org last_decoded_state_.Reset(); 113667ca2b42373e2f72e96daa4578dbe10333c61ecfstefan@webrtc.org DropPacketsFromNackList(EstimatedLowSequenceNumber(*key_frame_it->second)); 1137376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } else if (decodable_frames_.empty()) { 11388148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org // All frames dropped. Reset the decoding state and clear missing sequence 11398148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org // numbers as we're starting fresh. 11408148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org last_decoded_state_.Reset(); 1141376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org missing_sequence_numbers_.clear(); 1142dded206d3c7f1b55ada0b36b84be80d987fd88c4edjee@google.com } 1143376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return key_frame_found; 1144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Must be called under the critical section |crit_sect_|. 11478148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.orgvoid VCMJitterBuffer::CountFrame(const VCMFrameBuffer& frame) { 11488148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org if (!frame.GetCountedFrame()) { 1149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Ignore ACK frames. 1150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_frame_count_++; 1151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11538148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org if (frame.FrameType() == kVideoFrameKey) { 11549c0f14d2cd43e388b5136f0ced7951ee58610e86hclam@chromium.org TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", 11559c0f14d2cd43e388b5136f0ced7951ee58610e86hclam@chromium.org frame.TimeStamp(), "KeyComplete"); 115674472fe9852769d834e135bde1229c24ab844244hclam@chromium.org } else { 11579c0f14d2cd43e388b5136f0ced7951ee58610e86hclam@chromium.org TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", 11589c0f14d2cd43e388b5136f0ced7951ee58610e86hclam@chromium.org frame.TimeStamp(), "DeltaComplete"); 115974472fe9852769d834e135bde1229c24ab844244hclam@chromium.org } 1160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update receive statistics. We count all layers, thus when you use layers 1162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // adding all key and delta frames might differ from frame count. 11638148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org if (frame.IsSessionComplete()) { 11645fdd10a56c3d7dcf2ea3cb2cd1118f616b783d24sprang@webrtc.org ++receive_statistics_[frame.FrameType()]; 1165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 116899199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.comvoid VCMJitterBuffer::UpdateAveragePacketsPerFrame(int current_number_packets) { 116999199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com if (frame_counter_ > kFastConvergeThreshold) { 117099199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com average_packets_per_frame_ = average_packets_per_frame_ 117199199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com * (1 - kNormalConvergeMultiplier) 117299199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com + current_number_packets * kNormalConvergeMultiplier; 117399199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com } else if (frame_counter_ > 0) { 117499199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com average_packets_per_frame_ = average_packets_per_frame_ 117599199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com * (1 - kFastConvergeMultiplier) 117699199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com + current_number_packets * kFastConvergeMultiplier; 117799199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com frame_counter_++; 117899199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com } else { 117999199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com average_packets_per_frame_ = current_number_packets; 118099199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com frame_counter_++; 118199199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com } 118299199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com} 118399199e5b490cc99936d798ca5958cf9eb26228e0agalusza@google.com 1184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Must be called under the critical section |crit_sect_|. 1185bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.orgvoid VCMJitterBuffer::CleanUpOldOrEmptyFrames() { 1186376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org drop_count_ += 11878148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org decodable_frames_.CleanUpOldOrEmptyFrames(&last_decoded_state_, 11888148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org &free_frames_); 1189376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org drop_count_ += 11908148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org incomplete_frames_.CleanUpOldOrEmptyFrames(&last_decoded_state_, 11918148118765d5b822258e7c6fc4f1155bc703a2dfstefan@webrtc.org &free_frames_); 1192bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org if (!last_decoded_state_.in_initial_state()) { 1193bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org DropPacketsFromNackList(last_decoded_state_.sequence_num()); 1194bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org } 1195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Must be called from within |crit_sect_|. 1198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMJitterBuffer::IsPacketRetransmitted(const VCMPacket& packet) const { 1199bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org return missing_sequence_numbers_.find(packet.seqNum) != 1200bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org missing_sequence_numbers_.end(); 1201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Must be called under the critical section |crit_sect_|. Should never be 1204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// called with retransmitted frames, they must be filtered out before this 1205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// function is called. 1206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMJitterBuffer::UpdateJitterEstimate(const VCMJitterSample& sample, 1207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool incomplete_frame) { 1208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (sample.latest_packet_time == -1) { 1209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 1210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateJitterEstimate(sample.latest_packet_time, sample.timestamp, 1212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sample.frame_size, incomplete_frame); 1213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Must be called under the critical section crit_sect_. Should never be 1216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// called with retransmitted frames, they must be filtered out before this 1217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// function is called. 1218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMJitterBuffer::UpdateJitterEstimate(const VCMFrameBuffer& frame, 1219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool incomplete_frame) { 1220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (frame.LatestPacketTimeMs() == -1) { 1221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 1222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // No retransmitted frames should be a part of the jitter 1224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // estimate. 1225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateJitterEstimate(frame.LatestPacketTimeMs(), frame.TimeStamp(), 1226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame.Length(), incomplete_frame); 1227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Must be called under the critical section |crit_sect_|. Should never be 1230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// called with retransmitted frames, they must be filtered out before this 1231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// function is called. 1232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMJitterBuffer::UpdateJitterEstimate( 1233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int64_t latest_packet_time_ms, 1234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint32_t timestamp, 1235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned int frame_size, 1236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool incomplete_frame) { 1237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (latest_packet_time_ms == -1) { 1238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 1239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int64_t frame_delay; 1241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool not_reordered = inter_frame_delay_.CalculateDelay(timestamp, 1242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &frame_delay, 1243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org latest_packet_time_ms); 1244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Filter out frames which have been reordered in time by the network 1245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (not_reordered) { 1246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update the jitter estimate with the new samples 1247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org jitter_estimate_.UpdateEstimate(frame_delay, frame_size, incomplete_frame); 1248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMJitterBuffer::WaitForRetransmissions() { 1252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (nack_mode_ == kNoNack) { 1253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // NACK disabled -> don't wait for retransmissions. 1254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 1255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1256bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org // Evaluate if the RTT is higher than |high_rtt_nack_threshold_ms_|, and in 1257bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org // that case we don't wait for retransmissions. 1258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (high_rtt_nack_threshold_ms_ >= 0 && 1259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtt_ms_ >= static_cast<unsigned int>(high_rtt_nack_threshold_ms_)) { 1260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 1261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return true; 1263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} // namespace webrtc 1265