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.
5 #include "media/cast/net/rtp/framer.h"
7 #include "base/logging.h"
12 typedef FrameList::const_iterator ConstFrameIterator
;
14 Framer::Framer(base::TickClock
* clock
,
15 RtpPayloadFeedback
* incoming_payload_feedback
,
17 bool decoder_faster_than_max_frame_rate
,
18 int max_unacked_frames
)
19 : decoder_faster_than_max_frame_rate_(decoder_faster_than_max_frame_rate
),
21 new CastMessageBuilder(clock
,
22 incoming_payload_feedback
,
25 decoder_faster_than_max_frame_rate
,
27 waiting_for_key_(true),
28 last_released_frame_(kStartFrameId
),
29 newest_frame_id_(kStartFrameId
) {
30 DCHECK(incoming_payload_feedback
) << "Invalid argument";
35 bool Framer::InsertPacket(const uint8
* payload_data
,
37 const RtpCastHeader
& rtp_header
,
40 uint32 frame_id
= rtp_header
.frame_id
;
42 if (rtp_header
.is_key_frame
&& waiting_for_key_
) {
43 last_released_frame_
= static_cast<uint32
>(frame_id
- 1);
44 waiting_for_key_
= false;
47 VLOG(1) << "InsertPacket frame:" << frame_id
48 << " packet:" << static_cast<int>(rtp_header
.packet_id
)
49 << " max packet:" << static_cast<int>(rtp_header
.max_packet_id
);
51 if (IsOlderFrameId(frame_id
, last_released_frame_
) && !waiting_for_key_
) {
56 // Update the last received frame id.
57 if (IsNewerFrameId(frame_id
, newest_frame_id_
)) {
58 newest_frame_id_
= frame_id
;
61 // Does this packet belong to a new frame?
62 FrameList::iterator it
= frames_
.find(frame_id
);
63 if (it
== frames_
.end()) {
65 linked_ptr
<FrameBuffer
> frame_info(new FrameBuffer
);
66 std::pair
<FrameList::iterator
, bool> retval
=
67 frames_
.insert(std::make_pair(frame_id
, frame_info
));
72 if (!it
->second
->InsertPacket(payload_data
, payload_size
, rtp_header
)) {
73 VLOG(3) << "Packet already received, ignored: frame "
74 << static_cast<int>(rtp_header
.frame_id
) << ", packet "
75 << rtp_header
.packet_id
;
80 return it
->second
->Complete();
83 // This does not release the frame.
84 bool Framer::GetEncodedFrame(EncodedFrame
* frame
,
86 bool* have_multiple_decodable_frames
) {
87 *have_multiple_decodable_frames
= HaveMultipleDecodableFrames();
91 if (NextContinuousFrame(&frame_id
)) {
92 // We have our next frame.
95 // Check if we can skip frames when our decoder is too slow.
96 if (!decoder_faster_than_max_frame_rate_
)
99 if (!NextFrameAllowingSkippingFrames(&frame_id
)) {
105 ConstFrameIterator it
= frames_
.find(frame_id
);
106 DCHECK(it
!= frames_
.end());
107 if (it
== frames_
.end())
110 return it
->second
->AssembleEncodedFrame(frame
);
113 void Framer::AckFrame(uint32 frame_id
) {
114 VLOG(2) << "ACK frame " << frame_id
;
115 cast_msg_builder_
->CompleteFrameReceived(frame_id
);
118 void Framer::Reset() {
119 waiting_for_key_
= true;
120 last_released_frame_
= kStartFrameId
;
121 newest_frame_id_
= kStartFrameId
;
123 cast_msg_builder_
->Reset();
126 void Framer::ReleaseFrame(uint32 frame_id
) {
127 RemoveOldFrames(frame_id
);
128 frames_
.erase(frame_id
);
130 // We have a frame - remove all frames with lower frame id.
131 bool skipped_old_frame
= false;
132 FrameList::iterator it
;
133 for (it
= frames_
.begin(); it
!= frames_
.end();) {
134 if (IsOlderFrameId(it
->first
, frame_id
)) {
136 skipped_old_frame
= true;
141 if (skipped_old_frame
) {
142 cast_msg_builder_
->UpdateCastMessage();
146 bool Framer::TimeToSendNextCastMessage(base::TimeTicks
* time_to_send
) {
147 return cast_msg_builder_
->TimeToSendNextCastMessage(time_to_send
);
150 void Framer::SendCastMessage() { cast_msg_builder_
->UpdateCastMessage(); }
152 void Framer::RemoveOldFrames(uint32 frame_id
) {
153 FrameList::iterator it
= frames_
.begin();
155 while (it
!= frames_
.end()) {
156 if (IsNewerFrameId(it
->first
, frame_id
)) {
159 // Older or equal; erase.
163 last_released_frame_
= frame_id
;
166 uint32
Framer::NewestFrameId() const { return newest_frame_id_
; }
168 bool Framer::NextContinuousFrame(uint32
* frame_id
) const {
169 FrameList::const_iterator it
;
171 for (it
= frames_
.begin(); it
!= frames_
.end(); ++it
) {
172 if (it
->second
->Complete() && ContinuousFrame(it
->second
.get())) {
173 *frame_id
= it
->first
;
180 bool Framer::HaveMultipleDecodableFrames() const {
181 // Find the oldest decodable frame.
182 FrameList::const_iterator it
;
183 bool found_one
= false;
184 for (it
= frames_
.begin(); it
!= frames_
.end(); ++it
) {
185 if (it
->second
->Complete() && DecodableFrame(it
->second
.get())) {
196 uint32
Framer::LastContinuousFrame() const {
197 uint32 last_continuous_frame_id
= last_released_frame_
;
198 uint32 next_expected_frame
= last_released_frame_
;
200 FrameList::const_iterator it
;
203 next_expected_frame
++;
204 it
= frames_
.find(next_expected_frame
);
205 if (it
== frames_
.end())
207 if (!it
->second
->Complete())
210 // We found the next continuous frame.
211 last_continuous_frame_id
= it
->first
;
212 } while (next_expected_frame
!= newest_frame_id_
);
213 return last_continuous_frame_id
;
216 bool Framer::NextFrameAllowingSkippingFrames(uint32
* frame_id
) const {
217 // Find the oldest decodable frame.
218 FrameList::const_iterator it_best_match
= frames_
.end();
219 FrameList::const_iterator it
;
220 for (it
= frames_
.begin(); it
!= frames_
.end(); ++it
) {
221 if (it
->second
->Complete() && DecodableFrame(it
->second
.get())) {
222 if (it_best_match
== frames_
.end() ||
223 IsOlderFrameId(it
->first
, it_best_match
->first
)) {
228 if (it_best_match
== frames_
.end())
231 *frame_id
= it_best_match
->first
;
235 bool Framer::Empty() const { return frames_
.empty(); }
237 int Framer::NumberOfCompleteFrames() const {
239 FrameList::const_iterator it
;
240 for (it
= frames_
.begin(); it
!= frames_
.end(); ++it
) {
241 if (it
->second
->Complete()) {
248 bool Framer::FrameExists(uint32 frame_id
) const {
249 return frames_
.end() != frames_
.find(frame_id
);
252 void Framer::GetMissingPackets(uint32 frame_id
,
254 PacketIdSet
* missing_packets
) const {
255 FrameList::const_iterator it
= frames_
.find(frame_id
);
256 if (it
== frames_
.end())
259 it
->second
->GetMissingPackets(last_frame
, missing_packets
);
262 bool Framer::ContinuousFrame(FrameBuffer
* frame
) const {
264 if (waiting_for_key_
&& !frame
->is_key_frame())
266 return static_cast<uint32
>(last_released_frame_
+ 1) == frame
->frame_id();
269 bool Framer::DecodableFrame(FrameBuffer
* frame
) const {
270 if (frame
->is_key_frame())
272 if (waiting_for_key_
&& !frame
->is_key_frame())
275 if (frame
->last_referenced_frame_id() == frame
->frame_id())
278 // Current frame is not necessarily referencing the last frame.
279 // Do we have the reference frame?
280 if (IsOlderFrameId(frame
->last_referenced_frame_id(), last_released_frame_
)) {
283 return frame
->last_referenced_frame_id() == last_released_frame_
;