Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / media / cast / rtcp / sender_rtcp_event_subscriber.cc
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.
4
5 #include "media/cast/rtcp/sender_rtcp_event_subscriber.h"
6
7 #include <utility>
8
9 #include "base/logging.h"
10 #include "media/cast/rtcp/rtcp_defines.h"
11
12 namespace media {
13 namespace cast {
14
15 SenderRtcpEventSubscriber::SenderRtcpEventSubscriber(
16     const size_t max_size_to_retain)
17     : max_size_to_retain_(max_size_to_retain) {
18   DCHECK(max_size_to_retain_ > 0u);
19 }
20
21 SenderRtcpEventSubscriber::~SenderRtcpEventSubscriber() {
22   DCHECK(thread_checker_.CalledOnValidThread());
23 }
24
25 void SenderRtcpEventSubscriber::OnReceiveFrameEvent(
26     const FrameEvent& frame_event) {
27   DCHECK(thread_checker_.CalledOnValidThread());
28   if (frame_event.type != kVideoFrameCaptureBegin &&
29       frame_event.type != kVideoFrameSentToEncoder &&
30       frame_event.type != kVideoFrameEncoded) {
31     // Not interested in other events.
32     return;
33   }
34
35   RtcpEventMap::iterator it = rtcp_events_.find(frame_event.rtp_timestamp);
36   if (it == rtcp_events_.end()) {
37     // We have not stored this frame (RTP timestamp) in our map.
38     RtcpEvent rtcp_event;
39     rtcp_event.type = frame_event.type;
40     rtcp_event.timestamp = frame_event.timestamp;
41
42     // Do not need to fill out rtcp_event.delay_delta or rtcp_event.packet_id
43     // as they are not set in frame events we are interested in.
44     rtcp_events_.insert(std::make_pair(frame_event.rtp_timestamp, rtcp_event));
45
46     TruncateMapIfNeeded();
47   } else {
48     // We already have this frame (RTP timestamp) in our map.
49     // Only update events that are later in the chain.
50     // This is due to that events can be reordered on the wire.
51     if (frame_event.type == kVideoFrameCaptureBegin) {
52       return;  // First event in chain can not be late by definition.
53     }
54
55     if (it->second.type == kVideoFrameEncoded) {
56       return;  // Last event in chain should not be updated.
57     }
58
59     // Update existing entry.
60     it->second.type = frame_event.type;
61   }
62
63   DCHECK(rtcp_events_.size() <= max_size_to_retain_);
64 }
65
66 void SenderRtcpEventSubscriber::OnReceivePacketEvent(
67     const PacketEvent& packet_event) {
68   DCHECK(thread_checker_.CalledOnValidThread());
69   // Do nothing as RTP sender is not interested in packet events for RTCP.
70 }
71
72 void SenderRtcpEventSubscriber::GetRtcpEventsAndReset(
73     RtcpEventMap* rtcp_events) {
74   DCHECK(thread_checker_.CalledOnValidThread());
75   rtcp_events->swap(rtcp_events_);
76   rtcp_events_.clear();
77 }
78
79 void SenderRtcpEventSubscriber::TruncateMapIfNeeded() {
80   // If map size has exceeded |max_size_to_retain_|, remove entry with
81   // the smallest RTP timestamp.
82   if (rtcp_events_.size() > max_size_to_retain_) {
83     DVLOG(2) << "RTCP event map exceeded size limit; "
84              << "removing oldest entry";
85     // This is fine since we only insert elements one at a time.
86     rtcp_events_.erase(rtcp_events_.begin());
87   }
88 }
89
90 }  // namespace cast
91 }  // namespace media