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