2011-07-07 08:21:25 +00:00
|
|
|
/*
|
2012-03-01 18:22:48 +00:00
|
|
|
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
2011-07-07 08:21:25 +00:00
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by a BSD-style license
|
|
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
|
|
|
|
* in the file PATENTS. All contributing project authors may
|
|
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
*/
|
|
|
|
|
|
2016-04-28 23:15:33 -07:00
|
|
|
#include "webrtc/video/rtp_stream_receiver.h"
|
2011-07-07 08:21:25 +00:00
|
|
|
|
2013-02-06 17:46:39 +00:00
|
|
|
#include <vector>
|
2016-11-15 00:57:57 -08:00
|
|
|
#include <utility>
|
2013-02-06 17:46:39 +00:00
|
|
|
|
2016-08-05 06:28:45 -07:00
|
|
|
#include "webrtc/base/checks.h"
|
2015-10-26 11:35:17 +01:00
|
|
|
#include "webrtc/base/logging.h"
|
2016-05-03 21:22:04 -07:00
|
|
|
#include "webrtc/common_types.h"
|
2016-02-26 16:26:20 +01:00
|
|
|
#include "webrtc/config.h"
|
2016-12-20 04:15:59 -08:00
|
|
|
#include "webrtc/media/base/mediaconstants.h"
|
2016-04-25 01:26:26 -07:00
|
|
|
#include "webrtc/modules/pacing/packet_router.h"
|
2013-05-17 13:44:48 +00:00
|
|
|
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
2015-11-04 08:31:52 +01:00
|
|
|
#include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
|
|
|
|
|
#include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h"
|
|
|
|
|
#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
|
|
|
|
|
#include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
|
|
|
|
|
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
|
2016-10-31 04:51:33 -07:00
|
|
|
#include "webrtc/modules/rtp_rtcp/include/ulpfec_receiver.h"
|
2017-02-13 05:59:46 -08:00
|
|
|
#include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h"
|
|
|
|
|
#include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h"
|
2016-11-15 00:57:57 -08:00
|
|
|
#include "webrtc/modules/video_coding/frame_object.h"
|
2016-12-20 04:15:59 -08:00
|
|
|
#include "webrtc/modules/video_coding/h264_sprop_parameter_sets.h"
|
2016-11-15 00:57:57 -08:00
|
|
|
#include "webrtc/modules/video_coding/h264_sps_pps_tracker.h"
|
|
|
|
|
#include "webrtc/modules/video_coding/packet_buffer.h"
|
2016-04-22 18:23:15 +02:00
|
|
|
#include "webrtc/modules/video_coding/video_coding_impl.h"
|
2016-11-15 00:57:57 -08:00
|
|
|
#include "webrtc/system_wrappers/include/field_trial.h"
|
2015-10-28 18:17:40 +01:00
|
|
|
#include "webrtc/system_wrappers/include/metrics.h"
|
|
|
|
|
#include "webrtc/system_wrappers/include/timestamp_extrapolator.h"
|
|
|
|
|
#include "webrtc/system_wrappers/include/trace.h"
|
2016-05-03 21:22:04 -07:00
|
|
|
#include "webrtc/video/receive_statistics_proxy.h"
|
2016-05-06 05:32:22 -07:00
|
|
|
#include "webrtc/video/vie_remb.h"
|
2011-07-07 08:21:25 +00:00
|
|
|
|
|
|
|
|
namespace webrtc {
|
|
|
|
|
|
2016-11-15 00:57:57 -08:00
|
|
|
namespace {
|
|
|
|
|
constexpr int kPacketBufferStartSize = 32;
|
|
|
|
|
constexpr int kPacketBufferMaxSixe = 2048;
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-25 01:26:26 -07:00
|
|
|
std::unique_ptr<RtpRtcp> CreateRtpRtcpModule(
|
|
|
|
|
ReceiveStatistics* receive_statistics,
|
|
|
|
|
Transport* outgoing_transport,
|
|
|
|
|
RtcpRttStats* rtt_stats,
|
|
|
|
|
RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer,
|
2017-01-24 02:36:58 -08:00
|
|
|
TransportSequenceNumberAllocator* transport_sequence_number_allocator) {
|
2016-04-25 01:26:26 -07:00
|
|
|
RtpRtcp::Configuration configuration;
|
|
|
|
|
configuration.audio = false;
|
|
|
|
|
configuration.receiver_only = true;
|
|
|
|
|
configuration.receive_statistics = receive_statistics;
|
|
|
|
|
configuration.outgoing_transport = outgoing_transport;
|
|
|
|
|
configuration.intra_frame_callback = nullptr;
|
|
|
|
|
configuration.rtt_stats = rtt_stats;
|
|
|
|
|
configuration.rtcp_packet_type_counter_observer =
|
|
|
|
|
rtcp_packet_type_counter_observer;
|
|
|
|
|
configuration.transport_sequence_number_allocator =
|
|
|
|
|
transport_sequence_number_allocator;
|
|
|
|
|
configuration.send_bitrate_observer = nullptr;
|
|
|
|
|
configuration.send_frame_count_observer = nullptr;
|
|
|
|
|
configuration.send_side_delay_observer = nullptr;
|
2016-05-02 23:44:01 -07:00
|
|
|
configuration.send_packet_observer = nullptr;
|
2016-04-25 01:26:26 -07:00
|
|
|
configuration.bandwidth_callback = nullptr;
|
|
|
|
|
configuration.transport_feedback_callback = nullptr;
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<RtpRtcp> rtp_rtcp(RtpRtcp::CreateRtpRtcp(configuration));
|
|
|
|
|
rtp_rtcp->SetSendingStatus(false);
|
|
|
|
|
rtp_rtcp->SetSendingMediaStatus(false);
|
|
|
|
|
rtp_rtcp->SetRTCPStatus(RtcpMode::kCompound);
|
|
|
|
|
|
|
|
|
|
return rtp_rtcp;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-14 11:40:13 +00:00
|
|
|
static const int kPacketLogIntervalMs = 10000;
|
|
|
|
|
|
2016-04-28 23:15:33 -07:00
|
|
|
RtpStreamReceiver::RtpStreamReceiver(
|
|
|
|
|
Transport* transport,
|
|
|
|
|
RtcpRttStats* rtt_stats,
|
2016-05-03 21:22:04 -07:00
|
|
|
PacketRouter* packet_router,
|
2016-05-06 05:32:22 -07:00
|
|
|
VieRemb* remb,
|
2016-06-10 17:58:01 +02:00
|
|
|
const VideoReceiveStream::Config* config,
|
2016-05-06 05:32:22 -07:00
|
|
|
ReceiveStatisticsProxy* receive_stats_proxy,
|
2016-07-29 12:59:36 +02:00
|
|
|
ProcessThread* process_thread,
|
2016-11-15 00:57:57 -08:00
|
|
|
NackSender* nack_sender,
|
|
|
|
|
KeyFrameRequestSender* keyframe_request_sender,
|
|
|
|
|
video_coding::OnCompleteFrameCallback* complete_frame_callback,
|
|
|
|
|
VCMTiming* timing)
|
2016-01-21 23:24:59 +01:00
|
|
|
: clock_(Clock::GetRealTimeClock()),
|
2016-06-10 17:58:01 +02:00
|
|
|
config_(*config),
|
2016-04-25 01:26:26 -07:00
|
|
|
packet_router_(packet_router),
|
2016-05-06 05:32:22 -07:00
|
|
|
remb_(remb),
|
|
|
|
|
process_thread_(process_thread),
|
2016-03-02 15:05:53 +01:00
|
|
|
ntp_estimator_(clock_),
|
2013-05-29 12:12:51 +00:00
|
|
|
rtp_header_parser_(RtpHeaderParser::Create()),
|
2016-03-02 15:05:53 +01:00
|
|
|
rtp_receiver_(RtpReceiver::CreateVideoReceiver(clock_,
|
|
|
|
|
this,
|
2016-04-28 23:15:33 -07:00
|
|
|
this,
|
2016-03-02 15:05:53 +01:00
|
|
|
&rtp_payload_registry_)),
|
2014-10-14 11:40:13 +00:00
|
|
|
rtp_receive_statistics_(ReceiveStatistics::Create(clock_)),
|
2016-10-31 04:51:33 -07:00
|
|
|
ulpfec_receiver_(UlpfecReceiver::Create(this)),
|
2013-09-06 13:40:11 +00:00
|
|
|
receiving_(false),
|
2014-03-24 20:28:11 +00:00
|
|
|
restored_packet_in_use_(false),
|
2016-04-25 01:26:26 -07:00
|
|
|
last_packet_log_ms_(-1),
|
|
|
|
|
rtp_rtcp_(CreateRtpRtcpModule(rtp_receive_statistics_.get(),
|
|
|
|
|
transport,
|
|
|
|
|
rtt_stats,
|
2016-05-03 21:22:04 -07:00
|
|
|
receive_stats_proxy,
|
2017-01-24 02:36:58 -08:00
|
|
|
packet_router)),
|
2016-11-15 00:57:57 -08:00
|
|
|
complete_frame_callback_(complete_frame_callback),
|
|
|
|
|
keyframe_request_sender_(keyframe_request_sender),
|
|
|
|
|
timing_(timing) {
|
2016-04-25 01:26:26 -07:00
|
|
|
packet_router_->AddRtpModule(rtp_rtcp_.get());
|
2016-05-03 21:22:04 -07:00
|
|
|
rtp_receive_statistics_->RegisterRtpStatisticsCallback(receive_stats_proxy);
|
|
|
|
|
rtp_receive_statistics_->RegisterRtcpStatisticsCallback(receive_stats_proxy);
|
|
|
|
|
|
2016-06-10 17:58:01 +02:00
|
|
|
RTC_DCHECK(config_.rtp.rtcp_mode != RtcpMode::kOff)
|
2016-05-03 21:22:04 -07:00
|
|
|
<< "A stream should not be configured with RTCP disabled. This value is "
|
|
|
|
|
"reserved for internal usage.";
|
2016-05-06 05:32:22 -07:00
|
|
|
RTC_DCHECK(config_.rtp.remote_ssrc != 0);
|
|
|
|
|
// TODO(pbos): What's an appropriate local_ssrc for receive-only streams?
|
|
|
|
|
RTC_DCHECK(config_.rtp.local_ssrc != 0);
|
|
|
|
|
RTC_DCHECK(config_.rtp.remote_ssrc != config_.rtp.local_ssrc);
|
|
|
|
|
|
2016-06-10 17:58:01 +02:00
|
|
|
rtp_rtcp_->SetRTCPStatus(config_.rtp.rtcp_mode);
|
|
|
|
|
rtp_rtcp_->SetSSRC(config_.rtp.local_ssrc);
|
2016-04-25 01:26:26 -07:00
|
|
|
rtp_rtcp_->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp);
|
2016-06-10 17:58:01 +02:00
|
|
|
if (config_.rtp.remb) {
|
2016-05-06 05:32:22 -07:00
|
|
|
rtp_rtcp_->SetREMBStatus(true);
|
|
|
|
|
remb_->AddReceiveChannel(rtp_rtcp_.get());
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-10 17:58:01 +02:00
|
|
|
for (size_t i = 0; i < config_.rtp.extensions.size(); ++i) {
|
|
|
|
|
EnableReceiveRtpHeaderExtension(config_.rtp.extensions[i].uri,
|
|
|
|
|
config_.rtp.extensions[i].id);
|
2016-05-06 05:32:22 -07:00
|
|
|
}
|
2016-05-03 21:22:04 -07:00
|
|
|
|
|
|
|
|
static const int kMaxPacketAgeToNack = 450;
|
2016-06-10 17:58:01 +02:00
|
|
|
const int max_reordering_threshold = (config_.rtp.nack.rtp_history_ms > 0)
|
|
|
|
|
? kMaxPacketAgeToNack
|
|
|
|
|
: kDefaultMaxReorderingThreshold;
|
2016-05-03 21:22:04 -07:00
|
|
|
rtp_receive_statistics_->SetMaxReorderingThreshold(max_reordering_threshold);
|
2016-05-06 05:32:22 -07:00
|
|
|
|
Reland of Make RTX pt/apt reconfigurable by calling WebRtcVideoChannel2::SetRecvParameters. (patchset #1 id:1 of https://codereview.webrtc.org/2649323010/ )
Reason for revert:
Downstream project relied on changed struct.
Transition made possible by https://codereview.webrtc.org/2655243006/.
Original issue's description:
> Revert of Make RTX pt/apt reconfigurable by calling WebRtcVideoChannel2::SetRecvParameters. (patchset #7 id:160001 of https://codereview.webrtc.org/2646073004/ )
>
> Reason for revert:
> Breaks internal downstream project.
>
> Original issue's description:
> > Make RTX pt/apt reconfigurable by calling WebRtcVideoChannel2::SetRecvParameters.
> >
> > Prior to this CL, received RTX (associated) payload types were only configured
> > when WebRtcVideoChannel2::AddRecvStream was called. In the same method, the RTX
> > SSRC was set up.
> >
> > After this CL, the RTX (associated) payload types are set in
> > WebRtcVideoChannel2::SetRecvParameters, which is the appropriate place to set
> > them. The RTX SSRC is still set in WebRtcVideoChannel2::AddRecvStream, since
> > that is the code path that sets other SSRCs.
> >
> > As part of this fix, the VideoReceiveStream::Config::Rtp struct is changed.
> > We remove the possibility for each video payload type to have an associated
> > specific RTX SSRC. Although the config previously allowed for this, all payload
> > types always had the same RTX SSRC set, and the underlying RtpPayloadRegistry
> > did not support multiple SSRCs. This change to the config struct should thus not
> > have any functional impact. The change does however affect the RtcEventLog, since
> > that is used for storing the VideoReceiveStream::Configs. For simplicity,
> > this CL does not change the event log proto definitions, instead duplicating
> > the serialized RTX SSRCs such that they fit in the existing proto definition.
> >
> > BUG=webrtc:7011
> >
> > Review-Url: https://codereview.webrtc.org/2646073004
> > Cr-Commit-Position: refs/heads/master@{#16302}
> > Committed: https://chromium.googlesource.com/external/webrtc/+/fe2bef39cd2a5c891a49f7320514fb04324dc66c
>
> TBR=stefan@webrtc.org,magjed@webrtc.org,terelius@webrtc.org,brandtr@webrtc.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:7011
>
> Review-Url: https://codereview.webrtc.org/2649323010
> Cr-Commit-Position: refs/heads/master@{#16307}
> Committed: https://chromium.googlesource.com/external/webrtc/+/e4974953ce0d03a60fae7659b199a6a62a79fa30
TBR=stefan@webrtc.org,magjed@webrtc.org,terelius@webrtc.org,kjellander@webrtc.org,kjellander@google.com
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
# NOTREECHECKS=true
# NOTRY=true
BUG=webrtc:7011
Review-Url: https://codereview.webrtc.org/2654163006
Cr-Commit-Position: refs/heads/master@{#16322}
2017-01-27 04:53:07 -08:00
|
|
|
if (config_.rtp.rtx_ssrc) {
|
|
|
|
|
rtp_payload_registry_.SetRtxSsrc(config_.rtp.rtx_ssrc);
|
|
|
|
|
|
|
|
|
|
for (const auto& kv : config_.rtp.rtx_payload_types) {
|
|
|
|
|
RTC_DCHECK(kv.second != 0);
|
|
|
|
|
rtp_payload_registry_.SetRtxPayloadType(kv.second, kv.first);
|
|
|
|
|
}
|
2016-05-06 05:32:22 -07:00
|
|
|
}
|
|
|
|
|
|
2016-12-08 08:25:47 -08:00
|
|
|
if (IsUlpfecEnabled()) {
|
2016-05-06 05:32:22 -07:00
|
|
|
VideoCodec ulpfec_codec = {};
|
|
|
|
|
ulpfec_codec.codecType = kVideoCodecULPFEC;
|
|
|
|
|
strncpy(ulpfec_codec.plName, "ulpfec", sizeof(ulpfec_codec.plName));
|
2016-10-04 23:28:39 -07:00
|
|
|
ulpfec_codec.plType = config_.rtp.ulpfec.ulpfec_payload_type;
|
2016-12-13 02:23:03 -08:00
|
|
|
RTC_CHECK(AddReceiveCodec(ulpfec_codec));
|
Remove RED/RTX workaround from sender/receiver and VideoEngine2.
In older Chrome versions, the associated payload type in the RTX header
of retransmitted packets was always set to be the original media payload type,
regardless of the actual payload type of the packet. This meant that packets
encapsulated with RED headers had incorrect payload type information in the
RTX header. Due to an assumption in the receiver, this incorrect payload type
information would effectively be undone, leading to a working system.
Albeit working, this behaviour was undesired, and thus removed. In the interim,
several workarounds were introduced to not destroy interop between old and
new Chrome versions:
(1) https://codereview.webrtc.org/1649493004
- If no payload type mapping existed for RED over RTX, the payload type
of the underlying media would be used.
- If RED had been negotiated, received RTX packets would always be
assumed to contain RED.
(2) https://codereview.webrtc.org/1964473002
- If RED was removed from the remote description answer, it would be
disabled in the local receiver as well.
(3) https://codereview.webrtc.org/2033763002
- If RED was negotiated in the SDP, it would always be used, regardless
if ULPFEC was negotiated and used, or not.
Since the Chrome versions that exhibited the original bug now are very old,
this CL removes the workarounds from (1) and (2). In particular, after this
change, we will have the following behaviour:
- We assume that a payload type mapping for RED over RTX always is set.
If this is not the case, the RTX packet is not sent.
- The associated payload type of received RTX packets will always be obeyed.
- The (non)-existence of RED in the remote description does not affect the
local receiver.
The workaround in (3) still needs to exist, in order to interop with receivers
that did not have the workarounds in (1) and (2) removed. The change in (3)
can be removed in a couple of Chrome versions.
TESTED=Using AppRTC between patched Chrome (connected to ethernet) and standard Chrome M54 (connected to lossy internal Google WiFi), with and without FEC turned off using AppRTC flag. Also using "Munge SDP" sample on patched Chrome over loopback interface, with 100ms delay and 5% packet loss simulated using tc.
BUG=webrtc:6650
Review-Url: https://codereview.webrtc.org/2469093003
Cr-Commit-Position: refs/heads/master@{#15038}
2016-11-11 03:28:30 -08:00
|
|
|
}
|
2016-05-06 05:32:22 -07:00
|
|
|
|
Remove RED/RTX workaround from sender/receiver and VideoEngine2.
In older Chrome versions, the associated payload type in the RTX header
of retransmitted packets was always set to be the original media payload type,
regardless of the actual payload type of the packet. This meant that packets
encapsulated with RED headers had incorrect payload type information in the
RTX header. Due to an assumption in the receiver, this incorrect payload type
information would effectively be undone, leading to a working system.
Albeit working, this behaviour was undesired, and thus removed. In the interim,
several workarounds were introduced to not destroy interop between old and
new Chrome versions:
(1) https://codereview.webrtc.org/1649493004
- If no payload type mapping existed for RED over RTX, the payload type
of the underlying media would be used.
- If RED had been negotiated, received RTX packets would always be
assumed to contain RED.
(2) https://codereview.webrtc.org/1964473002
- If RED was removed from the remote description answer, it would be
disabled in the local receiver as well.
(3) https://codereview.webrtc.org/2033763002
- If RED was negotiated in the SDP, it would always be used, regardless
if ULPFEC was negotiated and used, or not.
Since the Chrome versions that exhibited the original bug now are very old,
this CL removes the workarounds from (1) and (2). In particular, after this
change, we will have the following behaviour:
- We assume that a payload type mapping for RED over RTX always is set.
If this is not the case, the RTX packet is not sent.
- The associated payload type of received RTX packets will always be obeyed.
- The (non)-existence of RED in the remote description does not affect the
local receiver.
The workaround in (3) still needs to exist, in order to interop with receivers
that did not have the workarounds in (1) and (2) removed. The change in (3)
can be removed in a couple of Chrome versions.
TESTED=Using AppRTC between patched Chrome (connected to ethernet) and standard Chrome M54 (connected to lossy internal Google WiFi), with and without FEC turned off using AppRTC flag. Also using "Munge SDP" sample on patched Chrome over loopback interface, with 100ms delay and 5% packet loss simulated using tc.
BUG=webrtc:6650
Review-Url: https://codereview.webrtc.org/2469093003
Cr-Commit-Position: refs/heads/master@{#15038}
2016-11-11 03:28:30 -08:00
|
|
|
if (IsRedEnabled()) {
|
2016-05-06 05:32:22 -07:00
|
|
|
VideoCodec red_codec = {};
|
|
|
|
|
red_codec.codecType = kVideoCodecRED;
|
|
|
|
|
strncpy(red_codec.plName, "red", sizeof(red_codec.plName));
|
2016-10-04 23:28:39 -07:00
|
|
|
red_codec.plType = config_.rtp.ulpfec.red_payload_type;
|
2016-12-13 02:23:03 -08:00
|
|
|
RTC_CHECK(AddReceiveCodec(red_codec));
|
2016-10-04 23:28:39 -07:00
|
|
|
if (config_.rtp.ulpfec.red_rtx_payload_type != -1) {
|
2016-05-06 05:32:22 -07:00
|
|
|
rtp_payload_registry_.SetRtxPayloadType(
|
2016-10-04 23:28:39 -07:00
|
|
|
config_.rtp.ulpfec.red_rtx_payload_type,
|
|
|
|
|
config_.rtp.ulpfec.red_payload_type);
|
2016-05-06 05:32:22 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-10 17:58:01 +02:00
|
|
|
if (config_.rtp.rtcp_xr.receiver_reference_time_report)
|
2016-05-06 05:32:22 -07:00
|
|
|
rtp_rtcp_->SetRtcpXrRrtrStatus(true);
|
|
|
|
|
|
|
|
|
|
// Stats callback for CNAME changes.
|
|
|
|
|
rtp_rtcp_->RegisterRtcpStatisticsCallback(receive_stats_proxy);
|
|
|
|
|
|
|
|
|
|
process_thread_->RegisterModule(rtp_rtcp_.get());
|
2016-11-15 00:57:57 -08:00
|
|
|
|
2017-02-27 01:59:36 -08:00
|
|
|
if (config_.rtp.nack.rtp_history_ms != 0) {
|
|
|
|
|
nack_module_.reset(
|
|
|
|
|
new NackModule(clock_, nack_sender, keyframe_request_sender));
|
|
|
|
|
process_thread_->RegisterModule(nack_module_.get());
|
|
|
|
|
}
|
2017-01-19 00:06:17 -08:00
|
|
|
|
2017-02-22 05:30:39 -08:00
|
|
|
packet_buffer_ = video_coding::PacketBuffer::Create(
|
|
|
|
|
clock_, kPacketBufferStartSize, kPacketBufferMaxSixe, this);
|
|
|
|
|
reference_finder_.reset(new video_coding::RtpFrameReferenceFinder(this));
|
2016-04-25 01:26:26 -07:00
|
|
|
}
|
2011-07-07 08:21:25 +00:00
|
|
|
|
2016-04-28 23:15:33 -07:00
|
|
|
RtpStreamReceiver::~RtpStreamReceiver() {
|
2017-02-27 01:59:36 -08:00
|
|
|
if (nack_module_) {
|
|
|
|
|
process_thread_->DeRegisterModule(nack_module_.get());
|
|
|
|
|
}
|
2016-05-06 05:32:22 -07:00
|
|
|
|
2017-02-27 01:59:36 -08:00
|
|
|
process_thread_->DeRegisterModule(rtp_rtcp_.get());
|
2016-11-15 00:57:57 -08:00
|
|
|
|
2016-04-25 01:26:26 -07:00
|
|
|
packet_router_->RemoveRtpModule(rtp_rtcp_.get());
|
2016-05-06 05:32:22 -07:00
|
|
|
rtp_rtcp_->SetREMBStatus(false);
|
2017-01-24 04:38:27 -08:00
|
|
|
if (config_.rtp.remb) {
|
|
|
|
|
remb_->RemoveReceiveChannel(rtp_rtcp_.get());
|
|
|
|
|
}
|
2015-01-15 07:40:20 +00:00
|
|
|
UpdateHistograms();
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2016-12-20 04:15:59 -08:00
|
|
|
bool RtpStreamReceiver::AddReceiveCodec(
|
|
|
|
|
const VideoCodec& video_codec,
|
|
|
|
|
const std::map<std::string, std::string>& codec_params) {
|
|
|
|
|
pt_codec_params_.insert(make_pair(video_codec.plType, codec_params));
|
|
|
|
|
return AddReceiveCodec(video_codec);
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-13 02:23:03 -08:00
|
|
|
bool RtpStreamReceiver::AddReceiveCodec(const VideoCodec& video_codec) {
|
2013-08-15 23:38:54 +00:00
|
|
|
int8_t old_pltype = -1;
|
2016-11-24 09:34:46 -08:00
|
|
|
if (rtp_payload_registry_.ReceivePayloadType(video_codec, &old_pltype) !=
|
|
|
|
|
-1) {
|
2016-03-02 15:05:53 +01:00
|
|
|
rtp_payload_registry_.DeRegisterReceivePayload(old_pltype);
|
2013-08-15 23:38:54 +00:00
|
|
|
}
|
2016-11-24 09:34:46 -08:00
|
|
|
return rtp_payload_registry_.RegisterReceivePayload(video_codec) == 0;
|
2013-08-15 23:38:54 +00:00
|
|
|
}
|
|
|
|
|
|
2016-04-28 23:15:33 -07:00
|
|
|
uint32_t RtpStreamReceiver::GetRemoteSsrc() const {
|
2013-08-15 23:38:54 +00:00
|
|
|
return rtp_receiver_->SSRC();
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-28 23:15:33 -07:00
|
|
|
int RtpStreamReceiver::GetCsrcs(uint32_t* csrcs) const {
|
2013-08-15 23:38:54 +00:00
|
|
|
return rtp_receiver_->CSRCs(csrcs);
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-28 23:15:33 -07:00
|
|
|
RtpReceiver* RtpStreamReceiver::GetRtpReceiver() const {
|
2013-08-15 23:38:54 +00:00
|
|
|
return rtp_receiver_.get();
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-28 23:15:33 -07:00
|
|
|
int32_t RtpStreamReceiver::OnReceivedPayloadData(
|
|
|
|
|
const uint8_t* payload_data,
|
2016-06-14 12:52:54 +02:00
|
|
|
size_t payload_size,
|
2016-04-28 23:15:33 -07:00
|
|
|
const WebRtcRTPHeader* rtp_header) {
|
2014-04-24 22:10:24 +00:00
|
|
|
WebRtcRTPHeader rtp_header_with_ntp = *rtp_header;
|
2014-05-14 16:53:51 +00:00
|
|
|
rtp_header_with_ntp.ntp_time_ms =
|
2016-03-02 15:05:53 +01:00
|
|
|
ntp_estimator_.Estimate(rtp_header->header.timestamp);
|
2017-02-22 05:30:39 -08:00
|
|
|
VCMPacket packet(payload_data, payload_size, rtp_header_with_ntp);
|
2017-02-27 01:59:36 -08:00
|
|
|
packet.timesNacked =
|
|
|
|
|
nack_module_ ? nack_module_->OnReceivedPacket(packet) : -1;
|
2017-02-22 05:30:39 -08:00
|
|
|
|
|
|
|
|
if (packet.codec == kVideoCodecH264) {
|
|
|
|
|
// Only when we start to receive packets will we know what payload type
|
|
|
|
|
// that will be used. When we know the payload type insert the correct
|
|
|
|
|
// sps/pps into the tracker.
|
|
|
|
|
if (packet.payloadType != last_payload_type_) {
|
|
|
|
|
last_payload_type_ = packet.payloadType;
|
|
|
|
|
InsertSpsPpsIntoTracker(packet.payloadType);
|
|
|
|
|
}
|
2017-02-08 05:25:42 -08:00
|
|
|
|
2017-02-22 05:30:39 -08:00
|
|
|
switch (tracker_.CopyAndFixBitstream(&packet)) {
|
|
|
|
|
case video_coding::H264SpsPpsTracker::kRequestKeyframe:
|
|
|
|
|
keyframe_request_sender_->RequestKeyFrame();
|
|
|
|
|
FALLTHROUGH();
|
|
|
|
|
case video_coding::H264SpsPpsTracker::kDrop:
|
|
|
|
|
return 0;
|
|
|
|
|
case video_coding::H264SpsPpsTracker::kInsert:
|
|
|
|
|
break;
|
Revert of Make the new jitter buffer the default jitter buffer. (patchset #2 id:290001 of https://codereview.chromium.org/2652043005/ )
Reason for revert:
Breaks downstream bots
Original issue's description:
> Reland of Make the new jitter buffer the default jitter buffer. (patchset #1 id:1 of https://codereview.webrtc.org/2638423003/ )
>
> Reason for revert:
> Bugfixes related to the new jitter buffer has landed.
>
> Original issue's description:
> > Revert of Make the new jitter buffer the default jitter buffer. (patchset #2 id:230001 of https://codereview.webrtc.org/2642753002/ )
> >
> > Reason for revert:
> > Breaks tests downstream.
> >
> > Original issue's description:
> > > Reland of Make the new jitter buffer the default jitter buffer. (patchset #1 id:1 of https://codereview.chromium.org/2632123005/ )
> > >
> > > Reason for revert:
> > > Fix in this CL: https://codereview.chromium.org/2640793003/
> > >
> > > Original issue's description:
> > > > Revert of Make the new jitter buffer the default jitter buffer. (patchset #7 id:120001 of https://codereview.chromium.org/2627463004/ )
> > > >
> > > > Reason for revert:
> > > > Breaks android bots.
> > > >
> > > > Original issue's description:
> > > > > Make the new jitter buffer the default jitter buffer.
> > > > >
> > > > > This CL contains only the changes necessary to make the switch to the new jitter
> > > > > buffer, clean up will be done in follow up CLs.
> > > > >
> > > > > In this CL:
> > > > > - Removed the WebRTC-NewVideoJitterBuffer experiment and made the
> > > > > new video jitter buffer the default one.
> > > > > - Moved WebRTC.Video.KeyFramesReceivedInPermille and
> > > > > WebRTC.Video.JitterBufferDelayInMs to the ReceiveStatisticsProxy.
> > > > >
> > > > > BUG=webrtc:5514
> > > > >
> > > > > Review-Url: https://codereview.webrtc.org/2627463004
> > > > > Cr-Commit-Position: refs/heads/master@{#16114}
> > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/0f0763d86d5d4e7f27e8dece02560e39c6da97d6
> > > >
> > > > TBR=stefan@webrtc.org,terelius@webrtc.org
> > > > # Skipping CQ checks because original CL landed less than 1 days ago.
> > > > NOPRESUBMIT=true
> > > > NOTREECHECKS=true
> > > > NOTRY=true
> > > > BUG=webrtc:5514
> > > >
> > > > Review-Url: https://codereview.webrtc.org/2632123005
> > > > Cr-Commit-Position: refs/heads/master@{#16117}
> > > > Committed: https://chromium.googlesource.com/external/webrtc/+/c08c191f7d206dc0de945185370d18f29d556931
> > >
> > > TBR=stefan@webrtc.org,terelius@webrtc.org
> > > # Not skipping CQ checks because original CL landed more than 1 days ago.
> > > BUG=webrtc:5514
> > >
> > > Review-Url: https://codereview.webrtc.org/2642753002
> > > Cr-Commit-Position: refs/heads/master@{#16149}
> > > Committed: https://chromium.googlesource.com/external/webrtc/+/f20dd0014d1cfc8a2e859a9e177e7fe2b21274ca
> >
> > TBR=stefan@webrtc.org,terelius@webrtc.org,philipel@webrtc.org
> > # Skipping CQ checks because original CL landed less than 1 days ago.
> > NOPRESUBMIT=true
> > NOTREECHECKS=true
> > NOTRY=true
> > BUG=webrtc:5514
> >
> > Review-Url: https://codereview.webrtc.org/2638423003
> > Cr-Commit-Position: refs/heads/master@{#16159}
> > Committed: https://chromium.googlesource.com/external/webrtc/+/04926b82641c426d764aa6e013e133db519129db
>
> TBR=stefan@webrtc.org,terelius@webrtc.org,kjellander@webrtc.org,kjellander@google.com
> # Not skipping CQ checks because original CL landed more than 1 days ago.
> BUG=webrtc:5514
>
> Review-Url: https://codereview.webrtc.org/2652043005
> Cr-Commit-Position: refs/heads/master@{#16293}
> Committed: https://chromium.googlesource.com/external/webrtc/+/09d6ef00fc21b9f2c2c27e50e5e2952329ac4b4b
TBR=stefan@webrtc.org,terelius@webrtc.org,kjellander@webrtc.org,kjellander@google.com
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:5514
Review-Url: https://codereview.webrtc.org/2656983002
Cr-Commit-Position: refs/heads/master@{#16316}
2017-01-27 02:19:05 -08:00
|
|
|
}
|
Reland of Make the new jitter buffer the default jitter buffer. (patchset #2 id:260001 of https://codereview.chromium.org/2656983002/ )
Reason for revert:
Incoming fix: https://codereview.chromium.org/2675693002/
Original issue's description:
> Revert of Make the new jitter buffer the default jitter buffer. (patchset #2 id:290001 of https://codereview.chromium.org/2652043005/ )
>
> Reason for revert:
> Breaks downstream bots
>
> Original issue's description:
> > Reland of Make the new jitter buffer the default jitter buffer. (patchset #1 id:1 of https://codereview.webrtc.org/2638423003/ )
> >
> > Reason for revert:
> > Bugfixes related to the new jitter buffer has landed.
> >
> > Original issue's description:
> > > Revert of Make the new jitter buffer the default jitter buffer. (patchset #2 id:230001 of https://codereview.webrtc.org/2642753002/ )
> > >
> > > Reason for revert:
> > > Breaks tests downstream.
> > >
> > > Original issue's description:
> > > > Reland of Make the new jitter buffer the default jitter buffer. (patchset #1 id:1 of https://codereview.chromium.org/2632123005/ )
> > > >
> > > > Reason for revert:
> > > > Fix in this CL: https://codereview.chromium.org/2640793003/
> > > >
> > > > Original issue's description:
> > > > > Revert of Make the new jitter buffer the default jitter buffer. (patchset #7 id:120001 of https://codereview.chromium.org/2627463004/ )
> > > > >
> > > > > Reason for revert:
> > > > > Breaks android bots.
> > > > >
> > > > > Original issue's description:
> > > > > > Make the new jitter buffer the default jitter buffer.
> > > > > >
> > > > > > This CL contains only the changes necessary to make the switch to the new jitter
> > > > > > buffer, clean up will be done in follow up CLs.
> > > > > >
> > > > > > In this CL:
> > > > > > - Removed the WebRTC-NewVideoJitterBuffer experiment and made the
> > > > > > new video jitter buffer the default one.
> > > > > > - Moved WebRTC.Video.KeyFramesReceivedInPermille and
> > > > > > WebRTC.Video.JitterBufferDelayInMs to the ReceiveStatisticsProxy.
> > > > > >
> > > > > > BUG=webrtc:5514
> > > > > >
> > > > > > Review-Url: https://codereview.webrtc.org/2627463004
> > > > > > Cr-Commit-Position: refs/heads/master@{#16114}
> > > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/0f0763d86d5d4e7f27e8dece02560e39c6da97d6
> > > > >
> > > > > TBR=stefan@webrtc.org,terelius@webrtc.org
> > > > > # Skipping CQ checks because original CL landed less than 1 days ago.
> > > > > NOPRESUBMIT=true
> > > > > NOTREECHECKS=true
> > > > > NOTRY=true
> > > > > BUG=webrtc:5514
> > > > >
> > > > > Review-Url: https://codereview.webrtc.org/2632123005
> > > > > Cr-Commit-Position: refs/heads/master@{#16117}
> > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/c08c191f7d206dc0de945185370d18f29d556931
> > > >
> > > > TBR=stefan@webrtc.org,terelius@webrtc.org
> > > > # Not skipping CQ checks because original CL landed more than 1 days ago.
> > > > BUG=webrtc:5514
> > > >
> > > > Review-Url: https://codereview.webrtc.org/2642753002
> > > > Cr-Commit-Position: refs/heads/master@{#16149}
> > > > Committed: https://chromium.googlesource.com/external/webrtc/+/f20dd0014d1cfc8a2e859a9e177e7fe2b21274ca
> > >
> > > TBR=stefan@webrtc.org,terelius@webrtc.org,philipel@webrtc.org
> > > # Skipping CQ checks because original CL landed less than 1 days ago.
> > > NOPRESUBMIT=true
> > > NOTREECHECKS=true
> > > NOTRY=true
> > > BUG=webrtc:5514
> > >
> > > Review-Url: https://codereview.webrtc.org/2638423003
> > > Cr-Commit-Position: refs/heads/master@{#16159}
> > > Committed: https://chromium.googlesource.com/external/webrtc/+/04926b82641c426d764aa6e013e133db519129db
> >
> > TBR=stefan@webrtc.org,terelius@webrtc.org,kjellander@webrtc.org,kjellander@google.com
> > # Not skipping CQ checks because original CL landed more than 1 days ago.
> > BUG=webrtc:5514
> >
> > Review-Url: https://codereview.webrtc.org/2652043005
> > Cr-Commit-Position: refs/heads/master@{#16293}
> > Committed: https://chromium.googlesource.com/external/webrtc/+/09d6ef00fc21b9f2c2c27e50e5e2952329ac4b4b
>
> TBR=stefan@webrtc.org,terelius@webrtc.org,kjellander@webrtc.org,kjellander@google.com
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:5514
>
> Review-Url: https://codereview.webrtc.org/2656983002
> Cr-Commit-Position: refs/heads/master@{#16316}
> Committed: https://chromium.googlesource.com/external/webrtc/+/27378f39ced81acb1c2a61808e5e42fcf65d4b8d
TBR=stefan@webrtc.org,terelius@webrtc.org,kjellander@webrtc.org,kjellander@google.com
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:5514
Review-Url: https://codereview.webrtc.org/2670183002
Cr-Commit-Position: refs/heads/master@{#16420}
2017-02-02 09:53:00 -08:00
|
|
|
|
|
|
|
|
} else {
|
2017-02-22 05:30:39 -08:00
|
|
|
uint8_t* data = new uint8_t[packet.sizeBytes];
|
|
|
|
|
memcpy(data, packet.dataPtr, packet.sizeBytes);
|
|
|
|
|
packet.dataPtr = data;
|
2011-11-28 22:39:24 +00:00
|
|
|
}
|
2017-02-22 05:30:39 -08:00
|
|
|
|
|
|
|
|
packet_buffer_->InsertPacket(&packet);
|
2011-11-28 22:39:24 +00:00
|
|
|
return 0;
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2016-04-28 23:15:33 -07:00
|
|
|
bool RtpStreamReceiver::OnRecoveredPacket(const uint8_t* rtp_packet,
|
|
|
|
|
size_t rtp_packet_length) {
|
2013-08-15 23:38:54 +00:00
|
|
|
RTPHeader header;
|
|
|
|
|
if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, &header)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
header.payload_type_frequency = kVideoPayloadTypeFrequency;
|
2014-09-04 06:48:14 +00:00
|
|
|
bool in_order = IsPacketInOrder(header);
|
|
|
|
|
return ReceivePacket(rtp_packet, rtp_packet_length, header, in_order);
|
2013-08-15 23:38:54 +00:00
|
|
|
}
|
|
|
|
|
|
2016-04-28 23:15:33 -07:00
|
|
|
// TODO(pbos): Remove as soon as audio can handle a changing payload type
|
|
|
|
|
// without this callback.
|
|
|
|
|
int32_t RtpStreamReceiver::OnInitializeDecoder(
|
|
|
|
|
const int8_t payload_type,
|
|
|
|
|
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
|
|
|
|
|
const int frequency,
|
|
|
|
|
const size_t channels,
|
|
|
|
|
const uint32_t rate) {
|
|
|
|
|
RTC_NOTREACHED();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RtpStreamReceiver::OnIncomingSSRCChanged(const uint32_t ssrc) {
|
|
|
|
|
rtp_rtcp_->SetRemoteSSRC(ssrc);
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-13 05:59:46 -08:00
|
|
|
void RtpStreamReceiver::OnRtpPacket(const RtpPacketReceived& packet) {
|
2011-11-28 22:39:24 +00:00
|
|
|
{
|
2016-01-21 23:24:59 +01:00
|
|
|
rtc::CritScope lock(&receive_cs_);
|
2013-07-26 09:02:46 +00:00
|
|
|
if (!receiving_) {
|
2017-02-13 05:59:46 -08:00
|
|
|
return;
|
2013-07-26 09:02:46 +00:00
|
|
|
}
|
2011-11-28 22:39:24 +00:00
|
|
|
}
|
2014-02-11 15:27:49 +00:00
|
|
|
|
2014-10-14 11:40:13 +00:00
|
|
|
int64_t now_ms = clock_->TimeInMilliseconds();
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
// Periodically log the RTP header of incoming packets.
|
2016-01-21 23:24:59 +01:00
|
|
|
rtc::CritScope lock(&receive_cs_);
|
2014-10-14 11:40:13 +00:00
|
|
|
if (now_ms - last_packet_log_ms_ > kPacketLogIntervalMs) {
|
|
|
|
|
std::stringstream ss;
|
2017-02-13 05:59:46 -08:00
|
|
|
ss << "Packet received on SSRC: " << packet.Ssrc()
|
|
|
|
|
<< " with payload type: " << static_cast<int>(packet.PayloadType())
|
|
|
|
|
<< ", timestamp: " << packet.Timestamp()
|
|
|
|
|
<< ", sequence number: " << packet.SequenceNumber()
|
|
|
|
|
<< ", arrival time: " << packet.arrival_time_ms();
|
|
|
|
|
int32_t time_offset;
|
|
|
|
|
if (packet.GetExtension<TransmissionOffset>(&time_offset)) {
|
|
|
|
|
ss << ", toffset: " << time_offset;
|
|
|
|
|
}
|
|
|
|
|
uint32_t send_time;
|
|
|
|
|
if (packet.GetExtension<AbsoluteSendTime>(&send_time)) {
|
|
|
|
|
ss << ", abs send time: " << send_time;
|
|
|
|
|
}
|
2014-10-14 11:40:13 +00:00
|
|
|
LOG(LS_INFO) << ss.str();
|
|
|
|
|
last_packet_log_ms_ = now_ms;
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-12-13 00:21:03 +00:00
|
|
|
|
2017-02-13 05:59:46 -08:00
|
|
|
// TODO(nisse): Delete use of GetHeader, but needs refactoring of
|
|
|
|
|
// ReceivePacket and IncomingPacket methods below.
|
|
|
|
|
RTPHeader header;
|
|
|
|
|
packet.GetHeader(&header);
|
|
|
|
|
|
2013-08-15 23:38:54 +00:00
|
|
|
header.payload_type_frequency = kVideoPayloadTypeFrequency;
|
2013-09-06 13:40:11 +00:00
|
|
|
|
2013-11-08 15:18:52 +00:00
|
|
|
bool in_order = IsPacketInOrder(header);
|
2016-03-02 15:05:53 +01:00
|
|
|
rtp_payload_registry_.SetIncomingPayloadType(header);
|
2017-02-13 05:59:46 -08:00
|
|
|
ReceivePacket(packet.data(), packet.size(), header, in_order);
|
2014-05-26 13:06:04 +00:00
|
|
|
// Update receive statistics after ReceivePacket.
|
|
|
|
|
// Receive statistics will be reset if the payload type changes (make sure
|
|
|
|
|
// that the first packet is included in the stats).
|
|
|
|
|
rtp_receive_statistics_->IncomingPacket(
|
2017-02-13 05:59:46 -08:00
|
|
|
header, packet.size(), IsPacketRetransmitted(header, in_order));
|
2013-09-06 13:40:11 +00:00
|
|
|
}
|
|
|
|
|
|
2016-05-03 21:22:04 -07:00
|
|
|
int32_t RtpStreamReceiver::RequestKeyFrame() {
|
|
|
|
|
return rtp_rtcp_->RequestKeyFrame();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t RtpStreamReceiver::SliceLossIndicationRequest(
|
|
|
|
|
const uint64_t picture_id) {
|
|
|
|
|
return rtp_rtcp_->SendRTCPSliceLossIndication(
|
|
|
|
|
static_cast<uint8_t>(picture_id));
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-08 08:25:47 -08:00
|
|
|
bool RtpStreamReceiver::IsUlpfecEnabled() const {
|
Remove RED/RTX workaround from sender/receiver and VideoEngine2.
In older Chrome versions, the associated payload type in the RTX header
of retransmitted packets was always set to be the original media payload type,
regardless of the actual payload type of the packet. This meant that packets
encapsulated with RED headers had incorrect payload type information in the
RTX header. Due to an assumption in the receiver, this incorrect payload type
information would effectively be undone, leading to a working system.
Albeit working, this behaviour was undesired, and thus removed. In the interim,
several workarounds were introduced to not destroy interop between old and
new Chrome versions:
(1) https://codereview.webrtc.org/1649493004
- If no payload type mapping existed for RED over RTX, the payload type
of the underlying media would be used.
- If RED had been negotiated, received RTX packets would always be
assumed to contain RED.
(2) https://codereview.webrtc.org/1964473002
- If RED was removed from the remote description answer, it would be
disabled in the local receiver as well.
(3) https://codereview.webrtc.org/2033763002
- If RED was negotiated in the SDP, it would always be used, regardless
if ULPFEC was negotiated and used, or not.
Since the Chrome versions that exhibited the original bug now are very old,
this CL removes the workarounds from (1) and (2). In particular, after this
change, we will have the following behaviour:
- We assume that a payload type mapping for RED over RTX always is set.
If this is not the case, the RTX packet is not sent.
- The associated payload type of received RTX packets will always be obeyed.
- The (non)-existence of RED in the remote description does not affect the
local receiver.
The workaround in (3) still needs to exist, in order to interop with receivers
that did not have the workarounds in (1) and (2) removed. The change in (3)
can be removed in a couple of Chrome versions.
TESTED=Using AppRTC between patched Chrome (connected to ethernet) and standard Chrome M54 (connected to lossy internal Google WiFi), with and without FEC turned off using AppRTC flag. Also using "Munge SDP" sample on patched Chrome over loopback interface, with 100ms delay and 5% packet loss simulated using tc.
BUG=webrtc:6650
Review-Url: https://codereview.webrtc.org/2469093003
Cr-Commit-Position: refs/heads/master@{#15038}
2016-11-11 03:28:30 -08:00
|
|
|
return config_.rtp.ulpfec.ulpfec_payload_type != -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool RtpStreamReceiver::IsRedEnabled() const {
|
|
|
|
|
return config_.rtp.ulpfec.red_payload_type != -1;
|
2016-05-06 05:32:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool RtpStreamReceiver::IsRetransmissionsEnabled() const {
|
|
|
|
|
return config_.rtp.nack.rtp_history_ms > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RtpStreamReceiver::RequestPacketRetransmit(
|
|
|
|
|
const std::vector<uint16_t>& sequence_numbers) {
|
|
|
|
|
rtp_rtcp_->SendNack(sequence_numbers);
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-03 21:22:04 -07:00
|
|
|
int32_t RtpStreamReceiver::ResendPackets(const uint16_t* sequence_numbers,
|
|
|
|
|
uint16_t length) {
|
|
|
|
|
return rtp_rtcp_->SendNACK(sequence_numbers, length);
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-15 00:57:57 -08:00
|
|
|
void RtpStreamReceiver::OnReceivedFrame(
|
|
|
|
|
std::unique_ptr<video_coding::RtpFrameObject> frame) {
|
2017-01-29 04:04:47 -08:00
|
|
|
if (!frame->delayed_by_retransmission())
|
|
|
|
|
timing_->IncomingTimestamp(frame->timestamp, clock_->TimeInMilliseconds());
|
2016-11-15 00:57:57 -08:00
|
|
|
reference_finder_->ManageFrame(std::move(frame));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RtpStreamReceiver::OnCompleteFrame(
|
|
|
|
|
std::unique_ptr<video_coding::FrameObject> frame) {
|
|
|
|
|
{
|
|
|
|
|
rtc::CritScope lock(&last_seq_num_cs_);
|
|
|
|
|
video_coding::RtpFrameObject* rtp_frame =
|
|
|
|
|
static_cast<video_coding::RtpFrameObject*>(frame.get());
|
|
|
|
|
last_seq_num_for_pic_id_[rtp_frame->picture_id] = rtp_frame->last_seq_num();
|
|
|
|
|
}
|
|
|
|
|
complete_frame_callback_->OnCompleteFrame(std::move(frame));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RtpStreamReceiver::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
|
2017-02-27 01:59:36 -08:00
|
|
|
if (nack_module_)
|
|
|
|
|
nack_module_->UpdateRtt(max_rtt_ms);
|
2016-11-15 00:57:57 -08:00
|
|
|
}
|
|
|
|
|
|
2017-02-13 05:59:46 -08:00
|
|
|
// TODO(nisse): Drop return value.
|
2016-04-28 23:15:33 -07:00
|
|
|
bool RtpStreamReceiver::ReceivePacket(const uint8_t* packet,
|
|
|
|
|
size_t packet_length,
|
|
|
|
|
const RTPHeader& header,
|
|
|
|
|
bool in_order) {
|
2016-03-02 15:05:53 +01:00
|
|
|
if (rtp_payload_registry_.IsEncapsulated(header)) {
|
2013-09-06 13:40:11 +00:00
|
|
|
return ParseAndHandleEncapsulatingHeader(packet, packet_length, header);
|
|
|
|
|
}
|
|
|
|
|
const uint8_t* payload = packet + header.headerLength;
|
Use size_t more consistently for packet/payload lengths.
See design doc at https://docs.google.com/a/chromium.org/document/d/1I6nmE9D_BmCY-IoV6MDPY2V6WYpEI-dg2apWXTfZyUI/edit?usp=sharing for more information.
This CL was reviewed and approved in pieces in the following CLs:
https://webrtc-codereview.appspot.com/24209004/
https://webrtc-codereview.appspot.com/24229004/
https://webrtc-codereview.appspot.com/24259004/
https://webrtc-codereview.appspot.com/25109004/
https://webrtc-codereview.appspot.com/26099004/
https://webrtc-codereview.appspot.com/27069004/
https://webrtc-codereview.appspot.com/27969004/
https://webrtc-codereview.appspot.com/27989004/
https://webrtc-codereview.appspot.com/29009004/
https://webrtc-codereview.appspot.com/30929004/
https://webrtc-codereview.appspot.com/30939004/
https://webrtc-codereview.appspot.com/31999004/
Committing as TBR to the original reviewers.
BUG=chromium:81439
TEST=none
TBR=pthatcher,henrik.lundin,tina.legrand,stefan,tkchin,glaznev,kjellander,perkj,mflodman,henrika,asapersson,niklas.enbom
Review URL: https://webrtc-codereview.appspot.com/23129004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@7726 4adac7df-926f-26a2-2b94-8c16560cd09d
2014-11-20 22:28:14 +00:00
|
|
|
assert(packet_length >= header.headerLength);
|
|
|
|
|
size_t payload_length = packet_length - header.headerLength;
|
2013-08-15 23:38:54 +00:00
|
|
|
PayloadUnion payload_specific;
|
2016-03-02 15:05:53 +01:00
|
|
|
if (!rtp_payload_registry_.GetPayloadSpecifics(header.payloadType,
|
|
|
|
|
&payload_specific)) {
|
2013-09-06 13:40:11 +00:00
|
|
|
return false;
|
2013-08-15 23:38:54 +00:00
|
|
|
}
|
2013-09-06 13:40:11 +00:00
|
|
|
return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length,
|
|
|
|
|
payload_specific, in_order);
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-28 23:15:33 -07:00
|
|
|
bool RtpStreamReceiver::ParseAndHandleEncapsulatingHeader(
|
|
|
|
|
const uint8_t* packet, size_t packet_length, const RTPHeader& header) {
|
2016-03-02 15:05:53 +01:00
|
|
|
if (rtp_payload_registry_.IsRed(header)) {
|
|
|
|
|
int8_t ulpfec_pt = rtp_payload_registry_.ulpfec_payload_type();
|
2015-01-28 13:58:27 +00:00
|
|
|
if (packet[header.headerLength] == ulpfec_pt) {
|
2015-01-27 12:17:29 +00:00
|
|
|
rtp_receive_statistics_->FecPacketReceived(header, packet_length);
|
2016-04-22 18:23:15 +02:00
|
|
|
// Notify video_receiver about received FEC packets to avoid NACKing these
|
|
|
|
|
// packets.
|
2015-01-28 13:58:27 +00:00
|
|
|
NotifyReceiverOfFecPacket(header);
|
|
|
|
|
}
|
2016-10-31 04:51:33 -07:00
|
|
|
if (ulpfec_receiver_->AddReceivedRedPacket(header, packet, packet_length,
|
|
|
|
|
ulpfec_pt) != 0) {
|
2013-09-06 13:40:11 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2016-10-31 04:51:33 -07:00
|
|
|
return ulpfec_receiver_->ProcessReceivedFec() == 0;
|
2016-03-02 15:05:53 +01:00
|
|
|
} else if (rtp_payload_registry_.IsRtx(header)) {
|
2014-03-19 18:14:52 +00:00
|
|
|
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 true;
|
|
|
|
|
}
|
2013-09-06 13:40:11 +00:00
|
|
|
// Remove the RTX header and parse the original RTP header.
|
|
|
|
|
if (packet_length < header.headerLength)
|
|
|
|
|
return false;
|
Use size_t more consistently for packet/payload lengths.
See design doc at https://docs.google.com/a/chromium.org/document/d/1I6nmE9D_BmCY-IoV6MDPY2V6WYpEI-dg2apWXTfZyUI/edit?usp=sharing for more information.
This CL was reviewed and approved in pieces in the following CLs:
https://webrtc-codereview.appspot.com/24209004/
https://webrtc-codereview.appspot.com/24229004/
https://webrtc-codereview.appspot.com/24259004/
https://webrtc-codereview.appspot.com/25109004/
https://webrtc-codereview.appspot.com/26099004/
https://webrtc-codereview.appspot.com/27069004/
https://webrtc-codereview.appspot.com/27969004/
https://webrtc-codereview.appspot.com/27989004/
https://webrtc-codereview.appspot.com/29009004/
https://webrtc-codereview.appspot.com/30929004/
https://webrtc-codereview.appspot.com/30939004/
https://webrtc-codereview.appspot.com/31999004/
Committing as TBR to the original reviewers.
BUG=chromium:81439
TEST=none
TBR=pthatcher,henrik.lundin,tina.legrand,stefan,tkchin,glaznev,kjellander,perkj,mflodman,henrika,asapersson,niklas.enbom
Review URL: https://webrtc-codereview.appspot.com/23129004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@7726 4adac7df-926f-26a2-2b94-8c16560cd09d
2014-11-20 22:28:14 +00:00
|
|
|
if (packet_length > sizeof(restored_packet_))
|
2013-09-06 13:40:11 +00:00
|
|
|
return false;
|
2016-01-21 23:24:59 +01:00
|
|
|
rtc::CritScope lock(&receive_cs_);
|
2013-09-06 13:40:11 +00:00
|
|
|
if (restored_packet_in_use_) {
|
2014-05-14 08:02:22 +00:00
|
|
|
LOG(LS_WARNING) << "Multiple RTX headers detected, dropping packet.";
|
2013-09-06 13:40:11 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2016-03-02 15:05:53 +01:00
|
|
|
if (!rtp_payload_registry_.RestoreOriginalPacket(
|
2015-10-14 11:29:49 -07:00
|
|
|
restored_packet_, packet, &packet_length, rtp_receiver_->SSRC(),
|
|
|
|
|
header)) {
|
2016-02-03 13:29:59 +01:00
|
|
|
LOG(LS_WARNING) << "Incoming RTX packet: Invalid RTP header ssrc: "
|
|
|
|
|
<< header.ssrc << " payload type: "
|
|
|
|
|
<< static_cast<int>(header.payloadType);
|
2013-09-06 13:40:11 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
restored_packet_in_use_ = true;
|
2015-10-14 11:29:49 -07:00
|
|
|
bool ret = OnRecoveredPacket(restored_packet_, packet_length);
|
2013-09-06 13:40:11 +00:00
|
|
|
restored_packet_in_use_ = false;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2016-04-28 23:15:33 -07:00
|
|
|
void RtpStreamReceiver::NotifyReceiverOfFecPacket(const RTPHeader& header) {
|
2015-01-28 13:58:27 +00:00
|
|
|
int8_t last_media_payload_type =
|
2016-03-02 15:05:53 +01:00
|
|
|
rtp_payload_registry_.last_received_media_payload_type();
|
2015-01-28 13:58:27 +00:00
|
|
|
if (last_media_payload_type < 0) {
|
|
|
|
|
LOG(LS_WARNING) << "Failed to get last media payload type.";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// Fake an empty media packet.
|
|
|
|
|
WebRtcRTPHeader rtp_header = {};
|
|
|
|
|
rtp_header.header = header;
|
|
|
|
|
rtp_header.header.payloadType = last_media_payload_type;
|
|
|
|
|
rtp_header.header.paddingLength = 0;
|
|
|
|
|
PayloadUnion payload_specific;
|
2016-03-02 15:05:53 +01:00
|
|
|
if (!rtp_payload_registry_.GetPayloadSpecifics(last_media_payload_type,
|
|
|
|
|
&payload_specific)) {
|
2015-01-28 13:58:27 +00:00
|
|
|
LOG(LS_WARNING) << "Failed to get payload specifics.";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
rtp_header.type.Video.codec = payload_specific.Video.videoCodecType;
|
2015-03-12 20:50:57 +00:00
|
|
|
rtp_header.type.Video.rotation = kVideoRotation_0;
|
|
|
|
|
if (header.extension.hasVideoRotation) {
|
2016-09-08 03:24:58 -07:00
|
|
|
rtp_header.type.Video.rotation = header.extension.videoRotation;
|
2015-03-12 20:50:57 +00:00
|
|
|
}
|
2016-06-08 00:24:21 -07:00
|
|
|
rtp_header.type.Video.playout_delay = header.extension.playout_delay;
|
|
|
|
|
|
2016-04-04 17:56:10 +02:00
|
|
|
OnReceivedPayloadData(nullptr, 0, &rtp_header);
|
2015-01-28 13:58:27 +00:00
|
|
|
}
|
|
|
|
|
|
2016-04-28 23:15:33 -07:00
|
|
|
bool RtpStreamReceiver::DeliverRtcp(const uint8_t* rtcp_packet,
|
|
|
|
|
size_t rtcp_packet_length) {
|
2011-11-28 22:39:24 +00:00
|
|
|
{
|
2016-01-21 23:24:59 +01:00
|
|
|
rtc::CritScope lock(&receive_cs_);
|
2013-07-26 09:02:46 +00:00
|
|
|
if (!receiving_) {
|
2016-02-08 14:07:14 +01:00
|
|
|
return false;
|
2013-07-26 09:02:46 +00:00
|
|
|
}
|
2014-04-24 22:10:24 +00:00
|
|
|
}
|
|
|
|
|
|
2016-04-15 14:59:13 +02:00
|
|
|
rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length);
|
2016-03-02 15:05:53 +01:00
|
|
|
|
2015-01-12 21:51:21 +00:00
|
|
|
int64_t rtt = 0;
|
2016-04-15 14:59:13 +02:00
|
|
|
rtp_rtcp_->RTT(rtp_receiver_->SSRC(), &rtt, nullptr, nullptr, nullptr);
|
2014-10-09 10:52:43 +00:00
|
|
|
if (rtt == 0) {
|
|
|
|
|
// Waiting for valid rtt.
|
2016-02-08 14:07:14 +01:00
|
|
|
return true;
|
2014-10-09 10:52:43 +00:00
|
|
|
}
|
|
|
|
|
uint32_t ntp_secs = 0;
|
|
|
|
|
uint32_t ntp_frac = 0;
|
|
|
|
|
uint32_t rtp_timestamp = 0;
|
2016-04-15 14:59:13 +02:00
|
|
|
if (rtp_rtcp_->RemoteNTP(&ntp_secs, &ntp_frac, nullptr, nullptr,
|
|
|
|
|
&rtp_timestamp) != 0) {
|
2014-10-09 10:52:43 +00:00
|
|
|
// Waiting for RTCP.
|
2016-02-08 14:07:14 +01:00
|
|
|
return true;
|
2014-10-09 10:52:43 +00:00
|
|
|
}
|
2016-03-02 15:05:53 +01:00
|
|
|
ntp_estimator_.UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, rtp_timestamp);
|
2014-04-24 22:10:24 +00:00
|
|
|
|
2016-02-08 14:07:14 +01:00
|
|
|
return true;
|
2014-04-24 22:10:24 +00:00
|
|
|
}
|
|
|
|
|
|
2016-11-15 00:57:57 -08:00
|
|
|
void RtpStreamReceiver::FrameContinuous(uint16_t picture_id) {
|
2017-02-27 01:59:36 -08:00
|
|
|
if (!nack_module_)
|
|
|
|
|
return;
|
|
|
|
|
|
2017-02-22 05:30:39 -08:00
|
|
|
int seq_num = -1;
|
|
|
|
|
{
|
|
|
|
|
rtc::CritScope lock(&last_seq_num_cs_);
|
|
|
|
|
auto seq_num_it = last_seq_num_for_pic_id_.find(picture_id);
|
|
|
|
|
if (seq_num_it != last_seq_num_for_pic_id_.end())
|
|
|
|
|
seq_num = seq_num_it->second;
|
2016-11-15 00:57:57 -08:00
|
|
|
}
|
2017-02-22 05:30:39 -08:00
|
|
|
if (seq_num != -1)
|
|
|
|
|
nack_module_->ClearUpTo(seq_num);
|
2016-11-15 00:57:57 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RtpStreamReceiver::FrameDecoded(uint16_t picture_id) {
|
2017-02-22 05:30:39 -08:00
|
|
|
int seq_num = -1;
|
|
|
|
|
{
|
|
|
|
|
rtc::CritScope lock(&last_seq_num_cs_);
|
|
|
|
|
auto seq_num_it = last_seq_num_for_pic_id_.find(picture_id);
|
|
|
|
|
if (seq_num_it != last_seq_num_for_pic_id_.end()) {
|
|
|
|
|
seq_num = seq_num_it->second;
|
|
|
|
|
last_seq_num_for_pic_id_.erase(last_seq_num_for_pic_id_.begin(),
|
|
|
|
|
++seq_num_it);
|
2016-11-15 00:57:57 -08:00
|
|
|
}
|
Reland of Make the new jitter buffer the default jitter buffer. (patchset #2 id:260001 of https://codereview.chromium.org/2656983002/ )
Reason for revert:
Incoming fix: https://codereview.chromium.org/2675693002/
Original issue's description:
> Revert of Make the new jitter buffer the default jitter buffer. (patchset #2 id:290001 of https://codereview.chromium.org/2652043005/ )
>
> Reason for revert:
> Breaks downstream bots
>
> Original issue's description:
> > Reland of Make the new jitter buffer the default jitter buffer. (patchset #1 id:1 of https://codereview.webrtc.org/2638423003/ )
> >
> > Reason for revert:
> > Bugfixes related to the new jitter buffer has landed.
> >
> > Original issue's description:
> > > Revert of Make the new jitter buffer the default jitter buffer. (patchset #2 id:230001 of https://codereview.webrtc.org/2642753002/ )
> > >
> > > Reason for revert:
> > > Breaks tests downstream.
> > >
> > > Original issue's description:
> > > > Reland of Make the new jitter buffer the default jitter buffer. (patchset #1 id:1 of https://codereview.chromium.org/2632123005/ )
> > > >
> > > > Reason for revert:
> > > > Fix in this CL: https://codereview.chromium.org/2640793003/
> > > >
> > > > Original issue's description:
> > > > > Revert of Make the new jitter buffer the default jitter buffer. (patchset #7 id:120001 of https://codereview.chromium.org/2627463004/ )
> > > > >
> > > > > Reason for revert:
> > > > > Breaks android bots.
> > > > >
> > > > > Original issue's description:
> > > > > > Make the new jitter buffer the default jitter buffer.
> > > > > >
> > > > > > This CL contains only the changes necessary to make the switch to the new jitter
> > > > > > buffer, clean up will be done in follow up CLs.
> > > > > >
> > > > > > In this CL:
> > > > > > - Removed the WebRTC-NewVideoJitterBuffer experiment and made the
> > > > > > new video jitter buffer the default one.
> > > > > > - Moved WebRTC.Video.KeyFramesReceivedInPermille and
> > > > > > WebRTC.Video.JitterBufferDelayInMs to the ReceiveStatisticsProxy.
> > > > > >
> > > > > > BUG=webrtc:5514
> > > > > >
> > > > > > Review-Url: https://codereview.webrtc.org/2627463004
> > > > > > Cr-Commit-Position: refs/heads/master@{#16114}
> > > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/0f0763d86d5d4e7f27e8dece02560e39c6da97d6
> > > > >
> > > > > TBR=stefan@webrtc.org,terelius@webrtc.org
> > > > > # Skipping CQ checks because original CL landed less than 1 days ago.
> > > > > NOPRESUBMIT=true
> > > > > NOTREECHECKS=true
> > > > > NOTRY=true
> > > > > BUG=webrtc:5514
> > > > >
> > > > > Review-Url: https://codereview.webrtc.org/2632123005
> > > > > Cr-Commit-Position: refs/heads/master@{#16117}
> > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/c08c191f7d206dc0de945185370d18f29d556931
> > > >
> > > > TBR=stefan@webrtc.org,terelius@webrtc.org
> > > > # Not skipping CQ checks because original CL landed more than 1 days ago.
> > > > BUG=webrtc:5514
> > > >
> > > > Review-Url: https://codereview.webrtc.org/2642753002
> > > > Cr-Commit-Position: refs/heads/master@{#16149}
> > > > Committed: https://chromium.googlesource.com/external/webrtc/+/f20dd0014d1cfc8a2e859a9e177e7fe2b21274ca
> > >
> > > TBR=stefan@webrtc.org,terelius@webrtc.org,philipel@webrtc.org
> > > # Skipping CQ checks because original CL landed less than 1 days ago.
> > > NOPRESUBMIT=true
> > > NOTREECHECKS=true
> > > NOTRY=true
> > > BUG=webrtc:5514
> > >
> > > Review-Url: https://codereview.webrtc.org/2638423003
> > > Cr-Commit-Position: refs/heads/master@{#16159}
> > > Committed: https://chromium.googlesource.com/external/webrtc/+/04926b82641c426d764aa6e013e133db519129db
> >
> > TBR=stefan@webrtc.org,terelius@webrtc.org,kjellander@webrtc.org,kjellander@google.com
> > # Not skipping CQ checks because original CL landed more than 1 days ago.
> > BUG=webrtc:5514
> >
> > Review-Url: https://codereview.webrtc.org/2652043005
> > Cr-Commit-Position: refs/heads/master@{#16293}
> > Committed: https://chromium.googlesource.com/external/webrtc/+/09d6ef00fc21b9f2c2c27e50e5e2952329ac4b4b
>
> TBR=stefan@webrtc.org,terelius@webrtc.org,kjellander@webrtc.org,kjellander@google.com
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:5514
>
> Review-Url: https://codereview.webrtc.org/2656983002
> Cr-Commit-Position: refs/heads/master@{#16316}
> Committed: https://chromium.googlesource.com/external/webrtc/+/27378f39ced81acb1c2a61808e5e42fcf65d4b8d
TBR=stefan@webrtc.org,terelius@webrtc.org,kjellander@webrtc.org,kjellander@google.com
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:5514
Review-Url: https://codereview.webrtc.org/2670183002
Cr-Commit-Position: refs/heads/master@{#16420}
2017-02-02 09:53:00 -08:00
|
|
|
}
|
2017-02-22 05:30:39 -08:00
|
|
|
if (seq_num != -1) {
|
|
|
|
|
packet_buffer_->ClearTo(seq_num);
|
|
|
|
|
reference_finder_->ClearTo(seq_num);
|
|
|
|
|
}
|
2016-11-15 00:57:57 -08:00
|
|
|
}
|
|
|
|
|
|
2016-05-06 05:32:22 -07:00
|
|
|
void RtpStreamReceiver::SignalNetworkState(NetworkState state) {
|
|
|
|
|
rtp_rtcp_->SetRTCPStatus(state == kNetworkUp ? config_.rtp.rtcp_mode
|
|
|
|
|
: RtcpMode::kOff);
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-28 23:15:33 -07:00
|
|
|
void RtpStreamReceiver::StartReceive() {
|
2016-01-21 23:24:59 +01:00
|
|
|
rtc::CritScope lock(&receive_cs_);
|
2011-11-28 22:39:24 +00:00
|
|
|
receiving_ = true;
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2016-04-28 23:15:33 -07:00
|
|
|
void RtpStreamReceiver::StopReceive() {
|
2016-01-21 23:24:59 +01:00
|
|
|
rtc::CritScope lock(&receive_cs_);
|
2011-11-28 22:39:24 +00:00
|
|
|
receiving_ = false;
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2016-04-28 23:15:33 -07:00
|
|
|
bool RtpStreamReceiver::IsPacketInOrder(const RTPHeader& header) const {
|
2013-09-06 13:40:11 +00:00
|
|
|
StreamStatistician* statistician =
|
|
|
|
|
rtp_receive_statistics_->GetStatistician(header.ssrc);
|
|
|
|
|
if (!statistician)
|
|
|
|
|
return false;
|
|
|
|
|
return statistician->IsPacketInOrder(header.sequenceNumber);
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-28 23:15:33 -07:00
|
|
|
bool RtpStreamReceiver::IsPacketRetransmitted(const RTPHeader& header,
|
|
|
|
|
bool in_order) const {
|
2013-09-06 13:40:11 +00:00
|
|
|
// Retransmissions are handled separately if RTX is enabled.
|
2016-03-02 15:05:53 +01:00
|
|
|
if (rtp_payload_registry_.RtxEnabled())
|
2013-09-06 13:40:11 +00:00
|
|
|
return false;
|
|
|
|
|
StreamStatistician* statistician =
|
|
|
|
|
rtp_receive_statistics_->GetStatistician(header.ssrc);
|
|
|
|
|
if (!statistician)
|
|
|
|
|
return false;
|
|
|
|
|
// Check if this is a retransmission.
|
2015-01-12 21:51:21 +00:00
|
|
|
int64_t min_rtt = 0;
|
2016-04-15 14:59:13 +02:00
|
|
|
rtp_rtcp_->RTT(rtp_receiver_->SSRC(), nullptr, nullptr, &min_rtt, nullptr);
|
2013-11-08 15:18:52 +00:00
|
|
|
return !in_order &&
|
2013-09-06 13:40:11 +00:00
|
|
|
statistician->IsRetransmitOfOldPacket(header, min_rtt);
|
2013-08-15 23:38:54 +00:00
|
|
|
}
|
2016-05-06 05:32:22 -07:00
|
|
|
|
|
|
|
|
void RtpStreamReceiver::UpdateHistograms() {
|
2016-10-31 04:51:33 -07:00
|
|
|
FecPacketCounter counter = ulpfec_receiver_->GetPacketCounter();
|
2016-11-30 01:42:26 -08:00
|
|
|
if (counter.first_packet_time_ms == -1)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
int64_t elapsed_sec =
|
|
|
|
|
(clock_->TimeInMilliseconds() - counter.first_packet_time_ms) / 1000;
|
|
|
|
|
if (elapsed_sec < metrics::kMinRunTimeInSeconds)
|
|
|
|
|
return;
|
|
|
|
|
|
2016-05-06 05:32:22 -07:00
|
|
|
if (counter.num_packets > 0) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAM_PERCENTAGE(
|
2016-05-06 05:32:22 -07:00
|
|
|
"WebRTC.Video.ReceivedFecPacketsInPercent",
|
|
|
|
|
static_cast<int>(counter.num_fec_packets * 100 / counter.num_packets));
|
|
|
|
|
}
|
|
|
|
|
if (counter.num_fec_packets > 0) {
|
2016-09-09 22:40:25 -07:00
|
|
|
RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.RecoveredMediaPacketsInPercentOfFec",
|
|
|
|
|
static_cast<int>(counter.num_recovered_packets *
|
|
|
|
|
100 / counter.num_fec_packets));
|
2016-05-06 05:32:22 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RtpStreamReceiver::EnableReceiveRtpHeaderExtension(
|
|
|
|
|
const std::string& extension, int id) {
|
|
|
|
|
// One-byte-extension local identifiers are in the range 1-14 inclusive.
|
|
|
|
|
RTC_DCHECK_GE(id, 1);
|
|
|
|
|
RTC_DCHECK_LE(id, 14);
|
|
|
|
|
RTC_DCHECK(RtpExtension::IsSupportedForVideo(extension));
|
|
|
|
|
RTC_CHECK(rtp_header_parser_->RegisterRtpHeaderExtension(
|
|
|
|
|
StringToRtpExtensionType(extension), id));
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-20 04:15:59 -08:00
|
|
|
void RtpStreamReceiver::InsertSpsPpsIntoTracker(uint8_t payload_type) {
|
|
|
|
|
auto codec_params_it = pt_codec_params_.find(payload_type);
|
|
|
|
|
if (codec_params_it == pt_codec_params_.end())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
LOG(LS_INFO) << "Found out of band supplied codec parameters for"
|
2017-01-24 04:38:27 -08:00
|
|
|
<< " payload type: " << static_cast<int>(payload_type);
|
2016-12-20 04:15:59 -08:00
|
|
|
|
|
|
|
|
H264SpropParameterSets sprop_decoder;
|
|
|
|
|
auto sprop_base64_it =
|
|
|
|
|
codec_params_it->second.find(cricket::kH264FmtpSpropParameterSets);
|
|
|
|
|
|
|
|
|
|
if (sprop_base64_it == codec_params_it->second.end())
|
|
|
|
|
return;
|
|
|
|
|
|
2017-01-24 04:38:27 -08:00
|
|
|
if (!sprop_decoder.DecodeSprop(sprop_base64_it->second.c_str()))
|
2016-12-20 04:15:59 -08:00
|
|
|
return;
|
|
|
|
|
|
2017-01-24 02:38:17 -08:00
|
|
|
tracker_.InsertSpsPpsNalus(sprop_decoder.sps_nalu(),
|
|
|
|
|
sprop_decoder.pps_nalu());
|
2016-12-20 04:15:59 -08:00
|
|
|
}
|
|
|
|
|
|
2011-11-28 22:39:24 +00:00
|
|
|
} // namespace webrtc
|