Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 45 } // namespace | 45 } // namespace |
| 46 | 46 |
| 47 RTPSenderVideo::RTPSenderVideo(Clock* clock, RTPSender* rtp_sender) | 47 RTPSenderVideo::RTPSenderVideo(Clock* clock, RTPSender* rtp_sender) |
| 48 : rtp_sender_(rtp_sender), | 48 : rtp_sender_(rtp_sender), |
| 49 clock_(clock), | 49 clock_(clock), |
| 50 video_type_(kRtpVideoGeneric), | 50 video_type_(kRtpVideoGeneric), |
| 51 retransmission_settings_(kRetransmitBaseLayer), | 51 retransmission_settings_(kRetransmitBaseLayer), |
| 52 last_rotation_(kVideoRotation_0), | 52 last_rotation_(kVideoRotation_0), |
| 53 red_payload_type_(-1), | 53 red_payload_type_(-1), |
| 54 ulpfec_payload_type_(-1), | 54 ulpfec_payload_type_(-1), |
| 55 flexfec_sender_(nullptr), // TODO(brandtr): Wire up in future CL. | |
| 55 delta_fec_params_{0, 1, kFecMaskRandom}, | 56 delta_fec_params_{0, 1, kFecMaskRandom}, |
| 56 key_fec_params_{0, 1, kFecMaskRandom}, | 57 key_fec_params_{0, 1, kFecMaskRandom}, |
| 57 fec_bitrate_(1000, RateStatistics::kBpsScale), | 58 fec_bitrate_(1000, RateStatistics::kBpsScale), |
| 58 video_bitrate_(1000, RateStatistics::kBpsScale) { | 59 video_bitrate_(1000, RateStatistics::kBpsScale) { |
| 59 encoder_checker_.Detach(); | 60 encoder_checker_.Detach(); |
| 60 } | 61 } |
| 61 | 62 |
| 62 RTPSenderVideo::~RTPSenderVideo() {} | 63 RTPSenderVideo::~RTPSenderVideo() {} |
| 63 | 64 |
| 64 void RTPSenderVideo::SetVideoCodecType(RtpVideoCodecTypes video_type) { | 65 void RTPSenderVideo::SetVideoCodecType(RtpVideoCodecTypes video_type) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 104 LOG(LS_WARNING) << "Failed to send video packet " << seq_num; | 105 LOG(LS_WARNING) << "Failed to send video packet " << seq_num; |
| 105 return; | 106 return; |
| 106 } | 107 } |
| 107 rtc::CritScope cs(&stats_crit_); | 108 rtc::CritScope cs(&stats_crit_); |
| 108 video_bitrate_.Update(packet_size, clock_->TimeInMilliseconds()); | 109 video_bitrate_.Update(packet_size, clock_->TimeInMilliseconds()); |
| 109 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 110 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
| 110 "Video::PacketNormal", "timestamp", rtp_timestamp, | 111 "Video::PacketNormal", "timestamp", rtp_timestamp, |
| 111 "seqnum", seq_num); | 112 "seqnum", seq_num); |
| 112 } | 113 } |
| 113 | 114 |
| 114 void RTPSenderVideo::SendVideoPacketAsRed( | 115 void RTPSenderVideo::SendVideoPacketAsRedMaybeWithUlpfec( |
| 115 std::unique_ptr<RtpPacketToSend> media_packet, | 116 std::unique_ptr<RtpPacketToSend> media_packet, |
| 116 StorageType media_packet_storage, | 117 StorageType media_packet_storage, |
| 117 bool protect) { | 118 bool protect_media_packet) { |
| 118 uint32_t rtp_timestamp = media_packet->Timestamp(); | 119 uint32_t rtp_timestamp = media_packet->Timestamp(); |
| 119 uint16_t media_seq_num = media_packet->SequenceNumber(); | 120 uint16_t media_seq_num = media_packet->SequenceNumber(); |
| 120 | 121 |
| 121 std::unique_ptr<RtpPacketToSend> red_packet( | 122 std::unique_ptr<RtpPacketToSend> red_packet( |
| 122 new RtpPacketToSend(*media_packet)); | 123 new RtpPacketToSend(*media_packet)); |
| 123 BuildRedPayload(*media_packet, red_packet.get()); | 124 BuildRedPayload(*media_packet, red_packet.get()); |
| 124 | 125 |
| 125 std::vector<std::unique_ptr<RedPacket>> fec_packets; | 126 std::vector<std::unique_ptr<RedPacket>> fec_packets; |
| 126 StorageType fec_storage = kDontRetransmit; | 127 StorageType fec_storage = kDontRetransmit; |
| 127 { | 128 { |
| 128 // Only protect while creating RED and FEC packets, not when sending. | 129 // Only protect while creating RED and FEC packets, not when sending. |
| 129 rtc::CritScope cs(&crit_); | 130 rtc::CritScope cs(&crit_); |
| 130 red_packet->SetPayloadType(red_payload_type_); | 131 red_packet->SetPayloadType(red_payload_type_); |
| 131 if (protect) { | 132 if (ulpfec_enabled()) { |
| 132 ulpfec_generator_.AddRtpPacketAndGenerateFec( | 133 if (protect_media_packet) { |
| 133 media_packet->data(), media_packet->payload_size(), | 134 ulpfec_generator_.AddRtpPacketAndGenerateFec( |
| 134 media_packet->headers_size()); | 135 media_packet->data(), media_packet->payload_size(), |
| 135 } | 136 media_packet->headers_size()); |
| 136 uint16_t num_fec_packets = ulpfec_generator_.NumAvailableFecPackets(); | 137 } |
| 137 if (num_fec_packets > 0) { | 138 uint16_t num_fec_packets = ulpfec_generator_.NumAvailableFecPackets(); |
| 138 uint16_t first_fec_sequence_number = | 139 if (num_fec_packets > 0) { |
| 139 rtp_sender_->AllocateSequenceNumber(num_fec_packets); | 140 uint16_t first_fec_sequence_number = |
| 140 fec_packets = ulpfec_generator_.GetUlpfecPacketsAsRed( | 141 rtp_sender_->AllocateSequenceNumber(num_fec_packets); |
| 141 red_payload_type_, ulpfec_payload_type_, first_fec_sequence_number, | 142 fec_packets = ulpfec_generator_.GetUlpfecPacketsAsRed( |
| 142 media_packet->headers_size()); | 143 red_payload_type_, ulpfec_payload_type_, first_fec_sequence_number, |
| 143 RTC_DCHECK_EQ(num_fec_packets, fec_packets.size()); | 144 media_packet->headers_size()); |
| 144 if (retransmission_settings_ & kRetransmitFECPackets) | 145 RTC_DCHECK_EQ(num_fec_packets, fec_packets.size()); |
| 145 fec_storage = kAllowRetransmission; | 146 if (retransmission_settings_ & kRetransmitFECPackets) |
| 147 fec_storage = kAllowRetransmission; | |
| 148 } | |
| 146 } | 149 } |
| 147 } | 150 } |
| 148 // Send |red_packet| instead of |packet| for allocated sequence number. | 151 // Send |red_packet| instead of |packet| for allocated sequence number. |
| 149 size_t red_packet_size = red_packet->size(); | 152 size_t red_packet_size = red_packet->size(); |
| 150 if (rtp_sender_->SendToNetwork(std::move(red_packet), media_packet_storage, | 153 if (rtp_sender_->SendToNetwork(std::move(red_packet), media_packet_storage, |
| 151 RtpPacketSender::kLowPriority)) { | 154 RtpPacketSender::kLowPriority)) { |
| 152 rtc::CritScope cs(&stats_crit_); | 155 rtc::CritScope cs(&stats_crit_); |
| 153 video_bitrate_.Update(red_packet_size, clock_->TimeInMilliseconds()); | 156 video_bitrate_.Update(red_packet_size, clock_->TimeInMilliseconds()); |
| 154 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 157 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
| 155 "Video::PacketRed", "timestamp", rtp_timestamp, | 158 "Video::PacketRed", "timestamp", rtp_timestamp, |
| 156 "seqnum", media_seq_num); | 159 "seqnum", media_seq_num); |
| 157 } else { | 160 } else { |
| 158 LOG(LS_WARNING) << "Failed to send RED packet " << media_seq_num; | 161 LOG(LS_WARNING) << "Failed to send RED packet " << media_seq_num; |
| 159 } | 162 } |
| 160 for (const auto& fec_packet : fec_packets) { | 163 for (const auto& fec_packet : fec_packets) { |
| 161 // TODO(danilchap): Make ulpfec_generator_ generate RtpPacketToSend to avoid | 164 // TODO(danilchap): Make ulpfec_generator_ generate RtpPacketToSend to avoid |
| 162 // reparsing them. | 165 // reparsing them. |
| 163 std::unique_ptr<RtpPacketToSend> rtp_packet( | 166 std::unique_ptr<RtpPacketToSend> rtp_packet( |
| 164 new RtpPacketToSend(*media_packet)); | 167 new RtpPacketToSend(*media_packet)); |
| 165 RTC_CHECK(rtp_packet->Parse(fec_packet->data(), fec_packet->length())); | 168 RTC_CHECK(rtp_packet->Parse(fec_packet->data(), fec_packet->length())); |
| 166 rtp_packet->set_capture_time_ms(media_packet->capture_time_ms()); | 169 rtp_packet->set_capture_time_ms(media_packet->capture_time_ms()); |
| 167 uint16_t fec_sequence_number = rtp_packet->SequenceNumber(); | 170 uint16_t fec_sequence_number = rtp_packet->SequenceNumber(); |
| 168 if (rtp_sender_->SendToNetwork(std::move(rtp_packet), fec_storage, | 171 if (rtp_sender_->SendToNetwork(std::move(rtp_packet), fec_storage, |
| 169 RtpPacketSender::kLowPriority)) { | 172 RtpPacketSender::kLowPriority)) { |
| 170 rtc::CritScope cs(&stats_crit_); | 173 rtc::CritScope cs(&stats_crit_); |
| 171 fec_bitrate_.Update(fec_packet->length(), clock_->TimeInMilliseconds()); | 174 fec_bitrate_.Update(fec_packet->length(), clock_->TimeInMilliseconds()); |
| 172 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 175 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
| 173 "Video::PacketFec", "timestamp", rtp_timestamp, | 176 "Video::PacketUlpfec", "timestamp", rtp_timestamp, |
| 174 "seqnum", fec_sequence_number); | 177 "seqnum", fec_sequence_number); |
| 175 } else { | 178 } else { |
| 176 LOG(LS_WARNING) << "Failed to send FEC packet " << fec_sequence_number; | 179 LOG(LS_WARNING) << "Failed to send ULPFEC packet " << fec_sequence_number; |
| 177 } | 180 } |
| 178 } | 181 } |
| 179 } | 182 } |
| 183 | |
| 184 void RTPSenderVideo::SendVideoPacketWithFlexfec( | |
| 185 std::unique_ptr<RtpPacketToSend> media_packet, | |
| 186 StorageType media_packet_storage, | |
| 187 bool protect_media_packet) { | |
| 188 RTC_DCHECK(flexfec_sender_); | |
| 189 | |
| 190 if (protect_media_packet) | |
| 191 flexfec_sender_->AddRtpPacketAndGenerateFec(*media_packet); | |
| 192 | |
| 193 SendVideoPacket(std::move(media_packet), media_packet_storage); | |
| 194 | |
| 195 if (flexfec_sender_->FecAvailable()) { | |
| 196 std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets = | |
| 197 flexfec_sender_->GetFecPackets(); | |
| 198 for (auto& fec_packet : fec_packets) { | |
| 199 uint32_t timestamp = fec_packet->Timestamp(); | |
| 200 uint16_t seq_num = fec_packet->SequenceNumber(); | |
| 201 if (rtp_sender_->SendToNetwork(std::move(fec_packet), kDontRetransmit, | |
| 202 RtpPacketSender::kLowPriority)) { | |
| 203 // TODO(brandtr): Wire up stats here. | |
| 204 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | |
| 205 "Video::PacketFlexfec", "timestamp", timestamp, | |
| 206 "seqnum", seq_num); | |
| 207 } else { | |
| 208 LOG(LS_WARNING) << "Failed to send FlexFEC packet " << seq_num; | |
| 209 } | |
| 210 } | |
| 211 } | |
| 212 } | |
| 180 | 213 |
| 181 void RTPSenderVideo::SetUlpfecConfig(int red_payload_type, | 214 void RTPSenderVideo::SetUlpfecConfig(int red_payload_type, |
| 182 int ulpfec_payload_type) { | 215 int ulpfec_payload_type) { |
| 183 // Sanity check. Per the definition of UlpfecConfig (see config.h), | 216 // Sanity check. Per the definition of UlpfecConfig (see config.h), |
| 184 // a payload type of -1 means that the corresponding feature is | 217 // a payload type of -1 means that the corresponding feature is |
| 185 // turned off. | 218 // turned off. |
| 186 RTC_DCHECK_GE(red_payload_type, -1); | 219 RTC_DCHECK_GE(red_payload_type, -1); |
| 187 RTC_DCHECK_LE(red_payload_type, 127); | 220 RTC_DCHECK_LE(red_payload_type, 127); |
| 188 RTC_DCHECK_GE(ulpfec_payload_type, -1); | 221 RTC_DCHECK_GE(ulpfec_payload_type, -1); |
| 189 RTC_DCHECK_LE(ulpfec_payload_type, 127); | 222 RTC_DCHECK_LE(ulpfec_payload_type, 127); |
| 190 | 223 |
| 191 rtc::CritScope cs(&crit_); | 224 rtc::CritScope cs(&crit_); |
| 192 red_payload_type_ = red_payload_type; | 225 red_payload_type_ = red_payload_type; |
| 193 ulpfec_payload_type_ = ulpfec_payload_type; | 226 ulpfec_payload_type_ = ulpfec_payload_type; |
| 194 | 227 |
| 195 // Must not enable ULPFEC without RED. | 228 // Must not enable ULPFEC without RED. |
| 196 // TODO(brandtr): We currently support enabling RED without ULPFEC. Change | 229 // TODO(brandtr): We currently support enabling RED without ULPFEC. Change |
| 197 // this when we have removed the RED/RTX send-side workaround, so that we | 230 // this when we have removed the RED/RTX send-side workaround, so that we |
| 198 // ensure that RED and ULPFEC are only enabled together. | 231 // ensure that RED and ULPFEC are only enabled together. |
| 199 RTC_DCHECK(red_enabled() || !ulpfec_enabled()); | 232 RTC_DCHECK(red_enabled() || !ulpfec_enabled()); |
| 200 | 233 |
| 201 // Reset FEC rates. | 234 // Reset FEC parameters. |
| 202 delta_fec_params_ = FecProtectionParams{0, 1, kFecMaskRandom}; | 235 delta_fec_params_ = FecProtectionParams{0, 1, kFecMaskRandom}; |
| 203 key_fec_params_ = FecProtectionParams{0, 1, kFecMaskRandom}; | 236 key_fec_params_ = FecProtectionParams{0, 1, kFecMaskRandom}; |
| 204 } | 237 } |
| 205 | 238 |
| 206 void RTPSenderVideo::GetUlpfecConfig(int* red_payload_type, | 239 void RTPSenderVideo::GetUlpfecConfig(int* red_payload_type, |
| 207 int* ulpfec_payload_type) const { | 240 int* ulpfec_payload_type) const { |
| 208 rtc::CritScope cs(&crit_); | 241 rtc::CritScope cs(&crit_); |
| 209 *red_payload_type = red_payload_type_; | 242 *red_payload_type = red_payload_type_; |
| 210 *ulpfec_payload_type = ulpfec_payload_type_; | 243 *ulpfec_payload_type = ulpfec_payload_type_; |
| 211 } | 244 } |
| 212 | 245 |
| 213 size_t RTPSenderVideo::FecPacketOverhead() const { | 246 size_t RTPSenderVideo::FecPacketOverhead() const { |
| 247 const size_t media_rtp_header_length = rtp_sender_->RtpHeaderLength(); | |
| 248 | |
| 249 if (flexfec_enabled()) { | |
| 250 // For FlexFEC, the overhead is the FEC headers plus anything in the | |
| 251 // RTP header beyond the 12 bytes base header (CSRC list, extensions...) | |
| 252 // This reason for the header extensions to be included here is that | |
| 253 // from an FEC viewpoint, they are part of the payload to be protected. | |
| 254 // (The base RTP header is already protected by the FEC header.) | |
| 255 // Since FlexFEC is sent on a different SSRC than media, it may however | |
| 256 // have a different RTP header length. We should account for this, as we | |
| 257 // may gain/lose some "overhead" there. | |
| 258 return flexfec_sender_->MaxPacketOverhead() // FlexFEC headers. | |
| 259 + (media_rtp_header_length - kRtpHeaderSize) // Media header exts. | |
|
danilchap
2016/11/09 15:58:46
though this is correct, I do not understand comple
brandtr
2016/11/10 09:32:01
Refer to offline discussion.
| |
| 260 + (flexfec_sender_->RtpHeaderLength() // Space saved due to | |
| 261 - media_rtp_header_length); // FlexFEC RTP header | |
| 262 // being shorter than | |
| 263 // media RTP header. | |
| 264 } | |
| 265 | |
| 214 rtc::CritScope cs(&crit_); | 266 rtc::CritScope cs(&crit_); |
| 215 size_t overhead = 0; | 267 size_t overhead = 0; |
| 216 if (red_enabled()) { | 268 if (red_enabled()) { |
| 217 // Overhead is FEC headers plus RED for FEC header plus anything in RTP | 269 // The RED overhead is due to a small header. |
| 218 // header beyond the 12 bytes base header (CSRC list, extensions...) | 270 overhead += kRedForFecHeaderLength; |
| 219 // This reason for the header extensions to be included here is that | |
| 220 // from an FEC viewpoint, they are part of the payload to be protected. | |
| 221 // (The base RTP header is already protected by the FEC header.) | |
| 222 return ulpfec_generator_.MaxPacketOverhead() + kRedForFecHeaderLength + | |
| 223 (rtp_sender_->RtpHeaderLength() - kRtpHeaderSize); | |
| 224 } | 271 } |
| 225 if (ulpfec_enabled()) | 272 if (ulpfec_enabled()) { |
| 226 overhead += ulpfec_generator_.MaxPacketOverhead(); | 273 // For ULPFEC, the overhead is the FEC headers plus RED for FEC header |
| 274 // (see above) plus anything in RTP header beyond the 12 bytes base header | |
| 275 // (CSRC list, extensions...) | |
| 276 overhead += ulpfec_generator_.MaxPacketOverhead() // ULPFEC headers. | |
| 277 + (media_rtp_header_length // Media header exts. | |
| 278 - kRtpHeaderSize); | |
| 279 } | |
| 227 return overhead; | 280 return overhead; |
| 228 } | 281 } |
| 229 | 282 |
| 230 void RTPSenderVideo::SetFecParameters(const FecProtectionParams& delta_params, | 283 void RTPSenderVideo::SetFecParameters(const FecProtectionParams& delta_params, |
| 231 const FecProtectionParams& key_params) { | 284 const FecProtectionParams& key_params) { |
| 232 rtc::CritScope cs(&crit_); | 285 rtc::CritScope cs(&crit_); |
| 233 if (ulpfec_enabled()) { | 286 delta_fec_params_ = delta_params; |
| 234 delta_fec_params_ = delta_params; | 287 key_fec_params_ = key_params; |
| 235 key_fec_params_ = key_params; | |
| 236 } | |
| 237 } | 288 } |
| 238 | 289 |
| 239 bool RTPSenderVideo::SendVideo(RtpVideoCodecTypes video_type, | 290 bool RTPSenderVideo::SendVideo(RtpVideoCodecTypes video_type, |
| 240 FrameType frame_type, | 291 FrameType frame_type, |
| 241 int8_t payload_type, | 292 int8_t payload_type, |
| 242 uint32_t rtp_timestamp, | 293 uint32_t rtp_timestamp, |
| 243 int64_t capture_time_ms, | 294 int64_t capture_time_ms, |
| 244 const uint8_t* payload_data, | 295 const uint8_t* payload_data, |
| 245 size_t payload_size, | 296 size_t payload_size, |
| 246 const RTPFragmentationHeader* fragmentation, | 297 const RTPFragmentationHeader* fragmentation, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 283 | 334 |
| 284 std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( | 335 std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( |
| 285 video_type, max_data_payload_length, | 336 video_type, max_data_payload_length, |
| 286 video_header ? &(video_header->codecHeader) : nullptr, frame_type)); | 337 video_header ? &(video_header->codecHeader) : nullptr, frame_type)); |
| 287 | 338 |
| 288 StorageType storage; | 339 StorageType storage; |
| 289 bool red_enabled; | 340 bool red_enabled; |
| 290 bool first_frame = first_frame_sent_(); | 341 bool first_frame = first_frame_sent_(); |
| 291 { | 342 { |
| 292 rtc::CritScope cs(&crit_); | 343 rtc::CritScope cs(&crit_); |
| 344 | |
| 345 // Media packet storage. | |
| 346 storage = packetizer->GetStorageType(retransmission_settings_); | |
| 347 | |
| 348 // FEC settings. | |
| 293 const FecProtectionParams& fec_params = | 349 const FecProtectionParams& fec_params = |
| 294 frame_type == kVideoFrameKey ? key_fec_params_ : delta_fec_params_; | 350 frame_type == kVideoFrameKey ? key_fec_params_ : delta_fec_params_; |
| 295 ulpfec_generator_.SetFecParameters(fec_params); | 351 if (flexfec_enabled()) |
| 296 storage = packetizer->GetStorageType(retransmission_settings_); | 352 flexfec_sender_->SetFecParameters(fec_params); |
| 297 red_enabled = this->red_enabled(); | 353 red_enabled = this->red_enabled(); |
| 354 if (ulpfec_enabled()) | |
| 355 ulpfec_generator_.SetFecParameters(fec_params); | |
| 298 } | 356 } |
| 299 | 357 |
| 300 // TODO(changbin): we currently don't support to configure the codec to | 358 // TODO(changbin): we currently don't support to configure the codec to |
| 301 // output multiple partitions for VP8. Should remove below check after the | 359 // output multiple partitions for VP8. Should remove below check after the |
| 302 // issue is fixed. | 360 // issue is fixed. |
| 303 const RTPFragmentationHeader* frag = | 361 const RTPFragmentationHeader* frag = |
| 304 (video_type == kRtpVideoVp8) ? NULL : fragmentation; | 362 (video_type == kRtpVideoVp8) ? NULL : fragmentation; |
| 305 | 363 |
| 306 packetizer->SetPayloadData(payload_data, payload_size, frag); | 364 packetizer->SetPayloadData(payload_data, payload_size, frag); |
| 307 | 365 |
| 308 bool first = true; | 366 bool first = true; |
| 309 bool last = false; | 367 bool last = false; |
| 310 while (!last) { | 368 while (!last) { |
| 311 std::unique_ptr<RtpPacketToSend> packet(new RtpPacketToSend(*rtp_header)); | 369 std::unique_ptr<RtpPacketToSend> packet(new RtpPacketToSend(*rtp_header)); |
| 312 uint8_t* payload = packet->AllocatePayload(max_data_payload_length); | 370 uint8_t* payload = packet->AllocatePayload(max_data_payload_length); |
| 313 RTC_DCHECK(payload); | 371 RTC_DCHECK(payload); |
| 314 | 372 |
| 315 size_t payload_bytes_in_packet = 0; | 373 size_t payload_bytes_in_packet = 0; |
| 316 if (!packetizer->NextPacket(payload, &payload_bytes_in_packet, &last)) | 374 if (!packetizer->NextPacket(payload, &payload_bytes_in_packet, &last)) |
| 317 return false; | 375 return false; |
| 318 | 376 |
| 319 packet->SetPayloadSize(payload_bytes_in_packet); | 377 packet->SetPayloadSize(payload_bytes_in_packet); |
| 320 packet->SetMarker(last); | 378 packet->SetMarker(last); |
| 321 if (!rtp_sender_->AssignSequenceNumber(packet.get())) | 379 if (!rtp_sender_->AssignSequenceNumber(packet.get())) |
| 322 return false; | 380 return false; |
| 323 | 381 |
| 324 if (red_enabled) { | 382 const bool protect_packet = |
| 325 SendVideoPacketAsRed(std::move(packet), storage, | 383 (packetizer->GetProtectionType() == kProtectedPacket); |
| 326 packetizer->GetProtectionType() == kProtectedPacket); | 384 if (flexfec_enabled()) { |
| 385 // TODO(brandtr): Remove the FlexFEC code path when FlexfecSender | |
| 386 // is wired up to PacedSender instead. | |
| 387 SendVideoPacketWithFlexfec(std::move(packet), storage, protect_packet); | |
| 388 } else if (red_enabled) { | |
| 389 SendVideoPacketAsRedMaybeWithUlpfec(std::move(packet), storage, | |
| 390 protect_packet); | |
| 327 } else { | 391 } else { |
| 328 SendVideoPacket(std::move(packet), storage); | 392 SendVideoPacket(std::move(packet), storage); |
| 329 } | 393 } |
| 330 | 394 |
| 331 if (first_frame) { | 395 if (first_frame) { |
| 332 if (first) { | 396 if (first) { |
| 333 LOG(LS_INFO) | 397 LOG(LS_INFO) |
| 334 << "Sent first RTP packet of the first video frame (pre-pacer)"; | 398 << "Sent first RTP packet of the first video frame (pre-pacer)"; |
| 335 } | 399 } |
| 336 if (last) { | 400 if (last) { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 360 rtc::CritScope cs(&crit_); | 424 rtc::CritScope cs(&crit_); |
| 361 return retransmission_settings_; | 425 return retransmission_settings_; |
| 362 } | 426 } |
| 363 | 427 |
| 364 void RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) { | 428 void RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) { |
| 365 rtc::CritScope cs(&crit_); | 429 rtc::CritScope cs(&crit_); |
| 366 retransmission_settings_ = settings; | 430 retransmission_settings_ = settings; |
| 367 } | 431 } |
| 368 | 432 |
| 369 } // namespace webrtc | 433 } // namespace webrtc |
| OLD | NEW |