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

Unified Diff: media/cast/logging/encoding_event_subscriber.cc

Issue 241833002: Cast: Limit number of events/packets in EncodingEventSubscriber protos. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: media/cast/logging/encoding_event_subscriber.cc
diff --git a/media/cast/logging/encoding_event_subscriber.cc b/media/cast/logging/encoding_event_subscriber.cc
index 10ced1a5cceee7e98f1ee853023291e1bc0c172c..8f360a6b8bf3b9bbaf2747f7189edd5dddc57958 100644
--- a/media/cast/logging/encoding_event_subscriber.cc
+++ b/media/cast/logging/encoding_event_subscriber.cc
@@ -16,6 +16,23 @@ using media::cast::proto::AggregatedPacketEvent;
using media::cast::proto::BasePacketEvent;
using media::cast::proto::LogMetadata;
+namespace {
+
+// A size limit on maps to keep lookups fast.
+const size_t kMaxMapSize = 200;
+
+// The smallest (oredered by RTP timestamp) |kNumMapEntriesToTransfer| entries
+// will be moved when the map size reaches |kMaxMapSize|.
+// Must be smaller than |kMaxMapSize|.
+const size_t kNumMapEntriesToTransfer = 100;
+
+template <typename ProtoPtr>
+bool IsRtpTimestampLessThan(const ProtoPtr& lhs, const ProtoPtr& rhs) {
+ return lhs->relative_rtp_timestamp() < rhs->relative_rtp_timestamp();
+}
+
+}
+
namespace media {
namespace cast {
@@ -24,6 +41,8 @@ EncodingEventSubscriber::EncodingEventSubscriber(
size_t max_frames)
: event_media_type_(event_media_type),
max_frames_(max_frames),
+ frame_event_storage_index_(0),
+ packet_event_storage_index_(0),
seen_first_rtp_timestamp_(false),
first_rtp_timestamp_(0u) {}
@@ -35,92 +54,126 @@ void EncodingEventSubscriber::OnReceiveFrameEvent(
const FrameEvent& frame_event) {
DCHECK(thread_checker_.CalledOnValidThread());
- if (ShouldProcessEvent(frame_event.type)) {
- RtpTimestamp relative_rtp_timestamp =
- GetRelativeRtpTimestamp(frame_event.rtp_timestamp);
- FrameEventMap::iterator it = frame_event_map_.find(relative_rtp_timestamp);
- linked_ptr<AggregatedFrameEvent> event_proto;
+ if (!ShouldProcessEvent(frame_event.type))
+ return;
- // Look up existing entry. If not found, create a new entry and add to map.
- if (it == frame_event_map_.end()) {
+ RtpTimestamp relative_rtp_timestamp =
+ GetRelativeRtpTimestamp(frame_event.rtp_timestamp);
+ FrameEventMap::iterator it = frame_event_map_.find(relative_rtp_timestamp);
+ linked_ptr<AggregatedFrameEvent> event_proto;
+
+ // Look up existing entry. If not found, create a new entry and add to map.
+ if (it == frame_event_map_.end()) {
+ event_proto.reset(new AggregatedFrameEvent);
+ event_proto->set_relative_rtp_timestamp(relative_rtp_timestamp);
+ frame_event_map_.insert(
+ std::make_pair(relative_rtp_timestamp, event_proto));
+ } else {
+ event_proto = it->second;
+ if (event_proto->event_type_size() >= kMaxEventsPerProto) {
+ DVLOG(2) << "Too many events in frame " << frame_event.rtp_timestamp
+ << ". Using new frame event proto.";
+ AddFrameEventToStorage(event_proto);
event_proto.reset(new AggregatedFrameEvent);
event_proto->set_relative_rtp_timestamp(relative_rtp_timestamp);
- frame_event_map_.insert(
- std::make_pair(relative_rtp_timestamp, event_proto));
- } else {
- event_proto = it->second;
+ it->second = event_proto;
}
+ }
- event_proto->add_event_type(ToProtoEventType(frame_event.type));
- event_proto->add_event_timestamp_ms(
- (frame_event.timestamp - base::TimeTicks()).InMilliseconds());
-
- if (frame_event.type == kAudioFrameEncoded) {
- event_proto->set_encoded_frame_size(frame_event.size);
- } else if (frame_event.type == kVideoFrameEncoded) {
- event_proto->set_encoded_frame_size(frame_event.size);
- event_proto->set_key_frame(frame_event.key_frame);
- } else if (frame_event.type == kAudioPlayoutDelay ||
- frame_event.type == kVideoRenderDelay) {
- event_proto->set_delay_millis(frame_event.delay_delta.InMilliseconds());
- }
+ event_proto->add_event_type(ToProtoEventType(frame_event.type));
+ event_proto->add_event_timestamp_ms(
+ (frame_event.timestamp - base::TimeTicks()).InMilliseconds());
- TruncateFrameEventMapIfNeeded();
+ if (frame_event.type == kAudioFrameEncoded) {
+ event_proto->set_encoded_frame_size(frame_event.size);
+ } else if (frame_event.type == kVideoFrameEncoded) {
+ event_proto->set_encoded_frame_size(frame_event.size);
+ event_proto->set_key_frame(frame_event.key_frame);
+ } else if (frame_event.type == kAudioPlayoutDelay ||
+ frame_event.type == kVideoRenderDelay) {
+ event_proto->set_delay_millis(frame_event.delay_delta.InMilliseconds());
}
- DCHECK(frame_event_map_.size() <= max_frames_);
+ if (frame_event_map_.size() > kMaxMapSize)
+ TransferFrameEvents(kNumMapEntriesToTransfer);
+
+ DCHECK(frame_event_map_.size() <= kMaxMapSize);
+ DCHECK(frame_event_storage_.size() <= max_frames_);
}
void EncodingEventSubscriber::OnReceivePacketEvent(
const PacketEvent& packet_event) {
DCHECK(thread_checker_.CalledOnValidThread());
- if (ShouldProcessEvent(packet_event.type)) {
- RtpTimestamp relative_rtp_timestamp =
- GetRelativeRtpTimestamp(packet_event.rtp_timestamp);
- PacketEventMap::iterator it =
- packet_event_map_.find(relative_rtp_timestamp);
- linked_ptr<AggregatedPacketEvent> event_proto;
- BasePacketEvent* base_packet_event_proto = NULL;
+ if (!ShouldProcessEvent(packet_event.type))
+ return;
+ RtpTimestamp relative_rtp_timestamp =
+ GetRelativeRtpTimestamp(packet_event.rtp_timestamp);
+ PacketEventMap::iterator it =
+ packet_event_map_.find(relative_rtp_timestamp);
+ linked_ptr<AggregatedPacketEvent> event_proto;
+ BasePacketEvent* base_packet_event_proto = NULL;
+
+ // Look up existing entry. If not found, create a new entry and add to map.
+ if (it == packet_event_map_.end()) {
+ event_proto.reset(new AggregatedPacketEvent);
+ event_proto->set_relative_rtp_timestamp(relative_rtp_timestamp);
+ packet_event_map_.insert(
+ std::make_pair(relative_rtp_timestamp, event_proto));
+ base_packet_event_proto = event_proto->add_base_packet_event();
+ base_packet_event_proto->set_packet_id(packet_event.packet_id);
+ } else {
+ // Found existing entry, now look up existing BasePacketEvent using packet
+ // ID. If not found, create a new entry and add to proto.
+ event_proto = it->second;
+ RepeatedPtrField<BasePacketEvent>* field =
+ event_proto->mutable_base_packet_event();
+ for (RepeatedPtrField<BasePacketEvent>::pointer_iterator base_it =
+ field->pointer_begin();
+ base_it != field->pointer_end();
+ ++base_it) {
+ if ((*base_it)->packet_id() == packet_event.packet_id) {
+ base_packet_event_proto = *base_it;
+ break;
+ }
+ }
+ if (!base_packet_event_proto) {
+ if (event_proto->base_packet_event_size() >= kMaxPacketsPerFrame) {
+ DVLOG(3) << "Too many packets in AggregatedPacketEvent "
+ << packet_event.rtp_timestamp << ". "
+ << "Using new packet event proto.";
+ AddPacketEventToStorage(event_proto);
+ event_proto.reset(new AggregatedPacketEvent);
+ event_proto->set_relative_rtp_timestamp(relative_rtp_timestamp);
+ it->second = event_proto;
+ }
- // Look up existing entry. If not found, create a new entry and add to map.
- if (it == packet_event_map_.end()) {
+ base_packet_event_proto = event_proto->add_base_packet_event();
+ base_packet_event_proto->set_packet_id(packet_event.packet_id);
+ } else if (base_packet_event_proto->event_type_size() >=
+ kMaxEventsPerProto) {
+ DVLOG(3) << "Too many events in packet "
+ << packet_event.rtp_timestamp << ", "
+ << packet_event.packet_id << ". Using new packet event proto.";
+ AddPacketEventToStorage(event_proto);
event_proto.reset(new AggregatedPacketEvent);
event_proto->set_relative_rtp_timestamp(relative_rtp_timestamp);
- packet_event_map_.insert(
- std::make_pair(relative_rtp_timestamp, event_proto));
+ it->second = event_proto;
base_packet_event_proto = event_proto->add_base_packet_event();
base_packet_event_proto->set_packet_id(packet_event.packet_id);
- } else {
- // Found existing entry, now look up existing BasePacketEvent using packet
- // ID. If not found, create a new entry and add to proto.
- event_proto = it->second;
- RepeatedPtrField<BasePacketEvent>* field =
- event_proto->mutable_base_packet_event();
- for (RepeatedPtrField<BasePacketEvent>::pointer_iterator it =
- field->pointer_begin();
- it != field->pointer_end();
- ++it) {
- if ((*it)->packet_id() == packet_event.packet_id) {
- base_packet_event_proto = *it;
- break;
- }
- }
- if (!base_packet_event_proto) {
- base_packet_event_proto = event_proto->add_base_packet_event();
- base_packet_event_proto->set_packet_id(packet_event.packet_id);
- }
}
+ }
- base_packet_event_proto->add_event_type(
- ToProtoEventType(packet_event.type));
- base_packet_event_proto->add_event_timestamp_ms(
- (packet_event.timestamp - base::TimeTicks()).InMilliseconds());
+ base_packet_event_proto->add_event_type(
+ ToProtoEventType(packet_event.type));
+ base_packet_event_proto->add_event_timestamp_ms(
+ (packet_event.timestamp - base::TimeTicks()).InMilliseconds());
- TruncatePacketEventMapIfNeeded();
- }
+ if (packet_event_map_.size() > kMaxMapSize)
+ TransferPacketEvents(kNumMapEntriesToTransfer);
- DCHECK(packet_event_map_.size() <= max_frames_);
+ DCHECK(packet_event_map_.size() <= kMaxMapSize);
+ DCHECK(packet_event_storage_.size() <= max_frames_);
}
void EncodingEventSubscriber::OnReceiveGenericEvent(
@@ -129,19 +182,27 @@ void EncodingEventSubscriber::OnReceiveGenericEvent(
// Do nothing, there are no generic events we are interested in.
}
-void EncodingEventSubscriber::GetEventsAndReset(LogMetadata* metadata,
- FrameEventMap* frame_events,
- PacketEventMap* packet_events) {
+void EncodingEventSubscriber::GetEventsAndReset(
+ LogMetadata* metadata, FrameEventList* frame_events,
+ PacketEventList* packet_events) {
DCHECK(thread_checker_.CalledOnValidThread());
+ // Flush all events.
+ TransferFrameEvents(frame_event_map_.size());
+ TransferPacketEvents(packet_event_map_.size());
+ std::sort(frame_event_storage_.begin(), frame_event_storage_.end(),
+ &IsRtpTimestampLessThan<linked_ptr<AggregatedFrameEvent> >);
+ std::sort(packet_event_storage_.begin(), packet_event_storage_.end(),
+ &IsRtpTimestampLessThan<linked_ptr<AggregatedPacketEvent> >);
+
metadata->set_is_audio(event_media_type_ == AUDIO_EVENT);
metadata->set_first_rtp_timestamp(first_rtp_timestamp_);
- metadata->set_num_frame_events(frame_event_map_.size());
- metadata->set_num_packet_events(packet_event_map_.size());
+ metadata->set_num_frame_events(frame_event_storage_.size());
+ metadata->set_num_packet_events(packet_event_storage_.size());
metadata->set_reference_timestamp_ms_at_unix_epoch(
(base::TimeTicks::UnixEpoch() - base::TimeTicks()).InMilliseconds());
- frame_events->swap(frame_event_map_);
- packet_events->swap(packet_event_map_);
+ frame_events->swap(frame_event_storage_);
+ packet_events->swap(packet_event_storage_);
Reset();
}
@@ -149,18 +210,45 @@ bool EncodingEventSubscriber::ShouldProcessEvent(CastLoggingEvent event) {
return GetEventMediaType(event) == event_media_type_;
}
-void EncodingEventSubscriber::TruncateFrameEventMapIfNeeded() {
- // This works because this is called everytime an event is inserted and
- // we only insert events one at a time.
- if (frame_event_map_.size() > max_frames_)
- frame_event_map_.erase(frame_event_map_.begin());
+void EncodingEventSubscriber::TransferFrameEvents(size_t num_entries) {
+ DCHECK(frame_event_map_.size() >= num_entries);
+
+ FrameEventMap::iterator it = frame_event_map_.begin();
+ for (size_t i = 0; i < num_entries; i++, ++it)
+ AddFrameEventToStorage(it->second);
+
+ frame_event_map_.erase(frame_event_map_.begin(), it);
+}
+
+void EncodingEventSubscriber::TransferPacketEvents(size_t num_entries) {
+ DCHECK(packet_event_map_.size() >= num_entries);
+
+ PacketEventMap::iterator it = packet_event_map_.begin();
+ for (size_t i = 0; i < num_entries; i++, ++it)
Alpha Left Google 2014/04/22 18:20:42 Try to erase the entry while iterating. That way y
imcheng 2014/04/22 19:29:33 Per offline discussion, changed the semantics of f
+ AddPacketEventToStorage(it->second);
+
+ packet_event_map_.erase(packet_event_map_.begin(), it);
+}
+
+void EncodingEventSubscriber::AddFrameEventToStorage(
+ const linked_ptr<AggregatedFrameEvent>& frame_event_proto) {
+ if (frame_event_storage_.size() >= max_frames_) {
+ frame_event_storage_[frame_event_storage_index_] = frame_event_proto;
+ } else {
+ frame_event_storage_.push_back(frame_event_proto);
+ }
+
+ frame_event_storage_index_ = (frame_event_storage_index_ + 1) % max_frames_;
}
-void EncodingEventSubscriber::TruncatePacketEventMapIfNeeded() {
- // This works because this is called everytime an event is inserted and
- // we only insert events one at a time.
- if (packet_event_map_.size() > max_frames_)
- packet_event_map_.erase(packet_event_map_.begin());
+void EncodingEventSubscriber::AddPacketEventToStorage(
+ const linked_ptr<AggregatedPacketEvent>& packet_event_proto) {
+ if (packet_event_storage_.size() >= max_frames_)
+ packet_event_storage_[packet_event_storage_index_] = packet_event_proto;
+ else
+ packet_event_storage_.push_back(packet_event_proto);
+
+ packet_event_storage_index_ = (packet_event_storage_index_ + 1) % max_frames_;
}
RtpTimestamp EncodingEventSubscriber::GetRelativeRtpTimestamp(
@@ -175,7 +263,11 @@ RtpTimestamp EncodingEventSubscriber::GetRelativeRtpTimestamp(
void EncodingEventSubscriber::Reset() {
frame_event_map_.clear();
+ frame_event_storage_.clear();
+ frame_event_storage_index_ = 0;
packet_event_map_.clear();
+ packet_event_storage_.clear();
+ packet_event_storage_index_ = 0;
seen_first_rtp_timestamp_ = false;
first_rtp_timestamp_ = 0u;
}
« no previous file with comments | « media/cast/logging/encoding_event_subscriber.h ('k') | media/cast/logging/encoding_event_subscriber_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698