call: add media transport information

https://git.jami.net/savoirfairelinux/jami-client-qt/-/issues/510#510

Change-Id: Ie09ebd95ba161559c5c08b7e0618d6e87ecca1ee
This commit is contained in:
Nicolas Vengeon
2022-10-25 17:38:13 -04:00
committed by Sébastien Blin
parent a834804c4d
commit 412c301f98
5 changed files with 125 additions and 11 deletions

View File

@ -60,6 +60,10 @@ constexpr static char VIDEO_SOURCE[] = "VIDEO_SOURCE";
constexpr static char AUDIO_ONLY[] = "AUDIO_ONLY";
constexpr static char AUDIO_CODEC[] = "AUDIO_CODEC";
constexpr static char VIDEO_CODEC[] = "VIDEO_CODEC";
constexpr static char SOCKETS[] = "SOCKETS";
constexpr static char VIDEO_MIN_BITRATE[] = "VIDEO_MIN_BITRATE";
constexpr static char VIDEO_BITRATE[] = "VIDEO_BITRATE";
constexpr static char VIDEO_MAX_BITRATE[] = "VIDEO_MAX_BITRATE";
} // namespace Details

View File

@ -78,6 +78,12 @@ VideoRtpSession::~VideoRtpSession()
JAMI_DBG("[%p] Video RTP session destroyed", this);
}
const VideoBitrateInfo&
VideoRtpSession::getVideoBitrateInfo()
{
return videoBitrateInfo_;
}
/// Setup internal VideoBitrateInfo structure from media descriptors.
///
void

View File

@ -100,6 +100,8 @@ public:
void initRecorder(std::shared_ptr<MediaRecorder>& rec) override;
void deinitRecorder(std::shared_ptr<MediaRecorder>& rec) override;
const VideoBitrateInfo& getVideoBitrateInfo();
bool hasConference() { return conference_; }
std::shared_ptr<VideoInput>& getVideoLocal() { return videoLocal_; }

View File

@ -2977,19 +2977,39 @@ SIPCall::getDetails() const
details.emplace(libjami::Call::Details::PEER_HOLDING, peerHolding_ ? TRUE_STR : FALSE_STR);
#ifdef ENABLE_VIDEO
for (auto const& stream : rtpStreams_) {
if (stream.mediaAttribute_->type_ != MediaType::MEDIA_VIDEO)
continue;
details.emplace(libjami::Call::Details::VIDEO_SOURCE, stream.mediaAttribute_->sourceUri_);
if (auto const& rtpSession = stream.rtpSession_) {
if (auto codec = rtpSession->getCodec())
details.emplace(libjami::Call::Details::VIDEO_CODEC, codec->systemCodecInfo.name);
else
details.emplace(libjami::Call::Details::VIDEO_CODEC, "");
if (stream.mediaAttribute_->type_ == MediaType::MEDIA_VIDEO) {
details.emplace(libjami::Call::Details::VIDEO_SOURCE,
stream.mediaAttribute_->sourceUri_);
if (auto const& rtpSession = stream.rtpSession_) {
if (auto codec = rtpSession->getCodec()) {
details.emplace(libjami::Call::Details::VIDEO_CODEC,
codec->systemCodecInfo.name);
details.emplace(libjami::Call::Details::VIDEO_MIN_BITRATE,
std::to_string(codec->systemCodecInfo.minBitrate));
details.emplace(libjami::Call::Details::VIDEO_MAX_BITRATE,
std::to_string(codec->systemCodecInfo.maxBitrate));
const auto& curvideoRtpSession
= std::static_pointer_cast<video::VideoRtpSession>(rtpSession);
if (curvideoRtpSession) {
auto curBitrate = curvideoRtpSession->getVideoBitrateInfo()
.videoBitrateCurrent;
details.emplace(libjami::Call::Details::VIDEO_BITRATE,
std::to_string(curBitrate));
}
} else
details.emplace(libjami::Call::Details::VIDEO_CODEC, "");
}
} else if (stream.mediaAttribute_->type_ == MediaType::MEDIA_AUDIO) {
if (auto const& rtpSession = stream.rtpSession_) {
if (auto codec = rtpSession->getCodec()) {
details.emplace(libjami::Call::Details::AUDIO_CODEC,
codec->systemCodecInfo.name);
} else
details.emplace(libjami::Call::Details::AUDIO_CODEC, "");
}
}
}
#endif
#if HAVE_RINGNS
if (not peerRegisteredName_.empty())
@ -3023,6 +3043,10 @@ SIPCall::getDetails() const
}
}
#endif
if (auto transport = getIceMedia()) {
if (transport && transport->isRunning())
details.emplace(libjami::Call::Details::SOCKETS, transport->link().c_str());
}
return details;
}

View File

@ -32,10 +32,12 @@
#include "../../test_runner.h"
#include "jami.h"
#include "account_const.h"
#include "media_const.h"
#include "call_const.h"
#include "common.h"
using namespace libjami::Account;
using namespace libjami::Call::Details;
namespace jami {
namespace test {
@ -65,6 +67,7 @@ private:
void testStopSearching();
void testDeclineMultiDevice();
void testTlsInfosPeerCertificate();
void testSocketInfos();
CPPUNIT_TEST_SUITE(CallTest);
CPPUNIT_TEST(testCall);
@ -72,6 +75,7 @@ private:
CPPUNIT_TEST(testStopSearching);
CPPUNIT_TEST(testDeclineMultiDevice);
CPPUNIT_TEST(testTlsInfosPeerCertificate);
CPPUNIT_TEST(testSocketInfos);
CPPUNIT_TEST_SUITE_END();
};
@ -359,6 +363,80 @@ CallTest::testTlsInfosPeerCertificate()
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&] { return callStopped == 2; }));
}
void
CallTest::testSocketInfos()
{
auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
auto bobUri = bobAccount->getUsername();
auto aliceUri = aliceAccount->getUsername();
std::mutex mtx;
std::unique_lock<std::mutex> lk {mtx};
std::condition_variable cv;
std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> confHandlers;
std::atomic<int> callStopped {0};
std::string bobCallId;
std::string aliceCallState;
// Watch signals
confHandlers.insert(libjami::exportable_callback<libjami::CallSignal::IncomingCallWithMedia>(
[&](const std::string& accountId,
const std::string& callId,
const std::string&,
const std::vector<std::map<std::string, std::string>>&) {
if (accountId == bobId)
bobCallId = callId;
cv.notify_one();
}));
confHandlers.insert(libjami::exportable_callback<libjami::CallSignal::StateChange>(
[&](const std::string& accountId, const std::string&, const std::string& state, signed) {
if (accountId == aliceId)
aliceCallState = state;
if (state == "OVER") {
callStopped += 1;
if (callStopped == 2)
cv.notify_one();
}
}));
auto mediaReady = false;
confHandlers.insert(libjami::exportable_callback<libjami::CallSignal::MediaNegotiationStatus>(
[&](const std::string& callId,
const std::string& event,
const std::vector<std::map<std::string, std::string>>&) {
if (event == libjami::Media::MediaNegotiationStatusEvents::NEGOTIATION_SUCCESS) {
mediaReady = true;
cv.notify_one();
}
}));
libjami::registerSignalHandlers(confHandlers);
JAMI_INFO("Start call between alice and Bob");
auto callId = libjami::placeCallWithMedia(aliceId, bobUri, {});
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&] { return !bobCallId.empty(); }));
Manager::instance().answerCall(bobId, bobCallId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&] {
return aliceCallState == "CURRENT" && mediaReady;
}));
JAMI_INFO("Detail debug");
auto details = libjami::getCallDetails(aliceId, callId);
for (auto i = details.begin(); i != details.end(); i++) {
JAMI_INFO("%s : %s", i->first.c_str(), i->second.c_str());
}
auto call = std::dynamic_pointer_cast<SIPCall>(aliceAccount->getCall(callId));
auto transport = call->getIceMedia();
CPPUNIT_ASSERT(transport);
CPPUNIT_ASSERT(transport->isRunning());
CPPUNIT_ASSERT(transport->link().c_str() == details[libjami::Call::Details::SOCKETS]);
JAMI_INFO("Stop call between alice and Bob");
callStopped = 0;
Manager::instance().hangupCall(aliceId, callId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&] { return callStopped == 2; }));
}
} // namespace test
} // namespace jami