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), 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci max_seen_packet_id_(0), 1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) new_playout_delay_ms_(0), 18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) is_key_frame_(false), 19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) total_data_size_(0), 20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) last_referenced_frame_id_(0), 21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) packets_() {} 22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)FrameBuffer::~FrameBuffer() {} 24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool FrameBuffer::InsertPacket(const uint8* payload_data, 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t payload_size, 27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const RtpCastHeader& rtp_header) { 28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Is this the first packet in the frame? 29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (packets_.empty()) { 30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) frame_id_ = rtp_header.frame_id; 31424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) max_packet_id_ = rtp_header.max_packet_id; 32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) is_key_frame_ = rtp_header.is_key_frame; 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) new_playout_delay_ms_ = rtp_header.new_playout_delay_ms; 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (is_key_frame_) 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_EQ(rtp_header.frame_id, rtp_header.reference_frame_id); 365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu last_referenced_frame_id_ = rtp_header.reference_frame_id; 375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu rtp_timestamp_ = rtp_header.rtp_timestamp; 38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Is this the correct frame? 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (rtp_header.frame_id != frame_id_) 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Insert every packet only once. 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (packets_.find(rtp_header.packet_id) != packets_.end()) { 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::vector<uint8> data; 49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::pair<PacketMap::iterator, bool> retval = 50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) packets_.insert(make_pair(rtp_header.packet_id, data)); 51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Insert the packet. 53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) retval.first->second.resize(payload_size); 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::copy( 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) payload_data, payload_data + payload_size, retval.first->second.begin()); 56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ++num_packets_received_; 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci max_seen_packet_id_ = std::max(max_seen_packet_id_, rtp_header.packet_id); 59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) total_data_size_ += payload_size; 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 61424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 62424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 63424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool FrameBuffer::Complete() const { 64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return num_packets_received_ - 1 == max_packet_id_; 65424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 66424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool FrameBuffer::AssembleEncodedFrame(EncodedFrame* frame) const { 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!Complete()) 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 70424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 71424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Frame is complete -> construct. 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (is_key_frame_) 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch frame->dependency = EncodedFrame::KEY; 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) else if (frame_id_ == last_referenced_frame_id_) 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch frame->dependency = EncodedFrame::INDEPENDENT; 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) else 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch frame->dependency = EncodedFrame::DEPENDENT; 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) frame->frame_id = frame_id_; 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) frame->referenced_frame_id = last_referenced_frame_id_; 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) frame->rtp_timestamp = rtp_timestamp_; 8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) frame->new_playout_delay_ms = new_playout_delay_ms_; 82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 83424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Build the data vector. 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) frame->data.clear(); 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) frame->data.reserve(total_data_size_); 86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PacketMap::const_iterator it; 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (it = packets_.begin(); it != packets_.end(); ++it) 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) frame->data.insert(frame->data.end(), it->second.begin(), it->second.end()); 89424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 91424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid FrameBuffer::GetMissingPackets(bool newest_frame, 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PacketIdSet* missing_packets) const { 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Missing packets capped by max_seen_packet_id_. 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // (Iff it's the latest frame) 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int maximum = newest_frame ? max_seen_packet_id_ : max_packet_id_; 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int packet = 0; 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (PacketMap::const_iterator i = packets_.begin(); 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci i != packets_.end() && packet <= maximum; 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++i) { 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int end = std::min<int>(i->first, maximum + 1); 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci while (packet < end) { 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci missing_packets->insert(packet); 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet++; 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet++; 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci while (packet <= maximum) { 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci missing_packets->insert(packet); 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci packet++; 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 115424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} // namespace cast 116424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} // namespace media 117