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 { return missing_packets_
.empty(); }
43 void FrameInfo::GetMissingPackets(bool newest_frame
,
44 PacketIdSet
* missing_packets
) const {
46 // Missing packets capped by max_received_packet_id_.
47 PacketIdSet::const_iterator it_after_last_received
=
48 missing_packets_
.lower_bound(max_received_packet_id_
);
49 missing_packets
->insert(missing_packets_
.begin(), it_after_last_received
);
51 missing_packets
->insert(missing_packets_
.begin(), missing_packets_
.end());
55 FrameIdMap::FrameIdMap()
56 : waiting_for_key_(true),
57 last_released_frame_(kStartFrameId
),
58 newest_frame_id_(kStartFrameId
) {}
60 FrameIdMap::~FrameIdMap() {}
62 PacketType
FrameIdMap::InsertPacket(const RtpCastHeader
& rtp_header
) {
63 uint32 frame_id
= rtp_header
.frame_id
;
64 uint32 reference_frame_id
;
65 reference_frame_id
= rtp_header
.reference_frame_id
;
67 if (rtp_header
.is_key_frame
&& waiting_for_key_
) {
68 last_released_frame_
= static_cast<uint32
>(frame_id
- 1);
69 waiting_for_key_
= false;
72 VLOG(3) << "InsertPacket frame:" << frame_id
73 << " packet:" << static_cast<int>(rtp_header
.packet_id
)
74 << " max packet:" << static_cast<int>(rtp_header
.max_packet_id
);
76 if (IsOlderFrameId(frame_id
, last_released_frame_
) && !waiting_for_key_
) {
80 // Update the last received frame id.
81 if (IsNewerFrameId(frame_id
, newest_frame_id_
)) {
82 newest_frame_id_
= frame_id
;
85 // Does this packet belong to a new frame?
86 FrameMap::iterator it
= frame_map_
.find(frame_id
);
87 PacketType packet_type
;
88 if (it
== frame_map_
.end()) {
90 linked_ptr
<FrameInfo
> frame_info(new FrameInfo(frame_id
,
92 rtp_header
.max_packet_id
,
93 rtp_header
.is_key_frame
));
94 std::pair
<FrameMap::iterator
, bool> retval
=
95 frame_map_
.insert(std::make_pair(frame_id
, frame_info
));
97 packet_type
= retval
.first
->second
->InsertPacket(rtp_header
.packet_id
);
99 // Insert packet to existing frame.
100 packet_type
= it
->second
->InsertPacket(rtp_header
.packet_id
);
105 void FrameIdMap::RemoveOldFrames(uint32 frame_id
) {
106 FrameMap::iterator it
= frame_map_
.begin();
108 while (it
!= frame_map_
.end()) {
109 if (IsNewerFrameId(it
->first
, frame_id
)) {
112 // Older or equal; erase.
113 frame_map_
.erase(it
++);
116 last_released_frame_
= frame_id
;
119 void FrameIdMap::Clear() {
121 waiting_for_key_
= true;
122 last_released_frame_
= kStartFrameId
;
123 newest_frame_id_
= kStartFrameId
;
126 uint32
FrameIdMap::NewestFrameId() const { return newest_frame_id_
; }
128 bool FrameIdMap::NextContinuousFrame(uint32
* frame_id
) const {
129 FrameMap::const_iterator it
;
131 for (it
= frame_map_
.begin(); it
!= frame_map_
.end(); ++it
) {
132 if (it
->second
->Complete() && ContinuousFrame(it
->second
.get())) {
133 *frame_id
= it
->first
;
140 bool FrameIdMap::HaveMultipleDecodableFrames() const {
141 // Find the oldest decodable frame.
142 FrameMap::const_iterator it
;
143 bool found_one
= false;
144 for (it
= frame_map_
.begin(); it
!= frame_map_
.end(); ++it
) {
145 if (it
->second
->Complete() && DecodableFrame(it
->second
.get())) {
156 uint32
FrameIdMap::LastContinuousFrame() const {
157 uint32 last_continuous_frame_id
= last_released_frame_
;
158 uint32 next_expected_frame
= last_released_frame_
;
160 FrameMap::const_iterator it
;
163 next_expected_frame
++;
164 it
= frame_map_
.find(next_expected_frame
);
165 if (it
== frame_map_
.end())
167 if (!it
->second
->Complete())
170 // We found the next continuous frame.
171 last_continuous_frame_id
= it
->first
;
172 } while (next_expected_frame
!= newest_frame_id_
);
173 return last_continuous_frame_id
;
176 bool FrameIdMap::NextFrameAllowingSkippingFrames(uint32
* frame_id
) const {
177 // Find the oldest decodable frame.
178 FrameMap::const_iterator it_best_match
= frame_map_
.end();
179 FrameMap::const_iterator it
;
180 for (it
= frame_map_
.begin(); it
!= frame_map_
.end(); ++it
) {
181 if (it
->second
->Complete() && DecodableFrame(it
->second
.get())) {
182 if (it_best_match
== frame_map_
.end() ||
183 IsOlderFrameId(it
->first
, it_best_match
->first
)) {
188 if (it_best_match
== frame_map_
.end())
191 *frame_id
= it_best_match
->first
;
195 bool FrameIdMap::Empty() const { return frame_map_
.empty(); }
197 int FrameIdMap::NumberOfCompleteFrames() const {
199 FrameMap::const_iterator it
;
200 for (it
= frame_map_
.begin(); it
!= frame_map_
.end(); ++it
) {
201 if (it
->second
->Complete()) {
208 bool FrameIdMap::FrameExists(uint32 frame_id
) const {
209 return frame_map_
.end() != frame_map_
.find(frame_id
);
212 void FrameIdMap::GetMissingPackets(uint32 frame_id
,
214 PacketIdSet
* missing_packets
) const {
215 FrameMap::const_iterator it
= frame_map_
.find(frame_id
);
216 if (it
== frame_map_
.end())
219 it
->second
->GetMissingPackets(last_frame
, missing_packets
);
222 bool FrameIdMap::ContinuousFrame(FrameInfo
* frame
) const {
224 if (waiting_for_key_
&& !frame
->is_key_frame())
226 return static_cast<uint32
>(last_released_frame_
+ 1) == frame
->frame_id();
229 bool FrameIdMap::DecodableFrame(FrameInfo
* frame
) const {
230 if (frame
->is_key_frame())
232 if (waiting_for_key_
&& !frame
->is_key_frame())
235 if (frame
->referenced_frame_id() == frame
->frame_id())
238 // Current frame is not necessarily referencing the last frame.
239 // Do we have the reference frame?
240 if (IsOlderFrameId(frame
->referenced_frame_id(), last_released_frame_
)) {
243 return frame
->referenced_frame_id() == last_released_frame_
;