12d899751069605306521f226144f7287be7ab2d1Johnny Chen// Copyright 2014 The Chromium Authors. All rights reserved.
22d899751069605306521f226144f7287be7ab2d1Johnny Chen// Use of this source code is governed by a BSD-style license that can be
32d899751069605306521f226144f7287be7ab2d1Johnny Chen// found in the LICENSE file.
42d899751069605306521f226144f7287be7ab2d1Johnny Chen
52d899751069605306521f226144f7287be7ab2d1Johnny Chen#include <stdint.h>
62d899751069605306521f226144f7287be7ab2d1Johnny Chen
72d899751069605306521f226144f7287be7ab2d1Johnny Chen#include <vector>
82d899751069605306521f226144f7287be7ab2d1Johnny Chen
92d899751069605306521f226144f7287be7ab2d1Johnny Chen#include "base/rand_util.h"
102d899751069605306521f226144f7287be7ab2d1Johnny Chen#include "base/test/simple_test_tick_clock.h"
112d899751069605306521f226144f7287be7ab2d1Johnny Chen#include "base/time/tick_clock.h"
122d899751069605306521f226144f7287be7ab2d1Johnny Chen#include "base/time/time.h"
132d899751069605306521f226144f7287be7ab2d1Johnny Chen#include "media/cast/logging/logging_defines.h"
14#include "media/cast/logging/logging_impl.h"
15#include "media/cast/logging/simple_event_subscriber.h"
16#include "testing/gtest/include/gtest/gtest.h"
17
18namespace media {
19namespace cast {
20
21// Insert frame duration- one second.
22const int64 kIntervalTime1S = 1;
23// Test frame rate goal - 30fps.
24const int kFrameIntervalMs = 33;
25
26static const int64 kStartMillisecond = INT64_C(12345678900000);
27
28class LoggingImplTest : public ::testing::Test {
29 protected:
30  LoggingImplTest() {
31    testing_clock_.Advance(
32        base::TimeDelta::FromMilliseconds(kStartMillisecond));
33    logging_.AddRawEventSubscriber(&event_subscriber_);
34  }
35
36  virtual ~LoggingImplTest() {
37    logging_.RemoveRawEventSubscriber(&event_subscriber_);
38  }
39
40  LoggingImpl logging_;
41  base::SimpleTestTickClock testing_clock_;
42  SimpleEventSubscriber event_subscriber_;
43
44  DISALLOW_COPY_AND_ASSIGN(LoggingImplTest);
45};
46
47TEST_F(LoggingImplTest, BasicFrameLogging) {
48  base::TimeTicks start_time = testing_clock_.NowTicks();
49  base::TimeDelta time_interval = testing_clock_.NowTicks() - start_time;
50  uint32 rtp_timestamp = 0;
51  uint32 frame_id = 0;
52  base::TimeTicks now;
53  do {
54    now = testing_clock_.NowTicks();
55    logging_.InsertFrameEvent(
56        now, FRAME_CAPTURE_BEGIN, VIDEO_EVENT, rtp_timestamp, frame_id);
57    testing_clock_.Advance(
58        base::TimeDelta::FromMilliseconds(kFrameIntervalMs));
59    rtp_timestamp += kFrameIntervalMs * 90;
60    ++frame_id;
61    time_interval = now - start_time;
62  }  while (time_interval.InSeconds() < kIntervalTime1S);
63
64  // Get logging data.
65  std::vector<FrameEvent> frame_events;
66  event_subscriber_.GetFrameEventsAndReset(&frame_events);
67  // Size of vector should be equal to the number of events logged,
68  // which equals to number of frames in this case.
69  EXPECT_EQ(frame_id, frame_events.size());
70}
71
72TEST_F(LoggingImplTest, FrameLoggingWithSize) {
73  // Average packet size.
74  const int kBaseFrameSizeBytes = 25000;
75  const int kRandomSizeInterval = 100;
76  base::TimeTicks start_time = testing_clock_.NowTicks();
77  base::TimeDelta time_interval = testing_clock_.NowTicks() - start_time;
78  uint32 rtp_timestamp = 0;
79  uint32 frame_id = 0;
80  size_t sum_size = 0;
81  int target_bitrate = 1234;
82  do {
83    int size = kBaseFrameSizeBytes +
84        base::RandInt(-kRandomSizeInterval, kRandomSizeInterval);
85    sum_size += static_cast<size_t>(size);
86    logging_.InsertEncodedFrameEvent(testing_clock_.NowTicks(),
87                                     FRAME_ENCODED, VIDEO_EVENT, rtp_timestamp,
88                                     frame_id, size, true, target_bitrate);
89    testing_clock_.Advance(base::TimeDelta::FromMilliseconds(kFrameIntervalMs));
90    rtp_timestamp += kFrameIntervalMs * 90;
91    ++frame_id;
92    time_interval = testing_clock_.NowTicks() - start_time;
93  } while (time_interval.InSeconds() < kIntervalTime1S);
94  // Get logging data.
95  std::vector<FrameEvent> frame_events;
96  event_subscriber_.GetFrameEventsAndReset(&frame_events);
97  // Size of vector should be equal to the number of events logged, which
98  // equals to number of frames in this case.
99  EXPECT_EQ(frame_id, frame_events.size());
100}
101
102TEST_F(LoggingImplTest, FrameLoggingWithDelay) {
103  // Average packet size.
104  const int kPlayoutDelayMs = 50;
105  const int kRandomSizeInterval = 20;
106  base::TimeTicks start_time = testing_clock_.NowTicks();
107  base::TimeDelta time_interval = testing_clock_.NowTicks() - start_time;
108  uint32 rtp_timestamp = 0;
109  uint32 frame_id = 0;
110  do {
111    int delay = kPlayoutDelayMs +
112                base::RandInt(-kRandomSizeInterval, kRandomSizeInterval);
113    logging_.InsertFrameEventWithDelay(
114        testing_clock_.NowTicks(),
115        FRAME_CAPTURE_BEGIN,
116        VIDEO_EVENT,
117        rtp_timestamp,
118        frame_id,
119        base::TimeDelta::FromMilliseconds(delay));
120    testing_clock_.Advance(base::TimeDelta::FromMilliseconds(kFrameIntervalMs));
121    rtp_timestamp += kFrameIntervalMs * 90;
122    ++frame_id;
123    time_interval = testing_clock_.NowTicks() - start_time;
124  } while (time_interval.InSeconds() < kIntervalTime1S);
125  // Get logging data.
126  std::vector<FrameEvent> frame_events;
127  event_subscriber_.GetFrameEventsAndReset(&frame_events);
128  // Size of vector should be equal to the number of frames logged.
129  EXPECT_EQ(frame_id, frame_events.size());
130}
131
132TEST_F(LoggingImplTest, MultipleEventFrameLogging) {
133  base::TimeTicks start_time = testing_clock_.NowTicks();
134  base::TimeDelta time_interval = testing_clock_.NowTicks() - start_time;
135  uint32 rtp_timestamp = 0u;
136  uint32 frame_id = 0u;
137  uint32 num_events = 0u;
138  do {
139    logging_.InsertFrameEvent(testing_clock_.NowTicks(),
140                              FRAME_CAPTURE_END,
141                              VIDEO_EVENT,
142                              rtp_timestamp,
143                              frame_id);
144    ++num_events;
145    if (frame_id % 2) {
146      logging_.InsertEncodedFrameEvent(testing_clock_.NowTicks(),
147                                       FRAME_ENCODED, AUDIO_EVENT,
148                                       rtp_timestamp,
149                                       frame_id, 1500, true, 0);
150    } else if (frame_id % 3) {
151      logging_.InsertFrameEvent(testing_clock_.NowTicks(), FRAME_DECODED,
152                                VIDEO_EVENT, rtp_timestamp, frame_id);
153    } else {
154      logging_.InsertFrameEventWithDelay(
155          testing_clock_.NowTicks(), FRAME_PLAYOUT, VIDEO_EVENT,
156          rtp_timestamp, frame_id, base::TimeDelta::FromMilliseconds(20));
157    }
158    ++num_events;
159
160    testing_clock_.Advance(base::TimeDelta::FromMilliseconds(kFrameIntervalMs));
161    rtp_timestamp += kFrameIntervalMs * 90;
162    ++frame_id;
163    time_interval = testing_clock_.NowTicks() - start_time;
164  } while (time_interval.InSeconds() < kIntervalTime1S);
165  // Get logging data.
166  std::vector<FrameEvent> frame_events;
167  event_subscriber_.GetFrameEventsAndReset(&frame_events);
168  // Size of vector should be equal to the number of frames logged.
169  EXPECT_EQ(num_events, frame_events.size());
170  // Multiple events captured per frame.
171}
172
173TEST_F(LoggingImplTest, PacketLogging) {
174  const int kNumPacketsPerFrame = 10;
175  const int kBaseSize = 2500;
176  const int kSizeInterval = 100;
177  base::TimeTicks start_time = testing_clock_.NowTicks();
178  base::TimeTicks latest_time;
179  base::TimeDelta time_interval = testing_clock_.NowTicks() - start_time;
180  RtpTimestamp rtp_timestamp = 0;
181  int frame_id = 0;
182  int num_packets = 0;
183  int sum_size = 0u;
184  do {
185    for (int i = 0; i < kNumPacketsPerFrame; ++i) {
186      int size = kBaseSize + base::RandInt(-kSizeInterval, kSizeInterval);
187      sum_size += size;
188      latest_time = testing_clock_.NowTicks();
189      ++num_packets;
190      logging_.InsertPacketEvent(latest_time,
191                                 PACKET_RECEIVED,
192                                 VIDEO_EVENT,
193                                 rtp_timestamp,
194                                 frame_id,
195                                 i,
196                                 kNumPacketsPerFrame,
197                                 size);
198    }
199    testing_clock_.Advance(base::TimeDelta::FromMilliseconds(kFrameIntervalMs));
200    rtp_timestamp += kFrameIntervalMs * 90;
201    ++frame_id;
202    time_interval = testing_clock_.NowTicks() - start_time;
203  } while (time_interval.InSeconds() < kIntervalTime1S);
204  // Get logging data.
205  std::vector<PacketEvent> packet_events;
206  event_subscriber_.GetPacketEventsAndReset(&packet_events);
207  // Size of vector should be equal to the number of packets logged.
208  EXPECT_EQ(num_packets, static_cast<int>(packet_events.size()));
209}
210
211TEST_F(LoggingImplTest, MultipleRawEventSubscribers) {
212  SimpleEventSubscriber event_subscriber_2;
213
214  // Now logging_ has two subscribers.
215  logging_.AddRawEventSubscriber(&event_subscriber_2);
216
217  logging_.InsertFrameEvent(testing_clock_.NowTicks(),
218                            FRAME_CAPTURE_BEGIN,
219                            VIDEO_EVENT,
220                            /*rtp_timestamp*/ 0u,
221                            /*frame_id*/ 0u);
222
223  std::vector<FrameEvent> frame_events;
224  event_subscriber_.GetFrameEventsAndReset(&frame_events);
225  EXPECT_EQ(1u, frame_events.size());
226  frame_events.clear();
227  event_subscriber_2.GetFrameEventsAndReset(&frame_events);
228  EXPECT_EQ(1u, frame_events.size());
229
230  logging_.RemoveRawEventSubscriber(&event_subscriber_2);
231}
232
233}  // namespace cast
234}  // namespace media
235