Home | History | Annotate | Download | only in logging
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <gtest/gtest.h>
      6 
      7 #include "base/rand_util.h"
      8 #include "base/test/simple_test_tick_clock.h"
      9 #include "base/time/tick_clock.h"
     10 #include "base/time/time.h"
     11 #include "media/cast/logging/logging_impl.h"
     12 
     13 
     14 namespace media {
     15 namespace cast {
     16 
     17  // Insert frame duration- one second.
     18 const int64 kIntervalTime1S = 1;
     19 // Test frame rate goal - 30fps.
     20 const int kFrameIntervalMs = 33;
     21 
     22 static const int64 kStartMillisecond = GG_INT64_C(12345678900000);
     23 
     24 class TestLogging : public ::testing::Test {
     25  protected:
     26   TestLogging()
     27     // Enable logging, disable tracing and uma.
     28       : logging_(&testing_clock_, true, false, false) {
     29     testing_clock_.Advance(
     30         base::TimeDelta::FromMilliseconds(kStartMillisecond));
     31   }
     32 
     33   virtual ~TestLogging() {}
     34 
     35   LoggingImpl logging_;
     36   base::SimpleTestTickClock testing_clock_;
     37 };
     38 
     39 TEST_F(TestLogging, BasicFrameLogging) {
     40   base::TimeTicks start_time = testing_clock_.NowTicks();
     41   base::TimeDelta time_interval = testing_clock_.NowTicks() - start_time;
     42   uint32 rtp_timestamp = 0;
     43   uint32 frame_id = 0;
     44   do {
     45     logging_.InsertFrameEvent(kAudioFrameCaptured, rtp_timestamp, frame_id);
     46     testing_clock_.Advance(
     47        base::TimeDelta::FromMilliseconds(kFrameIntervalMs));
     48     rtp_timestamp += kFrameIntervalMs * 90;
     49     ++frame_id;
     50     time_interval = testing_clock_.NowTicks() - start_time;
     51   }  while (time_interval.InSeconds() < kIntervalTime1S);
     52   // Get logging data.
     53   FrameRawMap frame_map = logging_.GetFrameRawData();
     54   // Size of map should be equal to the number of frames logged.
     55   EXPECT_EQ(frame_id, frame_map.size());
     56   // Verify stats.
     57   const FrameStatsMap* frame_stats = logging_.GetFrameStatsData();
     58   // Size of stats equals the number of events.
     59   EXPECT_EQ(1u, frame_stats->size());
     60   FrameStatsMap::const_iterator it = frame_stats->find(kAudioFrameCaptured);
     61   EXPECT_TRUE(it != frame_stats->end());
     62   EXPECT_NEAR(30.3, it->second->framerate_fps, 0.1);
     63   EXPECT_EQ(0, it->second->bitrate_kbps);
     64   EXPECT_EQ(0, it->second->max_delay_ms);
     65   EXPECT_EQ(0, it->second->min_delay_ms);
     66   EXPECT_EQ(0, it->second->avg_delay_ms);
     67 }
     68 
     69 TEST_F(TestLogging, FrameLoggingWithSize) {
     70   // Average packet size.
     71   const int kBaseFrameSizeBytes = 25000;
     72   const int kRandomSizeInterval = 100;
     73   base::TimeTicks start_time = testing_clock_.NowTicks();
     74   base::TimeDelta time_interval = testing_clock_.NowTicks() - start_time;
     75   uint32 rtp_timestamp = 0;
     76   uint32 frame_id = 0;
     77   do {
     78     int size = kBaseFrameSizeBytes +
     79         base::RandInt(-kRandomSizeInterval, kRandomSizeInterval);
     80     logging_.InsertFrameEventWithSize(
     81         kAudioFrameCaptured, rtp_timestamp, frame_id, size);
     82     testing_clock_.Advance(
     83        base::TimeDelta::FromMilliseconds(kFrameIntervalMs));
     84     rtp_timestamp += kFrameIntervalMs * 90;
     85     ++frame_id;
     86     time_interval = testing_clock_.NowTicks() - start_time;
     87   }  while (time_interval.InSeconds() < kIntervalTime1S);
     88   // Get logging data.
     89   FrameRawMap frame_map =  logging_.GetFrameRawData();
     90   // Size of map should be equal to the number of frames logged.
     91   EXPECT_EQ(frame_id, frame_map.size());
     92   // Verify stats.
     93   const FrameStatsMap* frame_stats = logging_.GetFrameStatsData();
     94   // Size of stats equals the number of events.
     95   EXPECT_EQ(1u, frame_stats->size());
     96   FrameStatsMap::const_iterator it = frame_stats->find(kAudioFrameCaptured);
     97   EXPECT_TRUE(it != frame_stats->end());
     98   EXPECT_NEAR(30.3, it->second->framerate_fps, 0.1);
     99   EXPECT_NEAR(8 * kBaseFrameSizeBytes / (kFrameIntervalMs * 1000),
    100       it->second->bitrate_kbps, kRandomSizeInterval);
    101   EXPECT_EQ(0, it->second->max_delay_ms);
    102   EXPECT_EQ(0, it->second->min_delay_ms);
    103   EXPECT_EQ(0, it->second->avg_delay_ms);
    104 }
    105 
    106 TEST_F(TestLogging, FrameLoggingWithDelay) {
    107   // Average packet size.
    108   const int kPlayoutDelayMs = 50;
    109   const int kRandomSizeInterval = 20;
    110   base::TimeTicks start_time = testing_clock_.NowTicks();
    111   base::TimeDelta time_interval = testing_clock_.NowTicks() - start_time;
    112   uint32 rtp_timestamp = 0;
    113   uint32 frame_id = 0;
    114   do {
    115     int delay = kPlayoutDelayMs +
    116         base::RandInt(-kRandomSizeInterval, kRandomSizeInterval);
    117     logging_.InsertFrameEventWithDelay(
    118         kAudioFrameCaptured, rtp_timestamp, frame_id,
    119         base::TimeDelta::FromMilliseconds(delay));
    120     testing_clock_.Advance(
    121        base::TimeDelta::FromMilliseconds(kFrameIntervalMs));
    122     rtp_timestamp += kFrameIntervalMs * 90;
    123     ++frame_id;
    124     time_interval = testing_clock_.NowTicks() - start_time;
    125   }  while (time_interval.InSeconds() < kIntervalTime1S);
    126   // Get logging data.
    127   FrameRawMap frame_map =  logging_.GetFrameRawData();
    128   // Size of map should be equal to the number of frames logged.
    129   EXPECT_EQ(frame_id, frame_map.size());
    130   // Verify stats.
    131   const FrameStatsMap* frame_stats = logging_.GetFrameStatsData();
    132   // Size of stats equals the number of events.
    133   EXPECT_EQ(1u, frame_stats->size());
    134   FrameStatsMap::const_iterator it = frame_stats->find(kAudioFrameCaptured);
    135   EXPECT_TRUE(it != frame_stats->end());
    136   EXPECT_NEAR(30.3, it->second->framerate_fps, 0.1);
    137   EXPECT_EQ(0, it->second->bitrate_kbps);
    138   EXPECT_GE(kPlayoutDelayMs + kRandomSizeInterval, it->second->max_delay_ms);
    139   EXPECT_LE(kPlayoutDelayMs - kRandomSizeInterval, it->second->min_delay_ms);
    140   EXPECT_NEAR(kPlayoutDelayMs, it->second->avg_delay_ms,
    141       0.2 * kRandomSizeInterval);
    142 }
    143 
    144 TEST_F(TestLogging, MultipleEventFrameLogging) {
    145   base::TimeTicks start_time = testing_clock_.NowTicks();
    146   base::TimeDelta time_interval = testing_clock_.NowTicks() - start_time;
    147   uint32 rtp_timestamp = 0;
    148   uint32 frame_id = 0;
    149   do {
    150     logging_.InsertFrameEvent(kAudioFrameCaptured, rtp_timestamp, frame_id);
    151     if (frame_id % 2) {
    152       logging_.InsertFrameEventWithSize(
    153           kAudioFrameEncoded, rtp_timestamp, frame_id, 1500);
    154     } else if (frame_id % 3) {
    155       logging_.InsertFrameEvent(kVideoFrameDecoded, rtp_timestamp, frame_id);
    156     } else {
    157       logging_.InsertFrameEventWithDelay(
    158           kVideoRenderDelay, rtp_timestamp, frame_id,
    159           base::TimeDelta::FromMilliseconds(20));
    160     }
    161     testing_clock_.Advance(
    162         base::TimeDelta::FromMilliseconds(kFrameIntervalMs));
    163     rtp_timestamp += kFrameIntervalMs * 90;
    164     ++frame_id;
    165     time_interval = testing_clock_.NowTicks() - start_time;
    166   }  while (time_interval.InSeconds() < kIntervalTime1S);
    167   // Get logging data.
    168   FrameRawMap frame_map =  logging_.GetFrameRawData();
    169   // Size of map should be equal to the number of frames logged.
    170   EXPECT_EQ(frame_id, frame_map.size());
    171   // Multiple events captured per frame.
    172 }
    173 
    174 TEST_F(TestLogging, PacketLogging) {
    175   const int kNumPacketsPerFrame = 10;
    176   const int kBaseSize = 2500;
    177   const int kSizeInterval = 100;
    178   base::TimeTicks start_time = testing_clock_.NowTicks();
    179   base::TimeDelta time_interval = testing_clock_.NowTicks() - start_time;
    180   uint32 rtp_timestamp = 0;
    181   uint32 frame_id = 0;
    182   do {
    183     for (int i = 0; i < kNumPacketsPerFrame; ++i) {
    184       int size = kBaseSize + base::RandInt(-kSizeInterval, kSizeInterval);
    185       logging_.InsertPacketEvent(kPacketSentToPacer, rtp_timestamp, frame_id,
    186           i, kNumPacketsPerFrame, size);
    187     }
    188     testing_clock_.Advance(
    189        base::TimeDelta::FromMilliseconds(kFrameIntervalMs));
    190     rtp_timestamp += kFrameIntervalMs * 90;
    191     ++frame_id;
    192     time_interval = testing_clock_.NowTicks() - start_time;
    193   }  while (time_interval.InSeconds() < kIntervalTime1S);
    194   // Get logging data.
    195   PacketRawMap raw_map = logging_.GetPacketRawData();
    196   // Size of map should be equal to the number of frames logged.
    197   EXPECT_EQ(frame_id, raw_map.size());
    198   // Verify stats.
    199   const PacketStatsMap* stats_map = logging_.GetPacketStatsData();
    200   // Size of stats equals the number of events.
    201   EXPECT_EQ(1u, stats_map->size());
    202   PacketStatsMap::const_iterator it = stats_map->find(kPacketSentToPacer);
    203   EXPECT_TRUE(it != stats_map->end());
    204   // We only store the bitrate as a packet statistic.
    205   EXPECT_NEAR(8 * kNumPacketsPerFrame * kBaseSize / (kFrameIntervalMs * 1000),
    206       it->second, kSizeInterval);
    207 }
    208 
    209 TEST_F(TestLogging, GenericLogging) {
    210   // Insert multiple generic types.
    211   const int kNumRuns = 1000;
    212   const int kBaseValue = 20;
    213   for (int i = 0; i < kNumRuns; ++i) {
    214     int value = kBaseValue + base::RandInt(-5, 5);
    215     logging_.InsertGenericEvent(kRtt, value);
    216     if (i % 2) {
    217       logging_.InsertGenericEvent(kPacketLoss, value);
    218     }
    219     if (!(i % 4)) {
    220       logging_.InsertGenericEvent(kJitter, value);
    221     }
    222   }
    223   GenericRawMap raw_map = logging_.GetGenericRawData();
    224   const GenericStatsMap* stats_map = logging_.GetGenericStatsData();
    225   // Size of generic map = number of different events.
    226   EXPECT_EQ(3u, raw_map.size());
    227   EXPECT_EQ(3u, stats_map->size());
    228   // Raw events - size of internal map = number of calls.
    229   GenericRawMap::iterator rit = raw_map.find(kRtt);
    230   EXPECT_EQ(kNumRuns, rit->second.value.size());
    231   EXPECT_EQ(kNumRuns, rit->second.timestamp.size());
    232   rit = raw_map.find(kPacketLoss);
    233   EXPECT_EQ(kNumRuns / 2, rit->second.value.size());
    234   EXPECT_EQ(kNumRuns / 2, rit->second.timestamp.size());
    235   rit = raw_map.find(kJitter);
    236   EXPECT_EQ(kNumRuns / 4, rit->second.value.size());
    237   EXPECT_EQ(kNumRuns / 4, rit->second.timestamp.size());
    238   // Stats - one value per event.
    239   GenericStatsMap::const_iterator sit = stats_map->find(kRtt);
    240   EXPECT_NEAR(kBaseValue, sit->second, 2.5);
    241   sit = stats_map->find(kPacketLoss);
    242   EXPECT_NEAR(kBaseValue, sit->second, 2.5);
    243   sit = stats_map->find(kJitter);
    244   EXPECT_NEAR(kBaseValue, sit->second, 2.5);
    245 }
    246 
    247 }  // namespace cast
    248 }  // namespace media
    249