Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(468)

Side by Side Diff: media/cast/transport/rtp_sender/rtp_packetizer/rtp_packetizer.cc

Issue 248493002: Cast: Deduplicate packets in paced sender and always send older packets first (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: re-upping to trick build system Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/transport/rtp_sender/rtp_packetizer/rtp_packetizer.h" 5 #include "media/cast/transport/rtp_sender/rtp_packetizer/rtp_packetizer.h"
6 6
7 #include "base/big_endian.h" 7 #include "base/big_endian.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "media/cast/transport/pacing/paced_sender.h" 9 #include "media/cast/transport/pacing/paced_sender.h"
10 10
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 49
50 RtpPacketizer::~RtpPacketizer() {} 50 RtpPacketizer::~RtpPacketizer() {}
51 51
52 void RtpPacketizer::IncomingEncodedVideoFrame( 52 void RtpPacketizer::IncomingEncodedVideoFrame(
53 const EncodedVideoFrame* video_frame, 53 const EncodedVideoFrame* video_frame,
54 const base::TimeTicks& capture_time) { 54 const base::TimeTicks& capture_time) {
55 DCHECK(!config_.audio) << "Invalid state"; 55 DCHECK(!config_.audio) << "Invalid state";
56 if (config_.audio) 56 if (config_.audio)
57 return; 57 return;
58 58
59 time_last_sent_rtp_timestamp_ = capture_time;
60 Cast(video_frame->key_frame, 59 Cast(video_frame->key_frame,
61 video_frame->frame_id, 60 video_frame->frame_id,
62 video_frame->last_referenced_frame_id, 61 video_frame->last_referenced_frame_id,
63 video_frame->rtp_timestamp, 62 video_frame->rtp_timestamp,
64 video_frame->data); 63 video_frame->data,
64 capture_time);
65 } 65 }
66 66
67 void RtpPacketizer::IncomingEncodedAudioFrame( 67 void RtpPacketizer::IncomingEncodedAudioFrame(
68 const EncodedAudioFrame* audio_frame, 68 const EncodedAudioFrame* audio_frame,
69 const base::TimeTicks& recorded_time) { 69 const base::TimeTicks& recorded_time) {
70 DCHECK(config_.audio) << "Invalid state"; 70 DCHECK(config_.audio) << "Invalid state";
71 if (!config_.audio) 71 if (!config_.audio)
72 return; 72 return;
73 73
74 time_last_sent_rtp_timestamp_ = recorded_time;
75 Cast(true, 74 Cast(true,
76 audio_frame->frame_id, 75 audio_frame->frame_id,
77 0, 76 0,
78 audio_frame->rtp_timestamp, 77 audio_frame->rtp_timestamp,
79 audio_frame->data); 78 audio_frame->data,
79 recorded_time);
80 } 80 }
81 81
82 uint16 RtpPacketizer::NextSequenceNumber() { 82 uint16 RtpPacketizer::NextSequenceNumber() {
83 ++sequence_number_; 83 ++sequence_number_;
84 return sequence_number_ - 1; 84 return sequence_number_ - 1;
85 } 85 }
86 86
87 bool RtpPacketizer::LastSentTimestamp(base::TimeTicks* time_sent, 87 bool RtpPacketizer::LastSentTimestamp(base::TimeTicks* time_sent,
88 uint32* rtp_timestamp) const { 88 uint32* rtp_timestamp) const {
89 if (time_last_sent_rtp_timestamp_.is_null()) 89 if (time_last_sent_rtp_timestamp_.is_null())
90 return false; 90 return false;
91 91
92 *time_sent = time_last_sent_rtp_timestamp_; 92 *time_sent = time_last_sent_rtp_timestamp_;
93 *rtp_timestamp = rtp_timestamp_; 93 *rtp_timestamp = rtp_timestamp_;
94 return true; 94 return true;
95 } 95 }
96 96
97 // TODO(mikhal): Switch to pass data with a const_ref. 97 // TODO(mikhal): Switch to pass data with a const_ref.
98 void RtpPacketizer::Cast(bool is_key, 98 void RtpPacketizer::Cast(bool is_key,
99 uint32 frame_id, 99 uint32 frame_id,
100 uint32 reference_frame_id, 100 uint32 reference_frame_id,
101 uint32 timestamp, 101 uint32 timestamp,
102 const std::string& data) { 102 const std::string& data,
103 const base::TimeTicks& capture_time) {
104 time_last_sent_rtp_timestamp_ = capture_time;
103 uint16 rtp_header_length = kCommonRtpHeaderLength + kCastRtpHeaderLength; 105 uint16 rtp_header_length = kCommonRtpHeaderLength + kCastRtpHeaderLength;
104 uint16 max_length = config_.max_payload_length - rtp_header_length - 1; 106 uint16 max_length = config_.max_payload_length - rtp_header_length - 1;
105 rtp_timestamp_ = timestamp; 107 rtp_timestamp_ = timestamp;
106 108
107 // Split the payload evenly (round number up). 109 // Split the payload evenly (round number up).
108 size_t num_packets = (data.size() + max_length) / max_length; 110 size_t num_packets = (data.size() + max_length) / max_length;
109 size_t payload_length = (data.size() + num_packets) / num_packets; 111 size_t payload_length = (data.size() + num_packets) / num_packets;
110 DCHECK_LE(payload_length, max_length) << "Invalid argument"; 112 DCHECK_LE(payload_length, max_length) << "Invalid argument";
111 113
112 PacketList packets; 114 SendPacketVector packets;
115 PacketList packets_for_logging;
113 116
114 size_t remaining_size = data.size(); 117 size_t remaining_size = data.size();
115 std::string::const_iterator data_iter = data.begin(); 118 std::string::const_iterator data_iter = data.begin();
116 while (remaining_size > 0) { 119 while (remaining_size > 0) {
117 PacketRef packet(new base::RefCountedData<Packet>); 120 PacketRef packet(new base::RefCountedData<Packet>);
118 121
119 if (remaining_size < payload_length) { 122 if (remaining_size < payload_length) {
120 payload_length = remaining_size; 123 payload_length = remaining_size;
121 } 124 }
122 remaining_size -= payload_length; 125 remaining_size -= payload_length;
123 BuildCommonRTPheader(&packet->data, remaining_size == 0, timestamp); 126 BuildCommonRTPheader(&packet->data, remaining_size == 0, timestamp);
124 127
125 // Build Cast header. 128 // Build Cast header.
126 packet->data.push_back((is_key ? kCastKeyFrameBitMask : 0) | 129 packet->data.push_back((is_key ? kCastKeyFrameBitMask : 0) |
127 kCastReferenceFrameIdBitMask); 130 kCastReferenceFrameIdBitMask);
128 packet->data.push_back(frame_id); 131 packet->data.push_back(frame_id);
129 size_t start_size = packet->data.size(); 132 size_t start_size = packet->data.size();
130 packet->data.resize(start_size + 4); 133 packet->data.resize(start_size + 4);
131 base::BigEndianWriter big_endian_writer( 134 base::BigEndianWriter big_endian_writer(
132 reinterpret_cast<char*>(&(packet->data[start_size])), 4); 135 reinterpret_cast<char*>(&(packet->data[start_size])), 4);
133 big_endian_writer.WriteU16(packet_id_); 136 big_endian_writer.WriteU16(packet_id_);
134 big_endian_writer.WriteU16(static_cast<uint16>(num_packets - 1)); 137 big_endian_writer.WriteU16(static_cast<uint16>(num_packets - 1));
135 packet->data.push_back(static_cast<uint8>(reference_frame_id)); 138 packet->data.push_back(static_cast<uint8>(reference_frame_id));
136 139
137 // Copy payload data. 140 // Copy payload data.
138 packet->data.insert(packet->data.end(), 141 packet->data.insert(packet->data.end(),
139 data_iter, 142 data_iter,
140 data_iter + payload_length); 143 data_iter + payload_length);
141 144
145 PacketKey key = PacedPacketSender::MakePacketKey(capture_time,
146 config_.ssrc,
147 packet_id_);
148
142 // Store packet. 149 // Store packet.
143 packet_storage_->StorePacket(frame_id, packet_id_, packet); 150 packet_storage_->StorePacket(frame_id, packet_id_, key, packet);
144 ++packet_id_; 151 ++packet_id_;
145 data_iter += payload_length; 152 data_iter += payload_length;
146 153
147 // Update stats. 154 // Update stats.
148 ++send_packets_count_; 155 ++send_packets_count_;
149 send_octet_count_ += payload_length; 156 send_octet_count_ += payload_length;
150 packets.push_back(packet); 157 packets.push_back(make_pair(key, packet));
158 packets_for_logging.push_back(packet);
151 } 159 }
152 DCHECK(packet_id_ == num_packets) << "Invalid state"; 160 DCHECK(packet_id_ == num_packets) << "Invalid state";
153 161
154 logging_->InsertPacketListEvent( 162 logging_->InsertPacketListEvent(
155 clock_->NowTicks(), 163 clock_->NowTicks(),
156 config_.audio ? kAudioPacketSentToPacer : kVideoPacketSentToPacer, 164 config_.audio ? kAudioPacketSentToPacer : kVideoPacketSentToPacer,
157 packets); 165 packets_for_logging);
158 166
159 // Send to network. 167 // Send to network.
160 transport_->SendPackets(packets); 168 transport_->SendPackets(packets);
161 169
162 // Prepare for next frame. 170 // Prepare for next frame.
163 packet_id_ = 0; 171 packet_id_ = 0;
164 } 172 }
165 173
166 void RtpPacketizer::BuildCommonRTPheader(Packet* packet, 174 void RtpPacketizer::BuildCommonRTPheader(Packet* packet,
167 bool marker_bit, 175 bool marker_bit,
168 uint32 time_stamp) { 176 uint32 time_stamp) {
169 packet->push_back(0x80); 177 packet->push_back(0x80);
170 packet->push_back(static_cast<uint8>(config_.payload_type) | 178 packet->push_back(static_cast<uint8>(config_.payload_type) |
171 (marker_bit ? kRtpMarkerBitMask : 0)); 179 (marker_bit ? kRtpMarkerBitMask : 0));
172 size_t start_size = packet->size(); 180 size_t start_size = packet->size();
173 packet->resize(start_size + 10); 181 packet->resize(start_size + 10);
174 base::BigEndianWriter big_endian_writer( 182 base::BigEndianWriter big_endian_writer(
175 reinterpret_cast<char*>(&((*packet)[start_size])), 10); 183 reinterpret_cast<char*>(&((*packet)[start_size])), 10);
176 big_endian_writer.WriteU16(sequence_number_); 184 big_endian_writer.WriteU16(sequence_number_);
177 big_endian_writer.WriteU32(time_stamp); 185 big_endian_writer.WriteU32(time_stamp);
178 big_endian_writer.WriteU32(config_.ssrc); 186 big_endian_writer.WriteU32(config_.ssrc);
179 ++sequence_number_; 187 ++sequence_number_;
180 } 188 }
181 189
182 } // namespace transport 190 } // namespace transport
183 } // namespace cast 191 } // namespace cast
184 } // namespace media 192 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/transport/rtp_sender/rtp_packetizer/rtp_packetizer.h ('k') | media/cast/transport/rtp_sender/rtp_sender.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698