#define MS_CLASS "RTC::RtpEncodingParameters"
#include "Logger.hpp"
#include "MediaSoupErrors.hpp"
#include "Utils.hpp"
#include "RTC/RtpDictionaries.hpp"
#include <exception>
#include <regex>
namespace RTC
{
RtpEncodingParameters::RtpEncodingParameters(json& data)
{
MS_TRACE();
if (!data.is_object())
MS_THROW_TYPE_ERROR("data is not an object");
auto jsonSsrcIt = data.find("ssrc");
auto jsonRidIt = data.find("rid");
auto jsonCodecPayloadTypeIt = data.find("codecPayloadType");
auto jsonRtxIt = data.find("rtx");
auto jsonMaxBitrateIt = data.find("maxBitrate");
auto jsonMaxFramerateIt = data.find("maxFramerate");
auto jsonDtxIt = data.find("dtx");
auto jsonScalabilityModeIt = data.find("scalabilityMode");
if (
jsonSsrcIt != data.end() &&
Utils::Json::IsPositiveInteger(*jsonSsrcIt)
)
{
this->ssrc = jsonSsrcIt->get<uint32_t>();
}
if (jsonRidIt != data.end() && jsonRidIt->is_string())
this->rid = jsonRidIt->get<std::string>();
if (
jsonCodecPayloadTypeIt != data.end() &&
Utils::Json::IsPositiveInteger(*jsonCodecPayloadTypeIt)
)
{
this->codecPayloadType = jsonCodecPayloadTypeIt->get<uint8_t>();
this->hasCodecPayloadType = true;
}
if (jsonRtxIt != data.end() && jsonRtxIt->is_object())
{
this->rtx = RtpRtxParameters(*jsonRtxIt);
this->hasRtx = true;
}
if (
jsonMaxBitrateIt != data.end() &&
Utils::Json::IsPositiveInteger(*jsonMaxBitrateIt)
)
{
this->maxBitrate = jsonMaxBitrateIt->get<uint32_t>();
}
if (jsonMaxFramerateIt != data.end() && jsonMaxFramerateIt->is_number())
this->maxFramerate = jsonMaxFramerateIt->get<double>();
if (jsonDtxIt != data.end() && jsonDtxIt->is_boolean())
this->dtx = jsonDtxIt->get<bool>();
if (jsonScalabilityModeIt != data.end() && jsonScalabilityModeIt->is_string())
{
std::string scalabilityMode = jsonScalabilityModeIt->get<std::string>();
static const std::regex ScalabilityModeRegex(
"^[LS]([1-9]\\d{0,1})T([1-9]\\d{0,1})(_KEY)?.*", std::regex_constants::ECMAScript);
std::smatch match;
std::regex_match(scalabilityMode, match, ScalabilityModeRegex);
if (!match.empty())
{
this->scalabilityMode = scalabilityMode;
try
{
this->spatialLayers = std::stoul(match[1].str());
this->temporalLayers = std::stoul(match[2].str());
this->ksvc = match.size() >= 4 && match[3].str() == "_KEY";
}
catch (std::exception& e)
{
MS_THROW_TYPE_ERROR("invalid scalabilityMode: %s", e.what());
}
}
}
}
void RtpEncodingParameters::FillJson(json& jsonObject) const
{
MS_TRACE();
jsonObject = json::object();
if (this->ssrc != 0u)
jsonObject["ssrc"] = this->ssrc;
if (!this->rid.empty())
jsonObject["rid"] = this->rid;
if (this->hasCodecPayloadType)
jsonObject["codecPayloadType"] = this->codecPayloadType;
if (this->hasRtx)
this->rtx.FillJson(jsonObject["rtx"]);
if (this->maxBitrate != 0u)
jsonObject["maxBitrate"] = this->maxBitrate;
if (this->maxFramerate > 0)
jsonObject["maxFramerate"] = this->maxFramerate;
if (this->dtx)
jsonObject["dtx"] = this->dtx;
if (!this->scalabilityMode.empty())
{
jsonObject["scalabilityMode"] = this->scalabilityMode;
jsonObject["spatialLayers"] = this->spatialLayers;
jsonObject["temporalLayers"] = this->temporalLayers;
jsonObject["ksvc"] = this->ksvc;
}
}
}