diff --git a/include/rtc/common.hpp b/include/rtc/common.hpp index b96ac7d..8d65aea 100644 --- a/include/rtc/common.hpp +++ b/include/rtc/common.hpp @@ -19,14 +19,14 @@ #ifndef RTC_COMMON_H #define RTC_COMMON_H -#ifndef RTC_ENABLE_MEDIA -#define RTC_ENABLE_MEDIA 1 -#endif - #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 @@ -39,6 +39,8 @@ #define RTC_CPP_EXPORT #endif +#include "rtc.h" // for C API defines + #include "log.hpp" #include "utils.hpp" diff --git a/include/rtc/nalunit.hpp b/include/rtc/nalunit.hpp index f42546e..e719d20 100644 --- a/include/rtc/nalunit.hpp +++ b/include/rtc/nalunit.hpp @@ -62,11 +62,9 @@ private: /// 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)) {} + NalUnit(size_t size, bool includingHeader = true) : binary(size + (includingHeader ? 0 : 1)) {} - template - NalUnit(Iterator begin_, Iterator end_) : binary(begin_, end_) {} + template NalUnit(Iterator begin_, Iterator end_) : binary(begin_, end_) {} NalUnit(binary &&data) : binary(std::move(data)) {} @@ -101,9 +99,10 @@ 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); + binary data); - static std::vector> fragmentsFrom(std::shared_ptr nalu, uint16_t maximumFragmentSize); + static std::vector> + fragmentsFrom(std::shared_ptr nalu, uint16_t maximumFragmentSize); uint8_t unitType() { return fragmentHeader()->unitType(); } @@ -144,7 +143,8 @@ protected: class RTC_CPP_EXPORT NalUnits : public std::vector> { public: - static const uint16_t defaultMaximumFragmentSize; + static const uint16_t defaultMaximumFragmentSize = + uint16_t(RTC_DEFAULT_MTU - 12 - 8 - 40); // SRTP/UDP/IPv6 std::vector> generateFragments(uint16_t maximumFragmentSize); }; diff --git a/include/rtc/peerconnection.hpp b/include/rtc/peerconnection.hpp index 2c61572..01b85f9 100644 --- a/include/rtc/peerconnection.hpp +++ b/include/rtc/peerconnection.hpp @@ -27,7 +27,6 @@ #include "init.hpp" #include "message.hpp" #include "reliability.hpp" -#include "rtc.hpp" #include "track.hpp" #include diff --git a/include/rtc/rtc.h b/include/rtc/rtc.h index d003d9a..9fcfcf5 100644 --- a/include/rtc/rtc.h +++ b/include/rtc/rtc.h @@ -39,8 +39,14 @@ extern "C" { #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)(1280 - 12 - 8 - 40)) // SRTP/UDP/IPv6 +#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 @@ -116,13 +122,14 @@ typedef struct { bool enableIceTcp; uint16_t portRangeBegin; uint16_t portRangeEnd; + int mtu; // <= 0 means automatic } rtcConfiguration; typedef struct { bool unordered; bool unreliable; - unsigned int maxPacketLifeTime; // ignored if reliable - unsigned int maxRetransmits; // ignored if reliable + int maxPacketLifeTime; // ignored if reliable + int maxRetransmits; // ignored if reliable } rtcReliability; typedef struct { diff --git a/include/rtc/rtc.hpp b/include/rtc/rtc.hpp index ec8b286..3987f2f 100644 --- a/include/rtc/rtc.hpp +++ b/include/rtc/rtc.hpp @@ -16,15 +16,25 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +// C API +#include "rtc.h" + // C++ API #include "common.hpp" #include "init.hpp" // for rtc::Cleanup() #include "log.hpp" // #include "datachannel.hpp" +#include "track.hpp" #include "peerconnection.hpp" + +#if RTC_ENABLE_WEBSOCKET + +// WebSocket #include "websocket.hpp" +#endif // RTC_ENABLE_WEBSOCKET + #if RTC_ENABLE_MEDIA // Media handling @@ -39,5 +49,3 @@ #endif // RTC_ENABLE_MEDIA -// C API -#include "rtc.h" diff --git a/src/capi.cpp b/src/capi.cpp index 616344d..a8f857e 100644 --- a/src/capi.cpp +++ b/src/capi.cpp @@ -16,16 +16,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "common.hpp" - #include "rtc.h" -#include "datachannel.hpp" -#include "log.hpp" -#include "peerconnection.hpp" -#if RTC_ENABLE_WEBSOCKET -#include "websocket.hpp" -#endif +#include "rtc.hpp" #include "plog/Formatters/FuncMessageFormatter.h" @@ -359,12 +352,16 @@ int rtcCreatePeerConnection(const rtcConfiguration *config) { for (int i = 0; i < config->iceServersCount; ++i) c.iceServers.emplace_back(string(config->iceServers[i])); - if (config->portRangeBegin || config->portRangeEnd) { + c.enableIceTcp = config->enableIceTcp; + + if (config->portRangeBegin > 0 || config->portRangeEnd > 0) { c.portRangeBegin = config->portRangeBegin; c.portRangeEnd = config->portRangeEnd; } - c.enableIceTcp = config->enableIceTcp; + if(config->mtu > 0) + c.mtu = size_t(config->mtu); + return emplacePeerConnection(std::make_shared(c)); }); } @@ -398,7 +395,7 @@ int rtcAddDataChannelEx(int pc, const char *label, const rtcDataChannelInit *ini dci.reliability.rexmit = milliseconds(reliability->maxPacketLifeTime); } else { dci.reliability.type = Reliability::Type::Rexmit; - dci.reliability.rexmit = int(reliability->maxRetransmits); + dci.reliability.rexmit = reliability->maxRetransmits; } } else { dci.reliability.type = Reliability::Type::Reliable; @@ -447,7 +444,8 @@ int rtcDeleteDataChannel(int dc) { #if RTC_ENABLE_MEDIA -void setSSRC(Description::Media *description, uint32_t ssrc, const char *_name, const char *_msid, const char *_trackID) { +void setSSRC(Description::Media *description, uint32_t ssrc, const char *_name, const char *_msid, + const char *_trackID) { optional name = nullopt; if (_name) { @@ -468,7 +466,8 @@ void setSSRC(Description::Media *description, uint32_t ssrc, const char *_name, } int rtcAddTrackEx(int pc, rtcCodec codec, int payloadType, uint32_t ssrc, const char *_mid, - rtcDirection _direction, const char *_name, const char *_msid, const char *_trackID) { + rtcDirection _direction, const char *_name, const char *_msid, + const char *_trackID) { return wrap([&] { auto peerConnection = getPeerConnection(pc); @@ -545,13 +544,13 @@ int rtcAddTrackEx(int pc, rtcCodec codec, int payloadType, uint32_t ssrc, const } int rtcSetH264PacketizationHandler(int tr, uint32_t ssrc, const char *cname, uint8_t payloadType, - uint32_t clockRate, uint16_t maxFragmentSize, uint16_t sequenceNumber, - uint32_t timestamp) { + uint32_t clockRate, uint16_t maxFragmentSize, + uint16_t sequenceNumber, uint32_t timestamp) { return wrap([&] { auto track = getTrack(tr); // create RTP configuration auto rtpConfig = getNewRtpPacketizationConfig(ssrc, cname, payloadType, clockRate, - sequenceNumber, timestamp); + sequenceNumber, timestamp); // create packetizer auto packetizer = std::make_shared(rtpConfig, maxFragmentSize); // create H264 handler @@ -576,7 +575,7 @@ int rtcSetOpusPacketizationHandler(int tr, uint32_t ssrc, const char *cname, uin auto packetizer = std::make_shared(rtpConfig); // create Opus handler auto opusHandler = std::make_shared(packetizer); - emplaceMediaChainableHandler(opusHandler, tr); + emplaceMediaChainableHandler(opusHandler, tr); emplaceRTPConfig(rtpConfig, tr); // set handler track->setRtcpHandler(opusHandler); @@ -674,7 +673,7 @@ int rtcGetPreviousTrackSenderReportTimestamp(int id, uint32_t *timestamp) { } int rtcSetNeedsToSendRtcpSr(int id) { - return wrap([id]{ + return wrap([id] { auto sender = getRtcpSrReporter(id); sender->setNeedsToReport(); return RTC_ERR_SUCCESS; @@ -1012,10 +1011,10 @@ int rtcGetDataChannelReliability(int dc, rtcReliability *reliability) { reliability->unordered = dcr.unordered; if (dcr.type == Reliability::Type::Timed) { reliability->unreliable = true; - reliability->maxPacketLifeTime = unsigned(std::get(dcr.rexmit).count()); + reliability->maxPacketLifeTime = int(std::get(dcr.rexmit).count()); } else if (dcr.type == Reliability::Type::Rexmit) { reliability->unreliable = true; - reliability->maxRetransmits = unsigned(std::get(dcr.rexmit)); + reliability->maxRetransmits = std::get(dcr.rexmit); } else { reliability->unreliable = false; } diff --git a/src/globals.hpp b/src/globals.hpp index 206cd48..7174428 100644 --- a/src/globals.hpp +++ b/src/globals.hpp @@ -34,7 +34,7 @@ const size_t RECV_QUEUE_LIMIT = 1024 * 1024; // Max per-channel queue size const int THREADPOOL_SIZE = 4; // Number of threads in the global thread pool (>= 2) -const size_t DEFAULT_MTU = 1280; // IPv6 minimum guaranteed MTU +const size_t DEFAULT_MTU = RTC_DEFAULT_MTU; // defined in rtc.h } // namespace rtc diff --git a/src/impl/datachannel.cpp b/src/impl/datachannel.cpp index 87dad1e..e079b78 100644 --- a/src/impl/datachannel.cpp +++ b/src/impl/datachannel.cpp @@ -17,8 +17,8 @@ */ #include "datachannel.hpp" -#include "globals.hpp" #include "common.hpp" +#include "globals.hpp" #include "logcounter.hpp" #include "peerconnection.hpp" #include "sctptransport.hpp" @@ -255,9 +255,8 @@ void DataChannel::incoming(message_ptr message) { } } -NegotiatedDataChannel::NegotiatedDataChannel(std::weak_ptr pc, - uint16_t stream, string label, string protocol, - Reliability reliability) +NegotiatedDataChannel::NegotiatedDataChannel(std::weak_ptr pc, uint16_t stream, + string label, string protocol, Reliability reliability) : DataChannel(pc, stream, std::move(label), std::move(protocol), std::move(reliability)) {} NegotiatedDataChannel::NegotiatedDataChannel(std::weak_ptr pc, @@ -278,7 +277,7 @@ void NegotiatedDataChannel::open(shared_ptr transport) { switch (mReliability->type) { case Reliability::Type::Rexmit: channelType = CHANNEL_PARTIAL_RELIABLE_REXMIT; - reliabilityParameter = uint32_t(std::get(mReliability->rexmit)); + reliabilityParameter = uint32_t(std::max(std::get(mReliability->rexmit), 0)); break; case Reliability::Type::Timed: diff --git a/src/impl/peerconnection.hpp b/src/impl/peerconnection.hpp index a85a5cd..4a030e9 100644 --- a/src/impl/peerconnection.hpp +++ b/src/impl/peerconnection.hpp @@ -19,15 +19,21 @@ #ifndef RTC_IMPL_PEER_CONNECTION_H #define RTC_IMPL_PEER_CONNECTION_H +#include "common.hpp" #include "datachannel.hpp" #include "dtlstransport.hpp" #include "icetransport.hpp" -#include "common.hpp" #include "sctptransport.hpp" #include "track.hpp" #include "rtc/peerconnection.hpp" +#include +#include +#include +#include +#include + namespace rtc::impl { struct PeerConnection : std::enable_shared_from_this { @@ -43,12 +49,12 @@ struct PeerConnection : std::enable_shared_from_this { std::optional localDescription() const; std::optional remoteDescription() const; - std::shared_ptr initIceTransport(); - std::shared_ptr initDtlsTransport(); - std::shared_ptr initSctpTransport(); - std::shared_ptr getIceTransport() const; - std::shared_ptr getDtlsTransport() const; - std::shared_ptr getSctpTransport() const; + shared_ptr initIceTransport(); + shared_ptr initDtlsTransport(); + shared_ptr initSctpTransport(); + shared_ptr getIceTransport() const; + shared_ptr getDtlsTransport() const; + shared_ptr getSctpTransport() const; void closeTransports(); void endLocalCandidates(); @@ -63,7 +69,7 @@ struct PeerConnection : std::enable_shared_from_this { DataChannelInit init); shared_ptr findDataChannel(uint16_t stream); void shiftDataChannels(); - void iterateDataChannels(std::function channel)> func); + void iterateDataChannels(std::function channel)> func); void openDataChannels(); void closeDataChannels(); void remoteCloseDataChannels(); @@ -80,7 +86,7 @@ struct PeerConnection : std::enable_shared_from_this { string localBundleMid() const; void triggerDataChannel(std::weak_ptr weakDataChannel); - void triggerTrack(std::shared_ptr track); + void triggerTrack(shared_ptr track); bool changeState(State newState); bool changeGatheringState(GatheringState newState); bool changeSignalingState(SignalingState newState); @@ -95,26 +101,26 @@ struct PeerConnection : std::enable_shared_from_this { std::atomic signalingState = SignalingState::Stable; std::atomic negotiationNeeded = false; - synchronized_callback> dataChannelCallback; + synchronized_callback> dataChannelCallback; synchronized_callback localDescriptionCallback; synchronized_callback localCandidateCallback; synchronized_callback stateChangeCallback; synchronized_callback gatheringStateChangeCallback; synchronized_callback signalingStateChangeCallback; - synchronized_callback> trackCallback; + synchronized_callback> trackCallback; private: const init_token mInitToken = Init::Token(); const future_certificate_ptr mCertificate; - const std::unique_ptr mProcessor; + const unique_ptr mProcessor; std::optional mLocalDescription, mRemoteDescription; std::optional mCurrentLocalDescription; mutable std::mutex mLocalDescriptionMutex, mRemoteDescriptionMutex; - std::shared_ptr mIceTransport; - std::shared_ptr mDtlsTransport; - std::shared_ptr mSctpTransport; + shared_ptr mIceTransport; + shared_ptr mDtlsTransport; + shared_ptr mSctpTransport; std::unordered_map> mDataChannels; // by stream ID std::unordered_map> mTracks; // by mid diff --git a/src/nalunit.cpp b/src/nalunit.cpp index 0745efd..92d3976 100644 --- a/src/nalunit.cpp +++ b/src/nalunit.cpp @@ -92,8 +92,6 @@ void NalUnitFragmentA::setFragmentType(FragmentType type) { } } -const uint16_t NalUnits::defaultMaximumFragmentSize = DEFAULT_MTU - 12 - 8 - 40; // SRTP/UDP/IPv6 - std::vector> NalUnits::generateFragments(uint16_t maximumFragmentSize) { vector> result{}; for (auto nalu : *this) {