Disable accessible touch exploration by default.
[chromium-blink-merge.git] / media / cast / logging / encoding_event_subscriber.cc
blob48cc911ba80c0bcc04638e7a876264525d073b20
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.
5 #include "media/cast/logging/encoding_event_subscriber.h"
7 #include <cstring>
8 #include <utility>
10 #include "base/logging.h"
11 #include "media/cast/logging/proto/proto_utils.h"
13 using google::protobuf::RepeatedPtrField;
14 using media::cast::proto::AggregatedFrameEvent;
15 using media::cast::proto::AggregatedPacketEvent;
16 using media::cast::proto::BasePacketEvent;
17 using media::cast::proto::LogMetadata;
19 namespace {
21 // A size limit on maps to keep lookups fast.
22 const size_t kMaxMapSize = 200;
24 // The smallest (oredered by RTP timestamp) |kNumMapEntriesToTransfer| entries
25 // will be moved when the map size reaches |kMaxMapSize|.
26 // Must be smaller than |kMaxMapSize|.
27 const size_t kNumMapEntriesToTransfer = 100;
29 template <typename ProtoPtr>
30 bool IsRtpTimestampLessThan(const ProtoPtr& lhs, const ProtoPtr& rhs) {
31 return lhs->relative_rtp_timestamp() < rhs->relative_rtp_timestamp();
34 BasePacketEvent* GetNewBasePacketEvent(AggregatedPacketEvent* event_proto,
35 int packet_id, int size) {
36 BasePacketEvent* base = event_proto->add_base_packet_event();
37 base->set_packet_id(packet_id);
38 base->set_size(size);
39 return base;
44 namespace media {
45 namespace cast {
47 EncodingEventSubscriber::EncodingEventSubscriber(
48 EventMediaType event_media_type,
49 size_t max_frames)
50 : event_media_type_(event_media_type),
51 max_frames_(max_frames),
52 frame_event_storage_index_(0),
53 packet_event_storage_index_(0),
54 seen_first_rtp_timestamp_(false),
55 first_rtp_timestamp_(0u) {}
57 EncodingEventSubscriber::~EncodingEventSubscriber() {
58 DCHECK(thread_checker_.CalledOnValidThread());
61 void EncodingEventSubscriber::OnReceiveFrameEvent(
62 const FrameEvent& frame_event) {
63 DCHECK(thread_checker_.CalledOnValidThread());
65 if (event_media_type_ != frame_event.media_type)
66 return;
68 RtpTimestamp relative_rtp_timestamp =
69 GetRelativeRtpTimestamp(frame_event.rtp_timestamp);
70 FrameEventMap::iterator it = frame_event_map_.find(relative_rtp_timestamp);
71 linked_ptr<AggregatedFrameEvent> event_proto;
73 // Look up existing entry. If not found, create a new entry and add to map.
74 if (it == frame_event_map_.end()) {
75 event_proto.reset(new AggregatedFrameEvent);
76 event_proto->set_relative_rtp_timestamp(relative_rtp_timestamp);
77 frame_event_map_.insert(
78 std::make_pair(relative_rtp_timestamp, event_proto));
79 } else {
80 event_proto = it->second;
81 if (event_proto->event_type_size() >= kMaxEventsPerProto) {
82 DVLOG(2) << "Too many events in frame " << frame_event.rtp_timestamp
83 << ". Using new frame event proto.";
84 AddFrameEventToStorage(event_proto);
85 event_proto.reset(new AggregatedFrameEvent);
86 event_proto->set_relative_rtp_timestamp(relative_rtp_timestamp);
87 it->second = event_proto;
91 event_proto->add_event_type(ToProtoEventType(frame_event.type));
92 event_proto->add_event_timestamp_ms(
93 (frame_event.timestamp - base::TimeTicks()).InMilliseconds());
95 if (frame_event.type == FRAME_ENCODED) {
96 event_proto->set_encoded_frame_size(frame_event.size);
97 if (frame_event.media_type == VIDEO_EVENT) {
98 event_proto->set_encoded_frame_size(frame_event.size);
99 event_proto->set_key_frame(frame_event.key_frame);
100 event_proto->set_target_bitrate(frame_event.target_bitrate);
102 } else if (frame_event.type == FRAME_PLAYOUT) {
103 event_proto->set_delay_millis(frame_event.delay_delta.InMilliseconds());
106 if (frame_event_map_.size() > kMaxMapSize)
107 TransferFrameEvents(kNumMapEntriesToTransfer);
109 DCHECK(frame_event_map_.size() <= kMaxMapSize);
110 DCHECK(frame_event_storage_.size() <= max_frames_);
113 void EncodingEventSubscriber::OnReceivePacketEvent(
114 const PacketEvent& packet_event) {
115 DCHECK(thread_checker_.CalledOnValidThread());
117 if (event_media_type_ != packet_event.media_type)
118 return;
120 RtpTimestamp relative_rtp_timestamp =
121 GetRelativeRtpTimestamp(packet_event.rtp_timestamp);
122 PacketEventMap::iterator it =
123 packet_event_map_.find(relative_rtp_timestamp);
124 linked_ptr<AggregatedPacketEvent> event_proto;
125 BasePacketEvent* base_packet_event_proto = NULL;
127 // Look up existing entry. If not found, create a new entry and add to map.
128 if (it == packet_event_map_.end()) {
129 event_proto.reset(new AggregatedPacketEvent);
130 event_proto->set_relative_rtp_timestamp(relative_rtp_timestamp);
131 packet_event_map_.insert(
132 std::make_pair(relative_rtp_timestamp, event_proto));
133 base_packet_event_proto = GetNewBasePacketEvent(
134 event_proto.get(), packet_event.packet_id, packet_event.size);
135 } else {
136 // Found existing entry, now look up existing BasePacketEvent using packet
137 // ID. If not found, create a new entry and add to proto.
138 event_proto = it->second;
139 RepeatedPtrField<BasePacketEvent>* field =
140 event_proto->mutable_base_packet_event();
141 for (RepeatedPtrField<BasePacketEvent>::pointer_iterator base_it =
142 field->pointer_begin();
143 base_it != field->pointer_end();
144 ++base_it) {
145 if ((*base_it)->packet_id() == packet_event.packet_id) {
146 base_packet_event_proto = *base_it;
147 break;
150 if (!base_packet_event_proto) {
151 if (event_proto->base_packet_event_size() >= kMaxPacketsPerFrame) {
152 DVLOG(3) << "Too many packets in AggregatedPacketEvent "
153 << packet_event.rtp_timestamp << ". "
154 << "Using new packet event proto.";
155 AddPacketEventToStorage(event_proto);
156 event_proto.reset(new AggregatedPacketEvent);
157 event_proto->set_relative_rtp_timestamp(relative_rtp_timestamp);
158 it->second = event_proto;
161 base_packet_event_proto = GetNewBasePacketEvent(
162 event_proto.get(), packet_event.packet_id, packet_event.size);
163 } else if (base_packet_event_proto->event_type_size() >=
164 kMaxEventsPerProto) {
165 DVLOG(3) << "Too many events in packet "
166 << packet_event.rtp_timestamp << ", "
167 << packet_event.packet_id << ". Using new packet event proto.";
168 AddPacketEventToStorage(event_proto);
169 event_proto.reset(new AggregatedPacketEvent);
170 event_proto->set_relative_rtp_timestamp(relative_rtp_timestamp);
171 it->second = event_proto;
172 base_packet_event_proto = GetNewBasePacketEvent(
173 event_proto.get(), packet_event.packet_id, packet_event.size);
177 base_packet_event_proto->add_event_type(
178 ToProtoEventType(packet_event.type));
179 base_packet_event_proto->add_event_timestamp_ms(
180 (packet_event.timestamp - base::TimeTicks()).InMilliseconds());
182 // |base_packet_event_proto| could have been created with a receiver event
183 // which does not have the packet size and we would need to overwrite it when
184 // we see a sender event, which does have the packet size.
185 if (packet_event.size > 0) {
186 base_packet_event_proto->set_size(packet_event.size);
189 if (packet_event_map_.size() > kMaxMapSize)
190 TransferPacketEvents(kNumMapEntriesToTransfer);
192 DCHECK(packet_event_map_.size() <= kMaxMapSize);
193 DCHECK(packet_event_storage_.size() <= max_frames_);
196 void EncodingEventSubscriber::GetEventsAndReset(LogMetadata* metadata,
197 FrameEventList* frame_events, PacketEventList* packet_events) {
198 DCHECK(thread_checker_.CalledOnValidThread());
200 // Flush all events.
201 TransferFrameEvents(frame_event_map_.size());
202 TransferPacketEvents(packet_event_map_.size());
203 std::sort(frame_event_storage_.begin(), frame_event_storage_.end(),
204 &IsRtpTimestampLessThan<linked_ptr<AggregatedFrameEvent> >);
205 std::sort(packet_event_storage_.begin(), packet_event_storage_.end(),
206 &IsRtpTimestampLessThan<linked_ptr<AggregatedPacketEvent> >);
208 metadata->set_is_audio(event_media_type_ == AUDIO_EVENT);
209 metadata->set_first_rtp_timestamp(first_rtp_timestamp_);
210 metadata->set_num_frame_events(frame_event_storage_.size());
211 metadata->set_num_packet_events(packet_event_storage_.size());
212 metadata->set_reference_timestamp_ms_at_unix_epoch(
213 (base::TimeTicks::UnixEpoch() - base::TimeTicks()).InMilliseconds());
214 frame_events->swap(frame_event_storage_);
215 packet_events->swap(packet_event_storage_);
216 Reset();
219 void EncodingEventSubscriber::TransferFrameEvents(size_t max_num_entries) {
220 DCHECK(frame_event_map_.size() >= max_num_entries);
222 FrameEventMap::iterator it = frame_event_map_.begin();
223 for (size_t i = 0;
224 i < max_num_entries && it != frame_event_map_.end();
225 i++, ++it) {
226 AddFrameEventToStorage(it->second);
229 frame_event_map_.erase(frame_event_map_.begin(), it);
232 void EncodingEventSubscriber::TransferPacketEvents(size_t max_num_entries) {
233 PacketEventMap::iterator it = packet_event_map_.begin();
234 for (size_t i = 0;
235 i < max_num_entries && it != packet_event_map_.end();
236 i++, ++it) {
237 AddPacketEventToStorage(it->second);
240 packet_event_map_.erase(packet_event_map_.begin(), it);
243 void EncodingEventSubscriber::AddFrameEventToStorage(
244 const linked_ptr<AggregatedFrameEvent>& frame_event_proto) {
245 if (frame_event_storage_.size() >= max_frames_) {
246 frame_event_storage_[frame_event_storage_index_] = frame_event_proto;
247 } else {
248 frame_event_storage_.push_back(frame_event_proto);
251 frame_event_storage_index_ = (frame_event_storage_index_ + 1) % max_frames_;
254 void EncodingEventSubscriber::AddPacketEventToStorage(
255 const linked_ptr<AggregatedPacketEvent>& packet_event_proto) {
256 if (packet_event_storage_.size() >= max_frames_)
257 packet_event_storage_[packet_event_storage_index_] = packet_event_proto;
258 else
259 packet_event_storage_.push_back(packet_event_proto);
261 packet_event_storage_index_ = (packet_event_storage_index_ + 1) % max_frames_;
264 RtpTimestamp EncodingEventSubscriber::GetRelativeRtpTimestamp(
265 RtpTimestamp rtp_timestamp) {
266 if (!seen_first_rtp_timestamp_) {
267 seen_first_rtp_timestamp_ = true;
268 first_rtp_timestamp_ = rtp_timestamp;
271 return rtp_timestamp - first_rtp_timestamp_;
274 void EncodingEventSubscriber::Reset() {
275 frame_event_map_.clear();
276 frame_event_storage_.clear();
277 frame_event_storage_index_ = 0;
278 packet_event_map_.clear();
279 packet_event_storage_.clear();
280 packet_event_storage_index_ = 0;
281 seen_first_rtp_timestamp_ = false;
282 first_rtp_timestamp_ = 0u;
285 } // namespace cast
286 } // namespace media