Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 14:04:28 +01:00
parent 81b91f4139
commit f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* 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.
*/
#ifndef MODULES_RTP_RTCP_INCLUDE_FLEXFEC_RECEIVER_H_
#define MODULES_RTP_RTCP_INCLUDE_FLEXFEC_RECEIVER_H_
#include <stdint.h>
#include <memory>
#include "api/sequence_checker.h"
#include "api/units/timestamp.h"
#include "modules/rtp_rtcp/include/recovered_packet_receiver.h"
#include "modules/rtp_rtcp/source/forward_error_correction.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "modules/rtp_rtcp/source/ulpfec_receiver.h"
#include "rtc_base/system/no_unique_address.h"
#include "rtc_base/thread_annotations.h"
namespace webrtc {
class Clock;
class FlexfecReceiver {
public:
FlexfecReceiver(uint32_t ssrc,
uint32_t protected_media_ssrc,
RecoveredPacketReceiver* recovered_packet_receiver);
FlexfecReceiver(Clock* clock,
uint32_t ssrc,
uint32_t protected_media_ssrc,
RecoveredPacketReceiver* recovered_packet_receiver);
~FlexfecReceiver();
// Inserts a received packet (can be either media or FlexFEC) into the
// internal buffer, and sends the received packets to the erasure code.
// All newly recovered packets are sent back through the callback.
void OnRtpPacket(const RtpPacketReceived& packet);
// Returns a counter describing the added and recovered packets.
FecPacketCounter GetPacketCounter() const;
// Protected to aid testing.
protected:
std::unique_ptr<ForwardErrorCorrection::ReceivedPacket> AddReceivedPacket(
const RtpPacketReceived& packet);
void ProcessReceivedPacket(
const ForwardErrorCorrection::ReceivedPacket& received_packet);
private:
// Config.
const uint32_t ssrc_;
const uint32_t protected_media_ssrc_;
// Erasure code interfacing and callback.
std::unique_ptr<ForwardErrorCorrection> erasure_code_
RTC_GUARDED_BY(sequence_checker_);
ForwardErrorCorrection::RecoveredPacketList recovered_packets_
RTC_GUARDED_BY(sequence_checker_);
RecoveredPacketReceiver* const recovered_packet_receiver_;
// Logging and stats.
Clock* const clock_;
Timestamp last_recovered_packet_ RTC_GUARDED_BY(sequence_checker_) =
Timestamp::MinusInfinity();
FecPacketCounter packet_counter_ RTC_GUARDED_BY(sequence_checker_);
RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
};
} // namespace webrtc
#endif // MODULES_RTP_RTCP_INCLUDE_FLEXFEC_RECEIVER_H_

View file

@ -0,0 +1,104 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* 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.
*/
#ifndef MODULES_RTP_RTCP_INCLUDE_FLEXFEC_SENDER_H_
#define MODULES_RTP_RTCP_INCLUDE_FLEXFEC_SENDER_H_
#include <memory>
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/rtp_parameters.h"
#include "api/units/timestamp.h"
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtp_header_extension_size.h"
#include "modules/rtp_rtcp/source/ulpfec_generator.h"
#include "modules/rtp_rtcp/source/video_fec_generator.h"
#include "rtc_base/bitrate_tracker.h"
#include "rtc_base/random.h"
#include "rtc_base/synchronization/mutex.h"
namespace webrtc {
class Clock;
class RtpPacketToSend;
// Note that this class is not thread safe, and thus requires external
// synchronization. Currently, this is done using the lock in PayloadRouter.
class FlexfecSender : public VideoFecGenerator {
public:
FlexfecSender(int payload_type,
uint32_t ssrc,
uint32_t protected_media_ssrc,
absl::string_view mid,
const std::vector<RtpExtension>& rtp_header_extensions,
rtc::ArrayView<const RtpExtensionSize> extension_sizes,
const RtpState* rtp_state,
Clock* clock);
~FlexfecSender();
FecType GetFecType() const override {
return VideoFecGenerator::FecType::kFlexFec;
}
absl::optional<uint32_t> FecSsrc() override { return ssrc_; }
// Sets the FEC rate, max frames sent before FEC packets are sent,
// and what type of generator matrices are used.
void SetProtectionParameters(const FecProtectionParams& delta_params,
const FecProtectionParams& key_params) override;
// Adds a media packet to the internal buffer. When enough media packets
// have been added, the FEC packets are generated and stored internally.
// These FEC packets are then obtained by calling GetFecPackets().
void AddPacketAndGenerateFec(const RtpPacketToSend& packet) override;
// Returns generated FlexFEC packets.
std::vector<std::unique_ptr<RtpPacketToSend>> GetFecPackets() override;
// Returns the overhead, per packet, for FlexFEC.
size_t MaxPacketOverhead() const override;
DataRate CurrentFecRate() const override;
// Only called on the VideoSendStream queue, after operation has shut down.
absl::optional<RtpState> GetRtpState() override;
private:
// Utility.
Clock* const clock_;
Random random_;
Timestamp last_generated_packet_ = Timestamp::MinusInfinity();
// Config.
const int payload_type_;
const uint32_t timestamp_offset_;
const uint32_t ssrc_;
const uint32_t protected_media_ssrc_;
// MID value to send in the MID header extension.
const std::string mid_;
// Sequence number of next packet to generate.
uint16_t seq_num_;
// Implementation.
UlpfecGenerator ulpfec_generator_;
const RtpHeaderExtensionMap rtp_header_extension_map_;
const size_t header_extensions_size_;
mutable Mutex mutex_;
BitrateTracker fec_bitrate_ RTC_GUARDED_BY(mutex_);
};
} // namespace webrtc
#endif // MODULES_RTP_RTCP_INCLUDE_FLEXFEC_SENDER_H_

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* 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.
*/
#ifndef MODULES_RTP_RTCP_INCLUDE_RECEIVE_STATISTICS_H_
#define MODULES_RTP_RTCP_INCLUDE_RECEIVE_STATISTICS_H_
#include <map>
#include <memory>
#include <vector>
#include "absl/types/optional.h"
#include "call/rtp_packet_sink_interface.h"
#include "modules/rtp_rtcp/include/rtcp_statistics.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
namespace webrtc {
class Clock;
class ReceiveStatisticsProvider {
public:
virtual ~ReceiveStatisticsProvider() = default;
// Collects receive statistic in a form of rtcp report blocks.
// Returns at most `max_blocks` report blocks.
virtual std::vector<rtcp::ReportBlock> RtcpReportBlocks(
size_t max_blocks) = 0;
};
class StreamStatistician {
public:
virtual ~StreamStatistician();
virtual RtpReceiveStats GetStats() const = 0;
// Returns average over the stream life time.
virtual absl::optional<int> GetFractionLostInPercent() const = 0;
// TODO(bugs.webrtc.org/10679): Delete, migrate users to the above GetStats
// method (and extend RtpReceiveStats if needed).
// Gets receive stream data counters.
virtual StreamDataCounters GetReceiveStreamDataCounters() const = 0;
virtual uint32_t BitrateReceived() const = 0;
};
class ReceiveStatistics : public ReceiveStatisticsProvider,
public RtpPacketSinkInterface {
public:
~ReceiveStatistics() override = default;
// Returns a thread-safe instance of ReceiveStatistics.
// https://chromium.googlesource.com/chromium/src/+/lkgr/docs/threading_and_tasks.md#threading-lexicon
static std::unique_ptr<ReceiveStatistics> Create(Clock* clock);
// Returns a thread-compatible instance of ReceiveStatistics.
static std::unique_ptr<ReceiveStatistics> CreateThreadCompatible(
Clock* clock);
// Returns a pointer to the statistician of an ssrc.
virtual StreamStatistician* GetStatistician(uint32_t ssrc) const = 0;
// TODO(bugs.webrtc.org/10669): Deprecated, delete as soon as downstream
// projects are updated. This method sets the max reordering threshold of all
// current and future streams.
virtual void SetMaxReorderingThreshold(int max_reordering_threshold) = 0;
// Sets the max reordering threshold in number of packets.
virtual void SetMaxReorderingThreshold(uint32_t ssrc,
int max_reordering_threshold) = 0;
// Detect retransmissions, enabling updates of the retransmitted counters. The
// default is false.
virtual void EnableRetransmitDetection(uint32_t ssrc, bool enable) = 0;
};
} // namespace webrtc
#endif // MODULES_RTP_RTCP_INCLUDE_RECEIVE_STATISTICS_H_

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
*
* 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.
*/
#ifndef MODULES_RTP_RTCP_INCLUDE_RECOVERED_PACKET_RECEIVER_H_
#define MODULES_RTP_RTCP_INCLUDE_RECOVERED_PACKET_RECEIVER_H_
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "rtc_base/checks.h"
namespace webrtc {
// Callback interface for packets recovered by FlexFEC or ULPFEC. In
// the FlexFEC case, the implementation should be able to demultiplex
// the recovered RTP packets based on SSRC.
class RecoveredPacketReceiver {
public:
virtual void OnRecoveredPacket(const RtpPacketReceived& packet) = 0;
protected:
virtual ~RecoveredPacketReceiver() = default;
};
} // namespace webrtc
#endif // MODULES_RTP_RTCP_INCLUDE_RECOVERED_PACKET_RECEIVER_H_

View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
*
* 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.
*/
#ifndef MODULES_RTP_RTCP_INCLUDE_REMOTE_NTP_TIME_ESTIMATOR_H_
#define MODULES_RTP_RTCP_INCLUDE_REMOTE_NTP_TIME_ESTIMATOR_H_
#include <stdint.h>
#include "absl/types/optional.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "rtc_base/numerics/moving_percentile_filter.h"
#include "system_wrappers/include/rtp_to_ntp_estimator.h"
namespace webrtc {
class Clock;
// RemoteNtpTimeEstimator can be used to estimate a given RTP timestamp's NTP
// time in local timebase.
// Note that it needs to be trained with at least 2 RTCP SR (by calling
// `UpdateRtcpTimestamp`) before it can be used.
class RemoteNtpTimeEstimator {
public:
explicit RemoteNtpTimeEstimator(Clock* clock);
RemoteNtpTimeEstimator(const RemoteNtpTimeEstimator&) = delete;
RemoteNtpTimeEstimator& operator=(const RemoteNtpTimeEstimator&) = delete;
~RemoteNtpTimeEstimator() = default;
// Updates the estimator with round trip time `rtt` and
// new NTP time <-> RTP timestamp mapping from an RTCP sender report.
bool UpdateRtcpTimestamp(TimeDelta rtt,
NtpTime sender_send_time,
uint32_t rtp_timestamp);
// Estimates the NTP timestamp in local timebase from `rtp_timestamp`.
// Returns the NTP timestamp in ms when success. -1 if failed.
int64_t Estimate(uint32_t rtp_timestamp) {
NtpTime ntp_time = EstimateNtp(rtp_timestamp);
if (!ntp_time.Valid()) {
return -1;
}
return ntp_time.ToMs();
}
// Estimates the NTP timestamp in local timebase from `rtp_timestamp`.
// Returns invalid NtpTime (i.e. NtpTime(0)) on failure.
NtpTime EstimateNtp(uint32_t rtp_timestamp);
// Estimates the offset between the remote clock and the
// local one. This is equal to local NTP clock - remote NTP clock.
// The offset is returned in ntp time resolution, i.e. 1/2^32 sec ~= 0.2 ns.
// Returns nullopt on failure.
absl::optional<int64_t> EstimateRemoteToLocalClockOffset();
private:
Clock* clock_;
// Offset is measured with the same precision as NtpTime: in 1/2^32 seconds ~=
// 0.2 ns.
MovingMedianFilter<int64_t> ntp_clocks_offset_estimator_;
RtpToNtpEstimator rtp_to_ntp_;
Timestamp last_timing_log_ = Timestamp::MinusInfinity();
};
} // namespace webrtc
#endif // MODULES_RTP_RTCP_INCLUDE_REMOTE_NTP_TIME_ESTIMATOR_H_

View file

@ -0,0 +1,42 @@
/*
* Copyright 2019 The WebRTC Project Authors. All rights reserved.
*
* 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.
*/
#include "modules/rtp_rtcp/include/report_block_data.h"
#include "rtc_base/checks.h"
namespace webrtc {
TimeDelta ReportBlockData::jitter(int rtp_clock_rate_hz) const {
RTC_DCHECK_GT(rtp_clock_rate_hz, 0);
// Conversion to TimeDelta and division are swapped to avoid conversion
// to/from floating point types.
return TimeDelta::Seconds(jitter()) / rtp_clock_rate_hz;
}
void ReportBlockData::SetReportBlock(uint32_t sender_ssrc,
const rtcp::ReportBlock& report_block,
Timestamp report_block_timestamp_utc) {
sender_ssrc_ = sender_ssrc;
source_ssrc_ = report_block.source_ssrc();
fraction_lost_raw_ = report_block.fraction_lost();
cumulative_lost_ = report_block.cumulative_lost();
extended_highest_sequence_number_ = report_block.extended_high_seq_num();
jitter_ = report_block.jitter();
report_block_timestamp_utc_ = report_block_timestamp_utc;
}
void ReportBlockData::AddRoundTripTimeSample(TimeDelta rtt) {
last_rtt_ = rtt;
sum_rtt_ += rtt;
++num_rtts_;
}
} // namespace webrtc

View file

@ -0,0 +1,123 @@
/*
* Copyright 2019 The WebRTC Project Authors. All rights reserved.
*
* 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.
*/
#ifndef MODULES_RTP_RTCP_INCLUDE_REPORT_BLOCK_DATA_H_
#define MODULES_RTP_RTCP_INCLUDE_REPORT_BLOCK_DATA_H_
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
namespace webrtc {
// Represents fields and derived information received in RTCP report block
// attached to RTCP sender report or RTCP receiver report, as described in
// https://www.rfc-editor.org/rfc/rfc3550#section-6.4.1
class ReportBlockData {
public:
ReportBlockData() = default;
ReportBlockData(const ReportBlockData&) = default;
ReportBlockData& operator=(const ReportBlockData&) = default;
// The SSRC identifier for the originator of this report block,
// i.e. remote receiver of the RTP stream.
uint32_t sender_ssrc() const { return sender_ssrc_; }
// The SSRC identifier of the source to which the information in this
// reception report block pertains, i.e. local sender of the RTP stream.
uint32_t source_ssrc() const { return source_ssrc_; }
// The fraction of RTP data packets from 'source_ssrc()' lost since the
// previous report block was sent.
// Fraction loss in range [0.0, 1.0].
float fraction_lost() const { return fraction_lost_raw() / 256.0; }
// Fraction loss as was written in the raw packet: range is [0, 255] where 0
// represents no loss, and 255 represents 99.6% loss (255/256 * 100%).
uint8_t fraction_lost_raw() const { return fraction_lost_raw_; }
// The total number of RTP data packets from 'source_ssrc()' that have been
// lost since the beginning of reception. This number is defined to be the
// number of packets expected less the number of packets actually received,
// where the number of packets received includes any which are late or
// duplicates. Thus, packets that arrive late are not counted as lost, and the
// loss may be negative if there are duplicates.
int cumulative_lost() const { return cumulative_lost_; }
// The low 16 bits contain the highest sequence number received in an RTP data
// packet from 'source_ssrc()', and the most significant 16 bits extend that
// sequence number with the corresponding count of sequence number cycles.
uint32_t extended_highest_sequence_number() const {
return extended_highest_sequence_number_;
}
// An estimate of the statistical variance of the RTP data packet interarrival
// time, measured in RTP timestamp units. The interarrival jitter J is defined
// to be the mean deviation (smoothed absolute value) of the difference D in
// packet spacing at the receiver compared to the sender for a pair of
// packets.
uint32_t jitter() const { return jitter_; }
// Jitter converted to common time units.
TimeDelta jitter(int rtp_clock_rate_hz) const;
// Time in utc epoch (Jan 1st, 1970) the report block was received.
Timestamp report_block_timestamp_utc() const {
return report_block_timestamp_utc_;
}
// Round Trip Time measurments for given (sender_ssrc, source_ssrc) pair.
// Min, max, sum, number of measurements are since beginning of the call.
TimeDelta last_rtt() const { return last_rtt_; }
TimeDelta sum_rtts() const { return sum_rtt_; }
size_t num_rtts() const { return num_rtts_; }
bool has_rtt() const { return num_rtts_ != 0; }
void set_sender_ssrc(uint32_t ssrc) { sender_ssrc_ = ssrc; }
void set_source_ssrc(uint32_t ssrc) { source_ssrc_ = ssrc; }
void set_fraction_lost_raw(uint8_t lost) { fraction_lost_raw_ = lost; }
void set_cumulative_lost(int lost) { cumulative_lost_ = lost; }
void set_extended_highest_sequence_number(uint32_t sn) {
extended_highest_sequence_number_ = sn;
}
void set_jitter(uint32_t jitter) { jitter_ = jitter; }
void set_report_block_timestamp_utc(Timestamp arrival_time) {
report_block_timestamp_utc_ = arrival_time;
}
void SetReportBlock(uint32_t sender_ssrc,
const rtcp::ReportBlock& report_block,
Timestamp report_block_timestamp_utc);
void AddRoundTripTimeSample(TimeDelta rtt);
private:
uint32_t sender_ssrc_ = 0;
uint32_t source_ssrc_ = 0;
uint8_t fraction_lost_raw_ = 0;
int32_t cumulative_lost_ = 0;
uint32_t extended_highest_sequence_number_ = 0;
uint32_t jitter_ = 0;
Timestamp report_block_timestamp_utc_ = Timestamp::Zero();
TimeDelta last_rtt_ = TimeDelta::Zero();
TimeDelta sum_rtt_ = TimeDelta::Zero();
size_t num_rtts_ = 0;
};
class ReportBlockDataObserver {
public:
virtual ~ReportBlockDataObserver() = default;
virtual void OnReportBlockDataUpdated(ReportBlockData report_block_data) = 0;
};
} // namespace webrtc
#endif // MODULES_RTP_RTCP_INCLUDE_REPORT_BLOCK_DATA_H_

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
*
* 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.
*/
#ifndef MODULES_RTP_RTCP_INCLUDE_RTCP_STATISTICS_H_
#define MODULES_RTP_RTCP_INCLUDE_RTCP_STATISTICS_H_
#include <stdint.h>
#include "absl/strings/string_view.h"
namespace webrtc {
// Statistics for RTCP packet types.
struct RtcpPacketTypeCounter {
RtcpPacketTypeCounter()
: nack_packets(0),
fir_packets(0),
pli_packets(0),
nack_requests(0),
unique_nack_requests(0) {}
void Add(const RtcpPacketTypeCounter& other) {
nack_packets += other.nack_packets;
fir_packets += other.fir_packets;
pli_packets += other.pli_packets;
nack_requests += other.nack_requests;
unique_nack_requests += other.unique_nack_requests;
}
void Subtract(const RtcpPacketTypeCounter& other) {
nack_packets -= other.nack_packets;
fir_packets -= other.fir_packets;
pli_packets -= other.pli_packets;
nack_requests -= other.nack_requests;
unique_nack_requests -= other.unique_nack_requests;
}
int UniqueNackRequestsInPercent() const {
if (nack_requests == 0) {
return 0;
}
return static_cast<int>((unique_nack_requests * 100.0f / nack_requests) +
0.5f);
}
uint32_t nack_packets; // Number of RTCP NACK packets.
uint32_t fir_packets; // Number of RTCP FIR packets.
uint32_t pli_packets; // Number of RTCP PLI packets.
uint32_t nack_requests; // Number of NACKed RTP packets.
uint32_t unique_nack_requests; // Number of unique NACKed RTP packets.
};
class RtcpPacketTypeCounterObserver {
public:
virtual ~RtcpPacketTypeCounterObserver() {}
virtual void RtcpPacketTypesCounterUpdated(
uint32_t ssrc,
const RtcpPacketTypeCounter& packet_counter) = 0;
};
// Invoked for each cname passed in RTCP SDES blocks.
class RtcpCnameCallback {
public:
virtual ~RtcpCnameCallback() = default;
virtual void OnCname(uint32_t ssrc, absl::string_view cname) = 0;
};
} // namespace webrtc
#endif // MODULES_RTP_RTCP_INCLUDE_RTCP_STATISTICS_H_

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
*
* 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.
*/
#ifndef MODULES_RTP_RTCP_INCLUDE_RTP_CVO_H_
#define MODULES_RTP_RTCP_INCLUDE_RTP_CVO_H_
#include "api/video/video_rotation.h"
#include "rtc_base/checks.h"
namespace webrtc {
// Please refer to http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/
// 12.07.00_60/ts_126114v120700p.pdf Section 7.4.5. The rotation of a frame is
// the clockwise angle the frames must be rotated in order to display the frames
// correctly if the display is rotated in its natural orientation.
inline uint8_t ConvertVideoRotationToCVOByte(VideoRotation rotation) {
switch (rotation) {
case kVideoRotation_0:
return 0;
case kVideoRotation_90:
return 1;
case kVideoRotation_180:
return 2;
case kVideoRotation_270:
return 3;
}
RTC_DCHECK_NOTREACHED();
return 0;
}
inline VideoRotation ConvertCVOByteToVideoRotation(uint8_t cvo_byte) {
// CVO byte: |0 0 0 0 C F R R|.
const uint8_t rotation_bits = cvo_byte & 0x3;
switch (rotation_bits) {
case 0:
return kVideoRotation_0;
case 1:
return kVideoRotation_90;
case 2:
return kVideoRotation_180;
case 3:
return kVideoRotation_270;
default:
RTC_DCHECK_NOTREACHED();
return kVideoRotation_0;
}
}
} // namespace webrtc
#endif // MODULES_RTP_RTCP_INCLUDE_RTP_CVO_H_

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* 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.
*/
#ifndef MODULES_RTP_RTCP_INCLUDE_RTP_HEADER_EXTENSION_MAP_H_
#define MODULES_RTP_RTCP_INCLUDE_RTP_HEADER_EXTENSION_MAP_H_
#include <stdint.h>
#include <string>
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/rtp_parameters.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "rtc_base/checks.h"
namespace webrtc {
class RtpHeaderExtensionMap {
public:
static constexpr RTPExtensionType kInvalidType = kRtpExtensionNone;
static constexpr int kInvalidId = 0;
RtpHeaderExtensionMap();
explicit RtpHeaderExtensionMap(bool extmap_allow_mixed);
explicit RtpHeaderExtensionMap(rtc::ArrayView<const RtpExtension> extensions);
void Reset(rtc::ArrayView<const RtpExtension> extensions);
template <typename Extension>
bool Register(int id) {
return Register(id, Extension::kId, Extension::Uri());
}
bool RegisterByType(int id, RTPExtensionType type);
bool RegisterByUri(int id, absl::string_view uri);
bool IsRegistered(RTPExtensionType type) const {
return GetId(type) != kInvalidId;
}
// Return kInvalidType if not found.
RTPExtensionType GetType(int id) const;
// Return kInvalidId if not found.
uint8_t GetId(RTPExtensionType type) const {
RTC_DCHECK_GT(type, kRtpExtensionNone);
RTC_DCHECK_LT(type, kRtpExtensionNumberOfExtensions);
return ids_[type];
}
void Deregister(absl::string_view uri);
// Corresponds to the SDP attribute extmap-allow-mixed, see RFC8285.
// Set to true if it's allowed to mix one- and two-byte RTP header extensions
// in the same stream.
bool ExtmapAllowMixed() const { return extmap_allow_mixed_; }
void SetExtmapAllowMixed(bool extmap_allow_mixed) {
extmap_allow_mixed_ = extmap_allow_mixed;
}
private:
bool Register(int id, RTPExtensionType type, absl::string_view uri);
uint8_t ids_[kRtpExtensionNumberOfExtensions];
bool extmap_allow_mixed_;
};
} // namespace webrtc
#endif // MODULES_RTP_RTCP_INCLUDE_RTP_HEADER_EXTENSION_MAP_H_

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
*
* 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.
*/
#ifndef MODULES_RTP_RTCP_INCLUDE_RTP_PACKET_SENDER_H_
#define MODULES_RTP_RTCP_INCLUDE_RTP_PACKET_SENDER_H_
#include <memory>
#include <vector>
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
namespace webrtc {
class RtpPacketSender {
public:
virtual ~RtpPacketSender() = default;
// Insert a set of packets into queue, for eventual transmission. Based on the
// type of packets, they will be prioritized and scheduled relative to other
// packets and the current target send rate.
virtual void EnqueuePackets(
std::vector<std::unique_ptr<RtpPacketToSend>> packets) = 0;
// Clear any pending packets with the given SSRC from the queue.
// TODO(crbug.com/1395081): Make pure virtual when downstream code has been
// updated.
virtual void RemovePacketsForSsrc(uint32_t ssrc) {}
};
} // namespace webrtc
#endif // MODULES_RTP_RTCP_INCLUDE_RTP_PACKET_SENDER_H_

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* 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.
*/
#ifndef MODULES_RTP_RTCP_INCLUDE_RTP_RTCP_H_
#define MODULES_RTP_RTCP_INCLUDE_RTP_RTCP_H_
#include <memory>
#include "absl/base/attributes.h"
#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h"
namespace webrtc {
class ABSL_DEPRECATED("") RtpRtcp : public RtpRtcpInterface {
public:
// Instantiates a deprecated version of the RtpRtcp module.
static std::unique_ptr<RtpRtcp> ABSL_DEPRECATED("")
Create(const Configuration& configuration) {
return DEPRECATED_Create(configuration);
}
static std::unique_ptr<RtpRtcp> DEPRECATED_Create(
const Configuration& configuration);
// Process any pending tasks such as timeouts.
virtual void Process() = 0;
};
} // namespace webrtc
#endif // MODULES_RTP_RTCP_INCLUDE_RTP_RTCP_H_

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
*
* 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.
*/
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include <string.h>
#include <type_traits>
#include "absl/algorithm/container.h"
#include "api/array_view.h"
#include "modules/rtp_rtcp/source/rtp_packet.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
namespace webrtc {
namespace {
constexpr size_t kMidRsidMaxSize = 16;
// Check if passed character is a "token-char" from RFC 4566.
// https://datatracker.ietf.org/doc/html/rfc4566#section-9
// token-char = %x21 / %x23-27 / %x2A-2B / %x2D-2E / %x30-39
// / %x41-5A / %x5E-7E
bool IsTokenChar(char ch) {
return ch == 0x21 || (ch >= 0x23 && ch <= 0x27) || ch == 0x2a || ch == 0x2b ||
ch == 0x2d || ch == 0x2e || (ch >= 0x30 && ch <= 0x39) ||
(ch >= 0x41 && ch <= 0x5a) || (ch >= 0x5e && ch <= 0x7e);
}
} // namespace
bool IsLegalMidName(absl::string_view name) {
return (name.size() <= kMidRsidMaxSize && !name.empty() &&
absl::c_all_of(name, IsTokenChar));
}
bool IsLegalRsidName(absl::string_view name) {
return (name.size() <= kMidRsidMaxSize && !name.empty() &&
absl::c_all_of(name, isalnum));
}
StreamDataCounters::StreamDataCounters() = default;
RtpPacketCounter::RtpPacketCounter(const RtpPacket& packet)
: header_bytes(packet.headers_size()),
payload_bytes(packet.payload_size()),
padding_bytes(packet.padding_size()),
packets(1) {}
RtpPacketCounter::RtpPacketCounter(const RtpPacketToSend& packet_to_send)
: RtpPacketCounter(static_cast<const RtpPacket&>(packet_to_send)) {
total_packet_delay =
packet_to_send.time_in_send_queue().value_or(TimeDelta::Zero());
}
void RtpPacketCounter::AddPacket(const RtpPacket& packet) {
++packets;
header_bytes += packet.headers_size();
padding_bytes += packet.padding_size();
payload_bytes += packet.payload_size();
}
void RtpPacketCounter::AddPacket(const RtpPacketToSend& packet_to_send) {
AddPacket(static_cast<const RtpPacket&>(packet_to_send));
total_packet_delay +=
packet_to_send.time_in_send_queue().value_or(TimeDelta::Zero());
}
} // namespace webrtc

View file

@ -0,0 +1,420 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* 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.
*/
#ifndef MODULES_RTP_RTCP_INCLUDE_RTP_RTCP_DEFINES_H_
#define MODULES_RTP_RTCP_INCLUDE_RTP_RTCP_DEFINES_H_
#include <stddef.h>
#include <memory>
#include <vector>
#include "absl/algorithm/container.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#include "api/array_view.h"
#include "api/audio_codecs/audio_format.h"
#include "api/rtp_headers.h"
#include "api/transport/network_types.h"
#include "api/units/data_rate.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "modules/rtp_rtcp/include/report_block_data.h"
#include "modules/rtp_rtcp/source/rtcp_packet/remote_estimate.h"
#include "system_wrappers/include/clock.h"
#define RTCP_CNAME_SIZE 256 // RFC 3550 page 44, including null termination
#define IP_PACKET_SIZE 1500 // we assume ethernet
namespace webrtc {
class RtpPacket;
class RtpPacketToSend;
namespace rtcp {
class TransportFeedback;
}
const int kVideoPayloadTypeFrequency = 90000;
// TODO(bugs.webrtc.org/6458): Remove this when all the depending projects are
// updated to correctly set rtp rate for RtcpSender.
const int kBogusRtpRateForAudioRtcp = 8000;
// Minimum RTP header size in bytes.
const uint8_t kRtpHeaderSize = 12;
bool IsLegalMidName(absl::string_view name);
bool IsLegalRsidName(absl::string_view name);
// This enum must not have any gaps, i.e., all integers between
// kRtpExtensionNone and kRtpExtensionNumberOfExtensions must be valid enum
// entries.
enum RTPExtensionType : int {
kRtpExtensionNone,
kRtpExtensionTransmissionTimeOffset,
kRtpExtensionAudioLevel,
kRtpExtensionCsrcAudioLevel,
kRtpExtensionInbandComfortNoise,
kRtpExtensionAbsoluteSendTime,
kRtpExtensionAbsoluteCaptureTime,
kRtpExtensionVideoRotation,
kRtpExtensionTransportSequenceNumber,
kRtpExtensionTransportSequenceNumber02,
kRtpExtensionPlayoutDelay,
kRtpExtensionVideoContentType,
kRtpExtensionVideoLayersAllocation,
kRtpExtensionVideoTiming,
kRtpExtensionRtpStreamId,
kRtpExtensionRepairedRtpStreamId,
kRtpExtensionMid,
kRtpExtensionGenericFrameDescriptor,
kRtpExtensionGenericFrameDescriptor00 [[deprecated]] =
kRtpExtensionGenericFrameDescriptor,
kRtpExtensionDependencyDescriptor,
kRtpExtensionGenericFrameDescriptor02 [[deprecated]] =
kRtpExtensionDependencyDescriptor,
kRtpExtensionColorSpace,
kRtpExtensionVideoFrameTrackingId,
kRtpExtensionNumberOfExtensions // Must be the last entity in the enum.
};
enum RTCPAppSubTypes { kAppSubtypeBwe = 0x00 };
// TODO(sprang): Make this an enum class once rtcp_receiver has been cleaned up.
enum RTCPPacketType : uint32_t {
kRtcpReport = 0x0001,
kRtcpSr = 0x0002,
kRtcpRr = 0x0004,
kRtcpSdes = 0x0008,
kRtcpBye = 0x0010,
kRtcpPli = 0x0020,
kRtcpNack = 0x0040,
kRtcpFir = 0x0080,
kRtcpTmmbr = 0x0100,
kRtcpTmmbn = 0x0200,
kRtcpSrReq = 0x0400,
kRtcpLossNotification = 0x2000,
kRtcpRemb = 0x10000,
kRtcpTransmissionTimeOffset = 0x20000,
kRtcpXrReceiverReferenceTime = 0x40000,
kRtcpXrDlrrReportBlock = 0x80000,
kRtcpTransportFeedback = 0x100000,
kRtcpXrTargetBitrate = 0x200000
};
enum class KeyFrameReqMethod : uint8_t {
kNone, // Don't request keyframes.
kPliRtcp, // Request keyframes through Picture Loss Indication.
kFirRtcp // Request keyframes through Full Intra-frame Request.
};
enum RtxMode {
kRtxOff = 0x0,
kRtxRetransmitted = 0x1, // Only send retransmissions over RTX.
kRtxRedundantPayloads = 0x2 // Preventively send redundant payloads
// instead of padding.
};
const size_t kRtxHeaderSize = 2;
struct RtpState {
uint16_t sequence_number = 0;
uint32_t start_timestamp = 0;
uint32_t timestamp = 0;
Timestamp capture_time = Timestamp::MinusInfinity();
Timestamp last_timestamp_time = Timestamp::MinusInfinity();
bool ssrc_has_acked = false;
};
class RtcpIntraFrameObserver {
public:
virtual ~RtcpIntraFrameObserver() {}
virtual void OnReceivedIntraFrameRequest(uint32_t ssrc) = 0;
};
// Observer for incoming LossNotification RTCP messages.
// See the documentation of LossNotification for details.
class RtcpLossNotificationObserver {
public:
virtual ~RtcpLossNotificationObserver() = default;
virtual void OnReceivedLossNotification(uint32_t ssrc,
uint16_t seq_num_of_last_decodable,
uint16_t seq_num_of_last_received,
bool decodability_flag) = 0;
};
// Interface to watch incoming rtcp packets related to the link in general.
// All message handlers have default empty implementation. This way users only
// need to implement the ones they are interested in.
// All message handles pass `receive_time` parameter, which is receive time
// of the rtcp packet that triggered the update.
class NetworkLinkRtcpObserver {
public:
virtual ~NetworkLinkRtcpObserver() = default;
virtual void OnTransportFeedback(Timestamp receive_time,
const rtcp::TransportFeedback& feedback) {}
virtual void OnReceiverEstimatedMaxBitrate(Timestamp receive_time,
DataRate bitrate) {}
// Called on an RTCP packet with sender or receiver reports with non zero
// report blocks. Report blocks are combined from all reports into one array.
virtual void OnReport(Timestamp receive_time,
rtc::ArrayView<const ReportBlockData> report_blocks) {}
virtual void OnRttUpdate(Timestamp receive_time, TimeDelta rtt) {}
};
// NOTE! `kNumMediaTypes` must be kept in sync with RtpPacketMediaType!
static constexpr size_t kNumMediaTypes = 5;
enum class RtpPacketMediaType : size_t {
kAudio, // Audio media packets.
kVideo, // Video media packets.
kRetransmission, // Retransmisions, sent as response to NACK.
kForwardErrorCorrection, // FEC packets.
kPadding = kNumMediaTypes - 1, // RTX or plain padding sent to maintain BWE.
// Again, don't forget to update `kNumMediaTypes` if you add another value!
};
struct RtpPacketSendInfo {
uint16_t transport_sequence_number = 0;
absl::optional<uint32_t> media_ssrc;
uint16_t rtp_sequence_number = 0; // Only valid if `media_ssrc` is set.
uint32_t rtp_timestamp = 0;
size_t length = 0;
absl::optional<RtpPacketMediaType> packet_type;
PacedPacketInfo pacing_info;
};
class NetworkStateEstimateObserver {
public:
virtual void OnRemoteNetworkEstimate(NetworkStateEstimate estimate) = 0;
virtual ~NetworkStateEstimateObserver() = default;
};
class TransportFeedbackObserver {
public:
virtual ~TransportFeedbackObserver() = default;
virtual void OnAddPacket(const RtpPacketSendInfo& packet_info) = 0;
};
// Interface for PacketRouter to send rtcp feedback on behalf of
// congestion controller.
// TODO(bugs.webrtc.org/8239): Remove and use RtcpTransceiver directly
// when RtcpTransceiver always present in rtp transport.
class RtcpFeedbackSenderInterface {
public:
virtual ~RtcpFeedbackSenderInterface() = default;
virtual void SendCombinedRtcpPacket(
std::vector<std::unique_ptr<rtcp::RtcpPacket>> rtcp_packets) = 0;
virtual void SetRemb(int64_t bitrate_bps, std::vector<uint32_t> ssrcs) = 0;
virtual void UnsetRemb() = 0;
};
class StreamFeedbackObserver {
public:
struct StreamPacketInfo {
bool received;
// `rtp_sequence_number` and `is_retransmission` are only valid if `ssrc`
// is populated.
absl::optional<uint32_t> ssrc;
uint16_t rtp_sequence_number;
bool is_retransmission;
};
virtual ~StreamFeedbackObserver() = default;
virtual void OnPacketFeedbackVector(
std::vector<StreamPacketInfo> packet_feedback_vector) = 0;
};
class StreamFeedbackProvider {
public:
virtual void RegisterStreamFeedbackObserver(
std::vector<uint32_t> ssrcs,
StreamFeedbackObserver* observer) = 0;
virtual void DeRegisterStreamFeedbackObserver(
StreamFeedbackObserver* observer) = 0;
virtual ~StreamFeedbackProvider() = default;
};
class RtcpRttStats {
public:
virtual void OnRttUpdate(int64_t rtt) = 0;
virtual int64_t LastProcessedRtt() const = 0;
virtual ~RtcpRttStats() {}
};
struct RtpPacketCounter {
RtpPacketCounter()
: header_bytes(0), payload_bytes(0), padding_bytes(0), packets(0) {}
explicit RtpPacketCounter(const RtpPacket& packet);
explicit RtpPacketCounter(const RtpPacketToSend& packet_to_send);
void Add(const RtpPacketCounter& other) {
header_bytes += other.header_bytes;
payload_bytes += other.payload_bytes;
padding_bytes += other.padding_bytes;
packets += other.packets;
total_packet_delay += other.total_packet_delay;
}
bool operator==(const RtpPacketCounter& other) const {
return header_bytes == other.header_bytes &&
payload_bytes == other.payload_bytes &&
padding_bytes == other.padding_bytes && packets == other.packets &&
total_packet_delay == other.total_packet_delay;
}
// Not inlined, since use of RtpPacket would result in circular includes.
void AddPacket(const RtpPacket& packet);
void AddPacket(const RtpPacketToSend& packet_to_send);
size_t TotalBytes() const {
return header_bytes + payload_bytes + padding_bytes;
}
size_t header_bytes; // Number of bytes used by RTP headers.
size_t payload_bytes; // Payload bytes, excluding RTP headers and padding.
size_t padding_bytes; // Number of padding bytes.
size_t packets; // Number of packets.
// The total delay of all `packets`. For RtpPacketToSend packets, this is
// `time_in_send_queue()`. For receive packets, this is zero.
webrtc::TimeDelta total_packet_delay = webrtc::TimeDelta::Zero();
};
// Data usage statistics for a (rtp) stream.
struct StreamDataCounters {
StreamDataCounters();
void Add(const StreamDataCounters& other) {
transmitted.Add(other.transmitted);
retransmitted.Add(other.retransmitted);
fec.Add(other.fec);
if (other.first_packet_time < first_packet_time) {
// Use oldest time (excluding unsed value represented as plus infinity.
first_packet_time = other.first_packet_time;
}
}
void MaybeSetFirstPacketTime(Timestamp now) {
if (first_packet_time == Timestamp::PlusInfinity()) {
first_packet_time = now;
}
}
// Return time since first packet is send/received, or zero if such event
// haven't happen.
TimeDelta TimeSinceFirstPacket(Timestamp now) const {
return first_packet_time == Timestamp::PlusInfinity()
? TimeDelta::Zero()
: now - first_packet_time;
}
// Returns the number of bytes corresponding to the actual media payload (i.e.
// RTP headers, padding, retransmissions and fec packets are excluded).
// Note this function does not have meaning for an RTX stream.
size_t MediaPayloadBytes() const {
return transmitted.payload_bytes - retransmitted.payload_bytes -
fec.payload_bytes;
}
// Time when first packet is sent/received.
Timestamp first_packet_time = Timestamp::PlusInfinity();
RtpPacketCounter transmitted; // Number of transmitted packets/bytes.
RtpPacketCounter retransmitted; // Number of retransmitted packets/bytes.
RtpPacketCounter fec; // Number of redundancy packets/bytes.
};
class RtpSendRates {
template <std::size_t... Is>
constexpr std::array<DataRate, sizeof...(Is)> make_zero_array(
std::index_sequence<Is...>) {
return {{(static_cast<void>(Is), DataRate::Zero())...}};
}
public:
RtpSendRates()
: send_rates_(
make_zero_array(std::make_index_sequence<kNumMediaTypes>())) {}
RtpSendRates(const RtpSendRates& rhs) = default;
RtpSendRates& operator=(const RtpSendRates&) = default;
DataRate& operator[](RtpPacketMediaType type) {
return send_rates_[static_cast<size_t>(type)];
}
const DataRate& operator[](RtpPacketMediaType type) const {
return send_rates_[static_cast<size_t>(type)];
}
DataRate Sum() const {
return absl::c_accumulate(send_rates_, DataRate::Zero());
}
private:
std::array<DataRate, kNumMediaTypes> send_rates_;
};
// Callback, called whenever byte/packet counts have been updated.
class StreamDataCountersCallback {
public:
virtual ~StreamDataCountersCallback() {}
virtual void DataCountersUpdated(const StreamDataCounters& counters,
uint32_t ssrc) = 0;
};
// Information exposed through the GetStats api.
struct RtpReceiveStats {
// `packets_lost` and `jitter` are defined by RFC 3550, and exposed in the
// RTCReceivedRtpStreamStats dictionary, see
// https://w3c.github.io/webrtc-stats/#receivedrtpstats-dict*
int32_t packets_lost = 0;
// Interarrival jitter in samples.
uint32_t jitter = 0;
// Interarrival jitter in time.
webrtc::TimeDelta interarrival_jitter = webrtc::TimeDelta::Zero();
// Time of the last packet received in unix epoch,
// i.e. Timestamp::Zero() represents 1st Jan 1970 00:00
absl::optional<Timestamp> last_packet_received;
// Counters exposed in RTCInboundRtpStreamStats, see
// https://w3c.github.io/webrtc-stats/#inboundrtpstats-dict*
RtpPacketCounter packet_counter;
};
// Callback, used to notify an observer whenever new rates have been estimated.
class BitrateStatisticsObserver {
public:
virtual ~BitrateStatisticsObserver() {}
virtual void Notify(uint32_t total_bitrate_bps,
uint32_t retransmit_bitrate_bps,
uint32_t ssrc) = 0;
};
// Callback, used to notify an observer whenever a packet is sent to the
// transport.
class SendPacketObserver {
public:
virtual ~SendPacketObserver() = default;
virtual void OnSendPacket(absl::optional<uint16_t> packet_id,
Timestamp capture_time,
uint32_t ssrc) = 0;
};
} // namespace webrtc
#endif // MODULES_RTP_RTCP_INCLUDE_RTP_RTCP_DEFINES_H_