diff --git a/src/account.cpp b/src/account.cpp index 75eaee64397cf1cc527dfb763d03dd43a93d0cce..0c8565401dd92c401bf5b2556dd5ddf7ae2cf08f 100644 --- a/src/account.cpp +++ b/src/account.cpp @@ -85,6 +85,7 @@ const char * const Account::USER_AGENT_KEY = "useragent"; const char * const Account::HAS_CUSTOM_USER_AGENT_KEY = "hasCustomUserAgent"; const char * const Account::PRESENCE_MODULE_ENABLED_KEY = "presenceModuleEnabled"; const char * const Account::UPNP_ENABLED_KEY = "upnpEnabled"; +const char * const Account::ACTIVE_CODEC_KEY = "activeCodecs"; #ifdef __ANDROID__ constexpr const char * const DEFAULT_RINGTONE_PATH = "/data/data/cx.ring/files/ringtones/default.opus"; @@ -219,7 +220,7 @@ Account::serialize(YAML::Emitter& out) const out << YAML::Key << ALIAS_KEY << YAML::Value << alias_; out << YAML::Key << ACCOUNT_ENABLE_KEY << YAML::Value << enabled_; out << YAML::Key << TYPE_KEY << YAML::Value << getAccountType(); - out << YAML::Key << ALL_CODECS_KEY << YAML::Value << activeCodecs; + out << YAML::Key << ACTIVE_CODEC_KEY << YAML::Value << activeCodecs; out << YAML::Key << MAILBOX_KEY << YAML::Value << mailBox_; out << YAML::Key << ACCOUNT_AUTOANSWER_KEY << YAML::Value << autoAnswerEnabled_; out << YAML::Key << ACCOUNT_ACTIVE_CALL_LIMIT_KEY << YAML::Value << activeCallLimit_; @@ -236,6 +237,7 @@ void Account::unserialize(const YAML::Node& node) { using yaml_utils::parseValue; + using yaml_utils::parseValueOptional; parseValue(node, ALIAS_KEY, alias_); parseValue(node, ACCOUNT_ENABLE_KEY, enabled_); @@ -246,8 +248,24 @@ Account::unserialize(const YAML::Node& node) parseValue(node, MAILBOX_KEY, mailBox_); std::string activeCodecs; - parseValue(node, ALL_CODECS_KEY, activeCodecs); - setActiveCodecs(split_string_to_unsigned(activeCodecs, '/')); + if (parseValueOptional(node, ACTIVE_CODEC_KEY, activeCodecs)) + setActiveCodecs(split_string_to_unsigned(activeCodecs, '/')); + else { + std::string allCodecs; + if (parseValueOptional(node, ALL_CODECS_KEY, allCodecs)) { + JAMI_WARN("Converting deprecated codec list"); + auto list = convertIdToAVId(split_string_to_unsigned(allCodecs, '/')); + auto codec = searchCodecByName("H265", MEDIA_ALL); + // set H265 as first active codec if found + if (codec) + list.emplace(list.begin(), codec->systemCodecInfo.id); + setActiveCodecs(list); + runOnMainThread([id = getAccountID()]{ + if (auto sthis = Manager::instance().getAccount(id)) + Manager::instance().saveConfig(sthis); + }); + } + } parseValue(node, DISPLAY_NAME_KEY, displayName_); parseValue(node, HOSTNAME_KEY, hostname_); @@ -362,6 +380,41 @@ Account::sortCodec() }); } +std::vector<unsigned> +Account::convertIdToAVId(const std::vector<unsigned>& list) +{ +#if !(defined(TARGET_OS_IOS) && TARGET_OS_IOS) + constexpr size_t CODEC_NUM = 12; +#else + constexpr size_t CODEC_NUM = 10; +#endif + + static constexpr std::array<unsigned, CODEC_NUM> CODEC_ID_MAPPING = { + AV_CODEC_ID_NONE, + AV_CODEC_ID_H264, + AV_CODEC_ID_VP8, +#if !(defined(TARGET_OS_IOS) && TARGET_OS_IOS) + AV_CODEC_ID_MPEG4, + AV_CODEC_ID_H263, +#endif + AV_CODEC_ID_OPUS, + AV_CODEC_ID_ADPCM_G722, + AV_CODEC_ID_SPEEX & 0x20000000, + AV_CODEC_ID_SPEEX & 0x10000000, + AV_CODEC_ID_SPEEX, + AV_CODEC_ID_PCM_ALAW, + AV_CODEC_ID_PCM_MULAW + }; + + std::vector<unsigned> av_list; + av_list.reserve(list.size()); + for (auto& item : list) { + if (item > 0 and item < CODEC_ID_MAPPING.size()) + av_list.emplace_back(CODEC_ID_MAPPING[item]); + } + return av_list; +} + std::string Account::mapStateNumberToString(RegistrationState state) { @@ -563,6 +616,15 @@ Account::setCodecActive(unsigned codecId) } } +void +Account::setCodecInactive(unsigned codecId) +{ + for (auto& codecIt: accountCodecInfoList_) { + if (codecIt->systemCodecInfo.avcodecId == codecId) + codecIt->isActive = false; + } +} + std::vector<std::shared_ptr<AccountCodecInfo>> Account::getActiveAccountCodecInfoList(MediaType mediaType) const { diff --git a/src/account.h b/src/account.h index a8913ddbc9119ca6e7fb601b4915d30b7cbecaa3..e5271bab75670707f34541ef5e662090de32d9cd 100644 --- a/src/account.h +++ b/src/account.h @@ -323,6 +323,10 @@ class Account : public Serializable, public std::enable_shared_from_this<Account void setCodecActive(unsigned codecId); + void setCodecInactive(unsigned codecId); + + std::vector<unsigned> convertIdToAVId(const std::vector<unsigned>& list); + public: // virtual methods that has to be implemented by concrete classes /** * This method is called to request removal of possible account traces on the system, @@ -383,6 +387,7 @@ class Account : public Serializable, public std::enable_shared_from_this<Account static const char * const PROXY_ENABLED_KEY; static const char * const PROXY_SERVER_KEY; static const char * const PROXY_PUSH_TOKEN_KEY; + static const char * const ACTIVE_CODEC_KEY; static std::string mapStateNumberToString(RegistrationState state); diff --git a/src/client/videomanager.cpp b/src/client/videomanager.cpp index 6f76a75453b423d7ca70eff05af63ca396141f1c..739c8f85ea7f1f019de94cdd05d2d138755c4825 100644 --- a/src/client/videomanager.cpp +++ b/src/client/videomanager.cpp @@ -575,17 +575,13 @@ setEncodingAccelerated(bool state) jami::Manager::instance().videoPreferences.setEncodingAccelerated(state); jami::Manager::instance().saveConfig(); #endif - // refresh codec container + setH265 - jami::getSystemCodecContainer()->initCodecConfig(); for (const auto& acc : jami::Manager::instance().getAllAccounts()) { - // Save activated codec - auto activeCodecs = acc->getActiveCodecs(); - // Refresh codec list for the account - acc->loadDefaultCodecs(); - // Activate H265 if it is available, if not ignore - acc->setCodecActive(AV_CODEC_ID_HEVC); - // Reactivate saved codec - acc->setActiveCodecs(activeCodecs); + if (state) + acc->setCodecActive(AV_CODEC_ID_HEVC); + else + acc->setCodecInactive(AV_CODEC_ID_HEVC); + // Update and sort codecs + acc->setActiveCodecs(acc->getActiveCodecs()); jami::Manager::instance().saveConfig(acc); } } diff --git a/src/media/media_codec.cpp b/src/media/media_codec.cpp index 9c40b9143caca9bdf3a9fef12332fe9db78ff586..2ff6b66f29ba26393dc8dbf8e3680542dc4c058f 100644 --- a/src/media/media_codec.cpp +++ b/src/media/media_codec.cpp @@ -30,24 +30,17 @@ namespace jami { -static unsigned -generateId() -{ - static unsigned id = 0; - return ++id; -} - /* * SystemCodecInfo */ -SystemCodecInfo::SystemCodecInfo(unsigned avcodecId, const std::string& name, +SystemCodecInfo::SystemCodecInfo(unsigned codecId, unsigned avcodecId, const std::string& name, const std::string& libName, MediaType mediaType, CodecType codecType, unsigned bitrate, unsigned payloadType, unsigned minQuality, unsigned maxQuality) - : id(generateId()) + : id(codecId) , avcodecId(avcodecId) , name(name) , libName(libName) @@ -65,14 +58,15 @@ SystemCodecInfo::~SystemCodecInfo() /* * SystemAudioCodecInfo */ -SystemAudioCodecInfo::SystemAudioCodecInfo(unsigned m_avcodecId, +SystemAudioCodecInfo::SystemAudioCodecInfo(unsigned codecId, + unsigned m_avcodecId, const std::string& m_name, const std::string& m_libName, CodecType m_type, unsigned m_bitrate, unsigned m_sampleRate, unsigned m_nbChannels, unsigned m_payloadType) - : SystemCodecInfo(m_avcodecId, m_name, m_libName, MEDIA_AUDIO, m_type, m_bitrate, m_payloadType) + : SystemCodecInfo(codecId, m_avcodecId, m_name, m_libName, MEDIA_AUDIO, m_type, m_bitrate, m_payloadType) , audioformat{m_sampleRate, m_nbChannels} {} @@ -89,13 +83,14 @@ SystemAudioCodecInfo::getCodecSpecifications() {DRing::Account::ConfProperties::CodecInfo::BITRATE, std::to_string(bitrate)}, {DRing::Account::ConfProperties::CodecInfo::SAMPLE_RATE, std::to_string(audioformat.sample_rate)}, {DRing::Account::ConfProperties::CodecInfo::CHANNEL_NUMBER, std::to_string(audioformat.nb_channels)} - }; + }; } /* * SystemVideoCodecInfo */ -SystemVideoCodecInfo::SystemVideoCodecInfo(unsigned m_avcodecId, +SystemVideoCodecInfo::SystemVideoCodecInfo(unsigned codecId, + unsigned m_avcodecId, const std::string& m_name, const std::string& m_libName, CodecType m_type, @@ -105,7 +100,7 @@ SystemVideoCodecInfo::SystemVideoCodecInfo(unsigned m_avcodecId, unsigned m_payloadType, unsigned m_frameRate, unsigned m_profileId) - : SystemCodecInfo(m_avcodecId, m_name, m_libName, MEDIA_VIDEO, + : SystemCodecInfo(codecId, m_avcodecId, m_name, m_libName, MEDIA_VIDEO, m_type, m_bitrate, m_payloadType, m_minQuality, m_maxQuality) , frameRate(m_frameRate), profileId(m_profileId) {} diff --git a/src/media/media_codec.h b/src/media/media_codec.h index d1f2e99fd9c00cc058ee32d829e2e56d3cfdc2ff..998b443a56136b019674418578ee9290ed26cefd 100644 --- a/src/media/media_codec.h +++ b/src/media/media_codec.h @@ -73,7 +73,7 @@ struct SystemCodecInfo static constexpr unsigned DEFAULT_MAX_BITRATE {6000}; static constexpr unsigned DEFAULT_VIDEO_BITRATE {1200}; // in Kbits/second - SystemCodecInfo(unsigned avcodecId, const std::string& name, + SystemCodecInfo(unsigned codecId, unsigned avcodecId, const std::string& name, const std::string& libName, MediaType mediaType, CodecType codecType = CODEC_NONE, unsigned bitrate = 0, unsigned payloadType = 0, @@ -106,7 +106,7 @@ struct SystemCodecInfo */ struct SystemAudioCodecInfo : SystemCodecInfo { - SystemAudioCodecInfo(unsigned avcodecId, const std::string& name, + SystemAudioCodecInfo(unsigned codecId, unsigned avcodecId, const std::string& name, const std::string& libName, CodecType type, unsigned bitrate = 0, unsigned sampleRate = 0, unsigned nbChannels = 0, @@ -126,7 +126,7 @@ struct SystemAudioCodecInfo : SystemCodecInfo */ struct SystemVideoCodecInfo : SystemCodecInfo { - SystemVideoCodecInfo(unsigned avcodecId, const std::string& name, + SystemVideoCodecInfo(unsigned codecId, unsigned avcodecId, const std::string& name, const std::string& libName, CodecType type = CODEC_NONE, unsigned bitrate = 0, unsigned m_minQuality = 0, diff --git a/src/media/system_codec_container.cpp b/src/media/system_codec_container.cpp index 3c0ed717022f91e1bbaaaaa821e3a02052dca59a..34ec9c6c5549bfa3938d19b8a2de7072f468cb2b 100644 --- a/src/media/system_codec_container.cpp +++ b/src/media/system_codec_container.cpp @@ -61,33 +61,33 @@ SystemCodecContainer::initCodecConfig() availableCodecList_ = { #ifdef ENABLE_VIDEO /* Define supported video codec*/ - // std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_HEVC, + // std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_HEVC, AV_CODEC_ID_HEVC, // "H265", "", // CODEC_ENCODER_DECODER, // defaultBitrate, // minH265, // maxH265), - std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_H264, + std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_H264, AV_CODEC_ID_H264, "H264", "libx264", CODEC_ENCODER_DECODER, defaultBitrate, minH264, maxH264), - std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_VP8, + std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_VP8, AV_CODEC_ID_VP8, "VP8", "libvpx", CODEC_ENCODER_DECODER, defaultBitrate, minVP8, maxVP8), #if !(defined(TARGET_OS_IOS) && TARGET_OS_IOS) - std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_MPEG4, + std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_MPEG4, AV_CODEC_ID_MPEG4, "MP4V-ES", "mpeg4", CODEC_ENCODER_DECODER, defaultBitrate), - std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_H263, + std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_H263, AV_CODEC_ID_H263, "H263-1998", "h263", CODEC_ENCODER_DECODER, defaultBitrate), @@ -96,37 +96,37 @@ SystemCodecContainer::initCodecConfig() #endif /* Define supported audio codec*/ - std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_OPUS, + std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_OPUS, AV_CODEC_ID_OPUS, "opus", "libopus", CODEC_ENCODER_DECODER, 0, 48000, 2, 104), - std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_ADPCM_G722, + std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_ADPCM_G722, AV_CODEC_ID_ADPCM_G722, "G722", "g722", CODEC_ENCODER_DECODER, 0, 16000, 1, 9), - std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_SPEEX, + std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_SPEEX & 0x20000000, AV_CODEC_ID_SPEEX, "speex", "libspeex", CODEC_ENCODER_DECODER, 0, 32000, 1, 112), - std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_SPEEX, + std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_SPEEX & 0x10000000, AV_CODEC_ID_SPEEX, "speex", "libspeex", CODEC_ENCODER_DECODER, 0, 16000, 1, 111), - std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_SPEEX, + std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_SPEEX, AV_CODEC_ID_SPEEX, "speex", "libspeex", CODEC_ENCODER_DECODER, 0, 8000, 1, 110), - std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_PCM_ALAW, + std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_PCM_ALAW, AV_CODEC_ID_PCM_ALAW, "PCMA", "pcm_alaw", CODEC_ENCODER_DECODER, 64, 8000, 1, 8), - std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_PCM_MULAW, + std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_PCM_MULAW, AV_CODEC_ID_PCM_MULAW, "PCMU" ,"pcm_mulaw", CODEC_ENCODER_DECODER, 64, 8000, 1, 0), diff --git a/src/sip/sdp.cpp b/src/sip/sdp.cpp index cf597627c52df0249b7cc401849f20aa6e2c192d..f14060fc24848f1707c86c6450e550fcdd0d16a9 100644 --- a/src/sip/sdp.cpp +++ b/src/sip/sdp.cpp @@ -314,6 +314,14 @@ void Sdp::setLocalMediaVideoCapabilities(const std::vector<std::shared_ptr<Accou { #ifdef ENABLE_VIDEO video_codec_list_ = selectedCodecs; + // Do not expose H265 if accel is disactivated + if (not jami::Manager::instance().videoPreferences.getEncodingAccelerated()) { + for (auto it = video_codec_list_.begin(); it != video_codec_list_.end(); ++it) { + if ((*it)->systemCodecInfo.name == "H265") { + video_codec_list_.erase(it); + } + } + } #else (void) selectedCodecs; #endif