Home | History | Annotate | Download | only in rtp_sender
      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/net/rtp_sender/rtp_sender.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/rand_util.h"
      9 #include "media/cast/cast_defines.h"
     10 #include "media/cast/net/pacing/paced_sender.h"
     11 #include "media/cast/rtcp/rtcp_defines.h"
     12 #include "net/base/big_endian.h"
     13 
     14 namespace media {
     15 namespace cast {
     16 
     17 RtpSender::RtpSender(scoped_refptr<CastEnvironment> cast_environment,
     18                      const AudioSenderConfig* audio_config,
     19                      const VideoSenderConfig* video_config,
     20                      PacedPacketSender* transport)
     21     : cast_environment_(cast_environment),
     22       config_(),
     23       transport_(transport) {
     24   // Store generic cast config and create packetizer config.
     25   DCHECK(audio_config || video_config) << "Invalid argument";
     26   if (audio_config) {
     27     storage_.reset(new PacketStorage(cast_environment->Clock(),
     28                                      audio_config->rtp_history_ms));
     29     config_.audio = true;
     30     config_.ssrc = audio_config->sender_ssrc;
     31     config_.payload_type = audio_config->rtp_payload_type;
     32     config_.frequency = audio_config->frequency;
     33     config_.audio_codec = audio_config->codec;
     34   } else {
     35     storage_.reset(new PacketStorage(cast_environment->Clock(),
     36                                      video_config->rtp_history_ms));
     37     config_.audio = false;
     38     config_.ssrc = video_config->sender_ssrc;
     39     config_.payload_type = video_config->rtp_payload_type;
     40     config_.frequency = kVideoFrequency;
     41     config_.video_codec = video_config->codec;
     42   }
     43   // Randomly set start values.
     44   config_.sequence_number = base::RandInt(0, 65535);
     45   config_.rtp_timestamp = base::RandInt(0, 65535);
     46   config_.rtp_timestamp += base::RandInt(0, 65535) << 16;
     47   packetizer_.reset(new RtpPacketizer(transport, storage_.get(), config_));
     48 }
     49 
     50 RtpSender::~RtpSender() {}
     51 
     52 void RtpSender::IncomingEncodedVideoFrame(const EncodedVideoFrame* video_frame,
     53     const base::TimeTicks& capture_time) {
     54   packetizer_->IncomingEncodedVideoFrame(video_frame, capture_time);
     55 }
     56 
     57 void RtpSender::IncomingEncodedAudioFrame(const EncodedAudioFrame* audio_frame,
     58     const base::TimeTicks& recorded_time) {
     59   packetizer_->IncomingEncodedAudioFrame(audio_frame, recorded_time);
     60 }
     61 
     62 void RtpSender::ResendPackets(
     63     const MissingFramesAndPacketsMap& missing_frames_and_packets) {
     64   // Iterate over all frames in the list.
     65   for (MissingFramesAndPacketsMap::const_iterator it =
     66        missing_frames_and_packets.begin();
     67        it != missing_frames_and_packets.end(); ++it) {
     68     PacketList packets_to_resend;
     69     uint8 frame_id = it->first;
     70     const PacketIdSet& packets_set = it->second;
     71     bool success = false;
     72 
     73     if (packets_set.empty()) {
     74       VLOG(1) << "Missing all packets in frame " << static_cast<int>(frame_id);
     75 
     76       uint16 packet_id = 0;
     77       do {
     78         // Get packet from storage.
     79         success = storage_->GetPacket(frame_id, packet_id, &packets_to_resend);
     80 
     81         // Resend packet to the network.
     82         if (success) {
     83           VLOG(1) << "Resend " << static_cast<int>(frame_id)
     84                   << ":" << packet_id;
     85           // Set a unique incremental sequence number for every packet.
     86           Packet& packet = packets_to_resend.back();
     87           UpdateSequenceNumber(&packet);
     88           // Set the size as correspond to each frame.
     89           ++packet_id;
     90         }
     91       } while (success);
     92     } else {
     93       // Iterate over all of the packets in the frame.
     94       for (PacketIdSet::const_iterator set_it = packets_set.begin();
     95           set_it != packets_set.end(); ++set_it) {
     96         uint16 packet_id = *set_it;
     97         success = storage_->GetPacket(frame_id, packet_id, &packets_to_resend);
     98 
     99         // Resend packet to the network.
    100         if (success) {
    101           VLOG(1) << "Resend " << static_cast<int>(frame_id)
    102                   << ":" << packet_id;
    103           Packet& packet = packets_to_resend.back();
    104           UpdateSequenceNumber(&packet);
    105         }
    106       }
    107     }
    108     transport_->ResendPackets(packets_to_resend);
    109   }
    110 }
    111 
    112 void RtpSender::UpdateSequenceNumber(Packet* packet) {
    113   uint16 new_sequence_number = packetizer_->NextSequenceNumber();
    114   int index = 2;
    115   (*packet)[index] = (static_cast<uint8>(new_sequence_number));
    116   (*packet)[index + 1] =(static_cast<uint8>(new_sequence_number >> 8));
    117 }
    118 
    119 void RtpSender::RtpStatistics(const base::TimeTicks& now,
    120                               RtcpSenderInfo* sender_info) {
    121   // The timestamp of this Rtcp packet should be estimated as the timestamp of
    122   // the frame being captured at this moment. We are calculating that
    123   // timestamp as the last frame's timestamp + the time since the last frame
    124   // was captured.
    125   uint32 ntp_seconds = 0;
    126   uint32 ntp_fraction = 0;
    127   ConvertTimeTicksToNtp(now, &ntp_seconds, &ntp_fraction);
    128   sender_info->ntp_seconds = ntp_seconds;
    129   sender_info->ntp_fraction = ntp_fraction;
    130 
    131   base::TimeTicks time_sent;
    132   uint32 rtp_timestamp;
    133   if (packetizer_->LastSentTimestamp(&time_sent, &rtp_timestamp)) {
    134     base::TimeDelta time_since_last_send = now - time_sent;
    135     sender_info->rtp_timestamp = rtp_timestamp +
    136         time_since_last_send.InMilliseconds() * (config_.frequency / 1000);
    137   } else {
    138     sender_info->rtp_timestamp = 0;
    139   }
    140   sender_info->send_packet_count = packetizer_->send_packets_count();
    141   sender_info->send_octet_count = packetizer_->send_octet_count();
    142 }
    143 
    144 }  //  namespace cast
    145 }  // namespace media
    146