diff --git a/src/utils/payload-type-handler.cpp b/src/utils/payload-type-handler.cpp index fce4a60ec..25044f106 100644 --- a/src/utils/payload-type-handler.cpp +++ b/src/utils/payload-type-handler.cpp @@ -18,9 +18,13 @@ #include +#include "private.h" + +#include "logger/logger.h" + #include "payload-type-handler.h" -#include "private.h" +// ============================================================================= using namespace std; @@ -28,9 +32,11 @@ LINPHONE_BEGIN_NAMESPACE const int PayloadTypeHandler::udpHeaderSize = 8; const int PayloadTypeHandler::rtpHeaderSize = 12; -const int PayloadTypeHandler::ipv4HeaderSize = 20; /* 20 is the minimum, but there may be some options */ + +// 20 is the minimum, but there may be some options. +const int PayloadTypeHandler::ipv4HeaderSize = 20; + const VbrCodecBitrate PayloadTypeHandler::defaultVbrCodecBitrates[] = { - //{ 100, 44100, 100 }, { 64, 44100, 50 }, { 64, 16000, 40 }, { 32, 16000, 32 }, @@ -45,12 +51,18 @@ int PayloadTypeHandler::findPayloadTypeNumber (const bctbx_list_t *assigned, con const OrtpPayloadType *candidate = nullptr; for (const bctbx_list_t *elem = assigned; elem != nullptr; elem = bctbx_list_next(elem)) { const OrtpPayloadType *it = reinterpret_cast(bctbx_list_get_data(elem)); - if ((strcasecmp(pt->mime_type, payload_type_get_mime(it)) == 0) - && (it->clock_rate == pt->clock_rate) - && ((it->channels == pt->channels) || (pt->channels <= 0))) { + if ( + strcasecmp(pt->mime_type, payload_type_get_mime(it)) == 0 && + it->clock_rate == pt->clock_rate && + ((it->channels == pt->channels) || (pt->channels <= 0)) + ) { candidate = it; - if ((it->recv_fmtp && pt->recv_fmtp && (strcasecmp(it->recv_fmtp, pt->recv_fmtp) == 0)) || (!it->recv_fmtp && !pt->recv_fmtp)) - break; /* Exact match */ + if ( + (it->recv_fmtp && pt->recv_fmtp && (strcasecmp(it->recv_fmtp, pt->recv_fmtp) == 0)) || + (!it->recv_fmtp && !pt->recv_fmtp) + ) + // Exact match. + break; } } return candidate ? payload_type_get_number(candidate) : -1; @@ -74,7 +86,8 @@ bool PayloadTypeHandler::isPayloadTypeUsableForBandwidth (const OrtpPayloadType codecBand = getAudioPayloadTypeBandwidth(pt, bandwidthLimit); return bandwidthIsGreater(bandwidthLimit, (int)codecBand); case PAYLOAD_VIDEO: - if ((bandwidthLimit <= 0) || (bandwidthLimit >= videoEnablementLimit)) /* Infinite or greater than videoEnablementLimit */ + // Infinite or greater than videoEnablementLimit. + if (bandwidthLimit <= 0 || bandwidthLimit >= videoEnablementLimit) return true; break; case PAYLOAD_TEXT: @@ -104,11 +117,12 @@ void PayloadTypeHandler::assignPayloadTypeNumbers (const bctbx_list_t *codecs) { OrtpPayloadType *pt = reinterpret_cast(bctbx_list_get_data(elem)); int number = payload_type_get_number(pt); - /* Check if number is duplicated: it could be the case if the remote forced us to use a mapping with a previous offer */ + // Check if number is duplicated: it could be the case if the remote forced us to use a mapping with a previous offer. if ((number != -1) && !(pt->flags & PAYLOAD_TYPE_FROZEN_NUMBER)) { if (!isPayloadTypeNumberAvailable(codecs, number, pt)) { lInfo() << "Reassigning payload type " << number << " " << pt->mime_type << "/" << pt->clock_rate << " because already offered"; - number = -1; /* need to be re-assigned */ + // Need to be re-assigned. + number = -1; } } @@ -122,7 +136,7 @@ void PayloadTypeHandler::assignPayloadTypeNumbers (const bctbx_list_t *codecs) { } dynNumber++; } - if (dynNumber==127) { + if (dynNumber == 127) { lError() << "Too many payload types configured ! codec " << pt->mime_type << "/" << pt->clock_rate << " is disabled"; payload_type_set_enable(pt, false); } @@ -142,7 +156,7 @@ void PayloadTypeHandler::assignPayloadTypeNumbers (const bctbx_list_t *codecs) { } } -bctbx_list_t * PayloadTypeHandler::createSpecialPayloadTypes (const bctbx_list_t *codecs) { +bctbx_list_t *PayloadTypeHandler::createSpecialPayloadTypes (const bctbx_list_t *codecs) { bctbx_list_t *result = createTelephoneEventPayloadTypes(codecs); if (linphone_core_generic_comfort_noise_enabled(core)) { OrtpPayloadType *cn = payload_type_clone(&payload_type_cn); @@ -152,29 +166,32 @@ bctbx_list_t * PayloadTypeHandler::createSpecialPayloadTypes (const bctbx_list_t return result; } -bctbx_list_t * PayloadTypeHandler::createTelephoneEventPayloadTypes (const bctbx_list_t *codecs) { +bctbx_list_t *PayloadTypeHandler::createTelephoneEventPayloadTypes (const bctbx_list_t *codecs) { bctbx_list_t *result = nullptr; for (const bctbx_list_t *it = codecs; it != nullptr; it = bctbx_list_next(it)) { const OrtpPayloadType *pt = reinterpret_cast(bctbx_list_get_data(it)); - if (!hasTelephoneEventPayloadType(result, pt->clock_rate)) { - OrtpPayloadType *tev = payload_type_clone(&payload_type_telephone_event); - tev->clock_rate = pt->clock_rate; - /* Let it choose the number dynamically as for normal codecs */ - payload_type_set_number(tev, -1); - if (!result) { - /* But for first telephone-event, prefer the number that was configured in the core */ - if (isPayloadTypeNumberAvailable(codecs, core->codecs_conf.telephone_event_pt, nullptr)) - payload_type_set_number(tev, core->codecs_conf.telephone_event_pt); - } - result = bctbx_list_append(result, tev); - } + if (hasTelephoneEventPayloadType(result, pt->clock_rate)) + continue; + + OrtpPayloadType *tev = payload_type_clone(&payload_type_telephone_event); + tev->clock_rate = pt->clock_rate; + // Let it choose the number dynamically as for normal codecs. + payload_type_set_number(tev, -1); + // But for first telephone-event, prefer the number that was configured in the core. + if (!result && isPayloadTypeNumberAvailable(codecs, core->codecs_conf.telephone_event_pt, nullptr)) + payload_type_set_number(tev, core->codecs_conf.telephone_event_pt); + result = bctbx_list_append(result, tev); } return result; } bool PayloadTypeHandler::isPayloadTypeUsable (const OrtpPayloadType *pt) { - int maxBandwidth = getMinBandwidth(linphone_core_get_download_bandwidth(core), linphone_core_get_upload_bandwidth(core)); - return isPayloadTypeUsableForBandwidth(pt, maxBandwidth); + return isPayloadTypeUsableForBandwidth( + pt, getMinBandwidth( + linphone_core_get_download_bandwidth(core), + linphone_core_get_upload_bandwidth(core) + ) + ); } // ----------------------------------------------------------------------------- @@ -199,16 +216,16 @@ int PayloadTypeHandler::getAudioPayloadTypeBandwidth (const OrtpPayloadType *pt, /* *((codec-birate*ptime/8) + RTP header + UDP header + IP header)*8/ptime; - *ptime=1/npacket + * ptime=1/npacket */ double PayloadTypeHandler::getAudioPayloadTypeBandwidthFromCodecBitrate (const OrtpPayloadType *pt) { double npacket = 50; - if (strcmp(payload_type_get_mime(&payload_type_aaceld_44k), payload_type_get_mime(pt)) == 0) { - /* Special case of aac 44K because ptime=10ms */ + if (strcmp(payload_type_get_mime(&payload_type_aaceld_44k), payload_type_get_mime(pt)) == 0) + // Special case of aac 44K because ptime=10ms. npacket = 100; - } else if (strcmp(payload_type_get_mime(&payload_type_ilbc), payload_type_get_mime(pt)) == 0) { + else if (strcmp(payload_type_get_mime(&payload_type_ilbc), payload_type_get_mime(pt)) == 0) npacket = 1000 / 30.0; - } + int bitrate = pt->normal_bitrate; double packet_size = (((double)bitrate) / (npacket * 8)) + udpHeaderSize + rtpHeaderSize + ipv4HeaderSize; return packet_size * 8.0 * npacket; @@ -219,11 +236,12 @@ int PayloadTypeHandler::getMaxCodecSampleRate (const bctbx_list_t *codecs) { for (const bctbx_list_t *it = codecs; it != nullptr; it = bctbx_list_next(it)) { OrtpPayloadType *pt = reinterpret_cast(bctbx_list_get_data(it)); int sampleRate; - if (strcasecmp("G722", pt->mime_type) == 0) { - /* G722 spec says 8000 but the codec actually requires 16000 */ + if (strcasecmp("G722", pt->mime_type) == 0) + // G722 spec says 8000 but the codec actually requires 16000. sampleRate = 16000; - } else + else sampleRate = pt->clock_rate; + if (sampleRate > maxSampleRate) maxSampleRate = sampleRate; } @@ -252,7 +270,7 @@ bool PayloadTypeHandler::isPayloadTypeNumberAvailable (const bctbx_list_t *codec // ----------------------------------------------------------------------------- -bctbx_list_t * PayloadTypeHandler::makeCodecsList (SalStreamType type, int bandwidthLimit, int maxCodecs, const bctbx_list_t *previousList) { +bctbx_list_t *PayloadTypeHandler::makeCodecsList (SalStreamType type, int bandwidthLimit, int maxCodecs, const bctbx_list_t *previousList) { const bctbx_list_t *allCodecs = nullptr; switch (type) { default: @@ -273,13 +291,16 @@ bctbx_list_t * PayloadTypeHandler::makeCodecsList (SalStreamType type, int bandw OrtpPayloadType *pt = reinterpret_cast(bctbx_list_get_data(it)); if (!payload_type_enabled(pt)) continue; - if ((bandwidthLimit > 0) && !isPayloadTypeUsableForBandwidth(pt, bandwidthLimit)) { - lInfo() << "Codec " << pt->mime_type << "/" << pt->clock_rate << " eliminated because of audio bandwidth constraint of " - << bandwidthLimit << " kbit/s"; + + if (bandwidthLimit > 0 && !isPayloadTypeUsableForBandwidth(pt, bandwidthLimit)) { + lInfo() << "Codec " << pt->mime_type << "/" << pt->clock_rate << " eliminated because of audio bandwidth constraint of " << + bandwidthLimit << " kbit/s"; continue; } + if (!isPayloadTypeUsable(pt)) continue; + pt = payload_type_clone(pt); /* Look for a previously assigned number for this codec */ diff --git a/src/utils/payload-type-handler.h b/src/utils/payload-type-handler.h index 4aa09226c..892e175aa 100644 --- a/src/utils/payload-type-handler.h +++ b/src/utils/payload-type-handler.h @@ -19,25 +19,20 @@ #ifndef _PAYLOAD_TYPE_HANDLER_H_ #define _PAYLOAD_TYPE_HANDLER_H_ -#include "logger/logger.h" - #include "linphone/core.h" -#include "linphone/payload_type.h" #include "linphone/utils/general.h" -#include "sal/sal.h" + +#include "sal/sal.h" /* SalStreamType. */ // ============================================================================= -#define PAYLOAD_TYPE_ENABLED PAYLOAD_TYPE_USER_FLAG_0 +#define PAYLOAD_TYPE_ENABLED PAYLOAD_TYPE_USER_FLAG_0 #define PAYLOAD_TYPE_BITRATE_OVERRIDE PAYLOAD_TYPE_USER_FLAG_3 -#define PAYLOAD_TYPE_FROZEN_NUMBER PAYLOAD_TYPE_USER_FLAG_4 - -// ============================================================================= +#define PAYLOAD_TYPE_FROZEN_NUMBER PAYLOAD_TYPE_USER_FLAG_4 LINPHONE_BEGIN_NAMESPACE struct VbrCodecBitrate { -public: int maxAvailableBitrate; int minClockRate; int recommendedBitrate; @@ -46,20 +41,9 @@ public: class PayloadTypeHandler { public: PayloadTypeHandler (LinphoneCore *core) : core(core) {} - ~PayloadTypeHandler () = default; -private: - static int findPayloadTypeNumber (const bctbx_list_t *assigned, const OrtpPayloadType *pt); - static bool hasTelephoneEventPayloadType (const bctbx_list_t *tev, int rate); - static bool isPayloadTypeUsableForBandwidth (const OrtpPayloadType *pt, int bandwidthLimit); - static int lookupTypicalVbrBitrate (int maxBandwidth, int clockRate); + bctbx_list_t *makeCodecsList (SalStreamType type, int bandwidthLimit, int maxCodecs, const bctbx_list_t *previousList); - void assignPayloadTypeNumbers (const bctbx_list_t *codecs); - bctbx_list_t * createSpecialPayloadTypes (const bctbx_list_t *codecs); - bctbx_list_t * createTelephoneEventPayloadTypes (const bctbx_list_t *codecs); - bool isPayloadTypeUsable (const OrtpPayloadType *pt); - -public: static bool bandwidthIsGreater (int bandwidth1, int bandwidth2); static int getAudioPayloadTypeBandwidth (const OrtpPayloadType *pt, int maxBandwidth); static double getAudioPayloadTypeBandwidthFromCodecBitrate (const OrtpPayloadType *pt); @@ -68,9 +52,17 @@ public: static int getRemainingBandwidthForVideo (int total, int audio); static bool isPayloadTypeNumberAvailable (const bctbx_list_t *codecs, int number, const OrtpPayloadType *ignore); - bctbx_list_t * makeCodecsList (SalStreamType type, int bandwidthLimit, int maxCodecs, const bctbx_list_t *previousList); - private: + static int findPayloadTypeNumber (const bctbx_list_t *assigned, const OrtpPayloadType *pt); + static bool hasTelephoneEventPayloadType (const bctbx_list_t *tev, int rate); + static bool isPayloadTypeUsableForBandwidth (const OrtpPayloadType *pt, int bandwidthLimit); + static int lookupTypicalVbrBitrate (int maxBandwidth, int clockRate); + + void assignPayloadTypeNumbers (const bctbx_list_t *codecs); + bctbx_list_t *createSpecialPayloadTypes (const bctbx_list_t *codecs); + bctbx_list_t *createTelephoneEventPayloadTypes (const bctbx_list_t *codecs); + bool isPayloadTypeUsable (const OrtpPayloadType *pt); + static const int udpHeaderSize; static const int rtpHeaderSize; static const int ipv4HeaderSize;