OLD | NEW |
(Empty) | |
| 1 // Copyright 2013 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/framer/frame_buffer.h" |
| 6 |
| 7 namespace media { |
| 8 namespace cast { |
| 9 |
| 10 FrameBuffer::FrameBuffer() |
| 11 : frame_id_(0), |
| 12 max_packet_id_(0), |
| 13 num_packets_received_(0), |
| 14 is_key_frame_(false), |
| 15 total_data_size_(0), |
| 16 last_referenced_frame_id_(0), |
| 17 packets_() {} |
| 18 |
| 19 FrameBuffer::~FrameBuffer() {} |
| 20 |
| 21 void FrameBuffer::InsertPacket(const uint8* payload_data, |
| 22 int payload_size, |
| 23 const RtpCastHeader& rtp_header) { |
| 24 // Is this the first packet in the frame? |
| 25 if (packets_.empty()) { |
| 26 frame_id_ = rtp_header.frame_id; |
| 27 max_packet_id_ = rtp_header.max_packet_id; |
| 28 is_key_frame_ = rtp_header.is_key_frame; |
| 29 if (rtp_header.is_reference) { |
| 30 last_referenced_frame_id_ = rtp_header.reference_frame_id; |
| 31 } else { |
| 32 last_referenced_frame_id_ = static_cast<uint8>(rtp_header.frame_id - 1); |
| 33 } |
| 34 |
| 35 rtp_timestamp_ = rtp_header.webrtc.header.timestamp; |
| 36 } |
| 37 // Is this the correct frame? |
| 38 if (rtp_header.frame_id != frame_id_) return; |
| 39 |
| 40 // Insert every packet only once. |
| 41 if (packets_.find(rtp_header.packet_id) != packets_.end()) return; |
| 42 |
| 43 std::vector<uint8> data; |
| 44 std::pair<PacketMap::iterator, bool> retval = |
| 45 packets_.insert(make_pair(rtp_header.packet_id, data)); |
| 46 |
| 47 // Insert the packet. |
| 48 retval.first->second.resize(payload_size); |
| 49 std::copy(payload_data, payload_data + payload_size, |
| 50 retval.first->second.begin()); |
| 51 |
| 52 ++num_packets_received_; |
| 53 total_data_size_ += payload_size; |
| 54 } |
| 55 |
| 56 bool FrameBuffer::Complete() const { |
| 57 return num_packets_received_ - 1 == max_packet_id_; |
| 58 } |
| 59 |
| 60 bool FrameBuffer::GetEncodedAudioFrame(EncodedAudioFrame* audio_frame, |
| 61 uint32* rtp_timestamp) const { |
| 62 if (!Complete()) return false; |
| 63 |
| 64 *rtp_timestamp = rtp_timestamp_; |
| 65 |
| 66 // Frame is complete -> construct. |
| 67 audio_frame->frame_id = frame_id_; |
| 68 |
| 69 // Build the data vector. |
| 70 audio_frame->data.clear(); |
| 71 audio_frame->data.reserve(total_data_size_); |
| 72 PacketMap::const_iterator it; |
| 73 for (it = packets_.begin(); it != packets_.end(); ++it) { |
| 74 audio_frame->data.insert(audio_frame->data.end(), |
| 75 it->second.begin(), it->second.end()); |
| 76 } |
| 77 return true; |
| 78 } |
| 79 |
| 80 bool FrameBuffer::GetEncodedVideoFrame(EncodedVideoFrame* video_frame, |
| 81 uint32* rtp_timestamp) const { |
| 82 if (!Complete()) return false; |
| 83 |
| 84 *rtp_timestamp = rtp_timestamp_; |
| 85 |
| 86 // Frame is complete -> construct. |
| 87 video_frame->key_frame = is_key_frame_; |
| 88 video_frame->frame_id = frame_id_; |
| 89 video_frame->last_referenced_frame_id = last_referenced_frame_id_; |
| 90 |
| 91 // Build the data vector. |
| 92 video_frame->data.clear(); |
| 93 video_frame->data.reserve(total_data_size_); |
| 94 PacketMap::const_iterator it; |
| 95 for (it = packets_.begin(); it != packets_.end(); ++it) { |
| 96 video_frame->data.insert(video_frame->data.end(), |
| 97 it->second.begin(), it->second.end()); |
| 98 } |
| 99 return true; |
| 100 } |
| 101 |
| 102 } // namespace cast |
| 103 } // namespace media |
OLD | NEW |