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/rtp_packetizer.h" 6 7 #include "base/big_endian.h" 8 #include "base/logging.h" 9 #include "media/cast/net/pacing/paced_sender.h" 10 #include "media/cast/net/rtp/rtp_defines.h" 11 12 namespace media { 13 namespace cast { 14 15 RtpPacketizerConfig::RtpPacketizerConfig() 16 : payload_type(-1), 17 max_payload_length(kMaxIpPacketSize - 28), // Default is IP-v4/UDP. 18 sequence_number(0), 19 ssrc(0) {} 20 21 RtpPacketizerConfig::~RtpPacketizerConfig() {} 22 23 RtpPacketizer::RtpPacketizer(PacedSender* const transport, 24 PacketStorage* packet_storage, 25 RtpPacketizerConfig rtp_packetizer_config) 26 : config_(rtp_packetizer_config), 27 transport_(transport), 28 packet_storage_(packet_storage), 29 sequence_number_(config_.sequence_number), 30 rtp_timestamp_(0), 31 packet_id_(0), 32 send_packet_count_(0), 33 send_octet_count_(0) { 34 DCHECK(transport) << "Invalid argument"; 35 } 36 37 RtpPacketizer::~RtpPacketizer() {} 38 39 uint16 RtpPacketizer::NextSequenceNumber() { 40 ++sequence_number_; 41 return sequence_number_ - 1; 42 } 43 44 void RtpPacketizer::SendFrameAsPackets(const EncodedFrame& frame) { 45 uint16 rtp_header_length = kRtpHeaderLength + kCastHeaderLength; 46 uint16 max_length = config_.max_payload_length - rtp_header_length - 1; 47 rtp_timestamp_ = frame.rtp_timestamp; 48 49 // Split the payload evenly (round number up). 50 size_t num_packets = (frame.data.size() + max_length) / max_length; 51 size_t payload_length = (frame.data.size() + num_packets) / num_packets; 52 DCHECK_LE(payload_length, max_length) << "Invalid argument"; 53 54 SendPacketVector packets; 55 56 size_t remaining_size = frame.data.size(); 57 std::string::const_iterator data_iter = frame.data.begin(); 58 while (remaining_size > 0) { 59 PacketRef packet(new base::RefCountedData<Packet>); 60 61 if (remaining_size < payload_length) { 62 payload_length = remaining_size; 63 } 64 remaining_size -= payload_length; 65 BuildCommonRTPheader( 66 &packet->data, remaining_size == 0, frame.rtp_timestamp); 67 68 // Build Cast header. 69 // TODO(miu): Should we always set the ref frame bit and the ref_frame_id? 70 DCHECK_NE(frame.dependency, EncodedFrame::UNKNOWN_DEPENDENCY); 71 uint8 num_extensions = 0; 72 if (frame.new_playout_delay_ms) 73 num_extensions++; 74 uint8 byte0 = kCastReferenceFrameIdBitMask; 75 if (frame.dependency == EncodedFrame::KEY) 76 byte0 |= kCastKeyFrameBitMask; 77 DCHECK_LE(num_extensions, kCastExtensionCountmask); 78 byte0 |= num_extensions; 79 packet->data.push_back(byte0); 80 packet->data.push_back(static_cast<uint8>(frame.frame_id)); 81 size_t start_size = packet->data.size(); 82 packet->data.resize(start_size + 4); 83 base::BigEndianWriter big_endian_writer( 84 reinterpret_cast<char*>(&(packet->data[start_size])), 4); 85 big_endian_writer.WriteU16(packet_id_); 86 big_endian_writer.WriteU16(static_cast<uint16>(num_packets - 1)); 87 packet->data.push_back(static_cast<uint8>(frame.referenced_frame_id)); 88 if (frame.new_playout_delay_ms) { 89 packet->data.push_back(kCastRtpExtensionAdaptiveLatency << 2); 90 packet->data.push_back(2); // 2 bytes 91 packet->data.push_back( 92 static_cast<uint8>(frame.new_playout_delay_ms >> 8)); 93 packet->data.push_back( 94 static_cast<uint8>(frame.new_playout_delay_ms)); 95 } 96 97 // Copy payload data. 98 packet->data.insert(packet->data.end(), 99 data_iter, 100 data_iter + payload_length); 101 data_iter += payload_length; 102 103 const PacketKey key = 104 PacedPacketSender::MakePacketKey(frame.reference_time, 105 config_.ssrc, 106 packet_id_++); 107 packets.push_back(make_pair(key, packet)); 108 109 // Update stats. 110 ++send_packet_count_; 111 send_octet_count_ += payload_length; 112 } 113 DCHECK(packet_id_ == num_packets) << "Invalid state"; 114 115 packet_storage_->StoreFrame(frame.frame_id, packets); 116 117 // Send to network. 118 transport_->SendPackets(packets); 119 120 // Prepare for next frame. 121 packet_id_ = 0; 122 } 123 124 void RtpPacketizer::BuildCommonRTPheader(Packet* packet, 125 bool marker_bit, 126 uint32 time_stamp) { 127 packet->push_back(0x80); 128 packet->push_back(static_cast<uint8>(config_.payload_type) | 129 (marker_bit ? kRtpMarkerBitMask : 0)); 130 size_t start_size = packet->size(); 131 packet->resize(start_size + 10); 132 base::BigEndianWriter big_endian_writer( 133 reinterpret_cast<char*>(&((*packet)[start_size])), 10); 134 big_endian_writer.WriteU16(sequence_number_); 135 big_endian_writer.WriteU32(time_stamp); 136 big_endian_writer.WriteU32(config_.ssrc); 137 ++sequence_number_; 138 } 139 140 } // namespace cast 141 } // namespace media 142