Index: webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc |
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc |
index 916561ea876bbc40af46433dca401e7a5519f6b7..dea269b43589f33140bf02445df98c32e13a64d6 100644 |
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc |
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc |
@@ -52,6 +52,7 @@ RTPSenderVideo::RTPSenderVideo(Clock* clock, RTPSender* rtp_sender) |
last_rotation_(kVideoRotation_0), |
red_payload_type_(-1), |
ulpfec_payload_type_(-1), |
+ flexfec_sender_(nullptr), // TODO(brandtr): Wire up in future CL. |
delta_fec_params_{0, 1, kFecMaskRandom}, |
key_fec_params_{0, 1, kFecMaskRandom}, |
fec_bitrate_(1000, RateStatistics::kBpsScale), |
@@ -114,7 +115,7 @@ void RTPSenderVideo::SendVideoPacket(std::unique_ptr<RtpPacketToSend> packet, |
void RTPSenderVideo::SendVideoPacketAsRed( |
std::unique_ptr<RtpPacketToSend> media_packet, |
StorageType media_packet_storage, |
- bool protect) { |
+ bool protect_packet) { |
uint32_t rtp_timestamp = media_packet->Timestamp(); |
uint16_t media_seq_num = media_packet->SequenceNumber(); |
@@ -128,7 +129,7 @@ void RTPSenderVideo::SendVideoPacketAsRed( |
// Only protect while creating RED and FEC packets, not when sending. |
rtc::CritScope cs(&crit_); |
red_packet->SetPayloadType(red_payload_type_); |
- if (protect) { |
+ if (ulpfec_enabled() && protect_packet) { |
ulpfec_generator_.AddRtpPacketAndGenerateFec( |
media_packet->data(), media_packet->payload_size(), |
media_packet->headers_size()); |
@@ -170,7 +171,7 @@ void RTPSenderVideo::SendVideoPacketAsRed( |
rtc::CritScope cs(&stats_crit_); |
fec_bitrate_.Update(fec_packet->length(), clock_->TimeInMilliseconds()); |
TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
- "Video::PacketFec", "timestamp", rtp_timestamp, |
+ "Video::PacketUlpfec", "timestamp", rtp_timestamp, |
"seqnum", fec_sequence_number); |
} else { |
LOG(LS_WARNING) << "Failed to send FEC packet " << fec_sequence_number; |
@@ -178,6 +179,43 @@ void RTPSenderVideo::SendVideoPacketAsRed( |
} |
} |
+std::vector<std::unique_ptr<RtpPacketToSend>> RTPSenderVideo::GetFlexfecPackets( |
danilchap
2016/11/08 11:45:08
try to order functions same as in header file, i.e
brandtr
2016/11/09 10:40:00
I changed the .h file instead :)
Now at least Sen
|
+ const RtpPacketToSend& media_packet) { |
+ RTC_DCHECK(flexfec_sender_); |
+ |
+ std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets; |
+ if (!flexfec_sender_->AddRtpPacketAndGenerateFec(media_packet)) { |
+ return fec_packets; |
+ } |
+ if (flexfec_sender_->FecAvailable()) { |
+ fec_packets = flexfec_sender_->GetFecPackets(); |
+ } |
+ |
+ return fec_packets; |
+} |
+ |
+void RTPSenderVideo::SendFlexfecPackets( |
+ std::vector<std::unique_ptr<RtpPacketToSend>>* fec_packets) { |
+ for (auto& fec_packet : *fec_packets) { |
+ uint32_t timestamp = fec_packet->Timestamp(); |
+ uint16_t seq_num = fec_packet->SequenceNumber(); |
+ // We do not support retransmitting lost FlexFEC packets. |
+ constexpr StorageType kFecStorage = kDontRetransmit; |
danilchap
2016/11/08 11:45:08
the enums values probably self-explained already,
brandtr
2016/11/09 10:40:00
Removed.
|
+ constexpr RtpPacketSender::Priority kFecPriority = |
+ RtpPacketSender::kLowPriority; |
+ if (rtp_sender_->SendToNetwork(std::move(fec_packet), kFecStorage, |
+ kFecPriority)) { |
+ // TODO(brandtr): Wire up stats here. |
danilchap
2016/11/08 11:45:08
may be resolve this TODO right away? or is it more
brandtr
2016/11/09 10:40:00
Yes, it's more complicated, since I want to do a c
|
+ TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
+ "Video::PacketFlexfec", "timestamp", timestamp, |
+ "seqnum", seq_num); |
+ } else { |
+ LOG(LS_WARNING) << "Failed to send FlexFEC packet " << seq_num; |
+ } |
+ } |
+ fec_packets->clear(); |
+} |
+ |
void RTPSenderVideo::SetUlpfecConfig(int red_payload_type, |
int ulpfec_payload_type) { |
// Sanity check. Per the definition of UlpfecConfig (see config.h), |
@@ -198,7 +236,7 @@ void RTPSenderVideo::SetUlpfecConfig(int red_payload_type, |
// ensure that RED and ULPFEC are only enabled together. |
RTC_DCHECK(red_enabled() || !ulpfec_enabled()); |
- // Reset FEC rates. |
+ // Reset FEC parameters. |
delta_fec_params_ = FecProtectionParams{0, 1, kFecMaskRandom}; |
key_fec_params_ = FecProtectionParams{0, 1, kFecMaskRandom}; |
} |
@@ -211,29 +249,34 @@ void RTPSenderVideo::GetUlpfecConfig(int* red_payload_type, |
} |
size_t RTPSenderVideo::FecPacketOverhead() const { |
+ // Overhead is FEC headers plus RED for FEC header plus anything in RTP |
+ // header beyond the 12 bytes base header (CSRC list, extensions...) |
+ // This reason for the header extensions to be included here is that |
+ // from an FEC viewpoint, they are part of the payload to be protected. |
+ // (The base RTP header is already protected by the FEC header.) |
+ |
+ if (flexfec_enabled()) { |
+ return flexfec_sender_->MaxPacketOverhead() + |
+ (rtp_sender_->RtpHeaderLength() - kRtpHeaderSize); |
+ } |
+ |
rtc::CritScope cs(&crit_); |
size_t overhead = 0; |
if (red_enabled()) { |
- // Overhead is FEC headers plus RED for FEC header plus anything in RTP |
- // header beyond the 12 bytes base header (CSRC list, extensions...) |
- // This reason for the header extensions to be included here is that |
- // from an FEC viewpoint, they are part of the payload to be protected. |
- // (The base RTP header is already protected by the FEC header.) |
- return ulpfec_generator_.MaxPacketOverhead() + kRedForFecHeaderLength + |
- (rtp_sender_->RtpHeaderLength() - kRtpHeaderSize); |
+ overhead += kRedForFecHeaderLength; |
+ } |
+ if (ulpfec_enabled()) { |
+ overhead += ulpfec_generator_.MaxPacketOverhead() + |
+ (rtp_sender_->RtpHeaderLength() - kRtpHeaderSize); |
} |
- if (ulpfec_enabled()) |
- overhead += ulpfec_generator_.MaxPacketOverhead(); |
return overhead; |
} |
void RTPSenderVideo::SetFecParameters(const FecProtectionParams& delta_params, |
const FecProtectionParams& key_params) { |
rtc::CritScope cs(&crit_); |
- if (ulpfec_enabled()) { |
- delta_fec_params_ = delta_params; |
- key_fec_params_ = key_params; |
- } |
+ delta_fec_params_ = delta_params; |
+ key_fec_params_ = key_params; |
} |
bool RTPSenderVideo::SendVideo(RtpVideoCodecTypes video_type, |
@@ -290,11 +333,20 @@ bool RTPSenderVideo::SendVideo(RtpVideoCodecTypes video_type, |
bool first_frame = first_frame_sent_(); |
{ |
rtc::CritScope cs(&crit_); |
+ |
+ // Media packet storage. |
+ storage = packetizer->GetStorageType(retransmission_settings_); |
+ |
+ // FEC settings. |
const FecProtectionParams& fec_params = |
frame_type == kVideoFrameKey ? key_fec_params_ : delta_fec_params_; |
- ulpfec_generator_.SetFecParameters(fec_params); |
- storage = packetizer->GetStorageType(retransmission_settings_); |
red_enabled = this->red_enabled(); |
+ if (flexfec_enabled()) { |
danilchap
2016/11/08 11:45:08
in this file it is more common to omit {} for one-
brandtr
2016/11/09 10:40:00
Yep, removed.
|
+ flexfec_sender_->SetFecParameters(fec_params); |
+ } |
+ if (ulpfec_enabled()) { |
+ ulpfec_generator_.SetFecParameters(fec_params); |
+ } |
} |
// TODO(changbin): we currently don't support to configure the codec to |
@@ -321,9 +373,25 @@ bool RTPSenderVideo::SendVideo(RtpVideoCodecTypes video_type, |
if (!rtp_sender_->AssignSequenceNumber(packet.get())) |
return false; |
- if (red_enabled) { |
- SendVideoPacketAsRed(std::move(packet), storage, |
- packetizer->GetProtectionType() == kProtectedPacket); |
+ const bool protect_packet = |
+ (packetizer->GetProtectionType() == kProtectedPacket); |
+ // Note that we either send non-encapsulated media packets with FlexFEC |
danilchap
2016/11/08 11:45:08
this comments feels like repeating (not explaining
brandtr
2016/11/09 10:40:00
Agree that the comment is a bit superfluous. I hav
|
+ // packets, or RED-encapsulated media packets with our without ULPFEC, |
+ // packets, or non-encapsulated media packets without any FEC packets. |
+ // If both FlexFEC and RED+ULPFEC are enabled, FlexFEC takes priority. |
+ // TODO(brandtr): Remove this FlexFEC code path, when FlexfecSender |
+ // is wired up to PacedSender instead. |
+ if (flexfec_enabled()) { |
+ std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets; |
+ if (protect_packet) |
+ fec_packets = GetFlexfecPackets(*packet); |
+ // Send media packet as usual. |
+ SendVideoPacket(std::move(packet), storage); |
+ // Send available FlexFEC packets after main media packet is sent. |
+ if (!fec_packets.empty()) |
+ SendFlexfecPackets(&fec_packets); |
danilchap
2016/11/08 11:45:08
may be cleaner to change SendFlexfecPackets to tak
brandtr
2016/11/09 10:40:00
Yes, that would have been nicer. Now that function
|
+ } else if (red_enabled) { |
+ SendVideoPacketAsRed(std::move(packet), storage, protect_packet); |
} else { |
SendVideoPacket(std::move(packet), storage); |
} |