Upstream version 6.35.121.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
12 namespace media {
13 namespace cast {
14 namespace transport {
15
16 // Schedule the RTP statistics callback every 33mS. As this interval affects the
17 // time offset of the render and playout times, we want it in the same ball park
18 // as the frame rate.
19 static const int kStatsCallbackIntervalMs = 33;
20
21 RtpSender::RtpSender(
22     base::TickClock* clock,
23     LoggingImpl* logging,
24     const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner,
25     PacedSender* const transport)
26     : clock_(clock),
27       logging_(logging),
28       transport_(transport),
29       stats_callback_(),
30       transport_task_runner_(transport_task_runner),
31       weak_factory_(this) {
32   // Randomly set sequence number start value.
33   config_.sequence_number = base::RandInt(0, 65535);
34 }
35
36 RtpSender::~RtpSender() {}
37
38 void RtpSender::InitializeAudio(const CastTransportAudioConfig& config) {
39   storage_.reset(new PacketStorage(clock_, config.base.rtp_config.history_ms));
40   config_.audio = true;
41   config_.ssrc = config.base.ssrc;
42   config_.payload_type = config.base.rtp_config.payload_type;
43   config_.frequency = config.frequency;
44   config_.audio_codec = config.codec;
45   packetizer_.reset(
46       new RtpPacketizer(transport_, storage_.get(), config_, clock_, logging_));
47 }
48
49 void RtpSender::InitializeVideo(const CastTransportVideoConfig& config) {
50   storage_.reset(new PacketStorage(clock_, config.base.rtp_config.history_ms));
51   config_.audio = false;
52   config_.ssrc = config.base.ssrc;
53   config_.payload_type = config.base.rtp_config.payload_type;
54   config_.frequency = kVideoFrequency;
55   config_.video_codec = config.codec;
56   packetizer_.reset(
57       new RtpPacketizer(transport_, storage_.get(), config_, clock_, logging_));
58 }
59
60 void RtpSender::IncomingEncodedVideoFrame(const EncodedVideoFrame* video_frame,
61                                           const base::TimeTicks& capture_time) {
62   DCHECK(packetizer_);
63   packetizer_->IncomingEncodedVideoFrame(video_frame, capture_time);
64 }
65
66 void RtpSender::IncomingEncodedAudioFrame(
67     const EncodedAudioFrame* audio_frame,
68     const base::TimeTicks& recorded_time) {
69   DCHECK(packetizer_);
70   packetizer_->IncomingEncodedAudioFrame(audio_frame, recorded_time);
71 }
72
73 void RtpSender::ResendPackets(
74     const MissingFramesAndPacketsMap& missing_frames_and_packets) {
75   DCHECK(storage_);
76   // Iterate over all frames in the list.
77   for (MissingFramesAndPacketsMap::const_iterator it =
78            missing_frames_and_packets.begin();
79        it != missing_frames_and_packets.end();
80        ++it) {
81     PacketList packets_to_resend;
82     uint8 frame_id = it->first;
83     const PacketIdSet& packets_set = it->second;
84     bool success = false;
85
86     if (packets_set.empty()) {
87       VLOG(3) << "Missing all packets in frame " << static_cast<int>(frame_id);
88
89       uint16 packet_id = 0;
90       do {
91         // Get packet from storage.
92         success = storage_->GetPacket(frame_id, packet_id, &packets_to_resend);
93
94         // Resend packet to the network.
95         if (success) {
96           VLOG(3) << "Resend " << static_cast<int>(frame_id) << ":"
97                   << packet_id;
98           // Set a unique incremental sequence number for every packet.
99           Packet& packet = packets_to_resend.back();
100           UpdateSequenceNumber(&packet);
101           // Set the size as correspond to each frame.
102           ++packet_id;
103         }
104       } while (success);
105     } else {
106       // Iterate over all of the packets in the frame.
107       for (PacketIdSet::const_iterator set_it = packets_set.begin();
108            set_it != packets_set.end();
109            ++set_it) {
110         uint16 packet_id = *set_it;
111         success = storage_->GetPacket(frame_id, packet_id, &packets_to_resend);
112
113         // Resend packet to the network.
114         if (success) {
115           VLOG(3) << "Resend " << static_cast<int>(frame_id) << ":"
116                   << packet_id;
117           Packet& packet = packets_to_resend.back();
118           UpdateSequenceNumber(&packet);
119         }
120       }
121     }
122     transport_->ResendPackets(packets_to_resend);
123   }
124 }
125
126 void RtpSender::UpdateSequenceNumber(Packet* packet) {
127   uint16 new_sequence_number = packetizer_->NextSequenceNumber();
128   int index = 2;
129   (*packet)[index] = (static_cast<uint8>(new_sequence_number));
130   (*packet)[index + 1] = (static_cast<uint8>(new_sequence_number >> 8));
131 }
132
133 void RtpSender::SubscribeRtpStatsCallback(
134     const CastTransportRtpStatistics& callback) {
135   stats_callback_ = callback;
136   ScheduleNextStatsReport();
137 }
138
139 void RtpSender::ScheduleNextStatsReport() {
140   transport_task_runner_->PostDelayedTask(
141       FROM_HERE,
142       base::Bind(&RtpSender::RtpStatistics, weak_factory_.GetWeakPtr()),
143       base::TimeDelta::FromMilliseconds(kStatsCallbackIntervalMs));
144 }
145
146 void RtpSender::RtpStatistics() {
147   RtcpSenderInfo sender_info;
148   base::TimeTicks time_sent;
149   uint32 rtp_timestamp = 0;
150   packetizer_->LastSentTimestamp(&time_sent, &rtp_timestamp);
151   sender_info.send_packet_count = packetizer_->send_packets_count();
152   sender_info.send_octet_count = packetizer_->send_octet_count();
153   stats_callback_.Run(sender_info, time_sent, rtp_timestamp);
154   ScheduleNextStatsReport();
155 }
156
157 }  // namespace transport
158 }  //  namespace cast
159 }  // namespace media