From ea592f5a5885d5f85dd82053d01a6047e7435e03 Mon Sep 17 00:00:00 2001 From: dijunkun Date: Tue, 21 Jan 2025 17:30:00 +0800 Subject: [PATCH] [fix] fix crash due to rtp extension --- src/channel/rtp_channel/rtp_audio_sender.cpp | 2 +- src/channel/rtp_channel/rtp_data_receiver.cpp | 2 +- src/channel/rtp_channel/rtp_data_sender.cpp | 2 +- .../rtp_channel/rtp_video_receiver.cpp | 2 +- src/channel/rtp_channel/rtp_video_sender.cpp | 2 +- src/channel/video_channel_send.h | 1 + src/common/api/transport/network_types.cc | 107 ++++++ src/common/network_route.h | 97 ------ src/common/rtc_base/arraysize.h | 32 ++ src/common/rtc_base/byte_order.h | 199 +++++++++++ .../rtc_base/numerics/safe_conversions_impl.h | 8 +- src/common/rtc_base/rate_statistics.cc | 1 + src/common/rtc_base/system/arch.h | 100 ++++++ src/common/rtc_base/system_time.cc | 22 +- src/common/rtc_base/time_utils.cc | 17 +- src/common/rtc_base/win32.cc | 309 ++++++++++++++++++ src/common/rtc_base/win32.h | 48 +++ .../decode/nvcodec/nvidia_video_decoder.cpp | 8 +- .../encode/nvcodec/nvidia_video_encoder.cpp | 2 +- src/qos/bwe_defines.cc | 24 ++ src/qos/clock.cc | 5 + src/qos/ntp_time_util.cc | 59 ++++ src/rtp/rtp_packet/rtp_codec.cpp | 32 ++ src/rtp/rtp_packet/rtp_packet.cpp | 2 +- src/rtp/rtp_packet/rtp_packet.h | 15 +- src/transport/ice_transport.cpp | 20 +- src/transport/ice_transport.h | 2 +- xmake.lua | 5 +- 28 files changed, 981 insertions(+), 144 deletions(-) create mode 100644 src/common/api/transport/network_types.cc delete mode 100644 src/common/network_route.h create mode 100644 src/common/rtc_base/arraysize.h create mode 100644 src/common/rtc_base/byte_order.h create mode 100644 src/common/rtc_base/system/arch.h create mode 100644 src/common/rtc_base/win32.cc create mode 100644 src/common/rtc_base/win32.h create mode 100644 src/qos/bwe_defines.cc create mode 100644 src/qos/ntp_time_util.cc diff --git a/src/channel/rtp_channel/rtp_audio_sender.cpp b/src/channel/rtp_channel/rtp_audio_sender.cpp index 2e37954..b24ba38 100644 --- a/src/channel/rtp_channel/rtp_audio_sender.cpp +++ b/src/channel/rtp_channel/rtp_audio_sender.cpp @@ -90,7 +90,7 @@ int RtpAudioSender::SendRtpPacket(RtpPacket& rtp_packet) { rtcp_sr.Encode(); - SendRtcpSR(rtcp_sr); + // SendRtcpSR(rtcp_sr); } return 0; diff --git a/src/channel/rtp_channel/rtp_data_receiver.cpp b/src/channel/rtp_channel/rtp_data_receiver.cpp index 391bf28..efc366d 100644 --- a/src/channel/rtp_channel/rtp_data_receiver.cpp +++ b/src/channel/rtp_channel/rtp_data_receiver.cpp @@ -60,7 +60,7 @@ void RtpDataReceiver::InsertRtpPacket(RtpPacket& rtp_packet) { rtcp_rr.Encode(); - SendRtcpRR(rtcp_rr); + // SendRtcpRR(rtcp_rr); } if (on_receive_data_) { diff --git a/src/channel/rtp_channel/rtp_data_sender.cpp b/src/channel/rtp_channel/rtp_data_sender.cpp index e0063cf..15bea07 100644 --- a/src/channel/rtp_channel/rtp_data_sender.cpp +++ b/src/channel/rtp_channel/rtp_data_sender.cpp @@ -90,7 +90,7 @@ int RtpDataSender::SendRtpPacket(RtpPacket& rtp_packet) { rtcp_sr.Encode(); - SendRtcpSR(rtcp_sr); + // SendRtcpSR(rtcp_sr); } return 0; diff --git a/src/channel/rtp_channel/rtp_video_receiver.cpp b/src/channel/rtp_channel/rtp_video_receiver.cpp index ac5503d..fa625be 100644 --- a/src/channel/rtp_channel/rtp_video_receiver.cpp +++ b/src/channel/rtp_channel/rtp_video_receiver.cpp @@ -107,7 +107,7 @@ void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) { rtcp_rr.Encode(); - SendRtcpRR(rtcp_rr); + // SendRtcpRR(rtcp_rr); } if (rtp_packet.PayloadType() == RtpPacket::PAYLOAD_TYPE::AV1) { ProcessAv1RtpPacket(rtp_packet); diff --git a/src/channel/rtp_channel/rtp_video_sender.cpp b/src/channel/rtp_channel/rtp_video_sender.cpp index 7e3e20f..487b333 100644 --- a/src/channel/rtp_channel/rtp_video_sender.cpp +++ b/src/channel/rtp_channel/rtp_video_sender.cpp @@ -86,7 +86,7 @@ int RtpVideoSender::SendRtpPacket(RtpPacket& rtp_packet) { report.lsr = 0; report.dlsr = 0; - rtcp_sr.SetReportBlock(report); + // rtcp_sr.SetReportBlock(report); rtcp_sr.Encode(); diff --git a/src/channel/video_channel_send.h b/src/channel/video_channel_send.h index bb7b673..225fae7 100644 --- a/src/channel/video_channel_send.h +++ b/src/channel/video_channel_send.h @@ -11,6 +11,7 @@ #include "ice_agent.h" #include "rtp_codec.h" #include "rtp_video_sender.h" +#include "transport_feedback.h" #include "transport_feedback_adapter.h" class VideoChannelSend { diff --git a/src/common/api/transport/network_types.cc b/src/common/api/transport/network_types.cc new file mode 100644 index 0000000..ccb4a6e --- /dev/null +++ b/src/common/api/transport/network_types.cc @@ -0,0 +1,107 @@ +/* + * 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. + */ + +#include "api/transport/network_types.h" + +#include +#include + +namespace webrtc { +StreamsConfig::StreamsConfig() = default; +StreamsConfig::StreamsConfig(const StreamsConfig&) = default; +StreamsConfig::~StreamsConfig() = default; + +TargetRateConstraints::TargetRateConstraints() = default; +TargetRateConstraints::TargetRateConstraints(const TargetRateConstraints&) = + default; +TargetRateConstraints::~TargetRateConstraints() = default; + +NetworkRouteChange::NetworkRouteChange() = default; +NetworkRouteChange::NetworkRouteChange(const NetworkRouteChange&) = default; +NetworkRouteChange::~NetworkRouteChange() = default; + +PacketResult::PacketResult() = default; +PacketResult::PacketResult(const PacketResult& other) = default; +PacketResult::~PacketResult() = default; + +bool PacketResult::ReceiveTimeOrder::operator()(const PacketResult& lhs, + const PacketResult& rhs) { + if (lhs.receive_time != rhs.receive_time) + return lhs.receive_time < rhs.receive_time; + if (lhs.sent_packet.send_time != rhs.sent_packet.send_time) + return lhs.sent_packet.send_time < rhs.sent_packet.send_time; + return lhs.sent_packet.sequence_number < rhs.sent_packet.sequence_number; +} + +TransportPacketsFeedback::TransportPacketsFeedback() = default; +TransportPacketsFeedback::TransportPacketsFeedback( + const TransportPacketsFeedback& other) = default; +TransportPacketsFeedback::~TransportPacketsFeedback() = default; + +std::vector TransportPacketsFeedback::ReceivedWithSendInfo() + const { + std::vector res; + for (const PacketResult& fb : packet_feedbacks) { + if (fb.IsReceived()) { + res.push_back(fb); + } + } + return res; +} + +std::vector TransportPacketsFeedback::LostWithSendInfo() const { + std::vector res; + for (const PacketResult& fb : packet_feedbacks) { + if (!fb.IsReceived()) { + res.push_back(fb); + } + } + return res; +} + +std::vector TransportPacketsFeedback::PacketsWithFeedback() + const { + return packet_feedbacks; +} + +std::vector TransportPacketsFeedback::SortedByReceiveTime() + const { + std::vector res; + for (const PacketResult& fb : packet_feedbacks) { + if (fb.IsReceived()) { + res.push_back(fb); + } + } + std::sort(res.begin(), res.end(), PacketResult::ReceiveTimeOrder()); + return res; +} + +NetworkControlUpdate::NetworkControlUpdate() = default; +NetworkControlUpdate::NetworkControlUpdate(const NetworkControlUpdate&) = + default; +NetworkControlUpdate::~NetworkControlUpdate() = default; + +PacedPacketInfo::PacedPacketInfo() = default; + +PacedPacketInfo::PacedPacketInfo(int probe_cluster_id, + int probe_cluster_min_probes, + int probe_cluster_min_bytes) + : probe_cluster_id(probe_cluster_id), + probe_cluster_min_probes(probe_cluster_min_probes), + probe_cluster_min_bytes(probe_cluster_min_bytes) {} + +bool PacedPacketInfo::operator==(const PacedPacketInfo& rhs) const { + return send_bitrate == rhs.send_bitrate && + probe_cluster_id == rhs.probe_cluster_id && + probe_cluster_min_probes == rhs.probe_cluster_min_probes && + probe_cluster_min_bytes == rhs.probe_cluster_min_bytes; +} + +} // namespace webrtc diff --git a/src/common/network_route.h b/src/common/network_route.h deleted file mode 100644 index 6a08132..0000000 --- a/src/common/network_route.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * @Author: DI JUNKUN - * @Date: 2025-01-13 - * Copyright (c) 2025 by DI JUNKUN, All Rights Reserved. - */ - -#ifndef _NETWORK_ROUTE_H_ -#define _NETWORK_ROUTE_H_ - -#include -#include - -struct NetworkRoute; - -class RouteEndpoint { - public: - enum AdapterType { - // This enum resembles the one in Chromium net::ConnectionType. - ADAPTER_TYPE_UNKNOWN = 0, - ADAPTER_TYPE_ETHERNET = 1 << 0, - ADAPTER_TYPE_WIFI = 1 << 1, - ADAPTER_TYPE_CELLULAR = 1 << 2, // This is CELLULAR of unknown type. - ADAPTER_TYPE_VPN = 1 << 3, - ADAPTER_TYPE_LOOPBACK = 1 << 4, - // ADAPTER_TYPE_ANY is used for a network, which only contains a single "any - // address" IP address (INADDR_ANY for IPv4 or in6addr_any for IPv6), and - // can - // use any/all network interfaces. Whereas ADAPTER_TYPE_UNKNOWN is used - // when the network uses a specific interface/IP, but its interface type can - // not be determined or not fit in this enum. - ADAPTER_TYPE_ANY = 1 << 5, - ADAPTER_TYPE_CELLULAR_2G = 1 << 6, - ADAPTER_TYPE_CELLULAR_3G = 1 << 7, - ADAPTER_TYPE_CELLULAR_4G = 1 << 8, - ADAPTER_TYPE_CELLULAR_5G = 1 << 9 - }; - - public: - RouteEndpoint() {} // Used by tests. - RouteEndpoint(AdapterType adapter_type, uint16_t adapter_id, - uint16_t network_id, bool uses_turn) - : adapter_type_(adapter_type), - adapter_id_(adapter_id), - network_id_(network_id), - uses_turn_(uses_turn) {} - - RouteEndpoint(const RouteEndpoint&) = default; - RouteEndpoint& operator=(const RouteEndpoint&) = default; - - bool operator==(const RouteEndpoint& other) const { - return adapter_type_ == other.adapter_type_ && - adapter_id_ == other.adapter_id_ && - network_id_ == other.network_id_ && uses_turn_ == other.uses_turn_; - } - - // Used by tests. - static RouteEndpoint CreateWithNetworkId(uint16_t network_id) { - return RouteEndpoint(ADAPTER_TYPE_UNKNOWN, - /* adapter_id = */ 0, network_id, - /* uses_turn = */ false); - } - RouteEndpoint CreateWithTurn(bool uses_turn) const { - return RouteEndpoint(adapter_type_, adapter_id_, network_id_, uses_turn); - } - - AdapterType adapter_type() const { return adapter_type_; } - uint16_t adapter_id() const { return adapter_id_; } - uint16_t network_id() const { return network_id_; } - bool uses_turn() const { return uses_turn_; } - - private: - AdapterType adapter_type_ = ADAPTER_TYPE_UNKNOWN; - uint16_t adapter_id_ = 0; - uint16_t network_id_ = 0; - bool uses_turn_ = false; -}; - -struct NetworkRoute { - bool connected = false; - RouteEndpoint local; - RouteEndpoint remote; - // Last packet id sent on the PREVIOUS route. - int last_sent_packet_id = -1; - // The overhead in bytes from IP layer and above. - // This is the maximum of any part of the route. - int packet_overhead = 0; - - bool operator==(const NetworkRoute& other) const { - return connected == other.connected && local == other.local && - remote == other.remote && packet_overhead == other.packet_overhead && - last_sent_packet_id == other.last_sent_packet_id; - } - - bool operator!=(const NetworkRoute& other) { return !operator==(other); } -}; - -#endif \ No newline at end of file diff --git a/src/common/rtc_base/arraysize.h b/src/common/rtc_base/arraysize.h new file mode 100644 index 0000000..bf8e6d8 --- /dev/null +++ b/src/common/rtc_base/arraysize.h @@ -0,0 +1,32 @@ +/* + * 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 RTC_BASE_ARRAYSIZE_H_ +#define RTC_BASE_ARRAYSIZE_H_ + +#include + +// This file defines the arraysize() macro and is derived from Chromium's +// base/macros.h. + +// The arraysize(arr) macro returns the # of elements in an array arr. +// The expression is a compile-time constant, and therefore can be +// used in defining new arrays, for example. If you use arraysize on +// a pointer by mistake, you will get a compile-time error. + +// This template function declaration is used in defining arraysize. +// Note that the function doesn't need an implementation, as we only +// use its type. +template +char (&ArraySizeHelper(T (&array)[N]))[N]; + +#define arraysize(array) (sizeof(ArraySizeHelper(array))) + +#endif // RTC_BASE_ARRAYSIZE_H_ diff --git a/src/common/rtc_base/byte_order.h b/src/common/rtc_base/byte_order.h new file mode 100644 index 0000000..91a9494 --- /dev/null +++ b/src/common/rtc_base/byte_order.h @@ -0,0 +1,199 @@ +/* + * Copyright 2004 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 RTC_BASE_BYTE_ORDER_H_ +#define RTC_BASE_BYTE_ORDER_H_ + +#include + +#include + +#if defined(__POSIX__) && !defined(__native_client__) +#include +#endif + +#include "rtc_base/system/arch.h" + +#if defined(__APPLE__) +#include + +#define htobe16(v) OSSwapHostToBigInt16(v) +#define htobe32(v) OSSwapHostToBigInt32(v) +#define htobe64(v) OSSwapHostToBigInt64(v) +#define be16toh(v) OSSwapBigToHostInt16(v) +#define be32toh(v) OSSwapBigToHostInt32(v) +#define be64toh(v) OSSwapBigToHostInt64(v) + +#define htole16(v) OSSwapHostToLittleInt16(v) +#define htole32(v) OSSwapHostToLittleInt32(v) +#define htole64(v) OSSwapHostToLittleInt64(v) +#define le16toh(v) OSSwapLittleToHostInt16(v) +#define le32toh(v) OSSwapLittleToHostInt32(v) +#define le64toh(v) OSSwapLittleToHostInt64(v) + +#elif defined(_WIN32) || defined(__native_client__) +#if defined(_WIN32) +#include +#include +#else +#include // no-presubmit-check +#endif // defined(_WIN32) + +#if defined(WEBRTC_ARCH_LITTLE_ENDIAN) +#define htobe16(v) htons(v) +#define htobe32(v) htonl(v) +#define be16toh(v) ntohs(v) +#define be32toh(v) ntohl(v) +#define htole16(v) (v) +#define htole32(v) (v) +#define htole64(v) (v) +#define le16toh(v) (v) +#define le32toh(v) (v) +#define le64toh(v) (v) +#if defined(_WIN32) +#define htobe64(v) _byteswap_uint64(v) +#define be64toh(v) _byteswap_uint64(v) +#endif // defined(_WIN32) +#if defined(__native_client__) +#define htobe64(v) __builtin_bswap64(v) +#define be64toh(v) __builtin_bswap64(v) +#endif // defined(__native_client__) + +#elif defined(WEBRTC_ARCH_BIG_ENDIAN) +#define htobe16(v) (v) +#define htobe32(v) (v) +#define be16toh(v) (v) +#define be32toh(v) (v) +#define htole16(v) __builtin_bswap16(v) +#define htole32(v) __builtin_bswap32(v) +#define htole64(v) __builtin_bswap64(v) +#define le16toh(v) __builtin_bswap16(v) +#define le32toh(v) __builtin_bswap32(v) +#define le64toh(v) __builtin_bswap64(v) +#if defined(_WIN32) +#define htobe64(v) (v) +#define be64toh(v) (v) +#endif // defined(_WIN32) +#if defined(__native_client__) +#define htobe64(v) (v) +#define be64toh(v) (v) +#endif // defined(__native_client__) +#else +#error WEBRTC_ARCH_BIG_ENDIAN or WEBRTC_ARCH_LITTLE_ENDIAN must be defined. +#endif // defined(WEBRTC_ARCH_LITTLE_ENDIAN) + +#elif defined(__POSIX__) +#include +#else +#error "Missing byte order functions for this arch." +#endif // defined(__APPLE__) + +namespace rtc { + +// Reading and writing of little and big-endian numbers from memory + +inline void Set8(void* memory, size_t offset, uint8_t v) { + static_cast(memory)[offset] = v; +} + +inline uint8_t Get8(const void* memory, size_t offset) { + return static_cast(memory)[offset]; +} + +inline void SetBE16(void* memory, uint16_t v) { + uint16_t val = htobe16(v); + memcpy(memory, &val, sizeof(val)); +} + +inline void SetBE32(void* memory, uint32_t v) { + uint32_t val = htobe32(v); + memcpy(memory, &val, sizeof(val)); +} + +inline void SetBE64(void* memory, uint64_t v) { + uint64_t val = htobe64(v); + memcpy(memory, &val, sizeof(val)); +} + +inline uint16_t GetBE16(const void* memory) { + uint16_t val; + memcpy(&val, memory, sizeof(val)); + return be16toh(val); +} + +inline uint32_t GetBE32(const void* memory) { + uint32_t val; + memcpy(&val, memory, sizeof(val)); + return be32toh(val); +} + +inline uint64_t GetBE64(const void* memory) { + uint64_t val; + memcpy(&val, memory, sizeof(val)); + return be64toh(val); +} + +inline void SetLE16(void* memory, uint16_t v) { + uint16_t val = htole16(v); + memcpy(memory, &val, sizeof(val)); +} + +inline void SetLE32(void* memory, uint32_t v) { + uint32_t val = htole32(v); + memcpy(memory, &val, sizeof(val)); +} + +inline void SetLE64(void* memory, uint64_t v) { + uint64_t val = htole64(v); + memcpy(memory, &val, sizeof(val)); +} + +inline uint16_t GetLE16(const void* memory) { + uint16_t val; + memcpy(&val, memory, sizeof(val)); + return le16toh(val); +} + +inline uint32_t GetLE32(const void* memory) { + uint32_t val; + memcpy(&val, memory, sizeof(val)); + return le32toh(val); +} + +inline uint64_t GetLE64(const void* memory) { + uint64_t val; + memcpy(&val, memory, sizeof(val)); + return le64toh(val); +} + +// Check if the current host is big endian. +inline bool IsHostBigEndian() { +#if defined(WEBRTC_ARCH_BIG_ENDIAN) + return true; +#else + return false; +#endif +} + +inline uint16_t HostToNetwork16(uint16_t n) { return htobe16(n); } + +inline uint32_t HostToNetwork32(uint32_t n) { return htobe32(n); } + +inline uint64_t HostToNetwork64(uint64_t n) { return htobe64(n); } + +inline uint16_t NetworkToHost16(uint16_t n) { return be16toh(n); } + +inline uint32_t NetworkToHost32(uint32_t n) { return be32toh(n); } + +inline uint64_t NetworkToHost64(uint64_t n) { return be64toh(n); } + +} // namespace rtc + +#endif // RTC_BASE_BYTE_ORDER_H_ diff --git a/src/common/rtc_base/numerics/safe_conversions_impl.h b/src/common/rtc_base/numerics/safe_conversions_impl.h index fe0f0d7..e355ee4 100644 --- a/src/common/rtc_base/numerics/safe_conversions_impl.h +++ b/src/common/rtc_base/numerics/safe_conversions_impl.h @@ -14,6 +14,8 @@ #define RTC_BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ #include +#undef max +#undef min namespace rtc { namespace internal { @@ -27,8 +29,7 @@ enum DstRange { OVERLAPS_RANGE, CONTAINS_RANGE }; // Helper templates to statically determine if our destination type can contain // all values represented by the source type. -template ::is_signed ? DST_SIGNED : DST_UNSIGNED, SrcSign IsSrcSigned = @@ -85,8 +86,7 @@ enum RangeCheckResult { RangeCheckResult(((is_in_upper_bound) ? 0 : TYPE_OVERFLOW) | \ ((is_in_lower_bound) ? 0 : TYPE_UNDERFLOW)) -template ::is_signed ? DST_SIGNED : DST_UNSIGNED, SrcSign IsSrcSigned = diff --git a/src/common/rtc_base/rate_statistics.cc b/src/common/rtc_base/rate_statistics.cc index 2bb8cb5..1d110e4 100644 --- a/src/common/rtc_base/rate_statistics.cc +++ b/src/common/rtc_base/rate_statistics.cc @@ -15,6 +15,7 @@ #include #include "log.h" +#include "rtc_base/numerics/safe_compare.h" #include "rtc_base/numerics/safe_conversions.h" namespace webrtc { diff --git a/src/common/rtc_base/system/arch.h b/src/common/rtc_base/system/arch.h new file mode 100644 index 0000000..9d945ef --- /dev/null +++ b/src/common/rtc_base/system/arch.h @@ -0,0 +1,100 @@ +/* + * 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. + */ + +// This file contains platform-specific typedefs and defines. +// Much of it is derived from Chromium's build/build_config.h. + +#ifndef RTC_BASE_SYSTEM_ARCH_H_ +#define RTC_BASE_SYSTEM_ARCH_H_ + +// Processor architecture detection. For more info on what's defined, see: +// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros +// https://www.agner.org/optimize/calling_conventions.pdf +// https://sourceforge.net/p/predef/wiki/Architectures/ +// or with gcc, run: "echo | gcc -E -dM -" +#if defined(_M_X64) || defined(__x86_64__) +#define WEBRTC_ARCH_X86_FAMILY +#define WEBRTC_ARCH_X86_64 +#define WEBRTC_ARCH_64_BITS +#define WEBRTC_ARCH_LITTLE_ENDIAN +#elif defined(_M_ARM64) || defined(__aarch64__) +#define WEBRTC_ARCH_ARM_FAMILY +#define WEBRTC_ARCH_64_BITS +#define WEBRTC_ARCH_LITTLE_ENDIAN +#elif defined(_M_IX86) || defined(__i386__) +#define WEBRTC_ARCH_X86_FAMILY +#define WEBRTC_ARCH_X86 +#define WEBRTC_ARCH_32_BITS +#define WEBRTC_ARCH_LITTLE_ENDIAN +#elif defined(_M_ARM) || defined(__ARMEL__) +#define WEBRTC_ARCH_ARM_FAMILY +#define WEBRTC_ARCH_32_BITS +#define WEBRTC_ARCH_LITTLE_ENDIAN +#elif defined(__MIPSEL__) || defined(__MIPSEB__) +#define WEBRTC_ARCH_MIPS_FAMILY +#if defined(__LP64__) +#define WEBRTC_ARCH_64_BITS +#else +#define WEBRTC_ARCH_32_BITS +#endif +#if defined(__MIPSEL__) +#define WEBRTC_ARCH_LITTLE_ENDIAN +#else +#define WEBRTC_ARCH_BIG_ENDIAN +#endif +#elif defined(__PPC__) +#if defined(__PPC64__) +#define WEBRTC_ARCH_64_BITS +#else +#define WEBRTC_ARCH_32_BITS +#endif +#if defined(__LITTLE_ENDIAN__) +#define WEBRTC_ARCH_LITTLE_ENDIAN +#else +#define WEBRTC_ARCH_BIG_ENDIAN +#endif +#elif defined(__sparc) || defined(__sparc__) +#if __SIZEOF_LONG__ == 8 +#define WEBRTC_ARCH_64_BITS +#else +#define WEBRTC_ARCH_32_BITS +#endif +#define WEBRTC_ARCH_BIG_ENDIAN +#elif defined(__riscv) && __riscv_xlen == 64 +#define WEBRTC_ARCH_64_BITS +#define WEBRTC_ARCH_LITTLE_ENDIAN +#elif defined(__riscv) && __riscv_xlen == 32 +#define WEBRTC_ARCH_32_BITS +#define WEBRTC_ARCH_LITTLE_ENDIAN +#elif defined(__loongarch32) +#define WEBRTC_ARCH_LOONG_FAMILY +#define WEBRTC_ARCH_LOONG32 +#define WEBRTC_ARCH_32_BITS +#define WEBRTC_ARCH_LITTLE_ENDIAN +#elif defined(__loongarch64) +#define WEBRTC_ARCH_LOONG_FAMILY +#define WEBRTC_ARCH_LOONG64 +#define WEBRTC_ARCH_64_BITS +#define WEBRTC_ARCH_LITTLE_ENDIAN +#elif defined(__pnacl__) +#define WEBRTC_ARCH_32_BITS +#define WEBRTC_ARCH_LITTLE_ENDIAN +#elif defined(__EMSCRIPTEN__) +#define WEBRTC_ARCH_32_BITS +#define WEBRTC_ARCH_LITTLE_ENDIAN +#else +#error Please add support for your architecture in rtc_base/system/arch.h +#endif + +#if !(defined(WEBRTC_ARCH_LITTLE_ENDIAN) ^ defined(WEBRTC_ARCH_BIG_ENDIAN)) +#error Define either WEBRTC_ARCH_LITTLE_ENDIAN or WEBRTC_ARCH_BIG_ENDIAN +#endif + +#endif // RTC_BASE_SYSTEM_ARCH_H_ diff --git a/src/common/rtc_base/system_time.cc b/src/common/rtc_base/system_time.cc index 65ddca4..6ae171b 100644 --- a/src/common/rtc_base/system_time.cc +++ b/src/common/rtc_base/system_time.cc @@ -16,14 +16,14 @@ #include -#if defined(WEBRTC_POSIX) +#if defined(__POSIX__) #include -#if defined(WEBRTC_MAC) +#if defined(__APPLE__) #include #endif #endif -#if defined(WEBRTC_WIN) +#if defined(_WIN32) // clang-format off // clang formatting would put last, // which leads to compilation failure. @@ -41,7 +41,7 @@ namespace rtc { int64_t SystemTimeNanos() { int64_t ticks; -#if defined(WEBRTC_MAC) +#if defined(__APPLE__) static mach_timebase_info_data_t timebase; if (timebase.denom == 0) { // Get the timebase if this is the first time we run. @@ -54,7 +54,7 @@ int64_t SystemTimeNanos() { return rtc::dchecked_cast(a * b); }; ticks = mul(mach_absolute_time(), timebase.numer) / timebase.denom; -#elif defined(WEBRTC_POSIX) +#elif defined(__POSIX__) struct timespec ts; // TODO(deadbeef): Do we need to handle the case when CLOCK_MONOTONIC is not // supported? @@ -63,11 +63,13 @@ int64_t SystemTimeNanos() { static_cast(ts.tv_nsec); #elif defined(WINUWP) ticks = WinUwpSystemTimeNanos(); -#elif defined(WEBRTC_WIN) +#elif defined(_WIN32) // TODO(webrtc:14601): Fix the volatile increment instead of suppressing the // warning. +#if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-volatile" +#endif static volatile LONG last_timegettime = 0; static volatile int64_t num_wrap_timegettime = 0; volatile LONG* last_timegettime_ptr = &last_timegettime; @@ -84,9 +86,13 @@ int64_t SystemTimeNanos() { } ticks = now + (num_wrap_timegettime << 32); // TODO(deadbeef): Calculate with nanosecond precision. Otherwise, we're - // just wasting a multiply and divide when doing Time() on Windows. - ticks = ticks * kNumNanosecsPerMillisec; +#if defined(__clang__) #pragma clang diagnostic pop +#endif + ticks = ticks * kNumNanosecsPerMillisec; +#if defined(__clang__) +#pragma clang diagnostic pop +#endif #else #error Unsupported platform. #endif diff --git a/src/common/rtc_base/time_utils.cc b/src/common/rtc_base/time_utils.cc index 2018e51..b341da9 100644 --- a/src/common/rtc_base/time_utils.cc +++ b/src/common/rtc_base/time_utils.cc @@ -10,23 +10,23 @@ #include -#if defined(WEBRTC_POSIX) +#if defined(__POSIX__) #include #endif #include "rtc_base/numerics/safe_conversions.h" #include "rtc_base/time_utils.h" #include "system_time.h" -#if defined(WEBRTC_WIN) +#if defined(_WIN32) #include "rtc_base/win32.h" #endif -#if defined(WEBRTC_WIN) +#if defined(_WIN32) #include #endif namespace rtc { -#if defined(WEBRTC_WIN) || defined(WINUWP) +#if defined(_WIN32) || defined(WINUWP) // FileTime (January 1st 1601) to Unix time (January 1st 1970) // offset in units of 100ns. static constexpr uint64_t kFileTimeToUnixTimeEpochOffset = @@ -161,10 +161,7 @@ int64_t TimeMillis() { return TimeNanos() / kNumNanosecsPerMillisec; } int64_t TimeMicros() { return TimeNanos() / kNumNanosecsPerMicrosec; } -int64_t TimeAfter(int64_t elapsed) { - RTC_DCHECK_GE(elapsed, 0); - return TimeMillis() + elapsed; -} +int64_t TimeAfter(int64_t elapsed) { return TimeMillis() + elapsed; } int32_t TimeDiff32(uint32_t later, uint32_t earlier) { return later - earlier; } @@ -215,13 +212,13 @@ int64_t TimeUTCMicros() { if (g_clock) { return g_clock->TimeNanos() / kNumNanosecsPerMicrosec; } -#if defined(WEBRTC_POSIX) +#if defined(__POSIX__) struct timeval time; gettimeofday(&time, nullptr); // Convert from second (1.0) and microsecond (1e-6). return (static_cast(time.tv_sec) * rtc::kNumMicrosecsPerSec + time.tv_usec); -#elif defined(WEBRTC_WIN) +#elif defined(_WIN32) FILETIME ft; // This will give us system file in UTC format in multiples of 100ns. GetSystemTimeAsFileTime(&ft); diff --git a/src/common/rtc_base/win32.cc b/src/common/rtc_base/win32.cc new file mode 100644 index 0000000..be36563 --- /dev/null +++ b/src/common/rtc_base/win32.cc @@ -0,0 +1,309 @@ +/* + * Copyright 2004 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 "rtc_base/win32.h" + +#include +#include + +#include + +#include "rtc_base/arraysize.h" +#include "rtc_base/byte_order.h" + +namespace rtc { + +// Helper function declarations for inet_ntop/inet_pton. +static const char* inet_ntop_v4(const void* src, char* dst, socklen_t size); +static const char* inet_ntop_v6(const void* src, char* dst, socklen_t size); +static int inet_pton_v4(const char* src, void* dst); +static int inet_pton_v6(const char* src, void* dst); + +// Implementation of inet_ntop (create a printable representation of an +// ip address). XP doesn't have its own inet_ntop, and +// WSAAddressToString requires both IPv6 to be installed and for Winsock +// to be initialized. +const char* win32_inet_ntop(int af, const void* src, char* dst, + socklen_t size) { + if (!src || !dst) { + return nullptr; + } + switch (af) { + case AF_INET: { + return inet_ntop_v4(src, dst, size); + } + case AF_INET6: { + return inet_ntop_v6(src, dst, size); + } + } + return nullptr; +} + +// As above, but for inet_pton. Implements inet_pton for v4 and v6. +// Note that our inet_ntop will output normal 'dotted' v4 addresses only. +int win32_inet_pton(int af, const char* src, void* dst) { + if (!src || !dst) { + return 0; + } + if (af == AF_INET) { + return inet_pton_v4(src, dst); + } else if (af == AF_INET6) { + return inet_pton_v6(src, dst); + } + return -1; +} + +// Helper function for inet_ntop for IPv4 addresses. +// Outputs "dotted-quad" decimal notation. +const char* inet_ntop_v4(const void* src, char* dst, socklen_t size) { + if (size < INET_ADDRSTRLEN) { + return nullptr; + } + const struct in_addr* as_in_addr = + reinterpret_cast(src); + snprintf(dst, size, "%d.%d.%d.%d", as_in_addr->S_un.S_un_b.s_b1, + as_in_addr->S_un.S_un_b.s_b2, as_in_addr->S_un.S_un_b.s_b3, + as_in_addr->S_un.S_un_b.s_b4); + return dst; +} + +// Helper function for inet_ntop for IPv6 addresses. +const char* inet_ntop_v6(const void* src, char* dst, socklen_t size) { + if (size < INET6_ADDRSTRLEN) { + return nullptr; + } + const uint16_t* as_shorts = reinterpret_cast(src); + int runpos[8]; + int current = 1; + int max = 0; + int maxpos = -1; + int run_array_size = arraysize(runpos); + // Run over the address marking runs of 0s. + for (int i = 0; i < run_array_size; ++i) { + if (as_shorts[i] == 0) { + runpos[i] = current; + if (current > max) { + maxpos = i; + max = current; + } + ++current; + } else { + runpos[i] = -1; + current = 1; + } + } + + if (max > 0) { + int tmpmax = maxpos; + // Run back through, setting -1 for all but the longest run. + for (int i = run_array_size - 1; i >= 0; i--) { + if (i > tmpmax) { + runpos[i] = -1; + } else if (runpos[i] == -1) { + // We're less than maxpos, we hit a -1, so the 'good' run is done. + // Setting tmpmax -1 means all remaining positions get set to -1. + tmpmax = -1; + } + } + } + + char* cursor = dst; + // Print IPv4 compatible and IPv4 mapped addresses using the IPv4 helper. + // These addresses have an initial run of either eight zero-bytes followed + // by 0xFFFF, or an initial run of ten zero-bytes. + if (runpos[0] == 1 && + (maxpos == 5 || (maxpos == 4 && as_shorts[5] == 0xFFFF))) { + *cursor++ = ':'; + *cursor++ = ':'; + if (maxpos == 4) { + cursor += snprintf(cursor, INET6_ADDRSTRLEN - 2, "ffff:"); + } + const struct in_addr* as_v4 = + reinterpret_cast(&(as_shorts[6])); + inet_ntop_v4(as_v4, cursor, + static_cast(INET6_ADDRSTRLEN - (cursor - dst))); + } else { + for (int i = 0; i < run_array_size; ++i) { + if (runpos[i] == -1) { + cursor += snprintf(cursor, INET6_ADDRSTRLEN - (cursor - dst), "%x", + NetworkToHost16(as_shorts[i])); + if (i != 7 && runpos[i + 1] != 1) { + *cursor++ = ':'; + } + } else if (runpos[i] == 1) { + // Entered the run; print the colons and skip the run. + *cursor++ = ':'; + *cursor++ = ':'; + i += (max - 1); + } + } + } + return dst; +} + +// Helper function for inet_pton for IPv4 addresses. +// `src` points to a character string containing an IPv4 network address in +// dotted-decimal format, "ddd.ddd.ddd.ddd", where ddd is a decimal number +// of up to three digits in the range 0 to 255. +// The address is converted and copied to dst, +// which must be sizeof(struct in_addr) (4) bytes (32 bits) long. +int inet_pton_v4(const char* src, void* dst) { + const int kIpv4AddressSize = 4; + int found = 0; + const char* src_pos = src; + unsigned char result[kIpv4AddressSize] = {0}; + + while (*src_pos != '\0') { + // strtol won't treat whitespace characters in the begining as an error, + // so check to ensure this is started with digit before passing to strtol. + if (!isdigit(*src_pos)) { + return 0; + } + char* end_pos; + long value = strtol(src_pos, &end_pos, 10); + if (value < 0 || value > 255 || src_pos == end_pos) { + return 0; + } + ++found; + if (found > kIpv4AddressSize) { + return 0; + } + result[found - 1] = static_cast(value); + src_pos = end_pos; + if (*src_pos == '.') { + // There's more. + ++src_pos; + } else if (*src_pos != '\0') { + // If it's neither '.' nor '\0' then return fail. + return 0; + } + } + if (found != kIpv4AddressSize) { + return 0; + } + memcpy(dst, result, sizeof(result)); + return 1; +} + +// Helper function for inet_pton for IPv6 addresses. +int inet_pton_v6(const char* src, void* dst) { + // sscanf will pick any other invalid chars up, but it parses 0xnnnn as hex. + // Check for literal x in the input string. + const char* readcursor = src; + char c = *readcursor++; + while (c) { + if (c == 'x') { + return 0; + } + c = *readcursor++; + } + readcursor = src; + + struct in6_addr an_addr; + memset(&an_addr, 0, sizeof(an_addr)); + + uint16_t* addr_cursor = reinterpret_cast(&an_addr.s6_addr[0]); + uint16_t* addr_end = reinterpret_cast(&an_addr.s6_addr[16]); + bool seencompressed = false; + + // Addresses that start with "::" (i.e., a run of initial zeros) or + // "::ffff:" can potentially be IPv4 mapped or compatibility addresses. + // These have dotted-style IPv4 addresses on the end (e.g. "::192.168.7.1"). + if (*readcursor == ':' && *(readcursor + 1) == ':' && + *(readcursor + 2) != 0) { + // Check for periods, which we'll take as a sign of v4 addresses. + const char* addrstart = readcursor + 2; + if (strchr(addrstart, '.')) { + const char* colon = strchr(addrstart, ':'); + if (colon) { + uint16_t a_short; + int bytesread = 0; + if (sscanf(addrstart, "%hx%n", &a_short, &bytesread) != 1 || + a_short != 0xFFFF || bytesread != 4) { + // Colons + periods means has to be ::ffff:a.b.c.d. But it wasn't. + return 0; + } else { + an_addr.s6_addr[10] = 0xFF; + an_addr.s6_addr[11] = 0xFF; + addrstart = colon + 1; + } + } + struct in_addr v4; + if (inet_pton_v4(addrstart, &v4.s_addr)) { + memcpy(&an_addr.s6_addr[12], &v4, sizeof(v4)); + memcpy(dst, &an_addr, sizeof(an_addr)); + return 1; + } else { + // Invalid v4 address. + return 0; + } + } + } + + // For addresses without a trailing IPv4 component ('normal' IPv6 addresses). + while (*readcursor != 0 && addr_cursor < addr_end) { + if (*readcursor == ':') { + if (*(readcursor + 1) == ':') { + if (seencompressed) { + // Can only have one compressed run of zeroes ("::") per address. + return 0; + } + // Hit a compressed run. Count colons to figure out how much of the + // address is skipped. + readcursor += 2; + const char* coloncounter = readcursor; + int coloncount = 0; + if (*coloncounter == 0) { + // Special case - trailing ::. + addr_cursor = addr_end; + } else { + while (*coloncounter) { + if (*coloncounter == ':') { + ++coloncount; + } + ++coloncounter; + } + // (coloncount + 1) is the number of shorts left in the address. + // If this number is greater than the number of available shorts, the + // address is malformed. + if (coloncount + 1 > addr_end - addr_cursor) { + return 0; + } + addr_cursor = addr_end - (coloncount + 1); + seencompressed = true; + } + } else { + ++readcursor; + } + } else { + uint16_t word; + int bytesread = 0; + if (sscanf(readcursor, "%4hx%n", &word, &bytesread) != 1) { + return 0; + } else { + *addr_cursor = HostToNetwork16(word); + ++addr_cursor; + readcursor += bytesread; + if (*readcursor != ':' && *readcursor != '\0') { + return 0; + } + } + } + } + + if (*readcursor != '\0' || addr_cursor < addr_end) { + // Catches addresses too short or too long. + return 0; + } + memcpy(dst, &an_addr, sizeof(an_addr)); + return 1; +} + +} // namespace rtc diff --git a/src/common/rtc_base/win32.h b/src/common/rtc_base/win32.h new file mode 100644 index 0000000..bd72941 --- /dev/null +++ b/src/common/rtc_base/win32.h @@ -0,0 +1,48 @@ +/* + * Copyright 2004 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 RTC_BASE_WIN32_H_ +#define RTC_BASE_WIN32_H_ + +#ifndef _WIN32 +#error "Only #include this header in Windows builds" +#endif + +// Make sure we don't get min/max macros +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#include + +// Must be after winsock2.h. +#include + +typedef int socklen_t; + +#ifndef SECURITY_MANDATORY_LABEL_AUTHORITY +// Add defines that we use if we are compiling against older sdks +#define SECURITY_MANDATORY_MEDIUM_RID (0x00002000L) +#define TokenIntegrityLevel static_cast(0x19) +typedef struct _TOKEN_MANDATORY_LABEL { + SID_AND_ATTRIBUTES Label; +} TOKEN_MANDATORY_LABEL, *PTOKEN_MANDATORY_LABEL; +#endif // SECURITY_MANDATORY_LABEL_AUTHORITY + +#undef SetPort + +namespace rtc { + +const char* win32_inet_ntop(int af, const void* src, char* dst, socklen_t size); +int win32_inet_pton(int af, const char* src, void* dst); + +} // namespace rtc + +#endif // RTC_BASE_WIN32_H_ diff --git a/src/media/video/decode/nvcodec/nvidia_video_decoder.cpp b/src/media/video/decode/nvcodec/nvidia_video_decoder.cpp index 3735505..860e9a5 100644 --- a/src/media/video/decode/nvcodec/nvidia_video_decoder.cpp +++ b/src/media/video/decode/nvcodec/nvidia_video_decoder.cpp @@ -4,7 +4,7 @@ #include "nvcodec_api.h" // #define SAVE_DECODED_NV12_STREAM -// #define SAVE_RECEIVED_H264_STREAM +#define SAVE_RECEIVED_H264_STREAM NvidiaVideoDecoder::NvidiaVideoDecoder() {} NvidiaVideoDecoder::~NvidiaVideoDecoder() { @@ -66,10 +66,11 @@ int NvidiaVideoDecoder::Init() { int NvidiaVideoDecoder::Decode( const uint8_t *data, size_t size, std::function on_receive_decoded_frame) { + LOG_ERROR("1"); if (!decoder) { return -1; } - + LOG_ERROR("2"); #ifdef SAVE_RECEIVED_H264_STREAM fwrite((unsigned char *)data, 1, size, file_h264_); #endif @@ -79,11 +80,14 @@ int NvidiaVideoDecoder::Decode( } int num_frame_returned = decoder->Decode(data, (int)size); + LOG_ERROR("???? {}", num_frame_returned); for (size_t i = 0; i < num_frame_returned; ++i) { cudaVideoSurfaceFormat format = decoder->GetOutputFormat(); + LOG_ERROR("3"); if (format == cudaVideoSurfaceFormat_NV12) { uint8_t *decoded_frame_buffer = nullptr; decoded_frame_buffer = decoder->GetFrame(); + LOG_ERROR("4"); if (decoded_frame_buffer) { if (on_receive_decoded_frame) { VideoFrame decoded_frame( diff --git a/src/media/video/encode/nvcodec/nvidia_video_encoder.cpp b/src/media/video/encode/nvcodec/nvidia_video_encoder.cpp index 987e351..57c7ae9 100644 --- a/src/media/video/encode/nvcodec/nvidia_video_encoder.cpp +++ b/src/media/video/encode/nvcodec/nvidia_video_encoder.cpp @@ -7,7 +7,7 @@ #include "nvcodec_common.h" // #define SAVE_RECEIVED_NV12_STREAM -// #define SAVE_ENCODED_H264_STREAM +#define SAVE_ENCODED_H264_STREAM NvidiaVideoEncoder::NvidiaVideoEncoder() {} NvidiaVideoEncoder::~NvidiaVideoEncoder() { diff --git a/src/qos/bwe_defines.cc b/src/qos/bwe_defines.cc new file mode 100644 index 0000000..39159a0 --- /dev/null +++ b/src/qos/bwe_defines.cc @@ -0,0 +1,24 @@ +/* + * 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. + */ + +#include "bwe_defines.h" + +namespace webrtc { + +const char kBweTypeHistogram[] = "WebRTC.BWE.Types"; + +RateControlInput::RateControlInput( + BandwidthUsage bw_state, + const std::optional& estimated_throughput) + : bw_state(bw_state), estimated_throughput(estimated_throughput) {} + +RateControlInput::~RateControlInput() = default; + +} // namespace webrtc diff --git a/src/qos/clock.cc b/src/qos/clock.cc index 8b40982..fcc89b5 100644 --- a/src/qos/clock.cc +++ b/src/qos/clock.cc @@ -55,4 +55,9 @@ class RealTimeClock : public Clock { return TimeMicrosToNtp(timestamp.us()); } }; + +Clock* Clock::GetRealTimeClock() { + static Clock* const clock = new RealTimeClock(); + return clock; +} } // namespace webrtc \ No newline at end of file diff --git a/src/qos/ntp_time_util.cc b/src/qos/ntp_time_util.cc new file mode 100644 index 0000000..a31f300 --- /dev/null +++ b/src/qos/ntp_time_util.cc @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#include "ntp_time_util.h" + +#include +#include + +#include "api/units/time_delta.h" +#include "rtc_base/numerics/divide_round.h" +#include "rtc_base/time_utils.h" + +namespace webrtc { + +uint32_t SaturatedToCompactNtp(TimeDelta delta) { + constexpr uint32_t kMaxCompactNtp = 0xFFFFFFFF; + constexpr int kCompactNtpInSecond = 0x10000; + if (delta <= TimeDelta::Zero()) return 0; + if (delta.us() >= + kMaxCompactNtp * rtc::kNumMicrosecsPerSec / kCompactNtpInSecond) + return kMaxCompactNtp; + // To convert to compact ntp need to divide by 1e6 to get seconds, + // then multiply by 0x10000 to get the final result. + // To avoid float operations, multiplication and division swapped. + return DivideRoundToNearest(delta.us() * kCompactNtpInSecond, + rtc::kNumMicrosecsPerSec); +} + +TimeDelta CompactNtpIntervalToTimeDelta(uint32_t compact_ntp_interval) { + // Convert to 64bit value to avoid multiplication overflow. + int64_t value = int64_t{compact_ntp_interval}; + if (compact_ntp_interval > 0x8000'0000) { + value -= (int64_t{1} << 32); + } + // To convert to TimeDelta need to divide by 2^16 to get seconds, + // then multiply by 1'000'000 to get microseconds. To avoid float operations, + // multiplication and division are swapped. + int64_t us = DivideRoundToNearest(value * rtc::kNumMicrosecsPerSec, 1 << 16); + return TimeDelta::Micros(us); +} + +TimeDelta CompactNtpRttToTimeDelta(uint32_t compact_ntp_interval) { + static constexpr TimeDelta kMinRtt = TimeDelta::Millis(1); + // Interval to convert expected to be positive, e.g. RTT or delay. + // Because interval can be derived from non-monotonic ntp clock, + // it might become negative that is indistinguishable from very large values. + // Since very large RTT/delay is less likely than non-monotonic ntp clock, + // such value is considered negative and converted to minimum value of 1ms. + // Small RTT value is considered too good to be true and increased to 1ms. + return std::max(CompactNtpIntervalToTimeDelta(compact_ntp_interval), kMinRtt); +} +} // namespace webrtc diff --git a/src/rtp/rtp_packet/rtp_codec.cpp b/src/rtp/rtp_packet/rtp_codec.cpp index 968217d..957dca0 100644 --- a/src/rtp/rtp_packet/rtp_codec.cpp +++ b/src/rtp/rtp_packet/rtp_codec.cpp @@ -449,6 +449,14 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size, RtpPacket rtp_packet; rtp_packet.SetVerion(version_); rtp_packet.SetHasPadding(has_padding_); + + has_extension_ = true; + uint32_t abs_send_time = + std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count(); + rtp_packet.SetAbsoluteSendTimestamp(abs_send_time); + rtp_packet.SetHasExtension(has_extension_); rtp_packet.SetMarker(1); rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_)); @@ -490,6 +498,14 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size, RtpPacket rtp_packet; rtp_packet.SetVerion(version_); rtp_packet.SetHasPadding(has_padding_); + + has_extension_ = true; + uint32_t abs_send_time = + std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count(); + rtp_packet.SetAbsoluteSendTimestamp(abs_send_time); + rtp_packet.SetHasExtension(has_extension_); rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0); rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_)); @@ -541,6 +557,14 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size, RtpPacket rtp_packet; rtp_packet.SetVerion(version_); rtp_packet.SetHasPadding(has_padding_); + + has_extension_ = true; + uint32_t abs_send_time = + std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count(); + rtp_packet.SetAbsoluteSendTimestamp(abs_send_time); + rtp_packet.SetHasExtension(has_extension_); rtp_packet.SetMarker(1); rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_)); @@ -569,6 +593,14 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size, RtpPacket rtp_packet; rtp_packet.SetVerion(version_); rtp_packet.SetHasPadding(has_padding_); + + has_extension_ = true; + uint32_t abs_send_time = + std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count(); + rtp_packet.SetAbsoluteSendTimestamp(abs_send_time); + rtp_packet.SetHasExtension(has_extension_); rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0); rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_)); diff --git a/src/rtp/rtp_packet/rtp_packet.cpp b/src/rtp/rtp_packet/rtp_packet.cpp index e982f7d..81a0ab8 100644 --- a/src/rtp/rtp_packet/rtp_packet.cpp +++ b/src/rtp/rtp_packet/rtp_packet.cpp @@ -35,7 +35,7 @@ void RtpPacket::ParseRtpData() { RtpPacket::RtpPacket() : buffer_(new uint8_t[DEFAULT_MTU]), size_(DEFAULT_MTU) { memset(buffer_, 0, DEFAULT_MTU); - ParseRtpData(); + // ParseRtpData(); } RtpPacket::RtpPacket(uint32_t size) : buffer_(new uint8_t[size]), size_(size) {} diff --git a/src/rtp/rtp_packet/rtp_packet.h b/src/rtp/rtp_packet/rtp_packet.h index 43995b4..f73a946 100644 --- a/src/rtp/rtp_packet/rtp_packet.h +++ b/src/rtp/rtp_packet/rtp_packet.h @@ -213,12 +213,12 @@ class RtpPacket { void SetCsrcs(std::vector &csrcs) { csrcs_ = csrcs; } void SetExtensionProfile(uint16_t extension_profile) { - extension_profile_ = extension_profile; + // extension_profile_ = extension_profile; } void SetExtensionData(uint8_t *extension_data, uint16_t extension_len) { - extension_len_ = extension_len; - extension_data_ = new uint8_t[extension_len_]; - memcpy(extension_data_, extension_data, extension_len_); + // extension_len_ = extension_len; + // extension_data_ = new uint8_t[extension_len_]; + // memcpy(extension_data_, extension_data, extension_len_); } void SetAbsoluteSendTimestamp(uint32_t abs_send_time) { @@ -228,9 +228,10 @@ class RtpPacket { // Allocate memory for the extension data if not already allocated if (extension_data_ == nullptr) { - extension_data_ = new uint8_t[4]; // 2 bytes for profile, 2 bytes for - // length, 3 bytes for abs_send_time - extension_len_ = 4; + extension_data_ = + (uint8_t *)malloc(5); // 2 bytes for profile, 2 bytes for length, 3 + // bytes for abs_send_time + extension_len_ = 5; } // Set the extension profile to 0xBEDE (one-byte header) diff --git a/src/transport/ice_transport.cpp b/src/transport/ice_transport.cpp index 4110cba..d52f9d2 100644 --- a/src/transport/ice_transport.cpp +++ b/src/transport/ice_transport.cpp @@ -131,8 +131,10 @@ void IceTransport::InitializeChannels( data_channel_send_->Initialize(RtpPacket::PAYLOAD_TYPE::DATA); video_channel_receive_ = std::make_unique( - ice_agent_, ice_io_statistics_, - [this](VideoFrame &video_frame) { OnReceiveCompleteFrame(video_frame); }); + ice_agent_, ice_io_statistics_, [this](VideoFrame &video_frame) { + LOG_ERROR("ccccccc"); + OnReceiveCompleteFrame(video_frame); + }); audio_channel_receive_ = std::make_unique( ice_agent_, ice_io_statistics_, [this](const char *data, size_t size) { @@ -356,11 +358,14 @@ bool IceTransport::HandleCongestionControlFeedback( if (!feedback.Parse(rtcp_block) || feedback.packets().empty()) { return false; } - uint32_t first_media_source_ssrc = feedback.packets()[0].ssrc; - if (first_media_source_ssrc == local_media_ssrc() || - registered_ssrcs_.contains(first_media_source_ssrc)) { - rtcp_packet_info->congestion_control_feedback.emplace(std::move(feedback)); - } + // uint32_t first_media_source_ssrc = feedback.packets()[0].ssrc; + // if (first_media_source_ssrc == local_media_ssrc() || + // registered_ssrcs_.contains(first_media_source_ssrc)) { + // rtcp_packet_info->congestion_control_feedback.emplace(std::move(feedback)); + // } + + video_channel_send_->OnCongestionControlFeedback( + std::chrono::system_clock::now().time_since_epoch().count(), feedback); return true; } @@ -374,6 +379,7 @@ void IceTransport::OnReceiveCompleteFrame(VideoFrame &video_frame) { x_video_frame.width = video_frame.Width(); x_video_frame.height = video_frame.Height(); x_video_frame.size = video_frame.Size(); + LOG_ERROR("ccccccc 2222222"); on_receive_video_(&x_video_frame, remote_user_id_.data(), remote_user_id_.size(), user_data_); } diff --git a/src/transport/ice_transport.h b/src/transport/ice_transport.h index 82e87ec..40db78a 100644 --- a/src/transport/ice_transport.h +++ b/src/transport/ice_transport.h @@ -74,6 +74,7 @@ class IceTransport { std::function on_receive_video) { + LOG_ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!"); on_receive_video_ = on_receive_video; } @@ -240,7 +241,6 @@ class IceTransport { std::unique_ptr rtp_audio_sender_ = nullptr; std::unique_ptr rtp_data_receiver_ = nullptr; std::unique_ptr rtp_data_sender_ = nullptr; - RtpPacket pop_packet_; bool start_send_packet_ = false; uint32_t last_complete_frame_ts_ = 0; diff --git a/xmake.lua b/xmake.lua index e22957a..750415b 100644 --- a/xmake.lua +++ b/xmake.lua @@ -41,9 +41,12 @@ target("log") target("common") set_kind("object") + add_deps("log") add_files("src/common/common.cpp", + "src/common/rtc_base/*.cc", "src/common/rtc_base/numerics/*.cc", - "src/common/api/units/*.cc") + "src/common/api/units/*.cc", + "src/common/api/transport/*.cc") add_includedirs("src/common", {public = true}) target("inih")