[fix] fix crash due to rtp extension

This commit is contained in:
dijunkun
2025-01-21 17:30:00 +08:00
parent 477fd1f13b
commit ea592f5a58
28 changed files with 981 additions and 144 deletions

View File

@@ -90,7 +90,7 @@ int RtpAudioSender::SendRtpPacket(RtpPacket& rtp_packet) {
rtcp_sr.Encode(); rtcp_sr.Encode();
SendRtcpSR(rtcp_sr); // SendRtcpSR(rtcp_sr);
} }
return 0; return 0;

View File

@@ -60,7 +60,7 @@ void RtpDataReceiver::InsertRtpPacket(RtpPacket& rtp_packet) {
rtcp_rr.Encode(); rtcp_rr.Encode();
SendRtcpRR(rtcp_rr); // SendRtcpRR(rtcp_rr);
} }
if (on_receive_data_) { if (on_receive_data_) {

View File

@@ -90,7 +90,7 @@ int RtpDataSender::SendRtpPacket(RtpPacket& rtp_packet) {
rtcp_sr.Encode(); rtcp_sr.Encode();
SendRtcpSR(rtcp_sr); // SendRtcpSR(rtcp_sr);
} }
return 0; return 0;

View File

@@ -107,7 +107,7 @@ void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) {
rtcp_rr.Encode(); rtcp_rr.Encode();
SendRtcpRR(rtcp_rr); // SendRtcpRR(rtcp_rr);
} }
if (rtp_packet.PayloadType() == RtpPacket::PAYLOAD_TYPE::AV1) { if (rtp_packet.PayloadType() == RtpPacket::PAYLOAD_TYPE::AV1) {
ProcessAv1RtpPacket(rtp_packet); ProcessAv1RtpPacket(rtp_packet);

View File

@@ -86,7 +86,7 @@ int RtpVideoSender::SendRtpPacket(RtpPacket& rtp_packet) {
report.lsr = 0; report.lsr = 0;
report.dlsr = 0; report.dlsr = 0;
rtcp_sr.SetReportBlock(report); // rtcp_sr.SetReportBlock(report);
rtcp_sr.Encode(); rtcp_sr.Encode();

View File

@@ -11,6 +11,7 @@
#include "ice_agent.h" #include "ice_agent.h"
#include "rtp_codec.h" #include "rtp_codec.h"
#include "rtp_video_sender.h" #include "rtp_video_sender.h"
#include "transport_feedback.h"
#include "transport_feedback_adapter.h" #include "transport_feedback_adapter.h"
class VideoChannelSend { class VideoChannelSend {

View 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

View File

@@ -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

View 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_

View 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_

View File

@@ -14,6 +14,8 @@
#define RTC_BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ #define RTC_BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
#include <limits> #include <limits>
#undef max
#undef min
namespace rtc { namespace rtc {
namespace internal { namespace internal {
@@ -27,8 +29,7 @@ enum DstRange { OVERLAPS_RANGE, CONTAINS_RANGE };
// Helper templates to statically determine if our destination type can contain // Helper templates to statically determine if our destination type can contain
// all values represented by the source type. // all values represented by the source type.
template <typename Dst, template <typename Dst, typename Src,
typename Src,
DstSign IsDstSigned = DstSign IsDstSigned =
std::numeric_limits<Dst>::is_signed ? DST_SIGNED : DST_UNSIGNED, std::numeric_limits<Dst>::is_signed ? DST_SIGNED : DST_UNSIGNED,
SrcSign IsSrcSigned = SrcSign IsSrcSigned =
@@ -85,8 +86,7 @@ enum RangeCheckResult {
RangeCheckResult(((is_in_upper_bound) ? 0 : TYPE_OVERFLOW) | \ RangeCheckResult(((is_in_upper_bound) ? 0 : TYPE_OVERFLOW) | \
((is_in_lower_bound) ? 0 : TYPE_UNDERFLOW)) ((is_in_lower_bound) ? 0 : TYPE_UNDERFLOW))
template <typename Dst, template <typename Dst, typename Src,
typename Src,
DstSign IsDstSigned = DstSign IsDstSigned =
std::numeric_limits<Dst>::is_signed ? DST_SIGNED : DST_UNSIGNED, std::numeric_limits<Dst>::is_signed ? DST_SIGNED : DST_UNSIGNED,
SrcSign IsSrcSigned = SrcSign IsSrcSigned =

View File

@@ -15,6 +15,7 @@
#include <memory> #include <memory>
#include "log.h" #include "log.h"
#include "rtc_base/numerics/safe_compare.h"
#include "rtc_base/numerics/safe_conversions.h" #include "rtc_base/numerics/safe_conversions.h"
namespace webrtc { namespace webrtc {

View 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_

View File

@@ -16,14 +16,14 @@
#include <limits> #include <limits>
#if defined(WEBRTC_POSIX) #if defined(__POSIX__)
#include <sys/time.h> #include <sys/time.h>
#if defined(WEBRTC_MAC) #if defined(__APPLE__)
#include <mach/mach_time.h> #include <mach/mach_time.h>
#endif #endif
#endif #endif
#if defined(WEBRTC_WIN) #if defined(_WIN32)
// clang-format off // clang-format off
// clang formatting would put <windows.h> last, // clang formatting would put <windows.h> last,
// which leads to compilation failure. // which leads to compilation failure.
@@ -41,7 +41,7 @@ namespace rtc {
int64_t SystemTimeNanos() { int64_t SystemTimeNanos() {
int64_t ticks; int64_t ticks;
#if defined(WEBRTC_MAC) #if defined(__APPLE__)
static mach_timebase_info_data_t timebase; static mach_timebase_info_data_t timebase;
if (timebase.denom == 0) { if (timebase.denom == 0) {
// Get the timebase if this is the first time we run. // 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); return rtc::dchecked_cast<int64_t>(a * b);
}; };
ticks = mul(mach_absolute_time(), timebase.numer) / timebase.denom; ticks = mul(mach_absolute_time(), timebase.numer) / timebase.denom;
#elif defined(WEBRTC_POSIX) #elif defined(__POSIX__)
struct timespec ts; struct timespec ts;
// TODO(deadbeef): Do we need to handle the case when CLOCK_MONOTONIC is not // TODO(deadbeef): Do we need to handle the case when CLOCK_MONOTONIC is not
// supported? // supported?
@@ -63,11 +63,13 @@ int64_t SystemTimeNanos() {
static_cast<int64_t>(ts.tv_nsec); static_cast<int64_t>(ts.tv_nsec);
#elif defined(WINUWP) #elif defined(WINUWP)
ticks = WinUwpSystemTimeNanos(); ticks = WinUwpSystemTimeNanos();
#elif defined(WEBRTC_WIN) #elif defined(_WIN32)
// TODO(webrtc:14601): Fix the volatile increment instead of suppressing the // TODO(webrtc:14601): Fix the volatile increment instead of suppressing the
// warning. // warning.
#if defined(__clang__)
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-volatile" #pragma clang diagnostic ignored "-Wdeprecated-volatile"
#endif
static volatile LONG last_timegettime = 0; static volatile LONG last_timegettime = 0;
static volatile int64_t num_wrap_timegettime = 0; static volatile int64_t num_wrap_timegettime = 0;
volatile LONG* last_timegettime_ptr = &last_timegettime; volatile LONG* last_timegettime_ptr = &last_timegettime;
@@ -84,9 +86,13 @@ int64_t SystemTimeNanos() {
} }
ticks = now + (num_wrap_timegettime << 32); ticks = now + (num_wrap_timegettime << 32);
// TODO(deadbeef): Calculate with nanosecond precision. Otherwise, we're // TODO(deadbeef): Calculate with nanosecond precision. Otherwise, we're
// just wasting a multiply and divide when doing Time() on Windows. #if defined(__clang__)
ticks = ticks * kNumNanosecsPerMillisec;
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif
ticks = ticks * kNumNanosecsPerMillisec;
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#else #else
#error Unsupported platform. #error Unsupported platform.
#endif #endif

View File

@@ -10,23 +10,23 @@
#include <stdint.h> #include <stdint.h>
#if defined(WEBRTC_POSIX) #if defined(__POSIX__)
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include "rtc_base/numerics/safe_conversions.h" #include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/time_utils.h" #include "rtc_base/time_utils.h"
#include "system_time.h" #include "system_time.h"
#if defined(WEBRTC_WIN) #if defined(_WIN32)
#include "rtc_base/win32.h" #include "rtc_base/win32.h"
#endif #endif
#if defined(WEBRTC_WIN) #if defined(_WIN32)
#include <minwinbase.h> #include <minwinbase.h>
#endif #endif
namespace rtc { namespace rtc {
#if defined(WEBRTC_WIN) || defined(WINUWP) #if defined(_WIN32) || defined(WINUWP)
// FileTime (January 1st 1601) to Unix time (January 1st 1970) // FileTime (January 1st 1601) to Unix time (January 1st 1970)
// offset in units of 100ns. // offset in units of 100ns.
static constexpr uint64_t kFileTimeToUnixTimeEpochOffset = static constexpr uint64_t kFileTimeToUnixTimeEpochOffset =
@@ -161,10 +161,7 @@ int64_t TimeMillis() { return TimeNanos() / kNumNanosecsPerMillisec; }
int64_t TimeMicros() { return TimeNanos() / kNumNanosecsPerMicrosec; } int64_t TimeMicros() { return TimeNanos() / kNumNanosecsPerMicrosec; }
int64_t TimeAfter(int64_t elapsed) { int64_t TimeAfter(int64_t elapsed) { return TimeMillis() + elapsed; }
RTC_DCHECK_GE(elapsed, 0);
return TimeMillis() + elapsed;
}
int32_t TimeDiff32(uint32_t later, uint32_t earlier) { return later - earlier; } int32_t TimeDiff32(uint32_t later, uint32_t earlier) { return later - earlier; }
@@ -215,13 +212,13 @@ int64_t TimeUTCMicros() {
if (g_clock) { if (g_clock) {
return g_clock->TimeNanos() / kNumNanosecsPerMicrosec; return g_clock->TimeNanos() / kNumNanosecsPerMicrosec;
} }
#if defined(WEBRTC_POSIX) #if defined(__POSIX__)
struct timeval time; struct timeval time;
gettimeofday(&time, nullptr); gettimeofday(&time, nullptr);
// Convert from second (1.0) and microsecond (1e-6). // Convert from second (1.0) and microsecond (1e-6).
return (static_cast<int64_t>(time.tv_sec) * rtc::kNumMicrosecsPerSec + return (static_cast<int64_t>(time.tv_sec) * rtc::kNumMicrosecsPerSec +
time.tv_usec); time.tv_usec);
#elif defined(WEBRTC_WIN) #elif defined(_WIN32)
FILETIME ft; FILETIME ft;
// This will give us system file in UTC format in multiples of 100ns. // This will give us system file in UTC format in multiples of 100ns.
GetSystemTimeAsFileTime(&ft); GetSystemTimeAsFileTime(&ft);

View 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

View 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_

View File

@@ -4,7 +4,7 @@
#include "nvcodec_api.h" #include "nvcodec_api.h"
// #define SAVE_DECODED_NV12_STREAM // #define SAVE_DECODED_NV12_STREAM
// #define SAVE_RECEIVED_H264_STREAM #define SAVE_RECEIVED_H264_STREAM
NvidiaVideoDecoder::NvidiaVideoDecoder() {} NvidiaVideoDecoder::NvidiaVideoDecoder() {}
NvidiaVideoDecoder::~NvidiaVideoDecoder() { NvidiaVideoDecoder::~NvidiaVideoDecoder() {
@@ -66,10 +66,11 @@ int NvidiaVideoDecoder::Init() {
int NvidiaVideoDecoder::Decode( int NvidiaVideoDecoder::Decode(
const uint8_t *data, size_t size, const uint8_t *data, size_t size,
std::function<void(VideoFrame)> on_receive_decoded_frame) { std::function<void(VideoFrame)> on_receive_decoded_frame) {
LOG_ERROR("1");
if (!decoder) { if (!decoder) {
return -1; return -1;
} }
LOG_ERROR("2");
#ifdef SAVE_RECEIVED_H264_STREAM #ifdef SAVE_RECEIVED_H264_STREAM
fwrite((unsigned char *)data, 1, size, file_h264_); fwrite((unsigned char *)data, 1, size, file_h264_);
#endif #endif
@@ -79,11 +80,14 @@ int NvidiaVideoDecoder::Decode(
} }
int num_frame_returned = decoder->Decode(data, (int)size); int num_frame_returned = decoder->Decode(data, (int)size);
LOG_ERROR("???? {}", num_frame_returned);
for (size_t i = 0; i < num_frame_returned; ++i) { for (size_t i = 0; i < num_frame_returned; ++i) {
cudaVideoSurfaceFormat format = decoder->GetOutputFormat(); cudaVideoSurfaceFormat format = decoder->GetOutputFormat();
LOG_ERROR("3");
if (format == cudaVideoSurfaceFormat_NV12) { if (format == cudaVideoSurfaceFormat_NV12) {
uint8_t *decoded_frame_buffer = nullptr; uint8_t *decoded_frame_buffer = nullptr;
decoded_frame_buffer = decoder->GetFrame(); decoded_frame_buffer = decoder->GetFrame();
LOG_ERROR("4");
if (decoded_frame_buffer) { if (decoded_frame_buffer) {
if (on_receive_decoded_frame) { if (on_receive_decoded_frame) {
VideoFrame decoded_frame( VideoFrame decoded_frame(

View File

@@ -7,7 +7,7 @@
#include "nvcodec_common.h" #include "nvcodec_common.h"
// #define SAVE_RECEIVED_NV12_STREAM // #define SAVE_RECEIVED_NV12_STREAM
// #define SAVE_ENCODED_H264_STREAM #define SAVE_ENCODED_H264_STREAM
NvidiaVideoEncoder::NvidiaVideoEncoder() {} NvidiaVideoEncoder::NvidiaVideoEncoder() {}
NvidiaVideoEncoder::~NvidiaVideoEncoder() { NvidiaVideoEncoder::~NvidiaVideoEncoder() {

24
src/qos/bwe_defines.cc Normal file
View 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

View File

@@ -55,4 +55,9 @@ class RealTimeClock : public Clock {
return TimeMicrosToNtp(timestamp.us()); return TimeMicrosToNtp(timestamp.us());
} }
}; };
Clock* Clock::GetRealTimeClock() {
static Clock* const clock = new RealTimeClock();
return clock;
}
} // namespace webrtc } // namespace webrtc

59
src/qos/ntp_time_util.cc Normal file
View 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

View File

@@ -449,6 +449,14 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
RtpPacket rtp_packet; RtpPacket rtp_packet;
rtp_packet.SetVerion(version_); rtp_packet.SetVerion(version_);
rtp_packet.SetHasPadding(has_padding_); 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.SetHasExtension(has_extension_);
rtp_packet.SetMarker(1); rtp_packet.SetMarker(1);
rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_)); rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
@@ -490,6 +498,14 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
RtpPacket rtp_packet; RtpPacket rtp_packet;
rtp_packet.SetVerion(version_); rtp_packet.SetVerion(version_);
rtp_packet.SetHasPadding(has_padding_); 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.SetHasExtension(has_extension_);
rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0); rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0);
rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_)); rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
@@ -541,6 +557,14 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
RtpPacket rtp_packet; RtpPacket rtp_packet;
rtp_packet.SetVerion(version_); rtp_packet.SetVerion(version_);
rtp_packet.SetHasPadding(has_padding_); 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.SetHasExtension(has_extension_);
rtp_packet.SetMarker(1); rtp_packet.SetMarker(1);
rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_)); rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));
@@ -569,6 +593,14 @@ void RtpCodec::Encode(uint8_t* buffer, uint32_t size,
RtpPacket rtp_packet; RtpPacket rtp_packet;
rtp_packet.SetVerion(version_); rtp_packet.SetVerion(version_);
rtp_packet.SetHasPadding(has_padding_); 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.SetHasExtension(has_extension_);
rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0); rtp_packet.SetMarker(index == packet_num - 1 ? 1 : 0);
rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_)); rtp_packet.SetPayloadType(RtpPacket::PAYLOAD_TYPE(payload_type_));

View File

@@ -35,7 +35,7 @@ void RtpPacket::ParseRtpData() {
RtpPacket::RtpPacket() : buffer_(new uint8_t[DEFAULT_MTU]), size_(DEFAULT_MTU) { RtpPacket::RtpPacket() : buffer_(new uint8_t[DEFAULT_MTU]), size_(DEFAULT_MTU) {
memset(buffer_, 0, DEFAULT_MTU); memset(buffer_, 0, DEFAULT_MTU);
ParseRtpData(); // ParseRtpData();
} }
RtpPacket::RtpPacket(uint32_t size) : buffer_(new uint8_t[size]), size_(size) {} RtpPacket::RtpPacket(uint32_t size) : buffer_(new uint8_t[size]), size_(size) {}

View File

@@ -213,12 +213,12 @@ class RtpPacket {
void SetCsrcs(std::vector<uint32_t> &csrcs) { csrcs_ = csrcs; } void SetCsrcs(std::vector<uint32_t> &csrcs) { csrcs_ = csrcs; }
void SetExtensionProfile(uint16_t extension_profile) { void SetExtensionProfile(uint16_t extension_profile) {
extension_profile_ = extension_profile; // extension_profile_ = extension_profile;
} }
void SetExtensionData(uint8_t *extension_data, uint16_t extension_len) { void SetExtensionData(uint8_t *extension_data, uint16_t extension_len) {
extension_len_ = extension_len; // extension_len_ = extension_len;
extension_data_ = new uint8_t[extension_len_]; // extension_data_ = new uint8_t[extension_len_];
memcpy(extension_data_, extension_data, extension_len_); // memcpy(extension_data_, extension_data, extension_len_);
} }
void SetAbsoluteSendTimestamp(uint32_t abs_send_time) { void SetAbsoluteSendTimestamp(uint32_t abs_send_time) {
@@ -228,9 +228,10 @@ class RtpPacket {
// Allocate memory for the extension data if not already allocated // Allocate memory for the extension data if not already allocated
if (extension_data_ == nullptr) { if (extension_data_ == nullptr) {
extension_data_ = new uint8_t[4]; // 2 bytes for profile, 2 bytes for extension_data_ =
// length, 3 bytes for abs_send_time (uint8_t *)malloc(5); // 2 bytes for profile, 2 bytes for length, 3
extension_len_ = 4; // bytes for abs_send_time
extension_len_ = 5;
} }
// Set the extension profile to 0xBEDE (one-byte header) // Set the extension profile to 0xBEDE (one-byte header)

View File

@@ -131,8 +131,10 @@ void IceTransport::InitializeChannels(
data_channel_send_->Initialize(RtpPacket::PAYLOAD_TYPE::DATA); data_channel_send_->Initialize(RtpPacket::PAYLOAD_TYPE::DATA);
video_channel_receive_ = std::make_unique<VideoChannelReceive>( video_channel_receive_ = std::make_unique<VideoChannelReceive>(
ice_agent_, ice_io_statistics_, ice_agent_, ice_io_statistics_, [this](VideoFrame &video_frame) {
[this](VideoFrame &video_frame) { OnReceiveCompleteFrame(video_frame); }); LOG_ERROR("ccccccc");
OnReceiveCompleteFrame(video_frame);
});
audio_channel_receive_ = std::make_unique<AudioChannelReceive>( audio_channel_receive_ = std::make_unique<AudioChannelReceive>(
ice_agent_, ice_io_statistics_, [this](const char *data, size_t size) { 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()) { if (!feedback.Parse(rtcp_block) || feedback.packets().empty()) {
return false; return false;
} }
uint32_t first_media_source_ssrc = feedback.packets()[0].ssrc; // uint32_t first_media_source_ssrc = feedback.packets()[0].ssrc;
if (first_media_source_ssrc == local_media_ssrc() || // if (first_media_source_ssrc == local_media_ssrc() ||
registered_ssrcs_.contains(first_media_source_ssrc)) { // registered_ssrcs_.contains(first_media_source_ssrc)) {
rtcp_packet_info->congestion_control_feedback.emplace(std::move(feedback)); // 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; return true;
} }
@@ -374,6 +379,7 @@ void IceTransport::OnReceiveCompleteFrame(VideoFrame &video_frame) {
x_video_frame.width = video_frame.Width(); x_video_frame.width = video_frame.Width();
x_video_frame.height = video_frame.Height(); x_video_frame.height = video_frame.Height();
x_video_frame.size = video_frame.Size(); x_video_frame.size = video_frame.Size();
LOG_ERROR("ccccccc 2222222");
on_receive_video_(&x_video_frame, remote_user_id_.data(), on_receive_video_(&x_video_frame, remote_user_id_.data(),
remote_user_id_.size(), user_data_); remote_user_id_.size(), user_data_);
} }

View File

@@ -74,6 +74,7 @@ class IceTransport {
std::function<void(const XVideoFrame *, const char *, const size_t, std::function<void(const XVideoFrame *, const char *, const size_t,
void *)> void *)>
on_receive_video) { on_receive_video) {
LOG_ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!");
on_receive_video_ = on_receive_video; on_receive_video_ = on_receive_video;
} }
@@ -240,7 +241,6 @@ class IceTransport {
std::unique_ptr<RtpAudioSender> rtp_audio_sender_ = nullptr; std::unique_ptr<RtpAudioSender> rtp_audio_sender_ = nullptr;
std::unique_ptr<RtpDataReceiver> rtp_data_receiver_ = nullptr; std::unique_ptr<RtpDataReceiver> rtp_data_receiver_ = nullptr;
std::unique_ptr<RtpDataSender> rtp_data_sender_ = nullptr; std::unique_ptr<RtpDataSender> rtp_data_sender_ = nullptr;
RtpPacket pop_packet_;
bool start_send_packet_ = false; bool start_send_packet_ = false;
uint32_t last_complete_frame_ts_ = 0; uint32_t last_complete_frame_ts_ = 0;

View File

@@ -41,9 +41,12 @@ target("log")
target("common") target("common")
set_kind("object") set_kind("object")
add_deps("log")
add_files("src/common/common.cpp", add_files("src/common/common.cpp",
"src/common/rtc_base/*.cc",
"src/common/rtc_base/numerics/*.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}) add_includedirs("src/common", {public = true})
target("inih") target("inih")