Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: media/cast/logging/stats_event_subscriber.cc

Issue 482383005: Cast logging: Additional stats for getStats() API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@REAL-NEW-MASTER
Patch Set: Rebase Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/cast/logging/stats_event_subscriber.h" 5 #include "media/cast/logging/stats_event_subscriber.h"
6 6
7 #include "base/format_macros.h"
7 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/strings/stringprintf.h"
8 #include "base/values.h" 10 #include "base/values.h"
9 11
10 #define STAT_ENUM_TO_STRING(enum) \ 12 #define STAT_ENUM_TO_STRING(enum) \
11 case enum: \ 13 case enum: \
12 return #enum 14 return #enum
13 15
14 namespace media { 16 namespace media {
15 namespace cast { 17 namespace cast {
16 18
17 namespace { 19 namespace {
18 20
19 using media::cast::CastLoggingEvent; 21 using media::cast::CastLoggingEvent;
20 using media::cast::EventMediaType; 22 using media::cast::EventMediaType;
21 23
22 const size_t kMaxPacketEventTimeMapSize = 1000; 24 const size_t kMaxPacketEventTimeMapSize = 1000;
23 25
24 bool IsReceiverEvent(CastLoggingEvent event) { 26 bool IsReceiverEvent(CastLoggingEvent event) {
25 return event == FRAME_DECODED 27 return event == FRAME_DECODED
26 || event == FRAME_PLAYOUT 28 || event == FRAME_PLAYOUT
27 || event == FRAME_ACK_SENT 29 || event == FRAME_ACK_SENT
28 || event == PACKET_RECEIVED; 30 || event == PACKET_RECEIVED;
29 } 31 }
30 32
31 } // namespace 33 } // namespace
32 34
35 StatsEventSubscriber::SimpleHistogram::SimpleHistogram(int64 min,
36 int64 max,
37 int64 width)
38 : min_(min), max_(max), width_(width), buckets_((max - min) / width + 2) {
39 CHECK_GT(buckets_.size(), 2u);
40 CHECK_EQ(0, (max_ - min_) % width_);
41 }
42
43 StatsEventSubscriber::SimpleHistogram::~SimpleHistogram() {
44 }
45
46 void StatsEventSubscriber::SimpleHistogram::Add(int64 sample) {
47 if (sample < min_) {
48 ++buckets_.front();
49 } else if (sample >= max_) {
50 ++buckets_.back();
51 } else {
52 size_t index = 1 + (sample - min_) / width_;
53 DCHECK_LT(index, buckets_.size());
54 ++buckets_[index];
55 }
56 }
57
58 void StatsEventSubscriber::SimpleHistogram::Reset() {
59 buckets_.assign(buckets_.size(), 0);
60 }
61
62 scoped_ptr<base::ListValue>
63 StatsEventSubscriber::SimpleHistogram::GetHistogram() const {
64 scoped_ptr<base::ListValue> histo(new base::ListValue);
65
66 scoped_ptr<base::DictionaryValue> bucket(new base::DictionaryValue);
67
68 bucket->SetString("bucket", base::StringPrintf("< %" PRId64, min_));
69 bucket->SetInteger("count", buckets_.front());
70 histo->Append(bucket.release());
71
72 for (size_t i = 1; i < buckets_.size() - 1; i++) {
73 bucket.reset(new base::DictionaryValue);
74
75 int64 lower = min_ + (i - 1) * width_;
76 int64 upper = lower + width_ - 1;
77 bucket->SetString(
78 "bucket", base::StringPrintf("%" PRId64 " - %" PRId64, lower, upper));
79 bucket->SetInteger("count", buckets_[i]);
80 histo->Append(bucket.release());
81 }
82
83 bucket.reset(new base::DictionaryValue);
84
85 bucket->SetString("bucket", base::StringPrintf(">= %" PRId64, max_));
86 bucket->SetInteger("count", buckets_.back());
87 histo->Append(bucket.release());
88
89 return histo.Pass();
90 }
91
33 StatsEventSubscriber::StatsEventSubscriber( 92 StatsEventSubscriber::StatsEventSubscriber(
34 EventMediaType event_media_type, 93 EventMediaType event_media_type,
35 base::TickClock* clock, 94 base::TickClock* clock,
36 ReceiverTimeOffsetEstimator* offset_estimator) 95 ReceiverTimeOffsetEstimator* offset_estimator)
37 : event_media_type_(event_media_type), 96 : event_media_type_(event_media_type),
38 clock_(clock), 97 clock_(clock),
39 offset_estimator_(offset_estimator), 98 offset_estimator_(offset_estimator),
40 network_latency_datapoints_(0), 99 network_latency_datapoints_(0),
41 e2e_latency_datapoints_(0), 100 e2e_latency_datapoints_(0),
42 num_frames_dropped_by_encoder_(0), 101 num_frames_dropped_by_encoder_(0),
43 num_frames_late_(0) { 102 num_frames_late_(0),
103 start_time_(clock_->NowTicks()) {
44 DCHECK(event_media_type == AUDIO_EVENT || event_media_type == VIDEO_EVENT); 104 DCHECK(event_media_type == AUDIO_EVENT || event_media_type == VIDEO_EVENT);
45 base::TimeTicks now = clock_->NowTicks(); 105
46 start_time_ = now; 106 InitHistograms();
47 last_response_received_time_ = base::TimeTicks();
48 } 107 }
49 108
50 StatsEventSubscriber::~StatsEventSubscriber() { 109 StatsEventSubscriber::~StatsEventSubscriber() {
51 DCHECK(thread_checker_.CalledOnValidThread()); 110 DCHECK(thread_checker_.CalledOnValidThread());
52 } 111 }
53 112
54 void StatsEventSubscriber::OnReceiveFrameEvent(const FrameEvent& frame_event) { 113 void StatsEventSubscriber::OnReceiveFrameEvent(const FrameEvent& frame_event) {
55 DCHECK(thread_checker_.CalledOnValidThread()); 114 DCHECK(thread_checker_.CalledOnValidThread());
56 115
57 CastLoggingEvent type = frame_event.type; 116 CastLoggingEvent type = frame_event.type;
58 if (frame_event.media_type != event_media_type_) 117 if (frame_event.media_type != event_media_type_)
59 return; 118 return;
60 119
61 FrameStatsMap::iterator it = frame_stats_.find(type); 120 FrameStatsMap::iterator it = frame_stats_.find(type);
62 if (it == frame_stats_.end()) { 121 if (it == frame_stats_.end()) {
63 FrameLogStats stats; 122 FrameLogStats stats;
64 stats.event_counter = 1; 123 stats.event_counter = 1;
65 stats.sum_size = frame_event.size; 124 stats.sum_size = frame_event.size;
66 stats.sum_delay = frame_event.delay_delta; 125 stats.sum_delay = frame_event.delay_delta;
67 frame_stats_.insert(std::make_pair(type, stats)); 126 frame_stats_.insert(std::make_pair(type, stats));
68 } else { 127 } else {
69 ++(it->second.event_counter); 128 ++(it->second.event_counter);
70 it->second.sum_size += frame_event.size; 129 it->second.sum_size += frame_event.size;
71 it->second.sum_delay += frame_event.delay_delta; 130 it->second.sum_delay += frame_event.delay_delta;
72 } 131 }
73 132
133 bool is_receiver_event = IsReceiverEvent(type);
134 UpdateFirstLastEventTime(frame_event.timestamp, is_receiver_event);
135
74 if (type == FRAME_CAPTURE_BEGIN) { 136 if (type == FRAME_CAPTURE_BEGIN) {
75 RecordFrameCaptureTime(frame_event); 137 RecordFrameCaptureTime(frame_event);
138 } else if (type == FRAME_CAPTURE_END) {
139 RecordCaptureLatency(frame_event);
76 } else if (type == FRAME_ENCODED) { 140 } else if (type == FRAME_ENCODED) {
77 MarkAsEncoded(frame_event.rtp_timestamp); 141 RecordEncodeLatency(frame_event);
142 } else if (type == FRAME_ACK_SENT) {
143 RecordFrameTxLatency(frame_event);
78 } else if (type == FRAME_PLAYOUT) { 144 } else if (type == FRAME_PLAYOUT) {
79 RecordE2ELatency(frame_event); 145 RecordE2ELatency(frame_event);
80 if (frame_event.delay_delta <= base::TimeDelta()) 146 base::TimeDelta delay_delta = frame_event.delay_delta;
147 histograms_[PLAYOUT_DELAY_MS_HISTO]->Add(delay_delta.InMillisecondsF());
148 if (delay_delta <= base::TimeDelta())
81 num_frames_late_++; 149 num_frames_late_++;
82 } 150 }
83 151
84 if (IsReceiverEvent(type)) 152 if (is_receiver_event)
85 UpdateLastResponseTime(frame_event.timestamp); 153 UpdateLastResponseTime(frame_event.timestamp);
86 } 154 }
87 155
88 void StatsEventSubscriber::OnReceivePacketEvent( 156 void StatsEventSubscriber::OnReceivePacketEvent(
89 const PacketEvent& packet_event) { 157 const PacketEvent& packet_event) {
90 DCHECK(thread_checker_.CalledOnValidThread()); 158 DCHECK(thread_checker_.CalledOnValidThread());
91 159
92 CastLoggingEvent type = packet_event.type; 160 CastLoggingEvent type = packet_event.type;
93 if (packet_event.media_type != event_media_type_) 161 if (packet_event.media_type != event_media_type_)
94 return; 162 return;
95 163
96 PacketStatsMap::iterator it = packet_stats_.find(type); 164 PacketStatsMap::iterator it = packet_stats_.find(type);
97 if (it == packet_stats_.end()) { 165 if (it == packet_stats_.end()) {
98 PacketLogStats stats; 166 PacketLogStats stats;
99 stats.event_counter = 1; 167 stats.event_counter = 1;
100 stats.sum_size = packet_event.size; 168 stats.sum_size = packet_event.size;
101 packet_stats_.insert(std::make_pair(type, stats)); 169 packet_stats_.insert(std::make_pair(type, stats));
102 } else { 170 } else {
103 ++(it->second.event_counter); 171 ++(it->second.event_counter);
104 it->second.sum_size += packet_event.size; 172 it->second.sum_size += packet_event.size;
105 } 173 }
106 174
175 bool is_receiver_event = IsReceiverEvent(type);
176 UpdateFirstLastEventTime(packet_event.timestamp, is_receiver_event);
177
107 if (type == PACKET_SENT_TO_NETWORK || 178 if (type == PACKET_SENT_TO_NETWORK ||
108 type == PACKET_RECEIVED) { 179 type == PACKET_RECEIVED) {
109 RecordNetworkLatency(packet_event); 180 RecordNetworkLatency(packet_event);
110 } else if (type == PACKET_RETRANSMITTED) { 181 } else if (type == PACKET_RETRANSMITTED) {
111 // We only measure network latency using packets that doesn't have to be 182 // We only measure network latency using packets that doesn't have to be
112 // retransmitted as there is precisely one sent-receive timestamp pairs. 183 // retransmitted as there is precisely one sent-receive timestamp pairs.
113 ErasePacketSentTime(packet_event); 184 ErasePacketSentTime(packet_event);
114 } 185 }
115 186
116 if (IsReceiverEvent(type)) 187 if (is_receiver_event)
117 UpdateLastResponseTime(packet_event.timestamp); 188 UpdateLastResponseTime(packet_event.timestamp);
118 } 189 }
119 190
191 void StatsEventSubscriber::UpdateFirstLastEventTime(base::TimeTicks timestamp,
192 bool is_receiver_event) {
193 if (is_receiver_event) {
194 base::TimeDelta receiver_offset;
195 if (!GetReceiverOffset(&receiver_offset))
196 return;
197 timestamp -= receiver_offset;
198 }
199
200 if (first_event_time_.is_null()) {
201 first_event_time_ = timestamp;
202 } else {
203 first_event_time_ = std::min(first_event_time_, timestamp);
204 }
205 if (last_event_time_.is_null()) {
206 last_event_time_ = timestamp;
207 } else {
208 last_event_time_ = std::max(last_event_time_, timestamp);
209 }
210 }
211
120 scoped_ptr<base::DictionaryValue> StatsEventSubscriber::GetStats() const { 212 scoped_ptr<base::DictionaryValue> StatsEventSubscriber::GetStats() const {
121 StatsMap stats_map; 213 StatsMap stats_map;
122 GetStatsInternal(&stats_map); 214 GetStatsInternal(&stats_map);
123 scoped_ptr<base::DictionaryValue> ret(new base::DictionaryValue); 215 scoped_ptr<base::DictionaryValue> ret(new base::DictionaryValue);
124 216
125 scoped_ptr<base::DictionaryValue> stats(new base::DictionaryValue); 217 scoped_ptr<base::DictionaryValue> stats(new base::DictionaryValue);
126 for (StatsMap::const_iterator it = stats_map.begin(); it != stats_map.end(); 218 for (StatsMap::const_iterator it = stats_map.begin(); it != stats_map.end();
127 ++it) { 219 ++it) {
128 stats->SetDouble(CastStatToString(it->first), it->second); 220 stats->SetDouble(CastStatToString(it->first), it->second);
129 } 221 }
222 for (HistogramMap::const_iterator it = histograms_.begin();
223 it != histograms_.end();
224 ++it) {
225 stats->Set(CastStatToString(it->first),
226 it->second->GetHistogram().release());
227 }
130 228
131 ret->Set(event_media_type_ == AUDIO_EVENT ? "audio" : "video", 229 ret->Set(event_media_type_ == AUDIO_EVENT ? "audio" : "video",
132 stats.release()); 230 stats.release());
133 231
134 return ret.Pass(); 232 return ret.Pass();
135 } 233 }
136 234
137 void StatsEventSubscriber::Reset() { 235 void StatsEventSubscriber::Reset() {
138 DCHECK(thread_checker_.CalledOnValidThread()); 236 DCHECK(thread_checker_.CalledOnValidThread());
139 237
140 frame_stats_.clear(); 238 frame_stats_.clear();
141 packet_stats_.clear(); 239 packet_stats_.clear();
142 total_network_latency_ = base::TimeDelta(); 240 total_network_latency_ = base::TimeDelta();
143 network_latency_datapoints_ = 0; 241 network_latency_datapoints_ = 0;
144 total_e2e_latency_ = base::TimeDelta(); 242 total_e2e_latency_ = base::TimeDelta();
145 e2e_latency_datapoints_ = 0; 243 e2e_latency_datapoints_ = 0;
146 num_frames_dropped_by_encoder_ = 0; 244 num_frames_dropped_by_encoder_ = 0;
147 num_frames_late_ = 0; 245 num_frames_late_ = 0;
148 recent_captured_frames_.clear(); 246 recent_frame_infos_.clear();
149 packet_sent_times_.clear(); 247 packet_sent_times_.clear();
150 start_time_ = clock_->NowTicks(); 248 start_time_ = clock_->NowTicks();
151 last_response_received_time_ = base::TimeTicks(); 249 last_response_received_time_ = base::TimeTicks();
250 for (HistogramMap::iterator it = histograms_.begin(); it != histograms_.end();
251 ++it) {
252 it->second->Reset();
253 }
254
255 first_event_time_ = base::TimeTicks();
256 last_event_time_ = base::TimeTicks();
152 } 257 }
153 258
154 // static 259 // static
155 const char* StatsEventSubscriber::CastStatToString(CastStat stat) { 260 const char* StatsEventSubscriber::CastStatToString(CastStat stat) {
156 switch (stat) { 261 switch (stat) {
157 STAT_ENUM_TO_STRING(CAPTURE_FPS); 262 STAT_ENUM_TO_STRING(CAPTURE_FPS);
158 STAT_ENUM_TO_STRING(ENCODE_FPS); 263 STAT_ENUM_TO_STRING(ENCODE_FPS);
159 STAT_ENUM_TO_STRING(DECODE_FPS); 264 STAT_ENUM_TO_STRING(DECODE_FPS);
160 STAT_ENUM_TO_STRING(AVG_ENCODE_TIME_MS); 265 STAT_ENUM_TO_STRING(AVG_ENCODE_TIME_MS);
161 STAT_ENUM_TO_STRING(AVG_PLAYOUT_DELAY_MS); 266 STAT_ENUM_TO_STRING(AVG_PLAYOUT_DELAY_MS);
162 STAT_ENUM_TO_STRING(AVG_NETWORK_LATENCY_MS); 267 STAT_ENUM_TO_STRING(AVG_NETWORK_LATENCY_MS);
163 STAT_ENUM_TO_STRING(AVG_E2E_LATENCY_MS); 268 STAT_ENUM_TO_STRING(AVG_E2E_LATENCY_MS);
164 STAT_ENUM_TO_STRING(ENCODE_KBPS); 269 STAT_ENUM_TO_STRING(ENCODE_KBPS);
165 STAT_ENUM_TO_STRING(TRANSMISSION_KBPS); 270 STAT_ENUM_TO_STRING(TRANSMISSION_KBPS);
166 STAT_ENUM_TO_STRING(RETRANSMISSION_KBPS); 271 STAT_ENUM_TO_STRING(RETRANSMISSION_KBPS);
167 STAT_ENUM_TO_STRING(PACKET_LOSS_FRACTION); 272 STAT_ENUM_TO_STRING(PACKET_LOSS_FRACTION);
168 STAT_ENUM_TO_STRING(MS_SINCE_LAST_RECEIVER_RESPONSE); 273 STAT_ENUM_TO_STRING(MS_SINCE_LAST_RECEIVER_RESPONSE);
169 STAT_ENUM_TO_STRING(NUM_FRAMES_CAPTURED); 274 STAT_ENUM_TO_STRING(NUM_FRAMES_CAPTURED);
170 STAT_ENUM_TO_STRING(NUM_FRAMES_DROPPED_BY_ENCODER); 275 STAT_ENUM_TO_STRING(NUM_FRAMES_DROPPED_BY_ENCODER);
171 STAT_ENUM_TO_STRING(NUM_FRAMES_LATE); 276 STAT_ENUM_TO_STRING(NUM_FRAMES_LATE);
172 STAT_ENUM_TO_STRING(NUM_PACKETS_SENT); 277 STAT_ENUM_TO_STRING(NUM_PACKETS_SENT);
173 STAT_ENUM_TO_STRING(NUM_PACKETS_RETRANSMITTED); 278 STAT_ENUM_TO_STRING(NUM_PACKETS_RETRANSMITTED);
174 STAT_ENUM_TO_STRING(NUM_PACKETS_RTX_REJECTED); 279 STAT_ENUM_TO_STRING(NUM_PACKETS_RTX_REJECTED);
280 STAT_ENUM_TO_STRING(FIRST_EVENT_TIME_MS);
281 STAT_ENUM_TO_STRING(LAST_EVENT_TIME_MS);
282 STAT_ENUM_TO_STRING(CAPTURE_LATENCY_MS_HISTO);
283 STAT_ENUM_TO_STRING(ENCODE_LATENCY_MS_HISTO);
284 STAT_ENUM_TO_STRING(PACKET_LATENCY_MS_HISTO);
285 STAT_ENUM_TO_STRING(FRAME_LATENCY_MS_HISTO);
286 STAT_ENUM_TO_STRING(PLAYOUT_DELAY_MS_HISTO);
175 } 287 }
176 NOTREACHED(); 288 NOTREACHED();
177 return ""; 289 return "";
178 } 290 }
179 291
292 const int kMaxLatencyBucketMs = 800;
293 const int kBucketWidthMs = 20;
294
295 void StatsEventSubscriber::InitHistograms() {
296 histograms_[CAPTURE_LATENCY_MS_HISTO].reset(
297 new SimpleHistogram(0, kMaxLatencyBucketMs, kBucketWidthMs));
298 histograms_[ENCODE_LATENCY_MS_HISTO].reset(
299 new SimpleHistogram(0, kMaxLatencyBucketMs, kBucketWidthMs));
300 histograms_[PACKET_LATENCY_MS_HISTO].reset(
301 new SimpleHistogram(0, kMaxLatencyBucketMs, kBucketWidthMs));
302 histograms_[FRAME_LATENCY_MS_HISTO].reset(
303 new SimpleHistogram(0, kMaxLatencyBucketMs, kBucketWidthMs));
304 histograms_[PLAYOUT_DELAY_MS_HISTO].reset(
305 new SimpleHistogram(0, kMaxLatencyBucketMs, kBucketWidthMs));
306 }
307
180 void StatsEventSubscriber::GetStatsInternal(StatsMap* stats_map) const { 308 void StatsEventSubscriber::GetStatsInternal(StatsMap* stats_map) const {
181 DCHECK(thread_checker_.CalledOnValidThread()); 309 DCHECK(thread_checker_.CalledOnValidThread());
182 310
183 stats_map->clear(); 311 stats_map->clear();
184 312
185 base::TimeTicks end_time = clock_->NowTicks(); 313 base::TimeTicks end_time = clock_->NowTicks();
186 314
187 PopulateFpsStat( 315 PopulateFpsStat(
188 end_time, FRAME_CAPTURE_BEGIN, CAPTURE_FPS, stats_map); 316 end_time, FRAME_CAPTURE_BEGIN, CAPTURE_FPS, stats_map);
189 PopulateFpsStat( 317 PopulateFpsStat(
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 352
225 if (!last_response_received_time_.is_null()) { 353 if (!last_response_received_time_.is_null()) {
226 stats_map->insert( 354 stats_map->insert(
227 std::make_pair(MS_SINCE_LAST_RECEIVER_RESPONSE, 355 std::make_pair(MS_SINCE_LAST_RECEIVER_RESPONSE,
228 (end_time - last_response_received_time_).InMillisecondsF())); 356 (end_time - last_response_received_time_).InMillisecondsF()));
229 } 357 }
230 358
231 stats_map->insert(std::make_pair(NUM_FRAMES_DROPPED_BY_ENCODER, 359 stats_map->insert(std::make_pair(NUM_FRAMES_DROPPED_BY_ENCODER,
232 num_frames_dropped_by_encoder_)); 360 num_frames_dropped_by_encoder_));
233 stats_map->insert(std::make_pair(NUM_FRAMES_LATE, num_frames_late_)); 361 stats_map->insert(std::make_pair(NUM_FRAMES_LATE, num_frames_late_));
362 if (!first_event_time_.is_null()) {
363 stats_map->insert(std::make_pair(
364 FIRST_EVENT_TIME_MS,
365 (first_event_time_ - base::TimeTicks::UnixEpoch()).InMillisecondsF()));
366 }
367 if (!last_event_time_.is_null()) {
368 stats_map->insert(std::make_pair(
369 LAST_EVENT_TIME_MS,
370 (last_event_time_ - base::TimeTicks::UnixEpoch()).InMillisecondsF()));
371 }
234 } 372 }
235 373
236 bool StatsEventSubscriber::GetReceiverOffset(base::TimeDelta* offset) { 374 bool StatsEventSubscriber::GetReceiverOffset(base::TimeDelta* offset) {
237 base::TimeDelta receiver_offset_lower_bound; 375 base::TimeDelta receiver_offset_lower_bound;
238 base::TimeDelta receiver_offset_upper_bound; 376 base::TimeDelta receiver_offset_upper_bound;
239 if (!offset_estimator_->GetReceiverOffsetBounds( 377 if (!offset_estimator_->GetReceiverOffsetBounds(
240 &receiver_offset_lower_bound, &receiver_offset_upper_bound)) { 378 &receiver_offset_lower_bound, &receiver_offset_upper_bound)) {
241 return false; 379 return false;
242 } 380 }
243 381
244 *offset = (receiver_offset_lower_bound + receiver_offset_upper_bound) / 2; 382 *offset = (receiver_offset_lower_bound + receiver_offset_upper_bound) / 2;
245 return true; 383 return true;
246 } 384 }
247 385
386 void StatsEventSubscriber::MaybeInsertFrameInfo(RtpTimestamp rtp_timestamp,
387 const FrameInfo& frame_info) {
388 // No need to insert if |rtp_timestamp| is the smaller than every key in the
389 // map as it is just going to get erased anyway.
390 if (recent_frame_infos_.size() == kMaxFrameInfoMapSize &&
391 rtp_timestamp < recent_frame_infos_.begin()->first) {
392 return;
393 }
394
395 recent_frame_infos_.insert(std::make_pair(rtp_timestamp, frame_info));
396
397 if (recent_frame_infos_.size() >= kMaxFrameInfoMapSize) {
398 FrameInfoMap::iterator erase_it = recent_frame_infos_.begin();
399 if (erase_it->second.encode_time.is_null())
400 num_frames_dropped_by_encoder_++;
401 recent_frame_infos_.erase(erase_it);
402 }
403 }
404
248 void StatsEventSubscriber::RecordFrameCaptureTime( 405 void StatsEventSubscriber::RecordFrameCaptureTime(
249 const FrameEvent& frame_event) { 406 const FrameEvent& frame_event) {
250 recent_captured_frames_.insert(std::make_pair( 407 FrameInfo frame_info;
251 frame_event.rtp_timestamp, FrameInfo(frame_event.timestamp))); 408 frame_info.capture_time = frame_event.timestamp;
252 if (recent_captured_frames_.size() > kMaxFrameInfoMapSize) { 409 MaybeInsertFrameInfo(frame_event.rtp_timestamp, frame_info);
253 FrameInfoMap::iterator erase_it = recent_captured_frames_.begin();
254 if (!erase_it->second.encoded)
255 num_frames_dropped_by_encoder_++;
256 recent_captured_frames_.erase(erase_it);
257 }
258 } 410 }
259 411
260 void StatsEventSubscriber::MarkAsEncoded(RtpTimestamp rtp_timestamp) { 412 void StatsEventSubscriber::RecordCaptureLatency(const FrameEvent& frame_event) {
261 FrameInfoMap::iterator it = recent_captured_frames_.find(rtp_timestamp); 413 FrameInfoMap::iterator it =
262 if (it != recent_captured_frames_.end()) 414 recent_frame_infos_.find(frame_event.rtp_timestamp);
263 it->second.encoded = true; 415 if (it == recent_frame_infos_.end())
416 return;
417
418 if (!it->second.capture_time.is_null()) {
419 double capture_latency_ms =
420 (it->second.capture_time - frame_event.timestamp).InMillisecondsF();
421 histograms_[CAPTURE_LATENCY_MS_HISTO]->Add(capture_latency_ms);
422 }
423
424 it->second.capture_end_time = frame_event.timestamp;
425 }
426
427 void StatsEventSubscriber::RecordEncodeLatency(const FrameEvent& frame_event) {
428 FrameInfoMap::iterator it =
429 recent_frame_infos_.find(frame_event.rtp_timestamp);
430 if (it == recent_frame_infos_.end()) {
431 FrameInfo frame_info;
432 frame_info.encode_time = frame_event.timestamp;
433 MaybeInsertFrameInfo(frame_event.rtp_timestamp, frame_info);
434 return;
435 }
436
437 if (!it->second.capture_end_time.is_null()) {
438 double encode_latency_ms =
439 (frame_event.timestamp - it->second.capture_end_time).InMillisecondsF();
440 histograms_[ENCODE_LATENCY_MS_HISTO]->Add(encode_latency_ms);
441 }
442
443 it->second.encode_time = frame_event.timestamp;
444 }
445
446 void StatsEventSubscriber::RecordFrameTxLatency(const FrameEvent& frame_event) {
447 FrameInfoMap::iterator it =
448 recent_frame_infos_.find(frame_event.rtp_timestamp);
449 if (it == recent_frame_infos_.end())
450 return;
451
452 if (it->second.encode_time.is_null())
453 return;
454
455 base::TimeDelta receiver_offset;
456 if (!GetReceiverOffset(&receiver_offset))
457 return;
458
459 base::TimeTicks sender_time = frame_event.timestamp - receiver_offset;
460 double frame_tx_latency_ms =
461 (sender_time - it->second.encode_time).InMillisecondsF();
462 histograms_[FRAME_LATENCY_MS_HISTO]->Add(frame_tx_latency_ms);
264 } 463 }
265 464
266 void StatsEventSubscriber::RecordE2ELatency(const FrameEvent& frame_event) { 465 void StatsEventSubscriber::RecordE2ELatency(const FrameEvent& frame_event) {
267 base::TimeDelta receiver_offset; 466 base::TimeDelta receiver_offset;
268 if (!GetReceiverOffset(&receiver_offset)) 467 if (!GetReceiverOffset(&receiver_offset))
269 return; 468 return;
270 469
271 FrameInfoMap::iterator it = 470 FrameInfoMap::iterator it =
272 recent_captured_frames_.find(frame_event.rtp_timestamp); 471 recent_frame_infos_.find(frame_event.rtp_timestamp);
273 if (it == recent_captured_frames_.end()) 472 if (it == recent_frame_infos_.end())
274 return; 473 return;
275 474
276 // Playout time is event time + playout delay. 475 // Playout time is event time + playout delay.
277 base::TimeTicks playout_time = 476 base::TimeTicks playout_time =
278 frame_event.timestamp + frame_event.delay_delta - receiver_offset; 477 frame_event.timestamp + frame_event.delay_delta - receiver_offset;
279 total_e2e_latency_ += playout_time - it->second.capture_time; 478 total_e2e_latency_ += playout_time - it->second.capture_time;
280 e2e_latency_datapoints_++; 479 e2e_latency_datapoints_++;
281 } 480 }
282 481
283 void StatsEventSubscriber::UpdateLastResponseTime( 482 void StatsEventSubscriber::UpdateLastResponseTime(
(...skipping 15 matching lines...) Expand all
299 void StatsEventSubscriber::RecordNetworkLatency( 498 void StatsEventSubscriber::RecordNetworkLatency(
300 const PacketEvent& packet_event) { 499 const PacketEvent& packet_event) {
301 base::TimeDelta receiver_offset; 500 base::TimeDelta receiver_offset;
302 if (!GetReceiverOffset(&receiver_offset)) 501 if (!GetReceiverOffset(&receiver_offset))
303 return; 502 return;
304 503
305 std::pair<RtpTimestamp, uint16> key( 504 std::pair<RtpTimestamp, uint16> key(
306 std::make_pair(packet_event.rtp_timestamp, packet_event.packet_id)); 505 std::make_pair(packet_event.rtp_timestamp, packet_event.packet_id));
307 PacketEventTimeMap::iterator it = packet_sent_times_.find(key); 506 PacketEventTimeMap::iterator it = packet_sent_times_.find(key);
308 if (it == packet_sent_times_.end()) { 507 if (it == packet_sent_times_.end()) {
309 std::pair<RtpTimestamp, uint16> key(
310 std::make_pair(packet_event.rtp_timestamp, packet_event.packet_id));
311 std::pair<base::TimeTicks, CastLoggingEvent> value = 508 std::pair<base::TimeTicks, CastLoggingEvent> value =
312 std::make_pair(packet_event.timestamp, packet_event.type); 509 std::make_pair(packet_event.timestamp, packet_event.type);
313 packet_sent_times_.insert(std::make_pair(key, value)); 510 packet_sent_times_.insert(std::make_pair(key, value));
314 if (packet_sent_times_.size() > kMaxPacketEventTimeMapSize) 511 if (packet_sent_times_.size() > kMaxPacketEventTimeMapSize)
315 packet_sent_times_.erase(packet_sent_times_.begin()); 512 packet_sent_times_.erase(packet_sent_times_.begin());
316 } else { 513 } else {
317 std::pair<base::TimeTicks, CastLoggingEvent> value = it->second; 514 std::pair<base::TimeTicks, CastLoggingEvent> value = it->second;
318 CastLoggingEvent recorded_type = value.second; 515 CastLoggingEvent recorded_type = value.second;
319 bool match = false; 516 bool match = false;
320 base::TimeTicks packet_sent_time; 517 base::TimeTicks packet_sent_time;
321 base::TimeTicks packet_received_time; 518 base::TimeTicks packet_received_time;
322 if (recorded_type == PACKET_SENT_TO_NETWORK && 519 if (recorded_type == PACKET_SENT_TO_NETWORK &&
323 packet_event.type == PACKET_RECEIVED) { 520 packet_event.type == PACKET_RECEIVED) {
324 packet_sent_time = value.first; 521 packet_sent_time = value.first;
325 packet_received_time = packet_event.timestamp; 522 packet_received_time = packet_event.timestamp;
326 match = true; 523 match = true;
327 } else if (recorded_type == PACKET_RECEIVED && 524 } else if (recorded_type == PACKET_RECEIVED &&
328 packet_event.type == PACKET_SENT_TO_NETWORK) { 525 packet_event.type == PACKET_SENT_TO_NETWORK) {
329 packet_sent_time = packet_event.timestamp; 526 packet_sent_time = packet_event.timestamp;
330 packet_received_time = value.first; 527 packet_received_time = value.first;
331 match = true; 528 match = true;
332 } 529 }
333 if (match) { 530 if (match) {
334 // Subtract by offset. 531 // Subtract by offset.
335 packet_received_time -= receiver_offset; 532 packet_received_time -= receiver_offset;
533 base::TimeDelta latency_delta = packet_received_time - packet_sent_time;
336 534
337 total_network_latency_ += packet_received_time - packet_sent_time; 535 total_network_latency_ += latency_delta;
338 network_latency_datapoints_++; 536 network_latency_datapoints_++;
537
538 histograms_[PACKET_LATENCY_MS_HISTO]->Add(
539 latency_delta.InMillisecondsF());
540
339 packet_sent_times_.erase(it); 541 packet_sent_times_.erase(it);
340 } 542 }
341 } 543 }
342 } 544 }
343 545
344 void StatsEventSubscriber::PopulateFpsStat(base::TimeTicks end_time, 546 void StatsEventSubscriber::PopulateFpsStat(base::TimeTicks end_time,
345 CastLoggingEvent event, 547 CastLoggingEvent event,
346 CastStat stat, 548 CastStat stat,
347 StatsMap* stats_map) const { 549 StatsMap* stats_map) const {
348 FrameStatsMap::const_iterator it = frame_stats_.find(event); 550 FrameStatsMap::const_iterator it = frame_stats_.find(event);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 } 642 }
441 643
442 StatsEventSubscriber::FrameLogStats::FrameLogStats() 644 StatsEventSubscriber::FrameLogStats::FrameLogStats()
443 : event_counter(0), sum_size(0) {} 645 : event_counter(0), sum_size(0) {}
444 StatsEventSubscriber::FrameLogStats::~FrameLogStats() {} 646 StatsEventSubscriber::FrameLogStats::~FrameLogStats() {}
445 647
446 StatsEventSubscriber::PacketLogStats::PacketLogStats() 648 StatsEventSubscriber::PacketLogStats::PacketLogStats()
447 : event_counter(0), sum_size(0) {} 649 : event_counter(0), sum_size(0) {}
448 StatsEventSubscriber::PacketLogStats::~PacketLogStats() {} 650 StatsEventSubscriber::PacketLogStats::~PacketLogStats() {}
449 651
450 StatsEventSubscriber::FrameInfo::FrameInfo(base::TimeTicks capture_time) 652 StatsEventSubscriber::FrameInfo::FrameInfo() : encoded(false) {
451 : capture_time(capture_time), encoded(false) {
452 } 653 }
453 StatsEventSubscriber::FrameInfo::~FrameInfo() { 654 StatsEventSubscriber::FrameInfo::~FrameInfo() {
454 } 655 }
455 656
456 } // namespace cast 657 } // namespace cast
457 } // namespace media 658 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/logging/stats_event_subscriber.h ('k') | media/cast/logging/stats_event_subscriber_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698