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.
5 #include "media/cast/framer/frame_id_map.h"
7 #include "base/logging.h"
8 #include "media/cast/rtp_receiver/rtp_receiver_defines.h"
13 FrameInfo::FrameInfo(uint32 frame_id
,
14 uint32 referenced_frame_id
,
17 : is_key_frame_(key_frame
),
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
);
27 FrameInfo::~FrameInfo() {}
29 PacketType
FrameInfo::InsertPacket(uint16 packet_id
) {
30 if (missing_packets_
.find(packet_id
) == missing_packets_
.end()) {
31 return kDuplicatePacket
;
33 // Update the last received packet id.
34 if (IsNewerPacketId(packet_id
, max_received_packet_id_
)) {
35 max_received_packet_id_
= packet_id
;
37 missing_packets_
.erase(packet_id
);
38 return missing_packets_
.empty() ? kNewPacketCompletingFrame
: kNewPacket
;
41 bool FrameInfo::Complete() const {
42 return missing_packets_
.empty();
45 void FrameInfo::GetMissingPackets(bool newest_frame
,
46 PacketIdSet
* missing_packets
) const {
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
);
53 missing_packets
->insert(missing_packets_
.begin(), missing_packets_
.end());
58 FrameIdMap::FrameIdMap()
59 : waiting_for_key_(true),
60 last_released_frame_(kStartFrameId
),
61 newest_frame_id_(kStartFrameId
) {
64 FrameIdMap::~FrameIdMap() {}
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
;
72 reference_frame_id
= static_cast<uint32
>(frame_id
- 1);
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;
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
);
84 if (IsOlderFrameId(frame_id
, last_released_frame_
) && !waiting_for_key_
) {
88 // Update the last received frame id.
89 if (IsNewerFrameId(frame_id
, newest_frame_id_
)) {
90 newest_frame_id_
= frame_id
;
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()) {
98 linked_ptr
<FrameInfo
> frame_info(new FrameInfo(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
));
105 packet_type
= retval
.first
->second
->InsertPacket(rtp_header
.packet_id
);
107 // Insert packet to existing frame.
108 packet_type
= it
->second
->InsertPacket(rtp_header
.packet_id
);
113 void FrameIdMap::RemoveOldFrames(uint32 frame_id
) {
114 FrameMap::iterator it
= frame_map_
.begin();
116 while (it
!= frame_map_
.end()) {
117 if (IsNewerFrameId(it
->first
, frame_id
)) {
120 // Older or equal; erase.
121 frame_map_
.erase(it
++);
124 last_released_frame_
= frame_id
;
127 void FrameIdMap::Clear() {
129 waiting_for_key_
= true;
130 last_released_frame_
= kStartFrameId
;
131 newest_frame_id_
= kStartFrameId
;
134 uint32
FrameIdMap::NewestFrameId() const {
135 return newest_frame_id_
;
138 bool FrameIdMap::NextContinuousFrame(uint32
* frame_id
) const {
139 FrameMap::const_iterator it
;
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
;
150 uint32
FrameIdMap::LastContinuousFrame() const {
151 uint32 last_continuous_frame_id
= last_released_frame_
;
152 uint32 next_expected_frame
= last_released_frame_
;
154 FrameMap::const_iterator it
;
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;
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
;
168 bool FrameIdMap::NextAudioFrameAllowingMissingFrames(uint32
* frame_id
) const {
169 // First check if we have continuous frames.
170 if (NextContinuousFrame(frame_id
)) return true;
172 // Find the oldest frame.
173 FrameMap::const_iterator it_best_match
= frame_map_
.end();
174 FrameMap::const_iterator it
;
176 // Find first complete frame.
177 for (it
= frame_map_
.begin(); it
!= frame_map_
.end(); ++it
) {
178 if (it
->second
->Complete()) {
183 if (it_best_match
== frame_map_
.end()) return false; // No complete frame.
186 for (; it
!= frame_map_
.end(); ++it
) {
187 if (it
->second
->Complete() &&
188 IsOlderFrameId(it
->first
, it_best_match
->first
)) {
192 *frame_id
= it_best_match
->first
;
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())) {
205 if (it_best_match
== frame_map_
.end()) return false;
207 *frame_id
= it_best_match
->first
;
211 bool FrameIdMap::Empty() const {
212 return frame_map_
.empty();
215 int FrameIdMap::NumberOfCompleteFrames() const {
217 FrameMap::const_iterator it
;
218 for (it
= frame_map_
.begin(); it
!= frame_map_
.end(); ++it
) {
219 if (it
->second
->Complete()) {
226 bool FrameIdMap::FrameExists(uint32 frame_id
) const {
227 return frame_map_
.end() != frame_map_
.find(frame_id
);
230 void FrameIdMap::GetMissingPackets(uint32 frame_id
,
232 PacketIdSet
* missing_packets
) const {
233 FrameMap::const_iterator it
= frame_map_
.find(frame_id
);
234 if (it
== frame_map_
.end()) return;
236 it
->second
->GetMissingPackets(last_frame
, missing_packets
);
239 bool FrameIdMap::ContinuousFrame(FrameInfo
* frame
) const {
241 if (waiting_for_key_
&& !frame
->is_key_frame()) return false;
242 return static_cast<uint32
>(last_released_frame_
+ 1) == frame
->frame_id();
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;
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_
)) {
254 return frame
->referenced_frame_id() == last_released_frame_
;