Unregister from GCM when the only GCM app is removed
[chromium-blink-merge.git] / media / cast / net / rtcp / receiver_rtcp_event_subscriber.cc
blobc96b71f3b54b5c81962a81ac7ca763571a9d9005
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/net/rtcp/receiver_rtcp_event_subscriber.h"
7 #include <utility>
9 namespace media {
10 namespace cast {
12 ReceiverRtcpEventSubscriber::ReceiverRtcpEventSubscriber(
13 const size_t max_size_to_retain, EventMediaType type)
14 : max_size_to_retain_(
15 max_size_to_retain * (kResendDelay * kNumResends + 1)),
16 type_(type),
17 popped_events_(0) {
18 DCHECK(max_size_to_retain_ > 0u);
19 DCHECK(type_ == AUDIO_EVENT || type_ == VIDEO_EVENT);
20 for (size_t i = 0; i < kNumResends; i++) {
21 send_ptrs_[i] = 0;
25 ReceiverRtcpEventSubscriber::~ReceiverRtcpEventSubscriber() {
26 DCHECK(thread_checker_.CalledOnValidThread());
29 void ReceiverRtcpEventSubscriber::OnReceiveFrameEvent(
30 const FrameEvent& frame_event) {
31 DCHECK(thread_checker_.CalledOnValidThread());
33 if (ShouldProcessEvent(frame_event.type, frame_event.media_type)) {
34 RtcpEvent rtcp_event;
35 switch (frame_event.type) {
36 case FRAME_PLAYOUT:
37 rtcp_event.delay_delta = frame_event.delay_delta;
38 case FRAME_ACK_SENT:
39 case FRAME_DECODED:
40 rtcp_event.type = frame_event.type;
41 rtcp_event.timestamp = frame_event.timestamp;
42 rtcp_events_.push_back(
43 std::make_pair(frame_event.rtp_timestamp, rtcp_event));
44 break;
45 default:
46 break;
50 TruncateMapIfNeeded();
53 void ReceiverRtcpEventSubscriber::OnReceivePacketEvent(
54 const PacketEvent& packet_event) {
55 DCHECK(thread_checker_.CalledOnValidThread());
57 if (ShouldProcessEvent(packet_event.type, packet_event.media_type)) {
58 RtcpEvent rtcp_event;
59 if (packet_event.type == PACKET_RECEIVED) {
60 rtcp_event.type = packet_event.type;
61 rtcp_event.timestamp = packet_event.timestamp;
62 rtcp_event.packet_id = packet_event.packet_id;
63 rtcp_events_.push_back(
64 std::make_pair(packet_event.rtp_timestamp, rtcp_event));
68 TruncateMapIfNeeded();
71 struct CompareByFirst {
72 bool operator()(const std::pair<RtpTimestamp, RtcpEvent>& a,
73 const std::pair<RtpTimestamp, RtcpEvent>& b) {
74 return a.first < b.first;
78 void ReceiverRtcpEventSubscriber::GetRtcpEventsWithRedundancy(
79 RtcpEvents* rtcp_events) {
80 DCHECK(thread_checker_.CalledOnValidThread());
81 DCHECK(rtcp_events);
83 uint64 event_level = rtcp_events_.size() + popped_events_;
84 event_levels_for_past_frames_.push_back(event_level);
86 for (size_t i = 0; i < kNumResends; i++) {
87 size_t resend_delay = kResendDelay * i;
88 if (event_levels_for_past_frames_.size() < resend_delay + 1)
89 break;
91 uint64 send_limit = event_levels_for_past_frames_[
92 event_levels_for_past_frames_.size() - 1 - resend_delay];
94 if (send_ptrs_[i] < popped_events_) {
95 send_ptrs_[i] = popped_events_;
98 while (send_ptrs_[i] < send_limit &&
99 rtcp_events->size() < kMaxEventsPerRTCP) {
100 rtcp_events->push_back(rtcp_events_[send_ptrs_[i] - popped_events_]);
101 send_ptrs_[i]++;
103 send_limit = send_ptrs_[i];
106 if (event_levels_for_past_frames_.size() > kResendDelay * (kNumResends + 1)) {
107 while (popped_events_ < event_levels_for_past_frames_[0]) {
108 rtcp_events_.pop_front();
109 popped_events_++;
111 event_levels_for_past_frames_.pop_front();
114 std::sort(rtcp_events->begin(), rtcp_events->end(), CompareByFirst());
117 void ReceiverRtcpEventSubscriber::TruncateMapIfNeeded() {
118 // If map size has exceeded |max_size_to_retain_|, remove entry with
119 // the smallest RTP timestamp.
120 if (rtcp_events_.size() > max_size_to_retain_) {
121 DVLOG(3) << "RTCP event map exceeded size limit; "
122 << "removing oldest entry";
123 // This is fine since we only insert elements one at a time.
124 rtcp_events_.pop_front();
125 popped_events_++;
128 DCHECK(rtcp_events_.size() <= max_size_to_retain_);
131 bool ReceiverRtcpEventSubscriber::ShouldProcessEvent(
132 CastLoggingEvent event_type, EventMediaType event_media_type) {
133 return type_ == event_media_type &&
134 (event_type == FRAME_ACK_SENT || event_type == FRAME_DECODED ||
135 event_type == FRAME_PLAYOUT || event_type == PACKET_RECEIVED);
138 } // namespace cast
139 } // namespace media