mirror of
https://github.com/mii443/SimpleDatachannel.git
synced 2025-08-22 16:25:31 +00:00
Initial commit
This commit is contained in:
25447
include/nlohmann/json.hpp
Normal file
25447
include/nlohmann/json.hpp
Normal file
File diff suppressed because it is too large
Load Diff
84
include/rtc/candidate.hpp
Normal file
84
include/rtc/candidate.hpp
Normal file
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#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);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, const rtc::Candidate &candidate);
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, const rtc::Candidate::Type &type);
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out,
|
||||
const rtc::Candidate::TransportType &transportType);
|
||||
|
||||
#endif
|
70
include/rtc/channel.hpp
Normal file
70
include/rtc/channel.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Copyright (c) 2019-2021 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_CHANNEL_H
|
||||
#define RTC_CHANNEL_H
|
||||
|
||||
#include "common.hpp"
|
||||
#include "message.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);
|
||||
|
||||
// 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
|
80
include/rtc/common.hpp
Normal file
80
include/rtc/common.hpp
Normal file
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_COMMON_H
|
||||
#define RTC_COMMON_H
|
||||
|
||||
#ifndef RTC_ENABLE_WEBSOCKET
|
||||
#define RTC_ENABLE_WEBSOCKET 1
|
||||
#endif
|
||||
|
||||
#ifndef RTC_ENABLE_MEDIA
|
||||
#define RTC_ENABLE_MEDIA 1
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define RTC_CPP_EXPORT __declspec(dllexport)
|
||||
#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
|
||||
#else
|
||||
#define RTC_CPP_EXPORT
|
||||
#endif
|
||||
|
||||
#include "rtc.h" // for C API defines
|
||||
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <variant>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#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 binary_ptr = std::shared_ptr<binary>;
|
||||
|
||||
using std::size_t;
|
||||
using std::ptrdiff_t;
|
||||
using std::uint16_t;
|
||||
using std::uint32_t;
|
||||
using std::uint64_t;
|
||||
using std::uint8_t;
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
97
include/rtc/configuration.hpp
Normal file
97
include/rtc/configuration.hpp
Normal file
@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_ICE_CONFIGURATION_H
|
||||
#define RTC_ICE_CONFIGURATION_H
|
||||
|
||||
#include "common.hpp"
|
||||
#include "message.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 { None = 0, Socks5, Http, Last = Http };
|
||||
|
||||
ProxyServer(Type type_, string hostname_, uint16_t port_, string username_ = "",
|
||||
string password_ = "");
|
||||
|
||||
Type type;
|
||||
string hostname;
|
||||
uint16_t port;
|
||||
string username;
|
||||
string password;
|
||||
};
|
||||
|
||||
enum class CertificateType {
|
||||
Default = RTC_CERTIFICATE_DEFAULT, // ECDSA
|
||||
Ecdsa = RTC_CERTIFICATE_ECDSA,
|
||||
Rsa = RTC_CERTIFICATE_RSA
|
||||
};
|
||||
|
||||
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;
|
||||
bool enableIceTcp = false;
|
||||
bool disableAutoNegotiation = false;
|
||||
|
||||
// Port range
|
||||
uint16_t portRangeBegin = 1024;
|
||||
uint16_t portRangeEnd = 65535;
|
||||
|
||||
// MTU
|
||||
optional<size_t> mtu;
|
||||
|
||||
// Local max message size at reception
|
||||
optional<size_t> maxMessageSize;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
96
include/rtc/datachannel.hpp
Normal file
96
include/rtc/datachannel.hpp
Normal file
@ -0,0 +1,96 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_DATA_CHANNEL_H
|
||||
#define RTC_DATA_CHANNEL_H
|
||||
|
||||
#include "channel.hpp"
|
||||
#include "common.hpp"
|
||||
#include "message.hpp"
|
||||
#include "reliability.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <shared_mutex>
|
||||
#include <type_traits>
|
||||
#include <shared_mutex>
|
||||
|
||||
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);
|
||||
virtual ~DataChannel();
|
||||
|
||||
uint16_t stream() const;
|
||||
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
|
275
include/rtc/description.hpp
Normal file
275
include/rtc/description.hpp
Normal file
@ -0,0 +1,275 @@
|
||||
/**
|
||||
* Copyright (c) 2019-2020 Paul-Louis Ageneau
|
||||
* Copyright (c) 2020 Staz Modrzynski
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#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 4.2 (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";
|
||||
|
||||
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;
|
||||
optional<string> iceUfrag() const;
|
||||
optional<string> icePwd() const;
|
||||
optional<string> fingerprint() const;
|
||||
bool ended() const;
|
||||
|
||||
void hintType(Type type);
|
||||
void setFingerprint(string fingerprint);
|
||||
|
||||
bool hasCandidate(const Candidate &candidate) const;
|
||||
void addCandidate(Candidate candidate);
|
||||
void addCandidates(std::vector<Candidate> candidates);
|
||||
void endCandidates();
|
||||
std::vector<Candidate> extractCandidates();
|
||||
|
||||
operator string() const;
|
||||
string generateSdp(string_view eol) const;
|
||||
string generateApplicationSdp(string_view eol) const;
|
||||
|
||||
class RTC_CPP_EXPORT Entry {
|
||||
public:
|
||||
virtual ~Entry() = default;
|
||||
|
||||
virtual string type() const { return mType; }
|
||||
virtual string description() const { return mDescription; }
|
||||
virtual string mid() const { return mMid; }
|
||||
Direction direction() const { return mDirection; }
|
||||
void setDirection(Direction dir);
|
||||
|
||||
operator string() const;
|
||||
string generateSdp(string_view eol, string_view addr, string_view port) const;
|
||||
|
||||
virtual void parseSdpLine(string_view line);
|
||||
|
||||
std::vector<string>::iterator beginAttributes();
|
||||
std::vector<string>::iterator endAttributes();
|
||||
std::vector<string>::iterator removeAttribute(std::vector<string>::iterator iterator);
|
||||
|
||||
protected:
|
||||
Entry(const string &mline, string mid, Direction dir = Direction::Unknown);
|
||||
virtual string generateSdpLines(string_view eol) const;
|
||||
|
||||
std::vector<string> mAttributes;
|
||||
|
||||
private:
|
||||
string mType;
|
||||
string mDescription;
|
||||
string mMid;
|
||||
Direction mDirection;
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT Application : public Entry {
|
||||
public:
|
||||
Application(string mid = "data");
|
||||
virtual ~Application() = default;
|
||||
|
||||
string description() const override;
|
||||
Application reciprocate() const;
|
||||
|
||||
void setSctpPort(uint16_t port) { mSctpPort = port; }
|
||||
void hintSctpPort(uint16_t port) { mSctpPort = mSctpPort.value_or(port); }
|
||||
void setMaxMessageSize(size_t size) { mMaxMessageSize = size; }
|
||||
|
||||
optional<uint16_t> sctpPort() const { return mSctpPort; }
|
||||
optional<size_t> maxMessageSize() const { return mMaxMessageSize; }
|
||||
|
||||
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 &sdp);
|
||||
Media(const string &mline, string mid, Direction dir = Direction::SendOnly);
|
||||
virtual ~Media() = default;
|
||||
|
||||
string description() const override;
|
||||
Media reciprocate() const;
|
||||
|
||||
void removeFormat(const string &fmt);
|
||||
|
||||
void addSSRC(uint32_t ssrc, optional<string> name, optional<string> msid = nullopt,
|
||||
optional<string> trackID = nullopt);
|
||||
void removeSSRC(uint32_t oldSSRC);
|
||||
void replaceSSRC(uint32_t oldSSRC, uint32_t ssrc, optional<string> name,
|
||||
optional<string> msid = nullopt, optional<string> trackID = nullopt);
|
||||
bool hasSSRC(uint32_t ssrc);
|
||||
std::vector<uint32_t> getSSRCs();
|
||||
std::optional<std::string> getCNameForSsrc(uint32_t ssrc);
|
||||
|
||||
void setBitrate(int bitrate);
|
||||
int getBitrate() const;
|
||||
|
||||
bool hasPayloadType(int payloadType) const;
|
||||
|
||||
void addRTXCodec(unsigned int payloadType, unsigned int originalPayloadType,
|
||||
unsigned int clockRate);
|
||||
|
||||
virtual void parseSdpLine(string_view line) override;
|
||||
|
||||
struct RTPMap {
|
||||
RTPMap(string_view mline);
|
||||
RTPMap() {}
|
||||
|
||||
void removeFB(const string &string);
|
||||
void addFB(const string &string);
|
||||
void addAttribute(string attr) { fmtps.emplace_back(std::move(attr)); }
|
||||
|
||||
int pt;
|
||||
string format;
|
||||
int clockRate;
|
||||
string encParams;
|
||||
|
||||
std::vector<string> rtcpFbs;
|
||||
std::vector<string> fmtps;
|
||||
|
||||
static int parsePT(string_view view);
|
||||
void setMLine(string_view view);
|
||||
};
|
||||
|
||||
void addRTPMap(const RTPMap &map);
|
||||
|
||||
std::map<int, RTPMap>::iterator beginMaps();
|
||||
std::map<int, RTPMap>::iterator endMaps();
|
||||
std::map<int, RTPMap>::iterator removeMap(std::map<int, RTPMap>::iterator iterator);
|
||||
|
||||
private:
|
||||
virtual string generateSdpLines(string_view eol) const override;
|
||||
|
||||
int mBas = -1;
|
||||
|
||||
Media::RTPMap &getFormat(int fmt);
|
||||
Media::RTPMap &getFormat(const string &fmt);
|
||||
|
||||
std::map<int, RTPMap> mRtpMap;
|
||||
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);
|
||||
};
|
||||
|
||||
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 addVP8Codec(int payloadType);
|
||||
void addVP9Codec(int payloadType);
|
||||
};
|
||||
|
||||
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(unsigned int index);
|
||||
variant<const Media *, const Application *> media(unsigned int index) const;
|
||||
unsigned 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;
|
||||
optional<string> mIceUfrag, mIcePwd;
|
||||
optional<string> mFingerprint;
|
||||
|
||||
// Entries
|
||||
std::vector<shared_ptr<Entry>> mEntries;
|
||||
shared_ptr<Application> mApplication;
|
||||
|
||||
// Candidates
|
||||
std::vector<Candidate> mCandidates;
|
||||
bool mEnded = false;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, const rtc::Description &description);
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, rtc::Description::Type type);
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, rtc::Description::Role role);
|
||||
|
||||
#endif
|
71
include/rtc/global.hpp
Normal file
71
include/rtc/global.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2021 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_GLOBAL_H
|
||||
#define RTC_GLOBAL_H
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#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);
|
||||
#ifdef PLOG_DEFAULT_INSTANCE_ID
|
||||
RTC_CPP_EXPORT void InitLogger(plog::Severity severity, plog::IAppender *appender = nullptr);
|
||||
#endif
|
||||
|
||||
RTC_CPP_EXPORT void Preload();
|
||||
RTC_CPP_EXPORT 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);
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, rtc::LogLevel level);
|
||||
|
||||
#endif
|
42
include/rtc/h264packetizationhandler.hpp
Normal file
42
include/rtc/h264packetizationhandler.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_H264_PACKETIZATION_HANDLER_H
|
||||
#define RTC_H264_PACKETIZATION_HANDLER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "h264rtppacketizer.hpp"
|
||||
#include "nalunit.hpp"
|
||||
#include "mediachainablehandler.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
/// Handler for H264 packetization
|
||||
class RTC_CPP_EXPORT H264PacketizationHandler final : public MediaChainableHandler {
|
||||
public:
|
||||
/// Construct handler for H264 packetization.
|
||||
/// @param packetizer RTP packetizer for h264
|
||||
H264PacketizationHandler(shared_ptr<H264RtpPacketizer> packetizer);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_H264_PACKETIZATION_HANDLER_H */
|
67
include/rtc/h264rtppacketizer.hpp
Normal file
67
include/rtc/h264rtppacketizer.hpp
Normal file
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_H264_RTP_PACKETIZER_H
|
||||
#define RTC_H264_RTP_PACKETIZER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "nalunit.hpp"
|
||||
#include "rtppacketizer.hpp"
|
||||
#include "mediahandlerrootelement.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
/// RTP packetization of h264 payload
|
||||
class RTC_CPP_EXPORT H264RtpPacketizer final : public RtpPacketizer, public MediaHandlerRootElement {
|
||||
shared_ptr<NalUnits> splitMessage(binary_ptr message);
|
||||
const uint16_t maximumFragmentSize;
|
||||
|
||||
public:
|
||||
/// Default clock rate for H264 in RTP
|
||||
inline static const uint32_t defaultClockRate = 90 * 1000;
|
||||
|
||||
/// Nalunit separator
|
||||
enum class Separator {
|
||||
LongStartSequence, // 0x00, 0x00, 0x00, 0x01
|
||||
ShortStartSequence, // 0x00, 0x00, 0x01
|
||||
StartSequence, // LongStartSequence or ShortStartSequence
|
||||
Length // first 4 bytes is nal unit length
|
||||
};
|
||||
|
||||
H264RtpPacketizer(H264RtpPacketizer::Separator separator, shared_ptr<RtpPacketizationConfig> rtpConfig,
|
||||
uint16_t maximumFragmentSize = NalUnits::defaultMaximumFragmentSize);
|
||||
|
||||
/// 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 rtpConfig RTP configuration
|
||||
/// @param maximumFragmentSize maximum size of one NALU fragment
|
||||
H264RtpPacketizer(shared_ptr<RtpPacketizationConfig> rtpConfig,
|
||||
uint16_t maximumFragmentSize = NalUnits::defaultMaximumFragmentSize);
|
||||
|
||||
ChainedOutgoingProduct processOutgoingBinaryMessage(ChainedMessagesProduct messages, message_ptr control) override;
|
||||
private:
|
||||
const Separator separator;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_H264_RTP_PACKETIZER_H */
|
56
include/rtc/mediachainablehandler.hpp
Normal file
56
include/rtc/mediachainablehandler.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_MEDIA_CHAINABLE_HANDLER_H
|
||||
#define RTC_MEDIA_CHAINABLE_HANDLER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "mediahandler.hpp"
|
||||
#include "mediahandlerrootelement.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class RTC_CPP_EXPORT MediaChainableHandler : public MediaHandler {
|
||||
const shared_ptr<MediaHandlerRootElement> root;
|
||||
shared_ptr<MediaHandlerElement> leaf;
|
||||
std::mutex inoutMutex;
|
||||
|
||||
message_ptr handleIncomingBinary(message_ptr);
|
||||
message_ptr handleIncomingControl(message_ptr);
|
||||
message_ptr handleOutgoingBinary(message_ptr);
|
||||
message_ptr handleOutgoingControl(message_ptr);
|
||||
bool sendProduct(ChainedOutgoingProduct product);
|
||||
public:
|
||||
MediaChainableHandler(shared_ptr<MediaHandlerRootElement> root);
|
||||
~MediaChainableHandler();
|
||||
message_ptr incoming(message_ptr ptr) override;
|
||||
message_ptr outgoing(message_ptr ptr) override;
|
||||
|
||||
bool send(message_ptr msg);
|
||||
|
||||
/// Adds element to chain
|
||||
/// @param chainable Chainable element
|
||||
void addToChain(shared_ptr<MediaHandlerElement> chainable);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // RTC_ENABLE_MEDIA
|
||||
|
||||
#endif // RTC_MEDIA_CHAINABLE_HANDLER_H
|
50
include/rtc/mediahandler.hpp
Normal file
50
include/rtc/mediahandler.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Staz Modrzynski
|
||||
* Copyright (c) 2020 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_MEDIA_HANDLER_H
|
||||
#define RTC_MEDIA_HANDLER_H
|
||||
|
||||
#include "common.hpp"
|
||||
#include "message.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class RTC_CPP_EXPORT MediaHandler {
|
||||
protected:
|
||||
// Use this callback when trying to send custom data (such as RTCP) to the client.
|
||||
synchronized_callback<message_ptr> outgoingCallback;
|
||||
|
||||
public:
|
||||
// Called when there is traffic coming from the peer
|
||||
virtual message_ptr incoming(message_ptr ptr) = 0;
|
||||
|
||||
// Called when there is traffic that needs to be sent to the peer
|
||||
virtual message_ptr outgoing(message_ptr ptr) = 0;
|
||||
|
||||
// This callback is used to send traffic back to the peer.
|
||||
void onOutgoing(const std::function<void(message_ptr)> &cb) {
|
||||
this->outgoingCallback = synchronized_callback<message_ptr>(cb);
|
||||
}
|
||||
|
||||
virtual bool requestKeyframe() { return false; }
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // RTC_MEDIA_HANDLER_H
|
112
include/rtc/mediahandlerelement.hpp
Normal file
112
include/rtc/mediahandlerelement.hpp
Normal file
@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_MEDIA_HANDLER_ELEMENT_H
|
||||
#define RTC_MEDIA_HANDLER_ELEMENT_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "common.hpp"
|
||||
#include "message.hpp"
|
||||
#include "rtp.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
using ChainedMessagesProduct = shared_ptr<std::vector<binary_ptr>>;
|
||||
|
||||
RTC_CPP_EXPORT ChainedMessagesProduct make_chained_messages_product();
|
||||
RTC_CPP_EXPORT ChainedMessagesProduct make_chained_messages_product(message_ptr msg);
|
||||
|
||||
/// Ougoing messages
|
||||
struct RTC_CPP_EXPORT ChainedOutgoingProduct {
|
||||
ChainedOutgoingProduct(ChainedMessagesProduct messages = nullptr, message_ptr control = nullptr);
|
||||
const ChainedMessagesProduct messages;
|
||||
const message_ptr control;
|
||||
};
|
||||
|
||||
/// Incoming messages with response
|
||||
struct RTC_CPP_EXPORT ChainedIncomingProduct {
|
||||
ChainedIncomingProduct(ChainedMessagesProduct incoming = nullptr, ChainedMessagesProduct outgoing = nullptr);
|
||||
const ChainedMessagesProduct incoming;
|
||||
const ChainedOutgoingProduct outgoing;
|
||||
};
|
||||
|
||||
/// Incoming control messages with response
|
||||
struct RTC_CPP_EXPORT ChainedIncomingControlProduct {
|
||||
ChainedIncomingControlProduct(message_ptr incoming, optional<ChainedOutgoingProduct> outgoing = nullopt);
|
||||
const message_ptr incoming;
|
||||
const optional<ChainedOutgoingProduct> outgoing;
|
||||
};
|
||||
|
||||
/// Chainable handler
|
||||
class RTC_CPP_EXPORT MediaHandlerElement: public std::enable_shared_from_this<MediaHandlerElement> {
|
||||
shared_ptr<MediaHandlerElement> upstream = nullptr;
|
||||
shared_ptr<MediaHandlerElement> downstream = nullptr;
|
||||
|
||||
void prepareAndSendResponse(optional<ChainedOutgoingProduct> outgoing, std::function<bool (ChainedOutgoingProduct)> send);
|
||||
|
||||
void removeFromChain();
|
||||
public:
|
||||
MediaHandlerElement();
|
||||
|
||||
/// Creates response to incoming message
|
||||
/// @param messages Current repsonse
|
||||
/// @returns New response
|
||||
optional<ChainedOutgoingProduct> processOutgoingResponse(ChainedOutgoingProduct messages);
|
||||
|
||||
// Process incoming and ougoing messages
|
||||
message_ptr formIncomingControlMessage(message_ptr message, std::function<bool (ChainedOutgoingProduct)> send);
|
||||
ChainedMessagesProduct formIncomingBinaryMessage(ChainedMessagesProduct messages, std::function<bool (ChainedOutgoingProduct)> send);
|
||||
message_ptr formOutgoingControlMessage(message_ptr message);
|
||||
optional<ChainedOutgoingProduct> formOutgoingBinaryMessage(ChainedOutgoingProduct product);
|
||||
|
||||
/// Process current control message
|
||||
/// @param messages current message
|
||||
/// @returns Modified message and response
|
||||
virtual ChainedIncomingControlProduct processIncomingControlMessage(message_ptr messages);
|
||||
|
||||
/// Process current control message
|
||||
/// @param messages current message
|
||||
/// @returns Modified message
|
||||
virtual message_ptr processOutgoingControlMessage(message_ptr messages);
|
||||
|
||||
/// Process current binary message
|
||||
/// @param messages current message
|
||||
/// @returns Modified message and response
|
||||
virtual ChainedIncomingProduct processIncomingBinaryMessage(ChainedMessagesProduct messages);
|
||||
|
||||
/// Process current binary message
|
||||
/// @param messages current message
|
||||
/// @param control current control message
|
||||
/// @returns Modified binary message and control message
|
||||
virtual ChainedOutgoingProduct processOutgoingBinaryMessage(ChainedMessagesProduct messages, message_ptr control);
|
||||
|
||||
/// Set given element as upstream to this
|
||||
/// @param upstream Upstream element
|
||||
/// @returns Upstream element
|
||||
shared_ptr<MediaHandlerElement> chainWith(shared_ptr<MediaHandlerElement> upstream);
|
||||
|
||||
/// Remove all downstream elements from chain
|
||||
void recursiveRemoveChain();
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // RTC_ENABLE_MEDIA
|
||||
|
||||
#endif // RTC_MEDIA_HANDLER_ELEMENT_H
|
46
include/rtc/mediahandlerrootelement.hpp
Normal file
46
include/rtc/mediahandlerrootelement.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_MEDIA_HANDLER_ROOT_ELEMENT_H
|
||||
#define RTC_MEDIA_HANDLER_ROOT_ELEMENT_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "mediahandlerelement.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
/// Chainable message handler
|
||||
class RTC_CPP_EXPORT MediaHandlerRootElement : public MediaHandlerElement {
|
||||
public:
|
||||
MediaHandlerRootElement() { }
|
||||
|
||||
/// Reduce multiple messages into one message
|
||||
/// @param messages Messages to reduce
|
||||
virtual message_ptr reduce(ChainedMessagesProduct messages);
|
||||
|
||||
/// Splits message into multiple messages
|
||||
/// @param message Message to split
|
||||
virtual ChainedMessagesProduct split(message_ptr message);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // RTC_ENABLE_MEDIA
|
||||
|
||||
#endif // RTC_MEDIA_HANDLER_ROOT_ELEMENT_H
|
79
include/rtc/message.hpp
Normal file
79
include/rtc/message.hpp
Normal file
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Copyright (c) 2019-2020 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_MESSAGE_H
|
||||
#define RTC_MESSAGE_H
|
||||
|
||||
#include "common.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;
|
||||
};
|
||||
|
||||
using message_ptr = shared_ptr<Message>;
|
||||
using message_callback = std::function<void(message_ptr message)>;
|
||||
using message_variant = variant<binary, string>;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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(message_variant data);
|
||||
|
||||
RTC_CPP_EXPORT message_variant to_variant(Message &&message);
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
155
include/rtc/nalunit.hpp
Normal file
155
include/rtc/nalunit.hpp
Normal file
@ -0,0 +1,155 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_NAL_UNIT_H
|
||||
#define RTC_NAL_UNIT_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
/// Nalu header
|
||||
struct RTC_CPP_EXPORT NalUnitHeader {
|
||||
uint8_t _first = 0;
|
||||
|
||||
bool forbiddenBit() { return _first >> 7; }
|
||||
uint8_t nri() { return _first >> 5 & 0x03; }
|
||||
uint8_t unitType() { 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() { return _first >> 7; }
|
||||
bool reservedBit6() { return (_first >> 6) & 0x01; }
|
||||
bool isEnd() { return (_first >> 5) & 0x01; }
|
||||
uint8_t unitType() { return _first & 0x1F; }
|
||||
|
||||
void setStart(bool isSet) { _first = (_first & 0x7F) | (isSet << 7); }
|
||||
void setEnd(bool isSet) { _first = (_first & 0xDF) | (isSet << 6); }
|
||||
void setReservedBit6(bool isSet) { _first = (_first & 0xBF) | (isSet << 5); }
|
||||
void setUnitType(uint8_t type) { _first = (_first & 0xE0) | (type & 0x1F); }
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
/// Nal unit
|
||||
struct RTC_CPP_EXPORT NalUnit : binary {
|
||||
NalUnit(const NalUnit &unit) = default;
|
||||
NalUnit(size_t size, bool includingHeader = true) : binary(size + (includingHeader ? 0 : 1)) {}
|
||||
|
||||
template <typename Iterator> NalUnit(Iterator begin_, Iterator end_) : binary(begin_, end_) {}
|
||||
|
||||
NalUnit(binary &&data) : binary(std::move(data)) {}
|
||||
|
||||
NalUnit() : binary(1) {}
|
||||
|
||||
bool forbiddenBit() { return header()->forbiddenBit(); }
|
||||
uint8_t nri() { return header()->nri(); }
|
||||
uint8_t unitType() { return header()->unitType(); }
|
||||
binary payload() {
|
||||
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());
|
||||
}
|
||||
|
||||
protected:
|
||||
NalUnitHeader *header() {
|
||||
assert(size() >= 1);
|
||||
return (NalUnitHeader *)data();
|
||||
}
|
||||
};
|
||||
|
||||
/// Nal unit fragment A
|
||||
struct RTC_CPP_EXPORT NalUnitFragmentA : NalUnit {
|
||||
enum class FragmentType { Start, Middle, End };
|
||||
|
||||
NalUnitFragmentA(FragmentType type, bool forbiddenBit, uint8_t nri, uint8_t unitType,
|
||||
binary data);
|
||||
|
||||
static std::vector<shared_ptr<NalUnitFragmentA>>
|
||||
fragmentsFrom(shared_ptr<NalUnit> nalu, uint16_t maximumFragmentSize);
|
||||
|
||||
uint8_t unitType() { return fragmentHeader()->unitType(); }
|
||||
|
||||
binary payload() {
|
||||
assert(size() >= 2);
|
||||
return {begin() + 2, end()};
|
||||
}
|
||||
|
||||
FragmentType type() {
|
||||
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:
|
||||
NalUnitHeader *fragmentIndicator() { return (NalUnitHeader *)data(); }
|
||||
|
||||
NalUnitFragmentHeader *fragmentHeader() {
|
||||
return (NalUnitFragmentHeader *)fragmentIndicator() + 1;
|
||||
}
|
||||
|
||||
const uint8_t nal_type_fu_A = 28;
|
||||
};
|
||||
|
||||
class 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 maximumFragmentSize);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_NAL_UNIT_H */
|
42
include/rtc/opuspacketizationhandler.hpp
Normal file
42
include/rtc/opuspacketizationhandler.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_OPUS_PACKETIZATION_HANDLER_H
|
||||
#define RTC_OPUS_PACKETIZATION_HANDLER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "opusrtppacketizer.hpp"
|
||||
#include "mediachainablehandler.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
/// Handler for opus packetization
|
||||
class RTC_CPP_EXPORT OpusPacketizationHandler final : public MediaChainableHandler {
|
||||
|
||||
public:
|
||||
/// Construct handler for opus packetization.
|
||||
/// @param packetizer RTP packetizer for opus
|
||||
OpusPacketizationHandler(shared_ptr<OpusRtpPacketizer> packetizer);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_OPUS_PACKETIZATION_HANDLER_H */
|
58
include/rtc/opusrtppacketizer.hpp
Normal file
58
include/rtc/opusrtppacketizer.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_OPUS_RTP_PACKETIZER_H
|
||||
#define RTC_OPUS_RTP_PACKETIZER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "rtppacketizer.hpp"
|
||||
#include "mediahandlerrootelement.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
/// RTP packetizer for opus
|
||||
class RTC_CPP_EXPORT OpusRtpPacketizer final : public RtpPacketizer, public MediaHandlerRootElement {
|
||||
public:
|
||||
/// default clock rate used in opus RTP communication
|
||||
inline static const uint32_t defaultClockRate = 48 * 1000;
|
||||
|
||||
/// Constructs opus 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
|
||||
OpusRtpPacketizer(shared_ptr<RtpPacketizationConfig> rtpConfig);
|
||||
|
||||
/// Creates RTP packet for given payload based on `rtpConfig`.
|
||||
/// @note This function increase sequence number after packetization.
|
||||
/// @param payload RTP payload
|
||||
/// @param setMark This needs to be `false` for all RTP packets with opus payload
|
||||
binary_ptr packetize(binary_ptr payload, bool setMark) override;
|
||||
|
||||
/// Creates RTP packet for given samples (all samples share same RTP timesamp)
|
||||
/// @param messages opus samples
|
||||
/// @param control RTCP
|
||||
/// @returns RTP packets and unchanged `control`
|
||||
ChainedOutgoingProduct processOutgoingBinaryMessage(ChainedMessagesProduct messages, message_ptr control) override;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_OPUS_RTP_PACKETIZER_H */
|
123
include/rtc/peerconnection.hpp
Normal file
123
include/rtc/peerconnection.hpp
Normal file
@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_PEER_CONNECTION_H
|
||||
#define RTC_PEER_CONNECTION_H
|
||||
|
||||
#include "candidate.hpp"
|
||||
#include "configuration.hpp"
|
||||
#include "datachannel.hpp"
|
||||
#include "description.hpp"
|
||||
#include "common.hpp"
|
||||
#include "message.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 = "";
|
||||
};
|
||||
|
||||
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 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,
|
||||
} rtcSignalingState;
|
||||
|
||||
PeerConnection();
|
||||
PeerConnection(Configuration config);
|
||||
~PeerConnection();
|
||||
|
||||
void close();
|
||||
|
||||
const Configuration *config() const;
|
||||
State state() const;
|
||||
GatheringState gatheringState() const;
|
||||
SignalingState signalingState() const;
|
||||
bool hasMedia() const;
|
||||
optional<Description> localDescription() const;
|
||||
optional<Description> remoteDescription() const;
|
||||
optional<string> localAddress() const;
|
||||
optional<string> remoteAddress() const;
|
||||
bool getSelectedCandidatePair(Candidate *local, Candidate *remote);
|
||||
|
||||
void setLocalDescription(Description::Type type = Description::Type::Unspec);
|
||||
|
||||
void setRemoteDescription(Description description);
|
||||
void addRemoteCandidate(Candidate candidate);
|
||||
|
||||
shared_ptr<DataChannel> createDataChannel(string label, DataChannelInit init = {});
|
||||
void onDataChannel(std::function<void(std::shared_ptr<DataChannel> dataChannel)> callback);
|
||||
|
||||
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 onGatheringStateChange(std::function<void(GatheringState state)> callback);
|
||||
void onSignalingStateChange(std::function<void(SignalingState state)> callback);
|
||||
|
||||
// Stats
|
||||
void clearStats();
|
||||
size_t bytesSent();
|
||||
size_t bytesReceived();
|
||||
optional<std::chrono::milliseconds> rtt();
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, rtc::PeerConnection::State state);
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out,
|
||||
rtc::PeerConnection::GatheringState state);
|
||||
RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out,
|
||||
rtc::PeerConnection::SignalingState state);
|
||||
|
||||
#endif
|
38
include/rtc/reliability.hpp
Normal file
38
include/rtc/reliability.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_RELIABILITY_H
|
||||
#define RTC_RELIABILITY_H
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
struct Reliability {
|
||||
enum class Type { Reliable = 0, Rexmit, Timed };
|
||||
|
||||
Type type = Type::Reliable;
|
||||
bool unordered = false;
|
||||
variant<int, std::chrono::milliseconds> rexmit = 0;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
388
include/rtc/rtc.h
Normal file
388
include/rtc/rtc.h
Normal file
@ -0,0 +1,388 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_C_API
|
||||
#define RTC_C_API
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define RTC_EXPORT __declspec(dllexport)
|
||||
#ifdef CAPI_STDCALL
|
||||
#define RTC_API __stdcall
|
||||
#else
|
||||
#define RTC_API
|
||||
#endif
|
||||
#else // not WIN32
|
||||
#define RTC_EXPORT
|
||||
#define RTC_API
|
||||
#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_MAXIMUM_FRAGMENT_SIZE \
|
||||
((uint16_t)(RTC_DEFAULT_MTU - 12 - 8 - 40)) // SRTP/UDP/IPv6
|
||||
#define RTC_DEFAULT_MAXIMUM_PACKET_COUNT_FOR_NACK_CACHE ((unsigned)512)
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// 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_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,
|
||||
|
||||
// audio
|
||||
RTC_CODEC_OPUS = 128
|
||||
} rtcCodec;
|
||||
|
||||
typedef enum {
|
||||
RTC_DIRECTION_UNKNOWN = 0,
|
||||
RTC_DIRECTION_SENDONLY = 1,
|
||||
RTC_DIRECTION_RECVONLY = 2,
|
||||
RTC_DIRECTION_SENDRECV = 3,
|
||||
RTC_DIRECTION_INACTIVE = 4
|
||||
} rtcDirection;
|
||||
|
||||
#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 *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 *rtcBufferedAmountLowCallbackFunc)(int id, void *ptr);
|
||||
typedef void(RTC_API *rtcAvailableCallbackFunc)(int id, void *ptr);
|
||||
|
||||
// Log
|
||||
|
||||
// NULL cb on the first call will log to stdout
|
||||
RTC_EXPORT void rtcInitLogger(rtcLogLevel level, rtcLogCallbackFunc cb);
|
||||
|
||||
// User pointer
|
||||
RTC_EXPORT void rtcSetUserPointer(int id, void *ptr);
|
||||
RTC_EXPORT void *rtcGetUserPointer(int i);
|
||||
|
||||
// PeerConnection
|
||||
|
||||
typedef struct {
|
||||
const char **iceServers;
|
||||
int iceServersCount;
|
||||
const char *bindAddress; // libjuice only, NULL means any
|
||||
rtcCertificateType certificateType;
|
||||
bool enableIceTcp;
|
||||
bool disableAutoNegotiation;
|
||||
uint16_t portRangeBegin; // 0 means automatic
|
||||
uint16_t portRangeEnd; // 0 means automatic
|
||||
int mtu; // <= 0 means automatic
|
||||
int maxMessageSize; // <= 0 means default
|
||||
} rtcConfiguration;
|
||||
|
||||
RTC_EXPORT int rtcCreatePeerConnection(const rtcConfiguration *config); // returns pc id
|
||||
RTC_EXPORT int rtcDeletePeerConnection(int pc);
|
||||
|
||||
RTC_EXPORT int rtcSetLocalDescriptionCallback(int pc, rtcDescriptionCallbackFunc cb);
|
||||
RTC_EXPORT int rtcSetLocalCandidateCallback(int pc, rtcCandidateCallbackFunc cb);
|
||||
RTC_EXPORT int rtcSetStateChangeCallback(int pc, rtcStateChangeCallbackFunc cb);
|
||||
RTC_EXPORT int rtcSetGatheringStateChangeCallback(int pc, rtcGatheringStateCallbackFunc cb);
|
||||
RTC_EXPORT int rtcSetSignalingStateChangeCallback(int pc, rtcSignalingStateCallbackFunc cb);
|
||||
|
||||
RTC_EXPORT int rtcSetLocalDescription(int pc, const char *type);
|
||||
RTC_EXPORT int rtcSetRemoteDescription(int pc, const char *sdp, const char *type);
|
||||
RTC_EXPORT int rtcAddRemoteCandidate(int pc, const char *cand, const char *mid);
|
||||
|
||||
RTC_EXPORT int rtcGetLocalDescription(int pc, char *buffer, int size);
|
||||
RTC_EXPORT int rtcGetRemoteDescription(int pc, char *buffer, int size);
|
||||
|
||||
RTC_EXPORT int rtcGetLocalDescriptionType(int pc, char *buffer, int size);
|
||||
RTC_EXPORT int rtcGetRemoteDescriptionType(int pc, char *buffer, int size);
|
||||
|
||||
RTC_EXPORT int rtcGetLocalAddress(int pc, char *buffer, int size);
|
||||
RTC_EXPORT int rtcGetRemoteAddress(int pc, char *buffer, int size);
|
||||
|
||||
RTC_EXPORT int rtcGetSelectedCandidatePair(int pc, char *local, int localSize, char *remote,
|
||||
int remoteSize);
|
||||
|
||||
// DataChannel
|
||||
|
||||
typedef struct {
|
||||
bool unordered;
|
||||
bool unreliable;
|
||||
int maxPacketLifeTime; // ignored if reliable
|
||||
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_EXPORT int rtcSetDataChannelCallback(int pc, rtcDataChannelCallbackFunc cb);
|
||||
RTC_EXPORT int rtcCreateDataChannel(int pc, const char *label); // returns dc id
|
||||
RTC_EXPORT int rtcCreateDataChannelEx(int pc, const char *label,
|
||||
const rtcDataChannelInit *init); // returns dc id
|
||||
RTC_EXPORT int rtcIsOpen(int dc);
|
||||
RTC_EXPORT int rtcDeleteDataChannel(int dc);
|
||||
|
||||
RTC_EXPORT int rtcGetDataChannelStream(int dc);
|
||||
RTC_EXPORT int rtcGetDataChannelLabel(int dc, char *buffer, int size);
|
||||
RTC_EXPORT int rtcGetDataChannelProtocol(int dc, char *buffer, int size);
|
||||
RTC_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
|
||||
} rtcTrackInit;
|
||||
|
||||
RTC_EXPORT int rtcSetTrackCallback(int pc, rtcTrackCallbackFunc cb);
|
||||
RTC_EXPORT int rtcAddTrack(int pc, const char *mediaDescriptionSdp); // returns tr id
|
||||
RTC_EXPORT int rtcAddTrackEx(int pc, const rtcTrackInit *init); // returns tr id
|
||||
RTC_EXPORT int rtcDeleteTrack(int tr);
|
||||
|
||||
RTC_EXPORT int rtcGetTrackDescription(int tr, char *buffer, int size);
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
// Media
|
||||
|
||||
typedef struct {
|
||||
uint32_t ssrc;
|
||||
const char *cname;
|
||||
uint8_t payloadType;
|
||||
uint32_t clockRate;
|
||||
uint16_t maxFragmentSize; // Maximum NALU fragment size
|
||||
uint16_t sequenceNumber;
|
||||
uint32_t timestamp;
|
||||
} rtcPacketizationHandlerInit;
|
||||
|
||||
typedef struct {
|
||||
double seconds; // Start time in seconds
|
||||
bool since1970; // true if seconds since 1970
|
||||
// false if seconds since 1900
|
||||
uint32_t timestamp; // Start timestamp
|
||||
} rtcStartTime;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ssrc;
|
||||
const char *name; // optional
|
||||
const char *msid; // optional
|
||||
const char *trackId; // optional, track ID used in MSID
|
||||
} rtcSsrcForTypeInit;
|
||||
|
||||
// Set H264PacketizationHandler for track
|
||||
RTC_EXPORT int rtcSetH264PacketizationHandler(int tr, const rtcPacketizationHandlerInit *init);
|
||||
|
||||
// Set OpusPacketizationHandler for track
|
||||
RTC_EXPORT int rtcSetOpusPacketizationHandler(int tr, const rtcPacketizationHandlerInit *init);
|
||||
|
||||
// Chain RtcpSrReporter to handler chain for given track
|
||||
RTC_EXPORT int rtcChainRtcpSrReporter(int tr);
|
||||
|
||||
// Chain RtcpNackResponder to handler chain for given track
|
||||
RTC_EXPORT int rtcChainRtcpNackResponder(int tr, unsigned int maxStoredPacketsCount);
|
||||
|
||||
/// Set start time for RTP stream
|
||||
RTC_EXPORT int rtcSetRtpConfigurationStartTime(int id, const rtcStartTime *startTime);
|
||||
|
||||
// Start stats recording for RTCP Sender Reporter
|
||||
RTC_EXPORT int rtcStartRtcpSenderReporterRecording(int id);
|
||||
|
||||
// Transform seconds to timestamp using track's clock rate
|
||||
// Result is written to timestamp
|
||||
RTC_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_EXPORT int rtcTransformTimestampToSeconds(int id, uint32_t timestamp, double *seconds);
|
||||
|
||||
// Get current timestamp
|
||||
// Result is written to timestamp
|
||||
RTC_EXPORT int rtcGetCurrentTrackTimestamp(int id, uint32_t *timestamp);
|
||||
|
||||
// Get start timestamp for track identified by given id
|
||||
// Result is written to timestamp
|
||||
RTC_EXPORT int rtcGetTrackStartTimestamp(int id, uint32_t *timestamp);
|
||||
|
||||
// Set RTP timestamp for track identified by given id
|
||||
RTC_EXPORT int rtcSetTrackRtpTimestamp(int id, uint32_t timestamp);
|
||||
|
||||
// Get timestamp of previous RTCP SR
|
||||
// Result is written to timestamp
|
||||
RTC_EXPORT int rtcGetPreviousTrackSenderReportTimestamp(int id, uint32_t *timestamp);
|
||||
|
||||
// Set NeedsToReport flag in RtcpSrReporter handler identified by given track id
|
||||
RTC_EXPORT int rtcSetNeedsToSendRtcpSr(int id);
|
||||
|
||||
/// 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
|
||||
/// @param mediaType Media type (audio/video)
|
||||
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);
|
||||
|
||||
#endif // RTC_ENABLE_MEDIA
|
||||
|
||||
#if RTC_ENABLE_WEBSOCKET
|
||||
|
||||
// WebSocket
|
||||
|
||||
typedef struct {
|
||||
bool disableTlsVerification; // if true, don't verify the TLS certificate
|
||||
} rtcWsConfiguration;
|
||||
|
||||
RTC_EXPORT int rtcCreateWebSocket(const char *url); // returns ws id
|
||||
RTC_EXPORT int rtcCreateWebSocketEx(const char *url, const rtcWsConfiguration *config);
|
||||
RTC_EXPORT int rtcDeleteWebsocket(int ws);
|
||||
|
||||
#endif
|
||||
|
||||
// DataChannel, Track, and WebSocket common API
|
||||
|
||||
RTC_EXPORT int rtcSetOpenCallback(int id, rtcOpenCallbackFunc cb);
|
||||
RTC_EXPORT int rtcSetClosedCallback(int id, rtcClosedCallbackFunc cb);
|
||||
RTC_EXPORT int rtcSetErrorCallback(int id, rtcErrorCallbackFunc cb);
|
||||
RTC_EXPORT int rtcSetMessageCallback(int id, rtcMessageCallbackFunc cb);
|
||||
RTC_EXPORT int rtcSendMessage(int id, const char *data, int size);
|
||||
|
||||
RTC_EXPORT int rtcGetBufferedAmount(int id); // total size buffered to send
|
||||
RTC_EXPORT int rtcSetBufferedAmountLowThreshold(int id, int amount);
|
||||
RTC_EXPORT int rtcSetBufferedAmountLowCallback(int id, rtcBufferedAmountLowCallbackFunc cb);
|
||||
|
||||
// DataChannel, Track, and WebSocket common extended API
|
||||
|
||||
RTC_EXPORT int rtcGetAvailableAmount(int id); // total size available to receive
|
||||
RTC_EXPORT int rtcSetAvailableCallback(int id, rtcAvailableCallbackFunc cb);
|
||||
RTC_EXPORT int rtcReceiveMessage(int id, char *buffer, int *size);
|
||||
|
||||
// Optional global preload and cleanup
|
||||
|
||||
RTC_EXPORT void rtcPreload(void);
|
||||
RTC_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 msecs, 0 means optimized default, < 0 means disabled
|
||||
int minRetransmitTimeoutMs; // in msecs, <= 0 means optimized default
|
||||
int maxRetransmitTimeoutMs; // in msecs, <= 0 means optimized default
|
||||
int initialRetransmitTimeoutMs; // in msecs, <= 0 means optimized default
|
||||
int maxRetransmitAttempts; // number of retransmissions, <= 0 means optimized default
|
||||
int heartbeatIntervalMs; // in msecs, <= 0 means optimized default
|
||||
} rtcSctpSettings;
|
||||
|
||||
// Note: SCTP settings apply to newly-created PeerConnections only
|
||||
RTC_EXPORT int rtcSetSctpSettings(const rtcSctpSettings *settings);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
49
include/rtc/rtc.hpp
Normal file
49
include/rtc/rtc.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// C API
|
||||
#include "rtc.h"
|
||||
|
||||
// C++ API
|
||||
#include "common.hpp"
|
||||
#include "global.hpp"
|
||||
//
|
||||
#include "datachannel.hpp"
|
||||
#include "peerconnection.hpp"
|
||||
#include "track.hpp"
|
||||
|
||||
#if RTC_ENABLE_WEBSOCKET
|
||||
|
||||
// WebSocket
|
||||
#include "websocket.hpp"
|
||||
|
||||
#endif // RTC_ENABLE_WEBSOCKET
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
// Media handling
|
||||
#include "mediachainablehandler.hpp"
|
||||
#include "rtcpnackresponder.hpp"
|
||||
#include "rtcpreceivingsession.hpp"
|
||||
#include "rtcpsrreporter.hpp"
|
||||
|
||||
// Opus/h264 streaming
|
||||
#include "h264packetizationhandler.hpp"
|
||||
#include "opuspacketizationhandler.hpp"
|
||||
|
||||
#endif // RTC_ENABLE_MEDIA
|
95
include/rtc/rtcpnackresponder.hpp
Normal file
95
include/rtc/rtcpnackresponder.hpp
Normal file
@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_RTCP_NACK_RESPONDER_H
|
||||
#define RTC_RTCP_NACK_RESPONDER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "mediahandlerelement.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <queue>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class RTC_CPP_EXPORT RtcpNackResponder final: public MediaHandlerElement {
|
||||
|
||||
/// Packet storage
|
||||
class RTC_CPP_EXPORT Storage {
|
||||
|
||||
/// Packet storage element
|
||||
struct RTC_CPP_EXPORT Element {
|
||||
Element(binary_ptr packet, uint16_t sequenceNumber, shared_ptr<Element> next = nullptr);
|
||||
const binary_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{};
|
||||
|
||||
/// Maximum storage size
|
||||
const unsigned maximumSize;
|
||||
|
||||
/// Returnst current size
|
||||
unsigned size();
|
||||
|
||||
public:
|
||||
static const unsigned defaultMaximumSize = 512;
|
||||
|
||||
Storage(unsigned _maximumSize);
|
||||
|
||||
/// Returns packet with given sequence number
|
||||
optional<binary_ptr> get(uint16_t sequenceNumber);
|
||||
|
||||
/// Stores packet
|
||||
/// @param packet Packet
|
||||
void store(binary_ptr packet);
|
||||
};
|
||||
|
||||
const shared_ptr<Storage> storage;
|
||||
std::mutex reportMutex;
|
||||
|
||||
public:
|
||||
RtcpNackResponder(unsigned maxStoredPacketCount = Storage::defaultMaximumSize);
|
||||
|
||||
/// Checks for RTCP NACK and handles it,
|
||||
/// @param message RTCP message
|
||||
/// @returns unchanged RTCP message and requested RTP packets
|
||||
ChainedIncomingControlProduct processIncomingControlMessage(message_ptr message) override;
|
||||
|
||||
/// Stores RTP packets in internal storage
|
||||
/// @param messages RTP packets
|
||||
/// @param control RTCP
|
||||
/// @returns Unchanged RTP and RTCP
|
||||
ChainedOutgoingProduct processOutgoingBinaryMessage(ChainedMessagesProduct messages, message_ptr control) override;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_RTCP_NACK_RESPONDER_H */
|
59
include/rtc/rtcpreceivingsession.hpp
Normal file
59
include/rtc/rtcpreceivingsession.hpp
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Staz Modrzynski
|
||||
* Copyright (c) 2020 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
// An RtcpSession can be plugged into a Track to handle the whole RTCP session
|
||||
class RTC_CPP_EXPORT RtcpReceivingSession : public MediaHandler {
|
||||
public:
|
||||
message_ptr incoming(message_ptr ptr) override;
|
||||
message_ptr outgoing(message_ptr ptr) override;
|
||||
bool send(message_ptr ptr);
|
||||
|
||||
void requestBitrate(unsigned int newBitrate);
|
||||
|
||||
bool requestKeyframe() override;
|
||||
|
||||
protected:
|
||||
void pushREMB(unsigned int bitrate);
|
||||
void pushRR(unsigned int lastSR_delay);
|
||||
|
||||
void pushPLI();
|
||||
|
||||
unsigned int mRequestedBitrate = 0;
|
||||
SSRC mSsrc = 0;
|
||||
uint32_t mGreatestSeqNo = 0;
|
||||
uint64_t mSyncRTPTS, mSyncNTPTS;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // RTC_ENABLE_MEDIA
|
||||
|
||||
#endif // RTC_RTCP_RECEIVING_SESSION_H
|
71
include/rtc/rtcpsrreporter.hpp
Normal file
71
include/rtc/rtcpsrreporter.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_RTCP_SENDER_REPORTABLE_H
|
||||
#define RTC_RTCP_SENDER_REPORTABLE_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "message.hpp"
|
||||
#include "rtppacketizationconfig.hpp"
|
||||
#include "mediahandlerelement.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class RTC_CPP_EXPORT RtcpSrReporter final: public MediaHandlerElement {
|
||||
|
||||
bool needsToReport = false;
|
||||
|
||||
uint32_t packetCount = 0;
|
||||
uint32_t payloadOctets = 0;
|
||||
double timeOffset = 0;
|
||||
|
||||
uint32_t _previousReportedTimestamp = 0;
|
||||
|
||||
void addToReport(RTP *rtp, uint32_t rtpSize);
|
||||
message_ptr getSenderReport(uint32_t timestamp);
|
||||
|
||||
public:
|
||||
static uint64_t secondsToNTP(double seconds);
|
||||
|
||||
/// Timestamp of previous sender report
|
||||
const uint32_t &previousReportedTimestamp = _previousReportedTimestamp;
|
||||
|
||||
/// RTP configuration
|
||||
const shared_ptr<RtpPacketizationConfig> rtpConfig;
|
||||
|
||||
RtcpSrReporter(shared_ptr<RtpPacketizationConfig> rtpConfig);
|
||||
|
||||
ChainedOutgoingProduct processOutgoingBinaryMessage(ChainedMessagesProduct messages, message_ptr control) override;
|
||||
|
||||
/// Set `needsToReport` flag. Sender report will be sent before next RTP packet with same
|
||||
/// timestamp.
|
||||
void setNeedsToReport();
|
||||
|
||||
/// Set offset to compute NTS for RTCP SR packets. Offset represents relation between real start
|
||||
/// time and timestamp of the stream in RTP packets
|
||||
/// @note `time_offset = rtpConfig->startTime_s -
|
||||
/// rtpConfig->timestampToSeconds(rtpConfig->timestamp)`
|
||||
void startRecording();
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_RTCP_SENDER_REPORTABLE_H */
|
345
include/rtc/rtp.hpp
Normal file
345
include/rtc/rtp.hpp
Normal file
@ -0,0 +1,345 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Staz Modrzynski
|
||||
* Copyright (c) 2020 Paul-Louis Ageneau
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_RTP_HPP
|
||||
#define RTC_RTP_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace rtc {
|
||||
|
||||
typedef uint32_t SSRC;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct RTC_CPP_EXPORT RTP {
|
||||
uint8_t _first;
|
||||
uint8_t _payloadType;
|
||||
uint16_t _seqNumber;
|
||||
uint32_t _timestamp;
|
||||
SSRC _ssrc;
|
||||
SSRC _csrc[16];
|
||||
|
||||
[[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]] 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);
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RTCP_ReportBlock {
|
||||
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 jitter() const;
|
||||
[[nodiscard]] uint32_t delaySinceSR() const;
|
||||
|
||||
[[nodiscard]] SSRC getSSRC() const;
|
||||
[[nodiscard]] uint32_t getNTPOfSR() const;
|
||||
[[nodiscard]] unsigned int getLossPercentage() const;
|
||||
[[nodiscard]] unsigned int getPacketLostCount() const;
|
||||
|
||||
void preparePacket(SSRC in_ssrc, unsigned int packetsLost, unsigned int totalPackets,
|
||||
uint16_t highestSeqNo, uint16_t seqNoCycles, uint32_t jitter,
|
||||
uint64_t lastSR_NTP, uint64_t lastSR_DELAY);
|
||||
void setSSRC(SSRC in_ssrc);
|
||||
void setPacketsLost(unsigned int packetsLost, unsigned int totalPackets);
|
||||
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 RTCP_HEADER {
|
||||
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 RTCP_FB_HEADER {
|
||||
RTCP_HEADER 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 RTCP_SR {
|
||||
RTCP_HEADER header;
|
||||
|
||||
SSRC _senderSSRC;
|
||||
uint64_t _ntpTimestamp;
|
||||
uint32_t _rtpTimestamp;
|
||||
uint32_t _packetCount;
|
||||
uint32_t _octetCount;
|
||||
|
||||
RTCP_ReportBlock _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 RTCP_ReportBlock *getReportBlock(int num) const;
|
||||
[[nodiscard]] RTCP_ReportBlock *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 RTCP_SDES_ITEM {
|
||||
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 RTCP_SDES_CHUNK {
|
||||
SSRC _ssrc;
|
||||
RTCP_SDES_ITEM _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 RTCP_SDES_ITEM *getItem(int num) const;
|
||||
[[nodiscard]] RTCP_SDES_ITEM *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 RTCP_SDES {
|
||||
RTCP_HEADER header;
|
||||
RTCP_SDES_CHUNK _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 RTCP_SDES_CHUNK *getChunk(int num) const;
|
||||
RTCP_SDES_CHUNK *getChunk(int num);
|
||||
|
||||
void preparePacket(uint8_t chunkCount);
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RTCP_RR {
|
||||
RTCP_HEADER header;
|
||||
|
||||
SSRC _senderSSRC;
|
||||
RTCP_ReportBlock _reportBlocks;
|
||||
|
||||
[[nodiscard]] static size_t SizeWithReportBlocks(uint8_t reportCount);
|
||||
|
||||
SSRC senderSSRC() const;
|
||||
bool isSenderReport();
|
||||
bool isReceiverReport();
|
||||
|
||||
[[nodiscard]] RTCP_ReportBlock *getReportBlock(int num);
|
||||
[[nodiscard]] const RTCP_ReportBlock *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 RTCP_REMB {
|
||||
RTCP_FB_HEADER 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);
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RTCP_PLI {
|
||||
RTCP_FB_HEADER header;
|
||||
|
||||
[[nodiscard]] static unsigned int Size();
|
||||
|
||||
void preparePacket(SSRC messageSSRC);
|
||||
|
||||
void log() const;
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RTCP_FIR_PART {
|
||||
uint32_t ssrc;
|
||||
uint8_t seqNo;
|
||||
uint8_t dummy1;
|
||||
uint16_t dummy2;
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RTCP_FIR {
|
||||
RTCP_FB_HEADER header;
|
||||
RTCP_FIR_PART parts[1];
|
||||
|
||||
static unsigned int Size();
|
||||
|
||||
void preparePacket(SSRC messageSSRC, uint8_t seqNo);
|
||||
|
||||
void log() const;
|
||||
};
|
||||
|
||||
struct RTC_CPP_EXPORT RTCP_NACK_PART {
|
||||
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 RTCP_NACK {
|
||||
RTCP_FB_HEADER header;
|
||||
RTCP_NACK_PART 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 RTP_RTX {
|
||||
RTP 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(RTP *dest, size_t totalSize, uint8_t originalPayloadType);
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
}; // namespace rtc
|
||||
|
||||
#endif
|
95
include/rtc/rtppacketizationconfig.hpp
Normal file
95
include/rtc/rtppacketizationconfig.hpp
Normal file
@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_RTP_PACKETIZATION_CONFIG_H
|
||||
#define RTC_RTP_PACKETIZATION_CONFIG_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "rtp.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
/// RTP configuration used in packetization process
|
||||
class RTC_CPP_EXPORT RtpPacketizationConfig {
|
||||
uint32_t _startTimestamp = 0;
|
||||
double _startTime_s = 0;
|
||||
RtpPacketizationConfig(const RtpPacketizationConfig &) = delete;
|
||||
|
||||
public:
|
||||
const SSRC ssrc;
|
||||
const std::string cname;
|
||||
const uint8_t payloadType;
|
||||
const uint32_t clockRate;
|
||||
const double &startTime_s = _startTime_s;
|
||||
const uint32_t &startTimestamp = _startTimestamp;
|
||||
|
||||
/// current sequence number
|
||||
uint16_t sequenceNumber;
|
||||
/// current timestamp
|
||||
uint32_t timestamp;
|
||||
|
||||
enum class EpochStart : unsigned long long {
|
||||
T1970 = 2208988800, // number of seconds between 1970 and 1900
|
||||
T1900 = 0
|
||||
};
|
||||
|
||||
/// Creates relation between time and timestamp mapping given start time and start timestamp
|
||||
/// @param startTime_s Start time of the stream
|
||||
/// @param epochStart Type of used epoch
|
||||
/// @param startTimestamp Corresponding timestamp for given start time (current timestamp will
|
||||
/// be used if value is nullopt)
|
||||
void setStartTime(double startTime_s, EpochStart epochStart,
|
||||
optional<uint32_t> startTimestamp = std::nullopt);
|
||||
|
||||
/// 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
|
||||
/// @param sequenceNumber Initial sequence number of RTP packets (random number is choosed if
|
||||
/// nullopt)
|
||||
/// @param timestamp Initial timastamp of RTP packets (random number is choosed if nullopt)
|
||||
RtpPacketizationConfig(SSRC ssrc, std::string cname, uint8_t payloadType, uint32_t clockRate,
|
||||
optional<uint16_t> sequenceNumber = std::nullopt,
|
||||
optional<uint32_t> timestamp = std::nullopt);
|
||||
|
||||
/// 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 */
|
54
include/rtc/rtppacketizer.hpp
Normal file
54
include/rtc/rtppacketizer.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Filip Klembara (in2core)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_RTP_PACKETIZER_H
|
||||
#define RTC_RTP_PACKETIZER_H
|
||||
|
||||
#if RTC_ENABLE_MEDIA
|
||||
|
||||
#include "message.hpp"
|
||||
#include "rtppacketizationconfig.hpp"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
/// Class responsible for RTP packetization
|
||||
class RTC_CPP_EXPORT RtpPacketizer {
|
||||
static const auto rtpHeaderSize = 12;
|
||||
|
||||
public:
|
||||
// RTP configuration
|
||||
const shared_ptr<RtpPacketizationConfig> rtpConfig;
|
||||
|
||||
/// 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);
|
||||
|
||||
/// Creates RTP packet for given payload based on `rtpConfig`.
|
||||
/// @note This function increase sequence number after packetization.
|
||||
/// @param payload RTP payload
|
||||
/// @param setMark Set marker flag in RTP packet if true
|
||||
virtual shared_ptr<binary> packetize(shared_ptr<binary> payload, bool setMark);
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif /* RTC_ENABLE_MEDIA */
|
||||
|
||||
#endif /* RTC_RTP_PACKETIZER_H */
|
73
include/rtc/track.hpp
Normal file
73
include/rtc/track.hpp
Normal file
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_TRACK_H
|
||||
#define RTC_TRACK_H
|
||||
|
||||
#include "channel.hpp"
|
||||
#include "common.hpp"
|
||||
#include "description.hpp"
|
||||
#include "mediahandler.hpp"
|
||||
#include "message.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <shared_mutex>
|
||||
|
||||
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() = default;
|
||||
|
||||
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;
|
||||
|
||||
bool requestKeyframe();
|
||||
|
||||
void setMediaHandler(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
|
173
include/rtc/utils.hpp
Normal file
173
include/rtc/utils.hpp
Normal file
@ -0,0 +1,173 @@
|
||||
/**
|
||||
* Copyright (c) 2019-2021 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
std::function<void(Args...)> wrap() const {
|
||||
return [this](Args... args) { (*this)(std::move(args)...); };
|
||||
}
|
||||
|
||||
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::move(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
|
73
include/rtc/websocket.hpp
Normal file
73
include/rtc/websocket.hpp
Normal file
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2021 Paul-Louis Ageneau
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef RTC_WEBSOCKET_H
|
||||
#define RTC_WEBSOCKET_H
|
||||
|
||||
#if RTC_ENABLE_WEBSOCKET
|
||||
|
||||
#include "channel.hpp"
|
||||
#include "common.hpp"
|
||||
#include "message.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,
|
||||
};
|
||||
|
||||
struct Configuration {
|
||||
bool disableTlsVerification = false; // if true, don't verify the TLS certificate
|
||||
std::vector<string> protocols;
|
||||
};
|
||||
|
||||
WebSocket();
|
||||
WebSocket(Configuration config);
|
||||
~WebSocket();
|
||||
|
||||
State readyState() const;
|
||||
|
||||
bool isOpen() const override;
|
||||
bool isClosed() const override;
|
||||
size_t maxMessageSize() const override;
|
||||
|
||||
void open(const string &url);
|
||||
void close() override;
|
||||
bool send(const message_variant data) override;
|
||||
bool send(const byte *data, size_t size) override;
|
||||
|
||||
private:
|
||||
using CheshireCat<impl::WebSocket>::impl;
|
||||
};
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif
|
||||
|
||||
#endif // RTC_WEBSOCKET_H
|
Reference in New Issue
Block a user