root/media/cast/rtp_receiver/receiver_stats_unittest.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. jitter_
  2. ExpectedJitter
  3. TEST_F
  4. TEST_F
  5. TEST_F
  6. TEST_F
  7. TEST_F
  8. TEST_F

// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <gtest/gtest.h>

#include <stdint.h>

#include "base/test/simple_test_tick_clock.h"
#include "base/time/time.h"
#include "media/cast/rtp_receiver/receiver_stats.h"
#include "media/cast/rtp_receiver/rtp_receiver_defines.h"

namespace media {
namespace cast {

static const int64 kStartMillisecond = INT64_C(12345678900000);
static const uint32 kStdTimeIncrementMs = 33;

class ReceiverStatsTest : public ::testing::Test {
 protected:
  ReceiverStatsTest()
      : stats_(&testing_clock_),
        rtp_header_(),
        fraction_lost_(0),
        cumulative_lost_(0),
        extended_high_sequence_number_(0),
        jitter_(0) {
    testing_clock_.Advance(
        base::TimeDelta::FromMilliseconds(kStartMillisecond));
    start_time_ = testing_clock_.NowTicks();
    delta_increments_ = base::TimeDelta::FromMilliseconds(kStdTimeIncrementMs);
    rtp_header_.webrtc.header.sequenceNumber = 0;
    rtp_header_.webrtc.header.timestamp = 0;
  }
  virtual ~ReceiverStatsTest() {}

  uint32 ExpectedJitter(uint32 const_interval, int num_packets) {
    float jitter = 0;
    // Assume timestamps have a constant kStdTimeIncrementMs interval.
    float float_interval =
        static_cast<float>(const_interval - kStdTimeIncrementMs);
    for (int i = 0; i < num_packets; ++i) {
      jitter += (float_interval - jitter) / 16;
    }
    return static_cast<uint32>(jitter + 0.5f);
  }

  ReceiverStats stats_;
  RtpCastHeader rtp_header_;
  uint8 fraction_lost_;
  uint32 cumulative_lost_;
  uint32 extended_high_sequence_number_;
  uint32 jitter_;
  base::SimpleTestTickClock testing_clock_;
  base::TimeTicks start_time_;
  base::TimeDelta delta_increments_;

  DISALLOW_COPY_AND_ASSIGN(ReceiverStatsTest);
};

TEST_F(ReceiverStatsTest, ResetState) {
  stats_.GetStatistics(&fraction_lost_,
                       &cumulative_lost_,
                       &extended_high_sequence_number_,
                       &jitter_);
  EXPECT_EQ(0u, fraction_lost_);
  EXPECT_EQ(0u, cumulative_lost_);
  EXPECT_EQ(0u, extended_high_sequence_number_);
  EXPECT_EQ(0u, jitter_);
}

TEST_F(ReceiverStatsTest, LossCount) {
  for (int i = 0; i < 300; ++i) {
    if (i % 4)
      stats_.UpdateStatistics(rtp_header_);
    if (i % 3) {
      rtp_header_.webrtc.header.timestamp += 33 * 90;
    }
    ++rtp_header_.webrtc.header.sequenceNumber;
    testing_clock_.Advance(delta_increments_);
  }
  stats_.GetStatistics(&fraction_lost_,
                       &cumulative_lost_,
                       &extended_high_sequence_number_,
                       &jitter_);
  EXPECT_EQ(63u, fraction_lost_);
  EXPECT_EQ(74u, cumulative_lost_);
  // Build extended sequence number.
  uint32 extended_seq_num = rtp_header_.webrtc.header.sequenceNumber - 1;
  EXPECT_EQ(extended_seq_num, extended_high_sequence_number_);
}

TEST_F(ReceiverStatsTest, NoLossWrap) {
  rtp_header_.webrtc.header.sequenceNumber = 65500;
  for (int i = 0; i < 300; ++i) {
    stats_.UpdateStatistics(rtp_header_);
    if (i % 3) {
      rtp_header_.webrtc.header.timestamp += 33 * 90;
    }
    ++rtp_header_.webrtc.header.sequenceNumber;
    testing_clock_.Advance(delta_increments_);
  }
  stats_.GetStatistics(&fraction_lost_,
                       &cumulative_lost_,
                       &extended_high_sequence_number_,
                       &jitter_);
  EXPECT_EQ(0u, fraction_lost_);
  EXPECT_EQ(0u, cumulative_lost_);
  // Build extended sequence number (one wrap cycle).
  uint32 extended_seq_num =
      (1 << 16) + rtp_header_.webrtc.header.sequenceNumber - 1;
  EXPECT_EQ(extended_seq_num, extended_high_sequence_number_);
}

TEST_F(ReceiverStatsTest, LossCountWrap) {
  const uint32 start_sequence_number = 65500;
  rtp_header_.webrtc.header.sequenceNumber = start_sequence_number;
  for (int i = 0; i < 300; ++i) {
    if (i % 4)
      stats_.UpdateStatistics(rtp_header_);
    if (i % 3)
      // Update timestamp.
      ++rtp_header_.webrtc.header.timestamp;
    ++rtp_header_.webrtc.header.sequenceNumber;
    testing_clock_.Advance(delta_increments_);
  }
  stats_.GetStatistics(&fraction_lost_,
                       &cumulative_lost_,
                       &extended_high_sequence_number_,
                       &jitter_);
  EXPECT_EQ(63u, fraction_lost_);
  EXPECT_EQ(74u, cumulative_lost_);
  // Build extended sequence number (one wrap cycle).
  uint32 extended_seq_num =
      (1 << 16) + rtp_header_.webrtc.header.sequenceNumber - 1;
  EXPECT_EQ(extended_seq_num, extended_high_sequence_number_);
}

TEST_F(ReceiverStatsTest, BasicJitter) {
  for (int i = 0; i < 300; ++i) {
    stats_.UpdateStatistics(rtp_header_);
    ++rtp_header_.webrtc.header.sequenceNumber;
    rtp_header_.webrtc.header.timestamp += 33 * 90;
    testing_clock_.Advance(delta_increments_);
  }
  stats_.GetStatistics(&fraction_lost_,
                       &cumulative_lost_,
                       &extended_high_sequence_number_,
                       &jitter_);
  EXPECT_FALSE(fraction_lost_);
  EXPECT_FALSE(cumulative_lost_);
  // Build extended sequence number (one wrap cycle).
  uint32 extended_seq_num = rtp_header_.webrtc.header.sequenceNumber - 1;
  EXPECT_EQ(extended_seq_num, extended_high_sequence_number_);
  EXPECT_EQ(ExpectedJitter(kStdTimeIncrementMs, 300), jitter_);
}

TEST_F(ReceiverStatsTest, NonTrivialJitter) {
  const int kAdditionalIncrement = 5;
  for (int i = 0; i < 300; ++i) {
    stats_.UpdateStatistics(rtp_header_);
    ++rtp_header_.webrtc.header.sequenceNumber;
    rtp_header_.webrtc.header.timestamp += 33 * 90;
    base::TimeDelta additional_delta =
        base::TimeDelta::FromMilliseconds(kAdditionalIncrement);
    testing_clock_.Advance(delta_increments_ + additional_delta);
  }
  stats_.GetStatistics(&fraction_lost_,
                       &cumulative_lost_,
                       &extended_high_sequence_number_,
                       &jitter_);
  EXPECT_FALSE(fraction_lost_);
  EXPECT_FALSE(cumulative_lost_);
  // Build extended sequence number (one wrap cycle).
  uint32 extended_seq_num = rtp_header_.webrtc.header.sequenceNumber - 1;
  EXPECT_EQ(extended_seq_num, extended_high_sequence_number_);
  EXPECT_EQ(ExpectedJitter(kStdTimeIncrementMs + kAdditionalIncrement, 300),
            jitter_);
}

}  // namespace cast
}  // namespace media

/* [<][>][^][v][top][bottom][index][help] */