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.
5 #include "media/cast/transport/rtp_sender/rtp_sender.h"
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"
17 // Schedule the RTP statistics callback every 33mS. As this interval affects the
18 // time offset of the render and playout times, we want it in the same ball park
20 static const int kStatsCallbackIntervalMs = 33;
23 base::TickClock* clock,
24 const CastTransportConfig& config,
26 const scoped_refptr<base::TaskRunner>& transport_task_runner,
27 PacedSender* const transport)
29 transport_(transport),
31 transport_task_runner_(transport_task_runner) {
32 // Store generic cast config and create packetizer config.
35 new PacketStorage(clock, config.audio_rtp_config.history_ms));
37 config_.ssrc = config.audio_ssrc;
38 config_.payload_type = config.audio_rtp_config.payload_type;
39 config_.frequency = config.audio_frequency;
40 config_.audio_codec = config.audio_codec;
43 new PacketStorage(clock, config.audio_rtp_config.history_ms));
44 config_.audio = false;
45 config_.ssrc = config.video_ssrc;
46 config_.payload_type = config.video_rtp_config.payload_type;
47 config_.frequency = kVideoFrequency;
48 config_.video_codec = config.video_codec;
50 // Randomly set start values.
51 config_.sequence_number = base::RandInt(0, 65535);
53 new RtpPacketizer(transport, storage_.get(), config_));
56 RtpSender::~RtpSender() {}
58 void RtpSender::IncomingEncodedVideoFrame(const EncodedVideoFrame* video_frame,
59 const base::TimeTicks& capture_time) {
60 packetizer_->IncomingEncodedVideoFrame(video_frame, capture_time);
63 void RtpSender::IncomingEncodedAudioFrame(
64 const EncodedAudioFrame* audio_frame,
65 const base::TimeTicks& recorded_time) {
66 packetizer_->IncomingEncodedAudioFrame(audio_frame, recorded_time);
69 void RtpSender::ResendPackets(
70 const MissingFramesAndPacketsMap& missing_frames_and_packets) {
71 // Iterate over all frames in the list.
72 for (MissingFramesAndPacketsMap::const_iterator it =
73 missing_frames_and_packets.begin();
74 it != missing_frames_and_packets.end();
76 PacketList packets_to_resend;
77 uint8 frame_id = it->first;
78 const PacketIdSet& packets_set = it->second;
81 if (packets_set.empty()) {
82 VLOG(1) << "Missing all packets in frame " << static_cast<int>(frame_id);
86 // Get packet from storage.
87 success = storage_->GetPacket(frame_id, packet_id, &packets_to_resend);
89 // Resend packet to the network.
91 VLOG(1) << "Resend " << static_cast<int>(frame_id) << ":"
93 // Set a unique incremental sequence number for every packet.
94 Packet& packet = packets_to_resend.back();
95 UpdateSequenceNumber(&packet);
96 // Set the size as correspond to each frame.
101 // Iterate over all of the packets in the frame.
102 for (PacketIdSet::const_iterator set_it = packets_set.begin();
103 set_it != packets_set.end();
105 uint16 packet_id = *set_it;
106 success = storage_->GetPacket(frame_id, packet_id, &packets_to_resend);
108 // Resend packet to the network.
110 VLOG(1) << "Resend " << static_cast<int>(frame_id) << ":"
112 Packet& packet = packets_to_resend.back();
113 UpdateSequenceNumber(&packet);
117 transport_->ResendPackets(packets_to_resend);
121 void RtpSender::UpdateSequenceNumber(Packet* packet) {
122 uint16 new_sequence_number = packetizer_->NextSequenceNumber();
124 (*packet)[index] = (static_cast<uint8>(new_sequence_number));
125 (*packet)[index + 1] = (static_cast<uint8>(new_sequence_number >> 8));
128 void RtpSender::SubscribeRtpStatsCallback(
129 const CastTransportRtpStatistics& callback) {
130 stats_callback_ = callback;
131 ScheduleNextStatsReport();
134 void RtpSender::ScheduleNextStatsReport() {
135 transport_task_runner_->PostDelayedTask(
137 base::Bind(&RtpSender::RtpStatistics, base::AsWeakPtr(this)),
138 base::TimeDelta::FromMilliseconds(kStatsCallbackIntervalMs));
141 void RtpSender::RtpStatistics() {
142 RtcpSenderInfo sender_info;
143 base::TimeTicks time_sent;
144 uint32 rtp_timestamp = 0;
145 packetizer_->LastSentTimestamp(&time_sent, &rtp_timestamp);
146 sender_info.send_packet_count = packetizer_->send_packets_count();
147 sender_info.send_octet_count = packetizer_->send_octet_count();
148 stats_callback_.Run(sender_info, time_sent, rtp_timestamp);
149 ScheduleNextStatsReport();
152 } // namespace transport