Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / media / cast / framer / frame_id_map.cc
1 // Copyright 2013 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/framer/frame_id_map.h"
6
7 #include "base/logging.h"
8 #include "media/cast/rtp_receiver/rtp_receiver_defines.h"
9
10 namespace media {
11 namespace cast {
12
13 FrameInfo::FrameInfo(uint32 frame_id,
14                      uint32 referenced_frame_id,
15                      uint16 max_packet_id,
16                      bool key_frame)
17     : is_key_frame_(key_frame),
18       frame_id_(frame_id),
19       referenced_frame_id_(referenced_frame_id),
20       max_received_packet_id_(0) {
21   // Create the set with all packets missing.
22   for (uint16 i = 0; i <= max_packet_id; i++) {
23     missing_packets_.insert(i);
24   }
25 }
26
27 FrameInfo::~FrameInfo() {}
28
29 PacketType FrameInfo::InsertPacket(uint16 packet_id) {
30   if (missing_packets_.find(packet_id) == missing_packets_.end()) {
31     return kDuplicatePacket;
32   }
33   // Update the last received packet id.
34   if (IsNewerPacketId(packet_id, max_received_packet_id_)) {
35     max_received_packet_id_ = packet_id;
36   }
37   missing_packets_.erase(packet_id);
38   return missing_packets_.empty() ? kNewPacketCompletingFrame : kNewPacket;
39 }
40
41 bool FrameInfo::Complete() const {
42   return missing_packets_.empty();
43 }
44
45 void FrameInfo::GetMissingPackets(bool newest_frame,
46                                   PacketIdSet* missing_packets) const {
47   if (newest_frame) {
48     // Missing packets capped by max_received_packet_id_.
49     PacketIdSet::const_iterator it_after_last_received =
50         missing_packets_.lower_bound(max_received_packet_id_);
51     missing_packets->insert(missing_packets_.begin(), it_after_last_received);
52   } else {
53     missing_packets->insert(missing_packets_.begin(), missing_packets_.end());
54   }
55 }
56
57
58 FrameIdMap::FrameIdMap()
59     : waiting_for_key_(true),
60       last_released_frame_(kStartFrameId),
61       newest_frame_id_(kStartFrameId) {
62 }
63
64 FrameIdMap::~FrameIdMap() {}
65
66 PacketType FrameIdMap::InsertPacket(const RtpCastHeader& rtp_header) {
67   uint32 frame_id = rtp_header.frame_id;
68   uint32 reference_frame_id;
69   if (rtp_header.is_reference) {
70     reference_frame_id = rtp_header.reference_frame_id;
71   } else {
72     reference_frame_id = static_cast<uint32>(frame_id - 1);
73   }
74
75   if (rtp_header.is_key_frame && waiting_for_key_) {
76     last_released_frame_ = static_cast<uint32>(frame_id - 1);
77     waiting_for_key_ = false;
78   }
79
80   VLOG(1) << "InsertPacket frame:" << frame_id
81           << " packet:" << static_cast<int>(rtp_header.packet_id)
82           << " max packet:" << static_cast<int>(rtp_header.max_packet_id);
83
84   if (IsOlderFrameId(frame_id, last_released_frame_) && !waiting_for_key_) {
85     return kTooOldPacket;
86   }
87
88   // Update the last received frame id.
89   if (IsNewerFrameId(frame_id, newest_frame_id_)) {
90     newest_frame_id_ = frame_id;
91   }
92
93   // Does this packet belong to a new frame?
94   FrameMap::iterator it = frame_map_.find(frame_id);
95   PacketType packet_type;
96   if (it == frame_map_.end()) {
97     // New frame.
98     linked_ptr<FrameInfo> frame_info(new FrameInfo(frame_id,
99                                                    reference_frame_id,
100                                                    rtp_header.max_packet_id,
101                                                    rtp_header.is_key_frame));
102     std::pair<FrameMap::iterator, bool> retval =
103         frame_map_.insert(std::make_pair(frame_id, frame_info));
104
105     packet_type = retval.first->second->InsertPacket(rtp_header.packet_id);
106   } else {
107     // Insert packet to existing frame.
108     packet_type = it->second->InsertPacket(rtp_header.packet_id);
109   }
110   return packet_type;
111 }
112
113 void FrameIdMap::RemoveOldFrames(uint32 frame_id) {
114   FrameMap::iterator it = frame_map_.begin();
115
116   while (it != frame_map_.end()) {
117     if (IsNewerFrameId(it->first, frame_id)) {
118       ++it;
119     } else {
120       // Older or equal; erase.
121       frame_map_.erase(it++);
122     }
123   }
124   last_released_frame_ = frame_id;
125 }
126
127 void FrameIdMap::Clear() {
128   frame_map_.clear();
129   waiting_for_key_ = true;
130   last_released_frame_ = kStartFrameId;
131   newest_frame_id_ = kStartFrameId;
132 }
133
134 uint32 FrameIdMap::NewestFrameId() const {
135   return newest_frame_id_;
136 }
137
138 bool FrameIdMap::NextContinuousFrame(uint32* frame_id) const {
139   FrameMap::const_iterator it;
140
141   for (it = frame_map_.begin(); it != frame_map_.end(); ++it) {
142     if (it->second->Complete() && ContinuousFrame(it->second.get())) {
143       *frame_id = it->first;
144       return true;
145     }
146   }
147   return false;
148 }
149
150 uint32 FrameIdMap::LastContinuousFrame() const {
151   uint32 last_continuous_frame_id = last_released_frame_;
152   uint32 next_expected_frame = last_released_frame_;
153
154   FrameMap::const_iterator it;
155
156   do {
157     next_expected_frame++;
158     it = frame_map_.find(next_expected_frame);
159     if (it == frame_map_.end()) break;
160     if (!it->second->Complete()) break;
161
162     // We found the next continuous frame.
163     last_continuous_frame_id = it->first;
164   } while (next_expected_frame != newest_frame_id_);
165   return last_continuous_frame_id;
166 }
167
168 bool FrameIdMap::NextAudioFrameAllowingMissingFrames(uint32* frame_id) const {
169   // First check if we have continuous frames.
170   if (NextContinuousFrame(frame_id)) return true;
171
172   // Find the oldest frame.
173   FrameMap::const_iterator it_best_match = frame_map_.end();
174   FrameMap::const_iterator it;
175
176   // Find first complete frame.
177   for (it = frame_map_.begin(); it != frame_map_.end(); ++it) {
178     if (it->second->Complete()) {
179       it_best_match = it;
180       break;
181     }
182   }
183   if (it_best_match == frame_map_.end()) return false;  // No complete frame.
184
185   ++it;
186   for (; it != frame_map_.end(); ++it) {
187     if (it->second->Complete() &&
188         IsOlderFrameId(it->first, it_best_match->first)) {
189       it_best_match = it;
190     }
191   }
192   *frame_id = it_best_match->first;
193   return true;
194 }
195
196 bool FrameIdMap::NextVideoFrameAllowingSkippingFrames(uint32* frame_id) const {
197   // Find the oldest decodable frame.
198   FrameMap::const_iterator it_best_match = frame_map_.end();
199   FrameMap::const_iterator it;
200   for (it = frame_map_.begin(); it != frame_map_.end(); ++it) {
201     if (it->second->Complete() && DecodableVideoFrame(it->second.get())) {
202       it_best_match = it;
203     }
204   }
205   if (it_best_match == frame_map_.end()) return false;
206
207   *frame_id = it_best_match->first;
208   return true;
209 }
210
211 bool FrameIdMap::Empty() const {
212   return frame_map_.empty();
213 }
214
215 int FrameIdMap::NumberOfCompleteFrames() const {
216   int count = 0;
217   FrameMap::const_iterator it;
218   for (it = frame_map_.begin(); it != frame_map_.end(); ++it) {
219     if (it->second->Complete()) {
220       ++count;
221     }
222   }
223   return count;
224 }
225
226 bool FrameIdMap::FrameExists(uint32 frame_id) const {
227   return frame_map_.end() != frame_map_.find(frame_id);
228 }
229
230 void FrameIdMap::GetMissingPackets(uint32 frame_id,
231                                    bool last_frame,
232                                    PacketIdSet* missing_packets) const {
233   FrameMap::const_iterator it = frame_map_.find(frame_id);
234   if (it == frame_map_.end()) return;
235
236   it->second->GetMissingPackets(last_frame, missing_packets);
237 }
238
239 bool FrameIdMap::ContinuousFrame(FrameInfo* frame) const {
240   DCHECK(frame);
241   if (waiting_for_key_ && !frame->is_key_frame()) return false;
242   return static_cast<uint32>(last_released_frame_ + 1) == frame->frame_id();
243 }
244
245 bool FrameIdMap::DecodableVideoFrame(FrameInfo* frame) const {
246   if (frame->is_key_frame()) return true;
247   if (waiting_for_key_ && !frame->is_key_frame()) return false;
248
249   // Current frame is not necessarily referencing the last frame.
250   // Do we have the reference frame?
251   if (IsOlderFrameId(frame->referenced_frame_id(), last_released_frame_)) {
252     return true;
253   }
254   return frame->referenced_frame_id() == last_released_frame_;
255 }
256
257 }  //  namespace cast
258 }  //  namespace media