• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
TestLogging()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 
~TestLogging()33   virtual ~TestLogging() {}
34 
35   LoggingImpl logging_;
36   base::SimpleTestTickClock testing_clock_;
37 };
38 
TEST_F(TestLogging,BasicFrameLogging)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 
TEST_F(TestLogging,FrameLoggingWithSize)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 
TEST_F(TestLogging,FrameLoggingWithDelay)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 
TEST_F(TestLogging,MultipleEventFrameLogging)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 
TEST_F(TestLogging,PacketLogging)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 
TEST_F(TestLogging,GenericLogging)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