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.
4
5#include "media/cast/net/rtp/framer.h"
6
7#include "base/logging.h"
8
9namespace media {
10namespace cast {
11
12typedef FrameList::const_iterator ConstFrameIterator;
13
14Framer::Framer(base::TickClock* clock,
15               RtpPayloadFeedback* incoming_payload_feedback,
16               uint32 ssrc,
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),
20      cast_msg_builder_(
21          new CastMessageBuilder(clock,
22                                 incoming_payload_feedback,
23                                 this,
24                                 ssrc,
25                                 decoder_faster_than_max_frame_rate,
26                                 max_unacked_frames)),
27      waiting_for_key_(true),
28      last_released_frame_(kStartFrameId),
29      newest_frame_id_(kStartFrameId) {
30  DCHECK(incoming_payload_feedback) << "Invalid argument";
31}
32
33Framer::~Framer() {}
34
35bool Framer::InsertPacket(const uint8* payload_data,
36                          size_t payload_size,
37                          const RtpCastHeader& rtp_header,
38                          bool* duplicate) {
39  *duplicate = false;
40  uint32 frame_id = rtp_header.frame_id;
41
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;
45  }
46
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);
50
51  if (IsOlderFrameId(frame_id, last_released_frame_) && !waiting_for_key_) {
52    // Packet is too old.
53    return false;
54  }
55
56  // Update the last received frame id.
57  if (IsNewerFrameId(frame_id, newest_frame_id_)) {
58    newest_frame_id_ = frame_id;
59  }
60
61  // Does this packet belong to a new frame?
62  FrameList::iterator it = frames_.find(frame_id);
63  if (it == frames_.end()) {
64    // New frame.
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));
68    it = retval.first;
69  }
70
71    // Insert packet.
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;
76    *duplicate = true;
77    return false;
78  }
79
80  return it->second->Complete();
81}
82
83// This does not release the frame.
84bool Framer::GetEncodedFrame(EncodedFrame* frame,
85                             bool* next_frame,
86                             bool* have_multiple_decodable_frames) {
87  *have_multiple_decodable_frames = HaveMultipleDecodableFrames();
88
89  uint32 frame_id;
90  // Find frame id.
91  if (NextContinuousFrame(&frame_id)) {
92    // We have our next frame.
93    *next_frame = true;
94  } else {
95    // Check if we can skip frames when our decoder is too slow.
96    if (!decoder_faster_than_max_frame_rate_)
97      return false;
98
99    if (!NextFrameAllowingSkippingFrames(&frame_id)) {
100      return false;
101    }
102    *next_frame = false;
103  }
104
105  ConstFrameIterator it = frames_.find(frame_id);
106  DCHECK(it != frames_.end());
107  if (it == frames_.end())
108    return false;
109
110  return it->second->AssembleEncodedFrame(frame);
111}
112
113void Framer::AckFrame(uint32 frame_id) {
114  VLOG(2) << "ACK frame " << frame_id;
115  cast_msg_builder_->CompleteFrameReceived(frame_id);
116}
117
118void Framer::Reset() {
119  waiting_for_key_ = true;
120  last_released_frame_ = kStartFrameId;
121  newest_frame_id_ = kStartFrameId;
122  frames_.clear();
123  cast_msg_builder_->Reset();
124}
125
126void Framer::ReleaseFrame(uint32 frame_id) {
127  RemoveOldFrames(frame_id);
128  frames_.erase(frame_id);
129
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)) {
135      frames_.erase(it++);
136      skipped_old_frame = true;
137    } else {
138      ++it;
139    }
140  }
141  if (skipped_old_frame) {
142    cast_msg_builder_->UpdateCastMessage();
143  }
144}
145
146bool Framer::TimeToSendNextCastMessage(base::TimeTicks* time_to_send) {
147  return cast_msg_builder_->TimeToSendNextCastMessage(time_to_send);
148}
149
150void Framer::SendCastMessage() { cast_msg_builder_->UpdateCastMessage(); }
151
152void Framer::RemoveOldFrames(uint32 frame_id) {
153  FrameList::iterator it = frames_.begin();
154
155  while (it != frames_.end()) {
156    if (IsNewerFrameId(it->first, frame_id)) {
157      ++it;
158    } else {
159      // Older or equal; erase.
160      frames_.erase(it++);
161    }
162  }
163  last_released_frame_ = frame_id;
164}
165
166uint32 Framer::NewestFrameId() const { return newest_frame_id_; }
167
168bool Framer::NextContinuousFrame(uint32* frame_id) const {
169  FrameList::const_iterator it;
170
171  for (it = frames_.begin(); it != frames_.end(); ++it) {
172    if (it->second->Complete() && ContinuousFrame(it->second.get())) {
173      *frame_id = it->first;
174      return true;
175    }
176  }
177  return false;
178}
179
180bool 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())) {
186      if (found_one) {
187        return true;
188      } else {
189        found_one = true;
190      }
191    }
192  }
193  return false;
194}
195
196uint32 Framer::LastContinuousFrame() const {
197  uint32 last_continuous_frame_id = last_released_frame_;
198  uint32 next_expected_frame = last_released_frame_;
199
200  FrameList::const_iterator it;
201
202  do {
203    next_expected_frame++;
204    it = frames_.find(next_expected_frame);
205    if (it == frames_.end())
206      break;
207    if (!it->second->Complete())
208      break;
209
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;
214}
215
216bool 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)) {
224        it_best_match = it;
225      }
226    }
227  }
228  if (it_best_match == frames_.end())
229    return false;
230
231  *frame_id = it_best_match->first;
232  return true;
233}
234
235bool Framer::Empty() const { return frames_.empty(); }
236
237int Framer::NumberOfCompleteFrames() const {
238  int count = 0;
239  FrameList::const_iterator it;
240  for (it = frames_.begin(); it != frames_.end(); ++it) {
241    if (it->second->Complete()) {
242      ++count;
243    }
244  }
245  return count;
246}
247
248bool Framer::FrameExists(uint32 frame_id) const {
249  return frames_.end() != frames_.find(frame_id);
250}
251
252void Framer::GetMissingPackets(uint32 frame_id,
253                                   bool last_frame,
254                                   PacketIdSet* missing_packets) const {
255  FrameList::const_iterator it = frames_.find(frame_id);
256  if (it == frames_.end())
257    return;
258
259  it->second->GetMissingPackets(last_frame, missing_packets);
260}
261
262bool Framer::ContinuousFrame(FrameBuffer* frame) const {
263  DCHECK(frame);
264  if (waiting_for_key_ && !frame->is_key_frame())
265    return false;
266  return static_cast<uint32>(last_released_frame_ + 1) == frame->frame_id();
267}
268
269bool Framer::DecodableFrame(FrameBuffer* frame) const {
270  if (frame->is_key_frame())
271    return true;
272  if (waiting_for_key_ && !frame->is_key_frame())
273    return false;
274  // Self-reference?
275  if (frame->last_referenced_frame_id() == frame->frame_id())
276    return true;
277
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_)) {
281    return true;
282  }
283  return frame->last_referenced_frame_id() == last_released_frame_;
284}
285
286
287}  // namespace cast
288}  // namespace media
289