Chromium Code Reviews| 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 5a7333a70893b3d3f6c0caaadfadc207fac1de0b..f8c9866c1becbcae29d7235bab1f5806cc44cf2c 100644 |
| --- a/media/cast/logging/encoding_event_subscriber.cc |
| +++ b/media/cast/logging/encoding_event_subscriber.cc |
| @@ -4,6 +4,7 @@ |
| #include "media/cast/logging/encoding_event_subscriber.h" |
| +#include <cstring> |
| #include <utility> |
| #include "base/logging.h" |
| @@ -18,7 +19,12 @@ using media::cast::proto::BasePacketEvent; |
| namespace media { |
| namespace cast { |
| -EncodingEventSubscriber::EncodingEventSubscriber() {} |
| +EncodingEventSubscriber::EncodingEventSubscriber( |
| + EncodingEventSubscriberConfig config) |
| + : config_(config) { |
| + DCHECK_GT(config_.max_generic_event_values, 0); |
| + memset(next_write_index_, 0, sizeof(next_write_index_)); |
| +} |
| EncodingEventSubscriber::~EncodingEventSubscriber() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| @@ -28,91 +34,120 @@ void EncodingEventSubscriber::OnReceiveFrameEvent( |
| const FrameEvent& frame_event) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - FrameEventMap::iterator it = frame_event_map_.find(frame_event.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_rtp_timestamp(frame_event.rtp_timestamp); |
| - frame_event_map_.insert( |
| - std::make_pair(frame_event.rtp_timestamp, event_proto)); |
| - } else { |
| - event_proto = it->second; |
| - } |
| + if (ShouldProcessEvent(frame_event.type)) { |
| + FrameEventMap::iterator it = |
| + frame_event_map_.find(frame_event.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_rtp_timestamp(frame_event.rtp_timestamp); |
| + frame_event_map_.insert( |
| + std::make_pair(frame_event.rtp_timestamp, event_proto)); |
| + } else { |
| + event_proto = it->second; |
| + } |
| - event_proto->add_event_type(ToProtoEventType(frame_event.type)); |
| - event_proto->add_event_timestamp_micros( |
| - frame_event.timestamp.ToInternalValue()); |
| + event_proto->add_event_type(ToProtoEventType(frame_event.type)); |
| + event_proto->add_event_timestamp_micros( |
| + frame_event.timestamp.ToInternalValue()); |
| - if (frame_event.type == kAudioFrameEncoded || |
| - frame_event.type == kVideoFrameEncoded) { |
| - event_proto->set_encoded_frame_size(frame_event.size); |
| - } else if (frame_event.type == kAudioPlayoutDelay || |
| - frame_event.type == kVideoRenderDelay) { |
| - event_proto->set_delay_millis(frame_event.delay_delta.InMilliseconds()); |
| + if (frame_event.type == kAudioFrameEncoded || |
| + frame_event.type == kVideoFrameEncoded) { |
| + event_proto->set_encoded_frame_size(frame_event.size); |
| + } else if (frame_event.type == kAudioPlayoutDelay || |
| + frame_event.type == kVideoRenderDelay) { |
| + event_proto->set_delay_millis(frame_event.delay_delta.InMilliseconds()); |
| + } |
| + |
| + TruncateFrameEventMapIfNeeded(); |
| } |
| + |
| + DCHECK(frame_event_map_.size() <= config_.max_frames); |
| } |
| void EncodingEventSubscriber::OnReceivePacketEvent( |
| const PacketEvent& packet_event) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - PacketEventMap::iterator it = |
| - packet_event_map_.find(packet_event.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_rtp_timestamp(packet_event.rtp_timestamp); |
| - packet_event_map_.insert( |
| - std::make_pair(packet_event.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 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) { |
| + if (ShouldProcessEvent(packet_event.type)) { |
| + PacketEventMap::iterator it = |
| + packet_event_map_.find(packet_event.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_rtp_timestamp(packet_event.rtp_timestamp); |
| + packet_event_map_.insert( |
| + std::make_pair(packet_event.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 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_micros( |
| + packet_event.timestamp.ToInternalValue()); |
| + |
| + TruncatePacketEventMapIfNeeded(); |
| } |
| - base_packet_event_proto->add_event_type(ToProtoEventType(packet_event.type)); |
| - base_packet_event_proto->add_event_timestamp_micros( |
| - packet_event.timestamp.ToInternalValue()); |
| + DCHECK(packet_event_map_.size() <= config_.max_frames); |
| } |
| void EncodingEventSubscriber::OnReceiveGenericEvent( |
|
Alpha Left Google
2014/02/14 18:42:39
What are the generic events that we capture? I'm n
imcheng
2014/02/14 20:24:17
As mentioned in the other file, there are 7 generi
|
| const GenericEvent& generic_event) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| - GenericEventMap::iterator it = generic_event_map_.find(generic_event.type); |
| - linked_ptr<AggregatedGenericEvent> event_proto; |
| - if (it == generic_event_map_.end()) { |
| - event_proto.reset(new AggregatedGenericEvent); |
| - event_proto->set_event_type(ToProtoEventType(generic_event.type)); |
| - generic_event_map_.insert(std::make_pair(generic_event.type, event_proto)); |
| - } else { |
| - event_proto = it->second; |
| - } |
| + if (ShouldProcessEvent(generic_event.type)) { |
| + GenericEventMap::iterator it = generic_event_map_.find(generic_event.type); |
| + linked_ptr<AggregatedGenericEvent> event_proto; |
| + if (it == generic_event_map_.end()) { |
| + event_proto.reset(new AggregatedGenericEvent); |
| + event_proto->set_event_type(ToProtoEventType(generic_event.type)); |
| + generic_event_map_.insert( |
| + std::make_pair(generic_event.type, event_proto)); |
| + } else { |
| + event_proto = it->second; |
| + } |
| - event_proto->add_event_timestamp_micros( |
| - generic_event.timestamp.ToInternalValue()); |
| - event_proto->add_value(generic_event.value); |
| + if (event_proto->value_size() < config_.max_generic_event_values) { |
| + event_proto->add_event_timestamp_micros( |
| + generic_event.timestamp.ToInternalValue()); |
| + event_proto->add_value(generic_event.value); |
| + } else { |
| + // Reached maximum size, treat the repeated fields as circular buffer and |
| + // rewrite oldest value. |
| + int index = next_write_index_[generic_event.type]; |
| + event_proto->set_event_timestamp_micros( |
| + index, generic_event.timestamp.ToInternalValue()); |
| + event_proto->set_value(index, generic_event.value); |
| + next_write_index_[generic_event.type] = |
| + (index + 1) % config_.max_generic_event_values; |
| + } |
| + } |
| } |
| void EncodingEventSubscriber::GetFrameEventsAndReset( |
| @@ -134,6 +169,25 @@ void EncodingEventSubscriber::GetGenericEventsAndReset( |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| generic_event_map->swap(generic_event_map_); |
| generic_event_map_.clear(); |
| + memset(next_write_index_, 0, sizeof(next_write_index_)); |
| +} |
| + |
| +bool EncodingEventSubscriber::ShouldProcessEvent(CastLoggingEvent event) { |
| + return GetEventMediaType(event) == config_.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() > config_.max_frames) |
| + frame_event_map_.erase(frame_event_map_.begin()); |
| +} |
| + |
| +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() > config_.max_frames) |
| + packet_event_map_.erase(packet_event_map_.begin()); |
| } |
| } // namespace cast |