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