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