- fixes from pvqa_pcap

This commit is contained in:
2024-12-23 17:39:45 +03:00
parent bf2d513080
commit 4ba1ea7fa2
7 changed files with 313 additions and 186 deletions
+217 -120
View File
@@ -25,33 +25,95 @@ using namespace MT;
using strx = strx;
// ---------------- EvsSpec ---------------
bool CodecList::Settings::contains(int ptype) const
{
if (ptype >= 0 && ptype < 96)
return true;
if (mAmrNbOctetPayloadType.contains(ptype))
return true;
if (mAmrNbPayloadType.contains(ptype))
return true;
if (mAmrWbOctetPayloadType.contains(ptype))
return true;
if (mAmrWbPayloadType.contains(ptype))
return true;
for (const auto& s: mOpusSpec)
if (s.mPayloadType == ptype)
return true;
for (const auto& s: mEvsSpec)
if (s.mPayloadType == ptype)
return true;
if (mIsac16KPayloadType == ptype || mIsac32KPayloadType == ptype)
return true;
if (mIlbc20PayloadType == ptype || mIlbc30PayloadType == ptype)
return true;
if (mGsmEfrPayloadType == ptype || mGsmFrPayloadType == ptype || mGsmHrPayloadType == ptype)
return true;
return false;
}
std::string CodecList::Settings::toString() const
{
std::ostringstream oss;
oss << "wrap IuUP: " << mWrapIuUP << std::endl
<< "skip decode: " << mSkipDecode << std::endl;
for (int ptype: mAmrWbPayloadType)
oss << "AMR WB ptype: " << ptype << std::endl;
for (int ptype: mAmrWbOctetPayloadType)
oss << "AMR WB octet-aligned ptype: " << ptype << std::endl;
for (int ptype: mAmrNbPayloadType)
oss << "AMR NB ptype: " << ptype << std::endl;
for (int ptype: mAmrNbOctetPayloadType)
oss << "AMR NB octet-aligned ptype:" << ptype << std::endl;
// oss << "wrap IuUP: " << mWrapIuUP << std::endl
// << "skip decode: " << mSkipDecode << std::endl;
oss << "ISAC 16Khz ptype: " << mIsac16KPayloadType << std::endl
<< "ISAC 32Khz ptype: " << mIsac32KPayloadType << std::endl
<< "iLBC 20ms ptype: " << mIlbc20PayloadType << std::endl
<< "iLBC 30ms ptype: " << mIlbc30PayloadType << std::endl
<< "GSM FR ptype: " << mGsmFrPayloadType << ", GSM FR plength: " << mGsmFrPayloadLength << std::endl
<< "GSM HR ptype: " << mGsmHrPayloadType << std::endl
<< "GSM EFR ptype: " << mGsmEfrPayloadType << std::endl;
if (!mAmrWbPayloadType.empty())
{
oss << "AMR WB ptype: ";
for (int ptype: mAmrWbPayloadType)
oss << ptype << " ";
}
if (!mAmrWbOctetPayloadType.empty())
{
oss << "AMR WB octet ptype: ";
for (int ptype: mAmrWbOctetPayloadType)
oss << ptype << " ";
}
if (!mAmrNbPayloadType.empty())
{
oss << "AMR ptype: ";
for (int ptype: mAmrNbPayloadType)
oss << ptype << " ";
}
if (!mAmrNbOctetPayloadType.empty())
{
oss << "AMR octet ptype: ";
for (int ptype: mAmrNbOctetPayloadType)
oss << ptype << " ";
}
if (mIsac16KPayloadType != -1)
oss << "ISAC 16Khz ptype: " << mIsac16KPayloadType << " ";
if (mIsac32KPayloadType != -1)
oss << "ISAC 32Khz ptype: " << mIsac32KPayloadType << " ";
if (mIlbc20PayloadType != -1)
oss << "iLBC 20ms ptype: " << mIlbc20PayloadType << " ";
if (mIlbc30PayloadType != -1)
oss << "iLBC 30ms ptype: " << mIlbc30PayloadType << " ";
if (mGsmFrPayloadType != -1)
oss << "GSM FR ptype: " << mGsmFrPayloadType << ", GSM FR plength: " << mGsmFrPayloadLength << " ";
if (mGsmHrPayloadType != -1)
oss << "GSM HR ptype: " << mGsmHrPayloadType << " ";
if (mGsmEfrPayloadType != -1)
oss << "GSM EFR ptype: " << mGsmEfrPayloadType << " ";
for (auto& spec: mEvsSpec)
{
oss << "EVS ptype: " << spec.mPayloadType << ", bw: " << spec.mBandwidth << ", enc: " << (spec.mEncodingType == EvsSpec::Encoding_MIME ? "mime" : "g192") << std::endl;
oss << "EVS ptype: " << spec.mPayloadType << ", bw: " << spec.mBandwidth << ", enc: " << (spec.mEncodingType == EvsSpec::Encoding_MIME ? "mime" : "g192") << " ";
}
for (auto& spec: mOpusSpec)
@@ -100,24 +162,24 @@ CodecList::Settings::EvsSpec CodecList::Settings::EvsSpec::parse(const std::stri
if (encoding_type == "mime")
result.mEncodingType = Encoding_MIME;
else
if (encoding_type == "g192")
result.mEncodingType = Encoding_G192;
else
throw std::logic_error("Bad EVS codec encoding type");
if (encoding_type == "g192")
result.mEncodingType = Encoding_G192;
else
throw std::logic_error("Bad EVS codec encoding type");
// Bandwidth
std::string& bandwidth = parts.back();
if (bandwidth == "nb" || bandwidth == "NB")
result.mBandwidth = Bandwidth_NB;
else
if (bandwidth == "wb" || bandwidth == "WB")
result.mBandwidth = Bandwidth_WB;
else
if (bandwidth == "swb" || bandwidth == "SWB")
result.mBandwidth = Bandwidth_SWB;
else
if (bandwidth == "fb" || bandwidth == "FB")
result.mBandwidth = Bandwidth_FB;
if (bandwidth == "wb" || bandwidth == "WB")
result.mBandwidth = Bandwidth_WB;
else
if (bandwidth == "swb" || bandwidth == "SWB")
result.mBandwidth = Bandwidth_SWB;
else
if (bandwidth == "fb" || bandwidth == "FB")
result.mBandwidth = Bandwidth_FB;
}
return result;
@@ -145,6 +207,21 @@ CodecList::Settings::OpusSpec CodecList::Settings::OpusSpec::parse(const std::st
}
#if defined(USE_RESIP_INTEGRATION)
static int findOctetMode(const char* line)
{
const char* param_name = "octet-align=";
auto p = strstr(line, param_name);
if (!p)
return 0;
p += strlen(param_name);
char int_buf[8] = {0};
int int_buf_offset = 0;
while (*p && isdigit(*p) && int_buf_offset < sizeof(int_buf))
int_buf[int_buf_offset++] = *p++;
return atoi(int_buf);
}
CodecList::Settings CodecList::Settings::parseSdp(const std::list<resip::Codec>& codeclist)
{
CodecList::Settings r{DefaultSettings};
@@ -155,15 +232,44 @@ CodecList::Settings CodecList::Settings::parseSdp(const std::list<resip::Codec>&
int samplerate = c.getRate();
int ptype = c.payloadType();
auto enc_params = c.encodingParameters(); // This must channels number for Opus codec
auto params = c.parameters();
// Dynamic payload type codecs only - ISAC / iLBC / Speex / etc.
if (codec_name == "OPUS")
{
// Check the parameters
auto enc_params = c.encodingParameters(); // This must channels number for Opus codec
auto params = c.parameters();
int channels = strx::toInt(enc_params.c_str(), 1);
r.mOpusSpec.push_back({ptype, samplerate, channels});
}
else
if (codec_name == "AMR-WB")
{
int octet_mode = findOctetMode(params.c_str());
if (octet_mode != -1)
{
if (octet_mode == 0)
r.mAmrWbPayloadType.insert(ptype);
else
if (octet_mode == 1)
r.mAmrWbOctetPayloadType.insert(ptype);
}
// std::cout << "AMR-WB parameters: " << params.c_str() << ", found octet-mode: " << octet_mode << std::endl;
}
else
if (codec_name == "AMR")
{
int octet_mode = findOctetMode(params.c_str());
if (octet_mode != -1)
{
if (octet_mode == 0)
r.mAmrWbPayloadType.insert(ptype);
else
if (octet_mode == 1)
r.mAmrWbOctetPayloadType.insert(ptype);
}
// std::cout << "AMR parameters: " << params.c_str() << ", found octet-mode: " << octet_mode << std::endl;
}
}
return r;
}
@@ -173,7 +279,7 @@ CodecList::Settings CodecList::Settings::parseSdp(const std::list<resip::Codec>&
bool CodecList::Settings::operator == (const Settings& rhs) const
{
if (std::tie(mWrapIuUP, mSkipDecode, mIsac16KPayloadType, mIsac32KPayloadType, mIlbc20PayloadType, mIlbc30PayloadType, mGsmFrPayloadType, mGsmFrPayloadLength, mGsmEfrPayloadType, mGsmHrPayloadType) !=
std::tie(rhs.mWrapIuUP, rhs.mSkipDecode, rhs.mIsac16KPayloadType, rhs.mIsac32KPayloadType, rhs.mIlbc20PayloadType, rhs.mIlbc30PayloadType, rhs.mGsmFrPayloadType, rhs.mGsmFrPayloadLength, rhs.mGsmEfrPayloadType, rhs.mGsmHrPayloadType))
std::tie(rhs.mWrapIuUP, rhs.mSkipDecode, rhs.mIsac16KPayloadType, rhs.mIsac32KPayloadType, rhs.mIlbc20PayloadType, rhs.mIlbc30PayloadType, rhs.mGsmFrPayloadType, rhs.mGsmFrPayloadLength, rhs.mGsmEfrPayloadType, rhs.mGsmHrPayloadType))
return false;
if (mAmrNbOctetPayloadType != rhs.mAmrNbOctetPayloadType)
@@ -211,108 +317,99 @@ bool CodecList::Settings::operator == (const Settings& rhs) const
CodecList::Settings CodecList::Settings::DefaultSettings;
CodecList::CodecList(const Settings& settings)
:mSettings(settings)
:mSettings(settings)
{
init(mSettings);
}
void CodecList::init(const Settings& settings)
{
for (auto f: mFactoryList)
delete f;
mFactoryList.clear();
mFactoryList.clear();
mSettings = settings;
#if defined(USE_OPUS_CODEC)
if (settings.mOpusSpec.empty())
{
mFactoryList.push_back(new OpusCodec::OpusFactory(48000, 2, MT_OPUS_CODEC_PT));
}
else
{
for (auto spec: settings.mOpusSpec)
{
mFactoryList.push_back(new OpusCodec::OpusFactory(spec.mRate, spec.mChannels, spec.mPayloadType));
mFactoryList.push_back(std::make_shared<OpusCodec::OpusFactory>(spec.mRate, spec.mChannels, spec.mPayloadType));
}
}
#endif
#if !defined(TARGET_ANDROID) && !defined(TARGET_OPENWRT) && !defined(TARGET_RPI)
#if defined(USE_AMR_CODEC)
for (int pt: mSettings.mAmrWbPayloadType)
mFactoryList.push_back(new AmrWbCodec::CodecFactory({mSettings.mWrapIuUP, false, pt}));
for (int pt: mSettings.mAmrWbOctetPayloadType)
mFactoryList.push_back(new AmrWbCodec::CodecFactory({mSettings.mWrapIuUP, true, pt}));
for (int pt: mSettings.mAmrWbPayloadType)
mFactoryList.push_back(std::make_shared<AmrWbCodec::CodecFactory>(AmrCodecConfig{mSettings.mWrapIuUP, false, pt}));
for (int pt: mSettings.mAmrWbOctetPayloadType)
mFactoryList.push_back(std::make_shared<AmrWbCodec::CodecFactory>(AmrCodecConfig{mSettings.mWrapIuUP, true, pt}));
for (int pt: mSettings.mAmrNbPayloadType)
mFactoryList.push_back(new AmrNbCodec::CodecFactory({mSettings.mWrapIuUP, false, pt}));
for (int pt: mSettings.mAmrNbOctetPayloadType)
mFactoryList.push_back(new AmrNbCodec::CodecFactory({mSettings.mWrapIuUP, true, pt}));
for (int pt: mSettings.mAmrNbPayloadType)
mFactoryList.push_back(std::make_shared<AmrNbCodec::CodecFactory>(AmrCodecConfig{mSettings.mWrapIuUP, false, pt}));
for (int pt: mSettings.mAmrNbOctetPayloadType)
mFactoryList.push_back(std::make_shared<AmrNbCodec::CodecFactory>(AmrCodecConfig{mSettings.mWrapIuUP, true, pt}));
mFactoryList.push_back(new GsmEfrCodec::GsmEfrFactory(mSettings.mWrapIuUP, mSettings.mGsmEfrPayloadType));
if (mSettings.mGsmEfrPayloadType != -1)
mFactoryList.push_back(std::make_shared<GsmEfrCodec::GsmEfrFactory>(mSettings.mWrapIuUP, mSettings.mGsmEfrPayloadType));
#endif
#endif
// mFactoryList.push_back(new IsacCodec::IsacFactory16K(mSettings.mIsac16KPayloadType));
// mFactoryList.push_back(new IlbcCodec::IlbcFactory(mSettings.mIlbc20PayloadType, mSettings.mIlbc30PayloadType));
mFactoryList.push_back(new G711Codec::AlawFactory());
mFactoryList.push_back(new G711Codec::UlawFactory());
mFactoryList.push_back(std::make_shared<G711Codec::AlawFactory>());
mFactoryList.push_back(std::make_shared<G711Codec::UlawFactory>());
mFactoryList.push_back(new GsmCodec::GsmFactory(mSettings.mGsmFrPayloadLength == 32 ? GsmCodec::Type::Bytes_32 : GsmCodec::Type::Bytes_33, mSettings.mGsmFrPayloadType));
mFactoryList.push_back(new G722Codec::G722Factory());
mFactoryList.push_back(new G729Codec::G729Factory());
if (mSettings.mGsmFrPayloadType != -1)
mFactoryList.push_back(std::make_shared<GsmCodec::GsmFactory>(mSettings.mGsmFrPayloadLength == 32 ? GsmCodec::Type::Bytes_32 : GsmCodec::Type::Bytes_33, mSettings.mGsmFrPayloadType));
mFactoryList.push_back(std::make_shared<G722Codec::G722Factory>());
mFactoryList.push_back(std::make_shared<G729Codec::G729Factory>());
#ifndef TARGET_ANDROID
mFactoryList.push_back(new GsmHrCodec::GsmHrFactory(mSettings.mGsmHrPayloadType));
if (mSettings.mGsmHrPayloadType != -1)
mFactoryList.push_back(std::make_shared<GsmHrCodec::GsmHrFactory>(mSettings.mGsmHrPayloadType));
#endif
#if !defined(TARGET_ANDROID) && defined(USE_EVS_CODEC)
for (auto& spec: settings.mEvsSpec)
{
EVSCodec::StreamParameters evs_params;
evs_params.mime = spec.mEncodingType == Settings::EvsSpec::Encoding_MIME;
evs_params.bw = (int)spec.mBandwidth;
evs_params.ptime = 20;
evs_params.ptype = spec.mPayloadType;
for (auto& spec: settings.mEvsSpec)
{
EVSCodec::StreamParameters evs_params;
evs_params.mime = spec.mEncodingType == Settings::EvsSpec::Encoding_MIME;
evs_params.bw = (int)spec.mBandwidth;
evs_params.ptime = 20;
evs_params.ptype = spec.mPayloadType;
mFactoryList.push_back(new EVSCodec::EVSFactory(evs_params));
}
mFactoryList.push_back(std::make_shared<EVSCodec::EVSFactory>(evs_params));
}
#endif
}
CodecList::~CodecList()
{
for (auto f: mFactoryList)
delete f;
mFactoryList.clear();
}
int CodecList::count() const
{
return static_cast<int>(mFactoryList.size());
return static_cast<int>(mFactoryList.size());
}
Codec::Factory& CodecList::codecAt(int index) const
{
return *mFactoryList[static_cast<size_t>(index)];
return *mFactoryList[static_cast<size_t>(index)];
}
int CodecList::findCodec(const std::string &name) const
{
for (int i=0; i<count(); i++)
{
if (codecAt(i).name() == name)
return i;
}
return -1;
for (int i=0; i<count(); i++)
{
if (codecAt(i).name() == name)
return i;
}
return -1;
}
void CodecList::fillCodecMap(CodecMap& cm)
{
cm.clear();
for (auto& factory: mFactoryList)
{
// Create codec here. Although they are not needed right now - they can be needed to find codec's info.
PCodec c = factory->create();
cm.insert({factory->payloadType(), c});
}
cm.clear();
for (auto& factory: mFactoryList)
{
// Create codec here. Although they are not needed right now - they can be needed to find codec's info.
PCodec c = factory->create();
cm.insert({factory->payloadType(), c});
}
}
CodecListPriority::CodecListPriority()
@@ -327,55 +424,55 @@ CodecListPriority::~CodecListPriority()
bool CodecListPriority::isNegativePriority(const CodecListPriority::Item& item)
{
return item.mPriority < 0;
return item.mPriority < 0;
}
bool CodecListPriority::compare(const Item& item1, const Item& item2)
{
return item1.mPriority < item2.mPriority;
return item1.mPriority < item2.mPriority;
}
void CodecListPriority::setupFrom(PVariantMap vmap)
{
CodecList::Settings settings;
CodecList cl(settings);
//mPriorityList.resize(cl.count());
bool emptyVmap = vmap ? vmap->empty() : true;
CodecList::Settings settings;
CodecList cl(settings);
//mPriorityList.resize(cl.count());
bool emptyVmap = vmap ? vmap->empty() : true;
if (emptyVmap)
{
for (int i=0; i<cl.count(); i++)
if (emptyVmap)
{
Item item;
item.mCodecIndex = i;
item.mPriority = i;
mPriorityList.push_back(item);
for (int i=0; i<cl.count(); i++)
{
Item item;
item.mCodecIndex = i;
item.mPriority = i;
mPriorityList.push_back(item);
}
}
}
else
{
for (int i=0; i<cl.count(); i++)
else
{
Item item;
item.mCodecIndex = i;
item.mPriority = vmap->exists(i) ? vmap->at(i).asInt() : 1000; // Non listed codecs will get lower priority
mPriorityList.push_back(item);
for (int i=0; i<cl.count(); i++)
{
Item item;
item.mCodecIndex = i;
item.mPriority = vmap->exists(i) ? vmap->at(i).asInt() : 1000; // Non listed codecs will get lower priority
mPriorityList.push_back(item);
}
// Remove -1 records
mPriorityList.erase(std::remove_if(mPriorityList.begin(), mPriorityList.end(), isNegativePriority), mPriorityList.end());
// Sort by priority
std::sort(mPriorityList.begin(), mPriorityList.end(), compare);
}
// Remove -1 records
mPriorityList.erase(std::remove_if(mPriorityList.begin(), mPriorityList.end(), isNegativePriority), mPriorityList.end());
// Sort by priority
std::sort(mPriorityList.begin(), mPriorityList.end(), compare);
}
}
int CodecListPriority::count(const CodecList & /*cl*/) const
{
return static_cast<int>(mPriorityList.size());
return static_cast<int>(mPriorityList.size());
}
Codec::Factory& CodecListPriority::codecAt(const CodecList& cl, int index) const
{
return cl.codecAt(mPriorityList[static_cast<size_t>(index)].mCodecIndex);
return cl.codecAt(mPriorityList[static_cast<size_t>(index)].mCodecIndex);
}