mirror of
https://github.com/sipeed/MaixCDK.git
synced 2026-09-10 21:59:54 -05:00
12
components/3rd_party/datachannel/CMakeLists.txt
vendored
12
components/3rd_party/datachannel/CMakeLists.txt
vendored
@@ -4,11 +4,10 @@ if(CONFIG_LIBDATACHANNEL_COMPILE_FROM_SOURCE)
|
||||
set(compile_from_src 1)
|
||||
endif()
|
||||
|
||||
if (compile_from_src)
|
||||
set(libdatachannel_version_str "${CONFIG_LIBDATACHANNEL_VERSION_MAJOR}.${CONFIG_LIBDATACHANNEL_VERSION_MINOR}.${CONFIG_LIBDATACHANNEL_VERSION_PATCH}")
|
||||
set(srcs_path "${DL_EXTRACTED_PATH}/libdatachannel_srcs/libdatachannel-${libdatachannel_version_str}")
|
||||
list(APPEND ADD_INCLUDE "${srcs_path}/include" ".")
|
||||
|
||||
if (compile_from_src)
|
||||
list(APPEND ADD_PRIVATE_INCLUDE "${srcs_path}/include/rtc" "${srcs_path}/src")
|
||||
|
||||
if(PLATFORM_MAIXCAM)
|
||||
@@ -19,16 +18,19 @@ if (compile_from_src)
|
||||
aux_source_directory("${srcs_path}/src/impl" ADD_SRCS)
|
||||
list(APPEND ADD_REQUIREMENTS openssl json libjuice libsrtp plog usrsctp cpp-httplib)
|
||||
list(APPEND ADD_DEFINITIONS_PRIVATE -DJUICE_STATIC -DRTC_ENABLE_MEDIA=1 -DRTC_ENABLE_WEBSOCKET=1 -DRTC_EXPORTS -DRTC_SYSTEM_JUICE=0 -DRTC_SYSTEM_SRTP=0 -DUSE_GNUTLS=0 -DUSE_NICE=0 -D_GNU_SOURCE -Ddatachannel_EXPORTS -DNDEBUG -w)
|
||||
|
||||
register_component(DYNAMIC)
|
||||
else()
|
||||
list(APPEND ADD_INCLUDE "include" ".")
|
||||
list(APPEND ADD_REQUIREMENTS json cpp-httplib)
|
||||
if (PLATFORM_MAIXCAM)
|
||||
list(APPEND ADD_DYNAMIC_LIB "so/maixcam/libdatachannel.so")
|
||||
list(APPEND ADD_DYNAMIC_LIB "lib/maixcam/libdatachannel.so")
|
||||
elseif(PLATFORM_MAIXCAM2)
|
||||
list(APPEND ADD_DYNAMIC_LIB "so/maixcam2/libdatachannel.so")
|
||||
list(APPEND ADD_DYNAMIC_LIB "lib/maixcam2/libdatachannel.so")
|
||||
else()
|
||||
list(APPEND ADD_REQUIREMENTS libdatachannel)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
register_component()
|
||||
endif()
|
||||
|
||||
|
||||
57
components/3rd_party/datachannel/include/rtc/av1rtppacketizer.hpp
vendored
Normal file
57
components/3rd_party/datachannel/include/rtc/av1rtppacketizer.hpp
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Copyright (c) 2023 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_AV1_RTP_PACKETIZER_H
|
||||
#define RTC_AV1_RTP_PACKETIZER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "mediahandler.hpp"
|
||||
#include "nalunit.hpp"
|
||||
#include "rtppacketizer.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// RTP packetization of AV1 payload
|
||||
class RTC_CPP_EXPORT AV1RtpPacketizer final : public RtpPacketizer {
|
||||
public:
|
||||
inline static const uint32_t ClockRate = VideoClockRate;
|
||||
[[deprecated("Use ClockRate")]] inline static const uint32_t defaultClockRate = ClockRate;
|
||||
|
||||
// Define how OBUs are seperated in a AV1 Sample
|
||||
enum class Packetization {
|
||||
Obu = RTC_OBU_PACKETIZED_OBU,
|
||||
TemporalUnit = RTC_OBU_PACKETIZED_TEMPORAL_UNIT,
|
||||
};
|
||||
|
||||
// Constructs AV1 payload packetizer with given RTP configuration.
|
||||
// @note RTP configuration is used in packetization process which may change some configuration
|
||||
// properties such as sequence number.
|
||||
AV1RtpPacketizer(Packetization packetization, shared_ptr<RtpPacketizationConfig> rtpConfig,
|
||||
size_t maxFragmentSize = DefaultMaxFragmentSize);
|
||||
|
||||
private:
|
||||
static std::vector<binary> extractTemporalUnitObus(const binary &data);
|
||||
|
||||
std::vector<binary> fragment(binary data) override;
|
||||
std::vector<binary> fragmentObu(const binary &data);
|
||||
|
||||
const Packetization mPacketization;
|
||||
const size_t mMaxFragmentSize;
|
||||
|
||||
std::unique_ptr<binary> mSequenceHeader;
|
||||
};
|
||||
|
||||
// For backward compatibility, do not use
|
||||
using AV1PacketizationHandler [[deprecated("Add AV1RtpPacketizer directly")]] = PacketizationHandler;
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_AV1_RTP_PACKETIZER_H */
|
||||
77
components/3rd_party/datachannel/include/rtc/candidate.hpp
vendored
Normal file
77
components/3rd_party/datachannel/include/rtc/candidate.hpp
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_CANDIDATE_H
|
||||
#define RTC_CANDIDATE_H
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class RTC_CPP_EXPORT Candidate {
|
||||
public:
|
||||
enum class Family { Unresolved, Ipv4, Ipv6 };
|
||||
enum class Type { Unknown, Host, ServerReflexive, PeerReflexive, Relayed };
|
||||
enum class TransportType { Unknown, Udp, TcpActive, TcpPassive, TcpSo, TcpUnknown };
|
||||
|
||||
Candidate();
|
||||
Candidate(string candidate);
|
||||
Candidate(string candidate, string mid);
|
||||
|
||||
void hintMid(string mid);
|
||||
void changeAddress(string addr);
|
||||
void changeAddress(string addr, uint16_t port);
|
||||
void changeAddress(string addr, string service);
|
||||
|
||||
enum class ResolveMode { Simple, Lookup };
|
||||
bool resolve(ResolveMode mode = ResolveMode::Simple);
|
||||
|
||||
Type type() const;
|
||||
TransportType transportType() const;
|
||||
uint32_t priority() const;
|
||||
string candidate() const;
|
||||
string mid() const;
|
||||
operator string() const;
|
||||
|
||||
bool operator==(const Candidate &other) const;
|
||||
bool operator!=(const Candidate &other) const;
|
||||
|
||||
bool isResolved() const;
|
||||
Family family() const;
|
||||
optional<string> address() const;
|
||||
optional<uint16_t> port() const;
|
||||
|
||||
private:
|
||||
void parse(string candidate);
|
||||
|
||||
string mFoundation;
|
||||
uint32_t mComponent, mPriority;
|
||||
string mTypeString, mTransportString;
|
||||
Type mType;
|
||||
TransportType mTransportType;
|
||||
string mNode, mService;
|
||||
string mTail;
|
||||
|
||||
optional<string> mMid;
|
||||
|
||||
// Extracted on resolution
|
||||
Family mFamily;
|
||||
string mAddress;
|
||||
uint16_t mPort;
|
||||
};
|
||||
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, const Candidate &candidate);
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, const Candidate::Type &type);
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out,
|
||||
const Candidate::TransportType &transportType);
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
61
components/3rd_party/datachannel/include/rtc/channel.hpp
vendored
Normal file
61
components/3rd_party/datachannel/include/rtc/channel.hpp
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright (c) 2019-2021 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_CHANNEL_H
|
||||
#define RTC_CHANNEL_H
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
namespace impl {
|
||||
struct Channel;
|
||||
}
|
||||
|
||||
class RTC_CPP_EXPORT Channel : private CheshireCat<impl::Channel> {
|
||||
public:
|
||||
virtual ~Channel();
|
||||
|
||||
virtual void close() = 0;
|
||||
virtual bool send(message_variant data) = 0; // returns false if buffered
|
||||
virtual bool send(const byte *data, size_t size) = 0;
|
||||
|
||||
virtual bool isOpen() const = 0;
|
||||
virtual bool isClosed() const = 0;
|
||||
virtual size_t maxMessageSize() const; // max message size in a call to send
|
||||
virtual size_t bufferedAmount() const; // total size buffered to send
|
||||
|
||||
void onOpen(std::function<void()> callback);
|
||||
void onClosed(std::function<void()> callback);
|
||||
void onError(std::function<void(string error)> callback);
|
||||
|
||||
void onMessage(std::function<void(message_variant data)> callback);
|
||||
void onMessage(std::function<void(binary data)> binaryCallback,
|
||||
std::function<void(string data)> stringCallback);
|
||||
|
||||
void onBufferedAmountLow(std::function<void()> callback);
|
||||
void setBufferedAmountLowThreshold(size_t amount);
|
||||
|
||||
void resetCallbacks();
|
||||
|
||||
// Extended API
|
||||
optional<message_variant> receive(); // only if onMessage unset
|
||||
optional<message_variant> peek(); // only if onMessage unset
|
||||
size_t availableAmount() const; // total size available to receive
|
||||
void onAvailable(std::function<void()> callback);
|
||||
|
||||
protected:
|
||||
Channel(impl_ptr<impl::Channel> impl);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // RTC_CHANNEL_H
|
||||
85
components/3rd_party/datachannel/include/rtc/common.hpp
vendored
Normal file
85
components/3rd_party/datachannel/include/rtc/common.hpp
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_COMMON_H
|
||||
#define RTC_COMMON_H
|
||||
|
||||
#ifdef RTC_STATIC
|
||||
#define RTC_CPP_EXPORT
|
||||
#else // dynamic library
|
||||
#ifdef _WIN32
|
||||
#ifdef RTC_EXPORTS
|
||||
#define RTC_CPP_EXPORT __declspec(dllexport) // building the library
|
||||
#else
|
||||
#define RTC_CPP_EXPORT __declspec(dllimport) // using the library
|
||||
#endif
|
||||
#else // not WIN32
|
||||
#define RTC_CPP_EXPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0602 // Windows 8
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4251) // disable "X needs to have dll-interface..."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef RTC_ENABLE_WEBSOCKET
|
||||
#define RTC_ENABLE_WEBSOCKET 1
|
||||
#endif
|
||||
|
||||
#ifndef RTC_ENABLE_MEDIA
|
||||
#define RTC_ENABLE_MEDIA 1
|
||||
#endif
|
||||
|
||||
#include "rtc.h" // for C API defines
|
||||
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
using std::byte;
|
||||
using std::nullopt;
|
||||
using std::optional;
|
||||
using std::shared_ptr;
|
||||
using std::string;
|
||||
using std::string_view;
|
||||
using std::unique_ptr;
|
||||
using std::variant;
|
||||
using std::weak_ptr;
|
||||
|
||||
using binary = std::vector<byte>;
|
||||
using message_variant = variant<binary, string>;
|
||||
|
||||
using std::int16_t;
|
||||
using std::int32_t;
|
||||
using std::int64_t;
|
||||
using std::int8_t;
|
||||
using std::ptrdiff_t;
|
||||
using std::size_t;
|
||||
using std::uint16_t;
|
||||
using std::uint32_t;
|
||||
using std::uint64_t;
|
||||
using std::uint8_t;
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
129
components/3rd_party/datachannel/include/rtc/configuration.hpp
vendored
Normal file
129
components/3rd_party/datachannel/include/rtc/configuration.hpp
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_ICE_CONFIGURATION_H
|
||||
#define RTC_ICE_CONFIGURATION_H
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
struct RTC_CPP_EXPORT IceServer {
|
||||
enum class Type { Stun, Turn };
|
||||
enum class RelayType { TurnUdp, TurnTcp, TurnTls };
|
||||
|
||||
// Any type
|
||||
IceServer(const string &url);
|
||||
|
||||
// STUN
|
||||
IceServer(string hostname_, uint16_t port_);
|
||||
IceServer(string hostname_, string service_);
|
||||
|
||||
// TURN
|
||||
IceServer(string hostname_, uint16_t port, string username_, string password_,
|
||||
RelayType relayType_ = RelayType::TurnUdp);
|
||||
IceServer(string hostname_, string service_, string username_, string password_,
|
||||
RelayType relayType_ = RelayType::TurnUdp);
|
||||
|
||||
string hostname;
|
||||
uint16_t port;
|
||||
Type type;
|
||||
string username;
|
||||
string password;
|
||||
RelayType relayType;
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT ProxyServer {
|
||||
enum class Type { Http, Socks5 };
|
||||
|
||||
ProxyServer(const string &url);
|
||||
|
||||
ProxyServer(Type type_, string hostname_, uint16_t port_);
|
||||
ProxyServer(Type type_, string hostname_, uint16_t port_, string username_, string password_);
|
||||
|
||||
Type type;
|
||||
string hostname;
|
||||
uint16_t port;
|
||||
optional<string> username;
|
||||
optional<string> password;
|
||||
};
|
||||
|
||||
enum class CertificateType {
|
||||
Default = RTC_CERTIFICATE_DEFAULT, // ECDSA
|
||||
Ecdsa = RTC_CERTIFICATE_ECDSA,
|
||||
Rsa = RTC_CERTIFICATE_RSA
|
||||
};
|
||||
|
||||
enum class TransportPolicy { All = RTC_TRANSPORT_POLICY_ALL, Relay = RTC_TRANSPORT_POLICY_RELAY };
|
||||
|
||||
struct RTC_CPP_EXPORT Configuration {
|
||||
// ICE settings
|
||||
std::vector<IceServer> iceServers;
|
||||
optional<ProxyServer> proxyServer; // libnice only
|
||||
optional<string> bindAddress; // libjuice only, default any
|
||||
|
||||
// Options
|
||||
CertificateType certificateType = CertificateType::Default;
|
||||
TransportPolicy iceTransportPolicy = TransportPolicy::All;
|
||||
bool enableIceTcp = false;
|
||||
bool enableIceUdpMux = false; // libjuice only
|
||||
bool disableAutoNegotiation = false;
|
||||
bool disableAutoGathering = false;
|
||||
bool forceMediaTransport = false;
|
||||
bool disableFingerprintVerification = false;
|
||||
|
||||
// Port range
|
||||
uint16_t portRangeBegin = 1024;
|
||||
uint16_t portRangeEnd = 65535;
|
||||
|
||||
// Network MTU
|
||||
optional<size_t> mtu;
|
||||
|
||||
// Local maximum message size for Data Channels
|
||||
optional<size_t> maxMessageSize;
|
||||
|
||||
// Certificates and private keys
|
||||
optional<string> certificatePemFile;
|
||||
optional<string> keyPemFile;
|
||||
optional<string> keyPemPass;
|
||||
};
|
||||
|
||||
#ifdef RTC_ENABLE_WEBSOCKET
|
||||
|
||||
struct WebSocketConfiguration {
|
||||
bool disableTlsVerification = false; // if true, don't verify the TLS certificate
|
||||
optional<ProxyServer> proxyServer; // only non-authenticated http supported for now
|
||||
std::vector<string> protocols;
|
||||
optional<std::chrono::milliseconds> connectionTimeout; // zero to disable
|
||||
optional<std::chrono::milliseconds> pingInterval; // zero to disable
|
||||
optional<int> maxOutstandingPings;
|
||||
optional<string> caCertificatePemFile;
|
||||
optional<string> certificatePemFile;
|
||||
optional<string> keyPemFile;
|
||||
optional<string> keyPemPass;
|
||||
optional<size_t> maxMessageSize;
|
||||
};
|
||||
|
||||
struct WebSocketServerConfiguration {
|
||||
uint16_t port = 8080;
|
||||
bool enableTls = false;
|
||||
optional<string> certificatePemFile;
|
||||
optional<string> keyPemFile;
|
||||
optional<string> keyPemPass;
|
||||
optional<string> bindAddress;
|
||||
optional<std::chrono::milliseconds> connectionTimeout;
|
||||
optional<size_t> maxMessageSize;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
80
components/3rd_party/datachannel/include/rtc/datachannel.hpp
vendored
Normal file
80
components/3rd_party/datachannel/include/rtc/datachannel.hpp
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_DATA_CHANNEL_H
|
||||
#define RTC_DATA_CHANNEL_H
|
||||
|
||||
#include "channel.hpp"
|
||||
#include "common.hpp"
|
||||
#include "reliability.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
namespace impl {
|
||||
|
||||
struct DataChannel;
|
||||
struct PeerConnection;
|
||||
|
||||
} // namespace impl
|
||||
|
||||
class RTC_CPP_EXPORT DataChannel final : private CheshireCat<impl::DataChannel>, public Channel {
|
||||
public:
|
||||
DataChannel(impl_ptr<impl::DataChannel> impl);
|
||||
~DataChannel() override;
|
||||
|
||||
optional<uint16_t> stream() const;
|
||||
optional<uint16_t> id() const;
|
||||
string label() const;
|
||||
string protocol() const;
|
||||
Reliability reliability() const;
|
||||
|
||||
bool isOpen(void) const override;
|
||||
bool isClosed(void) const override;
|
||||
size_t maxMessageSize() const override;
|
||||
|
||||
void close(void) override;
|
||||
bool send(message_variant data) override;
|
||||
bool send(const byte *data, size_t size) override;
|
||||
template <typename Buffer> bool sendBuffer(const Buffer &buf);
|
||||
template <typename Iterator> bool sendBuffer(Iterator first, Iterator last);
|
||||
|
||||
private:
|
||||
using CheshireCat<impl::DataChannel>::impl;
|
||||
};
|
||||
|
||||
template <typename Buffer> std::pair<const byte *, size_t> to_bytes(const Buffer &buf) {
|
||||
using T = typename std::remove_pointer<decltype(buf.data())>::type;
|
||||
using E = typename std::conditional<std::is_void<T>::value, byte, T>::type;
|
||||
return std::make_pair(static_cast<const byte *>(static_cast<const void *>(buf.data())),
|
||||
buf.size() * sizeof(E));
|
||||
}
|
||||
|
||||
template <typename Buffer> bool DataChannel::sendBuffer(const Buffer &buf) {
|
||||
auto [bytes, size] = to_bytes(buf);
|
||||
return send(bytes, size);
|
||||
}
|
||||
|
||||
template <typename Iterator> bool DataChannel::sendBuffer(Iterator first, Iterator last) {
|
||||
size_t size = 0;
|
||||
for (Iterator it = first; it != last; ++it)
|
||||
size += it->size();
|
||||
|
||||
binary buffer(size);
|
||||
byte *pos = buffer.data();
|
||||
for (Iterator it = first; it != last; ++it) {
|
||||
auto [bytes, len] = to_bytes(*it);
|
||||
pos = std::copy(bytes, bytes + len, pos);
|
||||
}
|
||||
return send(std::move(buffer));
|
||||
}
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
107
components/3rd_party/datachannel/include/rtc/dependencydescriptor.hpp
vendored
Normal file
107
components/3rd_party/datachannel/include/rtc/dependencydescriptor.hpp
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Shigemasa Watanabe (Wandbox)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_DEPENDENCY_DESCRIPTOR_H
|
||||
#define RTC_DEPENDENCY_DESCRIPTOR_H
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <bitset>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
struct BitWriter {
|
||||
static BitWriter fromSizeBits(byte *buf, size_t offsetBits, size_t sizeBits);
|
||||
static BitWriter fromNull();
|
||||
|
||||
size_t getWrittenBits() const;
|
||||
|
||||
bool write(uint64_t v, size_t bits);
|
||||
// Write non-symmetric unsigned encoded integer
|
||||
// ref: https://aomediacodec.github.io/av1-rtp-spec/#a82-syntax
|
||||
bool writeNonSymmetric(uint64_t v, uint64_t n);
|
||||
|
||||
private:
|
||||
size_t writePartialByte(uint8_t *p, size_t offset, uint64_t v, size_t bits);
|
||||
|
||||
private:
|
||||
byte *mBuf = nullptr;
|
||||
size_t mInitialOffset = 0;
|
||||
size_t mOffset = 0;
|
||||
size_t mSize = 0;
|
||||
};
|
||||
|
||||
enum class DecodeTargetIndication {
|
||||
NotPresent = 0,
|
||||
Discardable = 1,
|
||||
Switch = 2,
|
||||
Required = 3,
|
||||
};
|
||||
|
||||
struct RenderResolution {
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
};
|
||||
|
||||
struct FrameDependencyTemplate {
|
||||
int spatialId = 0;
|
||||
int temporalId = 0;
|
||||
std::vector<DecodeTargetIndication> decodeTargetIndications;
|
||||
std::vector<int> frameDiffs;
|
||||
std::vector<int> chainDiffs;
|
||||
};
|
||||
|
||||
struct FrameDependencyStructure {
|
||||
int templateIdOffset = 0;
|
||||
int decodeTargetCount = 0;
|
||||
int chainCount = 0;
|
||||
std::vector<int> decodeTargetProtectedBy;
|
||||
std::vector<RenderResolution> resolutions;
|
||||
std::vector<FrameDependencyTemplate> templates;
|
||||
};
|
||||
|
||||
struct DependencyDescriptor {
|
||||
bool startOfFrame = true;
|
||||
bool endOfFrame = true;
|
||||
int frameNumber = 0;
|
||||
FrameDependencyTemplate dependencyTemplate;
|
||||
std::optional<RenderResolution> resolution;
|
||||
std::optional<uint32_t> activeDecodeTargetsBitmask;
|
||||
bool structureAttached;
|
||||
};
|
||||
|
||||
struct DependencyDescriptorContext {
|
||||
DependencyDescriptor descriptor;
|
||||
std::bitset<32> activeChains;
|
||||
FrameDependencyStructure structure;
|
||||
};
|
||||
|
||||
// Write dependency descriptor to RTP Header Extension
|
||||
// Dependency descriptor specification is here:
|
||||
// https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension
|
||||
class DependencyDescriptorWriter {
|
||||
public:
|
||||
explicit DependencyDescriptorWriter(const DependencyDescriptorContext& context);
|
||||
size_t getSizeBits() const;
|
||||
size_t getSize() const;
|
||||
void writeTo(byte *buf, size_t sizeBytes) const;
|
||||
|
||||
private:
|
||||
void doWriteTo(BitWriter &writer) const;
|
||||
void writeBits(BitWriter &writer, uint64_t v, size_t bits) const;
|
||||
void writeNonSymmetric(BitWriter &writer, uint64_t v, uint64_t n) const;
|
||||
|
||||
private:
|
||||
const FrameDependencyStructure &mStructure;
|
||||
std::bitset<32> mActiveChains;
|
||||
const DependencyDescriptor &mDescriptor;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
328
components/3rd_party/datachannel/include/rtc/description.hpp
vendored
Normal file
328
components/3rd_party/datachannel/include/rtc/description.hpp
vendored
Normal file
@@ -0,0 +1,328 @@
|
||||
/**
|
||||
* Copyright (c) 2019-2020 Paul-Louis Ageneau
|
||||
* Copyright (c) 2020 Staz Modrzynski
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_DESCRIPTION_H
|
||||
#define RTC_DESCRIPTION_H
|
||||
|
||||
#include "candidate.hpp"
|
||||
#include "common.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
const string DEFAULT_OPUS_AUDIO_PROFILE =
|
||||
"minptime=10;maxaveragebitrate=96000;stereo=1;sprop-stereo=1;useinbandfec=1";
|
||||
|
||||
// Use Constrained Baseline profile Level 3.1 (necessary for Firefox)
|
||||
// https://developer.mozilla.org/en-US/docs/Web/Media/Formats/WebRTC_codecs#Supported_video_codecs
|
||||
// TODO: Should be 42E0 but 42C0 appears to be more compatible. Investigate this.
|
||||
const string DEFAULT_H264_VIDEO_PROFILE =
|
||||
"profile-level-id=42e01f;packetization-mode=1;level-asymmetry-allowed=1";
|
||||
|
||||
struct CertificateFingerprint {
|
||||
enum class Algorithm { Sha1, Sha224, Sha256, Sha384, Sha512 };
|
||||
static string AlgorithmIdentifier(Algorithm algorithm);
|
||||
static size_t AlgorithmSize(Algorithm algorithm);
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
Algorithm algorithm;
|
||||
string value;
|
||||
};
|
||||
|
||||
class RTC_CPP_EXPORT Description {
|
||||
public:
|
||||
enum class Type { Unspec, Offer, Answer, Pranswer, Rollback };
|
||||
enum class Role { ActPass, Passive, Active };
|
||||
|
||||
enum class Direction {
|
||||
SendOnly = RTC_DIRECTION_SENDONLY,
|
||||
RecvOnly = RTC_DIRECTION_RECVONLY,
|
||||
SendRecv = RTC_DIRECTION_SENDRECV,
|
||||
Inactive = RTC_DIRECTION_INACTIVE,
|
||||
Unknown = RTC_DIRECTION_UNKNOWN
|
||||
};
|
||||
|
||||
Description(const string &sdp, Type type = Type::Unspec, Role role = Role::ActPass);
|
||||
Description(const string &sdp, string typeString);
|
||||
|
||||
Type type() const;
|
||||
string typeString() const;
|
||||
Role role() const;
|
||||
string bundleMid() const;
|
||||
std::vector<string> iceOptions() const;
|
||||
optional<string> iceUfrag() const;
|
||||
optional<string> icePwd() const;
|
||||
optional<CertificateFingerprint> fingerprint() const;
|
||||
bool ended() const;
|
||||
|
||||
void hintType(Type type);
|
||||
void addIceOption(string option);
|
||||
void removeIceOption(const string &option);
|
||||
void setIceAttribute(string ufrag, string pwd);
|
||||
void setFingerprint(CertificateFingerprint f);
|
||||
|
||||
std::vector<string> attributes() const;
|
||||
void addAttribute(string attr);
|
||||
void removeAttribute(const string &attr);
|
||||
|
||||
std::vector<Candidate> candidates() const;
|
||||
std::vector<Candidate> extractCandidates();
|
||||
bool hasCandidate(const Candidate &candidate) const;
|
||||
void addCandidate(Candidate candidate);
|
||||
void addCandidates(std::vector<Candidate> candidates);
|
||||
void endCandidates();
|
||||
|
||||
operator string() const;
|
||||
string generateSdp(string_view eol = "\r\n") const;
|
||||
string generateApplicationSdp(string_view eol = "\r\n") const;
|
||||
|
||||
class RTC_CPP_EXPORT Entry {
|
||||
public:
|
||||
virtual ~Entry() = default;
|
||||
|
||||
virtual string type() const;
|
||||
virtual string protocol() const;
|
||||
virtual string description() const;
|
||||
virtual string mid() const;
|
||||
|
||||
Direction direction() const;
|
||||
void setDirection(Direction dir);
|
||||
|
||||
bool isRemoved() const;
|
||||
void markRemoved();
|
||||
|
||||
std::vector<string> attributes() const;
|
||||
void addAttribute(string attr);
|
||||
void removeAttribute(const string &attr);
|
||||
void addRid(string rid);
|
||||
|
||||
struct RTC_CPP_EXPORT ExtMap {
|
||||
static int parseId(string_view description);
|
||||
|
||||
ExtMap(int id, string uri, Direction direction = Direction::Unknown);
|
||||
ExtMap(string_view description);
|
||||
|
||||
void setDescription(string_view description);
|
||||
|
||||
int id;
|
||||
string uri;
|
||||
string attributes;
|
||||
Direction direction = Direction::Unknown;
|
||||
};
|
||||
|
||||
std::vector<int> extIds();
|
||||
ExtMap *extMap(int id);
|
||||
const ExtMap *extMap(int id) const;
|
||||
void addExtMap(ExtMap map);
|
||||
void removeExtMap(int id);
|
||||
|
||||
operator string() const;
|
||||
string generateSdp(string_view eol = "\r\n", string_view addr = "0.0.0.0",
|
||||
uint16_t port = 9) const;
|
||||
|
||||
virtual void parseSdpLine(string_view line);
|
||||
|
||||
protected:
|
||||
Entry(const string &mline, string mid, Direction dir = Direction::Unknown);
|
||||
|
||||
virtual string generateSdpLines(string_view eol) const;
|
||||
|
||||
std::vector<string> mAttributes;
|
||||
std::map<int, ExtMap> mExtMaps;
|
||||
|
||||
private:
|
||||
string mType;
|
||||
string mProtocol;
|
||||
string mDescription;
|
||||
string mMid;
|
||||
std::vector<string> mRids;
|
||||
Direction mDirection;
|
||||
bool mIsRemoved;
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT Application : public Entry {
|
||||
public:
|
||||
Application(string mid = "data");
|
||||
Application(const string &mline, string mid);
|
||||
virtual ~Application() = default;
|
||||
|
||||
Application reciprocate() const;
|
||||
|
||||
void setSctpPort(uint16_t port);
|
||||
void hintSctpPort(uint16_t port);
|
||||
void setMaxMessageSize(size_t size);
|
||||
|
||||
optional<uint16_t> sctpPort() const;
|
||||
optional<size_t> maxMessageSize() const;
|
||||
|
||||
virtual void parseSdpLine(string_view line) override;
|
||||
|
||||
private:
|
||||
virtual string generateSdpLines(string_view eol) const override;
|
||||
|
||||
optional<uint16_t> mSctpPort;
|
||||
optional<size_t> mMaxMessageSize;
|
||||
};
|
||||
|
||||
// Media (non-data)
|
||||
class RTC_CPP_EXPORT Media : public Entry {
|
||||
public:
|
||||
Media(const string &mline, string mid, Direction dir = Direction::SendOnly);
|
||||
Media(const string &sdp);
|
||||
virtual ~Media() = default;
|
||||
|
||||
string description() const override;
|
||||
Media reciprocate() const;
|
||||
|
||||
void addSSRC(uint32_t ssrc, optional<string> name, optional<string> msid = nullopt,
|
||||
optional<string> trackId = nullopt);
|
||||
void removeSSRC(uint32_t ssrc);
|
||||
void replaceSSRC(uint32_t old, uint32_t ssrc, optional<string> name,
|
||||
optional<string> msid = nullopt, optional<string> trackID = nullopt);
|
||||
bool hasSSRC(uint32_t ssrc) const;
|
||||
void clearSSRCs();
|
||||
std::vector<uint32_t> getSSRCs() const;
|
||||
optional<std::string> getCNameForSsrc(uint32_t ssrc) const;
|
||||
|
||||
int bitrate() const;
|
||||
void setBitrate(int bitrate);
|
||||
|
||||
struct RTC_CPP_EXPORT RtpMap {
|
||||
static int parsePayloadType(string_view description);
|
||||
|
||||
explicit RtpMap(int payloadType);
|
||||
RtpMap(string_view description);
|
||||
|
||||
void setDescription(string_view description);
|
||||
|
||||
void addFeedback(string fb);
|
||||
void removeFeedback(const string &str);
|
||||
void addParameter(string p);
|
||||
void removeParameter(const string &str);
|
||||
|
||||
int payloadType;
|
||||
string format;
|
||||
int clockRate;
|
||||
string encParams;
|
||||
|
||||
std::vector<string> rtcpFbs;
|
||||
std::vector<string> fmtps;
|
||||
};
|
||||
|
||||
bool hasPayloadType(int payloadType) const;
|
||||
std::vector<int> payloadTypes() const;
|
||||
RtpMap *rtpMap(int payloadType);
|
||||
const RtpMap *rtpMap(int payloadType) const;
|
||||
void addRtpMap(RtpMap map);
|
||||
void removeRtpMap(int payloadType);
|
||||
void removeFormat(const string &format);
|
||||
|
||||
void addRtxCodec(int payloadType, int origPayloadType, unsigned int clockRate);
|
||||
|
||||
virtual void parseSdpLine(string_view line) override;
|
||||
|
||||
private:
|
||||
virtual string generateSdpLines(string_view eol) const override;
|
||||
|
||||
int mBas = -1;
|
||||
|
||||
std::vector<int> mOrderedPayloadTypes;
|
||||
std::map<int, RtpMap> mRtpMaps;
|
||||
std::vector<uint32_t> mSsrcs;
|
||||
std::map<uint32_t, string> mCNameMap;
|
||||
};
|
||||
|
||||
class RTC_CPP_EXPORT Audio : public Media {
|
||||
public:
|
||||
Audio(string mid = "audio", Direction dir = Direction::SendOnly);
|
||||
|
||||
void addAudioCodec(int payloadType, string codec, optional<string> profile = std::nullopt);
|
||||
void addOpusCodec(int payloadType, optional<string> profile = DEFAULT_OPUS_AUDIO_PROFILE);
|
||||
void addPCMACodec(int payloadType, optional<string> profile = std::nullopt);
|
||||
void addPCMUCodec(int payloadType, optional<string> profile = std::nullopt);
|
||||
void addAACCodec(int payloadType, optional<string> profile = std::nullopt);
|
||||
void addG722Codec(int payloadType, optional<string> profile = std::nullopt);
|
||||
|
||||
[[deprecated("Use addAACCodec")]] inline void
|
||||
addAacCodec(int payloadType, optional<string> profile = std::nullopt) {
|
||||
addAACCodec(payloadType, std::move(profile));
|
||||
};
|
||||
};
|
||||
|
||||
class RTC_CPP_EXPORT Video : public Media {
|
||||
public:
|
||||
Video(string mid = "video", Direction dir = Direction::SendOnly);
|
||||
|
||||
void addVideoCodec(int payloadType, string codec, optional<string> profile = std::nullopt);
|
||||
|
||||
void addH264Codec(int payloadType, optional<string> profile = DEFAULT_H264_VIDEO_PROFILE);
|
||||
void addH265Codec(int payloadType, optional<string> profile = std::nullopt);
|
||||
void addVP8Codec(int payloadType, optional<string> profile = std::nullopt);
|
||||
void addVP9Codec(int payloadType, optional<string> profile = std::nullopt);
|
||||
void addAV1Codec(int payloadType, optional<string> profile = std::nullopt);
|
||||
};
|
||||
|
||||
bool hasApplication() const;
|
||||
bool hasAudioOrVideo() const;
|
||||
bool hasMid(string_view mid) const;
|
||||
|
||||
int addMedia(Media media);
|
||||
int addMedia(Application application);
|
||||
int addApplication(string mid = "data");
|
||||
int addVideo(string mid = "video", Direction dir = Direction::SendOnly);
|
||||
int addAudio(string mid = "audio", Direction dir = Direction::SendOnly);
|
||||
void clearMedia();
|
||||
|
||||
variant<Media *, Application *> media(int index);
|
||||
variant<const Media *, const Application *> media(int index) const;
|
||||
int mediaCount() const;
|
||||
|
||||
const Application *application() const;
|
||||
Application *application();
|
||||
|
||||
static Type stringToType(const string &typeString);
|
||||
static string typeToString(Type type);
|
||||
|
||||
private:
|
||||
optional<Candidate> defaultCandidate() const;
|
||||
shared_ptr<Entry> createEntry(string mline, string mid, Direction dir);
|
||||
void removeApplication();
|
||||
|
||||
Type mType;
|
||||
|
||||
// Session-level attributes
|
||||
Role mRole;
|
||||
string mUsername;
|
||||
string mSessionId;
|
||||
std::vector<string> mIceOptions;
|
||||
optional<string> mIceUfrag, mIcePwd;
|
||||
optional<CertificateFingerprint> mFingerprint;
|
||||
std::vector<string> mAttributes; // other attributes
|
||||
|
||||
// Entries
|
||||
std::vector<shared_ptr<Entry>> mEntries;
|
||||
shared_ptr<Application> mApplication;
|
||||
|
||||
// Candidates
|
||||
std::vector<Candidate> mCandidates;
|
||||
bool mEnded = false;
|
||||
};
|
||||
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, const Description &description);
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, Description::Type type);
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, Description::Role role);
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, const Description::Direction &direction);
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
32
components/3rd_party/datachannel/include/rtc/frameinfo.hpp
vendored
Normal file
32
components/3rd_party/datachannel/include/rtc/frameinfo.hpp
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (c) 2019-2020 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_FRAMEINFO_H
|
||||
#define RTC_FRAMEINFO_H
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
struct RTC_CPP_EXPORT FrameInfo {
|
||||
FrameInfo(uint32_t timestamp) : timestamp(timestamp) {};
|
||||
template<typename Period = std::ratio<1>> FrameInfo(std::chrono::duration<double, Period> timestamp) : timestampSeconds(timestamp) {};
|
||||
|
||||
[[deprecated]] FrameInfo(uint8_t payloadType, uint32_t timestamp) : timestamp(timestamp), payloadType(payloadType) {};
|
||||
|
||||
uint32_t timestamp = 0;
|
||||
uint8_t payloadType = 0;
|
||||
|
||||
optional<std::chrono::duration<double>> timestampSeconds;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // RTC_FRAMEINFO_H
|
||||
59
components/3rd_party/datachannel/include/rtc/global.hpp
vendored
Normal file
59
components/3rd_party/datachannel/include/rtc/global.hpp
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2021 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_GLOBAL_H
|
||||
#define RTC_GLOBAL_H
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <future>
|
||||
#include <iostream>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
enum class LogLevel { // Don't change, it must match plog severity
|
||||
None = 0,
|
||||
Fatal = 1,
|
||||
Error = 2,
|
||||
Warning = 3,
|
||||
Info = 4,
|
||||
Debug = 5,
|
||||
Verbose = 6
|
||||
};
|
||||
|
||||
typedef std::function<void(LogLevel level, string message)> LogCallback;
|
||||
|
||||
RTC_CPP_EXPORT void InitLogger(LogLevel level, LogCallback callback = nullptr);
|
||||
|
||||
RTC_CPP_EXPORT void Preload();
|
||||
RTC_CPP_EXPORT std::shared_future<void> Cleanup();
|
||||
|
||||
struct SctpSettings {
|
||||
// For the following settings, not set means optimized default
|
||||
optional<size_t> recvBufferSize; // in bytes
|
||||
optional<size_t> sendBufferSize; // in bytes
|
||||
optional<size_t> maxChunksOnQueue; // in chunks
|
||||
optional<size_t> initialCongestionWindow; // in MTUs
|
||||
optional<size_t> maxBurst; // in MTUs
|
||||
optional<unsigned int> congestionControlModule; // 0: RFC2581, 1: HSTCP, 2: H-TCP, 3: RTCC
|
||||
optional<std::chrono::milliseconds> delayedSackTime;
|
||||
optional<std::chrono::milliseconds> minRetransmitTimeout;
|
||||
optional<std::chrono::milliseconds> maxRetransmitTimeout;
|
||||
optional<std::chrono::milliseconds> initialRetransmitTimeout;
|
||||
optional<unsigned int> maxRetransmitAttempts;
|
||||
optional<std::chrono::milliseconds> heartbeatInterval;
|
||||
};
|
||||
|
||||
RTC_CPP_EXPORT void SetSctpSettings(SctpSettings s);
|
||||
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, LogLevel level);
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
42
components/3rd_party/datachannel/include/rtc/h264rtpdepacketizer.hpp
vendored
Normal file
42
components/3rd_party/datachannel/include/rtc/h264rtpdepacketizer.hpp
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Staz Modrzynski
|
||||
* Copyright (c) 2020 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_H264_RTP_DEPACKETIZER_H
|
||||
#define RTC_H264_RTP_DEPACKETIZER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "common.hpp"
|
||||
#include "message.hpp"
|
||||
#include "nalunit.hpp"
|
||||
#include "rtp.hpp"
|
||||
#include "rtpdepacketizer.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
/// RTP depacketization for H264
|
||||
class RTC_CPP_EXPORT H264RtpDepacketizer final : public VideoRtpDepacketizer {
|
||||
public:
|
||||
using Separator = NalUnit::Separator;
|
||||
|
||||
H264RtpDepacketizer(Separator separator = Separator::StartSequence);
|
||||
~H264RtpDepacketizer();
|
||||
|
||||
private:
|
||||
message_ptr reassemble(message_buffer &buffer) override;
|
||||
void addSeparator(binary &frame);
|
||||
|
||||
const NalUnit::Separator mSeparator;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // RTC_ENABLE_MEDIA
|
||||
|
||||
#endif /* RTC_H264_RTP_DEPACKETIZER_H */
|
||||
57
components/3rd_party/datachannel/include/rtc/h264rtppacketizer.hpp
vendored
Normal file
57
components/3rd_party/datachannel/include/rtc/h264rtppacketizer.hpp
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
* Copyright (c) 2023 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_H264_RTP_PACKETIZER_H
|
||||
#define RTC_H264_RTP_PACKETIZER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "nalunit.hpp"
|
||||
#include "rtppacketizer.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
/// RTP packetization for H264
|
||||
class RTC_CPP_EXPORT H264RtpPacketizer final : public RtpPacketizer {
|
||||
public:
|
||||
using Separator = NalUnit::Separator;
|
||||
|
||||
inline static const uint32_t ClockRate = VideoClockRate;
|
||||
[[deprecated("Use ClockRate")]] inline static const uint32_t defaultClockRate = ClockRate;
|
||||
|
||||
/// Constructs h264 payload packetizer with given RTP configuration.
|
||||
/// @note RTP configuration is used in packetization process which may change some configuration
|
||||
/// properties such as sequence number.
|
||||
/// @param separator NAL unit separator
|
||||
/// @param rtpConfig RTP configuration
|
||||
/// @param maxFragmentSize maximum size of one NALU fragment
|
||||
H264RtpPacketizer(Separator separator, shared_ptr<RtpPacketizationConfig> rtpConfig,
|
||||
size_t maxFragmentSize = DefaultMaxFragmentSize);
|
||||
|
||||
// For backward compatibility, do not use
|
||||
[[deprecated]] H264RtpPacketizer(
|
||||
shared_ptr<RtpPacketizationConfig> rtpConfig,
|
||||
size_t maxFragmentSize = DefaultMaxFragmentSize);
|
||||
|
||||
private:
|
||||
std::vector<binary> fragment(binary data) override;
|
||||
std::vector<NalUnit> splitFrame(const binary &frame);
|
||||
|
||||
const Separator mSeparator;
|
||||
const size_t mMaxFragmentSize;
|
||||
};
|
||||
|
||||
// For backward compatibility, do not use
|
||||
using H264PacketizationHandler [[deprecated("Add H264RtpPacketizer directly")]] = PacketizationHandler;
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_H264_RTP_PACKETIZER_H */
|
||||
194
components/3rd_party/datachannel/include/rtc/h265nalunit.hpp
vendored
Normal file
194
components/3rd_party/datachannel/include/rtc/h265nalunit.hpp
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
* Copyright (c) 2023 Zita Liao (Dolby)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_H265_NAL_UNIT_H
|
||||
#define RTC_H265_NAL_UNIT_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "common.hpp"
|
||||
#include "nalunit.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
#define H265_FU_HEADER_SIZE 1
|
||||
/// Nalu header
|
||||
struct RTC_CPP_EXPORT H265NalUnitHeader {
|
||||
/*
|
||||
* nal_unit_header( ) {
|
||||
* forbidden_zero_bit f(1)
|
||||
* nal_unit_type u(6)
|
||||
* nuh_layer_id u(6)
|
||||
* nuh_temporal_id_plus1 u(3)
|
||||
}
|
||||
*/
|
||||
uint8_t _first = 0; // high byte of header
|
||||
uint8_t _second = 0; // low byte of header
|
||||
|
||||
bool forbiddenBit() const { return _first >> 7; }
|
||||
uint8_t unitType() const { return (_first & 0b0111'1110) >> 1; }
|
||||
uint8_t nuhLayerId() const { return ((_first & 0x1) << 5) | ((_second & 0b1111'1000) >> 3); }
|
||||
uint8_t nuhTempIdPlus1() const { return _second & 0b111; }
|
||||
|
||||
void setForbiddenBit(bool isSet) { _first = (_first & 0x7F) | (isSet << 7); }
|
||||
void setUnitType(uint8_t type) { _first = (_first & 0b1000'0001) | ((type & 0b11'1111) << 1); }
|
||||
void setNuhLayerId(uint8_t nuhLayerId) {
|
||||
_first = (_first & 0b1111'1110) | ((nuhLayerId & 0b10'0000) >> 5);
|
||||
_second = (_second & 0b0000'0111) | ((nuhLayerId & 0b01'1111) << 3);
|
||||
}
|
||||
void setNuhTempIdPlus1(uint8_t nuhTempIdPlus1) {
|
||||
_second = (_second & 0b1111'1000) | (nuhTempIdPlus1 & 0b111);
|
||||
}
|
||||
};
|
||||
|
||||
/// Nalu fragment header
|
||||
struct RTC_CPP_EXPORT H265NalUnitFragmentHeader {
|
||||
/*
|
||||
* +---------------+
|
||||
* |0|1|2|3|4|5|6|7|
|
||||
* +-+-+-+-+-+-+-+-+
|
||||
* |S|E| FuType |
|
||||
* +---------------+
|
||||
*/
|
||||
uint8_t _first = 0;
|
||||
|
||||
bool isStart() const { return _first >> 7; }
|
||||
bool isEnd() const { return (_first >> 6) & 0x01; }
|
||||
uint8_t unitType() const { return _first & 0b11'1111; }
|
||||
|
||||
void setStart(bool isSet) { _first = (_first & 0x7F) | (isSet << 7); }
|
||||
void setEnd(bool isSet) { _first = (_first & 0b1011'1111) | (isSet << 6); }
|
||||
void setUnitType(uint8_t type) { _first = (_first & 0b1100'0000) | (type & 0b11'1111); }
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
struct H265NalUnitFragment;
|
||||
|
||||
/// NAL unit
|
||||
struct RTC_CPP_EXPORT H265NalUnit : NalUnit {
|
||||
static std::vector<binary> GenerateFragments(const std::vector<H265NalUnit> &nalus,
|
||||
size_t maxFragmentSize);
|
||||
|
||||
H265NalUnit(const H265NalUnit &unit) = default;
|
||||
H265NalUnit(size_t size, bool includingHeader = true)
|
||||
: NalUnit(size, includingHeader, NalUnit::Type::H265) {}
|
||||
H265NalUnit(binary &&data) : NalUnit(std::move(data)) {}
|
||||
H265NalUnit() : NalUnit(NalUnit::Type::H265) {}
|
||||
|
||||
template <typename Iterator>
|
||||
H265NalUnit(Iterator begin_, Iterator end_) : NalUnit(begin_, end_) {}
|
||||
|
||||
bool forbiddenBit() const { return header()->forbiddenBit(); }
|
||||
uint8_t unitType() const { return header()->unitType(); }
|
||||
uint8_t nuhLayerId() const { return header()->nuhLayerId(); }
|
||||
uint8_t nuhTempIdPlus1() const { return header()->nuhTempIdPlus1(); }
|
||||
|
||||
binary payload() const {
|
||||
assert(size() >= H265_NAL_HEADER_SIZE);
|
||||
return {begin() + H265_NAL_HEADER_SIZE, end()};
|
||||
}
|
||||
|
||||
void setForbiddenBit(bool isSet) { header()->setForbiddenBit(isSet); }
|
||||
void setUnitType(uint8_t type) { header()->setUnitType(type); }
|
||||
void setNuhLayerId(uint8_t nuhLayerId) { header()->setNuhLayerId(nuhLayerId); }
|
||||
void setNuhTempIdPlus1(uint8_t nuhTempIdPlus1) { header()->setNuhTempIdPlus1(nuhTempIdPlus1); }
|
||||
|
||||
void setPayload(binary payload) {
|
||||
assert(size() >= H265_NAL_HEADER_SIZE);
|
||||
erase(begin() + H265_NAL_HEADER_SIZE, end());
|
||||
insert(end(), payload.begin(), payload.end());
|
||||
}
|
||||
|
||||
std::vector<H265NalUnitFragment> generateFragments(size_t maxFragmentSize) const;
|
||||
|
||||
protected:
|
||||
const H265NalUnitHeader *header() const {
|
||||
assert(size() >= H265_NAL_HEADER_SIZE);
|
||||
return reinterpret_cast<const H265NalUnitHeader *>(data());
|
||||
}
|
||||
|
||||
H265NalUnitHeader *header() {
|
||||
assert(size() >= H265_NAL_HEADER_SIZE);
|
||||
return reinterpret_cast<H265NalUnitHeader *>(data());
|
||||
}
|
||||
};
|
||||
|
||||
/// NAL unit fragment
|
||||
struct RTC_CPP_EXPORT H265NalUnitFragment : H265NalUnit {
|
||||
[[deprecated]] static std::vector<shared_ptr<H265NalUnitFragment>> fragmentsFrom(shared_ptr<H265NalUnit> nalu,
|
||||
uint16_t maxFragmentSize);
|
||||
|
||||
enum class FragmentType { Start, Middle, End };
|
||||
|
||||
H265NalUnitFragment(FragmentType type, bool forbiddenBit, uint8_t nuhLayerId,
|
||||
uint8_t nuhTempIdPlus1, uint8_t unitType, binary data);
|
||||
|
||||
uint8_t unitType() const { return fragmentHeader()->unitType(); }
|
||||
|
||||
binary payload() const {
|
||||
assert(size() >= H265_NAL_HEADER_SIZE + H265_FU_HEADER_SIZE);
|
||||
return {begin() + H265_NAL_HEADER_SIZE + H265_FU_HEADER_SIZE, end()};
|
||||
}
|
||||
|
||||
FragmentType type() const {
|
||||
if (fragmentHeader()->isStart()) {
|
||||
return FragmentType::Start;
|
||||
} else if (fragmentHeader()->isEnd()) {
|
||||
return FragmentType::End;
|
||||
} else {
|
||||
return FragmentType::Middle;
|
||||
}
|
||||
}
|
||||
|
||||
void setUnitType(uint8_t type) { fragmentHeader()->setUnitType(type); }
|
||||
|
||||
void setPayload(binary payload) {
|
||||
assert(size() >= H265_NAL_HEADER_SIZE + H265_FU_HEADER_SIZE);
|
||||
erase(begin() + H265_NAL_HEADER_SIZE + H265_FU_HEADER_SIZE, end());
|
||||
insert(end(), payload.begin(), payload.end());
|
||||
}
|
||||
|
||||
void setFragmentType(FragmentType type);
|
||||
|
||||
protected:
|
||||
const uint8_t nal_type_fu = 49;
|
||||
|
||||
H265NalUnitHeader *fragmentIndicator() { return reinterpret_cast<H265NalUnitHeader *>(data()); }
|
||||
|
||||
const H265NalUnitHeader *fragmentIndicator() const {
|
||||
return reinterpret_cast<const H265NalUnitHeader *>(data());
|
||||
}
|
||||
|
||||
H265NalUnitFragmentHeader *fragmentHeader() {
|
||||
return reinterpret_cast<H265NalUnitFragmentHeader *>(data() + H265_NAL_HEADER_SIZE);
|
||||
}
|
||||
|
||||
const H265NalUnitFragmentHeader *fragmentHeader() const {
|
||||
return reinterpret_cast<const H265NalUnitFragmentHeader *>(data() + H265_NAL_HEADER_SIZE);
|
||||
}
|
||||
};
|
||||
|
||||
class [[deprecated]] RTC_CPP_EXPORT H265NalUnits : public std::vector<shared_ptr<H265NalUnit>> {
|
||||
public:
|
||||
static const uint16_t defaultMaximumFragmentSize =
|
||||
uint16_t(RTC_DEFAULT_MTU - 12 - 8 - 40); // SRTP/UDP/IPv6
|
||||
|
||||
std::vector<shared_ptr<binary>> generateFragments(uint16_t maxFragmentSize);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_NAL_UNIT_H */
|
||||
45
components/3rd_party/datachannel/include/rtc/h265rtpdepacketizer.hpp
vendored
Normal file
45
components/3rd_party/datachannel/include/rtc/h265rtpdepacketizer.hpp
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Staz Modrzynski
|
||||
* Copyright (c) 2020-2024 Paul-Louis Ageneau
|
||||
* Copyright (c) 2024 Robert Edmonds
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_H265_RTP_DEPACKETIZER_H
|
||||
#define RTC_H265_RTP_DEPACKETIZER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "common.hpp"
|
||||
#include "h265nalunit.hpp"
|
||||
#include "message.hpp"
|
||||
#include "rtp.hpp"
|
||||
#include "rtpdepacketizer.hpp"
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
/// RTP depacketization for H265
|
||||
class RTC_CPP_EXPORT H265RtpDepacketizer final : public VideoRtpDepacketizer {
|
||||
public:
|
||||
using Separator = NalUnit::Separator;
|
||||
|
||||
H265RtpDepacketizer(Separator separator = Separator::StartSequence);
|
||||
~H265RtpDepacketizer();
|
||||
|
||||
private:
|
||||
message_ptr reassemble(message_buffer &buffer);
|
||||
void addSeparator(binary &frame);
|
||||
|
||||
const NalUnit::Separator mSeparator;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // RTC_ENABLE_MEDIA
|
||||
|
||||
#endif // RTC_H265_RTP_DEPACKETIZER_H
|
||||
55
components/3rd_party/datachannel/include/rtc/h265rtppacketizer.hpp
vendored
Normal file
55
components/3rd_party/datachannel/include/rtc/h265rtppacketizer.hpp
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright (c) 2023 Zita Liao (Dolby)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_H265_RTP_PACKETIZER_H
|
||||
#define RTC_H265_RTP_PACKETIZER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "h265nalunit.hpp"
|
||||
#include "rtppacketizer.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// RTP packetization for H265
|
||||
class RTC_CPP_EXPORT H265RtpPacketizer final : public RtpPacketizer {
|
||||
public:
|
||||
using Separator = NalUnit::Separator;
|
||||
|
||||
inline static const uint32_t ClockRate = VideoClockRate;
|
||||
[[deprecated("Use ClockRate")]] inline static const uint32_t defaultClockRate = ClockRate;
|
||||
|
||||
// Constructs h265 payload packetizer with given RTP configuration.
|
||||
// @note RTP configuration is used in packetization process which may change some configuration
|
||||
// properties such as sequence number.
|
||||
// @param separator NAL unit separator
|
||||
// @param rtpConfig RTP configuration
|
||||
// @param maxFragmentSize maximum size of one NALU fragment
|
||||
H265RtpPacketizer(Separator separator, shared_ptr<RtpPacketizationConfig> rtpConfig,
|
||||
size_t maxFragmentSize = DefaultMaxFragmentSize);
|
||||
|
||||
// For backward compatibility, do not use
|
||||
[[deprecated]] H265RtpPacketizer(shared_ptr<RtpPacketizationConfig> rtpConfig,
|
||||
size_t maxFragmentSize = DefaultMaxFragmentSize);
|
||||
|
||||
private:
|
||||
std::vector<binary> fragment(binary data) override;
|
||||
std::vector<H265NalUnit> splitFrame(const binary &frame);
|
||||
|
||||
const NalUnit::Separator mSeparator;
|
||||
const size_t mMaxFragmentSize;
|
||||
};
|
||||
|
||||
// For backward compatibility, do not use
|
||||
using H265PacketizationHandler [[deprecated("Add H265RtpPacketizer directly")]] = PacketizationHandler;
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_H265_RTP_PACKETIZER_H */
|
||||
47
components/3rd_party/datachannel/include/rtc/iceudpmuxlistener.hpp
vendored
Normal file
47
components/3rd_party/datachannel/include/rtc/iceudpmuxlistener.hpp
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Alex Potsides
|
||||
* Copyright (c) 2025 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_ICE_UDP_MUX_LISTENER_H
|
||||
#define RTC_ICE_UDP_MUX_LISTENER_H
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
namespace impl {
|
||||
|
||||
struct IceUdpMuxListener;
|
||||
|
||||
} // namespace impl
|
||||
|
||||
struct IceUdpMuxRequest { // TODO change name
|
||||
string localUfrag;
|
||||
string remoteUfrag;
|
||||
string remoteAddress;
|
||||
uint16_t remotePort;
|
||||
};
|
||||
|
||||
class RTC_CPP_EXPORT IceUdpMuxListener final : private CheshireCat<impl::IceUdpMuxListener> {
|
||||
public:
|
||||
IceUdpMuxListener(uint16_t port, optional<string> bindAddress = nullopt);
|
||||
~IceUdpMuxListener();
|
||||
|
||||
void stop();
|
||||
|
||||
uint16_t port() const;
|
||||
|
||||
void OnUnhandledStunRequest(std::function<void(IceUdpMuxRequest)> callback);
|
||||
|
||||
private:
|
||||
using CheshireCat<impl::IceUdpMuxListener>::impl;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
58
components/3rd_party/datachannel/include/rtc/mediahandler.hpp
vendored
Normal file
58
components/3rd_party/datachannel/include/rtc/mediahandler.hpp
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Staz Modrzynski
|
||||
* Copyright (c) 2020 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_MEDIA_HANDLER_H
|
||||
#define RTC_MEDIA_HANDLER_H
|
||||
|
||||
#include "common.hpp"
|
||||
#include "description.hpp"
|
||||
#include "message.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class RTC_CPP_EXPORT MediaHandler : public std::enable_shared_from_this<MediaHandler> {
|
||||
public:
|
||||
MediaHandler();
|
||||
virtual ~MediaHandler();
|
||||
|
||||
/// Called when a media is added or updated
|
||||
/// @param desc Description of the media
|
||||
virtual void media([[maybe_unused]] const Description::Media &desc) {}
|
||||
|
||||
/// Called when there is traffic coming from the peer
|
||||
/// @param messages Incoming messages from the peer, can be modified by the handler
|
||||
/// @param send Send callback to send messages back to the peer
|
||||
virtual void incoming([[maybe_unused]] message_vector &messages, [[maybe_unused]] const message_callback &send) {}
|
||||
|
||||
/// Called when there is traffic that needs to be sent to the peer
|
||||
/// @param messages Outgoing messages to the peer, can be modified by the handler
|
||||
/// @param send Send callback to send messages back to the peer
|
||||
virtual void outgoing([[maybe_unused]] message_vector &messages, [[maybe_unused]] const message_callback &send) {}
|
||||
|
||||
virtual bool requestKeyframe(const message_callback &send);
|
||||
virtual bool requestBitrate(unsigned int bitrate, const message_callback &send);
|
||||
|
||||
void addToChain(shared_ptr<MediaHandler> handler);
|
||||
void setNext(shared_ptr<MediaHandler> handler);
|
||||
shared_ptr<MediaHandler> next();
|
||||
shared_ptr<const MediaHandler> next() const;
|
||||
shared_ptr<MediaHandler> last(); // never null
|
||||
shared_ptr<const MediaHandler> last() const; // never null
|
||||
|
||||
void mediaChain(const Description::Media &desc);
|
||||
void incomingChain(message_vector &messages, const message_callback &send);
|
||||
void outgoingChain(message_vector &messages, const message_callback &send);
|
||||
|
||||
private:
|
||||
shared_ptr<MediaHandler> mNext;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // RTC_MEDIA_HANDLER_H
|
||||
100
components/3rd_party/datachannel/include/rtc/message.hpp
vendored
Normal file
100
components/3rd_party/datachannel/include/rtc/message.hpp
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Copyright (c) 2019-2020 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_MESSAGE_H
|
||||
#define RTC_MESSAGE_H
|
||||
|
||||
#include "common.hpp"
|
||||
#include "frameinfo.hpp"
|
||||
#include "reliability.hpp"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
struct RTC_CPP_EXPORT Message : binary {
|
||||
enum Type { Binary, String, Control, Reset };
|
||||
|
||||
Message(const Message &message) = default;
|
||||
Message(size_t size, Type type_ = Binary) : binary(size), type(type_) {}
|
||||
|
||||
template <typename Iterator>
|
||||
Message(Iterator begin_, Iterator end_, Type type_ = Binary)
|
||||
: binary(begin_, end_), type(type_) {}
|
||||
|
||||
Message(binary &&data, Type type_ = Binary) : binary(std::move(data)), type(type_) {}
|
||||
|
||||
Type type;
|
||||
unsigned int stream = 0; // Stream id (SCTP stream or SSRC)
|
||||
unsigned int dscp = 0; // Differentiated Services Code Point
|
||||
shared_ptr<Reliability> reliability;
|
||||
shared_ptr<FrameInfo> frameInfo;
|
||||
};
|
||||
|
||||
using message_ptr = shared_ptr<Message>;
|
||||
using message_callback = std::function<void(message_ptr message)>;
|
||||
using message_vector = std::vector<message_ptr>;
|
||||
|
||||
inline size_t message_size_func(const message_ptr &m) {
|
||||
return m->type == Message::Binary || m->type == Message::String ? m->size() : 0;
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
message_ptr make_message(Iterator begin, Iterator end, Message::Type type = Message::Binary,
|
||||
unsigned int stream = 0, shared_ptr<Reliability> reliability = nullptr) {
|
||||
auto message = std::make_shared<Message>(begin, end, type);
|
||||
message->stream = stream;
|
||||
message->reliability = reliability;
|
||||
return message;
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
message_ptr make_message(Iterator begin, Iterator end, shared_ptr<FrameInfo> frameInfo) {
|
||||
auto message = std::make_shared<Message>(begin, end);
|
||||
message->frameInfo = frameInfo;
|
||||
return message;
|
||||
}
|
||||
|
||||
// For backward compatibiity, do not use
|
||||
template <typename Iterator>
|
||||
[[deprecated]] message_ptr make_message(Iterator begin, Iterator end, Message::Type type,
|
||||
unsigned int stream, shared_ptr<FrameInfo> frameInfo) {
|
||||
auto message = std::make_shared<Message>(begin, end, type);
|
||||
message->stream = stream;
|
||||
message->frameInfo = frameInfo;
|
||||
return message;
|
||||
}
|
||||
|
||||
RTC_CPP_EXPORT message_ptr make_message(size_t size, Message::Type type = Message::Binary,
|
||||
unsigned int stream = 0,
|
||||
shared_ptr<Reliability> reliability = nullptr);
|
||||
|
||||
RTC_CPP_EXPORT message_ptr make_message(binary &&data, Message::Type type = Message::Binary,
|
||||
unsigned int stream = 0,
|
||||
shared_ptr<Reliability> reliability = nullptr);
|
||||
|
||||
RTC_CPP_EXPORT message_ptr make_message(binary &&data, shared_ptr<FrameInfo> frameInfo);
|
||||
|
||||
RTC_CPP_EXPORT message_ptr make_message(size_t size, message_ptr orig);
|
||||
|
||||
RTC_CPP_EXPORT message_ptr make_message(message_variant data);
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
// Reconstructs a message_ptr from an opaque rtcMessage pointer that
|
||||
// was allocated by rtcCreateOpaqueMessage().
|
||||
message_ptr make_message_from_opaque_ptr(rtcMessage *&&message);
|
||||
|
||||
#endif
|
||||
|
||||
RTC_CPP_EXPORT message_variant to_variant(Message &&message);
|
||||
RTC_CPP_EXPORT message_variant to_variant(const Message &message);
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
197
components/3rd_party/datachannel/include/rtc/nalunit.hpp
vendored
Normal file
197
components/3rd_party/datachannel/include/rtc/nalunit.hpp
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_NAL_UNIT_H
|
||||
#define RTC_NAL_UNIT_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
/// Nalu header
|
||||
struct RTC_CPP_EXPORT NalUnitHeader {
|
||||
uint8_t _first = 0;
|
||||
|
||||
bool forbiddenBit() const { return _first >> 7; }
|
||||
uint8_t nri() const { return _first >> 5 & 0x03; }
|
||||
uint8_t idc() const { return _first & 0x60; }
|
||||
uint8_t unitType() const { return _first & 0x1F; }
|
||||
|
||||
void setForbiddenBit(bool isSet) { _first = (_first & 0x7F) | (isSet << 7); }
|
||||
void setNRI(uint8_t nri) { _first = (_first & 0x9F) | ((nri & 0x03) << 5); }
|
||||
void setUnitType(uint8_t type) { _first = (_first & 0xE0) | (type & 0x1F); }
|
||||
};
|
||||
|
||||
/// Nalu fragment header
|
||||
struct RTC_CPP_EXPORT NalUnitFragmentHeader {
|
||||
uint8_t _first = 0;
|
||||
|
||||
bool isStart() const { return _first >> 7; }
|
||||
bool reservedBit6() const { return (_first >> 5) & 0x01; }
|
||||
bool isEnd() const { return (_first >> 6) & 0x01; }
|
||||
uint8_t unitType() const { return _first & 0x1F; }
|
||||
|
||||
void setStart(bool isSet) { _first = (_first & 0x7F) | (isSet << 7); }
|
||||
void setEnd(bool isSet) { _first = (_first & 0xBF) | (isSet << 6); }
|
||||
void setReservedBit6(bool isSet) { _first = (_first & 0xDF) | (isSet << 5); }
|
||||
void setUnitType(uint8_t type) { _first = (_first & 0xE0) | (type & 0x1F); }
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
enum NalUnitStartSequenceMatch {
|
||||
NUSM_noMatch,
|
||||
NUSM_firstZero,
|
||||
NUSM_secondZero,
|
||||
NUSM_thirdZero,
|
||||
NUSM_shortMatch,
|
||||
NUSM_longMatch
|
||||
};
|
||||
|
||||
static const size_t H264_NAL_HEADER_SIZE = 1;
|
||||
static const size_t H265_NAL_HEADER_SIZE = 2;
|
||||
|
||||
struct NalUnitFragmentA;
|
||||
|
||||
/// NAL unit
|
||||
struct RTC_CPP_EXPORT NalUnit : binary {
|
||||
static std::vector<binary> GenerateFragments(const std::vector<NalUnit> &nalus,
|
||||
size_t maxFragmentSize);
|
||||
|
||||
enum class Separator {
|
||||
Length = RTC_NAL_SEPARATOR_LENGTH, // first 4 bytes are NAL unit length
|
||||
LongStartSequence = RTC_NAL_SEPARATOR_LONG_START_SEQUENCE, // 0x00, 0x00, 0x00, 0x01
|
||||
ShortStartSequence = RTC_NAL_SEPARATOR_SHORT_START_SEQUENCE, // 0x00, 0x00, 0x01
|
||||
StartSequence = RTC_NAL_SEPARATOR_START_SEQUENCE, // LongStartSequence or ShortStartSequence
|
||||
};
|
||||
|
||||
static NalUnitStartSequenceMatch StartSequenceMatchSucc(NalUnitStartSequenceMatch match,
|
||||
std::byte _byte, Separator separator);
|
||||
|
||||
enum class Type { H264, H265 };
|
||||
|
||||
NalUnit(const NalUnit &unit) = default;
|
||||
NalUnit(size_t size, bool includingHeader = true, Type type = Type::H264)
|
||||
: binary(size + (includingHeader ? 0
|
||||
: (type == Type::H264 ? H264_NAL_HEADER_SIZE
|
||||
: H265_NAL_HEADER_SIZE))) {}
|
||||
NalUnit(binary &&data) : binary(std::move(data)) {}
|
||||
NalUnit(Type type = Type::H264)
|
||||
: binary(type == Type::H264 ? H264_NAL_HEADER_SIZE : H265_NAL_HEADER_SIZE) {}
|
||||
template <typename Iterator> NalUnit(Iterator begin_, Iterator end_) : binary(begin_, end_) {}
|
||||
|
||||
bool forbiddenBit() const { return header()->forbiddenBit(); }
|
||||
uint8_t nri() const { return header()->nri(); }
|
||||
uint8_t unitType() const { return header()->unitType(); }
|
||||
|
||||
binary payload() const {
|
||||
assert(size() >= 1);
|
||||
return {begin() + 1, end()};
|
||||
}
|
||||
|
||||
void setForbiddenBit(bool isSet) { header()->setForbiddenBit(isSet); }
|
||||
void setNRI(uint8_t nri) { header()->setNRI(nri); }
|
||||
void setUnitType(uint8_t type) { header()->setUnitType(type); }
|
||||
|
||||
void setPayload(binary payload) {
|
||||
assert(size() >= 1);
|
||||
erase(begin() + 1, end());
|
||||
insert(end(), payload.begin(), payload.end());
|
||||
}
|
||||
|
||||
std::vector<NalUnitFragmentA> generateFragments(size_t maxFragmentSize) const;
|
||||
|
||||
protected:
|
||||
const NalUnitHeader *header() const {
|
||||
assert(size() >= 1);
|
||||
return reinterpret_cast<const NalUnitHeader *>(data());
|
||||
}
|
||||
|
||||
NalUnitHeader *header() {
|
||||
assert(size() >= 1);
|
||||
return reinterpret_cast<NalUnitHeader *>(data());
|
||||
}
|
||||
};
|
||||
|
||||
/// Nal unit fragment A
|
||||
struct RTC_CPP_EXPORT NalUnitFragmentA : NalUnit {
|
||||
// For backward compatibility, do not use
|
||||
[[deprecated]] static std::vector<shared_ptr<NalUnitFragmentA>>
|
||||
fragmentsFrom(shared_ptr<NalUnit> nalu, uint16_t maxFragmentSize);
|
||||
|
||||
enum class FragmentType { Start, Middle, End };
|
||||
|
||||
NalUnitFragmentA(FragmentType type, bool forbiddenBit, uint8_t nri, uint8_t unitType,
|
||||
binary data);
|
||||
|
||||
uint8_t unitType() const { return fragmentHeader()->unitType(); }
|
||||
|
||||
binary payload() const {
|
||||
assert(size() >= 2);
|
||||
return {begin() + 2, end()};
|
||||
}
|
||||
|
||||
FragmentType type() const {
|
||||
if (fragmentHeader()->isStart()) {
|
||||
return FragmentType::Start;
|
||||
} else if (fragmentHeader()->isEnd()) {
|
||||
return FragmentType::End;
|
||||
} else {
|
||||
return FragmentType::Middle;
|
||||
}
|
||||
}
|
||||
|
||||
void setUnitType(uint8_t type) { fragmentHeader()->setUnitType(type); }
|
||||
|
||||
void setPayload(binary payload) {
|
||||
assert(size() >= 2);
|
||||
erase(begin() + 2, end());
|
||||
insert(end(), payload.begin(), payload.end());
|
||||
}
|
||||
|
||||
void setFragmentType(FragmentType type);
|
||||
|
||||
protected:
|
||||
const uint8_t nal_type_fu_A = 28;
|
||||
|
||||
NalUnitHeader *fragmentIndicator() { return reinterpret_cast<NalUnitHeader *>(data()); }
|
||||
|
||||
const NalUnitHeader *fragmentIndicator() const {
|
||||
return reinterpret_cast<const NalUnitHeader *>(data());
|
||||
}
|
||||
|
||||
NalUnitFragmentHeader *fragmentHeader() {
|
||||
return reinterpret_cast<NalUnitFragmentHeader *>(fragmentIndicator() + 1);
|
||||
}
|
||||
|
||||
const NalUnitFragmentHeader *fragmentHeader() const {
|
||||
return reinterpret_cast<const NalUnitFragmentHeader *>(fragmentIndicator() + 1);
|
||||
}
|
||||
};
|
||||
|
||||
// For backward compatibility, do not use
|
||||
class [[deprecated]] RTC_CPP_EXPORT NalUnits : public std::vector<shared_ptr<NalUnit>> {
|
||||
public:
|
||||
static const uint16_t defaultMaximumFragmentSize =
|
||||
uint16_t(RTC_DEFAULT_MTU - 12 - 8 - 40); // SRTP/UDP/IPv6
|
||||
|
||||
std::vector<shared_ptr<binary>> generateFragments(uint16_t maxFragmentSize);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_NAL_UNIT_H */
|
||||
49
components/3rd_party/datachannel/include/rtc/pacinghandler.hpp
vendored
Normal file
49
components/3rd_party/datachannel/include/rtc/pacinghandler.hpp
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Sean DuBois <sean@siobud.com>
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_PACING_HANDLER_H
|
||||
#define RTC_PACING_HANDLER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "mediahandler.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <queue>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// Paced sending of RTP packets. It takes a stream of RTP packets that can have an uneven bitrate
|
||||
// and delivers them in a smoother manner by sending a fixed size of them on an interval
|
||||
class RTC_CPP_EXPORT PacingHandler : public MediaHandler {
|
||||
public:
|
||||
PacingHandler(double bitsPerSecond, std::chrono::milliseconds sendInterval);
|
||||
|
||||
void outgoing(message_vector &messages, const message_callback &send) override;
|
||||
|
||||
private:
|
||||
std::atomic<bool> mHaveScheduled = false;
|
||||
|
||||
double mBytesPerSecond;
|
||||
double mBudget;
|
||||
|
||||
std::chrono::milliseconds mSendInterval;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> mLastRun;
|
||||
|
||||
std::mutex mMutex;
|
||||
std::queue<message_ptr> mRtpBuffer;
|
||||
|
||||
void schedule(const message_callback &send);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // RTC_ENABLE_MEDIA
|
||||
|
||||
#endif // RTC_PACING_HANDLER_H
|
||||
142
components/3rd_party/datachannel/include/rtc/peerconnection.hpp
vendored
Normal file
142
components/3rd_party/datachannel/include/rtc/peerconnection.hpp
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_PEER_CONNECTION_H
|
||||
#define RTC_PEER_CONNECTION_H
|
||||
|
||||
#include "candidate.hpp"
|
||||
#include "common.hpp"
|
||||
#include "configuration.hpp"
|
||||
#include "datachannel.hpp"
|
||||
#include "description.hpp"
|
||||
#include "reliability.hpp"
|
||||
#include "track.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
namespace impl {
|
||||
|
||||
struct PeerConnection;
|
||||
|
||||
}
|
||||
|
||||
struct RTC_CPP_EXPORT DataChannelInit {
|
||||
Reliability reliability = {};
|
||||
bool negotiated = false;
|
||||
optional<uint16_t> id = nullopt;
|
||||
string protocol = "";
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT LocalDescriptionInit {
|
||||
optional<string> iceUfrag;
|
||||
optional<string> icePwd;
|
||||
};
|
||||
|
||||
class RTC_CPP_EXPORT PeerConnection final : CheshireCat<impl::PeerConnection> {
|
||||
public:
|
||||
enum class State : int {
|
||||
New = RTC_NEW,
|
||||
Connecting = RTC_CONNECTING,
|
||||
Connected = RTC_CONNECTED,
|
||||
Disconnected = RTC_DISCONNECTED,
|
||||
Failed = RTC_FAILED,
|
||||
Closed = RTC_CLOSED
|
||||
};
|
||||
|
||||
enum class IceState : int {
|
||||
New = RTC_ICE_NEW,
|
||||
Checking = RTC_ICE_CHECKING,
|
||||
Connected = RTC_ICE_CONNECTED,
|
||||
Completed = RTC_ICE_COMPLETED,
|
||||
Failed = RTC_ICE_FAILED,
|
||||
Disconnected = RTC_ICE_DISCONNECTED,
|
||||
Closed = RTC_ICE_CLOSED
|
||||
};
|
||||
|
||||
enum class GatheringState : int {
|
||||
New = RTC_GATHERING_NEW,
|
||||
InProgress = RTC_GATHERING_INPROGRESS,
|
||||
Complete = RTC_GATHERING_COMPLETE
|
||||
};
|
||||
|
||||
enum class SignalingState : int {
|
||||
Stable = RTC_SIGNALING_STABLE,
|
||||
HaveLocalOffer = RTC_SIGNALING_HAVE_LOCAL_OFFER,
|
||||
HaveRemoteOffer = RTC_SIGNALING_HAVE_REMOTE_OFFER,
|
||||
HaveLocalPranswer = RTC_SIGNALING_HAVE_LOCAL_PRANSWER,
|
||||
HaveRemotePranswer = RTC_SIGNALING_HAVE_REMOTE_PRANSWER,
|
||||
};
|
||||
|
||||
PeerConnection();
|
||||
PeerConnection(Configuration config);
|
||||
~PeerConnection();
|
||||
|
||||
void close();
|
||||
|
||||
const Configuration *config() const;
|
||||
State state() const;
|
||||
IceState iceState() const;
|
||||
GatheringState gatheringState() const;
|
||||
SignalingState signalingState() const;
|
||||
bool negotiationNeeded() const;
|
||||
bool hasMedia() const;
|
||||
optional<Description> localDescription() const;
|
||||
optional<Description> remoteDescription() const;
|
||||
size_t remoteMaxMessageSize() const;
|
||||
optional<string> localAddress() const;
|
||||
optional<string> remoteAddress() const;
|
||||
uint16_t maxDataChannelId() const;
|
||||
bool getSelectedCandidatePair(Candidate *local, Candidate *remote);
|
||||
|
||||
void setLocalDescription(Description::Type type = Description::Type::Unspec, LocalDescriptionInit init = {});
|
||||
void gatherLocalCandidates(std::vector<IceServer> additionalIceServers = {});
|
||||
void setRemoteDescription(Description description);
|
||||
void addRemoteCandidate(Candidate candidate);
|
||||
|
||||
// For specific use cases only
|
||||
Description createOffer();
|
||||
Description createAnswer();
|
||||
|
||||
void setMediaHandler(shared_ptr<MediaHandler> handler);
|
||||
shared_ptr<MediaHandler> getMediaHandler();
|
||||
|
||||
[[nodiscard]] shared_ptr<DataChannel> createDataChannel(string label,
|
||||
DataChannelInit init = {});
|
||||
void onDataChannel(std::function<void(std::shared_ptr<DataChannel> dataChannel)> callback);
|
||||
|
||||
[[nodiscard]] shared_ptr<Track> addTrack(Description::Media description);
|
||||
void onTrack(std::function<void(std::shared_ptr<Track> track)> callback);
|
||||
|
||||
void onLocalDescription(std::function<void(Description description)> callback);
|
||||
void onLocalCandidate(std::function<void(Candidate candidate)> callback);
|
||||
void onStateChange(std::function<void(State state)> callback);
|
||||
void onIceStateChange(std::function<void(IceState state)> callback);
|
||||
void onGatheringStateChange(std::function<void(GatheringState state)> callback);
|
||||
void onSignalingStateChange(std::function<void(SignalingState state)> callback);
|
||||
|
||||
void resetCallbacks();
|
||||
CertificateFingerprint remoteFingerprint();
|
||||
|
||||
// Stats
|
||||
void clearStats();
|
||||
size_t bytesSent();
|
||||
size_t bytesReceived();
|
||||
optional<std::chrono::milliseconds> rtt();
|
||||
};
|
||||
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, PeerConnection::State state);
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, PeerConnection::IceState state);
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, PeerConnection::GatheringState state);
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, PeerConnection::SignalingState state);
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
36
components/3rd_party/datachannel/include/rtc/plihandler.hpp
vendored
Normal file
36
components/3rd_party/datachannel/include/rtc/plihandler.hpp
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (c) 2023 Arda Cinar
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_PLI_RESPONDER_H
|
||||
#define RTC_PLI_RESPONDER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "mediahandler.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
/// Responds to PLI and FIR messages sent by the receiver. The sender should respond to these
|
||||
/// messages by sending an intra.
|
||||
class RTC_CPP_EXPORT PliHandler final : public MediaHandler {
|
||||
rtc::synchronized_callback<> mOnPli;
|
||||
|
||||
public:
|
||||
/// Constructs the PLIResponder object to notify whenever a new intra frame is requested
|
||||
/// @param onPli The callback that gets called whenever an intra frame is requested by the receiver
|
||||
PliHandler(std::function<void(void)> onPli);
|
||||
|
||||
void incoming(message_vector &messages, const message_callback &send) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // RTC_ENABLE_MEDIA
|
||||
|
||||
#endif // RTC_PLI_RESPONDER_H
|
||||
43
components/3rd_party/datachannel/include/rtc/reliability.hpp
vendored
Normal file
43
components/3rd_party/datachannel/include/rtc/reliability.hpp
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_RELIABILITY_H
|
||||
#define RTC_RELIABILITY_H
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
struct Reliability {
|
||||
// It true, the channel does not enforce message ordering and out-of-order delivery is allowed
|
||||
bool unordered = false;
|
||||
|
||||
// If both maxPacketLifeTime or maxRetransmits are unset, the channel is reliable.
|
||||
// If either maxPacketLifeTime or maxRetransmits is set, the channel is unreliable.
|
||||
// (The settings are exclusive so both maxPacketLifetime and maxRetransmits must not be set.)
|
||||
|
||||
// Time window during which transmissions and retransmissions may occur
|
||||
optional<std::chrono::milliseconds> maxPacketLifeTime;
|
||||
|
||||
// Maximum number of retransmissions that are attempted
|
||||
optional<unsigned int> maxRetransmits;
|
||||
|
||||
// For backward compatibility, do not use
|
||||
enum class Type { Reliable = 0, Rexmit, Timed };
|
||||
union {
|
||||
Type typeDeprecated = Type::Reliable;
|
||||
[[deprecated("Use maxPacketLifeTime or maxRetransmits")]] Type type;
|
||||
};
|
||||
variant<int, std::chrono::milliseconds> rexmit = 0;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
35
components/3rd_party/datachannel/include/rtc/rembhandler.hpp
vendored
Normal file
35
components/3rd_party/datachannel/include/rtc/rembhandler.hpp
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Vladimir Voronin
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_REMB_RESPONDER_H
|
||||
#define RTC_REMB_RESPONDER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "mediahandler.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
/// Responds to REMB messages sent by the receiver.
|
||||
class RTC_CPP_EXPORT RembHandler final : public MediaHandler {
|
||||
rtc::synchronized_callback<unsigned int> mOnRemb;
|
||||
|
||||
public:
|
||||
/// Constructs the RembResponder object to notify whenever a bitrate
|
||||
/// @param onRemb The callback that gets called whenever a bitrate by the receiver
|
||||
RembHandler(std::function<void(unsigned int)> onRemb);
|
||||
|
||||
void incoming(message_vector &messages, const message_callback &send) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // RTC_ENABLE_MEDIA
|
||||
|
||||
#endif // RTC_REMB_RESPONDER_H
|
||||
545
components/3rd_party/datachannel/include/rtc/rtc.h
vendored
Normal file
545
components/3rd_party/datachannel/include/rtc/rtc.h
vendored
Normal file
@@ -0,0 +1,545 @@
|
||||
/**
|
||||
* Copyright (c) 2019-2021 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_C_API
|
||||
#define RTC_C_API
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef RTC_STATIC
|
||||
#define RTC_C_EXPORT
|
||||
#else // dynamic library
|
||||
#ifdef _WIN32
|
||||
#ifdef RTC_EXPORTS
|
||||
#define RTC_C_EXPORT __declspec(dllexport) // building the library
|
||||
#else
|
||||
#define RTC_C_EXPORT __declspec(dllimport) // using the library
|
||||
#endif
|
||||
#else // not WIN32
|
||||
#define RTC_C_EXPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef RTC_ENABLE_WEBSOCKET
|
||||
#define RTC_ENABLE_WEBSOCKET 1
|
||||
#endif
|
||||
|
||||
#ifndef RTC_ENABLE_MEDIA
|
||||
#define RTC_ENABLE_MEDIA 1
|
||||
#endif
|
||||
|
||||
#define RTC_DEFAULT_MTU 1280 // IPv6 minimum guaranteed MTU
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
#define RTC_DEFAULT_MAX_FRAGMENT_SIZE ((uint16_t)(RTC_DEFAULT_MTU - 12 - 8 - 40)) // SRTP/UDP/IPv6
|
||||
#define RTC_DEFAULT_MAX_STORED_PACKET_COUNT 512
|
||||
// Deprecated, do not use
|
||||
#define RTC_DEFAULT_MAXIMUM_FRAGMENT_SIZE RTC_DEFAULT_MAX_FRAGMENT_SIZE
|
||||
#define RTC_DEFAULT_MAXIMUM_PACKET_COUNT_FOR_NACK_CACHE RTC_DEFAULT_MAX_STORED_PACKET_COUNT
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef CAPI_STDCALL
|
||||
#define RTC_API __stdcall
|
||||
#else
|
||||
#define RTC_API
|
||||
#endif
|
||||
#else // not WIN32
|
||||
#define RTC_API
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define RTC_DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
#define RTC_DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
#define DEPRECATED
|
||||
#endif
|
||||
|
||||
// libdatachannel C API
|
||||
|
||||
typedef enum {
|
||||
RTC_NEW = 0,
|
||||
RTC_CONNECTING = 1,
|
||||
RTC_CONNECTED = 2,
|
||||
RTC_DISCONNECTED = 3,
|
||||
RTC_FAILED = 4,
|
||||
RTC_CLOSED = 5
|
||||
} rtcState;
|
||||
|
||||
typedef enum {
|
||||
RTC_ICE_NEW = 0,
|
||||
RTC_ICE_CHECKING = 1,
|
||||
RTC_ICE_CONNECTED = 2,
|
||||
RTC_ICE_COMPLETED = 3,
|
||||
RTC_ICE_FAILED = 4,
|
||||
RTC_ICE_DISCONNECTED = 5,
|
||||
RTC_ICE_CLOSED = 6
|
||||
} rtcIceState;
|
||||
|
||||
typedef enum {
|
||||
RTC_GATHERING_NEW = 0,
|
||||
RTC_GATHERING_INPROGRESS = 1,
|
||||
RTC_GATHERING_COMPLETE = 2
|
||||
} rtcGatheringState;
|
||||
|
||||
typedef enum {
|
||||
RTC_SIGNALING_STABLE = 0,
|
||||
RTC_SIGNALING_HAVE_LOCAL_OFFER = 1,
|
||||
RTC_SIGNALING_HAVE_REMOTE_OFFER = 2,
|
||||
RTC_SIGNALING_HAVE_LOCAL_PRANSWER = 3,
|
||||
RTC_SIGNALING_HAVE_REMOTE_PRANSWER = 4,
|
||||
} rtcSignalingState;
|
||||
|
||||
typedef enum { // Don't change, it must match plog severity
|
||||
RTC_LOG_NONE = 0,
|
||||
RTC_LOG_FATAL = 1,
|
||||
RTC_LOG_ERROR = 2,
|
||||
RTC_LOG_WARNING = 3,
|
||||
RTC_LOG_INFO = 4,
|
||||
RTC_LOG_DEBUG = 5,
|
||||
RTC_LOG_VERBOSE = 6
|
||||
} rtcLogLevel;
|
||||
|
||||
typedef enum {
|
||||
RTC_CERTIFICATE_DEFAULT = 0, // ECDSA
|
||||
RTC_CERTIFICATE_ECDSA = 1,
|
||||
RTC_CERTIFICATE_RSA = 2,
|
||||
} rtcCertificateType;
|
||||
|
||||
typedef enum {
|
||||
// video
|
||||
RTC_CODEC_H264 = 0,
|
||||
RTC_CODEC_VP8 = 1,
|
||||
RTC_CODEC_VP9 = 2,
|
||||
RTC_CODEC_H265 = 3,
|
||||
RTC_CODEC_AV1 = 4,
|
||||
|
||||
// audio
|
||||
RTC_CODEC_OPUS = 128,
|
||||
RTC_CODEC_PCMU = 129,
|
||||
RTC_CODEC_PCMA = 130,
|
||||
RTC_CODEC_AAC = 131,
|
||||
RTC_CODEC_G722 = 132,
|
||||
} rtcCodec;
|
||||
|
||||
typedef enum {
|
||||
RTC_DIRECTION_UNKNOWN = 0,
|
||||
RTC_DIRECTION_SENDONLY = 1,
|
||||
RTC_DIRECTION_RECVONLY = 2,
|
||||
RTC_DIRECTION_SENDRECV = 3,
|
||||
RTC_DIRECTION_INACTIVE = 4
|
||||
} rtcDirection;
|
||||
|
||||
typedef enum { RTC_TRANSPORT_POLICY_ALL = 0, RTC_TRANSPORT_POLICY_RELAY = 1 } rtcTransportPolicy;
|
||||
|
||||
#define RTC_ERR_SUCCESS 0
|
||||
#define RTC_ERR_INVALID -1 // invalid argument
|
||||
#define RTC_ERR_FAILURE -2 // runtime error
|
||||
#define RTC_ERR_NOT_AVAIL -3 // element not available
|
||||
#define RTC_ERR_TOO_SMALL -4 // buffer too small
|
||||
|
||||
typedef void(RTC_API *rtcLogCallbackFunc)(rtcLogLevel level, const char *message);
|
||||
typedef void(RTC_API *rtcDescriptionCallbackFunc)(int pc, const char *sdp, const char *type,
|
||||
void *ptr);
|
||||
typedef void(RTC_API *rtcCandidateCallbackFunc)(int pc, const char *cand, const char *mid,
|
||||
void *ptr);
|
||||
typedef void(RTC_API *rtcStateChangeCallbackFunc)(int pc, rtcState state, void *ptr);
|
||||
typedef void(RTC_API *rtcIceStateChangeCallbackFunc)(int pc, rtcIceState state, void *ptr);
|
||||
typedef void(RTC_API *rtcGatheringStateCallbackFunc)(int pc, rtcGatheringState state, void *ptr);
|
||||
typedef void(RTC_API *rtcSignalingStateCallbackFunc)(int pc, rtcSignalingState state, void *ptr);
|
||||
typedef void(RTC_API *rtcDataChannelCallbackFunc)(int pc, int dc, void *ptr);
|
||||
typedef void(RTC_API *rtcTrackCallbackFunc)(int pc, int tr, void *ptr);
|
||||
typedef void(RTC_API *rtcOpenCallbackFunc)(int id, void *ptr);
|
||||
typedef void(RTC_API *rtcClosedCallbackFunc)(int id, void *ptr);
|
||||
typedef void(RTC_API *rtcErrorCallbackFunc)(int id, const char *error, void *ptr);
|
||||
typedef void(RTC_API *rtcMessageCallbackFunc)(int id, const char *message, int size, void *ptr);
|
||||
typedef void *(RTC_API *rtcInterceptorCallbackFunc)(int pc, const char *message, int size,
|
||||
void *ptr);
|
||||
typedef void(RTC_API *rtcBufferedAmountLowCallbackFunc)(int id, void *ptr);
|
||||
typedef void(RTC_API *rtcAvailableCallbackFunc)(int id, void *ptr);
|
||||
typedef void(RTC_API *rtcPliHandlerCallbackFunc)(int tr, void *ptr);
|
||||
typedef void(RTC_API *rtcRembHandlerCallbackFunc)(int tr, unsigned int bitrate, void *ptr);
|
||||
|
||||
// Log
|
||||
|
||||
// NULL cb on the first call will log to stdout
|
||||
RTC_C_EXPORT void rtcInitLogger(rtcLogLevel level, rtcLogCallbackFunc cb);
|
||||
|
||||
// User pointer
|
||||
RTC_C_EXPORT void rtcSetUserPointer(int id, void *ptr);
|
||||
RTC_C_EXPORT void *rtcGetUserPointer(int i);
|
||||
|
||||
// PeerConnection
|
||||
|
||||
typedef struct {
|
||||
const char **iceServers;
|
||||
int iceServersCount;
|
||||
const char *proxyServer; // libnice only
|
||||
const char *bindAddress; // libjuice only, NULL means any
|
||||
rtcCertificateType certificateType;
|
||||
rtcTransportPolicy iceTransportPolicy;
|
||||
bool enableIceTcp;
|
||||
bool enableIceUdpMux; // libjuice only
|
||||
bool disableAutoNegotiation;
|
||||
bool forceMediaTransport;
|
||||
uint16_t portRangeBegin; // 0 means automatic
|
||||
uint16_t portRangeEnd; // 0 means automatic
|
||||
int mtu; // <= 0 means automatic
|
||||
int maxMessageSize; // <= 0 means default
|
||||
} rtcConfiguration;
|
||||
|
||||
RTC_C_EXPORT int rtcCreatePeerConnection(const rtcConfiguration *config); // returns pc id
|
||||
RTC_C_EXPORT int rtcClosePeerConnection(int pc);
|
||||
RTC_C_EXPORT int rtcDeletePeerConnection(int pc);
|
||||
|
||||
RTC_C_EXPORT int rtcSetLocalDescriptionCallback(int pc, rtcDescriptionCallbackFunc cb);
|
||||
RTC_C_EXPORT int rtcSetLocalCandidateCallback(int pc, rtcCandidateCallbackFunc cb);
|
||||
RTC_C_EXPORT int rtcSetStateChangeCallback(int pc, rtcStateChangeCallbackFunc cb);
|
||||
RTC_C_EXPORT int rtcSetIceStateChangeCallback(int pc, rtcIceStateChangeCallbackFunc cb);
|
||||
RTC_C_EXPORT int rtcSetGatheringStateChangeCallback(int pc, rtcGatheringStateCallbackFunc cb);
|
||||
RTC_C_EXPORT int rtcSetSignalingStateChangeCallback(int pc, rtcSignalingStateCallbackFunc cb);
|
||||
|
||||
RTC_C_EXPORT int rtcSetLocalDescription(int pc, const char *type); // type may be NULL
|
||||
RTC_C_EXPORT int rtcSetRemoteDescription(int pc, const char *sdp, const char *type);
|
||||
RTC_C_EXPORT int rtcAddRemoteCandidate(int pc, const char *cand, const char *mid);
|
||||
|
||||
RTC_C_EXPORT int rtcGetLocalDescription(int pc, char *buffer, int size);
|
||||
RTC_C_EXPORT int rtcGetRemoteDescription(int pc, char *buffer, int size);
|
||||
|
||||
RTC_C_EXPORT int rtcGetLocalDescriptionType(int pc, char *buffer, int size);
|
||||
RTC_C_EXPORT int rtcGetRemoteDescriptionType(int pc, char *buffer, int size);
|
||||
|
||||
// For specific use cases only
|
||||
RTC_C_EXPORT int rtcCreateOffer(int pc, char *buffer, int size);
|
||||
RTC_C_EXPORT int rtcCreateAnswer(int pc, char *buffer, int size);
|
||||
|
||||
RTC_C_EXPORT int rtcGetLocalAddress(int pc, char *buffer, int size);
|
||||
RTC_C_EXPORT int rtcGetRemoteAddress(int pc, char *buffer, int size);
|
||||
|
||||
RTC_C_EXPORT int rtcGetSelectedCandidatePair(int pc, char *local, int localSize, char *remote,
|
||||
int remoteSize);
|
||||
|
||||
RTC_C_EXPORT bool rtcIsNegotiationNeeded(int pc);
|
||||
|
||||
RTC_C_EXPORT int rtcGetMaxDataChannelStream(int pc);
|
||||
RTC_C_EXPORT int rtcGetRemoteMaxMessageSize(int pc);
|
||||
|
||||
// DataChannel, Track, and WebSocket common API
|
||||
|
||||
RTC_C_EXPORT int rtcSetOpenCallback(int id, rtcOpenCallbackFunc cb);
|
||||
RTC_C_EXPORT int rtcSetClosedCallback(int id, rtcClosedCallbackFunc cb);
|
||||
RTC_C_EXPORT int rtcSetErrorCallback(int id, rtcErrorCallbackFunc cb);
|
||||
RTC_C_EXPORT int rtcSetMessageCallback(int id, rtcMessageCallbackFunc cb);
|
||||
RTC_C_EXPORT int rtcSendMessage(int id, const char *data, int size);
|
||||
RTC_C_EXPORT int rtcClose(int id);
|
||||
RTC_C_EXPORT int rtcDelete(int id);
|
||||
RTC_C_EXPORT bool rtcIsOpen(int id);
|
||||
RTC_C_EXPORT bool rtcIsClosed(int id);
|
||||
|
||||
RTC_C_EXPORT int rtcMaxMessageSize(int id);
|
||||
RTC_C_EXPORT int rtcGetBufferedAmount(int id); // total size buffered to send
|
||||
RTC_C_EXPORT int rtcSetBufferedAmountLowThreshold(int id, int amount);
|
||||
RTC_C_EXPORT int rtcSetBufferedAmountLowCallback(int id, rtcBufferedAmountLowCallbackFunc cb);
|
||||
|
||||
// DataChannel, Track, and WebSocket common extended API
|
||||
|
||||
RTC_C_EXPORT int rtcGetAvailableAmount(int id); // total size available to receive
|
||||
RTC_C_EXPORT int rtcSetAvailableCallback(int id, rtcAvailableCallbackFunc cb);
|
||||
RTC_C_EXPORT int rtcReceiveMessage(int id, char *buffer, int *size);
|
||||
|
||||
// DataChannel
|
||||
|
||||
typedef struct {
|
||||
bool unordered;
|
||||
bool unreliable;
|
||||
unsigned int maxPacketLifeTime; // ignored if reliable
|
||||
unsigned int maxRetransmits; // ignored if reliable
|
||||
} rtcReliability;
|
||||
|
||||
typedef struct {
|
||||
rtcReliability reliability;
|
||||
const char *protocol; // empty string if NULL
|
||||
bool negotiated;
|
||||
bool manualStream;
|
||||
uint16_t stream; // numeric ID 0-65534, ignored if manualStream is false
|
||||
} rtcDataChannelInit;
|
||||
|
||||
RTC_C_EXPORT int rtcSetDataChannelCallback(int pc, rtcDataChannelCallbackFunc cb);
|
||||
RTC_C_EXPORT int rtcCreateDataChannel(int pc, const char *label); // returns dc id
|
||||
RTC_C_EXPORT int rtcCreateDataChannelEx(int pc, const char *label,
|
||||
const rtcDataChannelInit *init); // returns dc id
|
||||
RTC_C_EXPORT int rtcDeleteDataChannel(int dc);
|
||||
|
||||
RTC_C_EXPORT int rtcGetDataChannelStream(int dc);
|
||||
RTC_C_EXPORT int rtcGetDataChannelLabel(int dc, char *buffer, int size);
|
||||
RTC_C_EXPORT int rtcGetDataChannelProtocol(int dc, char *buffer, int size);
|
||||
RTC_C_EXPORT int rtcGetDataChannelReliability(int dc, rtcReliability *reliability);
|
||||
|
||||
// Track
|
||||
|
||||
typedef struct {
|
||||
rtcDirection direction;
|
||||
rtcCodec codec;
|
||||
int payloadType;
|
||||
uint32_t ssrc;
|
||||
const char *mid;
|
||||
const char *name; // optional
|
||||
const char *msid; // optional
|
||||
const char *trackId; // optional, track ID used in MSID
|
||||
const char *profile; // optional, codec profile
|
||||
} rtcTrackInit;
|
||||
|
||||
RTC_C_EXPORT int rtcSetTrackCallback(int pc, rtcTrackCallbackFunc cb);
|
||||
RTC_C_EXPORT int rtcAddTrack(int pc, const char *mediaDescriptionSdp); // returns tr id
|
||||
RTC_C_EXPORT int rtcAddTrackEx(int pc, const rtcTrackInit *init); // returns tr id
|
||||
RTC_C_EXPORT int rtcDeleteTrack(int tr);
|
||||
|
||||
RTC_C_EXPORT int rtcGetTrackDescription(int tr, char *buffer, int size);
|
||||
RTC_C_EXPORT int rtcGetTrackMid(int tr, char *buffer, int size);
|
||||
RTC_C_EXPORT int rtcGetTrackDirection(int tr, rtcDirection *direction);
|
||||
|
||||
RTC_C_EXPORT int rtcRequestKeyframe(int tr);
|
||||
RTC_C_EXPORT int rtcRequestBitrate(int tr, unsigned int bitrate);
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
// Media
|
||||
|
||||
// Define how OBUs are packetizied in a AV1 Sample
|
||||
typedef enum {
|
||||
RTC_OBU_PACKETIZED_OBU = 0,
|
||||
RTC_OBU_PACKETIZED_TEMPORAL_UNIT = 1,
|
||||
} rtcObuPacketization;
|
||||
|
||||
// Define how NAL units are separated in a H264/H265 sample
|
||||
typedef enum {
|
||||
RTC_NAL_SEPARATOR_LENGTH = 0, // first 4 bytes are NAL unit length
|
||||
RTC_NAL_SEPARATOR_LONG_START_SEQUENCE = 1, // 0x00, 0x00, 0x00, 0x01
|
||||
RTC_NAL_SEPARATOR_SHORT_START_SEQUENCE = 2, // 0x00, 0x00, 0x01
|
||||
RTC_NAL_SEPARATOR_START_SEQUENCE = 3, // long or short start sequence
|
||||
} rtcNalUnitSeparator;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ssrc;
|
||||
const char *cname;
|
||||
uint8_t payloadType;
|
||||
uint32_t clockRate;
|
||||
uint16_t sequenceNumber;
|
||||
uint32_t timestamp;
|
||||
|
||||
// H264, H265, AV1
|
||||
uint16_t maxFragmentSize; // Maximum fragment size, 0 means default
|
||||
|
||||
// H264/H265 only
|
||||
rtcNalUnitSeparator nalSeparator; // NAL unit separator
|
||||
|
||||
// AV1 only
|
||||
rtcObuPacketization obuPacketization; // OBU paketization for AV1 samples
|
||||
|
||||
uint8_t playoutDelayId;
|
||||
uint16_t playoutDelayMin;
|
||||
uint16_t playoutDelayMax;
|
||||
|
||||
uint8_t colorSpaceId;
|
||||
uint8_t colorChromaSitingHorz;
|
||||
uint8_t colorChromaSitingVert;
|
||||
uint8_t colorRange;
|
||||
uint8_t colorPrimaries;
|
||||
uint8_t colorTransfer;
|
||||
uint8_t colorMatrix;
|
||||
} rtcPacketizerInit;
|
||||
|
||||
// Deprecated, do not use
|
||||
typedef rtcPacketizerInit rtcPacketizationHandlerInit;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ssrc;
|
||||
const char *name; // optional
|
||||
const char *msid; // optional
|
||||
const char *trackId; // optional, track ID used in MSID
|
||||
} rtcSsrcForTypeInit;
|
||||
|
||||
// Opaque type used (via rtcMessage*) to reference an rtc::Message
|
||||
typedef void *rtcMessage;
|
||||
|
||||
// Allocate a new opaque message.
|
||||
// Must be explicitly freed by rtcDeleteOpaqueMessage() unless
|
||||
// explicitly returned by a media interceptor callback;
|
||||
RTC_C_EXPORT rtcMessage *rtcCreateOpaqueMessage(void *data, int size);
|
||||
RTC_C_EXPORT void rtcDeleteOpaqueMessage(rtcMessage *msg);
|
||||
|
||||
// Set MediaInterceptor on peer connection
|
||||
RTC_C_EXPORT int rtcSetMediaInterceptorCallback(int id, rtcInterceptorCallbackFunc cb);
|
||||
|
||||
// Set a packetizer on track
|
||||
RTC_C_EXPORT int rtcSetH264Packetizer(int tr, const rtcPacketizerInit *init);
|
||||
RTC_C_EXPORT int rtcSetH265Packetizer(int tr, const rtcPacketizerInit *init);
|
||||
RTC_C_EXPORT int rtcSetAV1Packetizer(int tr, const rtcPacketizerInit *init);
|
||||
RTC_C_EXPORT int rtcSetOpusPacketizer(int tr, const rtcPacketizerInit *init);
|
||||
RTC_C_EXPORT int rtcSetAACPacketizer(int tr, const rtcPacketizerInit *init);
|
||||
RTC_C_EXPORT int rtcSetPCMUPacketizer(int tr, const rtcPacketizerInit *init);
|
||||
RTC_C_EXPORT int rtcSetPCMAPacketizer(int tr, const rtcPacketizerInit *init);
|
||||
RTC_C_EXPORT int rtcSetG722Packetizer(int tr, const rtcPacketizerInit *init);
|
||||
|
||||
// Deprecated, do not use
|
||||
RTC_DEPRECATED static inline int
|
||||
rtcSetH264PacketizationHandler(int tr, const rtcPacketizationHandlerInit *init) {
|
||||
return rtcSetH264Packetizer(tr, init);
|
||||
}
|
||||
RTC_DEPRECATED static inline int
|
||||
rtcSetH265PacketizationHandler(int tr, const rtcPacketizationHandlerInit *init) {
|
||||
return rtcSetH265Packetizer(tr, init);
|
||||
}
|
||||
RTC_DEPRECATED static inline int
|
||||
rtcSetAV1PacketizationHandler(int tr, const rtcPacketizationHandlerInit *init) {
|
||||
return rtcSetAV1Packetizer(tr, init);
|
||||
}
|
||||
RTC_DEPRECATED static inline int
|
||||
rtcSetOpusPacketizationHandler(int tr, const rtcPacketizationHandlerInit *init) {
|
||||
return rtcSetOpusPacketizer(tr, init);
|
||||
}
|
||||
RTC_DEPRECATED static inline int
|
||||
rtcSetAACPacketizationHandler(int tr, const rtcPacketizationHandlerInit *init) {
|
||||
return rtcSetAACPacketizer(tr, init);
|
||||
}
|
||||
|
||||
// Chain RtcpReceivingSession on track
|
||||
RTC_C_EXPORT int rtcChainRtcpReceivingSession(int tr);
|
||||
|
||||
// Chain RtcpSrReporter on track
|
||||
RTC_C_EXPORT int rtcChainRtcpSrReporter(int tr);
|
||||
|
||||
// Chain RtcpNackResponder on track
|
||||
RTC_C_EXPORT int rtcChainRtcpNackResponder(int tr, unsigned int maxStoredPacketsCount);
|
||||
|
||||
// Chain PliHandler on track
|
||||
RTC_C_EXPORT int rtcChainPliHandler(int tr, rtcPliHandlerCallbackFunc cb);
|
||||
|
||||
// Chain RembHandler on track
|
||||
RTC_C_EXPORT int rtcChainRembHandler(int tr, rtcRembHandlerCallbackFunc cb);
|
||||
|
||||
// Transform seconds to timestamp using track's clock rate, result is written to timestamp
|
||||
RTC_C_EXPORT int rtcTransformSecondsToTimestamp(int id, double seconds, uint32_t *timestamp);
|
||||
|
||||
// Transform timestamp to seconds using track's clock rate, result is written to seconds
|
||||
RTC_C_EXPORT int rtcTransformTimestampToSeconds(int id, uint32_t timestamp, double *seconds);
|
||||
|
||||
// Get current timestamp, result is written to timestamp
|
||||
RTC_C_EXPORT int rtcGetCurrentTrackTimestamp(int id, uint32_t *timestamp);
|
||||
|
||||
// Set RTP timestamp for track identified by given id
|
||||
RTC_C_EXPORT int rtcSetTrackRtpTimestamp(int id, uint32_t timestamp);
|
||||
|
||||
// Get timestamp of last RTCP SR, result is written to timestamp
|
||||
RTC_C_EXPORT int rtcGetLastTrackSenderReportTimestamp(int id, uint32_t *timestamp);
|
||||
|
||||
// Get all available payload types for given codec and stores them in buffer, does nothing if
|
||||
// buffer is NULL
|
||||
int rtcGetTrackPayloadTypesForCodec(int tr, const char *ccodec, int *buffer, int size);
|
||||
|
||||
// Get all SSRCs for given track
|
||||
int rtcGetSsrcsForTrack(int tr, uint32_t *buffer, int count);
|
||||
|
||||
// Get CName for SSRC
|
||||
int rtcGetCNameForSsrc(int tr, uint32_t ssrc, char *cname, int cnameSize);
|
||||
|
||||
// Get all SSRCs for given media type in given SDP
|
||||
int rtcGetSsrcsForType(const char *mediaType, const char *sdp, uint32_t *buffer, int bufferSize);
|
||||
|
||||
// Set SSRC for given media type in given SDP
|
||||
int rtcSetSsrcForType(const char *mediaType, const char *sdp, char *buffer, const int bufferSize,
|
||||
rtcSsrcForTypeInit *init);
|
||||
|
||||
// For backward compatibility, do not use
|
||||
RTC_C_EXPORT RTC_DEPRECATED int rtcSetNeedsToSendRtcpSr(int id);
|
||||
|
||||
#endif // RTC_ENABLE_MEDIA
|
||||
|
||||
#if RTC_ENABLE_WEBSOCKET
|
||||
|
||||
// WebSocket
|
||||
|
||||
typedef struct {
|
||||
bool disableTlsVerification; // if true, don't verify the TLS certificate
|
||||
const char *proxyServer; // only non-authenticated http supported for now
|
||||
const char **protocols;
|
||||
int protocolsCount;
|
||||
int connectionTimeoutMs; // in milliseconds, 0 means default, < 0 means disabled
|
||||
int pingIntervalMs; // in milliseconds, 0 means default, < 0 means disabled
|
||||
int maxOutstandingPings; // 0 means default, < 0 means disabled
|
||||
int maxMessageSize; // <= 0 means default
|
||||
} rtcWsConfiguration;
|
||||
|
||||
RTC_C_EXPORT int rtcCreateWebSocket(const char *url); // returns ws id
|
||||
RTC_C_EXPORT int rtcCreateWebSocketEx(const char *url, const rtcWsConfiguration *config);
|
||||
RTC_C_EXPORT int rtcDeleteWebSocket(int ws);
|
||||
|
||||
RTC_C_EXPORT int rtcGetWebSocketRemoteAddress(int ws, char *buffer, int size);
|
||||
RTC_C_EXPORT int rtcGetWebSocketPath(int ws, char *buffer, int size);
|
||||
|
||||
// WebSocketServer
|
||||
|
||||
typedef void(RTC_API *rtcWebSocketClientCallbackFunc)(int wsserver, int ws, void *ptr);
|
||||
|
||||
typedef struct {
|
||||
uint16_t port; // 0 means automatic selection
|
||||
bool enableTls; // if true, enable TLS (WSS)
|
||||
const char *certificatePemFile; // NULL for autogenerated certificate
|
||||
const char *keyPemFile; // NULL for autogenerated certificate
|
||||
const char *keyPemPass; // NULL if no pass
|
||||
const char *bindAddress; // NULL for any
|
||||
int connectionTimeoutMs; // in milliseconds, 0 means default, < 0 means disabled
|
||||
int maxMessageSize; // <= 0 means default
|
||||
} rtcWsServerConfiguration;
|
||||
|
||||
RTC_C_EXPORT int rtcCreateWebSocketServer(const rtcWsServerConfiguration *config,
|
||||
rtcWebSocketClientCallbackFunc cb); // returns wsserver id
|
||||
RTC_C_EXPORT int rtcDeleteWebSocketServer(int wsserver);
|
||||
|
||||
RTC_C_EXPORT int rtcGetWebSocketServerPort(int wsserver);
|
||||
|
||||
#endif
|
||||
|
||||
// Optional global preload and cleanup
|
||||
|
||||
RTC_C_EXPORT void rtcPreload(void);
|
||||
RTC_C_EXPORT void rtcCleanup(void);
|
||||
|
||||
// SCTP global settings
|
||||
|
||||
typedef struct {
|
||||
int recvBufferSize; // in bytes, <= 0 means optimized default
|
||||
int sendBufferSize; // in bytes, <= 0 means optimized default
|
||||
int maxChunksOnQueue; // in chunks, <= 0 means optimized default
|
||||
int initialCongestionWindow; // in MTUs, <= 0 means optimized default
|
||||
int maxBurst; // in MTUs, 0 means optimized default, < 0 means disabled
|
||||
int congestionControlModule; // 0: RFC2581 (default), 1: HSTCP, 2: H-TCP, 3: RTCC
|
||||
int delayedSackTimeMs; // in milliseconds, 0 means optimized default, < 0 means disabled
|
||||
int minRetransmitTimeoutMs; // in milliseconds, <= 0 means optimized default
|
||||
int maxRetransmitTimeoutMs; // in milliseconds, <= 0 means optimized default
|
||||
int initialRetransmitTimeoutMs; // in milliseconds, <= 0 means optimized default
|
||||
int maxRetransmitAttempts; // number of retransmissions, <= 0 means optimized default
|
||||
int heartbeatIntervalMs; // in milliseconds, <= 0 means optimized default
|
||||
} rtcSctpSettings;
|
||||
|
||||
// Note: SCTP settings apply to newly-created PeerConnections only
|
||||
RTC_C_EXPORT int rtcSetSctpSettings(const rtcSctpSettings *settings);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
48
components/3rd_party/datachannel/include/rtc/rtc.hpp
vendored
Normal file
48
components/3rd_party/datachannel/include/rtc/rtc.hpp
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
// C API
|
||||
#include "rtc.h"
|
||||
|
||||
// C++ API
|
||||
#include "common.hpp"
|
||||
#include "global.hpp"
|
||||
//
|
||||
#include "datachannel.hpp"
|
||||
#include "peerconnection.hpp"
|
||||
#include "track.hpp"
|
||||
#include "iceudpmuxlistener.hpp"
|
||||
|
||||
#if RTC_ENABLE_WEBSOCKET
|
||||
|
||||
// WebSocket
|
||||
#include "websocket.hpp"
|
||||
#include "websocketserver.hpp"
|
||||
|
||||
#endif // RTC_ENABLE_WEBSOCKET
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
// Media
|
||||
#include "av1rtppacketizer.hpp"
|
||||
#include "dependencydescriptor.hpp"
|
||||
#include "h264rtppacketizer.hpp"
|
||||
#include "h264rtpdepacketizer.hpp"
|
||||
#include "h265rtppacketizer.hpp"
|
||||
#include "h265rtpdepacketizer.hpp"
|
||||
#include "mediahandler.hpp"
|
||||
#include "plihandler.hpp"
|
||||
#include "rembhandler.hpp"
|
||||
#include "pacinghandler.hpp"
|
||||
#include "rtcpnackresponder.hpp"
|
||||
#include "rtcpreceivingsession.hpp"
|
||||
#include "rtcpsrreporter.hpp"
|
||||
#include "rtppacketizer.hpp"
|
||||
#include "rtpdepacketizer.hpp"
|
||||
|
||||
#endif // RTC_ENABLE_MEDIA
|
||||
76
components/3rd_party/datachannel/include/rtc/rtcpnackresponder.hpp
vendored
Normal file
76
components/3rd_party/datachannel/include/rtc/rtcpnackresponder.hpp
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_RTCP_NACK_RESPONDER_H
|
||||
#define RTC_RTCP_NACK_RESPONDER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "mediahandler.hpp"
|
||||
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class RTC_CPP_EXPORT RtcpNackResponder final : public MediaHandler {
|
||||
public:
|
||||
static const size_t DefaultMaxSize = 512;
|
||||
|
||||
RtcpNackResponder(size_t maxSize = DefaultMaxSize);
|
||||
|
||||
void incoming(message_vector &messages, const message_callback &send) override;
|
||||
void outgoing(message_vector &messages, const message_callback &send) override;
|
||||
|
||||
private:
|
||||
// Packet storage
|
||||
class RTC_CPP_EXPORT Storage {
|
||||
|
||||
/// Packet storage element
|
||||
struct RTC_CPP_EXPORT Element {
|
||||
Element(message_ptr packet, uint16_t sequenceNumber, shared_ptr<Element> next = nullptr);
|
||||
const message_ptr packet;
|
||||
const uint16_t sequenceNumber;
|
||||
/// Pointer to newer element
|
||||
shared_ptr<Element> next = nullptr;
|
||||
};
|
||||
|
||||
private:
|
||||
/// Oldest packet in storage
|
||||
shared_ptr<Element> oldest = nullptr;
|
||||
/// Newest packet in storage
|
||||
shared_ptr<Element> newest = nullptr;
|
||||
/// Inner storage
|
||||
std::unordered_map<uint16_t, shared_ptr<Element>> storage{};
|
||||
std::mutex mutex;
|
||||
|
||||
/// Maximum storage size
|
||||
const size_t maxSize;
|
||||
|
||||
/// Returns current size
|
||||
size_t size();
|
||||
|
||||
public:
|
||||
Storage(size_t _maxSize);
|
||||
|
||||
/// Returns packet with given sequence number
|
||||
message_ptr get(uint16_t sequenceNumber);
|
||||
|
||||
/// Stores packet
|
||||
/// @param packet Packet
|
||||
void store(message_ptr packet);
|
||||
};
|
||||
|
||||
const shared_ptr<Storage> mStorage;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_RTCP_NACK_RESPONDER_H */
|
||||
79
components/3rd_party/datachannel/include/rtc/rtcpreceivingsession.hpp
vendored
Normal file
79
components/3rd_party/datachannel/include/rtc/rtcpreceivingsession.hpp
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Staz Modrzynski
|
||||
* Copyright (c) 2020 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_RTCP_RECEIVING_SESSION_H
|
||||
#define RTC_RTCP_RECEIVING_SESSION_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "common.hpp"
|
||||
#include "mediahandler.hpp"
|
||||
#include "message.hpp"
|
||||
#include "rtp.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
#define RTP_SEQ_MOD (1<<16)
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// An RtcpSession can be plugged into a Track to handle the whole RTCP session
|
||||
class RTC_CPP_EXPORT RtcpReceivingSession : public MediaHandler {
|
||||
public:
|
||||
RtcpReceivingSession() = default;
|
||||
virtual ~RtcpReceivingSession() = default;
|
||||
|
||||
void incoming(message_vector &messages, const message_callback &send) override;
|
||||
bool requestKeyframe(const message_callback &send) override;
|
||||
bool requestBitrate(unsigned int bitrate, const message_callback &send) override;
|
||||
|
||||
// For backward compatibility
|
||||
[[deprecated("Use Track::requestKeyframe()")]] inline bool requestKeyframe() { return false; };
|
||||
[[deprecated("Use Track::requestBitrate()")]] inline void requestBitrate(unsigned int) {};
|
||||
|
||||
struct SyncTimestamps {
|
||||
uint64_t rtpTimestamp;
|
||||
uint64_t ntpTimestamp;
|
||||
};
|
||||
|
||||
SyncTimestamps getSyncTimestamps();
|
||||
|
||||
protected:
|
||||
void pushREMB(const message_callback &send, unsigned int bitrate);
|
||||
void pushRR(const message_callback &send,unsigned int lastSrDelay);
|
||||
void pushPLI(const message_callback &send);
|
||||
|
||||
void initSeq(uint16_t seq);
|
||||
bool updateSeq(uint16_t seq);
|
||||
|
||||
SSRC mSsrc = 0;
|
||||
uint32_t mGreatestSeqNo = 0;
|
||||
uint16_t mMaxSeq = 0; // highest seq. number seen
|
||||
uint32_t mCycles = 0; // shifted count of seq. number cycles
|
||||
uint32_t mBaseSeq = 0; // base seq number
|
||||
uint32_t mBadSeq = 0; // last 'bad' seq number + 1
|
||||
uint32_t mProbation = 0; // sequ. packets till source is valid
|
||||
uint32_t mReceived = 0; // packets received
|
||||
uint32_t mExpectedPrior = 0; // packet expected at last interval
|
||||
uint32_t mReceivedPrior = 0; // packet received at last interval
|
||||
uint32_t mTransit = 0; // relative trans time for prev pkt
|
||||
uint32_t mJitter = 0;
|
||||
|
||||
SyncTimestamps mSyncTimestamps{0,0};
|
||||
|
||||
std::atomic<unsigned int> mRequestedBitrate = 0;
|
||||
std::mutex mSyncMutex;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // RTC_ENABLE_MEDIA
|
||||
|
||||
#endif // RTC_RTCP_RECEIVING_SESSION_H
|
||||
49
components/3rd_party/datachannel/include/rtc/rtcpsrreporter.hpp
vendored
Normal file
49
components/3rd_party/datachannel/include/rtc/rtcpsrreporter.hpp
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_RTCP_SR_REPORTER_H
|
||||
#define RTC_RTCP_SR_REPORTER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "mediahandler.hpp"
|
||||
#include "rtp.hpp"
|
||||
#include "rtppacketizationconfig.hpp"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class RTC_CPP_EXPORT RtcpSrReporter final : public MediaHandler {
|
||||
public:
|
||||
RtcpSrReporter(shared_ptr<RtpPacketizationConfig> rtpConfig);
|
||||
~RtcpSrReporter();
|
||||
|
||||
uint32_t lastReportedTimestamp() const;
|
||||
[[deprecated]] void setNeedsToReport();
|
||||
|
||||
void outgoing(message_vector &messages, const message_callback &send) override;
|
||||
|
||||
// TODO: remove this
|
||||
const shared_ptr<RtpPacketizationConfig> rtpConfig;
|
||||
|
||||
private:
|
||||
void addToReport(RtpHeader *header, size_t size);
|
||||
message_ptr getSenderReport(uint32_t timestamp);
|
||||
|
||||
uint32_t mPacketCount = 0;
|
||||
uint32_t mPayloadOctets = 0;
|
||||
uint32_t mLastReportedTimestamp = 0;
|
||||
std::chrono::steady_clock::time_point mLastReportTime;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_RTCP_SR_REPORTER_H */
|
||||
367
components/3rd_party/datachannel/include/rtc/rtp.hpp
vendored
Normal file
367
components/3rd_party/datachannel/include/rtc/rtp.hpp
vendored
Normal file
@@ -0,0 +1,367 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Staz Modrzynski
|
||||
* Copyright (c) 2020 Paul-Louis Ageneau
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_RTP_HPP
|
||||
#define RTC_RTP_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
typedef uint32_t SSRC;
|
||||
|
||||
RTC_CPP_EXPORT bool IsRtcp(const binary &data);
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct RTC_CPP_EXPORT RtpExtensionHeader {
|
||||
uint16_t _profileSpecificId;
|
||||
uint16_t _headerLength;
|
||||
|
||||
[[nodiscard]] uint16_t profileSpecificId() const;
|
||||
[[nodiscard]] uint16_t headerLength() const;
|
||||
|
||||
[[nodiscard]] size_t getSize() const;
|
||||
[[nodiscard]] const char *getBody() const;
|
||||
[[nodiscard]] char *getBody();
|
||||
|
||||
void setProfileSpecificId(uint16_t profileSpecificId);
|
||||
void setHeaderLength(uint16_t headerLength);
|
||||
|
||||
void clearBody();
|
||||
size_t writeCurrentVideoOrientation(bool twoByteHeader, size_t offset, uint8_t id,
|
||||
uint8_t value);
|
||||
size_t writeOneByteHeader(size_t offset, uint8_t id, const byte *value, size_t size);
|
||||
size_t writeTwoByteHeader(size_t offset, uint8_t id, const byte *value, size_t size);
|
||||
size_t writeHeader(bool twoByteHeader, size_t offset, uint8_t id, const byte *value,
|
||||
size_t size);
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RtpHeader {
|
||||
uint8_t _first;
|
||||
uint8_t _payloadType;
|
||||
uint16_t _seqNumber;
|
||||
uint32_t _timestamp;
|
||||
SSRC _ssrc;
|
||||
// The following field is SSRC _csrc[]
|
||||
|
||||
[[nodiscard]] uint8_t version() const;
|
||||
[[nodiscard]] bool padding() const;
|
||||
[[nodiscard]] bool extension() const;
|
||||
[[nodiscard]] uint8_t csrcCount() const;
|
||||
[[nodiscard]] uint8_t marker() const;
|
||||
[[nodiscard]] uint8_t payloadType() const;
|
||||
[[nodiscard]] uint16_t seqNumber() const;
|
||||
[[nodiscard]] uint32_t timestamp() const;
|
||||
[[nodiscard]] uint32_t ssrc() const;
|
||||
|
||||
[[nodiscard]] size_t getSize() const;
|
||||
[[nodiscard]] size_t getExtensionHeaderSize() const;
|
||||
[[nodiscard]] const RtpExtensionHeader *getExtensionHeader() const;
|
||||
[[nodiscard]] RtpExtensionHeader *getExtensionHeader();
|
||||
[[nodiscard]] const char *getBody() const;
|
||||
[[nodiscard]] char *getBody();
|
||||
|
||||
void log() const;
|
||||
|
||||
void preparePacket();
|
||||
void setSeqNumber(uint16_t newSeqNo);
|
||||
void setPayloadType(uint8_t newPayloadType);
|
||||
void setSsrc(uint32_t in_ssrc);
|
||||
void setMarker(bool marker);
|
||||
void setTimestamp(uint32_t i);
|
||||
void setExtension(bool extension);
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RtcpReportBlock {
|
||||
SSRC _ssrc;
|
||||
uint32_t _fractionLostAndPacketsLost; // fraction lost is 8-bit, packets lost is 24-bit
|
||||
uint16_t _seqNoCycles;
|
||||
uint16_t _highestSeqNo;
|
||||
uint32_t _jitter;
|
||||
uint32_t _lastReport;
|
||||
uint32_t _delaySinceLastReport;
|
||||
|
||||
[[nodiscard]] uint16_t seqNoCycles() const;
|
||||
[[nodiscard]] uint16_t highestSeqNo() const;
|
||||
[[nodiscard]] uint32_t extendedHighestSeqNo() const;
|
||||
[[nodiscard]] uint32_t jitter() const;
|
||||
[[nodiscard]] uint32_t delaySinceSR() const;
|
||||
|
||||
[[nodiscard]] SSRC getSSRC() const;
|
||||
[[nodiscard]] uint32_t getNTPOfSR() const;
|
||||
[[nodiscard]] uint8_t getFractionLost() const;
|
||||
[[nodiscard]] unsigned int getPacketsLostCount() const;
|
||||
|
||||
void preparePacket(SSRC in_ssrc, uint8_t fraction, unsigned int totalPacketsLost,
|
||||
uint16_t highestSeqNo, uint16_t seqNoCycles, uint32_t jitter,
|
||||
uint64_t lastSR_NTP, uint64_t lastSR_DELAY);
|
||||
void setSSRC(SSRC in_ssrc);
|
||||
void setPacketsLost(uint8_t fractionLost, unsigned int packetsLostCount);
|
||||
void setSeqNo(uint16_t highestSeqNo, uint16_t seqNoCycles);
|
||||
void setJitter(uint32_t jitter);
|
||||
void setNTPOfSR(uint64_t ntp);
|
||||
void setDelaySinceSR(uint32_t sr);
|
||||
|
||||
void log() const;
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RtcpHeader {
|
||||
uint8_t _first;
|
||||
uint8_t _payloadType;
|
||||
uint16_t _length;
|
||||
|
||||
[[nodiscard]] uint8_t version() const;
|
||||
[[nodiscard]] bool padding() const;
|
||||
[[nodiscard]] uint8_t reportCount() const;
|
||||
[[nodiscard]] uint8_t payloadType() const;
|
||||
[[nodiscard]] uint16_t length() const;
|
||||
[[nodiscard]] size_t lengthInBytes() const;
|
||||
|
||||
void prepareHeader(uint8_t payloadType, uint8_t reportCount, uint16_t length);
|
||||
void setPayloadType(uint8_t type);
|
||||
void setReportCount(uint8_t count);
|
||||
void setLength(uint16_t length);
|
||||
|
||||
void log() const;
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RtcpFbHeader {
|
||||
RtcpHeader header;
|
||||
|
||||
SSRC _packetSender;
|
||||
SSRC _mediaSource;
|
||||
|
||||
[[nodiscard]] SSRC packetSenderSSRC() const;
|
||||
[[nodiscard]] SSRC mediaSourceSSRC() const;
|
||||
|
||||
void setPacketSenderSSRC(SSRC ssrc);
|
||||
void setMediaSourceSSRC(SSRC ssrc);
|
||||
|
||||
void log() const;
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RtcpSr {
|
||||
RtcpHeader header;
|
||||
|
||||
SSRC _senderSSRC;
|
||||
uint64_t _ntpTimestamp;
|
||||
uint32_t _rtpTimestamp;
|
||||
uint32_t _packetCount;
|
||||
uint32_t _octetCount;
|
||||
|
||||
RtcpReportBlock _reportBlocks;
|
||||
|
||||
[[nodiscard]] static unsigned int Size(unsigned int reportCount);
|
||||
|
||||
[[nodiscard]] uint64_t ntpTimestamp() const;
|
||||
[[nodiscard]] uint32_t rtpTimestamp() const;
|
||||
[[nodiscard]] uint32_t packetCount() const;
|
||||
[[nodiscard]] uint32_t octetCount() const;
|
||||
[[nodiscard]] uint32_t senderSSRC() const;
|
||||
|
||||
[[nodiscard]] const RtcpReportBlock *getReportBlock(int num) const;
|
||||
[[nodiscard]] RtcpReportBlock *getReportBlock(int num);
|
||||
[[nodiscard]] unsigned int size(unsigned int reportCount);
|
||||
[[nodiscard]] size_t getSize() const;
|
||||
|
||||
void preparePacket(SSRC senderSSRC, uint8_t reportCount);
|
||||
void setNtpTimestamp(uint64_t ts);
|
||||
void setRtpTimestamp(uint32_t ts);
|
||||
void setOctetCount(uint32_t ts);
|
||||
void setPacketCount(uint32_t ts);
|
||||
|
||||
void log() const;
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RtcpSdesItem {
|
||||
uint8_t type;
|
||||
|
||||
uint8_t _length;
|
||||
char _text[1];
|
||||
|
||||
[[nodiscard]] static unsigned int Size(uint8_t textLength);
|
||||
|
||||
[[nodiscard]] string text() const;
|
||||
[[nodiscard]] uint8_t length() const;
|
||||
|
||||
void setText(string text);
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RtcpSdesChunk {
|
||||
SSRC _ssrc;
|
||||
RtcpSdesItem _items;
|
||||
|
||||
[[nodiscard]] static unsigned int Size(const std::vector<uint8_t> textLengths);
|
||||
|
||||
[[nodiscard]] SSRC ssrc() const;
|
||||
|
||||
void setSSRC(SSRC ssrc);
|
||||
|
||||
// Get item at given index
|
||||
// All items with index < num must be valid, otherwise this function has undefined behaviour
|
||||
// (use safelyCountChunkSize() to check if chunk is valid).
|
||||
[[nodiscard]] const RtcpSdesItem *getItem(int num) const;
|
||||
[[nodiscard]] RtcpSdesItem *getItem(int num);
|
||||
|
||||
// Get size of chunk
|
||||
// All items must be valid, otherwise this function has undefined behaviour (use
|
||||
// safelyCountChunkSize() to check if chunk is valid)
|
||||
[[nodiscard]] unsigned int getSize() const;
|
||||
|
||||
long safelyCountChunkSize(size_t maxChunkSize) const;
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RtcpSdes {
|
||||
RtcpHeader header;
|
||||
RtcpSdesChunk _chunks;
|
||||
|
||||
[[nodiscard]] static unsigned int Size(const std::vector<std::vector<uint8_t>> lengths);
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
// Returns number of chunks in this packet
|
||||
// Returns 0 if packet is invalid
|
||||
unsigned int chunksCount() const;
|
||||
|
||||
// Get chunk at given index
|
||||
// All chunks (and their items) with index < `num` must be valid, otherwise this function has
|
||||
// undefined behaviour (use `isValid` to check if chunk is valid).
|
||||
const RtcpSdesChunk *getChunk(int num) const;
|
||||
RtcpSdesChunk *getChunk(int num);
|
||||
|
||||
void preparePacket(uint8_t chunkCount);
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RtcpRr {
|
||||
RtcpHeader header;
|
||||
|
||||
SSRC _senderSSRC;
|
||||
RtcpReportBlock _reportBlocks;
|
||||
|
||||
[[nodiscard]] static size_t SizeWithReportBlocks(uint8_t reportCount);
|
||||
|
||||
SSRC senderSSRC() const;
|
||||
bool isSenderReport();
|
||||
bool isReceiverReport();
|
||||
|
||||
[[nodiscard]] RtcpReportBlock *getReportBlock(int num);
|
||||
[[nodiscard]] const RtcpReportBlock *getReportBlock(int num) const;
|
||||
[[nodiscard]] size_t getSize() const;
|
||||
|
||||
void preparePacket(SSRC senderSSRC, uint8_t reportCount);
|
||||
void setSenderSSRC(SSRC ssrc);
|
||||
|
||||
void log() const;
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RtcpRemb {
|
||||
RtcpFbHeader header;
|
||||
|
||||
char _id[4]; // Unique identifier ('R' 'E' 'M' 'B')
|
||||
uint32_t _bitrate; // Num SSRC, Br Exp, Br Mantissa (bit mask)
|
||||
SSRC _ssrc[1];
|
||||
|
||||
[[nodiscard]] static size_t SizeWithSSRCs(int count);
|
||||
|
||||
[[nodiscard]] unsigned int getSize() const;
|
||||
|
||||
void preparePacket(SSRC senderSSRC, unsigned int numSSRC, unsigned int in_bitrate);
|
||||
void setBitrate(unsigned int numSSRC, unsigned int in_bitrate);
|
||||
void setSsrc(int iterator, SSRC newSssrc);
|
||||
unsigned int getNumSSRC();
|
||||
unsigned int getBitrate();
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RtcpPli {
|
||||
RtcpFbHeader header;
|
||||
|
||||
[[nodiscard]] static unsigned int Size();
|
||||
|
||||
void preparePacket(SSRC messageSSRC);
|
||||
|
||||
void log() const;
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RtcpFirPart {
|
||||
uint32_t ssrc;
|
||||
uint8_t seqNo;
|
||||
uint8_t dummy1;
|
||||
uint16_t dummy2;
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RtcpFir {
|
||||
RtcpFbHeader header;
|
||||
RtcpFirPart parts[1];
|
||||
|
||||
static unsigned int Size();
|
||||
|
||||
void preparePacket(SSRC messageSSRC, uint8_t seqNo);
|
||||
|
||||
void log() const;
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RtcpNackPart {
|
||||
uint16_t _pid;
|
||||
uint16_t _blp;
|
||||
|
||||
uint16_t pid();
|
||||
uint16_t blp();
|
||||
|
||||
void setPid(uint16_t pid);
|
||||
void setBlp(uint16_t blp);
|
||||
|
||||
std::vector<uint16_t> getSequenceNumbers();
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RtcpNack {
|
||||
RtcpFbHeader header;
|
||||
RtcpNackPart parts[1];
|
||||
|
||||
[[nodiscard]] static unsigned int Size(unsigned int discreteSeqNoCount);
|
||||
|
||||
[[nodiscard]] unsigned int getSeqNoCount();
|
||||
|
||||
void preparePacket(SSRC ssrc, unsigned int discreteSeqNoCount);
|
||||
|
||||
/**
|
||||
* Add a packet to the list of missing packets.
|
||||
* @param fciCount The number of FCI fields that are present in this packet.
|
||||
* Let the number start at zero and let this function grow the number.
|
||||
* @param fciPID The seq no of the active FCI. It will be initialized automatically, and will
|
||||
* change automatically.
|
||||
* @param missingPacket The seq no of the missing packet. This will be added to the queue.
|
||||
* @return true if the packet has grown, false otherwise.
|
||||
*/
|
||||
bool addMissingPacket(unsigned int *fciCount, uint16_t *fciPID, uint16_t missingPacket);
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RtpRtx {
|
||||
RtpHeader header;
|
||||
|
||||
[[nodiscard]] const char *getBody() const;
|
||||
[[nodiscard]] char *getBody();
|
||||
[[nodiscard]] size_t getBodySize(size_t totalSize) const;
|
||||
[[nodiscard]] size_t getSize() const;
|
||||
[[nodiscard]] uint16_t getOriginalSeqNo() const;
|
||||
|
||||
// Returns the new size of the packet
|
||||
size_t normalizePacket(size_t totalSize, SSRC originalSSRC, uint8_t originalPayloadType);
|
||||
|
||||
size_t copyTo(RtpHeader *dest, size_t totalSize, uint8_t originalPayloadType);
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
79
components/3rd_party/datachannel/include/rtc/rtpdepacketizer.hpp
vendored
Normal file
79
components/3rd_party/datachannel/include/rtc/rtpdepacketizer.hpp
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Copyright (c) 2024 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_RTP_DEPACKETIZER_H
|
||||
#define RTC_RTP_DEPACKETIZER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "mediahandler.hpp"
|
||||
#include "message.hpp"
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// Base RTP depacketizer class
|
||||
class RTC_CPP_EXPORT RtpDepacketizer : public MediaHandler {
|
||||
public:
|
||||
RtpDepacketizer();
|
||||
RtpDepacketizer(uint32_t clockRate);
|
||||
virtual ~RtpDepacketizer();
|
||||
|
||||
virtual void incoming(message_vector &messages, const message_callback &send) override;
|
||||
|
||||
protected:
|
||||
shared_ptr<FrameInfo> createFrameInfo(uint32_t timestamp, uint8_t payloadType) const;
|
||||
|
||||
private:
|
||||
const uint32_t mClockRate;
|
||||
};
|
||||
|
||||
// Base class for video RTP depacketizer
|
||||
class RTC_CPP_EXPORT VideoRtpDepacketizer : public RtpDepacketizer {
|
||||
public:
|
||||
inline static const uint32_t ClockRate = 90000;
|
||||
|
||||
VideoRtpDepacketizer();
|
||||
virtual ~VideoRtpDepacketizer();
|
||||
|
||||
protected:
|
||||
struct sequence_cmp {
|
||||
bool operator()(message_ptr a, message_ptr b) const;
|
||||
};
|
||||
using message_buffer = std::set<message_ptr, sequence_cmp>;
|
||||
|
||||
virtual message_ptr reassemble(message_buffer &messages) = 0;
|
||||
|
||||
private:
|
||||
void incoming(message_vector &messages, const message_callback &send) override;
|
||||
|
||||
message_buffer mBuffer;
|
||||
};
|
||||
|
||||
// Generic audio RTP depacketizer
|
||||
template <uint32_t DEFAULT_CLOCK_RATE>
|
||||
class RTC_CPP_EXPORT AudioRtpDepacketizer final : public RtpDepacketizer {
|
||||
public:
|
||||
inline static const uint32_t DefaultClockRate = DEFAULT_CLOCK_RATE;
|
||||
|
||||
AudioRtpDepacketizer(uint32_t clockRate = DefaultClockRate) : RtpDepacketizer(clockRate) {}
|
||||
};
|
||||
|
||||
// Audio RTP depacketizers
|
||||
using OpusRtpDepacketizer = AudioRtpDepacketizer<48000>;
|
||||
using AACRtpDepacketizer = AudioRtpDepacketizer<48000>;
|
||||
using PCMARtpDepacketizer = AudioRtpDepacketizer<8000>;
|
||||
using PCMURtpDepacketizer = AudioRtpDepacketizer<8000>;
|
||||
using G722RtpDepacketizer = AudioRtpDepacketizer<8000>;
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_RTP_DEPACKETIZER_H */
|
||||
121
components/3rd_party/datachannel/include/rtc/rtppacketizationconfig.hpp
vendored
Normal file
121
components/3rd_party/datachannel/include/rtc/rtppacketizationconfig.hpp
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_RTP_PACKETIZATION_CONFIG_H
|
||||
#define RTC_RTP_PACKETIZATION_CONFIG_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "dependencydescriptor.hpp"
|
||||
#include "rtp.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// RTP configuration used in packetization process
|
||||
class RTC_CPP_EXPORT RtpPacketizationConfig {
|
||||
public:
|
||||
SSRC ssrc;
|
||||
std::string cname;
|
||||
uint8_t payloadType;
|
||||
uint32_t clockRate;
|
||||
uint8_t videoOrientationId;
|
||||
|
||||
// current sequence number
|
||||
uint16_t sequenceNumber;
|
||||
|
||||
// current timestamp
|
||||
uint32_t timestamp;
|
||||
|
||||
// start timestamp
|
||||
uint32_t startTimestamp;
|
||||
|
||||
/// Current video orientation
|
||||
///
|
||||
/// Bit# 7 6 5 4 3 2 1 0
|
||||
/// Definition 0 0 0 0 C F R1 R0
|
||||
///
|
||||
/// C
|
||||
/// 0 - Front-facing camera (use this if unsure)
|
||||
/// 1 - Back-facing camera
|
||||
///
|
||||
/// F
|
||||
/// 0 - No Flip
|
||||
/// 1 - Horizontal flip
|
||||
///
|
||||
/// R1 R0 - CW rotation that receiver must apply
|
||||
/// 0 - 0 degrees
|
||||
/// 1 - 90 degrees
|
||||
/// 2 - 180 degrees
|
||||
/// 3 - 270 degrees
|
||||
uint8_t videoOrientation = 0;
|
||||
|
||||
// MID Extension Header
|
||||
uint8_t midId = 0;
|
||||
optional<std::string> mid;
|
||||
|
||||
// RID Extension Header
|
||||
uint8_t ridId = 0;
|
||||
optional<std::string> rid;
|
||||
|
||||
// Dependency Descriptor Extension Header
|
||||
uint8_t dependencyDescriptorId = 0;
|
||||
|
||||
optional<DependencyDescriptorContext> dependencyDescriptorContext;
|
||||
// the negotiated ID of the playout delay header extension
|
||||
// https://webrtc.googlesource.com/src/+/main/docs/native-code/rtp-hdrext/playout-delay/README.md
|
||||
uint8_t playoutDelayId = 0;
|
||||
|
||||
// Minimum/maxiumum playout delay, in 10ms intervals. A value of 10 would equal a 100ms delay
|
||||
uint16_t playoutDelayMin = 0;
|
||||
uint16_t playoutDelayMax = 0;
|
||||
|
||||
// https://webrtc.googlesource.com/src/+/refs/heads/main/docs/native-code/rtp-hdrext/color-space/
|
||||
uint8_t colorSpaceId = 0; // the negotiated ID of color space header extension
|
||||
uint8_t colorChromaSitingHorz = 0; // unspecified
|
||||
uint8_t colorChromaSitingVert = 0; // unspecified
|
||||
uint8_t colorRange = 2; // full range
|
||||
uint8_t colorPrimaries = 1; // BT.709-6
|
||||
uint8_t colorTransfer = 1; // BT.709-6
|
||||
uint8_t colorMatrix = 1; // BT.709-6
|
||||
|
||||
/// Construct RTP configuration used in packetization process
|
||||
/// @param ssrc SSRC of source
|
||||
/// @param cname CNAME of source
|
||||
/// @param payloadType Payload type of source
|
||||
/// @param clockRate Clock rate of source used in timestamps
|
||||
/// nullopt)
|
||||
/// @param videoOrientationId Video orientation (see above)
|
||||
RtpPacketizationConfig(SSRC ssrc, std::string cname, uint8_t payloadType, uint32_t clockRate,
|
||||
uint8_t videoOrientationId = 0);
|
||||
|
||||
RtpPacketizationConfig(const RtpPacketizationConfig &) = delete;
|
||||
|
||||
/// Convert timestamp to seconds
|
||||
/// @param timestamp Timestamp
|
||||
/// @param clockRate Clock rate for timestamp calculation
|
||||
static double getSecondsFromTimestamp(uint32_t timestamp, uint32_t clockRate);
|
||||
|
||||
/// Convert timestamp to seconds
|
||||
/// @param timestamp Timestamp
|
||||
double timestampToSeconds(uint32_t timestamp);
|
||||
|
||||
/// Convert seconds to timestamp
|
||||
/// @param seconds Number of seconds
|
||||
/// @param clockRate Clock rate for timestamp calculation
|
||||
static uint32_t getTimestampFromSeconds(double seconds, uint32_t clockRate);
|
||||
|
||||
/// Convert seconds to timestamp
|
||||
/// @param seconds Number of seconds
|
||||
uint32_t secondsToTimestamp(double seconds);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_RTP_PACKETIZATION_CONFIG_H */
|
||||
105
components/3rd_party/datachannel/include/rtc/rtppacketizer.hpp
vendored
Normal file
105
components/3rd_party/datachannel/include/rtc/rtppacketizer.hpp
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_RTP_PACKETIZER_H
|
||||
#define RTC_RTP_PACKETIZER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "mediahandler.hpp"
|
||||
#include "message.hpp"
|
||||
#include "rtppacketizationconfig.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
/// RTP packetizer
|
||||
class RTC_CPP_EXPORT RtpPacketizer : public MediaHandler {
|
||||
public:
|
||||
/// Default maximum fragment size (for video packetizers)
|
||||
inline static const size_t DefaultMaxFragmentSize = RTC_DEFAULT_MAX_FRAGMENT_SIZE;
|
||||
|
||||
/// Clock rate for video in RTP
|
||||
inline static const uint32_t VideoClockRate = 90 * 1000;
|
||||
|
||||
/// Constructs packetizer with given RTP configuration
|
||||
/// @note RTP configuration is used in packetization process which may change some configuration
|
||||
/// properties such as sequence number.
|
||||
/// @param rtpConfig RTP configuration
|
||||
RtpPacketizer(shared_ptr<RtpPacketizationConfig> rtpConfig);
|
||||
virtual ~RtpPacketizer();
|
||||
|
||||
virtual void media(const Description::Media &desc) override;
|
||||
virtual void outgoing(message_vector &messages, const message_callback &send) override;
|
||||
|
||||
/// RTP packetization config
|
||||
const shared_ptr<RtpPacketizationConfig> rtpConfig;
|
||||
|
||||
protected:
|
||||
/// Fragment data into payloads
|
||||
/// Default implementation returns data as a single payload
|
||||
/// @param message Input data
|
||||
virtual std::vector<binary> fragment(binary data);
|
||||
|
||||
/// Creates an RTP packet for a payload
|
||||
/// @note This function increases the sequence number.
|
||||
/// @param payload RTP payload
|
||||
/// @param mark Set marker flag in RTP packet if true
|
||||
virtual message_ptr packetize(const binary &payload, bool mark);
|
||||
|
||||
// For backward compatibility, do not use
|
||||
[[deprecated]] virtual message_ptr packetize(shared_ptr<binary> payload, bool mark);
|
||||
|
||||
private:
|
||||
static const auto RtpHeaderSize = 12;
|
||||
static const auto RtpExtHeaderCvoSize = 8;
|
||||
};
|
||||
|
||||
// Generic audio RTP packetizer
|
||||
template <uint32_t DEFAULT_CLOCK_RATE>
|
||||
class RTC_CPP_EXPORT AudioRtpPacketizer final : public RtpPacketizer {
|
||||
public:
|
||||
inline static const uint32_t DefaultClockRate = DEFAULT_CLOCK_RATE;
|
||||
inline static const uint32_t defaultClockRate [[deprecated("Use DefaultClockRate")]] =
|
||||
DEFAULT_CLOCK_RATE; // for backward compatibility
|
||||
|
||||
AudioRtpPacketizer(shared_ptr<RtpPacketizationConfig> rtpConfig)
|
||||
: RtpPacketizer(std::move(rtpConfig)) {}
|
||||
};
|
||||
|
||||
// Audio RTP packetizers
|
||||
using OpusRtpPacketizer = AudioRtpPacketizer<48000>;
|
||||
using AACRtpPacketizer = AudioRtpPacketizer<48000>;
|
||||
using PCMARtpPacketizer = AudioRtpPacketizer<8000>;
|
||||
using PCMURtpPacketizer = AudioRtpPacketizer<8000>;
|
||||
using G722RtpPacketizer = AudioRtpPacketizer<8000>;
|
||||
|
||||
// Dummy wrapper for backward compatibility, do not use
|
||||
class RTC_CPP_EXPORT PacketizationHandler final : public MediaHandler {
|
||||
public:
|
||||
PacketizationHandler(shared_ptr<RtpPacketizer> packetizer)
|
||||
: mPacketizer(std::move(packetizer)) {}
|
||||
|
||||
inline void outgoing(message_vector &messages, const message_callback &send) {
|
||||
return mPacketizer->outgoing(messages, send);
|
||||
}
|
||||
|
||||
private:
|
||||
shared_ptr<RtpPacketizer> mPacketizer;
|
||||
};
|
||||
|
||||
// Audio packetization handlers for backward compatibility, do not use
|
||||
using OpusPacketizationHandler [[deprecated("Add OpusRtpPacketizer directly")]] =
|
||||
PacketizationHandler;
|
||||
using AACPacketizationHandler [[deprecated("Add AACRtpPacketizer directly")]] =
|
||||
PacketizationHandler;
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_RTP_PACKETIZER_H */
|
||||
65
components/3rd_party/datachannel/include/rtc/track.hpp
vendored
Normal file
65
components/3rd_party/datachannel/include/rtc/track.hpp
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_TRACK_H
|
||||
#define RTC_TRACK_H
|
||||
|
||||
#include "channel.hpp"
|
||||
#include "common.hpp"
|
||||
#include "description.hpp"
|
||||
#include "mediahandler.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
namespace impl {
|
||||
|
||||
class Track;
|
||||
|
||||
} // namespace impl
|
||||
|
||||
class RTC_CPP_EXPORT Track final : private CheshireCat<impl::Track>, public Channel {
|
||||
public:
|
||||
Track(impl_ptr<impl::Track> impl);
|
||||
~Track() override;
|
||||
|
||||
string mid() const;
|
||||
Description::Direction direction() const;
|
||||
Description::Media description() const;
|
||||
|
||||
void setDescription(Description::Media description);
|
||||
|
||||
void close(void) override;
|
||||
bool send(message_variant data) override;
|
||||
bool send(const byte *data, size_t size) override;
|
||||
|
||||
bool isOpen(void) const override;
|
||||
bool isClosed(void) const override;
|
||||
size_t maxMessageSize() const override;
|
||||
|
||||
void sendFrame(binary data, FrameInfo info);
|
||||
void sendFrame(const byte *data, size_t size, FrameInfo info);
|
||||
void onFrame(std::function<void(binary data, FrameInfo info)> callback);
|
||||
|
||||
bool requestKeyframe();
|
||||
bool requestBitrate(unsigned int bitrate);
|
||||
|
||||
void setMediaHandler(shared_ptr<MediaHandler> handler);
|
||||
void chainMediaHandler(shared_ptr<MediaHandler> handler);
|
||||
shared_ptr<MediaHandler> getMediaHandler();
|
||||
|
||||
// Deprecated, use setMediaHandler() and getMediaHandler()
|
||||
inline void setRtcpHandler(shared_ptr<MediaHandler> handler) { setMediaHandler(handler); }
|
||||
inline shared_ptr<MediaHandler> getRtcpHandler() { return getMediaHandler(); }
|
||||
|
||||
private:
|
||||
using CheshireCat<impl::Track>::impl;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
159
components/3rd_party/datachannel/include/rtc/utils.hpp
vendored
Normal file
159
components/3rd_party/datachannel/include/rtc/utils.hpp
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* Copyright (c) 2019-2021 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_UTILS_H
|
||||
#define RTC_UTILS_H
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// overloaded helper
|
||||
template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
|
||||
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
|
||||
|
||||
// weak_ptr bind helper
|
||||
template <typename F, typename T, typename... Args> auto weak_bind(F &&f, T *t, Args &&..._args) {
|
||||
return [bound = std::bind(f, t, _args...), weak_this = t->weak_from_this()](auto &&...args) {
|
||||
if (auto shared_this = weak_this.lock())
|
||||
return bound(args...);
|
||||
else
|
||||
return static_cast<decltype(bound(args...))>(false);
|
||||
};
|
||||
}
|
||||
|
||||
// scope_guard helper
|
||||
class scope_guard final {
|
||||
public:
|
||||
scope_guard(std::function<void()> func) : function(std::move(func)) {}
|
||||
scope_guard(scope_guard &&other) = delete;
|
||||
scope_guard(const scope_guard &) = delete;
|
||||
void operator=(const scope_guard &) = delete;
|
||||
|
||||
~scope_guard() {
|
||||
if (function)
|
||||
function();
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void()> function;
|
||||
};
|
||||
|
||||
// callback with built-in synchronization
|
||||
template <typename... Args> class synchronized_callback {
|
||||
public:
|
||||
synchronized_callback() = default;
|
||||
synchronized_callback(synchronized_callback &&cb) { *this = std::move(cb); }
|
||||
synchronized_callback(const synchronized_callback &cb) { *this = cb; }
|
||||
synchronized_callback(std::function<void(Args...)> func) { *this = std::move(func); }
|
||||
virtual ~synchronized_callback() { *this = nullptr; }
|
||||
|
||||
synchronized_callback &operator=(synchronized_callback &&cb) {
|
||||
std::scoped_lock lock(mutex, cb.mutex);
|
||||
set(std::exchange(cb.callback, nullptr));
|
||||
return *this;
|
||||
}
|
||||
|
||||
synchronized_callback &operator=(const synchronized_callback &cb) {
|
||||
std::scoped_lock lock(mutex, cb.mutex);
|
||||
set(cb.callback);
|
||||
return *this;
|
||||
}
|
||||
|
||||
synchronized_callback &operator=(std::function<void(Args...)> func) {
|
||||
std::lock_guard lock(mutex);
|
||||
set(std::move(func));
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator()(Args... args) const {
|
||||
std::lock_guard lock(mutex);
|
||||
return call(std::move(args)...);
|
||||
}
|
||||
|
||||
operator bool() const {
|
||||
std::lock_guard lock(mutex);
|
||||
return callback ? true : false;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void set(std::function<void(Args...)> func) { callback = std::move(func); }
|
||||
virtual bool call(Args... args) const {
|
||||
if (!callback)
|
||||
return false;
|
||||
|
||||
callback(std::move(args)...);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::function<void(Args...)> callback;
|
||||
mutable std::recursive_mutex mutex;
|
||||
};
|
||||
|
||||
// callback with built-in synchronization and replay of the last missed call
|
||||
template <typename... Args>
|
||||
class synchronized_stored_callback final : public synchronized_callback<Args...> {
|
||||
public:
|
||||
template <typename... CArgs>
|
||||
synchronized_stored_callback(CArgs &&...cargs)
|
||||
: synchronized_callback<Args...>(std::forward<CArgs>(cargs)...) {}
|
||||
~synchronized_stored_callback() {}
|
||||
|
||||
private:
|
||||
void set(std::function<void(Args...)> func) {
|
||||
synchronized_callback<Args...>::set(func);
|
||||
if (func && stored) {
|
||||
std::apply(func, std::move(*stored));
|
||||
stored.reset();
|
||||
}
|
||||
}
|
||||
|
||||
bool call(Args... args) const {
|
||||
if (!synchronized_callback<Args...>::call(args...))
|
||||
stored.emplace(std::move(args)...);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
mutable std::optional<std::tuple<Args...>> stored;
|
||||
};
|
||||
|
||||
// pimpl base class
|
||||
template <typename T> using impl_ptr = std::shared_ptr<T>;
|
||||
template <typename T> class CheshireCat {
|
||||
public:
|
||||
CheshireCat(impl_ptr<T> impl) : mImpl(std::move(impl)) {}
|
||||
template <typename... Args>
|
||||
CheshireCat(Args... args) : mImpl(std::make_shared<T>(std::forward<Args>(args)...)) {}
|
||||
CheshireCat(CheshireCat<T> &&cc) { *this = std::move(cc); }
|
||||
CheshireCat(const CheshireCat<T> &) = delete;
|
||||
|
||||
virtual ~CheshireCat() = default;
|
||||
|
||||
CheshireCat &operator=(CheshireCat<T> &&cc) {
|
||||
mImpl = std::move(cc.mImpl);
|
||||
return *this;
|
||||
};
|
||||
CheshireCat &operator=(const CheshireCat<T> &) = delete;
|
||||
|
||||
protected:
|
||||
impl_ptr<T> impl() { return mImpl; }
|
||||
impl_ptr<const T> impl() const { return mImpl; }
|
||||
|
||||
private:
|
||||
impl_ptr<T> mImpl;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
9
components/3rd_party/datachannel/include/rtc/version.h
vendored
Normal file
9
components/3rd_party/datachannel/include/rtc/version.h
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef RTC_VERSION_H
|
||||
#define RTC_VERSION_H
|
||||
|
||||
#define RTC_VERSION_MAJOR 0
|
||||
#define RTC_VERSION_MINOR 24
|
||||
#define RTC_VERSION_PATCH 0
|
||||
#define RTC_VERSION "0.24.0"
|
||||
|
||||
#endif
|
||||
67
components/3rd_party/datachannel/include/rtc/websocket.hpp
vendored
Normal file
67
components/3rd_party/datachannel/include/rtc/websocket.hpp
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2021 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_WEBSOCKET_H
|
||||
#define RTC_WEBSOCKET_H
|
||||
|
||||
#if RTC_ENABLE_WEBSOCKET
|
||||
|
||||
#include "channel.hpp"
|
||||
#include "common.hpp"
|
||||
#include "configuration.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
namespace impl {
|
||||
|
||||
struct WebSocket;
|
||||
|
||||
}
|
||||
|
||||
class RTC_CPP_EXPORT WebSocket final : private CheshireCat<impl::WebSocket>, public Channel {
|
||||
public:
|
||||
enum class State : int {
|
||||
Connecting = 0,
|
||||
Open = 1,
|
||||
Closing = 2,
|
||||
Closed = 3,
|
||||
};
|
||||
|
||||
using Configuration = WebSocketConfiguration;
|
||||
|
||||
WebSocket();
|
||||
WebSocket(Configuration config);
|
||||
WebSocket(impl_ptr<impl::WebSocket> impl);
|
||||
~WebSocket() override;
|
||||
|
||||
State readyState() const;
|
||||
|
||||
bool isOpen() const override;
|
||||
bool isClosed() const override;
|
||||
size_t maxMessageSize() const override;
|
||||
|
||||
void open(const string &url);
|
||||
void close() override;
|
||||
void forceClose();
|
||||
bool send(const message_variant data) override;
|
||||
bool send(const byte *data, size_t size) override;
|
||||
|
||||
optional<string> remoteAddress() const;
|
||||
optional<string> path() const;
|
||||
|
||||
private:
|
||||
using CheshireCat<impl::WebSocket>::impl;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, WebSocket::State state);
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
|
||||
#endif // RTC_WEBSOCKET_H
|
||||
48
components/3rd_party/datachannel/include/rtc/websocketserver.hpp
vendored
Normal file
48
components/3rd_party/datachannel/include/rtc/websocketserver.hpp
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Paul-Louis Ageneau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RTC_WEBSOCKETSERVER_H
|
||||
#define RTC_WEBSOCKETSERVER_H
|
||||
|
||||
#if RTC_ENABLE_WEBSOCKET
|
||||
|
||||
#include "common.hpp"
|
||||
#include "configuration.hpp"
|
||||
#include "websocket.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
namespace impl {
|
||||
|
||||
struct WebSocketServer;
|
||||
|
||||
}
|
||||
|
||||
class RTC_CPP_EXPORT WebSocketServer final : private CheshireCat<impl::WebSocketServer> {
|
||||
public:
|
||||
using Configuration = WebSocketServerConfiguration;
|
||||
|
||||
WebSocketServer();
|
||||
WebSocketServer(Configuration config);
|
||||
~WebSocketServer();
|
||||
|
||||
void stop();
|
||||
|
||||
uint16_t port() const;
|
||||
|
||||
void onClient(std::function<void(shared_ptr<WebSocket>)> callback);
|
||||
|
||||
private:
|
||||
using CheshireCat<impl::WebSocketServer>::impl;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
|
||||
#endif // RTC_WEBSOCKET_H
|
||||
BIN
components/3rd_party/datachannel/lib/maixcam/libdatachannel.so
vendored
Executable file
BIN
components/3rd_party/datachannel/lib/maixcam/libdatachannel.so
vendored
Executable file
Binary file not shown.
BIN
components/3rd_party/datachannel/lib/maixcam2/libdatachannel.so
vendored
Executable file
BIN
components/3rd_party/datachannel/lib/maixcam2/libdatachannel.so
vendored
Executable file
Binary file not shown.
@@ -41,6 +41,14 @@ typedef struct {
|
||||
int count;
|
||||
} mmf_h265_stream_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MMF_VENC_RCMODE_CBR = 0,
|
||||
MMF_VENC_RCMODE_VBR,
|
||||
MMF_VENC_RCMODE_FIXQP,
|
||||
MMF_VENC_RCMODE_MAX,
|
||||
} mmf_venc_rc_mode_e;
|
||||
|
||||
typedef struct {
|
||||
uint8_t type; // 0, jpg; 1, h265; 2, h264
|
||||
int w;
|
||||
@@ -51,6 +59,7 @@ typedef struct {
|
||||
int intput_fps; // h264/h265
|
||||
int output_fps; // h264/h265
|
||||
int bitrate; // h264/h265
|
||||
mmf_venc_rc_mode_e rc_mode; // h264/h265
|
||||
} mmf_venc_cfg_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -59,6 +59,14 @@ namespace maix::middleware::maixcam2 {
|
||||
AX_VENC_TYPE_MJPG,
|
||||
} ax_venc_type_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AX_VENC_RCMODE_CBR = 0,
|
||||
AX_VENC_RCMODE_VBR,
|
||||
AX_VENC_RCMODE_FIXQP,
|
||||
AX_VENC_RCMODE_MAX,
|
||||
} ax_venc_rc_mode_e;
|
||||
|
||||
typedef enum {
|
||||
AX_VDEC_TYPE_JPG = 0,
|
||||
AX_VDEC_TYPE_H264,
|
||||
@@ -89,6 +97,7 @@ namespace maix::middleware::maixcam2 {
|
||||
typedef struct {
|
||||
bool en;
|
||||
ax_venc_type_e type;
|
||||
ax_venc_rc_mode_e rc_mode;
|
||||
int w;
|
||||
int h;
|
||||
AX_IMG_FORMAT_E fmt;
|
||||
|
||||
@@ -31,16 +31,15 @@ namespace maix::video
|
||||
VIDEO_ENC_MP4_CBR, // Deprecated
|
||||
VIDEO_DEC_H265_CBR, // Deprecated
|
||||
VIDEO_DEC_MP4_CBR, // Deprecated
|
||||
VIDEO_H264_CBR, // Deprecated
|
||||
VIDEO_H265_CBR, // Deprecated
|
||||
VIDEO_H264_CBR_MP4, // Deprecated
|
||||
VIDEO_H265_CBR_MP4, // Deprecated
|
||||
|
||||
VIDEO_H264,
|
||||
VIDEO_H264_MP4,
|
||||
VIDEO_H264_FLV,
|
||||
VIDEO_H264_CBR,
|
||||
VIDEO_H264_VBR,
|
||||
VIDEO_H265,
|
||||
VIDEO_H265_MP4,
|
||||
VIDEO_H265_CBR,
|
||||
VIDEO_H265_VBR,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,17 @@ namespace maix::webrtc
|
||||
WEBRTC_STREAM_H265,
|
||||
};
|
||||
|
||||
/**
|
||||
* The rc type of webrtc
|
||||
* @maixpy maix.webrtc.WebRTCRCType
|
||||
*/
|
||||
enum class WebRTCRCType
|
||||
{
|
||||
WEBRTC_RC_NONE = 0, // format invalid
|
||||
WEBRTC_RC_CBR,
|
||||
WEBRTC_RC_VBR,
|
||||
};
|
||||
|
||||
/**
|
||||
* Region class
|
||||
* @maixpy maix.webrtc.Region
|
||||
@@ -86,18 +97,20 @@ namespace maix::webrtc
|
||||
* @brief Construct a new WebRTC object
|
||||
* @param ip listen ip
|
||||
* @param port listen port
|
||||
* @param fps video fps
|
||||
* @param stream_type stream type
|
||||
* @param rc_type rc type
|
||||
* @param bitrate video bitrate
|
||||
* @param gop video gop
|
||||
* @param signaling_ip signaling server bind ip
|
||||
* @param signaling_port signaling server bind port
|
||||
* @param http_server whether to enable the HTTP server
|
||||
* @param stun_server STUN server address
|
||||
* @param http_server whether to enable the HTTP server
|
||||
* @maixpy maix.webrtc.WebRTC.__init__
|
||||
* @maixcdk maix.webrtc.WebRTC.WebRTC
|
||||
*/
|
||||
WebRTC(std::string ip = std::string(), int port = 8000, int fps = 60,
|
||||
WebRTC(std::string ip = std::string(), int port = 8000,
|
||||
webrtc::WebRTCStreamType stream_type = webrtc::WebRTCStreamType::WEBRTC_STREAM_H264,
|
||||
webrtc::WebRTCRCType rc_type = webrtc::WebRTCRCType::WEBRTC_RC_CBR,
|
||||
int bitrate = 3000 * 1000, int gop = 60, std::string signaling_ip = std::string(),
|
||||
int signaling_port = 8001, const std::string &stun_server = "stun:stun.l.google.com:19302",
|
||||
bool http_server = true);
|
||||
@@ -250,9 +263,9 @@ namespace maix::webrtc
|
||||
int _port;
|
||||
std::string _signaling_ip;
|
||||
int _signaling_port;
|
||||
int _fps;
|
||||
int _gop;
|
||||
webrtc::WebRTCStreamType _stream_type;
|
||||
webrtc::WebRTCRCType _rc_type;
|
||||
bool _is_start;
|
||||
thread::Thread *_video_thread;
|
||||
std::string _stun_server;
|
||||
|
||||
@@ -34,17 +34,15 @@ namespace maix::webrtc
|
||||
return err::ERR_NOT_IMPL;
|
||||
}
|
||||
|
||||
WebRTC::WebRTC(std::string ip, int port, int fps,
|
||||
webrtc::WebRTCStreamType stream_type, int bitrate, int gop,
|
||||
std::string signaling_ip, int signaling_port,
|
||||
const std::string &stun_server,
|
||||
bool http_server)
|
||||
WebRTC::WebRTC(std::string ip, int port, webrtc::WebRTCStreamType stream_type,
|
||||
webrtc::WebRTCRCType rc_type, int bitrate, int gop, std::string signaling_ip,
|
||||
int signaling_port, const std::string &stun_server, bool http_server)
|
||||
{
|
||||
(void)ip;
|
||||
(void)port;
|
||||
(void)fps;
|
||||
(void)gop;
|
||||
(void)stream_type;
|
||||
(void)rc_type;
|
||||
(void)bitrate;
|
||||
(void)signaling_ip;
|
||||
(void)signaling_port;
|
||||
|
||||
@@ -56,19 +56,46 @@ namespace maix::video
|
||||
}
|
||||
|
||||
if (!strcmp(suffix, ".h264")) {
|
||||
video_type = video::VIDEO_H264;
|
||||
switch (type) {
|
||||
case video::VIDEO_H264: // fall through
|
||||
case video::VIDEO_H264_CBR:
|
||||
video_type = video::VIDEO_H264_CBR;
|
||||
break;
|
||||
case video::VIDEO_H264_VBR:
|
||||
video_type = video::VIDEO_H264_VBR;
|
||||
break;
|
||||
default:
|
||||
err::check_raise(err::ERR_RUNTIME, "Unsupported video type!");
|
||||
break;
|
||||
}
|
||||
} else if (!strcmp(suffix, ".h265")) {
|
||||
video_type = video::VIDEO_H264;
|
||||
switch (type) {
|
||||
case video::VIDEO_H265: // fall through
|
||||
case video::VIDEO_H265_CBR:
|
||||
video_type = video::VIDEO_H265_CBR;
|
||||
break;
|
||||
case video::VIDEO_H265_VBR:
|
||||
video_type = video::VIDEO_H265_VBR;
|
||||
break;
|
||||
default:
|
||||
err::check_raise(err::ERR_RUNTIME, "Unsupported video type!");
|
||||
break;
|
||||
}
|
||||
} else if (!strcmp(suffix, ".mp4")) {
|
||||
switch (type) {
|
||||
case video::VIDEO_H264: // fall through
|
||||
case video::VIDEO_H264_MP4: // fall through
|
||||
case video::VIDEO_H264_FLV:
|
||||
video_type = video::VIDEO_H264_MP4;
|
||||
case video::VIDEO_H264_CBR:
|
||||
video_type = video::VIDEO_H264_CBR;
|
||||
break;
|
||||
case video::VIDEO_H264_VBR:
|
||||
video_type = video::VIDEO_H264_VBR;
|
||||
break;
|
||||
case video::VIDEO_H265: // fall through
|
||||
case video::VIDEO_H265_MP4:
|
||||
video_type = video::VIDEO_H265_MP4;
|
||||
case video::VIDEO_H265_CBR:
|
||||
video_type = video::VIDEO_H265_CBR;
|
||||
break;
|
||||
case video::VIDEO_H265_VBR:
|
||||
video_type = video::VIDEO_H265_VBR;
|
||||
break;
|
||||
default:
|
||||
err::check_raise(err::ERR_RUNTIME, "Unsupported video type!");
|
||||
@@ -77,8 +104,11 @@ namespace maix::video
|
||||
} else if (!strcmp(suffix, ".flv")) {
|
||||
switch (type) {
|
||||
case video::VIDEO_H264: // fall through
|
||||
case video::VIDEO_H264_FLV:
|
||||
video_type = video::VIDEO_H264_FLV;
|
||||
case video::VIDEO_H264_CBR:
|
||||
video_type = video::VIDEO_H264_CBR;
|
||||
break;
|
||||
case video::VIDEO_H264_VBR:
|
||||
video_type = video::VIDEO_H264_VBR;
|
||||
break;
|
||||
default:
|
||||
err::check_raise(err::ERR_RUNTIME, "Unsupported video type!");
|
||||
@@ -94,12 +124,13 @@ namespace maix::video
|
||||
PAYLOAD_TYPE_E payload_type = PT_H264;
|
||||
switch (video_type) {
|
||||
case VIDEO_H264:
|
||||
case VIDEO_H264_MP4:
|
||||
case VIDEO_H264_FLV:
|
||||
case VIDEO_H264_CBR:
|
||||
case VIDEO_H264_VBR:
|
||||
payload_type = PT_H264;
|
||||
break;
|
||||
case VIDEO_H265:
|
||||
case VIDEO_H265_MP4:
|
||||
case VIDEO_H265_CBR:
|
||||
case VIDEO_H265_VBR:
|
||||
payload_type = PT_H265;
|
||||
break;
|
||||
default:
|
||||
@@ -112,12 +143,13 @@ namespace maix::video
|
||||
enum AVCodecID codec_id = AV_CODEC_ID_NONE;
|
||||
switch (video_type) {
|
||||
case VIDEO_H264:
|
||||
case VIDEO_H264_MP4:
|
||||
case VIDEO_H264_FLV:
|
||||
case VIDEO_H264_CBR:
|
||||
case VIDEO_H264_VBR:
|
||||
codec_id = AV_CODEC_ID_H264;
|
||||
break;
|
||||
case VIDEO_H265:
|
||||
case VIDEO_H265_MP4:
|
||||
case VIDEO_H265_CBR:
|
||||
case VIDEO_H265_VBR:
|
||||
codec_id = AV_CODEC_ID_HEVC;
|
||||
break;
|
||||
default:
|
||||
@@ -247,6 +279,8 @@ namespace maix::video
|
||||
if (_path.size() == 0) {
|
||||
switch (_type) {
|
||||
case VIDEO_H264:
|
||||
case VIDEO_H264_CBR:
|
||||
case VIDEO_H264_VBR:
|
||||
{
|
||||
mmf_venc_cfg_t cfg = {
|
||||
.type = 2, //1, h265, 2, h264
|
||||
@@ -258,8 +292,20 @@ namespace maix::video
|
||||
.intput_fps = _framerate,
|
||||
.output_fps = _framerate,
|
||||
.bitrate = _bitrate / 1000,
|
||||
.rc_mode = MMF_VENC_RCMODE_CBR,
|
||||
};
|
||||
|
||||
switch (_type) {
|
||||
case VIDEO_H264_CBR:
|
||||
cfg.rc_mode = MMF_VENC_RCMODE_CBR;
|
||||
break;
|
||||
case VIDEO_H264_VBR:
|
||||
cfg.rc_mode = MMF_VENC_RCMODE_VBR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 != mmf_init_v2(true)) {
|
||||
err::check_raise(err::ERR_RUNTIME, "init mmf failed!");
|
||||
}
|
||||
@@ -271,6 +317,8 @@ namespace maix::video
|
||||
break;
|
||||
}
|
||||
case VIDEO_H265:
|
||||
case VIDEO_H265_CBR:
|
||||
case VIDEO_H265_VBR:
|
||||
{
|
||||
mmf_venc_cfg_t cfg = {
|
||||
.type = 1, //1, h265, 2, h264
|
||||
@@ -282,8 +330,20 @@ namespace maix::video
|
||||
.intput_fps = _framerate,
|
||||
.output_fps = _framerate,
|
||||
.bitrate = _bitrate / 1000,
|
||||
.rc_mode = MMF_VENC_RCMODE_CBR,
|
||||
};
|
||||
|
||||
switch (_type) {
|
||||
case VIDEO_H265_CBR:
|
||||
cfg.rc_mode = MMF_VENC_RCMODE_CBR;
|
||||
break;
|
||||
case VIDEO_H265_VBR:
|
||||
cfg.rc_mode = MMF_VENC_RCMODE_VBR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 != mmf_init_v2(true)) {
|
||||
err::check_raise(err::ERR_RUNTIME, "init mmf failed!");
|
||||
}
|
||||
@@ -344,13 +404,32 @@ namespace maix::video
|
||||
.intput_fps = _framerate,
|
||||
.output_fps = _framerate,
|
||||
.bitrate = _bitrate / 1000,
|
||||
.rc_mode = MMF_VENC_RCMODE_CBR,
|
||||
};
|
||||
|
||||
if (venc_type == PT_H265) {
|
||||
cfg.type = 1;
|
||||
} else if (venc_type == PT_H264) {
|
||||
cfg.type = 2;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case VIDEO_H264_CBR:
|
||||
cfg.rc_mode = MMF_VENC_RCMODE_CBR;
|
||||
break;
|
||||
case VIDEO_H264_VBR:
|
||||
cfg.rc_mode = MMF_VENC_RCMODE_VBR;
|
||||
break;
|
||||
case VIDEO_H265_CBR:
|
||||
cfg.rc_mode = MMF_VENC_RCMODE_CBR;
|
||||
break;
|
||||
case VIDEO_H265_VBR:
|
||||
cfg.rc_mode = MMF_VENC_RCMODE_VBR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 != mmf_init_v2(true)) {
|
||||
err::check_raise(err::ERR_RUNTIME, "init mmf failed!");
|
||||
}
|
||||
@@ -368,6 +447,7 @@ namespace maix::video
|
||||
SwrContext *swr_ctx = NULL;
|
||||
AVPacket *audio_packet = NULL;
|
||||
|
||||
if (_path.size() == 0) {
|
||||
audio_packet = av_packet_alloc();
|
||||
err::check_null_raise(audio_packet, "av_packet_alloc");
|
||||
audio_packet->data = NULL;
|
||||
@@ -408,6 +488,7 @@ namespace maix::video
|
||||
audio_frame->format = AV_SAMPLE_FMT_FLTP;
|
||||
audio_frame->sample_rate = audio_codec_ctx->sample_rate;
|
||||
av_frame_get_buffer(audio_frame, 0);
|
||||
}
|
||||
|
||||
err::check_bool_raise(avformat_write_header(outputFormatContext, NULL) >= 0, "avformat_write_header failed!");
|
||||
|
||||
@@ -425,21 +506,24 @@ namespace maix::video
|
||||
param->frame_index = 0;
|
||||
param->last_encode_ms = time::ticks_ms();
|
||||
param->video_packet_list = new std::list<AVPacket *>;
|
||||
|
||||
bool is_raw_h264 = _path.find(".h264") != std::string::npos;
|
||||
bool is_raw_h265 = _path.find(".h265") != std::string::npos;
|
||||
|
||||
switch (video_type) {
|
||||
case VIDEO_H264:
|
||||
param->copy_sps_pps_per_iframe = true;
|
||||
break;
|
||||
case VIDEO_H264_MP4:
|
||||
param->copy_sps_pps_per_iframe = false;
|
||||
break;
|
||||
case VIDEO_H264_FLV:
|
||||
param->copy_sps_pps_per_iframe = false;
|
||||
case VIDEO_H264_CBR:
|
||||
case VIDEO_H264_VBR:
|
||||
param->copy_sps_pps_per_iframe = is_raw_h264 ? true : false;
|
||||
break;
|
||||
case VIDEO_H265:
|
||||
param->copy_sps_pps_per_iframe = true;
|
||||
break;
|
||||
case VIDEO_H265_MP4:
|
||||
param->copy_sps_pps_per_iframe = false;
|
||||
case VIDEO_H265_CBR:
|
||||
case VIDEO_H265_VBR:
|
||||
param->copy_sps_pps_per_iframe = is_raw_h265 ? true : false;
|
||||
break;
|
||||
default:
|
||||
err::check_raise(err::ERR_RUNTIME, "Unsupported video type!");
|
||||
@@ -465,12 +549,16 @@ namespace maix::video
|
||||
if (_path.size() == 0) {
|
||||
switch (_type) {
|
||||
case VIDEO_H264:
|
||||
case VIDEO_H264_CBR:
|
||||
case VIDEO_H264_VBR:
|
||||
{
|
||||
mmf_del_venc_channel(MMF_VENC_CHN);
|
||||
mmf_deinit_v2(false);
|
||||
break;
|
||||
}
|
||||
case VIDEO_H265:
|
||||
case VIDEO_H265_CBR:
|
||||
case VIDEO_H265_VBR:
|
||||
{
|
||||
mmf_del_venc_channel(MMF_VENC_CHN);
|
||||
mmf_deinit_v2(false);
|
||||
@@ -550,6 +638,8 @@ namespace maix::video
|
||||
|
||||
switch (_type) {
|
||||
case VIDEO_H264:
|
||||
case VIDEO_H264_CBR:
|
||||
case VIDEO_H264_VBR:
|
||||
{
|
||||
if (img && img->data() != NULL) { // encode from image
|
||||
if (img->data_size() > 2560 * 1440 * 3 / 2) {
|
||||
@@ -768,6 +858,8 @@ namespace maix::video
|
||||
break;
|
||||
}
|
||||
case VIDEO_H265:
|
||||
case VIDEO_H265_CBR:
|
||||
case VIDEO_H265_VBR:
|
||||
{
|
||||
if (img && img->data() != NULL) { // encode from image
|
||||
if (img->data_size() > 2560 * 1440 * 3 / 2) {
|
||||
@@ -967,6 +1059,8 @@ namespace maix::video
|
||||
|
||||
switch (_type) {
|
||||
case VIDEO_H264:
|
||||
case VIDEO_H264_CBR:
|
||||
case VIDEO_H264_VBR:
|
||||
{
|
||||
if (_block) {
|
||||
if (use_input_img) {
|
||||
@@ -4031,21 +4125,24 @@ _exit:
|
||||
packager->find_sps_pps = false;
|
||||
packager->frame_index = 0;
|
||||
packager->last_encode_ms = time::ticks_ms();
|
||||
|
||||
bool is_raw_h264 = path.find(".h264") != std::string::npos;
|
||||
bool is_raw_h265 = path.find(".h265") != std::string::npos;
|
||||
|
||||
switch (video_type) {
|
||||
case VIDEO_H264:
|
||||
packager->copy_sps_pps_per_iframe = true;
|
||||
break;
|
||||
case VIDEO_H264_MP4:
|
||||
packager->copy_sps_pps_per_iframe = false;
|
||||
break;
|
||||
case VIDEO_H264_FLV:
|
||||
packager->copy_sps_pps_per_iframe = false;
|
||||
case VIDEO_H264_CBR:
|
||||
case VIDEO_H264_VBR:
|
||||
packager->copy_sps_pps_per_iframe = is_raw_h264 ? true : false;
|
||||
break;
|
||||
case VIDEO_H265:
|
||||
packager->copy_sps_pps_per_iframe = true;
|
||||
break;
|
||||
case VIDEO_H265_MP4:
|
||||
packager->copy_sps_pps_per_iframe = false;
|
||||
case VIDEO_H265_CBR:
|
||||
case VIDEO_H265_VBR:
|
||||
packager->copy_sps_pps_per_iframe = is_raw_h265 ? true : false;
|
||||
break;
|
||||
default:
|
||||
err::check_raise(err::ERR_RUNTIME, "Unsupported video type!");
|
||||
|
||||
@@ -165,7 +165,6 @@ namespace maix::webrtc
|
||||
bool bind_audio_recorder;
|
||||
|
||||
int encoder_bitrate;
|
||||
int fps;
|
||||
int gop;
|
||||
|
||||
MaixWebRTCServer *webrtc_server;
|
||||
@@ -257,20 +256,37 @@ namespace maix::webrtc
|
||||
param->status = WEBRTC_IDLE;
|
||||
}
|
||||
|
||||
WebRTC::WebRTC(std::string ip, int port, int fps,
|
||||
webrtc::WebRTCStreamType stream_type, int bitrate, int gop,
|
||||
std::string signaling_ip, int signaling_port,
|
||||
const std::string &stun_server,
|
||||
bool http_server)
|
||||
static video::VideoType get_video_type( maix::webrtc::WebRTCStreamType stream, maix::webrtc::WebRTCRCType rc)
|
||||
{
|
||||
using stream_type = maix::webrtc::WebRTCStreamType;
|
||||
using rc_type = maix::webrtc::WebRTCRCType;
|
||||
|
||||
if (stream == stream_type::WEBRTC_STREAM_H264) {
|
||||
if (rc == rc_type::WEBRTC_RC_CBR) { return video::VIDEO_H264_CBR; }
|
||||
if (rc == rc_type::WEBRTC_RC_VBR) { return video::VIDEO_H264_VBR; }
|
||||
}
|
||||
|
||||
if (stream == stream_type::WEBRTC_STREAM_H265) {
|
||||
if (rc == rc_type::WEBRTC_RC_CBR) { return video::VIDEO_H265_CBR; }
|
||||
if (rc == rc_type::WEBRTC_RC_VBR) { return video::VIDEO_H265_VBR; }
|
||||
}
|
||||
|
||||
log::error("Unsupported video type stream=%d rc=%d", (int)stream, (int)rc);
|
||||
return video::VIDEO_H264_CBR;
|
||||
}
|
||||
|
||||
WebRTC::WebRTC(std::string ip, int port, webrtc::WebRTCStreamType stream_type,
|
||||
webrtc::WebRTCRCType rc_type, int bitrate, int gop, std::string signaling_ip,
|
||||
int signaling_port, const std::string &stun_server, bool http_server)
|
||||
{
|
||||
this->_ip = ip.size() ? ip : "0.0.0.0";
|
||||
this->_port = port;
|
||||
this->_signaling_ip = signaling_ip;
|
||||
this->_signaling_port = signaling_port;
|
||||
this->_stun_server = stun_server;
|
||||
this->_fps = fps;
|
||||
this->_gop = gop;
|
||||
this->_stream_type = stream_type;
|
||||
this->_rc_type = rc_type;
|
||||
this->_is_start = false;
|
||||
this->_video_thread = nullptr;
|
||||
this->_http_server = http_server;
|
||||
@@ -292,7 +308,6 @@ namespace maix::webrtc
|
||||
param->bind_camera = false;
|
||||
param->bind_audio_recorder = false;
|
||||
param->encoder_bitrate = bitrate;
|
||||
param->fps = fps;
|
||||
param->gop = gop;
|
||||
|
||||
param->webrtc_server = nullptr;
|
||||
@@ -353,17 +368,9 @@ namespace maix::webrtc
|
||||
param->encoder = nullptr;
|
||||
}
|
||||
|
||||
video::VideoType video_type;
|
||||
if (this->_stream_type == maix::webrtc::WebRTCStreamType::WEBRTC_STREAM_H264) {
|
||||
video_type = video::VIDEO_H264;
|
||||
} else if (this->_stream_type == maix::webrtc::WebRTCStreamType::WEBRTC_STREAM_H265) {
|
||||
video_type = video::VIDEO_H265;
|
||||
} else {
|
||||
log::error("Unsupported stream type: %d", this->_stream_type);
|
||||
return err::ERR_ARGS;
|
||||
}
|
||||
video::VideoType video_type = get_video_type(this->_stream_type, this->_rc_type);
|
||||
|
||||
param->encoder = new video::Encoder("", param->camera->width(), param->camera->height(), image::Format::FMT_YVU420SP, video_type, param->fps, param->gop, param->encoder_bitrate);
|
||||
param->encoder = new video::Encoder("", param->camera->width(), param->camera->height(), image::Format::FMT_YVU420SP, video_type, param->camera->fps(), param->gop, param->encoder_bitrate);
|
||||
err::check_null_raise(param->encoder, "Create video encoder failed!");
|
||||
|
||||
if (param->bind_audio_recorder) {
|
||||
@@ -376,7 +383,7 @@ namespace maix::webrtc
|
||||
}
|
||||
|
||||
MaixWebRTCServerBuilder builder;
|
||||
builder.set_ice_server("stun:stun.l.google.com:19302");
|
||||
builder.set_ice_server(this->_stun_server);
|
||||
|
||||
if (this->_stream_type == maix::webrtc::WebRTCStreamType::WEBRTC_STREAM_H265) {
|
||||
builder.set_video_codec(VideoCodec::H265);
|
||||
@@ -541,6 +548,9 @@ namespace maix::webrtc
|
||||
if (!get_ip((char *)"wlan0", new_ip)) {
|
||||
ip_list.push_back("http://" + std::string(new_ip) + ":" + std::to_string(port));
|
||||
}
|
||||
if (!get_ip((char *)"tailscale0", new_ip)) {
|
||||
ip_list.push_back("http://" + std::string(new_ip) + ":" + std::to_string(port));
|
||||
}
|
||||
} else {
|
||||
ip_list.push_back("http://" + ip + ":" + std::to_string(port));
|
||||
}
|
||||
|
||||
@@ -81,19 +81,46 @@ namespace maix::video
|
||||
}
|
||||
|
||||
if (!strcmp(suffix, ".h264")) {
|
||||
video_type = video::VIDEO_H264;
|
||||
switch (type) {
|
||||
case video::VIDEO_H264: // fall through
|
||||
case video::VIDEO_H264_CBR:
|
||||
video_type = video::VIDEO_H264_CBR;
|
||||
break;
|
||||
case video::VIDEO_H264_VBR:
|
||||
video_type = video::VIDEO_H264_VBR;
|
||||
break;
|
||||
default:
|
||||
err::check_raise(err::ERR_RUNTIME, "Unsupported video type!");
|
||||
break;
|
||||
}
|
||||
} else if (!strcmp(suffix, ".h265")) {
|
||||
video_type = video::VIDEO_H265;
|
||||
switch (type) {
|
||||
case video::VIDEO_H265: // fall through
|
||||
case video::VIDEO_H265_CBR:
|
||||
video_type = video::VIDEO_H265_CBR;
|
||||
break;
|
||||
case video::VIDEO_H265_VBR:
|
||||
video_type = video::VIDEO_H265_VBR;
|
||||
break;
|
||||
default:
|
||||
err::check_raise(err::ERR_RUNTIME, "Unsupported video type!");
|
||||
break;
|
||||
}
|
||||
} else if (!strcmp(suffix, ".mp4")) {
|
||||
switch (type) {
|
||||
case video::VIDEO_H264: // fall through
|
||||
case video::VIDEO_H264_MP4: // fall through
|
||||
case video::VIDEO_H264_FLV:
|
||||
video_type = video::VIDEO_H264_MP4;
|
||||
case video::VIDEO_H264_CBR:
|
||||
video_type = video::VIDEO_H264_CBR;
|
||||
break;
|
||||
case video::VIDEO_H264_VBR:
|
||||
video_type = video::VIDEO_H264_VBR;
|
||||
break;
|
||||
case video::VIDEO_H265: // fall through
|
||||
case video::VIDEO_H265_MP4:
|
||||
video_type = video::VIDEO_H265_MP4;
|
||||
case video::VIDEO_H265_CBR:
|
||||
video_type = video::VIDEO_H265_CBR;
|
||||
break;
|
||||
case video::VIDEO_H265_VBR:
|
||||
video_type = video::VIDEO_H265_VBR;
|
||||
break;
|
||||
default:
|
||||
err::check_raise(err::ERR_RUNTIME, "Unsupported video type!");
|
||||
@@ -102,8 +129,11 @@ namespace maix::video
|
||||
} else if (!strcmp(suffix, ".flv")) {
|
||||
switch (type) {
|
||||
case video::VIDEO_H264: // fall through
|
||||
case video::VIDEO_H264_FLV:
|
||||
video_type = video::VIDEO_H264_FLV;
|
||||
case video::VIDEO_H264_CBR:
|
||||
video_type = video::VIDEO_H264_CBR;
|
||||
break;
|
||||
case video::VIDEO_H264_VBR:
|
||||
video_type = video::VIDEO_H264_VBR;
|
||||
break;
|
||||
default:
|
||||
err::check_raise(err::ERR_RUNTIME, "Unsupported video type!");
|
||||
@@ -120,12 +150,13 @@ namespace maix::video
|
||||
enum AVCodecID codec_id = AV_CODEC_ID_NONE;
|
||||
switch (video_type) {
|
||||
case VIDEO_H264:
|
||||
case VIDEO_H264_MP4:
|
||||
case VIDEO_H264_FLV:
|
||||
case VIDEO_H264_CBR:
|
||||
case VIDEO_H264_VBR:
|
||||
codec_id = AV_CODEC_ID_H264;
|
||||
break;
|
||||
case VIDEO_H265:
|
||||
case VIDEO_H265_MP4:
|
||||
case VIDEO_H265_CBR:
|
||||
case VIDEO_H265_VBR:
|
||||
codec_id = AV_CODEC_ID_HEVC;
|
||||
break;
|
||||
default:
|
||||
@@ -313,21 +344,24 @@ namespace maix::video
|
||||
param->frame_index = 0;
|
||||
param->last_encode_ms = time::ticks_ms();
|
||||
param->video_packet_list = new std::list<AVPacket *>;
|
||||
|
||||
bool is_raw_h264 = _path.find(".h264") != std::string::npos;
|
||||
bool is_raw_h265 = _path.find(".h265") != std::string::npos;
|
||||
|
||||
switch (video_type) {
|
||||
case VIDEO_H264:
|
||||
param->copy_sps_pps_per_iframe = true;
|
||||
break;
|
||||
case VIDEO_H264_MP4:
|
||||
param->copy_sps_pps_per_iframe = false;
|
||||
break;
|
||||
case VIDEO_H264_FLV:
|
||||
param->copy_sps_pps_per_iframe = false;
|
||||
case VIDEO_H264_CBR:
|
||||
case VIDEO_H264_VBR:
|
||||
param->copy_sps_pps_per_iframe = is_raw_h264 ? true : false;
|
||||
break;
|
||||
case VIDEO_H265:
|
||||
param->copy_sps_pps_per_iframe = true;
|
||||
break;
|
||||
case VIDEO_H265_MP4:
|
||||
param->copy_sps_pps_per_iframe = false;
|
||||
case VIDEO_H265_CBR:
|
||||
case VIDEO_H265_VBR:
|
||||
param->copy_sps_pps_per_iframe = is_raw_h265 ? true : false;
|
||||
break;
|
||||
default:
|
||||
err::check_raise(err::ERR_RUNTIME, "Unsupported video type!");
|
||||
@@ -336,12 +370,12 @@ namespace maix::video
|
||||
maixcam2::ax_venc_param_t cfg = {0};
|
||||
switch (video_type) {
|
||||
case VIDEO_H264:
|
||||
case VIDEO_H264_MP4:
|
||||
case VIDEO_H264_FLV:
|
||||
case VIDEO_H264_CBR:
|
||||
cfg.w = width;
|
||||
cfg.h = height;
|
||||
cfg.fmt = maixcam2::get_ax_fmt_from_maix(format);
|
||||
cfg.type = maixcam2::AX_VENC_TYPE_H264;
|
||||
cfg.rc_mode = maixcam2::AX_VENC_RCMODE_CBR;
|
||||
cfg.h264.bitrate = bitrate / 1000;
|
||||
cfg.h264.input_fps = framerate;
|
||||
cfg.h264.output_fps = framerate;
|
||||
@@ -356,12 +390,31 @@ namespace maix::video
|
||||
cfg.h264.max_iprop = 40;
|
||||
cfg.h264.first_frame_start_qp = -1;
|
||||
break;
|
||||
case VIDEO_H264_VBR:
|
||||
cfg.w = width;
|
||||
cfg.h = height;
|
||||
cfg.fmt = maixcam2::get_ax_fmt_from_maix(format);
|
||||
cfg.type = maixcam2::AX_VENC_TYPE_H264;
|
||||
cfg.rc_mode = maixcam2::AX_VENC_RCMODE_VBR;
|
||||
cfg.h264.bitrate = bitrate / 1000;
|
||||
cfg.h264.input_fps = framerate;
|
||||
cfg.h264.output_fps = framerate;
|
||||
cfg.h264.gop = gop;
|
||||
cfg.h264.intra_qp_delta = -2;
|
||||
cfg.h264.de_breath_qp_delta = -2;
|
||||
cfg.h264.min_qp = 31;
|
||||
cfg.h264.max_qp = 46;
|
||||
cfg.h264.min_iqp = 31;
|
||||
cfg.h264.max_iqp = 46;
|
||||
cfg.h264.first_frame_start_qp = -1;
|
||||
break;
|
||||
case VIDEO_H265:
|
||||
case VIDEO_H265_MP4:
|
||||
case VIDEO_H265_CBR:
|
||||
cfg.w = width;
|
||||
cfg.h = height;
|
||||
cfg.fmt = maixcam2::get_ax_fmt_from_maix(format);
|
||||
cfg.type = maixcam2::AX_VENC_TYPE_H265;
|
||||
cfg.rc_mode = maixcam2::AX_VENC_RCMODE_CBR;
|
||||
cfg.h265.bitrate = bitrate / 1000;
|
||||
cfg.h265.input_fps = framerate;
|
||||
cfg.h265.output_fps = framerate;
|
||||
@@ -376,10 +429,25 @@ namespace maix::video
|
||||
cfg.h265.max_iprop = 40;
|
||||
cfg.h265.first_frame_start_qp = -1;
|
||||
cfg.h265.qp_delta_rgn = 10;
|
||||
cfg.h265.qp_map_type = AX_VENC_QPMAP_QP_DISABLE;
|
||||
cfg.h265.qp_map_blk_type = AX_VENC_QPMAP_BLOCK_DISABLE;
|
||||
cfg.h265.qp_map_block_unit = AX_VENC_QPMAP_BLOCK_UNIT_64x64;
|
||||
cfg.h265.ctb_rc_mode = AX_VENC_RC_CTBRC_DISABLE;
|
||||
break;
|
||||
case VIDEO_H265_VBR:
|
||||
cfg.w = width;
|
||||
cfg.h = height;
|
||||
cfg.fmt = maixcam2::get_ax_fmt_from_maix(format);
|
||||
cfg.rc_mode = maixcam2::AX_VENC_RCMODE_VBR;
|
||||
cfg.type = maixcam2::AX_VENC_TYPE_H265;
|
||||
cfg.h265.bitrate = bitrate / 1000;
|
||||
cfg.h265.input_fps = framerate;
|
||||
cfg.h265.output_fps = framerate;
|
||||
cfg.h265.gop = gop;
|
||||
cfg.h265.intra_qp_delta = -2;
|
||||
cfg.h265.de_breath_qp_delta = -2;
|
||||
cfg.h265.min_qp = 31;
|
||||
cfg.h265.max_qp = 46;
|
||||
cfg.h265.min_iqp = 31;
|
||||
cfg.h265.max_iqp = 46;
|
||||
cfg.h265.first_frame_start_qp = -1;
|
||||
cfg.h265.qp_delta_rgn = 10;
|
||||
break;
|
||||
default:
|
||||
err::check_raise(err::ERR_RUNTIME, "unsupport stream type!");
|
||||
@@ -2050,10 +2118,12 @@ __vdec_exit:
|
||||
::close(this->_fd);
|
||||
|
||||
switch (this->_video_type) {
|
||||
case VIDEO_ENC_H265_CBR:
|
||||
case VIDEO_H265_CBR:
|
||||
case VIDEO_H265_VBR:
|
||||
// do nothing
|
||||
break;
|
||||
case VIDEO_ENC_MP4_CBR:
|
||||
case VIDEO_H264_CBR:
|
||||
case VIDEO_H264_VBR:
|
||||
{
|
||||
char cmd[128];
|
||||
snprintf(cmd, sizeof(cmd), "ffmpeg -loglevel quiet -i %s -c:v copy -c:a copy %s -y", this->_tmp_path.c_str(), this->_path.c_str());
|
||||
|
||||
@@ -66,7 +66,6 @@ namespace maix::webrtc
|
||||
bool bind_audio_recorder;
|
||||
|
||||
int encoder_bitrate;
|
||||
int fps;
|
||||
int gop;
|
||||
|
||||
MaixWebRTCServer *webrtc_server;
|
||||
@@ -151,20 +150,37 @@ namespace maix::webrtc
|
||||
param->status = WEBRTC_IDLE;
|
||||
}
|
||||
|
||||
WebRTC::WebRTC(std::string ip, int port, int fps,
|
||||
webrtc::WebRTCStreamType stream_type, int bitrate, int gop,
|
||||
std::string signaling_ip, int signaling_port,
|
||||
const std::string &stun_server,
|
||||
bool http_server)
|
||||
static video::VideoType get_video_type( maix::webrtc::WebRTCStreamType stream, maix::webrtc::WebRTCRCType rc)
|
||||
{
|
||||
using stream_type = maix::webrtc::WebRTCStreamType;
|
||||
using rc_type = maix::webrtc::WebRTCRCType;
|
||||
|
||||
if (stream == stream_type::WEBRTC_STREAM_H264) {
|
||||
if (rc == rc_type::WEBRTC_RC_CBR) { return video::VIDEO_H264_CBR; }
|
||||
if (rc == rc_type::WEBRTC_RC_VBR) { return video::VIDEO_H264_VBR; }
|
||||
}
|
||||
|
||||
if (stream == stream_type::WEBRTC_STREAM_H265) {
|
||||
if (rc == rc_type::WEBRTC_RC_CBR) { return video::VIDEO_H265_CBR; }
|
||||
if (rc == rc_type::WEBRTC_RC_VBR) { return video::VIDEO_H265_VBR; }
|
||||
}
|
||||
|
||||
log::error("Unsupported video type stream=%d rc=%d", (int)stream, (int)rc);
|
||||
return video::VIDEO_H264_CBR;
|
||||
}
|
||||
|
||||
WebRTC::WebRTC(std::string ip, int port, webrtc::WebRTCStreamType stream_type,
|
||||
webrtc::WebRTCRCType rc_type, int bitrate, int gop, std::string signaling_ip,
|
||||
int signaling_port, const std::string &stun_server, bool http_server)
|
||||
{
|
||||
this->_ip = ip.size() ? ip : "0.0.0.0";
|
||||
this->_port = port;
|
||||
this->_signaling_ip = signaling_ip;
|
||||
this->_signaling_port = signaling_port;
|
||||
this->_stun_server = stun_server;
|
||||
this->_fps = fps;
|
||||
this->_gop = gop;
|
||||
this->_stream_type = stream_type;
|
||||
this->_rc_type = rc_type;
|
||||
this->_is_start = false;
|
||||
this->_video_thread = nullptr;
|
||||
this->_http_server = http_server;
|
||||
@@ -186,7 +202,6 @@ namespace maix::webrtc
|
||||
param->bind_camera = false;
|
||||
param->bind_audio_recorder = false;
|
||||
param->encoder_bitrate = bitrate;
|
||||
param->fps = fps;
|
||||
param->gop = gop;
|
||||
|
||||
param->webrtc_server = nullptr;
|
||||
@@ -247,17 +262,9 @@ namespace maix::webrtc
|
||||
param->encoder = nullptr;
|
||||
}
|
||||
|
||||
video::VideoType video_type;
|
||||
if (this->_stream_type == maix::webrtc::WebRTCStreamType::WEBRTC_STREAM_H264) {
|
||||
video_type = video::VIDEO_H264;
|
||||
} else if (this->_stream_type == maix::webrtc::WebRTCStreamType::WEBRTC_STREAM_H265) {
|
||||
video_type = video::VIDEO_H265;
|
||||
} else {
|
||||
log::error("Unsupported stream type: %d", this->_stream_type);
|
||||
return err::ERR_ARGS;
|
||||
}
|
||||
video::VideoType video_type = get_video_type(this->_stream_type, this->_rc_type);
|
||||
|
||||
param->encoder = new video::Encoder("", param->camera->width(), param->camera->height(), image::Format::FMT_YVU420SP, video_type, param->fps, param->gop, param->encoder_bitrate);
|
||||
param->encoder = new video::Encoder("", param->camera->width(), param->camera->height(), image::Format::FMT_YVU420SP, video_type, param->camera->fps(), param->gop, param->encoder_bitrate);
|
||||
err::check_null_raise(param->encoder, "Create video encoder failed!");
|
||||
|
||||
if (param->bind_audio_recorder) {
|
||||
@@ -270,7 +277,7 @@ namespace maix::webrtc
|
||||
}
|
||||
|
||||
MaixWebRTCServerBuilder builder;
|
||||
builder.set_ice_server("stun:stun.l.google.com:19302");
|
||||
builder.set_ice_server(this->_stun_server);
|
||||
|
||||
if (this->_stream_type == maix::webrtc::WebRTCStreamType::WEBRTC_STREAM_H265) {
|
||||
builder.set_video_codec(VideoCodec::H265);
|
||||
|
||||
Reference in New Issue
Block a user