Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

M120 #173

Merged
merged 11 commits into from
Jun 19, 2024
Merged

M120 #173

Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ configure_file (
)

# C++ standard requirements.
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Project options.
Expand Down
2 changes: 1 addition & 1 deletion include/Handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ namespace mediasoupclient
// Got transport local and remote parameters.
bool transportReady{ false };
// Map of RTCTransceivers indexed by MID.
std::unordered_map<std::string, webrtc::RtpTransceiverInterface*> mapMidTransceiver{};
std::unordered_map<std::string, rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> mapMidTransceiver{};
// PeerConnection instance.
std::unique_ptr<PeerConnection> pc{ nullptr };
bool hasDataChannelMediaSection = false;
Expand Down
36 changes: 35 additions & 1 deletion include/PeerConnection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,40 @@ namespace mediasoupclient
void OnInterestingUsage(int usagePattern) override;
};

class SetLocalDescriptionObserver : public webrtc::SetLocalDescriptionObserverInterface
{
public:
SetLocalDescriptionObserver() = default;
~SetLocalDescriptionObserver() override = default;

std::future<void> GetFuture();
void Reject(const std::string& error);

/* Virtual methods inherited from webrtc::SetLocalDescriptionObserver. */
public:
void OnSetLocalDescriptionComplete(webrtc::RTCError error) override;

private:
std::promise<void> promise;
};

class SetRemoteDescriptionObserver : public webrtc::SetRemoteDescriptionObserverInterface
{
public:
SetRemoteDescriptionObserver() = default;
~SetRemoteDescriptionObserver() override = default;

std::future<void> GetFuture();
void Reject(const std::string& error);

/* Virtual methods inherited from webrtc::SetRemoteDescriptionObserver. */
public:
void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override;

private:
std::promise<void> promise;
};

class SetSessionDescriptionObserver : public webrtc::SetSessionDescriptionObserver
{
public:
Expand Down Expand Up @@ -126,7 +160,7 @@ namespace mediasoupclient
rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
webrtc::RtpTransceiverInit rtpTransceiverInit);
std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> GetSenders();
bool RemoveTrack(webrtc::RtpSenderInterface* sender);
bool RemoveTrack(rtc::scoped_refptr<webrtc::RtpSenderInterface> sender);
nlohmann::json GetStats();
nlohmann::json GetStats(rtc::scoped_refptr<webrtc::RtpSenderInterface> selector);
nlohmann::json GetStats(rtc::scoped_refptr<webrtc::RtpReceiverInterface> selector);
Expand Down
19 changes: 10 additions & 9 deletions src/Handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ namespace mediasoupclient
if (encodings && !encodings->empty())
transceiverInit.send_encodings = *encodings;

webrtc::RtpTransceiverInterface* transceiver = this->pc->AddTransceiver(track, transceiverInit);
rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> scopedTrack{ track };
auto transceiver = this->pc->AddTransceiver(scopedTrack, transceiverInit);

if (!transceiver)
MSC_THROW_ERROR("error creating transceiver");
Expand Down Expand Up @@ -359,7 +360,7 @@ namespace mediasoupclient
SendResult sendResult;

sendResult.localId = localId;
sendResult.rtpSender = transceiver->sender();
sendResult.rtpSender = transceiver->sender().get();
sendResult.rtpParameters = sendingRtpParameters;

return sendResult;
Expand Down Expand Up @@ -461,7 +462,7 @@ namespace mediasoupclient
if (locaIdIt == this->mapMidTransceiver.end())
MSC_THROW_ERROR("associated RtpTransceiver not found");

auto* transceiver = locaIdIt->second;
auto transceiver = locaIdIt->second;
jmillan marked this conversation as resolved.
Show resolved Hide resolved

transceiver->sender()->SetTrack(nullptr);
this->pc->RemoveTrack(transceiver->sender());
Expand Down Expand Up @@ -500,7 +501,7 @@ namespace mediasoupclient
if (localIdIt == this->mapMidTransceiver.end())
MSC_THROW_ERROR("associated RtpTransceiver not found");

auto* transceiver = localIdIt->second;
auto transceiver = localIdIt->second;

transceiver->sender()->SetTrack(track);
}
Expand All @@ -516,7 +517,7 @@ namespace mediasoupclient
if (localIdIt == this->mapMidTransceiver.end())
MSC_THROW_ERROR("associated RtpTransceiver not found");

auto* transceiver = localIdIt->second;
auto transceiver = localIdIt->second;
auto parameters = transceiver->sender()->GetParameters();

bool hasLowEncoding{ false };
Expand Down Expand Up @@ -583,7 +584,7 @@ namespace mediasoupclient
if (localIdIt == this->mapMidTransceiver.end())
MSC_THROW_ERROR("associated RtpTransceiver not found");

auto* transceiver = localIdIt->second;
auto transceiver = localIdIt->second;
auto stats = this->pc->GetStats(transceiver->sender());

return stats;
Expand Down Expand Up @@ -690,7 +691,7 @@ namespace mediasoupclient

auto transceivers = this->pc->GetTransceivers();
auto transceiverIt = std::find_if(
transceivers.begin(), transceivers.end(), [&localId](webrtc::RtpTransceiverInterface* t) {
transceivers.begin(), transceivers.end(), [&localId](rtc::scoped_refptr<webrtc::RtpTransceiverInterface> t) {
return t->mid() == localId;
});

Expand All @@ -705,8 +706,8 @@ namespace mediasoupclient
RecvResult recvResult;

recvResult.localId = localId;
recvResult.rtpReceiver = transceiver->receiver();
recvResult.track = transceiver->receiver()->track();
recvResult.rtpReceiver = transceiver->receiver().get();
recvResult.track = transceiver->receiver()->track().get();

return recvResult;
}
Expand Down
118 changes: 98 additions & 20 deletions src/PeerConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ namespace mediasoupclient

this->peerConnectionFactory = webrtc::CreatePeerConnectionFactory(
this->networkThread.get(),
this->workerThread.get(),
// TMP: Use the same thread for signaling and worker.
// this->workerThread.get(),
this->signalingThread.get(),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also want to note that this looks extremely sketchy. If LibWebRTC truly wanted you to use signaling thread as both worker and signaling, they'd do so in other ways (such as taking only 2 pointers).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, this is a temporal work around that needs to be removed.

this->signalingThread.get(),
nullptr /*default_adm*/,
webrtc::CreateBuiltinAudioEncoderFactory(),
Expand Down Expand Up @@ -138,7 +140,7 @@ namespace mediasoupclient

MSC_WARN(
"webrtc::PeerConnection::SetConfiguration failed [%s:%s]",
webrtc::ToString(error.type()),
webrtc::ToString(error.type()).data(),
error.message());

return false;
Expand Down Expand Up @@ -179,14 +181,14 @@ namespace mediasoupclient
MSC_TRACE();

webrtc::SdpParseError error;
webrtc::SessionDescriptionInterface* sessionDescription;
rtc::scoped_refptr<SetSessionDescriptionObserver> observer(
new rtc::RefCountedObject<SetSessionDescriptionObserver>());
std::unique_ptr<webrtc::SessionDescriptionInterface> sessionDescription;
rtc::scoped_refptr<SetLocalDescriptionObserver> observer(
new rtc::RefCountedObject<SetLocalDescriptionObserver>());

const auto& typeStr = sdpType2String[type];
auto future = observer->GetFuture();

sessionDescription = webrtc::CreateSessionDescription(typeStr, sdp, &error);
sessionDescription.reset(webrtc::CreateSessionDescription(typeStr, sdp, &error));
if (sessionDescription == nullptr)
{
MSC_WARN(
Expand All @@ -199,7 +201,7 @@ namespace mediasoupclient
return future.get();
}

this->pc->SetLocalDescription(observer, sessionDescription);
this->pc->SetLocalDescription(std::move(sessionDescription), observer);

return future.get();
}
Expand All @@ -209,14 +211,14 @@ namespace mediasoupclient
MSC_TRACE();

webrtc::SdpParseError error;
webrtc::SessionDescriptionInterface* sessionDescription;
rtc::scoped_refptr<SetSessionDescriptionObserver> observer(
new rtc::RefCountedObject<SetSessionDescriptionObserver>());
std::unique_ptr<webrtc::SessionDescriptionInterface> sessionDescription;
rtc::scoped_refptr<SetRemoteDescriptionObserver> observer(
new rtc::RefCountedObject<SetRemoteDescriptionObserver>());

const auto& typeStr = sdpType2String[type];
auto future = observer->GetFuture();

sessionDescription = webrtc::CreateSessionDescription(typeStr, sdp, &error);
sessionDescription.reset(webrtc::CreateSessionDescription(typeStr, sdp, &error));
if (sessionDescription == nullptr)
{
MSC_WARN(
Expand All @@ -229,7 +231,7 @@ namespace mediasoupclient
return future.get();
}

this->pc->SetRemoteDescription(observer, sessionDescription);
this->pc->SetRemoteDescription(std::move(sessionDescription), observer);

return future.get();
}
Expand Down Expand Up @@ -317,11 +319,13 @@ namespace mediasoupclient
return this->pc->GetSenders();
}

bool PeerConnection::RemoveTrack(webrtc::RtpSenderInterface* sender)
bool PeerConnection::RemoveTrack(rtc::scoped_refptr<webrtc::RtpSenderInterface> sender)
{
MSC_TRACE();

return this->pc->RemoveTrack(sender);
const auto result = this->pc->RemoveTrackOrError(sender);

return result.ok();
}

json PeerConnection::GetStats()
Expand Down Expand Up @@ -371,10 +375,10 @@ namespace mediasoupclient
{
MSC_TRACE();

rtc::scoped_refptr<webrtc::DataChannelInterface> webrtcDataChannel =
this->pc->CreateDataChannel(label, config);
const auto result =
this->pc->CreateDataChannelOrError(label, config);

if (webrtcDataChannel.get())
if (result.ok())
{
MSC_DEBUG("Success creating data channel");
}
Expand All @@ -383,9 +387,83 @@ namespace mediasoupclient
MSC_THROW_ERROR("Failed creating data channel");
}

return webrtcDataChannel;
return result.value();
}

/* SetLocalDescriptionObserver */

std::future<void> PeerConnection::SetLocalDescriptionObserver::GetFuture()
{
MSC_TRACE();

return this->promise.get_future();
}

void PeerConnection::SetLocalDescriptionObserver::Reject(const std::string& error)
{
MSC_TRACE();

this->promise.set_exception(std::make_exception_ptr(MediaSoupClientError(error.c_str())));
}

void PeerConnection::SetLocalDescriptionObserver::OnSetLocalDescriptionComplete(webrtc::RTCError error)
{
MSC_TRACE();

if (!error.ok())
{
MSC_WARN(
"webtc::SetLocalDescriptionObserver failure [%s:%s]",
webrtc::ToString(error.type()).data(),
error.message());

auto message = std::string(error.message());

this->Reject(message);
}
else
{
this->promise.set_value();
}
};

/* SetRemoteDescriptionObserver */

std::future<void> PeerConnection::SetRemoteDescriptionObserver::GetFuture()
{
MSC_TRACE();

return this->promise.get_future();
}

void PeerConnection::SetRemoteDescriptionObserver::Reject(const std::string& error)
{
MSC_TRACE();

this->promise.set_exception(std::make_exception_ptr(MediaSoupClientError(error.c_str())));
}

void PeerConnection::SetRemoteDescriptionObserver::OnSetRemoteDescriptionComplete(webrtc::RTCError error)
{
MSC_TRACE();

if (!error.ok())
{
MSC_WARN(
"webtc::SetRemoteDescriptionObserver failure [%s:%s]",
webrtc::ToString(error.type()).data(),
error.message());

auto message = std::string(error.message());

this->Reject(message);
}
else
{
this->promise.set_value();
}
};

/* SetSessionDescriptionObserver */

std::future<void> PeerConnection::SetSessionDescriptionObserver::GetFuture()
Expand Down Expand Up @@ -415,7 +493,7 @@ namespace mediasoupclient

MSC_WARN(
"webtc::SetSessionDescriptionObserver failure [%s:%s]",
webrtc::ToString(error.type()),
webrtc::ToString(error.type()).data(),
error.message());

auto message = std::string(error.message());
Expand Down Expand Up @@ -459,7 +537,7 @@ namespace mediasoupclient

MSC_WARN(
"webtc::CreateSessionDescriptionObserver failure [%s:%s]",
webrtc::ToString(error.type()),
webrtc::ToString(error.type()).data(),
error.message());

auto message = std::string(error.message());
Expand Down
14 changes: 7 additions & 7 deletions src/sdp/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,29 +256,29 @@ namespace mediasoupclient
{
auto& ssrcGroups = *jsonSsrcGroupsIt;

std::find_if(
jmillan marked this conversation as resolved.
Show resolved Hide resolved
ssrcGroups.begin(), ssrcGroups.end(), [&firstSsrc, &firstRtxSsrc](const json& line) {
for (const auto& line : ssrcGroups)
{
auto jsonSemanticsIt = line.find("semantics");

if (jsonSemanticsIt == line.end() || !jsonSemanticsIt->is_string())
return false;
continue;

auto jsonSsrcsIt = line.find("ssrcs");

if (jsonSsrcsIt == line.end() || !jsonSsrcsIt->is_string())
return false;
continue;

auto v = mediasoupclient::Utils::split(jsonSsrcsIt->get<std::string>(), ' ');

if (std::stoull(v[0]) == firstSsrc)
{
firstRtxSsrc = std::stoull(v[1]);

return true;
break;
}

return false;
});
continue;
};
}

jsonSsrcIt = std::find_if(mSsrcs.begin(), mSsrcs.end(), [](const json& line) {
Expand Down
4 changes: 4 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,8 @@ add_subdirectory(deps/libwebrtc "${CMAKE_CURRENT_BINARY_DIR}/libwebrtc")
# Public (interface) dependencies.
target_link_libraries(test_mediasoupclient PUBLIC
webrtc
${LIBWEBRTC_BINARY_PATH}/api/video_codecs/libbuiltin_video_encoder_factory${CMAKE_STATIC_LIBRARY_SUFFIX}
${LIBWEBRTC_BINARY_PATH}/api/video_codecs/libbuiltin_video_decoder_factory${CMAKE_STATIC_LIBRARY_SUFFIX}
${LIBWEBRTC_BINARY_PATH}/media/librtc_simulcast_encoder_adapter${CMAKE_STATIC_LIBRARY_SUFFIX}
${LIBWEBRTC_BINARY_PATH}/media/librtc_internal_video_codecs${CMAKE_STATIC_LIBRARY_SUFFIX}
)