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"
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::AggregatedGenericEvent;
16 using media::cast::proto::AggregatedPacketEvent;
17 using media::cast::proto::BasePacketEvent;
22 EncodingEventSubscriber::EncodingEventSubscriber(
23 EventMediaType event_media_type, size_t max_frames)
24 : event_media_type_(event_media_type), max_frames_(max_frames) {}
26 EncodingEventSubscriber::~EncodingEventSubscriber() {
27 DCHECK(thread_checker_.CalledOnValidThread());
30 void EncodingEventSubscriber::OnReceiveFrameEvent(
31 const FrameEvent& frame_event) {
32 DCHECK(thread_checker_.CalledOnValidThread());
34 if (ShouldProcessEvent(frame_event.type)) {
35 FrameEventMap::iterator it =
36 frame_event_map_.find(frame_event.rtp_timestamp);
37 linked_ptr<AggregatedFrameEvent> event_proto;
39 // Look up existing entry. If not found, create a new entry and add to map.
40 if (it == frame_event_map_.end()) {
41 event_proto.reset(new AggregatedFrameEvent);
42 event_proto->set_rtp_timestamp(frame_event.rtp_timestamp);
43 frame_event_map_.insert(
44 std::make_pair(frame_event.rtp_timestamp, event_proto));
46 event_proto = it->second;
49 event_proto->add_event_type(ToProtoEventType(frame_event.type));
50 event_proto->add_event_timestamp_micros(
51 frame_event.timestamp.ToInternalValue());
53 if (frame_event.type == kAudioFrameEncoded ||
54 frame_event.type == kVideoFrameEncoded) {
55 event_proto->set_encoded_frame_size(frame_event.size);
56 } else if (frame_event.type == kAudioPlayoutDelay ||
57 frame_event.type == kVideoRenderDelay) {
58 event_proto->set_delay_millis(frame_event.delay_delta.InMilliseconds());
61 TruncateFrameEventMapIfNeeded();
64 DCHECK(frame_event_map_.size() <= max_frames_);
67 void EncodingEventSubscriber::OnReceivePacketEvent(
68 const PacketEvent& packet_event) {
69 DCHECK(thread_checker_.CalledOnValidThread());
71 if (ShouldProcessEvent(packet_event.type)) {
72 PacketEventMap::iterator it =
73 packet_event_map_.find(packet_event.rtp_timestamp);
74 linked_ptr<AggregatedPacketEvent> event_proto;
75 BasePacketEvent* base_packet_event_proto = NULL;
77 // Look up existing entry. If not found, create a new entry and add to map.
78 if (it == packet_event_map_.end()) {
79 event_proto.reset(new AggregatedPacketEvent);
80 event_proto->set_rtp_timestamp(packet_event.rtp_timestamp);
81 packet_event_map_.insert(
82 std::make_pair(packet_event.rtp_timestamp, event_proto));
83 base_packet_event_proto = event_proto->add_base_packet_event();
84 base_packet_event_proto->set_packet_id(packet_event.packet_id);
86 // Found existing entry, now look up existing BasePacketEvent using packet
87 // ID. If not found, create a new entry and add to proto.
88 event_proto = it->second;
89 RepeatedPtrField<BasePacketEvent>* field =
90 event_proto->mutable_base_packet_event();
91 for (RepeatedPtrField<BasePacketEvent>::pointer_iterator it =
92 field->pointer_begin();
93 it != field->pointer_end();
95 if ((*it)->packet_id() == packet_event.packet_id) {
96 base_packet_event_proto = *it;
100 if (!base_packet_event_proto) {
101 base_packet_event_proto = event_proto->add_base_packet_event();
102 base_packet_event_proto->set_packet_id(packet_event.packet_id);
106 base_packet_event_proto->add_event_type(
107 ToProtoEventType(packet_event.type));
108 base_packet_event_proto->add_event_timestamp_micros(
109 packet_event.timestamp.ToInternalValue());
111 TruncatePacketEventMapIfNeeded();
114 DCHECK(packet_event_map_.size() <= max_frames_);
117 void EncodingEventSubscriber::OnReceiveGenericEvent(
118 const GenericEvent& generic_event) {
119 DCHECK(thread_checker_.CalledOnValidThread());
120 // Do nothing, there are no generic events we are interested in.
123 void EncodingEventSubscriber::GetFrameEventsAndReset(
124 FrameEventMap* frame_event_map) {
125 DCHECK(thread_checker_.CalledOnValidThread());
126 frame_event_map->swap(frame_event_map_);
127 frame_event_map_.clear();
130 void EncodingEventSubscriber::GetPacketEventsAndReset(
131 PacketEventMap* packet_event_map) {
132 DCHECK(thread_checker_.CalledOnValidThread());
133 packet_event_map->swap(packet_event_map_);
134 packet_event_map_.clear();
138 bool EncodingEventSubscriber::ShouldProcessEvent(CastLoggingEvent event) {
139 return GetEventMediaType(event) == event_media_type_;
142 void EncodingEventSubscriber::TruncateFrameEventMapIfNeeded() {
143 // This works because this is called everytime an event is inserted and
144 // we only insert events one at a time.
145 if (frame_event_map_.size() > max_frames_)
146 frame_event_map_.erase(frame_event_map_.begin());
149 void EncodingEventSubscriber::TruncatePacketEventMapIfNeeded() {
150 // This works because this is called everytime an event is inserted and
151 // we only insert events one at a time.
152 if (packet_event_map_.size() > max_frames_)
153 packet_event_map_.erase(packet_event_map_.begin());