Line data Source code
1 : /*
2 : * Copyright (C) 2004-2025 Savoir-faire Linux Inc.
3 : *
4 : * This program is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 3 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * This program is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifdef HAVE_CONFIG_H
19 : #include "config.h"
20 : #endif
21 :
22 : #include "preferences.h"
23 : #include "logger.h"
24 : #include "audio/audiolayer.h"
25 : #if HAVE_OPENSL
26 : #include "audio/opensl/opensllayer.h"
27 : #else
28 : #if HAVE_ALSA
29 : #include "audio/alsa/alsalayer.h"
30 : #endif
31 : #if HAVE_JACK
32 : #include "audio/jack/jacklayer.h"
33 : #endif
34 : #if HAVE_PULSE
35 : #include "audio/pulseaudio/pulselayer.h"
36 : #endif
37 : #if HAVE_COREAUDIO
38 : #ifdef __APPLE__
39 : #include <TargetConditionals.h>
40 : #endif
41 : #if TARGET_OS_IOS
42 : #include "audio/coreaudio/ios/corelayer.h"
43 : #else
44 : #include "audio/coreaudio/osx/corelayer.h"
45 : #endif /* TARGET_OS_IOS */
46 : #endif /* HAVE_COREAUDIO */
47 : #if HAVE_PORTAUDIO
48 : #include "audio/portaudio/portaudiolayer.h"
49 : #endif
50 : #endif /* HAVE_OPENSL */
51 :
52 : #ifdef ENABLE_VIDEO
53 : #include "client/videomanager.h"
54 : #endif
55 :
56 : #pragma GCC diagnostic push
57 : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
58 : #include <yaml-cpp/yaml.h>
59 : #pragma GCC diagnostic pop
60 :
61 : #include "config/yamlparser.h"
62 : #include "connectivity/sip_utils.h"
63 : #include <sstream>
64 : #include <algorithm>
65 : #include <stdexcept>
66 : #include "fileutils.h"
67 : #include "string_utils.h"
68 :
69 : namespace jami {
70 :
71 : using yaml_utils::parseValue;
72 :
73 : constexpr const char* const Preferences::CONFIG_LABEL;
74 : const char* const Preferences::DFT_ZONE = "North America";
75 : const char* const Preferences::REGISTRATION_EXPIRE_KEY = "registrationexpire";
76 : constexpr std::string_view DEFAULT_CONFERENCE_RESOLUTION {"1280x720"};
77 :
78 : // general preferences
79 : static constexpr const char* ORDER_KEY {"order"};
80 : static constexpr const char* AUDIO_API_KEY {"audioApi"};
81 : static constexpr const char* HISTORY_LIMIT_KEY {"historyLimit"};
82 : static constexpr const char* RINGING_TIMEOUT {"ringingTimeout"};
83 : static constexpr const char* HISTORY_MAX_CALLS_KEY {"historyMaxCalls"};
84 : static constexpr const char* ZONE_TONE_CHOICE_KEY {"zoneToneChoice"};
85 : static constexpr const char* PORT_NUM_KEY {"portNum"};
86 : static constexpr const char* SEARCH_BAR_DISPLAY_KEY {"searchBarDisplay"};
87 : static constexpr const char* MD5_HASH_KEY {"md5Hash"};
88 :
89 : // voip preferences
90 : constexpr const char* const VoipPreference::CONFIG_LABEL;
91 : static constexpr const char* PLAY_DTMF_KEY {"playDtmf"};
92 : static constexpr const char* PLAY_TONES_KEY {"playTones"};
93 : static constexpr const char* PULSE_LENGTH_KEY {"pulseLength"};
94 :
95 : // audio preferences
96 : constexpr const char* const AudioPreference::CONFIG_LABEL;
97 : static constexpr const char* ALSAMAP_KEY {"alsa"};
98 : static constexpr const char* PULSEMAP_KEY {"pulse"};
99 : static constexpr const char* PORTAUDIO_KEY {"portaudio"};
100 : static constexpr const char* CARDIN_KEY {"cardIn"};
101 : static constexpr const char* CARDOUT_KEY {"cardOut"};
102 : static constexpr const char* CARLIBJAMI_KEY {"cardRing"};
103 : static constexpr const char* PLUGIN_KEY {"plugin"};
104 : static constexpr const char* SMPLRATE_KEY {"smplRate"};
105 : static constexpr const char* DEVICE_PLAYBACK_KEY {"devicePlayback"};
106 : static constexpr const char* DEVICE_RECORD_KEY {"deviceRecord"};
107 : static constexpr const char* DEVICE_RINGTONE_KEY {"deviceRingtone"};
108 : static constexpr const char* RECORDPATH_KEY {"recordPath"};
109 : static constexpr const char* ALWAYS_RECORDING_KEY {"alwaysRecording"};
110 : static constexpr const char* VOLUMEMIC_KEY {"volumeMic"};
111 : static constexpr const char* VOLUMESPKR_KEY {"volumeSpkr"};
112 : static constexpr const char* AUDIO_PROCESSOR_KEY {"audioProcessor"};
113 : static constexpr const char* NOISE_REDUCE_KEY {"noiseReduce"};
114 : static constexpr const char* AGC_KEY {"automaticGainControl"};
115 : static constexpr const char* CAPTURE_MUTED_KEY {"captureMuted"};
116 : static constexpr const char* PLAYBACK_MUTED_KEY {"playbackMuted"};
117 : static constexpr const char* VAD_KEY {"voiceActivityDetection"};
118 : static constexpr const char* ECHO_CANCEL_KEY {"echoCancel"};
119 :
120 : #ifdef ENABLE_VIDEO
121 : // video preferences
122 : constexpr const char* const VideoPreferences::CONFIG_LABEL;
123 : static constexpr const char* DECODING_ACCELERATED_KEY {"decodingAccelerated"};
124 : static constexpr const char* ENCODING_ACCELERATED_KEY {"encodingAccelerated"};
125 : static constexpr const char* RECORD_PREVIEW_KEY {"recordPreview"};
126 : static constexpr const char* RECORD_QUALITY_KEY {"recordQuality"};
127 : static constexpr const char* CONFERENCE_RESOLUTION_KEY {"conferenceResolution"};
128 : #endif
129 :
130 : #ifdef ENABLE_PLUGIN
131 : // plugin preferences
132 : constexpr const char* const PluginPreferences::CONFIG_LABEL;
133 : static constexpr const char* JAMI_PLUGIN_KEY {"pluginsEnabled"};
134 : static constexpr const char* JAMI_PLUGINS_INSTALLED_KEY {"installedPlugins"};
135 : static constexpr const char* JAMI_PLUGINS_LOADED_KEY {"loadedPlugins"};
136 : #endif
137 :
138 : static constexpr int PULSE_LENGTH_DEFAULT {250}; /** Default DTMF length */
139 : #ifndef _MSC_VER
140 : static constexpr const char* ALSA_DFT_CARD {"0"}; /** Default sound card index */
141 : #else
142 : static constexpr const char* ALSA_DFT_CARD {"-1"}; /** Default sound card index (Portaudio) */
143 : #endif // _MSC_VER
144 :
145 38 : Preferences::Preferences()
146 38 : : accountOrder_("")
147 38 : , historyLimit_(0)
148 38 : , historyMaxCalls_(20)
149 38 : , ringingTimeout_(30)
150 38 : , zoneToneChoice_(DFT_ZONE) // DFT_ZONE
151 38 : , portNum_(sip_utils::DEFAULT_SIP_PORT)
152 38 : , searchBarDisplay_(true)
153 38 : , md5Hash_(false)
154 38 : {}
155 :
156 : void
157 1706 : Preferences::verifyAccountOrder(const std::vector<std::string>& accountIDs)
158 : {
159 1706 : std::vector<std::string> tokens;
160 1706 : std::string token;
161 1706 : bool drop = false;
162 :
163 55475 : for (const auto c : accountOrder_) {
164 53769 : if (c != '/') {
165 50605 : token += c;
166 : } else {
167 3164 : if (find(accountIDs.begin(), accountIDs.end(), token) != accountIDs.end())
168 3160 : tokens.push_back(token);
169 : else {
170 4 : JAMI_DBG("Dropping nonexistent account %s", token.c_str());
171 4 : drop = true;
172 : }
173 3164 : token.clear();
174 : }
175 : }
176 :
177 1706 : if (drop) {
178 2 : accountOrder_.clear();
179 3 : for (const auto& t : tokens)
180 1 : accountOrder_ += t + '/';
181 : }
182 1706 : }
183 :
184 : void
185 796 : Preferences::addAccount(const std::string& newAccountID)
186 : {
187 : // Add the newly created account in the account order list
188 796 : if (not accountOrder_.empty())
189 532 : accountOrder_.insert(0, newAccountID + "/");
190 : else
191 264 : accountOrder_ = newAccountID + "/";
192 796 : }
193 :
194 : void
195 796 : Preferences::removeAccount(const std::string& oldAccountID)
196 : {
197 : // include the slash since we don't want to remove a partial match
198 796 : const size_t start = accountOrder_.find(oldAccountID + "/");
199 796 : if (start != std::string::npos)
200 796 : accountOrder_.erase(start, oldAccountID.length() + 1);
201 796 : }
202 :
203 : void
204 1706 : Preferences::serialize(YAML::Emitter& out) const
205 : {
206 1706 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
207 :
208 1706 : out << YAML::Key << HISTORY_LIMIT_KEY << YAML::Value << historyLimit_;
209 1706 : out << YAML::Key << RINGING_TIMEOUT << YAML::Value << ringingTimeout_;
210 1706 : out << YAML::Key << HISTORY_MAX_CALLS_KEY << YAML::Value << historyMaxCalls_;
211 1706 : out << YAML::Key << MD5_HASH_KEY << YAML::Value << md5Hash_;
212 1706 : out << YAML::Key << ORDER_KEY << YAML::Value << accountOrder_;
213 1706 : out << YAML::Key << PORT_NUM_KEY << YAML::Value << portNum_;
214 1706 : out << YAML::Key << SEARCH_BAR_DISPLAY_KEY << YAML::Value << searchBarDisplay_;
215 1706 : out << YAML::Key << ZONE_TONE_CHOICE_KEY << YAML::Value << zoneToneChoice_;
216 1706 : out << YAML::EndMap;
217 1706 : }
218 :
219 : void
220 35 : Preferences::unserialize(const YAML::Node& in)
221 : {
222 35 : const auto& node = in[CONFIG_LABEL];
223 :
224 35 : parseValue(node, ORDER_KEY, accountOrder_);
225 29 : parseValue(node, HISTORY_LIMIT_KEY, historyLimit_);
226 29 : parseValue(node, RINGING_TIMEOUT, ringingTimeout_);
227 29 : parseValue(node, HISTORY_MAX_CALLS_KEY, historyMaxCalls_);
228 29 : parseValue(node, ZONE_TONE_CHOICE_KEY, zoneToneChoice_);
229 29 : parseValue(node, PORT_NUM_KEY, portNum_);
230 29 : parseValue(node, SEARCH_BAR_DISPLAY_KEY, searchBarDisplay_);
231 29 : parseValue(node, MD5_HASH_KEY, md5Hash_);
232 35 : }
233 :
234 38 : VoipPreference::VoipPreference()
235 38 : : playDtmf_(true)
236 38 : , playTones_(true)
237 38 : , pulseLength_(PULSE_LENGTH_DEFAULT)
238 38 : {}
239 :
240 : void
241 1706 : VoipPreference::serialize(YAML::Emitter& out) const
242 : {
243 1706 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
244 1706 : out << YAML::Key << PLAY_DTMF_KEY << YAML::Value << playDtmf_;
245 1706 : out << YAML::Key << PLAY_TONES_KEY << YAML::Value << playTones_;
246 1706 : out << YAML::Key << PULSE_LENGTH_KEY << YAML::Value << pulseLength_;
247 1706 : out << YAML::EndMap;
248 1706 : }
249 :
250 : void
251 29 : VoipPreference::unserialize(const YAML::Node& in)
252 : {
253 29 : const auto& node = in[CONFIG_LABEL];
254 29 : parseValue(node, PLAY_DTMF_KEY, playDtmf_);
255 29 : parseValue(node, PLAY_TONES_KEY, playTones_);
256 29 : parseValue(node, PULSE_LENGTH_KEY, pulseLength_);
257 29 : }
258 :
259 38 : AudioPreference::AudioPreference()
260 38 : : audioApi_(PULSEAUDIO_API_STR)
261 38 : , alsaCardin_(atoi(ALSA_DFT_CARD))
262 38 : , alsaCardout_(atoi(ALSA_DFT_CARD))
263 38 : , alsaCardRingtone_(atoi(ALSA_DFT_CARD))
264 38 : , alsaPlugin_("default")
265 38 : , alsaSmplrate_(44100)
266 38 : , pulseDevicePlayback_("")
267 38 : , pulseDeviceRecord_("")
268 38 : , pulseDeviceRingtone_("")
269 38 : , recordpath_("")
270 38 : , alwaysRecording_(false)
271 38 : , volumemic_(1.0)
272 38 : , volumespkr_(1.0)
273 38 : , audioProcessor_("webrtc")
274 38 : , denoise_("auto")
275 38 : , agcEnabled_(true)
276 38 : , vadEnabled_(true)
277 38 : , echoCanceller_("auto")
278 38 : , captureMuted_(false)
279 76 : , playbackMuted_(false)
280 38 : {}
281 :
282 : #if HAVE_ALSA
283 :
284 : static const int ALSA_DFT_CARD_ID = 0; // Index of the default soundcard
285 :
286 : static void
287 96 : checkSoundCard(int& card, AudioDeviceType type)
288 : {
289 96 : if (not AlsaLayer::soundCardIndexExists(card, type)) {
290 96 : JAMI_WARN(" Card with index %d doesn't exist or is unusable.", card);
291 96 : card = ALSA_DFT_CARD_ID;
292 : }
293 96 : }
294 : #endif
295 :
296 : AudioLayer*
297 32 : AudioPreference::createAudioLayer()
298 : {
299 : #if HAVE_OPENSL
300 : return new OpenSLLayer(*this);
301 : #else
302 :
303 : #if HAVE_JACK
304 : if (audioApi_ == JACK_API_STR) {
305 : try {
306 : if (auto ret = system("jack_lsp > /dev/null"))
307 : throw std::runtime_error("Error running jack_lsp: " + std::to_string(ret));
308 : return new JackLayer(*this);
309 : } catch (const std::runtime_error& e) {
310 : JAMI_ERR("%s", e.what());
311 : #if HAVE_PULSE
312 : audioApi_ = PULSEAUDIO_API_STR;
313 : #elif HAVE_ALSA
314 : audioApi_ = ALSA_API_STR;
315 : #elif HAVE_COREAUDIO
316 : audioApi_ = COREAUDIO_API_STR;
317 : #elif HAVE_PORTAUDIO
318 : audioApi_ = PORTAUDIO_API_STR;
319 : #else
320 : throw;
321 : #endif // HAVE_PULSE
322 : }
323 : }
324 : #endif // HAVE_JACK
325 :
326 : #if HAVE_PULSE
327 :
328 32 : if (audioApi_ == PULSEAUDIO_API_STR) {
329 : try {
330 3 : return new PulseLayer(*this);
331 3 : } catch (const std::runtime_error& e) {
332 3 : JAMI_WARN("Unable to create pulseaudio layer, falling back to ALSA");
333 3 : }
334 : }
335 :
336 : #endif
337 :
338 : #if HAVE_ALSA
339 :
340 32 : audioApi_ = ALSA_API_STR;
341 32 : checkSoundCard(alsaCardin_, AudioDeviceType::CAPTURE);
342 32 : checkSoundCard(alsaCardout_, AudioDeviceType::PLAYBACK);
343 32 : checkSoundCard(alsaCardRingtone_, AudioDeviceType::RINGTONE);
344 :
345 32 : return new AlsaLayer(*this);
346 : #endif
347 :
348 : #if HAVE_COREAUDIO
349 : audioApi_ = COREAUDIO_API_STR;
350 : try {
351 : return new CoreLayer(*this);
352 : } catch (const std::runtime_error& e) {
353 : JAMI_WARN("Unable to create coreaudio layer. There will be no sound.");
354 : }
355 : return NULL;
356 : #endif
357 :
358 : #if HAVE_PORTAUDIO
359 : audioApi_ = PORTAUDIO_API_STR;
360 : try {
361 : return new PortAudioLayer(*this);
362 : } catch (const std::runtime_error& e) {
363 : JAMI_WARN("Unable to create PortAudio layer. There will be no sound.");
364 : }
365 : return nullptr;
366 : #endif
367 : #endif // HAVE_OPENSL
368 :
369 : JAMI_WARN("No audio layer provided");
370 : return nullptr;
371 : }
372 :
373 : std::vector<std::string>
374 0 : AudioPreference::getSupportedAudioManagers()
375 : {
376 : return {
377 : #if HAVE_OPENSL
378 : OPENSL_API_STR,
379 : #endif
380 : #if HAVE_ALSA
381 : ALSA_API_STR,
382 : #endif
383 : #if HAVE_PULSE
384 : PULSEAUDIO_API_STR,
385 : #endif
386 : #if HAVE_JACK
387 : JACK_API_STR,
388 : #endif
389 : #if HAVE_COREAUDIO
390 : COREAUDIO_API_STR,
391 : #endif
392 : #if HAVE_PORTAUDIO
393 : PORTAUDIO_API_STR,
394 : #endif
395 0 : };
396 : }
397 :
398 : void
399 1706 : AudioPreference::serialize(YAML::Emitter& out) const
400 : {
401 1706 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
402 : // alsa submap
403 1706 : out << YAML::Key << ALSAMAP_KEY << YAML::Value << YAML::BeginMap;
404 1706 : out << YAML::Key << CARDIN_KEY << YAML::Value << alsaCardin_;
405 1706 : out << YAML::Key << CARDOUT_KEY << YAML::Value << alsaCardout_;
406 1706 : out << YAML::Key << CARLIBJAMI_KEY << YAML::Value << alsaCardRingtone_;
407 1706 : out << YAML::Key << PLUGIN_KEY << YAML::Value << alsaPlugin_;
408 1706 : out << YAML::Key << SMPLRATE_KEY << YAML::Value << alsaSmplrate_;
409 1706 : out << YAML::EndMap;
410 :
411 : // common options
412 1706 : out << YAML::Key << ALWAYS_RECORDING_KEY << YAML::Value << alwaysRecording_;
413 1706 : out << YAML::Key << AUDIO_API_KEY << YAML::Value << audioApi_;
414 1706 : out << YAML::Key << CAPTURE_MUTED_KEY << YAML::Value << captureMuted_;
415 1706 : out << YAML::Key << PLAYBACK_MUTED_KEY << YAML::Value << playbackMuted_;
416 :
417 : // pulse submap
418 1706 : out << YAML::Key << PULSEMAP_KEY << YAML::Value << YAML::BeginMap;
419 1706 : out << YAML::Key << DEVICE_PLAYBACK_KEY << YAML::Value << pulseDevicePlayback_;
420 1706 : out << YAML::Key << DEVICE_RECORD_KEY << YAML::Value << pulseDeviceRecord_;
421 1706 : out << YAML::Key << DEVICE_RINGTONE_KEY << YAML::Value << pulseDeviceRingtone_;
422 1706 : out << YAML::EndMap;
423 :
424 : // portaudio submap
425 1706 : out << YAML::Key << PORTAUDIO_KEY << YAML::Value << YAML::BeginMap;
426 1706 : out << YAML::Key << DEVICE_PLAYBACK_KEY << YAML::Value << portaudioDevicePlayback_;
427 1706 : out << YAML::Key << DEVICE_RECORD_KEY << YAML::Value << portaudioDeviceRecord_;
428 1706 : out << YAML::Key << DEVICE_RINGTONE_KEY << YAML::Value << portaudioDeviceRingtone_;
429 1706 : out << YAML::EndMap;
430 :
431 : // more common options!
432 1706 : out << YAML::Key << RECORDPATH_KEY << YAML::Value << recordpath_;
433 1706 : out << YAML::Key << VOLUMEMIC_KEY << YAML::Value << volumemic_;
434 1706 : out << YAML::Key << VOLUMESPKR_KEY << YAML::Value << volumespkr_;
435 :
436 : // audio processor options, not in a submap
437 1706 : out << YAML::Key << AUDIO_PROCESSOR_KEY << YAML::Value << audioProcessor_;
438 1706 : out << YAML::Key << AGC_KEY << YAML::Value << agcEnabled_;
439 1706 : out << YAML::Key << VAD_KEY << YAML::Value << vadEnabled_;
440 1706 : out << YAML::Key << NOISE_REDUCE_KEY << YAML::Value << denoise_;
441 1706 : out << YAML::Key << ECHO_CANCEL_KEY << YAML::Value << echoCanceller_;
442 1706 : out << YAML::EndMap;
443 1706 : }
444 :
445 : bool
446 0 : AudioPreference::setRecordPath(const std::string& r)
447 : {
448 0 : std::string path = fileutils::expand_path(r);
449 0 : if (fileutils::isDirectoryWritable(path)) {
450 0 : recordpath_ = path;
451 0 : return true;
452 : } else {
453 0 : JAMI_ERR("%s is not writable, unable to be the recording path", path.c_str());
454 0 : return false;
455 : }
456 0 : }
457 :
458 : void
459 29 : AudioPreference::unserialize(const YAML::Node& in)
460 : {
461 29 : const auto& node = in[CONFIG_LABEL];
462 :
463 : // alsa submap
464 29 : const auto& alsa = node[ALSAMAP_KEY];
465 :
466 29 : parseValue(alsa, CARDIN_KEY, alsaCardin_);
467 29 : parseValue(alsa, CARDOUT_KEY, alsaCardout_);
468 29 : parseValue(alsa, CARLIBJAMI_KEY, alsaCardRingtone_);
469 29 : parseValue(alsa, PLUGIN_KEY, alsaPlugin_);
470 29 : parseValue(alsa, SMPLRATE_KEY, alsaSmplrate_);
471 :
472 : // common options
473 29 : parseValue(node, ALWAYS_RECORDING_KEY, alwaysRecording_);
474 29 : parseValue(node, AUDIO_API_KEY, audioApi_);
475 29 : parseValue(node, AGC_KEY, agcEnabled_);
476 29 : parseValue(node, CAPTURE_MUTED_KEY, captureMuted_);
477 29 : parseValue(node, NOISE_REDUCE_KEY, denoise_);
478 29 : parseValue(node, PLAYBACK_MUTED_KEY, playbackMuted_);
479 :
480 : // pulse submap
481 29 : const auto& pulse = node[PULSEMAP_KEY];
482 29 : parseValue(pulse, DEVICE_PLAYBACK_KEY, pulseDevicePlayback_);
483 29 : parseValue(pulse, DEVICE_RECORD_KEY, pulseDeviceRecord_);
484 29 : parseValue(pulse, DEVICE_RINGTONE_KEY, pulseDeviceRingtone_);
485 :
486 : // portaudio submap
487 29 : const auto& portaudio = node[PORTAUDIO_KEY];
488 29 : parseValue(portaudio, DEVICE_PLAYBACK_KEY, portaudioDevicePlayback_);
489 29 : parseValue(portaudio, DEVICE_RECORD_KEY, portaudioDeviceRecord_);
490 29 : parseValue(portaudio, DEVICE_RINGTONE_KEY, portaudioDeviceRingtone_);
491 :
492 : // more common options!
493 29 : parseValue(node, RECORDPATH_KEY, recordpath_);
494 29 : parseValue(node, VOLUMEMIC_KEY, volumemic_);
495 29 : parseValue(node, VOLUMESPKR_KEY, volumespkr_);
496 29 : parseValue(node, AUDIO_PROCESSOR_KEY, audioProcessor_);
497 29 : parseValue(node, VAD_KEY, vadEnabled_);
498 29 : parseValue(node, ECHO_CANCEL_KEY, echoCanceller_);
499 29 : }
500 :
501 : #ifdef ENABLE_VIDEO
502 38 : VideoPreferences::VideoPreferences()
503 38 : : decodingAccelerated_(true)
504 38 : , encodingAccelerated_(false)
505 38 : , recordPreview_(true)
506 38 : , recordQuality_(0)
507 38 : , conferenceResolution_(DEFAULT_CONFERENCE_RESOLUTION)
508 38 : {}
509 :
510 : void
511 1706 : VideoPreferences::serialize(YAML::Emitter& out) const
512 : {
513 1706 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
514 1706 : out << YAML::Key << RECORD_PREVIEW_KEY << YAML::Value << recordPreview_;
515 1706 : out << YAML::Key << RECORD_QUALITY_KEY << YAML::Value << recordQuality_;
516 : #ifdef ENABLE_HWACCEL
517 1706 : out << YAML::Key << DECODING_ACCELERATED_KEY << YAML::Value << decodingAccelerated_;
518 1706 : out << YAML::Key << ENCODING_ACCELERATED_KEY << YAML::Value << encodingAccelerated_;
519 : #endif
520 1706 : out << YAML::Key << CONFERENCE_RESOLUTION_KEY << YAML::Value << conferenceResolution_;
521 1706 : if (auto dm = getVideoDeviceMonitor())
522 1700 : dm->serialize(out);
523 1706 : out << YAML::EndMap;
524 1706 : }
525 :
526 : void
527 29 : VideoPreferences::unserialize(const YAML::Node& in)
528 : {
529 : // values may or may not be present
530 29 : const auto& node = in[CONFIG_LABEL];
531 : try {
532 29 : parseValue(node, RECORD_PREVIEW_KEY, recordPreview_);
533 29 : parseValue(node, RECORD_QUALITY_KEY, recordQuality_);
534 0 : } catch (...) {
535 0 : recordPreview_ = true;
536 0 : recordQuality_ = 0;
537 0 : }
538 : #ifdef ENABLE_HWACCEL
539 : try {
540 29 : parseValue(node, DECODING_ACCELERATED_KEY, decodingAccelerated_);
541 29 : parseValue(node, ENCODING_ACCELERATED_KEY, encodingAccelerated_);
542 0 : } catch (...) {
543 0 : decodingAccelerated_ = true;
544 0 : encodingAccelerated_ = false;
545 0 : }
546 : #endif
547 : try {
548 29 : parseValue(node, CONFERENCE_RESOLUTION_KEY, conferenceResolution_);
549 0 : } catch (...) {
550 0 : conferenceResolution_ = DEFAULT_CONFERENCE_RESOLUTION;
551 0 : }
552 29 : if (auto dm = getVideoDeviceMonitor())
553 0 : dm->unserialize(in);
554 29 : }
555 : #endif // ENABLE_VIDEO
556 :
557 : #ifdef ENABLE_PLUGIN
558 38 : PluginPreferences::PluginPreferences()
559 38 : : pluginsEnabled_(false)
560 38 : {}
561 :
562 : void
563 1706 : PluginPreferences::serialize(YAML::Emitter& out) const
564 : {
565 1706 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
566 1706 : out << YAML::Key << JAMI_PLUGIN_KEY << YAML::Value << pluginsEnabled_;
567 1706 : out << YAML::Key << JAMI_PLUGINS_INSTALLED_KEY << YAML::Value << installedPlugins_;
568 1706 : out << YAML::Key << JAMI_PLUGINS_LOADED_KEY << YAML::Value << loadedPlugins_;
569 1706 : out << YAML::EndMap;
570 1706 : }
571 :
572 : void
573 29 : PluginPreferences::unserialize(const YAML::Node& in)
574 : {
575 : // values may or may not be present
576 29 : const auto& node = in[CONFIG_LABEL];
577 : try {
578 29 : parseValue(node, JAMI_PLUGIN_KEY, pluginsEnabled_);
579 0 : } catch (...) {
580 0 : pluginsEnabled_ = false;
581 0 : }
582 :
583 29 : const auto& installedPluginsNode = node[JAMI_PLUGINS_INSTALLED_KEY];
584 : try {
585 29 : installedPlugins_ = yaml_utils::parseVector(installedPluginsNode);
586 0 : } catch (...) {
587 0 : }
588 :
589 29 : const auto& loadedPluginsNode = node[JAMI_PLUGINS_LOADED_KEY];
590 : try {
591 29 : loadedPlugins_ = yaml_utils::parseVector(loadedPluginsNode);
592 0 : } catch (...) {
593 : // loadedPlugins_ = {};
594 0 : }
595 29 : }
596 : #endif // ENABLE_PLUGIN
597 :
598 : } // namespace jami
|