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"
16 RtpSender::RtpSender(base::TickClock
* clock
,
17 const AudioSenderConfig
* audio_config
,
18 const VideoSenderConfig
* video_config
,
19 PacedPacketSender
* transport
)
21 transport_(transport
),
23 // Store generic cast config and create packetizer config.
24 DCHECK(audio_config
|| video_config
) << "Invalid argument";
26 storage_
.reset(new PacketStorage(clock
, audio_config
->rtp_history_ms
));
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
;
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
;
70 if (packets_set
.empty()) {
71 VLOG(1) << "Missing all packets in frame " << static_cast<int>(frame_id
);
75 // Get packet from storage.
76 success
= storage_
->GetPacket(frame_id
, packet_id
, &packets_to_resend
);
78 // Resend packet to the network.
80 VLOG(1) << "Resend " << static_cast<int>(frame_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.
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.
98 VLOG(1) << "Resend " << static_cast<int>(frame_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();
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
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);
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();