OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/cast/rtp_sender/rtp_sender.h" | 5 #include "media/cast/rtp_sender/rtp_sender.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
9 #include "media/cast/cast_defines.h" | 9 #include "media/cast/cast_defines.h" |
10 #include "media/cast/pacing/paced_sender.h" | 10 #include "media/cast/pacing/paced_sender.h" |
11 #include "media/cast/rtcp/rtcp_defines.h" | 11 #include "media/cast/rtcp/rtcp_defines.h" |
| 12 #include "net/base/big_endian.h" |
12 | 13 |
13 namespace media { | 14 namespace media { |
14 namespace cast { | 15 namespace cast { |
15 | 16 |
16 RtpSender::RtpSender(base::TickClock* clock, | 17 RtpSender::RtpSender(scoped_refptr<CastEnvironment> cast_environment, |
17 const AudioSenderConfig* audio_config, | 18 const AudioSenderConfig* audio_config, |
18 const VideoSenderConfig* video_config, | 19 const VideoSenderConfig* video_config, |
19 PacedPacketSender* transport) | 20 PacedPacketSender* transport) |
20 : config_(), | 21 : cast_environment_(cast_environment), |
21 transport_(transport), | 22 config_(), |
22 clock_(clock) { | 23 transport_(transport) { |
23 // Store generic cast config and create packetizer config. | 24 // Store generic cast config and create packetizer config. |
24 DCHECK(audio_config || video_config) << "Invalid argument"; | 25 DCHECK(audio_config || video_config) << "Invalid argument"; |
25 if (audio_config) { | 26 if (audio_config) { |
26 storage_.reset(new PacketStorage(clock, audio_config->rtp_history_ms)); | 27 storage_.reset(new PacketStorage(cast_environment->Clock(), |
| 28 audio_config->rtp_history_ms)); |
27 config_.audio = true; | 29 config_.audio = true; |
28 config_.ssrc = audio_config->sender_ssrc; | 30 config_.ssrc = audio_config->sender_ssrc; |
29 config_.payload_type = audio_config->rtp_payload_type; | 31 config_.payload_type = audio_config->rtp_payload_type; |
30 config_.frequency = audio_config->frequency; | 32 config_.frequency = audio_config->frequency; |
31 config_.audio_codec = audio_config->codec; | 33 config_.audio_codec = audio_config->codec; |
32 } else { | 34 } else { |
33 storage_.reset(new PacketStorage(clock, video_config->rtp_history_ms)); | 35 storage_.reset(new PacketStorage(cast_environment->Clock(), |
| 36 video_config->rtp_history_ms)); |
34 config_.audio = false; | 37 config_.audio = false; |
35 config_.ssrc = video_config->sender_ssrc; | 38 config_.ssrc = video_config->sender_ssrc; |
36 config_.payload_type = video_config->rtp_payload_type; | 39 config_.payload_type = video_config->rtp_payload_type; |
37 config_.frequency = kVideoFrequency; | 40 config_.frequency = kVideoFrequency; |
38 config_.video_codec = video_config->codec; | 41 config_.video_codec = video_config->codec; |
39 } | 42 } |
40 // Randomly set start values. | 43 // Randomly set start values. |
41 config_.sequence_number = base::RandInt(0, 65535); | 44 config_.sequence_number = base::RandInt(0, 65535); |
42 config_.rtp_timestamp = base::RandInt(0, 65535); | 45 config_.rtp_timestamp = base::RandInt(0, 65535); |
43 config_.rtp_timestamp += base::RandInt(0, 65535) << 16; | 46 config_.rtp_timestamp += base::RandInt(0, 65535) << 16; |
44 packetizer_.reset(new RtpPacketizer(transport, storage_.get(), config_)); | 47 packetizer_.reset(new RtpPacketizer(transport, storage_.get(), config_)); |
45 } | 48 } |
46 | 49 |
47 RtpSender::~RtpSender() {} | 50 RtpSender::~RtpSender() {} |
48 | 51 |
49 void RtpSender::IncomingEncodedVideoFrame(const EncodedVideoFrame* video_frame, | 52 void RtpSender::IncomingEncodedVideoFrame(const EncodedVideoFrame* video_frame, |
50 const base::TimeTicks& capture_time) { | 53 const base::TimeTicks& capture_time) { |
51 packetizer_->IncomingEncodedVideoFrame(video_frame, capture_time); | 54 packetizer_->IncomingEncodedVideoFrame(video_frame, capture_time); |
52 } | 55 } |
53 | 56 |
54 void RtpSender::IncomingEncodedAudioFrame(const EncodedAudioFrame* audio_frame, | 57 void RtpSender::IncomingEncodedAudioFrame(const EncodedAudioFrame* audio_frame, |
55 const base::TimeTicks& recorded_time) { | 58 const base::TimeTicks& recorded_time) { |
56 packetizer_->IncomingEncodedAudioFrame(audio_frame, recorded_time); | 59 packetizer_->IncomingEncodedAudioFrame(audio_frame, recorded_time); |
57 } | 60 } |
58 | 61 |
59 void RtpSender::ResendPackets( | 62 void RtpSender::ResendPackets( |
60 const MissingFramesAndPacketsMap& missing_frames_and_packets) { | 63 const MissingFramesAndPacketsMap& missing_frames_and_packets) { |
61 PacketList packets_to_resend = | 64 // Iterate over all frames in the list. |
62 storage_->GetPackets(missing_frames_and_packets); | 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; |
63 | 72 |
64 PacketList::iterator it = packets_to_resend.begin(); | 73 if (packets_set.empty()) { |
65 for (; it != packets_to_resend.end(); ++it) { | 74 VLOG(1) << "Missing all packets in frame " << static_cast<int>(frame_id); |
66 Packet& packet = *it; | 75 |
67 UpdateSequenceNumber(&packet); | 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); |
68 } | 109 } |
69 transport_->ResendPackets(packets_to_resend); | |
70 } | 110 } |
71 | 111 |
72 void RtpSender::UpdateSequenceNumber(Packet* packet) { | 112 void RtpSender::UpdateSequenceNumber(Packet* packet) { |
73 uint16 new_sequence_number = packetizer_->NextSequenceNumber(); | 113 uint16 new_sequence_number = packetizer_->NextSequenceNumber(); |
74 int index = 2; | 114 int index = 2; |
75 (*packet)[index] = (static_cast<uint8>(new_sequence_number)); | 115 (*packet)[index] = (static_cast<uint8>(new_sequence_number)); |
76 (*packet)[index + 1] =(static_cast<uint8>(new_sequence_number >> 8)); | 116 (*packet)[index + 1] =(static_cast<uint8>(new_sequence_number >> 8)); |
77 } | 117 } |
78 | 118 |
79 void RtpSender::RtpStatistics(const base::TimeTicks& now, | 119 void RtpSender::RtpStatistics(const base::TimeTicks& now, |
(...skipping 16 matching lines...) Expand all Loading... |
96 time_since_last_send.InMilliseconds() * (config_.frequency / 1000); | 136 time_since_last_send.InMilliseconds() * (config_.frequency / 1000); |
97 } else { | 137 } else { |
98 sender_info->rtp_timestamp = 0; | 138 sender_info->rtp_timestamp = 0; |
99 } | 139 } |
100 sender_info->send_packet_count = packetizer_->send_packets_count(); | 140 sender_info->send_packet_count = packetizer_->send_packets_count(); |
101 sender_info->send_octet_count = packetizer_->send_octet_count(); | 141 sender_info->send_octet_count = packetizer_->send_octet_count(); |
102 } | 142 } |
103 | 143 |
104 } // namespace cast | 144 } // namespace cast |
105 } // namespace media | 145 } // namespace media |
OLD | NEW |