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/frame_buffer.h"
7 #include "base/logging.h"
12 FrameBuffer::FrameBuffer()
15 num_packets_received_(0),
16 max_seen_packet_id_(0),
17 new_playout_delay_ms_(0),
20 last_referenced_frame_id_(0),
23 FrameBuffer::~FrameBuffer() {}
25 bool FrameBuffer::InsertPacket(const uint8
* payload_data
,
27 const RtpCastHeader
& rtp_header
) {
28 // Is this the first packet in the frame?
29 if (packets_
.empty()) {
30 frame_id_
= rtp_header
.frame_id
;
31 max_packet_id_
= rtp_header
.max_packet_id
;
32 is_key_frame_
= rtp_header
.is_key_frame
;
33 new_playout_delay_ms_
= rtp_header
.new_playout_delay_ms
;
35 DCHECK_EQ(rtp_header
.frame_id
, rtp_header
.reference_frame_id
);
36 last_referenced_frame_id_
= rtp_header
.reference_frame_id
;
37 rtp_timestamp_
= rtp_header
.rtp_timestamp
;
39 // Is this the correct frame?
40 if (rtp_header
.frame_id
!= frame_id_
)
43 // Insert every packet only once.
44 if (packets_
.find(rtp_header
.packet_id
) != packets_
.end()) {
48 std::vector
<uint8
> data
;
49 std::pair
<PacketMap::iterator
, bool> retval
=
50 packets_
.insert(make_pair(rtp_header
.packet_id
, data
));
53 retval
.first
->second
.resize(payload_size
);
55 payload_data
, payload_data
+ payload_size
, retval
.first
->second
.begin());
57 ++num_packets_received_
;
58 max_seen_packet_id_
= std::max(max_seen_packet_id_
, rtp_header
.packet_id
);
59 total_data_size_
+= payload_size
;
63 bool FrameBuffer::Complete() const {
64 return num_packets_received_
- 1 == max_packet_id_
;
67 bool FrameBuffer::AssembleEncodedFrame(EncodedFrame
* frame
) const {
71 // Frame is complete -> construct.
73 frame
->dependency
= EncodedFrame::KEY
;
74 else if (frame_id_
== last_referenced_frame_id_
)
75 frame
->dependency
= EncodedFrame::INDEPENDENT
;
77 frame
->dependency
= EncodedFrame::DEPENDENT
;
78 frame
->frame_id
= frame_id_
;
79 frame
->referenced_frame_id
= last_referenced_frame_id_
;
80 frame
->rtp_timestamp
= rtp_timestamp_
;
81 frame
->new_playout_delay_ms
= new_playout_delay_ms_
;
83 // Build the data vector.
85 frame
->data
.reserve(total_data_size_
);
86 PacketMap::const_iterator it
;
87 for (it
= packets_
.begin(); it
!= packets_
.end(); ++it
)
88 frame
->data
.insert(frame
->data
.end(), it
->second
.begin(), it
->second
.end());
92 void FrameBuffer::GetMissingPackets(bool newest_frame
,
93 PacketIdSet
* missing_packets
) const {
94 // Missing packets capped by max_seen_packet_id_.
95 // (Iff it's the latest frame)
96 int maximum
= newest_frame
? max_seen_packet_id_
: max_packet_id_
;
98 for (PacketMap::const_iterator i
= packets_
.begin();
99 i
!= packets_
.end() && packet
<= maximum
;
101 int end
= std::min
<int>(i
->first
, maximum
+ 1);
102 while (packet
< end
) {
103 missing_packets
->insert(packet
);
108 while (packet
<= maximum
) {
109 missing_packets
->insert(packet
);