Home | History | Annotate | Download | only in rtp_packetizer
      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