| Index: media/cast/logging/stats_event_subscriber.cc
|
| diff --git a/media/cast/logging/stats_event_subscriber.cc b/media/cast/logging/stats_event_subscriber.cc
|
| index 9e3226a21616d522ff8261defaaa31df49138e12..03c669cfcbcf4e2a0173079fdae6fbdc1b7426e1 100644
|
| --- a/media/cast/logging/stats_event_subscriber.cc
|
| +++ b/media/cast/logging/stats_event_subscriber.cc
|
| @@ -19,7 +19,6 @@ namespace {
|
| using media::cast::CastLoggingEvent;
|
| using media::cast::EventMediaType;
|
|
|
| -const size_t kMaxFrameEventTimeMapSize = 100;
|
| const size_t kMaxPacketEventTimeMapSize = 1000;
|
|
|
| bool IsReceiverEvent(CastLoggingEvent event) {
|
| @@ -39,7 +38,9 @@ StatsEventSubscriber::StatsEventSubscriber(
|
| clock_(clock),
|
| offset_estimator_(offset_estimator),
|
| network_latency_datapoints_(0),
|
| - e2e_latency_datapoints_(0) {
|
| + e2e_latency_datapoints_(0),
|
| + num_frames_dropped_by_encoder_(0),
|
| + num_frames_late_(0) {
|
| DCHECK(event_media_type == AUDIO_EVENT || event_media_type == VIDEO_EVENT);
|
| base::TimeTicks now = clock_->NowTicks();
|
| start_time_ = now;
|
| @@ -71,9 +72,13 @@ void StatsEventSubscriber::OnReceiveFrameEvent(const FrameEvent& frame_event) {
|
| }
|
|
|
| if (type == FRAME_CAPTURE_BEGIN) {
|
| - RecordFrameCapturedTime(frame_event);
|
| + RecordFrameCaptureTime(frame_event);
|
| + } else if (type == FRAME_ENCODED) {
|
| + MarkAsEncoded(frame_event.rtp_timestamp);
|
| } else if (type == FRAME_PLAYOUT) {
|
| RecordE2ELatency(frame_event);
|
| + if (frame_event.delay_delta <= base::TimeDelta())
|
| + num_frames_late_++;
|
| }
|
|
|
| if (IsReceiverEvent(type))
|
| @@ -138,7 +143,9 @@ void StatsEventSubscriber::Reset() {
|
| network_latency_datapoints_ = 0;
|
| total_e2e_latency_ = base::TimeDelta();
|
| e2e_latency_datapoints_ = 0;
|
| - frame_captured_times_.clear();
|
| + num_frames_dropped_by_encoder_ = 0;
|
| + num_frames_late_ = 0;
|
| + recent_captured_frames_.clear();
|
| packet_sent_times_.clear();
|
| start_time_ = clock_->NowTicks();
|
| last_response_received_time_ = base::TimeTicks();
|
| @@ -159,6 +166,12 @@ const char* StatsEventSubscriber::CastStatToString(CastStat stat) {
|
| STAT_ENUM_TO_STRING(RETRANSMISSION_KBPS);
|
| STAT_ENUM_TO_STRING(PACKET_LOSS_FRACTION);
|
| STAT_ENUM_TO_STRING(MS_SINCE_LAST_RECEIVER_RESPONSE);
|
| + STAT_ENUM_TO_STRING(NUM_FRAMES_CAPTURED);
|
| + STAT_ENUM_TO_STRING(NUM_FRAMES_DROPPED_BY_ENCODER);
|
| + STAT_ENUM_TO_STRING(NUM_FRAMES_LATE);
|
| + STAT_ENUM_TO_STRING(NUM_PACKETS_SENT);
|
| + STAT_ENUM_TO_STRING(NUM_PACKETS_RETRANSMITTED);
|
| + STAT_ENUM_TO_STRING(NUM_PACKETS_RTX_REJECTED);
|
| }
|
| NOTREACHED();
|
| return "";
|
| @@ -188,6 +201,12 @@ void StatsEventSubscriber::GetStatsInternal(StatsMap* stats_map) const {
|
| RETRANSMISSION_KBPS,
|
| stats_map);
|
| PopulatePacketLossPercentageStat(stats_map);
|
| + PopulateFrameCountStat(FRAME_CAPTURE_END, NUM_FRAMES_CAPTURED, stats_map);
|
| + PopulatePacketCountStat(PACKET_SENT_TO_NETWORK, NUM_PACKETS_SENT, stats_map);
|
| + PopulatePacketCountStat(
|
| + PACKET_RETRANSMITTED, NUM_PACKETS_RETRANSMITTED, stats_map);
|
| + PopulatePacketCountStat(
|
| + PACKET_RTX_REJECTED, NUM_PACKETS_RTX_REJECTED, stats_map);
|
|
|
| if (network_latency_datapoints_ > 0) {
|
| double avg_network_latency_ms =
|
| @@ -208,6 +227,10 @@ void StatsEventSubscriber::GetStatsInternal(StatsMap* stats_map) const {
|
| std::make_pair(MS_SINCE_LAST_RECEIVER_RESPONSE,
|
| (end_time - last_response_received_time_).InMillisecondsF()));
|
| }
|
| +
|
| + stats_map->insert(std::make_pair(NUM_FRAMES_DROPPED_BY_ENCODER,
|
| + num_frames_dropped_by_encoder_));
|
| + stats_map->insert(std::make_pair(NUM_FRAMES_LATE, num_frames_late_));
|
| }
|
|
|
| bool StatsEventSubscriber::GetReceiverOffset(base::TimeDelta* offset) {
|
| @@ -222,12 +245,22 @@ bool StatsEventSubscriber::GetReceiverOffset(base::TimeDelta* offset) {
|
| return true;
|
| }
|
|
|
| -void StatsEventSubscriber::RecordFrameCapturedTime(
|
| +void StatsEventSubscriber::RecordFrameCaptureTime(
|
| const FrameEvent& frame_event) {
|
| - frame_captured_times_.insert(
|
| - std::make_pair(frame_event.rtp_timestamp, frame_event.timestamp));
|
| - if (frame_captured_times_.size() > kMaxFrameEventTimeMapSize)
|
| - frame_captured_times_.erase(frame_captured_times_.begin());
|
| + recent_captured_frames_.insert(std::make_pair(
|
| + frame_event.rtp_timestamp, FrameInfo(frame_event.timestamp)));
|
| + if (recent_captured_frames_.size() > kMaxFrameInfoMapSize) {
|
| + FrameInfoMap::iterator erase_it = recent_captured_frames_.begin();
|
| + if (!erase_it->second.encoded)
|
| + num_frames_dropped_by_encoder_++;
|
| + recent_captured_frames_.erase(erase_it);
|
| + }
|
| +}
|
| +
|
| +void StatsEventSubscriber::MarkAsEncoded(RtpTimestamp rtp_timestamp) {
|
| + FrameInfoMap::iterator it = recent_captured_frames_.find(rtp_timestamp);
|
| + if (it != recent_captured_frames_.end())
|
| + it->second.encoded = true;
|
| }
|
|
|
| void StatsEventSubscriber::RecordE2ELatency(const FrameEvent& frame_event) {
|
| @@ -235,15 +268,15 @@ void StatsEventSubscriber::RecordE2ELatency(const FrameEvent& frame_event) {
|
| if (!GetReceiverOffset(&receiver_offset))
|
| return;
|
|
|
| - FrameEventTimeMap::iterator it =
|
| - frame_captured_times_.find(frame_event.rtp_timestamp);
|
| - if (it == frame_captured_times_.end())
|
| + FrameInfoMap::iterator it =
|
| + recent_captured_frames_.find(frame_event.rtp_timestamp);
|
| + if (it == recent_captured_frames_.end())
|
| return;
|
|
|
| // Playout time is event time + playout delay.
|
| base::TimeTicks playout_time =
|
| frame_event.timestamp + frame_event.delay_delta - receiver_offset;
|
| - total_e2e_latency_ += playout_time - it->second;
|
| + total_e2e_latency_ += playout_time - it->second.capture_time;
|
| e2e_latency_datapoints_++;
|
| }
|
|
|
| @@ -323,6 +356,24 @@ void StatsEventSubscriber::PopulateFpsStat(base::TimeTicks end_time,
|
| }
|
| }
|
|
|
| +void StatsEventSubscriber::PopulateFrameCountStat(CastLoggingEvent event,
|
| + CastStat stat,
|
| + StatsMap* stats_map) const {
|
| + FrameStatsMap::const_iterator it = frame_stats_.find(event);
|
| + if (it != frame_stats_.end()) {
|
| + stats_map->insert(std::make_pair(stat, it->second.event_counter));
|
| + }
|
| +}
|
| +
|
| +void StatsEventSubscriber::PopulatePacketCountStat(CastLoggingEvent event,
|
| + CastStat stat,
|
| + StatsMap* stats_map) const {
|
| + PacketStatsMap::const_iterator it = packet_stats_.find(event);
|
| + if (it != packet_stats_.end()) {
|
| + stats_map->insert(std::make_pair(stat, it->second.event_counter));
|
| + }
|
| +}
|
| +
|
| void StatsEventSubscriber::PopulatePlayoutDelayStat(StatsMap* stats_map) const {
|
| FrameStatsMap::const_iterator it = frame_stats_.find(FRAME_PLAYOUT);
|
| if (it != frame_stats_.end()) {
|
| @@ -396,5 +447,11 @@ StatsEventSubscriber::PacketLogStats::PacketLogStats()
|
| : event_counter(0), sum_size(0) {}
|
| StatsEventSubscriber::PacketLogStats::~PacketLogStats() {}
|
|
|
| +StatsEventSubscriber::FrameInfo::FrameInfo(base::TimeTicks capture_time)
|
| + : capture_time(capture_time), encoded(false) {
|
| +}
|
| +StatsEventSubscriber::FrameInfo::~FrameInfo() {
|
| +}
|
| +
|
| } // namespace cast
|
| } // namespace media
|
|
|