1// Copyright 2014 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 <stdint.h> 6 7#include <vector> 8 9#include "base/rand_util.h" 10#include "base/test/simple_test_tick_clock.h" 11#include "base/time/tick_clock.h" 12#include "base/time/time.h" 13#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