multiplex: Add new function for creating media streams in session
This commit is contained in:
parent
a8fc623f5a
commit
f21ac16d4d
|
@ -62,6 +62,39 @@ namespace uvgrtp {
|
|||
*/
|
||||
uvgrtp::media_stream *create_stream(uint16_t src_port, uint16_t dst_port, rtp_format_t fmt, int rce_flags);
|
||||
|
||||
/**
|
||||
* \brief Create a uni- or bidirectional media stream
|
||||
*
|
||||
* \details
|
||||
*
|
||||
* The created object is used for sending and/or receiving media, see documentation
|
||||
* for uvgrtp::media_stream for more details.
|
||||
*
|
||||
* If both addresses were provided when uvgrtp::session was created, by default
|
||||
* uvgRTP binds itself to local_addr:src_port and sends packets to remote_addr:dst_port.
|
||||
*
|
||||
* User can enable and disable functionality of media_stream by OR'ing (using |) RCE_* flags
|
||||
* together and passing them using the rce_flags parameter. In rce_flags, the RCE_SEND_ONLY flag
|
||||
* can be used to avoid binding and src_port is thus ignored. Correspondinly RCE_RECEIVE_ONLY flag
|
||||
* means dst_port is ignored. Without either RCE_SEND_ONLY or RCE_RECEIVE_ONLY,
|
||||
* and if only one address was provided for session that address is interpreted as remote_addr and
|
||||
* binding happens to ANY:src_port.
|
||||
*
|
||||
* \param remote_port Remote port where uvgRTP sends RTP packets
|
||||
* \param local_port Local port that uvgRTP listens to for incoming RTP packets
|
||||
* \param fmt Format of the media stream. see ::RTP_FORMAT for more details
|
||||
* \param rce_flags RTP context enable flags, see ::RTP_CTX_ENABLE_FLAGS for more details
|
||||
* \param remote_ssrc Remote SSRC that this stream will receive packets from
|
||||
* \param local_ssrc Local SSRC that will be present in packets that ´this stream sends
|
||||
*
|
||||
* \return RTP media stream object
|
||||
*
|
||||
* \retval uvgrtp::media_stream* On success
|
||||
* \retval nullptr On failure, see print and
|
||||
*/
|
||||
uvgrtp::media_stream* create_stream(uint16_t remote_port, uint16_t local_port, rtp_format_t fmt, int rce_flags,
|
||||
uint32_t remote_ssrc, uint32_t local_ssrc);
|
||||
|
||||
/**
|
||||
* \brief Create a unidirectional media_stream for an RTP session
|
||||
*
|
||||
|
|
125
src/session.cc
125
src/session.cc
|
@ -179,6 +179,131 @@ uvgrtp::media_stream* uvgrtp::session::create_stream(uint16_t src_port, uint16_t
|
|||
return stream;
|
||||
}
|
||||
|
||||
uvgrtp::media_stream* uvgrtp::session::create_stream(uint16_t remote_port, uint16_t local_port, rtp_format_t fmt, int rce_flags,
|
||||
uint32_t remote_ssrc, uint32_t local_ssrc)
|
||||
{
|
||||
if (rce_flags & RCE_OBSOLETE) {
|
||||
UVG_LOG_WARN("You are using a flag that has either been removed or has been enabled by default. Consider updating RCE flags");
|
||||
}
|
||||
|
||||
if ((rce_flags & RCE_SEND_ONLY) && (rce_flags & RCE_RECEIVE_ONLY)) {
|
||||
UVG_LOG_ERROR("Cannot both use RCE_SEND_ONLY and RCE_RECEIVE_ONLY!");
|
||||
rtp_errno = RTP_NOT_SUPPORTED;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// select which address the one address we got as a parameter is
|
||||
if (generic_address_ != "")
|
||||
{
|
||||
if (rce_flags & RCE_RECEIVE_ONLY)
|
||||
{
|
||||
local_address_ = generic_address_;
|
||||
}
|
||||
else
|
||||
{
|
||||
remote_address_ = generic_address_;
|
||||
}
|
||||
}
|
||||
else if ((rce_flags & RCE_RECEIVE_ONLY) && local_address_ == "")
|
||||
{
|
||||
UVG_LOG_ERROR("RCE_RECEIVE_ONLY requires local address!");
|
||||
rtp_errno = RTP_INVALID_VALUE;
|
||||
return nullptr;
|
||||
}
|
||||
else if ((rce_flags & RCE_SEND_ONLY) && remote_address_ == "")
|
||||
{
|
||||
UVG_LOG_ERROR("RCE_SEND_ONLY requires remote address!");
|
||||
rtp_errno = RTP_INVALID_VALUE;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ((rce_flags & RCE_RECEIVE_ONLY) && local_port == 0)
|
||||
{
|
||||
UVG_LOG_ERROR("RCE_RECEIVE_ONLY requires source port!");
|
||||
rtp_errno = RTP_INVALID_VALUE;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ((rce_flags & RCE_SEND_ONLY) && remote_port == 0)
|
||||
{
|
||||
UVG_LOG_ERROR("RCE_SEND_ONLY requires destination port!");
|
||||
rtp_errno = RTP_INVALID_VALUE;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uvgrtp::media_stream* stream =
|
||||
new uvgrtp::media_stream(cname_, remote_address_, local_address_, local_port, remote_port, fmt, sf_, rce_flags);
|
||||
|
||||
stream->configure_ctx(RCC_SSRC, local_ssrc);
|
||||
stream->configure_ctx(RCC_REMOTE_SSRC, remote_ssrc);
|
||||
|
||||
if (rce_flags & RCE_SRTP) {
|
||||
if (!uvgrtp::crypto::enabled()) {
|
||||
UVG_LOG_ERROR("Recompile uvgRTP with -D__RTP_CRYPTO__");
|
||||
delete stream;
|
||||
rtp_errno = RTP_GENERIC_ERROR;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (rce_flags & RCE_SRTP_REPLAY_PROTECTION)
|
||||
rce_flags |= RCE_SRTP_AUTHENTICATE_RTP;
|
||||
|
||||
if (rce_flags & RCE_SRTP_KMNGMNT_ZRTP) {
|
||||
|
||||
if (rce_flags & (RCE_SRTP_KEYSIZE_192 | RCE_SRTP_KEYSIZE_256)) {
|
||||
UVG_LOG_ERROR("Only 128-bit keys are supported with ZRTP");
|
||||
delete stream;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!(rce_flags & RCE_ZRTP_DIFFIE_HELLMAN_MODE) &&
|
||||
!(rce_flags & RCE_ZRTP_MULTISTREAM_MODE)) {
|
||||
UVG_LOG_INFO("ZRTP mode not selected, using Diffie-Hellman mode");
|
||||
rce_flags |= RCE_ZRTP_DIFFIE_HELLMAN_MODE;
|
||||
}
|
||||
|
||||
session_mtx_.lock();
|
||||
if (!zrtp_) {
|
||||
zrtp_ = std::shared_ptr<uvgrtp::zrtp>(new uvgrtp::zrtp());
|
||||
}
|
||||
session_mtx_.unlock();
|
||||
|
||||
if (stream->init(zrtp_) != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to initialize media stream %s:%d/%d", remote_address_.c_str(), local_port, remote_port);
|
||||
delete stream;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else if (rce_flags & RCE_SRTP_KMNGMNT_USER) {
|
||||
UVG_LOG_DEBUG("SRTP with user-managed keys enabled, postpone initialization");
|
||||
if (stream->init() != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to initialize media stream %s:%d/%d", remote_address_.c_str(), local_port, remote_port);
|
||||
delete stream;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
UVG_LOG_ERROR("SRTP key management scheme not specified!");
|
||||
rtp_errno = RTP_INVALID_VALUE;
|
||||
delete stream;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (stream->init() != RTP_OK) {
|
||||
UVG_LOG_ERROR("Failed to initialize media stream %s:%d/%d", remote_address_.c_str(), local_port, remote_port);
|
||||
delete stream;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
session_mtx_.lock();
|
||||
streams_.insert(std::make_pair(stream->get_key(), stream));
|
||||
session_mtx_.unlock();
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
rtp_error_t uvgrtp::session::destroy_stream(uvgrtp::media_stream *stream)
|
||||
{
|
||||
if (!stream)
|
||||
|
|
Loading…
Reference in New Issue