frame_buffer.cc revision 116680a4aac90f2aa7413d9095a592090648e557
1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// found in the LICENSE file.
4424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/cast/net/rtp/frame_buffer.h"
6424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/logging.h"
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace media {
10424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace cast {
11424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
12424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)FrameBuffer::FrameBuffer()
13424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    : frame_id_(0),
14424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      max_packet_id_(0),
15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      num_packets_received_(0),
16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      is_key_frame_(false),
17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      total_data_size_(0),
18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      last_referenced_frame_id_(0),
19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      packets_() {}
20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)FrameBuffer::~FrameBuffer() {}
22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void FrameBuffer::InsertPacket(const uint8* payload_data,
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                               size_t payload_size,
25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                               const RtpCastHeader& rtp_header) {
26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Is this the first packet in the frame?
27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (packets_.empty()) {
28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    frame_id_ = rtp_header.frame_id;
29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    max_packet_id_ = rtp_header.max_packet_id;
30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    is_key_frame_ = rtp_header.is_key_frame;
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (is_key_frame_)
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      DCHECK_EQ(rtp_header.frame_id, rtp_header.reference_frame_id);
335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    last_referenced_frame_id_ = rtp_header.reference_frame_id;
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    rtp_timestamp_ = rtp_header.rtp_timestamp;
35424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
36424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Is this the correct frame?
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (rtp_header.frame_id != frame_id_)
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
40424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Insert every packet only once.
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (packets_.find(rtp_header.packet_id) != packets_.end()) {
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  std::vector<uint8> data;
46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  std::pair<PacketMap::iterator, bool> retval =
47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      packets_.insert(make_pair(rtp_header.packet_id, data));
48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Insert the packet.
50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  retval.first->second.resize(payload_size);
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::copy(
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      payload_data, payload_data + payload_size, retval.first->second.begin());
53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ++num_packets_received_;
55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  total_data_size_ += payload_size;
56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool FrameBuffer::Complete() const {
59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return num_packets_received_ - 1 == max_packet_id_;
60424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
61424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool FrameBuffer::AssembleEncodedFrame(EncodedFrame* frame) const {
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!Complete())
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
65424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
66424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Frame is complete -> construct.
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (is_key_frame_)
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    frame->dependency = EncodedFrame::KEY;
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  else if (frame_id_ == last_referenced_frame_id_)
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    frame->dependency = EncodedFrame::INDEPENDENT;
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  else
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    frame->dependency = EncodedFrame::DEPENDENT;
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  frame->frame_id = frame_id_;
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  frame->referenced_frame_id = last_referenced_frame_id_;
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  frame->rtp_timestamp = rtp_timestamp_;
76424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
77424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Build the data vector.
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  frame->data.clear();
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  frame->data.reserve(total_data_size_);
80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  PacketMap::const_iterator it;
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (it = packets_.begin(); it != packets_.end(); ++it)
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    frame->data.insert(frame->data.end(), it->second.begin(), it->second.end());
83424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return true;
84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
85424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}  // namespace cast
87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}  // namespace media
88