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

Side by Side Diff: webrtc/modules/rtp_rtcp/source/producer_fec.cc

Issue 2260803002: Generalize FEC header formatting. (pt. 4) (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Lint fix. Created 4 years, 3 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 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 86
87 uint8_t* RedPacket::data() const { 87 uint8_t* RedPacket::data() const {
88 return data_.get(); 88 return data_.get();
89 } 89 }
90 90
91 size_t RedPacket::length() const { 91 size_t RedPacket::length() const {
92 return length_; 92 return length_;
93 } 93 }
94 94
95 ProducerFec::ProducerFec() 95 ProducerFec::ProducerFec()
96 : num_protected_frames_(0), 96 : fec_(ForwardErrorCorrection::CreateUlpfec()),
97 num_protected_frames_(0),
97 num_important_packets_(0), 98 num_important_packets_(0),
98 min_num_media_packets_(1) { 99 min_num_media_packets_(1) {
99 memset(&params_, 0, sizeof(params_)); 100 memset(&params_, 0, sizeof(params_));
100 memset(&new_params_, 0, sizeof(new_params_)); 101 memset(&new_params_, 0, sizeof(new_params_));
101 } 102 }
102 103
103 ProducerFec::~ProducerFec() { 104 ProducerFec::~ProducerFec() {
104 DeleteMediaPackets(); 105 DeleteMediaPackets();
105 } 106 }
106 107
107 std::unique_ptr<RedPacket> ProducerFec::BuildRedPacket( 108 std::unique_ptr<RedPacket> ProducerFec::BuildRedPacket(
108 const uint8_t* data_buffer, 109 const uint8_t* data_buffer,
109 size_t payload_length, 110 size_t payload_length,
110 size_t rtp_header_length, 111 size_t rtp_header_length,
111 int red_payload_type) { 112 int red_payload_type) {
112 std::unique_ptr<RedPacket> red_packet(new RedPacket( 113 std::unique_ptr<RedPacket> red_packet(new RedPacket(
113 payload_length + kRedForFecHeaderLength + rtp_header_length)); 114 payload_length + kRedForFecHeaderLength + rtp_header_length));
114 int payload_type = data_buffer[1] & 0x7f; 115 int payload_type = data_buffer[1] & 0x7f;
115 red_packet->CreateHeader(data_buffer, rtp_header_length, red_payload_type, 116 red_packet->CreateHeader(data_buffer, rtp_header_length, red_payload_type,
116 payload_type); 117 payload_type);
117 red_packet->AssignPayload(data_buffer + rtp_header_length, payload_length); 118 red_packet->AssignPayload(data_buffer + rtp_header_length, payload_length);
118 return red_packet; 119 return red_packet;
119 } 120 }
120 121
121 void ProducerFec::SetFecParameters(const FecProtectionParams* params, 122 void ProducerFec::SetFecParameters(const FecProtectionParams* params,
122 int num_important_packets) { 123 int num_important_packets) {
123 // Number of important packets (i.e. number of packets receiving additional 124 // Number of important packets (i.e. number of packets receiving additional
124 // protection in 'unequal protection mode') cannot exceed kMaxMediaPackets. 125 // protection in 'unequal protection mode') cannot exceed kMaxMediaPackets.
125 RTC_DCHECK_GE(params->fec_rate, 0); 126 RTC_DCHECK_GE(params->fec_rate, 0);
126 RTC_DCHECK_LE(params->fec_rate, 255); 127 RTC_DCHECK_LE(params->fec_rate, 255);
127 if (num_important_packets > 128 if (num_important_packets > static_cast<int>(kUlpfecMaxMediaPackets)) {
128 static_cast<int>(ForwardErrorCorrection::kMaxMediaPackets)) { 129 num_important_packets = kUlpfecMaxMediaPackets;
129 num_important_packets = ForwardErrorCorrection::kMaxMediaPackets;
130 } 130 }
131 // Store the new params and apply them for the next set of FEC packets being 131 // Store the new params and apply them for the next set of FEC packets being
132 // produced. 132 // produced.
133 new_params_ = *params; 133 new_params_ = *params;
134 num_important_packets_ = num_important_packets; 134 num_important_packets_ = num_important_packets;
135 if (params->fec_rate > kHighProtectionThreshold) { 135 if (params->fec_rate > kHighProtectionThreshold) {
136 min_num_media_packets_ = kMinMediaPackets; 136 min_num_media_packets_ = kMinMediaPackets;
137 } else { 137 } else {
138 min_num_media_packets_ = 1; 138 min_num_media_packets_ = 1;
139 } 139 }
140 } 140 }
141 141
142 int ProducerFec::AddRtpPacketAndGenerateFec(const uint8_t* data_buffer, 142 int ProducerFec::AddRtpPacketAndGenerateFec(const uint8_t* data_buffer,
143 size_t payload_length, 143 size_t payload_length,
144 size_t rtp_header_length) { 144 size_t rtp_header_length) {
145 RTC_DCHECK(generated_fec_packets_.empty()); 145 RTC_DCHECK(generated_fec_packets_.empty());
146 if (media_packets_.empty()) { 146 if (media_packets_.empty()) {
147 params_ = new_params_; 147 params_ = new_params_;
148 } 148 }
149 bool complete_frame = false; 149 bool complete_frame = false;
150 const bool marker_bit = (data_buffer[1] & kRtpMarkerBitMask) ? true : false; 150 const bool marker_bit = (data_buffer[1] & kRtpMarkerBitMask) ? true : false;
151 if (media_packets_.size() < ForwardErrorCorrection::kMaxMediaPackets) { 151 if (media_packets_.size() < kUlpfecMaxMediaPackets) {
152 // Generic FEC can only protect up to |kMaxMediaPackets| packets. 152 // Generic FEC can only protect up to |kUlpfecMaxMediaPackets| packets.
153 std::unique_ptr<ForwardErrorCorrection::Packet> packet( 153 std::unique_ptr<ForwardErrorCorrection::Packet> packet(
154 new ForwardErrorCorrection::Packet()); 154 new ForwardErrorCorrection::Packet());
155 packet->length = payload_length + rtp_header_length; 155 packet->length = payload_length + rtp_header_length;
156 memcpy(packet->data, data_buffer, packet->length); 156 memcpy(packet->data, data_buffer, packet->length);
157 media_packets_.push_back(std::move(packet)); 157 media_packets_.push_back(std::move(packet));
158 } 158 }
159 if (marker_bit) { 159 if (marker_bit) {
160 ++num_protected_frames_; 160 ++num_protected_frames_;
161 complete_frame = true; 161 complete_frame = true;
162 } 162 }
163 // Produce FEC over at most |params_.max_fec_frames| frames, or as soon as: 163 // Produce FEC over at most |params_.max_fec_frames| frames, or as soon as:
164 // (1) the excess overhead (actual overhead - requested/target overhead) is 164 // (1) the excess overhead (actual overhead - requested/target overhead) is
165 // less than |kMaxExcessOverhead|, and 165 // less than |kMaxExcessOverhead|, and
166 // (2) at least |min_num_media_packets_| media packets is reached. 166 // (2) at least |min_num_media_packets_| media packets is reached.
167 if (complete_frame && 167 if (complete_frame &&
168 (num_protected_frames_ == params_.max_fec_frames || 168 (num_protected_frames_ == params_.max_fec_frames ||
169 (ExcessOverheadBelowMax() && MinimumMediaPacketsReached()))) { 169 (ExcessOverheadBelowMax() && MinimumMediaPacketsReached()))) {
170 RTC_DCHECK_LE(num_important_packets_, 170 RTC_DCHECK_LE(num_important_packets_,
171 static_cast<int>(ForwardErrorCorrection::kMaxMediaPackets)); 171 static_cast<int>(kUlpfecMaxMediaPackets));
172 // TODO(pbos): Consider whether unequal protection should be enabled or not, 172 // TODO(pbos): Consider whether unequal protection should be enabled or not,
173 // it is currently always disabled. 173 // it is currently always disabled.
174 // 174 //
175 // Since unequal protection is disabled, the value of 175 // Since unequal protection is disabled, the value of
176 // |num_important_packets_| has no importance when calling GenerateFec(). 176 // |num_important_packets_| has no importance when calling GenerateFec().
177 constexpr bool kUseUnequalProtection = false; 177 constexpr bool kUseUnequalProtection = false;
178 int ret = fec_.EncodeFec(media_packets_, params_.fec_rate, 178 int ret = fec_->EncodeFec(media_packets_, params_.fec_rate,
179 num_important_packets_, kUseUnequalProtection, 179 num_important_packets_, kUseUnequalProtection,
180 params_.fec_mask_type, &generated_fec_packets_); 180 params_.fec_mask_type, &generated_fec_packets_);
181 if (generated_fec_packets_.empty()) { 181 if (generated_fec_packets_.empty()) {
182 num_protected_frames_ = 0; 182 num_protected_frames_ = 0;
183 DeleteMediaPackets(); 183 DeleteMediaPackets();
184 } 184 }
185 return ret; 185 return ret;
186 } 186 }
187 return 0; 187 return 0;
188 } 188 }
189 189
190 bool ProducerFec::ExcessOverheadBelowMax() const { 190 bool ProducerFec::ExcessOverheadBelowMax() const {
(...skipping 15 matching lines...) Expand all
206 206
207 bool ProducerFec::FecAvailable() const { 207 bool ProducerFec::FecAvailable() const {
208 return !generated_fec_packets_.empty(); 208 return !generated_fec_packets_.empty();
209 } 209 }
210 210
211 size_t ProducerFec::NumAvailableFecPackets() const { 211 size_t ProducerFec::NumAvailableFecPackets() const {
212 return generated_fec_packets_.size(); 212 return generated_fec_packets_.size();
213 } 213 }
214 214
215 size_t ProducerFec::MaxPacketOverhead() const { 215 size_t ProducerFec::MaxPacketOverhead() const {
216 return fec_.MaxPacketOverhead(); 216 return fec_->MaxPacketOverhead();
217 } 217 }
218 218
219 std::vector<std::unique_ptr<RedPacket>> ProducerFec::GetFecPacketsAsRed( 219 std::vector<std::unique_ptr<RedPacket>> ProducerFec::GetFecPacketsAsRed(
220 int red_payload_type, 220 int red_payload_type,
221 int ulpfec_payload_type, 221 int ulpfec_payload_type,
222 uint16_t first_seq_num, 222 uint16_t first_seq_num,
223 size_t rtp_header_length) { 223 size_t rtp_header_length) {
224 std::vector<std::unique_ptr<RedPacket>> red_packets; 224 std::vector<std::unique_ptr<RedPacket>> red_packets;
225 red_packets.reserve(generated_fec_packets_.size()); 225 red_packets.reserve(generated_fec_packets_.size());
226 RTC_DCHECK(!media_packets_.empty()); 226 RTC_DCHECK(!media_packets_.empty());
227 ForwardErrorCorrection::Packet* last_media_packet = 227 ForwardErrorCorrection::Packet* last_media_packet =
228 media_packets_.back().get(); 228 media_packets_.back().get();
229 uint16_t seq_num = first_seq_num; 229 uint16_t seq_num = first_seq_num;
230 for (const auto& fec_packet : generated_fec_packets_) { 230 for (const auto& fec_packet : generated_fec_packets_) {
231 // Wrap FEC packet (including FEC headers) in a RED packet. Since the 231 // Wrap FEC packet (including FEC headers) in a RED packet. Since the
232 // FEC packets in |generated_fec_packets_| don't have RTP headers, we 232 // FEC packets in |generated_fec_packets_| don't have RTP headers, we
233 // reuse the header from the last media packet. 233 // reuse the header from the last media packet.
234 std::unique_ptr<RedPacket> red_packet(new RedPacket( 234 std::unique_ptr<RedPacket> red_packet(new RedPacket(
235 fec_packet->length + kRedForFecHeaderLength + rtp_header_length)); 235 fec_packet->length + kRedForFecHeaderLength + rtp_header_length));
236 red_packet->CreateHeader(last_media_packet->data, rtp_header_length, 236 red_packet->CreateHeader(last_media_packet->data, rtp_header_length,
237 red_payload_type, ulpfec_payload_type); 237 red_payload_type, ulpfec_payload_type);
238 red_packet->SetSeqNum(seq_num++); 238 red_packet->SetSeqNum(seq_num++);
239 red_packet->ClearMarkerBit(); 239 red_packet->ClearMarkerBit();
240 red_packet->AssignPayload(fec_packet->data, fec_packet->length); 240 red_packet->AssignPayload(fec_packet->data, fec_packet->length);
241
242 red_packets.push_back(std::move(red_packet)); 241 red_packets.push_back(std::move(red_packet));
243 } 242 }
244
245 // Reset state. 243 // Reset state.
246 DeleteMediaPackets(); 244 DeleteMediaPackets();
247 generated_fec_packets_.clear(); 245 generated_fec_packets_.clear();
248 num_protected_frames_ = 0; 246 num_protected_frames_ = 0;
249
250 return red_packets; 247 return red_packets;
251 } 248 }
252 249
253 int ProducerFec::Overhead() const { 250 int ProducerFec::Overhead() const {
254 // Overhead is defined as relative to the number of media packets, and not 251 // Overhead is defined as relative to the number of media packets, and not
255 // relative to total number of packets. This definition is inherited from the 252 // relative to total number of packets. This definition is inherited from the
256 // protection factor produced by video_coding module and how the FEC 253 // protection factor produced by video_coding module and how the FEC
257 // generation is implemented. 254 // generation is implemented.
258 RTC_DCHECK(!media_packets_.empty()); 255 RTC_DCHECK(!media_packets_.empty());
259 int num_fec_packets = 256 int num_fec_packets =
260 fec_.NumFecPackets(media_packets_.size(), params_.fec_rate); 257 fec_->NumFecPackets(media_packets_.size(), params_.fec_rate);
261 // Return the overhead in Q8. 258 // Return the overhead in Q8.
262 return (num_fec_packets << 8) / media_packets_.size(); 259 return (num_fec_packets << 8) / media_packets_.size();
263 } 260 }
264 261
265 void ProducerFec::DeleteMediaPackets() { 262 void ProducerFec::DeleteMediaPackets() {
266 media_packets_.clear(); 263 media_packets_.clear();
267 } 264 }
268 265
269 } // namespace webrtc 266 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/producer_fec.h ('k') | webrtc/modules/rtp_rtcp/source/rtp_fec_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698