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