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.
|
|
|
|
|
*/
|
|
|
|
|
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "video/rtp_video_stream_receiver.h"
|
2011-07-07 08:21:25 +00:00
|
|
|
|
2019-09-26 11:25:52 +02:00
|
|
|
#include <algorithm>
|
|
|
|
|
#include <limits>
|
2016-11-15 00:57:57 -08:00
|
|
|
#include <utility>
|
2017-06-19 07:18:55 -07:00
|
|
|
#include <vector>
|
2013-02-06 17:46:39 +00:00
|
|
|
|
2019-03-28 10:51:27 -07:00
|
|
|
#include "absl/algorithm/container.h"
|
2018-08-09 16:16:34 +02:00
|
|
|
#include "absl/memory/memory.h"
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "media/base/media_constants.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "modules/pacing/packet_router.h"
|
|
|
|
|
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
|
|
|
|
#include "modules/rtp_rtcp/include/receive_statistics.h"
|
|
|
|
|
#include "modules/rtp_rtcp/include/rtp_cvo.h"
|
|
|
|
|
#include "modules/rtp_rtcp/include/rtp_rtcp.h"
|
|
|
|
|
#include "modules/rtp_rtcp/include/ulpfec_receiver.h"
|
2018-08-09 16:16:34 +02:00
|
|
|
#include "modules/rtp_rtcp/source/rtp_format.h"
|
2018-09-13 10:57:14 +02:00
|
|
|
#include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
|
|
|
|
|
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
|
2018-08-09 16:16:34 +02:00
|
|
|
#include "modules/rtp_rtcp/source/rtp_rtcp_config.h"
|
2019-09-10 10:48:48 +02:00
|
|
|
#include "modules/utility/include/process_thread.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "modules/video_coding/frame_object.h"
|
|
|
|
|
#include "modules/video_coding/h264_sprop_parameter_sets.h"
|
|
|
|
|
#include "modules/video_coding/h264_sps_pps_tracker.h"
|
2018-06-07 16:15:40 +02:00
|
|
|
#include "modules/video_coding/nack_module.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "modules/video_coding/packet_buffer.h"
|
|
|
|
|
#include "rtc_base/checks.h"
|
|
|
|
|
#include "rtc_base/location.h"
|
|
|
|
|
#include "rtc_base/logging.h"
|
2018-09-06 13:41:30 +02:00
|
|
|
#include "rtc_base/strings/string_builder.h"
|
2018-02-05 10:33:35 +01:00
|
|
|
#include "rtc_base/system/fallthrough.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "system_wrappers/include/field_trial.h"
|
|
|
|
|
#include "system_wrappers/include/metrics.h"
|
|
|
|
|
#include "video/receive_statistics_proxy.h"
|
2011-07-07 08:21:25 +00:00
|
|
|
|
|
|
|
|
namespace webrtc {
|
|
|
|
|
|
2016-11-15 00:57:57 -08:00
|
|
|
namespace {
|
2017-08-10 18:10:59 +02:00
|
|
|
// TODO(philipel): Change kPacketBufferStartSize back to 32 in M63 see:
|
|
|
|
|
// crbug.com/752886
|
|
|
|
|
constexpr int kPacketBufferStartSize = 512;
|
2018-10-22 14:33:39 +02:00
|
|
|
constexpr int kPacketBufferMaxSize = 2048;
|
2019-09-20 17:57:15 +02:00
|
|
|
|
|
|
|
|
int PacketBufferMaxSize() {
|
|
|
|
|
// The group here must be a positive power of 2, in which case that is used as
|
|
|
|
|
// size. All other values shall result in the default value being used.
|
|
|
|
|
const std::string group_name =
|
|
|
|
|
webrtc::field_trial::FindFullName("WebRTC-PacketBufferMaxSize");
|
|
|
|
|
int packet_buffer_max_size = kPacketBufferMaxSize;
|
|
|
|
|
if (!group_name.empty() &&
|
|
|
|
|
(sscanf(group_name.c_str(), "%d", &packet_buffer_max_size) != 1 ||
|
|
|
|
|
packet_buffer_max_size <= 0 ||
|
|
|
|
|
// Verify that the number is a positive power of 2.
|
|
|
|
|
(packet_buffer_max_size & (packet_buffer_max_size - 1)) != 0)) {
|
|
|
|
|
RTC_LOG(LS_WARNING) << "Invalid packet buffer max size: " << group_name;
|
|
|
|
|
packet_buffer_max_size = kPacketBufferMaxSize;
|
|
|
|
|
}
|
|
|
|
|
return packet_buffer_max_size;
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
} // namespace
|
2016-11-15 00:57:57 -08:00
|
|
|
|
2016-04-25 01:26:26 -07:00
|
|
|
std::unique_ptr<RtpRtcp> CreateRtpRtcpModule(
|
2019-03-04 19:39:01 +01:00
|
|
|
Clock* clock,
|
2016-04-25 01:26:26 -07:00
|
|
|
ReceiveStatistics* receive_statistics,
|
|
|
|
|
Transport* outgoing_transport,
|
|
|
|
|
RtcpRttStats* rtt_stats,
|
2019-08-19 15:45:00 +02:00
|
|
|
RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer,
|
|
|
|
|
uint32_t local_ssrc) {
|
2016-04-25 01:26:26 -07:00
|
|
|
RtpRtcp::Configuration configuration;
|
2019-03-04 19:39:01 +01:00
|
|
|
configuration.clock = clock;
|
2016-04-25 01:26:26 -07:00
|
|
|
configuration.audio = false;
|
|
|
|
|
configuration.receiver_only = true;
|
|
|
|
|
configuration.receive_statistics = receive_statistics;
|
|
|
|
|
configuration.outgoing_transport = outgoing_transport;
|
|
|
|
|
configuration.rtt_stats = rtt_stats;
|
|
|
|
|
configuration.rtcp_packet_type_counter_observer =
|
|
|
|
|
rtcp_packet_type_counter_observer;
|
2019-08-20 17:22:36 +02:00
|
|
|
configuration.local_media_ssrc = local_ssrc;
|
2016-04-25 01:26:26 -07:00
|
|
|
|
2019-03-06 11:31:09 +01:00
|
|
|
std::unique_ptr<RtpRtcp> rtp_rtcp = RtpRtcp::Create(configuration);
|
2016-04-25 01:26:26 -07:00
|
|
|
rtp_rtcp->SetRTCPStatus(RtcpMode::kCompound);
|
|
|
|
|
|
|
|
|
|
return rtp_rtcp;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-14 11:40:13 +00:00
|
|
|
static const int kPacketLogIntervalMs = 10000;
|
|
|
|
|
|
2019-05-31 13:25:50 +02:00
|
|
|
RtpVideoStreamReceiver::RtcpFeedbackBuffer::RtcpFeedbackBuffer(
|
|
|
|
|
KeyFrameRequestSender* key_frame_request_sender,
|
|
|
|
|
NackSender* nack_sender,
|
|
|
|
|
LossNotificationSender* loss_notification_sender)
|
|
|
|
|
: key_frame_request_sender_(key_frame_request_sender),
|
|
|
|
|
nack_sender_(nack_sender),
|
|
|
|
|
loss_notification_sender_(loss_notification_sender),
|
|
|
|
|
request_key_frame_(false) {
|
|
|
|
|
RTC_DCHECK(key_frame_request_sender_);
|
|
|
|
|
RTC_DCHECK(nack_sender_);
|
|
|
|
|
RTC_DCHECK(loss_notification_sender_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RtpVideoStreamReceiver::RtcpFeedbackBuffer::RequestKeyFrame() {
|
|
|
|
|
rtc::CritScope lock(&cs_);
|
|
|
|
|
request_key_frame_ = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RtpVideoStreamReceiver::RtcpFeedbackBuffer::SendNack(
|
|
|
|
|
const std::vector<uint16_t>& sequence_numbers,
|
|
|
|
|
bool buffering_allowed) {
|
|
|
|
|
RTC_DCHECK(!sequence_numbers.empty());
|
|
|
|
|
rtc::CritScope lock(&cs_);
|
|
|
|
|
nack_sequence_numbers_.insert(nack_sequence_numbers_.end(),
|
|
|
|
|
sequence_numbers.cbegin(),
|
|
|
|
|
sequence_numbers.cend());
|
|
|
|
|
if (!buffering_allowed) {
|
|
|
|
|
// Note that while *buffering* is not allowed, *batching* is, meaning that
|
|
|
|
|
// previously buffered messages may be sent along with the current message.
|
|
|
|
|
SendBufferedRtcpFeedback();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RtpVideoStreamReceiver::RtcpFeedbackBuffer::SendLossNotification(
|
|
|
|
|
uint16_t last_decoded_seq_num,
|
|
|
|
|
uint16_t last_received_seq_num,
|
2019-06-03 14:37:50 +02:00
|
|
|
bool decodability_flag,
|
|
|
|
|
bool buffering_allowed) {
|
|
|
|
|
RTC_DCHECK(buffering_allowed);
|
2019-05-31 13:25:50 +02:00
|
|
|
rtc::CritScope lock(&cs_);
|
2019-06-04 22:59:54 +02:00
|
|
|
RTC_DCHECK(!lntf_state_)
|
2019-05-31 13:25:50 +02:00
|
|
|
<< "SendLossNotification() called twice in a row with no call to "
|
|
|
|
|
"SendBufferedRtcpFeedback() in between.";
|
|
|
|
|
lntf_state_ = absl::make_optional<LossNotificationState>(
|
|
|
|
|
last_decoded_seq_num, last_received_seq_num, decodability_flag);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RtpVideoStreamReceiver::RtcpFeedbackBuffer::SendBufferedRtcpFeedback() {
|
|
|
|
|
bool request_key_frame = false;
|
|
|
|
|
std::vector<uint16_t> nack_sequence_numbers;
|
|
|
|
|
absl::optional<LossNotificationState> lntf_state;
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
rtc::CritScope lock(&cs_);
|
|
|
|
|
std::swap(request_key_frame, request_key_frame_);
|
|
|
|
|
std::swap(nack_sequence_numbers, nack_sequence_numbers_);
|
|
|
|
|
std::swap(lntf_state, lntf_state_);
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-03 14:37:50 +02:00
|
|
|
if (lntf_state) {
|
|
|
|
|
// If either a NACK or a key frame request is sent, we should buffer
|
|
|
|
|
// the LNTF and wait for them (NACK or key frame request) to trigger
|
|
|
|
|
// the compound feedback message.
|
|
|
|
|
// Otherwise, the LNTF should be sent out immediately.
|
|
|
|
|
const bool buffering_allowed =
|
|
|
|
|
request_key_frame || !nack_sequence_numbers.empty();
|
|
|
|
|
|
|
|
|
|
loss_notification_sender_->SendLossNotification(
|
|
|
|
|
lntf_state->last_decoded_seq_num, lntf_state->last_received_seq_num,
|
|
|
|
|
lntf_state->decodability_flag, buffering_allowed);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-31 13:25:50 +02:00
|
|
|
if (request_key_frame) {
|
|
|
|
|
key_frame_request_sender_->RequestKeyFrame();
|
|
|
|
|
} else if (!nack_sequence_numbers.empty()) {
|
|
|
|
|
nack_sender_->SendNack(nack_sequence_numbers, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-09 04:01:55 -07:00
|
|
|
RtpVideoStreamReceiver::RtpVideoStreamReceiver(
|
2019-03-04 19:39:01 +01:00
|
|
|
Clock* clock,
|
2016-04-28 23:15:33 -07:00
|
|
|
Transport* transport,
|
|
|
|
|
RtcpRttStats* rtt_stats,
|
2016-05-03 21:22:04 -07:00
|
|
|
PacketRouter* packet_router,
|
2016-06-10 17:58:01 +02:00
|
|
|
const VideoReceiveStream::Config* config,
|
Reland of Use RtxReceiveStream. (patchset #1 id:1 of https://codereview.webrtc.org/3007303002/ )
Reason for revert:
Identified a configuration problem in the video quality tests. Intend to fix and reland.
Original issue's description:
> Revert of Use RtxReceiveStream. (patchset #5 id:320001 of https://codereview.webrtc.org/3006063002/ )
>
> Reason for revert:
> This change appears to break ulpfec, with severe regressions, e.g., for webrtc_perf_test FullStackTest.ForemanCifPlr5Ulpfec
>
> Original issue's description:
> > Reland of Use RtxReceiveStream. (patchset #1 id:1 of https://codereview.webrtc.org/3010983002/ )
> >
> > Reason for revert:
> > Intend to fix perf failures and reland.
> >
> > Original issue's description:
> > > Revert of Use RtxReceiveStream. (patchset #5 id:80001 of https://codereview.webrtc.org/3008773002/ )
> > >
> > > Reason for revert:
> > > A few perf tests broken, including
> > >
> > > RampUpTest.UpDownUpAbsSendTimeSimulcastRedRtx
> > > RampUpTest.UpDownUpTransportSequenceNumberRtx
> > > RampUpTest.UpDownUpTransportSequenceNumberPacketLoss
> > >
> > >
> > > Original issue's description:
> > > > Use RtxReceiveStream.
> > > >
> > > > This also has the beneficial side-effect that when a media stream
> > > > which is protected by FlexFEC receives an RTX retransmission, the
> > > > retransmitted media packet is passed into the FlexFEC machinery,
> > > > which should improve its ability to recover packets via FEC.
> > > >
> > > > BUG=webrtc:7135
> > > >
> > > > Review-Url: https://codereview.webrtc.org/3008773002
> > > > Cr-Commit-Position: refs/heads/master@{#19649}
> > > > Committed: https://chromium.googlesource.com/external/webrtc/+/5c0f6c62ea3b1d2c43f8fc152961af27033475f7
> > >
> > > TBR=brandtr@webrtc.org,danilchap@webrtc.org,stefan@webrtc.org,magjed@webrtc.org
> > > # Skipping CQ checks because original CL landed less than 1 days ago.
> > > NOPRESUBMIT=true
> > > NOTREECHECKS=true
> > > NOTRY=true
> > > BUG=webrtc:7135
> > >
> > > Review-Url: https://codereview.webrtc.org/3010983002
> > > Cr-Commit-Position: refs/heads/master@{#19653}
> > > Committed: https://chromium.googlesource.com/external/webrtc/+/3c39c0137afa274d1d524b150b50304b38a2847b
> >
> > TBR=brandtr@webrtc.org,danilchap@webrtc.org,stefan@webrtc.org,magjed@webrtc.org
> > # Skipping CQ checks because original CL landed less than 1 days ago.
> > NOPRESUBMIT=true
> > NOTREECHECKS=true
> > BUG=webrtc:7135
> >
> > Review-Url: https://codereview.webrtc.org/3006063002
> > Cr-Commit-Position: refs/heads/master@{#19715}
> > Committed: https://chromium.googlesource.com/external/webrtc/+/35713eaf565c0fef07c8afc158d7b8fdf7ec3d78
>
> TBR=brandtr@webrtc.org,danilchap@webrtc.org,stefan@webrtc.org,magjed@webrtc.org
> # Not skipping CQ checks because original CL landed more than 1 days ago.
> BUG=webrtc:7135
>
> Review-Url: https://codereview.webrtc.org/3007303002
> Cr-Commit-Position: refs/heads/master@{#19744}
> Committed: https://chromium.googlesource.com/external/webrtc/+/8e7eee035178a7f10e19883681b5eaa4a7523107
TBR=brandtr@webrtc.org,danilchap@webrtc.org,stefan@webrtc.org,magjed@webrtc.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:7135
Review-Url: https://codereview.webrtc.org/3012963002
Cr-Commit-Position: refs/heads/master@{#19765}
2017-09-11 02:32:16 -07:00
|
|
|
ReceiveStatistics* rtp_receive_statistics,
|
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,
|
2019-05-29 13:35:14 +02:00
|
|
|
KeyFrameRequestSender* keyframe_request_sender,
|
2018-10-17 17:27:25 -07:00
|
|
|
video_coding::OnCompleteFrameCallback* complete_frame_callback,
|
|
|
|
|
rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor)
|
2019-03-04 19:39:01 +01:00
|
|
|
: clock_(clock),
|
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
|
|
|
process_thread_(process_thread),
|
2019-03-04 19:39:01 +01:00
|
|
|
ntp_estimator_(clock),
|
2017-09-25 10:47:00 +02:00
|
|
|
rtp_header_extensions_(config_.rtp.extensions),
|
Reland of Use RtxReceiveStream. (patchset #1 id:1 of https://codereview.webrtc.org/3007303002/ )
Reason for revert:
Identified a configuration problem in the video quality tests. Intend to fix and reland.
Original issue's description:
> Revert of Use RtxReceiveStream. (patchset #5 id:320001 of https://codereview.webrtc.org/3006063002/ )
>
> Reason for revert:
> This change appears to break ulpfec, with severe regressions, e.g., for webrtc_perf_test FullStackTest.ForemanCifPlr5Ulpfec
>
> Original issue's description:
> > Reland of Use RtxReceiveStream. (patchset #1 id:1 of https://codereview.webrtc.org/3010983002/ )
> >
> > Reason for revert:
> > Intend to fix perf failures and reland.
> >
> > Original issue's description:
> > > Revert of Use RtxReceiveStream. (patchset #5 id:80001 of https://codereview.webrtc.org/3008773002/ )
> > >
> > > Reason for revert:
> > > A few perf tests broken, including
> > >
> > > RampUpTest.UpDownUpAbsSendTimeSimulcastRedRtx
> > > RampUpTest.UpDownUpTransportSequenceNumberRtx
> > > RampUpTest.UpDownUpTransportSequenceNumberPacketLoss
> > >
> > >
> > > Original issue's description:
> > > > Use RtxReceiveStream.
> > > >
> > > > This also has the beneficial side-effect that when a media stream
> > > > which is protected by FlexFEC receives an RTX retransmission, the
> > > > retransmitted media packet is passed into the FlexFEC machinery,
> > > > which should improve its ability to recover packets via FEC.
> > > >
> > > > BUG=webrtc:7135
> > > >
> > > > Review-Url: https://codereview.webrtc.org/3008773002
> > > > Cr-Commit-Position: refs/heads/master@{#19649}
> > > > Committed: https://chromium.googlesource.com/external/webrtc/+/5c0f6c62ea3b1d2c43f8fc152961af27033475f7
> > >
> > > TBR=brandtr@webrtc.org,danilchap@webrtc.org,stefan@webrtc.org,magjed@webrtc.org
> > > # Skipping CQ checks because original CL landed less than 1 days ago.
> > > NOPRESUBMIT=true
> > > NOTREECHECKS=true
> > > NOTRY=true
> > > BUG=webrtc:7135
> > >
> > > Review-Url: https://codereview.webrtc.org/3010983002
> > > Cr-Commit-Position: refs/heads/master@{#19653}
> > > Committed: https://chromium.googlesource.com/external/webrtc/+/3c39c0137afa274d1d524b150b50304b38a2847b
> >
> > TBR=brandtr@webrtc.org,danilchap@webrtc.org,stefan@webrtc.org,magjed@webrtc.org
> > # Skipping CQ checks because original CL landed less than 1 days ago.
> > NOPRESUBMIT=true
> > NOTREECHECKS=true
> > BUG=webrtc:7135
> >
> > Review-Url: https://codereview.webrtc.org/3006063002
> > Cr-Commit-Position: refs/heads/master@{#19715}
> > Committed: https://chromium.googlesource.com/external/webrtc/+/35713eaf565c0fef07c8afc158d7b8fdf7ec3d78
>
> TBR=brandtr@webrtc.org,danilchap@webrtc.org,stefan@webrtc.org,magjed@webrtc.org
> # Not skipping CQ checks because original CL landed more than 1 days ago.
> BUG=webrtc:7135
>
> Review-Url: https://codereview.webrtc.org/3007303002
> Cr-Commit-Position: refs/heads/master@{#19744}
> Committed: https://chromium.googlesource.com/external/webrtc/+/8e7eee035178a7f10e19883681b5eaa4a7523107
TBR=brandtr@webrtc.org,danilchap@webrtc.org,stefan@webrtc.org,magjed@webrtc.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:7135
Review-Url: https://codereview.webrtc.org/3012963002
Cr-Commit-Position: refs/heads/master@{#19765}
2017-09-11 02:32:16 -07:00
|
|
|
rtp_receive_statistics_(rtp_receive_statistics),
|
2019-06-26 14:39:36 +02:00
|
|
|
ulpfec_receiver_(UlpfecReceiver::Create(config->rtp.remote_ssrc,
|
|
|
|
|
this,
|
|
|
|
|
config->rtp.extensions)),
|
2013-09-06 13:40:11 +00:00
|
|
|
receiving_(false),
|
2016-04-25 01:26:26 -07:00
|
|
|
last_packet_log_ms_(-1),
|
2019-05-29 13:35:14 +02:00
|
|
|
rtp_rtcp_(CreateRtpRtcpModule(clock,
|
|
|
|
|
rtp_receive_statistics_,
|
|
|
|
|
transport,
|
|
|
|
|
rtt_stats,
|
2019-08-19 15:45:00 +02:00
|
|
|
receive_stats_proxy,
|
|
|
|
|
config_.rtp.local_ssrc)),
|
2016-11-15 00:57:57 -08:00
|
|
|
complete_frame_callback_(complete_frame_callback),
|
2019-05-29 13:35:14 +02:00
|
|
|
keyframe_request_sender_(keyframe_request_sender),
|
2019-05-31 13:25:50 +02:00
|
|
|
// TODO(bugs.webrtc.org/10336): Let |rtcp_feedback_buffer_| communicate
|
|
|
|
|
// directly with |rtp_rtcp_|.
|
|
|
|
|
rtcp_feedback_buffer_(this, nack_sender, this),
|
2019-10-22 17:12:42 +02:00
|
|
|
packet_buffer_(clock_, kPacketBufferStartSize, PacketBufferMaxSize()),
|
2019-03-01 11:01:59 -08:00
|
|
|
has_received_frame_(false),
|
2019-11-12 15:20:21 +00:00
|
|
|
frames_decryptable_(false) {
|
2017-08-01 06:30:28 -07:00
|
|
|
constexpr bool remb_candidate = true;
|
2019-05-20 11:06:33 +02:00
|
|
|
if (packet_router_)
|
|
|
|
|
packet_router_->AddReceiveRtpModule(rtp_rtcp_.get(), remb_candidate);
|
2016-05-03 21:22:04 -07:00
|
|
|
|
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
|
|
|
// 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);
|
2017-06-09 06:12:11 -07:00
|
|
|
rtp_rtcp_->SetRemoteSSRC(config_.rtp.remote_ssrc);
|
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;
|
2019-05-24 14:04:28 +02:00
|
|
|
rtp_receive_statistics_->SetMaxReorderingThreshold(config_.rtp.remote_ssrc,
|
|
|
|
|
max_reordering_threshold);
|
|
|
|
|
// TODO(nisse): For historic reasons, we applied the above
|
|
|
|
|
// max_reordering_threshold also for RTX stats, which makes little sense since
|
|
|
|
|
// we don't NACK rtx packets. Consider deleting the below block, and rely on
|
|
|
|
|
// the default threshold.
|
|
|
|
|
if (config_.rtp.rtx_ssrc) {
|
|
|
|
|
rtp_receive_statistics_->SetMaxReorderingThreshold(
|
|
|
|
|
config_.rtp.rtx_ssrc, max_reordering_threshold);
|
|
|
|
|
}
|
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.
|
2019-08-05 12:45:19 +02:00
|
|
|
rtp_rtcp_->RegisterRtcpCnameCallback(receive_stats_proxy);
|
2016-05-06 05:32:22 -07:00
|
|
|
|
2017-03-03 03:20:24 -08:00
|
|
|
process_thread_->RegisterModule(rtp_rtcp_.get(), RTC_FROM_HERE);
|
2016-11-15 00:57:57 -08:00
|
|
|
|
2019-05-24 13:40:02 +02:00
|
|
|
if (config_.rtp.lntf.enabled) {
|
2019-02-25 13:00:51 +01:00
|
|
|
loss_notification_controller_ =
|
2019-09-17 17:06:18 +02:00
|
|
|
std::make_unique<LossNotificationController>(&rtcp_feedback_buffer_,
|
|
|
|
|
&rtcp_feedback_buffer_);
|
2019-05-27 22:43:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (config_.rtp.nack.rtp_history_ms != 0) {
|
2019-09-17 17:06:18 +02:00
|
|
|
nack_module_ = std::make_unique<NackModule>(clock_, &rtcp_feedback_buffer_,
|
|
|
|
|
&rtcp_feedback_buffer_);
|
2017-03-03 03:20:24 -08:00
|
|
|
process_thread_->RegisterModule(nack_module_.get(), RTC_FROM_HERE);
|
2017-02-27 01:59:36 -08:00
|
|
|
}
|
2017-01-19 00:06:17 -08:00
|
|
|
|
2018-11-06 11:21:25 +01:00
|
|
|
reference_finder_ =
|
2019-09-17 17:06:18 +02:00
|
|
|
std::make_unique<video_coding::RtpFrameReferenceFinder>(this);
|
2019-04-03 10:44:18 -07:00
|
|
|
|
2018-11-30 16:18:26 -08:00
|
|
|
// Only construct the encrypted receiver if frame encryption is enabled.
|
2019-04-03 10:44:18 -07:00
|
|
|
if (config_.crypto_options.sframe.require_frame_encryption) {
|
2018-11-30 16:18:26 -08:00
|
|
|
buffered_frame_decryptor_ =
|
2019-09-17 17:06:18 +02:00
|
|
|
std::make_unique<BufferedFrameDecryptor>(this, this);
|
2019-04-03 10:44:18 -07:00
|
|
|
if (frame_decryptor != nullptr) {
|
|
|
|
|
buffered_frame_decryptor_->SetFrameDecryptor(std::move(frame_decryptor));
|
|
|
|
|
}
|
2018-11-30 16:18:26 -08:00
|
|
|
}
|
2016-04-25 01:26:26 -07:00
|
|
|
}
|
2011-07-07 08:21:25 +00:00
|
|
|
|
2017-06-09 04:01:55 -07:00
|
|
|
RtpVideoStreamReceiver::~RtpVideoStreamReceiver() {
|
2017-08-02 07:39:07 -07:00
|
|
|
RTC_DCHECK(secondary_sinks_.empty());
|
|
|
|
|
|
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
|
|
|
|
2019-05-20 11:06:33 +02:00
|
|
|
if (packet_router_)
|
|
|
|
|
packet_router_->RemoveReceiveRtpModule(rtp_rtcp_.get());
|
2015-01-15 07:40:20 +00:00
|
|
|
UpdateHistograms();
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2018-08-09 16:16:34 +02:00
|
|
|
void RtpVideoStreamReceiver::AddReceiveCodec(
|
2016-12-20 04:15:59 -08:00
|
|
|
const VideoCodec& video_codec,
|
2019-05-23 13:21:12 +02:00
|
|
|
const std::map<std::string, std::string>& codec_params,
|
|
|
|
|
bool raw_payload) {
|
|
|
|
|
absl::optional<VideoCodecType> video_type;
|
|
|
|
|
if (!raw_payload) {
|
|
|
|
|
video_type = video_codec.codecType;
|
|
|
|
|
}
|
|
|
|
|
payload_type_map_.emplace(video_codec.plType, video_type);
|
2018-08-09 16:16:34 +02:00
|
|
|
pt_codec_params_.emplace(video_codec.plType, codec_params);
|
2013-08-15 23:38:54 +00:00
|
|
|
}
|
|
|
|
|
|
2018-07-31 08:29:53 +02:00
|
|
|
absl::optional<Syncable::Info> RtpVideoStreamReceiver::GetSyncInfo() const {
|
2018-08-09 16:16:34 +02:00
|
|
|
Syncable::Info info;
|
2018-07-31 08:29:53 +02:00
|
|
|
if (rtp_rtcp_->RemoteNTP(&info.capture_time_ntp_secs,
|
|
|
|
|
&info.capture_time_ntp_frac, nullptr, nullptr,
|
|
|
|
|
&info.capture_time_source_clock) != 0) {
|
|
|
|
|
return absl::nullopt;
|
|
|
|
|
}
|
2018-08-28 13:58:15 +02:00
|
|
|
{
|
2019-06-25 10:16:14 +02:00
|
|
|
rtc::CritScope lock(&sync_info_lock_);
|
2018-08-28 13:58:15 +02:00
|
|
|
if (!last_received_rtp_timestamp_ || !last_received_rtp_system_time_ms_) {
|
|
|
|
|
return absl::nullopt;
|
|
|
|
|
}
|
|
|
|
|
info.latest_received_capture_timestamp = *last_received_rtp_timestamp_;
|
|
|
|
|
info.latest_receive_time_ms = *last_received_rtp_system_time_ms_;
|
|
|
|
|
}
|
2018-07-31 08:29:53 +02:00
|
|
|
|
|
|
|
|
// Leaves info.current_delay_ms uninitialized.
|
|
|
|
|
return info;
|
2013-08-15 23:38:54 +00:00
|
|
|
}
|
|
|
|
|
|
2019-10-16 19:18:21 +02:00
|
|
|
void RtpVideoStreamReceiver::OnReceivedPayloadData(
|
|
|
|
|
rtc::ArrayView<const uint8_t> codec_payload,
|
|
|
|
|
const RtpPacketReceived& rtp_packet,
|
|
|
|
|
const RTPVideoHeader& video) {
|
2019-10-30 14:12:24 +01:00
|
|
|
RTC_DCHECK_RUN_ON(&worker_task_checker_);
|
2019-10-16 19:18:21 +02:00
|
|
|
RTPHeader rtp_header;
|
|
|
|
|
rtp_packet.GetHeader(&rtp_header);
|
|
|
|
|
VCMPacket packet(codec_payload.data(), codec_payload.size(), rtp_header,
|
|
|
|
|
video, ntp_estimator_.Estimate(rtp_packet.Timestamp()),
|
2019-06-20 10:05:55 +02:00
|
|
|
clock_->TimeInMilliseconds());
|
2019-10-16 19:18:21 +02:00
|
|
|
|
|
|
|
|
RTPVideoHeader& video_header = packet.video_header;
|
|
|
|
|
video_header.rotation = kVideoRotation_0;
|
|
|
|
|
video_header.content_type = VideoContentType::UNSPECIFIED;
|
|
|
|
|
video_header.video_timing.flags = VideoSendTiming::kInvalid;
|
|
|
|
|
video_header.is_last_packet_in_frame |= rtp_packet.Marker();
|
|
|
|
|
video_header.frame_marking.temporal_id = kNoTemporalIdx;
|
|
|
|
|
|
|
|
|
|
if (const auto* vp9_header =
|
|
|
|
|
absl::get_if<RTPVideoHeaderVP9>(&video_header.video_type_header)) {
|
|
|
|
|
video_header.is_last_packet_in_frame |= vp9_header->end_of_frame;
|
|
|
|
|
video_header.is_first_packet_in_frame |= vp9_header->beginning_of_frame;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rtp_packet.GetExtension<VideoOrientation>(&video_header.rotation);
|
|
|
|
|
rtp_packet.GetExtension<VideoContentTypeExtension>(
|
|
|
|
|
&video_header.content_type);
|
|
|
|
|
rtp_packet.GetExtension<VideoTimingExtension>(&video_header.video_timing);
|
|
|
|
|
rtp_packet.GetExtension<PlayoutDelayLimits>(&video_header.playout_delay);
|
|
|
|
|
rtp_packet.GetExtension<FrameMarkingExtension>(&video_header.frame_marking);
|
|
|
|
|
|
|
|
|
|
RtpGenericFrameDescriptor& generic_descriptor =
|
|
|
|
|
packet.generic_descriptor.emplace();
|
|
|
|
|
if (rtp_packet.GetExtension<RtpGenericFrameDescriptorExtension01>(
|
|
|
|
|
&generic_descriptor)) {
|
|
|
|
|
if (rtp_packet.HasExtension<RtpGenericFrameDescriptorExtension00>()) {
|
|
|
|
|
RTC_LOG(LS_WARNING) << "RTP packet had two different GFD versions.";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
generic_descriptor.SetByteRepresentation(
|
|
|
|
|
rtp_packet.GetRawExtension<RtpGenericFrameDescriptorExtension01>());
|
|
|
|
|
} else if ((rtp_packet.GetExtension<RtpGenericFrameDescriptorExtension00>(
|
|
|
|
|
&generic_descriptor))) {
|
|
|
|
|
generic_descriptor.SetByteRepresentation(
|
|
|
|
|
rtp_packet.GetRawExtension<RtpGenericFrameDescriptorExtension00>());
|
|
|
|
|
} else {
|
|
|
|
|
packet.generic_descriptor = absl::nullopt;
|
|
|
|
|
}
|
|
|
|
|
if (packet.generic_descriptor != absl::nullopt) {
|
|
|
|
|
video_header.is_first_packet_in_frame =
|
|
|
|
|
packet.generic_descriptor->FirstPacketInSubFrame();
|
|
|
|
|
video_header.is_last_packet_in_frame =
|
|
|
|
|
rtp_packet.Marker() ||
|
|
|
|
|
packet.generic_descriptor->LastPacketInSubFrame();
|
|
|
|
|
|
|
|
|
|
if (packet.generic_descriptor->FirstPacketInSubFrame()) {
|
|
|
|
|
video_header.frame_type =
|
|
|
|
|
packet.generic_descriptor->FrameDependenciesDiffs().empty()
|
|
|
|
|
? VideoFrameType::kVideoFrameKey
|
|
|
|
|
: VideoFrameType::kVideoFrameDelta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
video_header.width = packet.generic_descriptor->Width();
|
|
|
|
|
video_header.height = packet.generic_descriptor->Height();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Color space should only be transmitted in the last packet of a frame,
|
|
|
|
|
// therefore, neglect it otherwise so that last_color_space_ is not reset by
|
|
|
|
|
// mistake.
|
|
|
|
|
if (video_header.is_last_packet_in_frame) {
|
|
|
|
|
video_header.color_space = rtp_packet.GetExtension<ColorSpaceExtension>();
|
|
|
|
|
if (video_header.color_space ||
|
|
|
|
|
video_header.frame_type == VideoFrameType::kVideoFrameKey) {
|
|
|
|
|
// Store color space since it's only transmitted when changed or for key
|
|
|
|
|
// frames. Color space will be cleared if a key frame is transmitted
|
|
|
|
|
// without color space information.
|
|
|
|
|
last_color_space_ = video_header.color_space;
|
|
|
|
|
} else if (last_color_space_) {
|
|
|
|
|
video_header.color_space = last_color_space_;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-02-25 13:00:51 +01:00
|
|
|
|
2019-05-27 22:43:10 +02:00
|
|
|
if (loss_notification_controller_) {
|
2019-10-16 19:18:21 +02:00
|
|
|
if (rtp_packet.recovered()) {
|
2019-05-27 22:43:10 +02:00
|
|
|
// TODO(bugs.webrtc.org/10336): Implement support for reordering.
|
2019-09-13 14:18:58 +02:00
|
|
|
RTC_LOG(LS_INFO)
|
2019-05-27 22:43:10 +02:00
|
|
|
<< "LossNotificationController does not support reordering.";
|
2019-10-16 19:18:21 +02:00
|
|
|
} else if (!packet.generic_descriptor) {
|
2019-09-13 14:18:58 +02:00
|
|
|
RTC_LOG(LS_WARNING) << "LossNotificationController requires generic "
|
|
|
|
|
"frame descriptor, but it is missing.";
|
2019-05-27 22:43:10 +02:00
|
|
|
} else {
|
2019-10-16 19:18:21 +02:00
|
|
|
loss_notification_controller_->OnReceivedPacket(
|
|
|
|
|
rtp_packet.SequenceNumber(), *packet.generic_descriptor);
|
2019-05-27 22:43:10 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-22 10:36:35 +02:00
|
|
|
if (nack_module_) {
|
2019-04-24 09:41:16 +02:00
|
|
|
const bool is_keyframe =
|
|
|
|
|
video_header.is_first_packet_in_frame &&
|
|
|
|
|
video_header.frame_type == VideoFrameType::kVideoFrameKey;
|
2018-08-22 10:36:35 +02:00
|
|
|
|
|
|
|
|
packet.timesNacked = nack_module_->OnReceivedPacket(
|
2019-10-16 19:18:21 +02:00
|
|
|
rtp_packet.SequenceNumber(), is_keyframe, rtp_packet.recovered());
|
2018-08-22 10:36:35 +02:00
|
|
|
} else {
|
|
|
|
|
packet.timesNacked = -1;
|
|
|
|
|
}
|
2017-02-22 05:30:39 -08:00
|
|
|
|
2017-03-21 05:45:18 -07:00
|
|
|
if (packet.sizeBytes == 0) {
|
2018-03-23 13:22:29 +01:00
|
|
|
NotifyReceiverOfEmptyPacket(packet.seqNum);
|
2019-05-31 13:25:50 +02:00
|
|
|
rtcp_feedback_buffer_.SendBufferedRtcpFeedback();
|
2019-10-16 19:18:21 +02:00
|
|
|
return;
|
2017-03-21 05:45:18 -07:00
|
|
|
}
|
|
|
|
|
|
2019-02-20 13:12:21 +01:00
|
|
|
if (packet.codec() == kVideoCodecH264) {
|
2017-02-22 05:30:39 -08:00
|
|
|
// 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
|
|
|
|
2019-10-28 13:27:05 +01:00
|
|
|
video_coding::H264SpsPpsTracker::FixedBitstream fixed =
|
|
|
|
|
tracker_.CopyAndFixBitstream(codec_payload, &packet.video_header);
|
|
|
|
|
|
|
|
|
|
switch (fixed.action) {
|
2017-02-22 05:30:39 -08:00
|
|
|
case video_coding::H264SpsPpsTracker::kRequestKeyframe:
|
2019-05-31 13:25:50 +02:00
|
|
|
rtcp_feedback_buffer_.RequestKeyFrame();
|
|
|
|
|
rtcp_feedback_buffer_.SendBufferedRtcpFeedback();
|
2018-02-05 10:33:35 +01:00
|
|
|
RTC_FALLTHROUGH();
|
2017-02-22 05:30:39 -08:00
|
|
|
case video_coding::H264SpsPpsTracker::kDrop:
|
2019-10-16 19:18:21 +02:00
|
|
|
return;
|
2017-02-22 05:30:39 -08:00
|
|
|
case video_coding::H264SpsPpsTracker::kInsert:
|
2019-10-28 13:27:05 +01:00
|
|
|
packet.dataPtr = fixed.data.release();
|
|
|
|
|
packet.sizeBytes = fixed.size;
|
2017-02-22 05:30:39 -08:00
|
|
|
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
|
|
|
|
2019-05-31 13:25:50 +02:00
|
|
|
rtcp_feedback_buffer_.SendBufferedRtcpFeedback();
|
2019-10-30 14:12:24 +01:00
|
|
|
frame_counter_.Add(packet.timestamp);
|
2019-10-22 17:12:42 +02:00
|
|
|
OnInsertedPacket(packet_buffer_.InsertPacket(&packet));
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2017-06-09 04:01:55 -07:00
|
|
|
void RtpVideoStreamReceiver::OnRecoveredPacket(const uint8_t* rtp_packet,
|
|
|
|
|
size_t rtp_packet_length) {
|
2017-09-25 10:47:00 +02:00
|
|
|
RtpPacketReceived packet;
|
|
|
|
|
if (!packet.Parse(rtp_packet, rtp_packet_length))
|
2017-05-29 08:16:37 -07:00
|
|
|
return;
|
2018-08-09 16:16:34 +02:00
|
|
|
if (packet.PayloadType() == config_.rtp.red_payload_type) {
|
|
|
|
|
RTC_LOG(LS_WARNING) << "Discarding recovered packet with RED encapsulation";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-25 10:47:00 +02:00
|
|
|
packet.IdentifyExtensions(rtp_header_extensions_);
|
|
|
|
|
packet.set_payload_type_frequency(kVideoPayloadTypeFrequency);
|
2018-08-09 16:16:34 +02:00
|
|
|
// TODO(nisse): UlpfecReceiverImpl::ProcessReceivedFec passes both
|
|
|
|
|
// original (decapsulated) media packets and recovered packets to
|
|
|
|
|
// this callback. We need a way to distinguish, for setting
|
|
|
|
|
// packet.recovered() correctly. Ideally, move RED decapsulation out
|
|
|
|
|
// of the Ulpfec implementation.
|
2017-09-25 10:47:00 +02:00
|
|
|
|
2018-08-09 16:16:34 +02:00
|
|
|
ReceivePacket(packet);
|
2013-08-15 23:38:54 +00:00
|
|
|
}
|
|
|
|
|
|
2017-05-11 08:00:58 -07:00
|
|
|
// This method handles both regular RTP packets and packets recovered
|
|
|
|
|
// via FlexFEC.
|
2017-06-09 04:01:55 -07:00
|
|
|
void RtpVideoStreamReceiver::OnRtpPacket(const RtpPacketReceived& packet) {
|
2019-04-09 13:44:04 +02:00
|
|
|
RTC_DCHECK_RUN_ON(&worker_task_checker_);
|
2017-08-02 07:39:07 -07:00
|
|
|
|
2017-08-25 00:49:08 -07:00
|
|
|
if (!receiving_) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2014-10-14 11:40:13 +00:00
|
|
|
|
2017-08-25 00:49:08 -07:00
|
|
|
if (!packet.recovered()) {
|
2018-09-26 16:04:32 +02:00
|
|
|
// TODO(nisse): Exclude out-of-order packets?
|
2017-08-25 00:49:08 -07:00
|
|
|
int64_t now_ms = clock_->TimeInMilliseconds();
|
2018-08-28 13:58:15 +02:00
|
|
|
{
|
2019-06-25 10:16:14 +02:00
|
|
|
rtc::CritScope cs(&sync_info_lock_);
|
2018-08-28 13:58:15 +02:00
|
|
|
last_received_rtp_timestamp_ = packet.Timestamp();
|
|
|
|
|
last_received_rtp_system_time_ms_ = now_ms;
|
|
|
|
|
}
|
2017-08-25 00:49:08 -07:00
|
|
|
// Periodically log the RTP header of incoming packets.
|
|
|
|
|
if (now_ms - last_packet_log_ms_ > kPacketLogIntervalMs) {
|
2018-09-06 13:41:30 +02:00
|
|
|
rtc::StringBuilder ss;
|
2017-08-25 00:49:08 -07: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;
|
2017-02-13 05:59:46 -08:00
|
|
|
}
|
2017-08-25 00:49:08 -07:00
|
|
|
uint32_t send_time;
|
|
|
|
|
if (packet.GetExtension<AbsoluteSendTime>(&send_time)) {
|
|
|
|
|
ss << ", abs send time: " << send_time;
|
|
|
|
|
}
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_INFO) << ss.str();
|
2017-08-25 00:49:08 -07:00
|
|
|
last_packet_log_ms_ = now_ms;
|
2014-10-14 11:40:13 +00:00
|
|
|
}
|
|
|
|
|
}
|
2013-12-13 00:21:03 +00:00
|
|
|
|
2018-08-09 16:16:34 +02:00
|
|
|
ReceivePacket(packet);
|
2018-08-09 06:18:57 +00:00
|
|
|
|
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).
|
2017-05-11 08:00:58 -07:00
|
|
|
if (!packet.recovered()) {
|
2018-09-14 08:26:32 +02:00
|
|
|
rtp_receive_statistics_->OnRtpPacket(packet);
|
2017-05-11 08:00:58 -07:00
|
|
|
}
|
2017-08-02 07:39:07 -07:00
|
|
|
|
|
|
|
|
for (RtpPacketSinkInterface* secondary_sink : secondary_sinks_) {
|
|
|
|
|
secondary_sink->OnRtpPacket(packet);
|
|
|
|
|
}
|
2013-09-06 13:40:11 +00:00
|
|
|
}
|
|
|
|
|
|
2019-03-25 15:51:03 +01:00
|
|
|
void RtpVideoStreamReceiver::RequestKeyFrame() {
|
2019-05-31 13:25:50 +02:00
|
|
|
// TODO(bugs.webrtc.org/10336): Allow the sender to ignore key frame requests
|
|
|
|
|
// issued by anything other than the LossNotificationController if it (the
|
|
|
|
|
// sender) is relying on LNTF alone.
|
2019-05-29 13:35:14 +02:00
|
|
|
if (keyframe_request_sender_) {
|
|
|
|
|
keyframe_request_sender_->RequestKeyFrame();
|
|
|
|
|
} else {
|
2019-06-04 14:46:27 +02:00
|
|
|
rtp_rtcp_->SendPictureLossIndication();
|
2019-05-29 13:35:14 +02:00
|
|
|
}
|
2016-05-03 21:22:04 -07:00
|
|
|
}
|
|
|
|
|
|
2019-02-25 13:00:51 +01:00
|
|
|
void RtpVideoStreamReceiver::SendLossNotification(
|
|
|
|
|
uint16_t last_decoded_seq_num,
|
|
|
|
|
uint16_t last_received_seq_num,
|
2019-06-03 14:37:50 +02:00
|
|
|
bool decodability_flag,
|
|
|
|
|
bool buffering_allowed) {
|
2019-05-24 13:40:02 +02:00
|
|
|
RTC_DCHECK(config_.rtp.lntf.enabled);
|
2019-02-25 13:00:51 +01:00
|
|
|
rtp_rtcp_->SendLossNotification(last_decoded_seq_num, last_received_seq_num,
|
2019-06-03 14:37:50 +02:00
|
|
|
decodability_flag, buffering_allowed);
|
2019-02-25 13:00:51 +01:00
|
|
|
}
|
|
|
|
|
|
2017-06-09 04:01:55 -07:00
|
|
|
bool RtpVideoStreamReceiver::IsUlpfecEnabled() const {
|
2017-09-26 02:49:21 -07:00
|
|
|
return config_.rtp.ulpfec_payload_type != -1;
|
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
|
|
|
}
|
|
|
|
|
|
2017-06-09 04:01:55 -07:00
|
|
|
bool RtpVideoStreamReceiver::IsRetransmissionsEnabled() const {
|
2016-05-06 05:32:22 -07:00
|
|
|
return config_.rtp.nack.rtp_history_ms > 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-09 04:01:55 -07:00
|
|
|
void RtpVideoStreamReceiver::RequestPacketRetransmit(
|
2016-05-06 05:32:22 -07:00
|
|
|
const std::vector<uint16_t>& sequence_numbers) {
|
|
|
|
|
rtp_rtcp_->SendNack(sequence_numbers);
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-01 11:01:59 -08:00
|
|
|
bool RtpVideoStreamReceiver::IsDecryptable() const {
|
|
|
|
|
return frames_decryptable_.load();
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-22 17:12:42 +02:00
|
|
|
void RtpVideoStreamReceiver::OnInsertedPacket(
|
|
|
|
|
video_coding::PacketBuffer::InsertResult result) {
|
|
|
|
|
for (std::unique_ptr<video_coding::RtpFrameObject>& frame : result.frames) {
|
|
|
|
|
OnAssembledFrame(std::move(frame));
|
|
|
|
|
}
|
|
|
|
|
if (result.buffer_cleared) {
|
|
|
|
|
RequestKeyFrame();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-22 11:19:50 +01:00
|
|
|
void RtpVideoStreamReceiver::OnAssembledFrame(
|
2016-11-15 00:57:57 -08:00
|
|
|
std::unique_ptr<video_coding::RtpFrameObject> frame) {
|
2018-11-30 16:18:26 -08:00
|
|
|
RTC_DCHECK_RUN_ON(&network_tc_);
|
2019-02-25 13:00:51 +01:00
|
|
|
RTC_DCHECK(frame);
|
|
|
|
|
|
|
|
|
|
absl::optional<RtpGenericFrameDescriptor> descriptor =
|
|
|
|
|
frame->GetGenericFrameDescriptor();
|
|
|
|
|
|
|
|
|
|
if (loss_notification_controller_ && descriptor) {
|
|
|
|
|
loss_notification_controller_->OnAssembledFrame(
|
|
|
|
|
frame->first_seq_num(), descriptor->FrameId(),
|
|
|
|
|
descriptor->Discardable().value_or(false),
|
|
|
|
|
descriptor->FrameDependenciesDiffs());
|
2019-05-27 22:43:10 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-31 13:25:50 +02:00
|
|
|
// If frames arrive before a key frame, they would not be decodable.
|
|
|
|
|
// In that case, request a key frame ASAP.
|
2019-05-27 22:43:10 +02:00
|
|
|
if (!has_received_frame_) {
|
2019-03-21 15:43:58 +01:00
|
|
|
if (frame->FrameType() != VideoFrameType::kVideoFrameKey) {
|
2019-05-31 13:25:50 +02:00
|
|
|
// |loss_notification_controller_|, if present, would have already
|
|
|
|
|
// requested a key frame when the first packet for the non-key frame
|
|
|
|
|
// had arrived, so no need to replicate the request.
|
|
|
|
|
if (!loss_notification_controller_) {
|
|
|
|
|
RequestKeyFrame();
|
|
|
|
|
}
|
2018-10-22 13:33:09 -07:00
|
|
|
}
|
2019-05-31 13:25:50 +02:00
|
|
|
has_received_frame_ = true;
|
2018-10-22 13:33:09 -07:00
|
|
|
}
|
2019-02-25 13:00:51 +01:00
|
|
|
|
2019-09-26 11:25:52 +02:00
|
|
|
rtc::CritScope lock(&reference_finder_lock_);
|
|
|
|
|
// Reset |reference_finder_| if |frame| is new and the codec have changed.
|
|
|
|
|
if (current_codec_) {
|
|
|
|
|
bool frame_is_newer =
|
|
|
|
|
AheadOf(frame->Timestamp(), last_assembled_frame_rtp_timestamp_);
|
|
|
|
|
|
|
|
|
|
if (frame->codec_type() != current_codec_) {
|
|
|
|
|
if (frame_is_newer) {
|
2019-11-12 15:20:21 +00:00
|
|
|
// When we reset the |reference_finder_| we don't want new picture ids
|
|
|
|
|
// to overlap with old picture ids. To ensure that doesn't happen we
|
|
|
|
|
// start from the |last_completed_picture_id_| and add an offset in case
|
|
|
|
|
// of reordering.
|
|
|
|
|
reference_finder_ =
|
|
|
|
|
std::make_unique<video_coding::RtpFrameReferenceFinder>(
|
|
|
|
|
this, last_completed_picture_id_ +
|
|
|
|
|
std::numeric_limits<uint16_t>::max());
|
2019-09-26 11:25:52 +02:00
|
|
|
current_codec_ = frame->codec_type();
|
|
|
|
|
} else {
|
|
|
|
|
// Old frame from before the codec switch, discard it.
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (frame_is_newer) {
|
|
|
|
|
last_assembled_frame_rtp_timestamp_ = frame->Timestamp();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
current_codec_ = frame->codec_type();
|
|
|
|
|
last_assembled_frame_rtp_timestamp_ = frame->Timestamp();
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-30 16:18:26 -08:00
|
|
|
if (buffered_frame_decryptor_ == nullptr) {
|
|
|
|
|
reference_finder_->ManageFrame(std::move(frame));
|
|
|
|
|
} else {
|
|
|
|
|
buffered_frame_decryptor_->ManageEncryptedFrame(std::move(frame));
|
2018-10-17 17:27:25 -07:00
|
|
|
}
|
2016-11-15 00:57:57 -08:00
|
|
|
}
|
|
|
|
|
|
2017-06-09 04:01:55 -07:00
|
|
|
void RtpVideoStreamReceiver::OnCompleteFrame(
|
2018-02-22 14:35:06 +01:00
|
|
|
std::unique_ptr<video_coding::EncodedFrame> frame) {
|
2016-11-15 00:57:57 -08:00
|
|
|
{
|
|
|
|
|
rtc::CritScope lock(&last_seq_num_cs_);
|
|
|
|
|
video_coding::RtpFrameObject* rtp_frame =
|
|
|
|
|
static_cast<video_coding::RtpFrameObject*>(frame.get());
|
2018-03-19 15:34:53 +01:00
|
|
|
last_seq_num_for_pic_id_[rtp_frame->id.picture_id] =
|
|
|
|
|
rtp_frame->last_seq_num();
|
2016-11-15 00:57:57 -08:00
|
|
|
}
|
2019-09-26 11:25:52 +02:00
|
|
|
last_completed_picture_id_ =
|
|
|
|
|
std::max(last_completed_picture_id_, frame->id.picture_id);
|
2016-11-15 00:57:57 -08:00
|
|
|
complete_frame_callback_->OnCompleteFrame(std::move(frame));
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-30 16:18:26 -08:00
|
|
|
void RtpVideoStreamReceiver::OnDecryptedFrame(
|
|
|
|
|
std::unique_ptr<video_coding::RtpFrameObject> frame) {
|
2019-09-26 11:25:52 +02:00
|
|
|
rtc::CritScope lock(&reference_finder_lock_);
|
2018-11-30 16:18:26 -08:00
|
|
|
reference_finder_->ManageFrame(std::move(frame));
|
|
|
|
|
}
|
|
|
|
|
|
Reland "Refactor FrameDecryptorInterface::Decrypt to use new API."
This reverts commit 7dd83e2bf73a7f1746c5ee976939bf52e19fa8be.
Reason for revert: This wasn't the cause of the break.
Original change's description:
> Revert "Refactor FrameDecryptorInterface::Decrypt to use new API."
>
> This reverts commit 642aa81f7d5cc55d5b99e2abc51327eed9d40195.
>
> Reason for revert: Speculative revert. The chromium roll is failing:
> https://ci.chromium.org/p/chromium/builders/try/linux-rel/64388
> But I can't figure out exactly what is failing, this looks suspecious.
>
> Original change's description:
> > Refactor FrameDecryptorInterface::Decrypt to use new API.
> >
> > This change refactors the FrameDecryptorInterface to use the new API. The new
> > API surface simply moves bytes_written to the return type and implements a
> > simple Status type.
> >
> > Bug: webrtc:10512
> > Change-Id: I622c5d344d58e618853c94c2f691cf7c8fb73a36
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131460
> > Reviewed-by: Steve Anton <steveanton@webrtc.org>
> > Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org>
> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Commit-Queue: Benjamin Wright <benwright@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#27497}
>
> TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org
>
> Change-Id: Ia9ec70263762c34671af13f0d519e636eb8473cd
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: webrtc:10512
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132013
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#27510}
TBR=brandtr@webrtc.org,steveanton@webrtc.org,solenberg@webrtc.org,hbos@webrtc.org,ossu@webrtc.org,stefan@webrtc.org,benwright@webrtc.org
Change-Id: I8e4b7965cf1d1a1554c3b46e6245f5ad0d2dcbb4
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10512
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131982
Reviewed-by: Benjamin Wright <benwright@webrtc.org>
Commit-Queue: Benjamin Wright <benwright@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27529}
2019-04-09 20:08:41 +00:00
|
|
|
void RtpVideoStreamReceiver::OnDecryptionStatusChange(
|
|
|
|
|
FrameDecryptorInterface::Status status) {
|
|
|
|
|
frames_decryptable_.store(
|
|
|
|
|
(status == FrameDecryptorInterface::Status::kOk) ||
|
|
|
|
|
(status == FrameDecryptorInterface::Status::kRecoverable));
|
2019-03-01 11:01:59 -08:00
|
|
|
}
|
|
|
|
|
|
2019-04-03 10:44:18 -07:00
|
|
|
void RtpVideoStreamReceiver::SetFrameDecryptor(
|
|
|
|
|
rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {
|
|
|
|
|
RTC_DCHECK_RUN_ON(&network_tc_);
|
|
|
|
|
if (buffered_frame_decryptor_ == nullptr) {
|
|
|
|
|
buffered_frame_decryptor_ =
|
2019-09-17 17:06:18 +02:00
|
|
|
std::make_unique<BufferedFrameDecryptor>(this, this);
|
2019-04-03 10:44:18 -07:00
|
|
|
}
|
|
|
|
|
buffered_frame_decryptor_->SetFrameDecryptor(std::move(frame_decryptor));
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-25 22:19:25 +02:00
|
|
|
void RtpVideoStreamReceiver::UpdateRtt(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
|
|
|
}
|
|
|
|
|
|
2018-06-15 12:28:07 +02:00
|
|
|
absl::optional<int64_t> RtpVideoStreamReceiver::LastReceivedPacketMs() const {
|
2019-09-20 17:57:15 +02:00
|
|
|
return packet_buffer_.LastReceivedPacketMs();
|
2017-05-18 08:08:53 -07:00
|
|
|
}
|
|
|
|
|
|
2018-06-15 12:28:07 +02:00
|
|
|
absl::optional<int64_t> RtpVideoStreamReceiver::LastReceivedKeyframePacketMs()
|
2017-06-09 04:01:55 -07:00
|
|
|
const {
|
2019-09-20 17:57:15 +02:00
|
|
|
return packet_buffer_.LastReceivedKeyframePacketMs();
|
2017-05-18 08:08:53 -07:00
|
|
|
}
|
|
|
|
|
|
2017-08-02 07:39:07 -07:00
|
|
|
void RtpVideoStreamReceiver::AddSecondarySink(RtpPacketSinkInterface* sink) {
|
2019-04-09 13:44:04 +02:00
|
|
|
RTC_DCHECK_RUN_ON(&worker_task_checker_);
|
2019-03-28 10:51:27 -07:00
|
|
|
RTC_DCHECK(!absl::c_linear_search(secondary_sinks_, sink));
|
2017-08-02 07:39:07 -07:00
|
|
|
secondary_sinks_.push_back(sink);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RtpVideoStreamReceiver::RemoveSecondarySink(
|
|
|
|
|
const RtpPacketSinkInterface* sink) {
|
2019-04-09 13:44:04 +02:00
|
|
|
RTC_DCHECK_RUN_ON(&worker_task_checker_);
|
2019-03-28 10:51:27 -07:00
|
|
|
auto it = absl::c_find(secondary_sinks_, sink);
|
2017-08-02 07:39:07 -07:00
|
|
|
if (it == secondary_sinks_.end()) {
|
|
|
|
|
// We might be rolling-back a call whose setup failed mid-way. In such a
|
|
|
|
|
// case, it's simpler to remove "everything" rather than remember what
|
|
|
|
|
// has already been added.
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_WARNING) << "Removal of unknown sink.";
|
2017-08-02 07:39:07 -07:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
secondary_sinks_.erase(it);
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-09 16:16:34 +02:00
|
|
|
void RtpVideoStreamReceiver::ReceivePacket(const RtpPacketReceived& packet) {
|
|
|
|
|
if (packet.payload_size() == 0) {
|
2018-08-21 17:49:24 +02:00
|
|
|
// Padding or keep-alive packet.
|
2018-08-09 16:16:34 +02:00
|
|
|
// TODO(nisse): Could drop empty packets earlier, but need to figure out how
|
|
|
|
|
// they should be counted in stats.
|
2018-08-21 17:49:24 +02:00
|
|
|
NotifyReceiverOfEmptyPacket(packet.SequenceNumber());
|
2018-08-09 16:16:34 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (packet.PayloadType() == config_.rtp.red_payload_type) {
|
2018-09-14 08:26:32 +02:00
|
|
|
ParseAndHandleEncapsulatingHeader(packet);
|
2018-08-09 16:16:34 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-23 13:21:12 +02:00
|
|
|
const auto type_it = payload_type_map_.find(packet.PayloadType());
|
|
|
|
|
if (type_it == payload_type_map_.end()) {
|
2017-05-29 08:16:37 -07:00
|
|
|
return;
|
2013-09-06 13:40:11 +00:00
|
|
|
}
|
2018-08-09 16:16:34 +02:00
|
|
|
auto depacketizer =
|
2019-05-23 13:21:12 +02:00
|
|
|
absl::WrapUnique(RtpDepacketizer::Create(type_it->second));
|
2018-08-09 16:16:34 +02:00
|
|
|
|
|
|
|
|
if (!depacketizer) {
|
|
|
|
|
RTC_LOG(LS_ERROR) << "Failed to create depacketizer.";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
RtpDepacketizer::ParsedPayload parsed_payload;
|
|
|
|
|
if (!depacketizer->Parse(&parsed_payload, packet.payload().data(),
|
|
|
|
|
packet.payload().size())) {
|
|
|
|
|
RTC_LOG(LS_WARNING) << "Failed parsing payload.";
|
|
|
|
|
return;
|
2013-08-15 23:38:54 +00:00
|
|
|
}
|
2018-08-09 16:16:34 +02:00
|
|
|
|
2019-10-16 19:18:21 +02:00
|
|
|
OnReceivedPayloadData(
|
|
|
|
|
rtc::MakeArrayView(parsed_payload.payload, parsed_payload.payload_length),
|
|
|
|
|
packet, parsed_payload.video);
|
2013-09-06 13:40:11 +00:00
|
|
|
}
|
|
|
|
|
|
2017-06-09 04:01:55 -07:00
|
|
|
void RtpVideoStreamReceiver::ParseAndHandleEncapsulatingHeader(
|
2018-09-14 08:26:32 +02:00
|
|
|
const RtpPacketReceived& packet) {
|
2019-04-09 13:44:04 +02:00
|
|
|
RTC_DCHECK_RUN_ON(&worker_task_checker_);
|
2018-09-14 08:26:32 +02:00
|
|
|
if (packet.PayloadType() == config_.rtp.red_payload_type &&
|
|
|
|
|
packet.payload_size() > 0) {
|
|
|
|
|
if (packet.payload()[0] == config_.rtp.ulpfec_payload_type) {
|
2016-04-22 18:23:15 +02:00
|
|
|
// Notify video_receiver about received FEC packets to avoid NACKing these
|
|
|
|
|
// packets.
|
2018-09-14 08:26:32 +02:00
|
|
|
NotifyReceiverOfEmptyPacket(packet.SequenceNumber());
|
2015-01-28 13:58:27 +00:00
|
|
|
}
|
2019-09-20 11:40:12 +02:00
|
|
|
if (!ulpfec_receiver_->AddReceivedRedPacket(
|
|
|
|
|
packet, config_.rtp.ulpfec_payload_type)) {
|
2017-05-29 08:16:37 -07:00
|
|
|
return;
|
2013-09-06 13:40:11 +00:00
|
|
|
}
|
2017-05-29 08:16:37 -07:00
|
|
|
ulpfec_receiver_->ProcessReceivedFec();
|
2013-09-06 13:40:11 +00:00
|
|
|
}
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2018-03-23 13:22:29 +01:00
|
|
|
// In the case of a video stream without picture ids and no rtx the
|
|
|
|
|
// RtpFrameReferenceFinder will need to know about padding to
|
|
|
|
|
// correctly calculate frame references.
|
|
|
|
|
void RtpVideoStreamReceiver::NotifyReceiverOfEmptyPacket(uint16_t seq_num) {
|
2019-09-26 11:25:52 +02:00
|
|
|
{
|
|
|
|
|
rtc::CritScope lock(&reference_finder_lock_);
|
|
|
|
|
reference_finder_->PaddingReceived(seq_num);
|
|
|
|
|
}
|
2019-10-22 17:12:42 +02:00
|
|
|
OnInsertedPacket(packet_buffer_.InsertPadding(seq_num));
|
2018-03-23 13:22:29 +01:00
|
|
|
if (nack_module_) {
|
2018-10-31 10:12:27 +01:00
|
|
|
nack_module_->OnReceivedPacket(seq_num, /* is_keyframe = */ false,
|
|
|
|
|
/* is _recovered = */ false);
|
2017-06-19 07:18:55 -07:00
|
|
|
}
|
2019-02-25 13:00:51 +01:00
|
|
|
if (loss_notification_controller_) {
|
2019-05-27 22:43:10 +02:00
|
|
|
// TODO(bugs.webrtc.org/10336): Handle empty packets.
|
2019-02-25 13:00:51 +01:00
|
|
|
RTC_LOG(LS_WARNING)
|
|
|
|
|
<< "LossNotificationController does not expect empty packets.";
|
|
|
|
|
}
|
2015-01-28 13:58:27 +00:00
|
|
|
}
|
|
|
|
|
|
2017-06-09 04:01:55 -07:00
|
|
|
bool RtpVideoStreamReceiver::DeliverRtcp(const uint8_t* rtcp_packet,
|
|
|
|
|
size_t rtcp_packet_length) {
|
2019-04-09 13:44:04 +02:00
|
|
|
RTC_DCHECK_RUN_ON(&worker_task_checker_);
|
2017-08-25 00:49:08 -07:00
|
|
|
|
|
|
|
|
if (!receiving_) {
|
|
|
|
|
return false;
|
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;
|
2018-08-09 16:16:34 +02:00
|
|
|
rtp_rtcp_->RTT(config_.rtp.remote_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;
|
2017-10-30 11:17:34 +01:00
|
|
|
uint32_t recieved_ntp_secs = 0;
|
|
|
|
|
uint32_t recieved_ntp_frac = 0;
|
|
|
|
|
if (rtp_rtcp_->RemoteNTP(&ntp_secs, &ntp_frac, &recieved_ntp_secs,
|
|
|
|
|
&recieved_ntp_frac, &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
|
|
|
}
|
2017-10-30 11:17:34 +01:00
|
|
|
NtpTime recieved_ntp(recieved_ntp_secs, recieved_ntp_frac);
|
|
|
|
|
int64_t time_since_recieved =
|
|
|
|
|
clock_->CurrentNtpInMilliseconds() - recieved_ntp.ToMs();
|
|
|
|
|
// Don't use old SRs to estimate time.
|
|
|
|
|
if (time_since_recieved <= 1) {
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2017-09-04 07:03:46 -07:00
|
|
|
void RtpVideoStreamReceiver::FrameContinuous(int64_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
|
|
|
}
|
|
|
|
|
|
2017-09-04 07:03:46 -07:00
|
|
|
void RtpVideoStreamReceiver::FrameDecoded(int64_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) {
|
2019-09-20 17:57:15 +02:00
|
|
|
packet_buffer_.ClearTo(seq_num);
|
2019-09-26 11:25:52 +02:00
|
|
|
rtc::CritScope lock(&reference_finder_lock_);
|
2017-02-22 05:30:39 -08:00
|
|
|
reference_finder_->ClearTo(seq_num);
|
|
|
|
|
}
|
2016-11-15 00:57:57 -08:00
|
|
|
}
|
|
|
|
|
|
2017-06-09 04:01:55 -07:00
|
|
|
void RtpVideoStreamReceiver::SignalNetworkState(NetworkState state) {
|
2016-05-06 05:32:22 -07:00
|
|
|
rtp_rtcp_->SetRTCPStatus(state == kNetworkUp ? config_.rtp.rtcp_mode
|
|
|
|
|
: RtcpMode::kOff);
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-09 04:01:55 -07:00
|
|
|
void RtpVideoStreamReceiver::StartReceive() {
|
2019-04-09 13:44:04 +02:00
|
|
|
RTC_DCHECK_RUN_ON(&worker_task_checker_);
|
2011-11-28 22:39:24 +00:00
|
|
|
receiving_ = true;
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2017-06-09 04:01:55 -07:00
|
|
|
void RtpVideoStreamReceiver::StopReceive() {
|
2019-04-09 13:44:04 +02:00
|
|
|
RTC_DCHECK_RUN_ON(&worker_task_checker_);
|
2011-11-28 22:39:24 +00:00
|
|
|
receiving_ = false;
|
2011-07-07 08:21:25 +00:00
|
|
|
}
|
|
|
|
|
|
2017-06-09 04:01:55 -07:00
|
|
|
void RtpVideoStreamReceiver::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
|
|
|
}
|
2019-08-27 09:19:49 +02:00
|
|
|
if (config_.rtp.ulpfec_payload_type != -1) {
|
|
|
|
|
RTC_HISTOGRAM_COUNTS_10000(
|
|
|
|
|
"WebRTC.Video.FecBitrateReceivedInKbps",
|
|
|
|
|
static_cast<int>(counter.num_bytes * 8 / elapsed_sec / 1000));
|
|
|
|
|
}
|
2016-05-06 05:32:22 -07:00
|
|
|
}
|
|
|
|
|
|
2017-06-09 04:01:55 -07:00
|
|
|
void RtpVideoStreamReceiver::InsertSpsPpsIntoTracker(uint8_t payload_type) {
|
2016-12-20 04:15:59 -08:00
|
|
|
auto codec_params_it = pt_codec_params_.find(payload_type);
|
|
|
|
|
if (codec_params_it == pt_codec_params_.end())
|
|
|
|
|
return;
|
|
|
|
|
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_INFO) << "Found out of band supplied codec parameters for"
|
|
|
|
|
<< " 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
|