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