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 uint32
FrameIdMap::LastContinuousFrame() const {
141 uint32 last_continuous_frame_id
= last_released_frame_
;
142 uint32 next_expected_frame
= last_released_frame_
;
144 FrameMap::const_iterator it
;
147 next_expected_frame
++;
148 it
= frame_map_
.find(next_expected_frame
);
149 if (it
== frame_map_
.end())
151 if (!it
->second
->Complete())
154 // We found the next continuous frame.
155 last_continuous_frame_id
= it
->first
;
156 } while (next_expected_frame
!= newest_frame_id_
);
157 return last_continuous_frame_id
;
160 bool FrameIdMap::NextAudioFrameAllowingMissingFrames(uint32
* frame_id
) const {
161 // First check if we have continuous frames.
162 if (NextContinuousFrame(frame_id
))
165 // Find the oldest frame.
166 FrameMap::const_iterator it_best_match
= frame_map_
.end();
167 FrameMap::const_iterator it
;
169 // Find first complete frame.
170 for (it
= frame_map_
.begin(); it
!= frame_map_
.end(); ++it
) {
171 if (it
->second
->Complete()) {
176 if (it_best_match
== frame_map_
.end())
177 return false; // No complete frame.
180 for (; it
!= frame_map_
.end(); ++it
) {
181 if (it
->second
->Complete() &&
182 IsOlderFrameId(it
->first
, it_best_match
->first
)) {
186 *frame_id
= it_best_match
->first
;
190 bool FrameIdMap::NextVideoFrameAllowingSkippingFrames(uint32
* frame_id
) const {
191 // Find the oldest decodable frame.
192 FrameMap::const_iterator it_best_match
= frame_map_
.end();
193 FrameMap::const_iterator it
;
194 for (it
= frame_map_
.begin(); it
!= frame_map_
.end(); ++it
) {
195 if (it
->second
->Complete() && DecodableVideoFrame(it
->second
.get())) {
199 if (it_best_match
== frame_map_
.end())
202 *frame_id
= it_best_match
->first
;
206 bool FrameIdMap::Empty() const { return frame_map_
.empty(); }
208 int FrameIdMap::NumberOfCompleteFrames() const {
210 FrameMap::const_iterator it
;
211 for (it
= frame_map_
.begin(); it
!= frame_map_
.end(); ++it
) {
212 if (it
->second
->Complete()) {
219 bool FrameIdMap::FrameExists(uint32 frame_id
) const {
220 return frame_map_
.end() != frame_map_
.find(frame_id
);
223 void FrameIdMap::GetMissingPackets(uint32 frame_id
,
225 PacketIdSet
* missing_packets
) const {
226 FrameMap::const_iterator it
= frame_map_
.find(frame_id
);
227 if (it
== frame_map_
.end())
230 it
->second
->GetMissingPackets(last_frame
, missing_packets
);
233 bool FrameIdMap::ContinuousFrame(FrameInfo
* frame
) const {
235 if (waiting_for_key_
&& !frame
->is_key_frame())
237 return static_cast<uint32
>(last_released_frame_
+ 1) == frame
->frame_id();
240 bool FrameIdMap::DecodableVideoFrame(FrameInfo
* frame
) const {
241 if (frame
->is_key_frame())
243 if (waiting_for_key_
&& !frame
->is_key_frame())
246 // Current frame is not necessarily referencing the last frame.
247 // Do we have the reference frame?
248 if (IsOlderFrameId(frame
->referenced_frame_id(), last_released_frame_
)) {
251 return frame
->referenced_frame_id() == last_released_frame_
;