| Index: webrtc/video/rtp_video_stream_receiver.cc
|
| diff --git a/webrtc/video/rtp_video_stream_receiver.cc b/webrtc/video/rtp_video_stream_receiver.cc
|
| index 1dbd86988d30df5d655be795b23e6bcefba4f54f..a47055abf08465a2ed0e03886c2770e636a62af0 100644
|
| --- a/webrtc/video/rtp_video_stream_receiver.cc
|
| +++ b/webrtc/video/rtp_video_stream_receiver.cc
|
| @@ -86,7 +86,6 @@
|
| RtcpRttStats* rtt_stats,
|
| PacketRouter* packet_router,
|
| const VideoReceiveStream::Config* config,
|
| - ReceiveStatistics* rtp_receive_statistics,
|
| ReceiveStatisticsProxy* receive_stats_proxy,
|
| ProcessThread* process_thread,
|
| NackSender* nack_sender,
|
| @@ -103,11 +102,12 @@
|
| this,
|
| this,
|
| &rtp_payload_registry_)),
|
| - rtp_receive_statistics_(rtp_receive_statistics),
|
| + rtp_receive_statistics_(ReceiveStatistics::Create(clock_)),
|
| ulpfec_receiver_(UlpfecReceiver::Create(config->rtp.remote_ssrc, this)),
|
| receiving_(false),
|
| + restored_packet_in_use_(false),
|
| last_packet_log_ms_(-1),
|
| - rtp_rtcp_(CreateRtpRtcpModule(rtp_receive_statistics_,
|
| + rtp_rtcp_(CreateRtpRtcpModule(rtp_receive_statistics_.get(),
|
| transport,
|
| rtt_stats,
|
| receive_stats_proxy,
|
| @@ -146,8 +146,12 @@
|
| rtp_receive_statistics_->SetMaxReorderingThreshold(max_reordering_threshold);
|
|
|
| if (config_.rtp.rtx_ssrc) {
|
| - // Needed for rtp_payload_registry_.RtxEnabled().
|
| rtp_payload_registry_.SetRtxSsrc(config_.rtp.rtx_ssrc);
|
| +
|
| + for (const auto& kv : config_.rtp.rtx_associated_payload_types) {
|
| + RTC_DCHECK_NE(kv.first, 0);
|
| + rtp_payload_registry_.SetRtxPayloadType(kv.first, kv.second);
|
| + }
|
| }
|
|
|
| if (IsUlpfecEnabled()) {
|
| @@ -164,6 +168,11 @@
|
| strncpy(red_codec.plName, "red", sizeof(red_codec.plName));
|
| red_codec.plType = config_.rtp.ulpfec.red_payload_type;
|
| RTC_CHECK(AddReceiveCodec(red_codec));
|
| + if (config_.rtp.ulpfec.red_rtx_payload_type != -1) {
|
| + rtp_payload_registry_.SetRtxPayloadType(
|
| + config_.rtp.ulpfec.red_rtx_payload_type,
|
| + config_.rtp.ulpfec.red_payload_type);
|
| + }
|
| }
|
|
|
| if (config_.rtp.rtcp_xr.receiver_reference_time_report)
|
| @@ -486,7 +495,31 @@
|
| }
|
| ulpfec_receiver_->ProcessReceivedFec();
|
| } else if (rtp_payload_registry_.IsRtx(header)) {
|
| - LOG(LS_WARNING) << "Unexpected RTX packet on media ssrc";
|
| + if (header.headerLength + header.paddingLength == packet_length) {
|
| + // This is an empty packet and should be silently dropped before trying to
|
| + // parse the RTX header.
|
| + return;
|
| + }
|
| + // Remove the RTX header and parse the original RTP header.
|
| + if (packet_length < header.headerLength)
|
| + return;
|
| + if (packet_length > sizeof(restored_packet_))
|
| + return;
|
| + if (restored_packet_in_use_) {
|
| + LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet.";
|
| + return;
|
| + }
|
| + if (!rtp_payload_registry_.RestoreOriginalPacket(
|
| + restored_packet_, packet, &packet_length, config_.rtp.remote_ssrc,
|
| + header)) {
|
| + LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header ssrc: "
|
| + << header.ssrc << " payload type: "
|
| + << static_cast<int>(header.payloadType);
|
| + return;
|
| + }
|
| + restored_packet_in_use_ = true;
|
| + OnRecoveredPacket(restored_packet_, packet_length);
|
| + restored_packet_in_use_ = false;
|
| }
|
| }
|
|
|
|
|