mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-26 12:15:34 +08:00
[fix] fix crash due to rtp extension
This commit is contained in:
@@ -90,7 +90,7 @@ int RtpAudioSender::SendRtpPacket(RtpPacket& rtp_packet) {
|
||||
|
||||
rtcp_sr.Encode();
|
||||
|
||||
SendRtcpSR(rtcp_sr);
|
||||
// SendRtcpSR(rtcp_sr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -60,7 +60,7 @@ void RtpDataReceiver::InsertRtpPacket(RtpPacket& rtp_packet) {
|
||||
|
||||
rtcp_rr.Encode();
|
||||
|
||||
SendRtcpRR(rtcp_rr);
|
||||
// SendRtcpRR(rtcp_rr);
|
||||
}
|
||||
|
||||
if (on_receive_data_) {
|
||||
|
||||
@@ -90,7 +90,7 @@ int RtpDataSender::SendRtpPacket(RtpPacket& rtp_packet) {
|
||||
|
||||
rtcp_sr.Encode();
|
||||
|
||||
SendRtcpSR(rtcp_sr);
|
||||
// SendRtcpSR(rtcp_sr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
107
src/common/api/transport/network_types.cc
Normal file
107
src/common/api/transport/network_types.cc
Normal file
@@ -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 <algorithm>
|
||||
#include <vector>
|
||||
|
||||
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<PacketResult> TransportPacketsFeedback::ReceivedWithSendInfo()
|
||||
const {
|
||||
std::vector<PacketResult> res;
|
||||
for (const PacketResult& fb : packet_feedbacks) {
|
||||
if (fb.IsReceived()) {
|
||||
res.push_back(fb);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<PacketResult> TransportPacketsFeedback::LostWithSendInfo() const {
|
||||
std::vector<PacketResult> res;
|
||||
for (const PacketResult& fb : packet_feedbacks) {
|
||||
if (!fb.IsReceived()) {
|
||||
res.push_back(fb);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<PacketResult> TransportPacketsFeedback::PacketsWithFeedback()
|
||||
const {
|
||||
return packet_feedbacks;
|
||||
}
|
||||
|
||||
std::vector<PacketResult> TransportPacketsFeedback::SortedByReceiveTime()
|
||||
const {
|
||||
std::vector<PacketResult> 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
|
||||
@@ -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 <cstdint>
|
||||
#include <string>
|
||||
|
||||
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
|
||||
32
src/common/rtc_base/arraysize.h
Normal file
32
src/common/rtc_base/arraysize.h
Normal file
@@ -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 <stddef.h>
|
||||
|
||||
// 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 <typename T, size_t N>
|
||||
char (&ArraySizeHelper(T (&array)[N]))[N];
|
||||
|
||||
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
|
||||
|
||||
#endif // RTC_BASE_ARRAYSIZE_H_
|
||||
199
src/common/rtc_base/byte_order.h
Normal file
199
src/common/rtc_base/byte_order.h
Normal file
@@ -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 <stdint.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#if defined(__POSIX__) && !defined(__native_client__)
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "rtc_base/system/arch.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <libkern/OSByteOrder.h>
|
||||
|
||||
#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 <stdlib.h>
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <netinet/in.h> // 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 <endian.h>
|
||||
#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<uint8_t*>(memory)[offset] = v;
|
||||
}
|
||||
|
||||
inline uint8_t Get8(const void* memory, size_t offset) {
|
||||
return static_cast<const uint8_t*>(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_
|
||||
@@ -14,6 +14,8 @@
|
||||
#define RTC_BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
|
||||
|
||||
#include <limits>
|
||||
#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 <typename Dst,
|
||||
typename Src,
|
||||
template <typename Dst, typename Src,
|
||||
DstSign IsDstSigned =
|
||||
std::numeric_limits<Dst>::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 <typename Dst,
|
||||
typename Src,
|
||||
template <typename Dst, typename Src,
|
||||
DstSign IsDstSigned =
|
||||
std::numeric_limits<Dst>::is_signed ? DST_SIGNED : DST_UNSIGNED,
|
||||
SrcSign IsSrcSigned =
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "log.h"
|
||||
#include "rtc_base/numerics/safe_compare.h"
|
||||
#include "rtc_base/numerics/safe_conversions.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
100
src/common/rtc_base/system/arch.h
Normal file
100
src/common/rtc_base/system/arch.h
Normal file
@@ -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_
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
#include <limits>
|
||||
|
||||
#if defined(WEBRTC_POSIX)
|
||||
#if defined(__POSIX__)
|
||||
#include <sys/time.h>
|
||||
#if defined(WEBRTC_MAC)
|
||||
#if defined(__APPLE__)
|
||||
#include <mach/mach_time.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(WEBRTC_WIN)
|
||||
#if defined(_WIN32)
|
||||
// clang-format off
|
||||
// clang formatting would put <windows.h> 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<int64_t>(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<int64_t>(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
|
||||
|
||||
@@ -10,23 +10,23 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(WEBRTC_POSIX)
|
||||
#if defined(__POSIX__)
|
||||
#include <sys/time.h>
|
||||
#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 <minwinbase.h>
|
||||
#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<int64_t>(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);
|
||||
|
||||
309
src/common/rtc_base/win32.cc
Normal file
309
src/common/rtc_base/win32.cc
Normal file
@@ -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 <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#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<const struct in_addr*>(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<const uint16_t*>(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<const struct in_addr*>(&(as_shorts[6]));
|
||||
inet_ntop_v4(as_v4, cursor,
|
||||
static_cast<socklen_t>(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<unsigned char>(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<uint16_t*>(&an_addr.s6_addr[0]);
|
||||
uint16_t* addr_end = reinterpret_cast<uint16_t*>(&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
|
||||
48
src/common/rtc_base/win32.h
Normal file
48
src/common/rtc_base/win32.h
Normal file
@@ -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 <winsock2.h>
|
||||
|
||||
// Must be after winsock2.h.
|
||||
#include <windows.h>
|
||||
|
||||
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<TOKEN_INFORMATION_CLASS>(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_
|
||||
@@ -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<void(VideoFrame)> 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(
|
||||
|
||||
@@ -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() {
|
||||
|
||||
24
src/qos/bwe_defines.cc
Normal file
24
src/qos/bwe_defines.cc
Normal file
@@ -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<DataRate>& estimated_throughput)
|
||||
: bw_state(bw_state), estimated_throughput(estimated_throughput) {}
|
||||
|
||||
RateControlInput::~RateControlInput() = default;
|
||||
|
||||
} // namespace webrtc
|
||||
@@ -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
|
||||
59
src/qos/ntp_time_util.cc
Normal file
59
src/qos/ntp_time_util.cc
Normal file
@@ -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 <algorithm>
|
||||
#include <cstdint>
|
||||
|
||||
#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
|
||||
@@ -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::microseconds>(
|
||||
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::microseconds>(
|
||||
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::microseconds>(
|
||||
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::microseconds>(
|
||||
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_));
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
@@ -213,12 +213,12 @@ class RtpPacket {
|
||||
void SetCsrcs(std::vector<uint32_t> &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)
|
||||
|
||||
@@ -131,8 +131,10 @@ void IceTransport::InitializeChannels(
|
||||
data_channel_send_->Initialize(RtpPacket::PAYLOAD_TYPE::DATA);
|
||||
|
||||
video_channel_receive_ = std::make_unique<VideoChannelReceive>(
|
||||
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<AudioChannelReceive>(
|
||||
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_);
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ class IceTransport {
|
||||
std::function<void(const XVideoFrame *, const char *, const size_t,
|
||||
void *)>
|
||||
on_receive_video) {
|
||||
LOG_ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
on_receive_video_ = on_receive_video;
|
||||
}
|
||||
|
||||
@@ -240,7 +241,6 @@ class IceTransport {
|
||||
std::unique_ptr<RtpAudioSender> rtp_audio_sender_ = nullptr;
|
||||
std::unique_ptr<RtpDataReceiver> rtp_data_receiver_ = nullptr;
|
||||
std::unique_ptr<RtpDataSender> rtp_data_sender_ = nullptr;
|
||||
RtpPacket pop_packet_;
|
||||
bool start_send_packet_ = false;
|
||||
|
||||
uint32_t last_complete_frame_ts_ = 0;
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user