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 39 : Preferences::Preferences()
146 39 : : accountOrder_("")
147 39 : , historyLimit_(0)
148 39 : , historyMaxCalls_(20)
149 39 : , ringingTimeout_(30)
150 39 : , zoneToneChoice_(DFT_ZONE) // DFT_ZONE
151 39 : , portNum_(sip_utils::DEFAULT_SIP_PORT)
152 39 : , searchBarDisplay_(true)
153 39 : , md5Hash_(false)
154 39 : {}
155 :
156 : void
157 1442 : Preferences::verifyAccountOrder(const std::vector<std::string>& accountIDs)
158 : {
159 1442 : std::vector<std::string> tokens;
160 1442 : std::string token;
161 1442 : bool drop = false;
162 :
163 48212 : for (const auto c : accountOrder_) {
164 46770 : if (c != '/') {
165 44045 : token += c;
166 : } else {
167 2725 : if (find(accountIDs.begin(), accountIDs.end(), token) != accountIDs.end())
168 2722 : tokens.push_back(token);
169 : else {
170 3 : JAMI_DBG("Dropping nonexistent account %s", token.c_str());
171 3 : drop = true;
172 : }
173 2725 : token.clear();
174 : }
175 : }
176 :
177 1442 : if (drop) {
178 1 : accountOrder_.clear();
179 2 : for (const auto& t : tokens)
180 1 : accountOrder_ += t + '/';
181 : }
182 1442 : }
183 :
184 : void
185 654 : Preferences::addAccount(const std::string& newAccountID)
186 : {
187 : // Add the newly created account in the account order list
188 654 : if (not accountOrder_.empty())
189 437 : accountOrder_.insert(0, newAccountID + "/");
190 : else
191 217 : accountOrder_ = newAccountID + "/";
192 654 : }
193 :
194 : void
195 655 : Preferences::removeAccount(const std::string& oldAccountID)
196 : {
197 : // include the slash since we don't want to remove a partial match
198 655 : const size_t start = accountOrder_.find(oldAccountID + "/");
199 655 : if (start != std::string::npos)
200 654 : accountOrder_.erase(start, oldAccountID.length() + 1);
201 655 : }
202 :
203 : void
204 1442 : Preferences::serialize(YAML::Emitter& out) const
205 : {
206 1442 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
207 :
208 1442 : out << YAML::Key << HISTORY_LIMIT_KEY << YAML::Value << historyLimit_;
209 1442 : out << YAML::Key << RINGING_TIMEOUT << YAML::Value << ringingTimeout_;
210 1442 : out << YAML::Key << HISTORY_MAX_CALLS_KEY << YAML::Value << historyMaxCalls_;
211 1442 : out << YAML::Key << MD5_HASH_KEY << YAML::Value << md5Hash_;
212 1442 : out << YAML::Key << ORDER_KEY << YAML::Value << accountOrder_;
213 1442 : out << YAML::Key << PORT_NUM_KEY << YAML::Value << portNum_;
214 1442 : out << YAML::Key << SEARCH_BAR_DISPLAY_KEY << YAML::Value << searchBarDisplay_;
215 1442 : out << YAML::Key << ZONE_TONE_CHOICE_KEY << YAML::Value << zoneToneChoice_;
216 1442 : out << YAML::EndMap;
217 1442 : }
218 :
219 : void
220 36 : Preferences::unserialize(const YAML::Node& in)
221 : {
222 36 : const auto& node = in[CONFIG_LABEL];
223 :
224 36 : parseValue(node, ORDER_KEY, accountOrder_);
225 30 : parseValue(node, HISTORY_LIMIT_KEY, historyLimit_);
226 30 : parseValue(node, RINGING_TIMEOUT, ringingTimeout_);
227 30 : parseValue(node, HISTORY_MAX_CALLS_KEY, historyMaxCalls_);
228 30 : parseValue(node, ZONE_TONE_CHOICE_KEY, zoneToneChoice_);
229 30 : parseValue(node, PORT_NUM_KEY, portNum_);
230 30 : parseValue(node, SEARCH_BAR_DISPLAY_KEY, searchBarDisplay_);
231 30 : parseValue(node, MD5_HASH_KEY, md5Hash_);
232 36 : }
233 :
234 39 : VoipPreference::VoipPreference()
235 39 : : playDtmf_(true)
236 39 : , playTones_(true)
237 39 : , pulseLength_(PULSE_LENGTH_DEFAULT)
238 39 : {}
239 :
240 : void
241 1442 : VoipPreference::serialize(YAML::Emitter& out) const
242 : {
243 1442 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
244 1442 : out << YAML::Key << PLAY_DTMF_KEY << YAML::Value << playDtmf_;
245 1442 : out << YAML::Key << PLAY_TONES_KEY << YAML::Value << playTones_;
246 1442 : out << YAML::Key << PULSE_LENGTH_KEY << YAML::Value << pulseLength_;
247 1442 : out << YAML::EndMap;
248 1442 : }
249 :
250 : void
251 30 : VoipPreference::unserialize(const YAML::Node& in)
252 : {
253 30 : const auto& node = in[CONFIG_LABEL];
254 30 : parseValue(node, PLAY_DTMF_KEY, playDtmf_);
255 30 : parseValue(node, PLAY_TONES_KEY, playTones_);
256 30 : parseValue(node, PULSE_LENGTH_KEY, pulseLength_);
257 30 : }
258 :
259 39 : AudioPreference::AudioPreference()
260 39 : : audioApi_(PULSEAUDIO_API_STR)
261 39 : , alsaCardin_(atoi(ALSA_DFT_CARD))
262 39 : , alsaCardout_(atoi(ALSA_DFT_CARD))
263 39 : , alsaCardRingtone_(atoi(ALSA_DFT_CARD))
264 39 : , alsaPlugin_("default")
265 39 : , alsaSmplrate_(44100)
266 39 : , pulseDevicePlayback_("")
267 39 : , pulseDeviceRecord_("")
268 39 : , pulseDeviceRingtone_("")
269 39 : , recordpath_("")
270 39 : , alwaysRecording_(false)
271 39 : , volumemic_(1.0)
272 39 : , volumespkr_(1.0)
273 39 : , audioProcessor_("webrtc")
274 39 : , denoise_("auto")
275 39 : , agcEnabled_(true)
276 39 : , vadEnabled_(true)
277 39 : , echoCanceller_("auto")
278 39 : , captureMuted_(false)
279 78 : , playbackMuted_(false)
280 39 : {}
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 99 : checkSoundCard(int& card, AudioDeviceType type)
288 : {
289 99 : if (not AlsaLayer::soundCardIndexExists(card, type)) {
290 99 : JAMI_WARN(" Card with index %d doesn't exist or is unusable.", card);
291 99 : card = ALSA_DFT_CARD_ID;
292 : }
293 99 : }
294 : #endif
295 :
296 : AudioLayer*
297 33 : 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 33 : 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 33 : audioApi_ = ALSA_API_STR;
341 33 : checkSoundCard(alsaCardin_, AudioDeviceType::CAPTURE);
342 33 : checkSoundCard(alsaCardout_, AudioDeviceType::PLAYBACK);
343 33 : checkSoundCard(alsaCardRingtone_, AudioDeviceType::RINGTONE);
344 :
345 33 : 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 : {
378 : #if HAVE_OPENSL
379 : OPENSL_API_STR,
380 : #endif
381 : #if HAVE_ALSA
382 : ALSA_API_STR,
383 : #endif
384 : #if HAVE_PULSE
385 : PULSEAUDIO_API_STR,
386 : #endif
387 : #if HAVE_JACK
388 : JACK_API_STR,
389 : #endif
390 : #if HAVE_COREAUDIO
391 : COREAUDIO_API_STR,
392 : #endif
393 : #if HAVE_PORTAUDIO
394 : PORTAUDIO_API_STR,
395 : #endif
396 0 : };
397 : }
398 :
399 : void
400 1442 : AudioPreference::serialize(YAML::Emitter& out) const
401 : {
402 1442 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
403 : // alsa submap
404 1442 : out << YAML::Key << ALSAMAP_KEY << YAML::Value << YAML::BeginMap;
405 1442 : out << YAML::Key << CARDIN_KEY << YAML::Value << alsaCardin_;
406 1442 : out << YAML::Key << CARDOUT_KEY << YAML::Value << alsaCardout_;
407 1442 : out << YAML::Key << CARLIBJAMI_KEY << YAML::Value << alsaCardRingtone_;
408 1442 : out << YAML::Key << PLUGIN_KEY << YAML::Value << alsaPlugin_;
409 1442 : out << YAML::Key << SMPLRATE_KEY << YAML::Value << alsaSmplrate_;
410 1442 : out << YAML::EndMap;
411 :
412 : // common options
413 1442 : out << YAML::Key << ALWAYS_RECORDING_KEY << YAML::Value << alwaysRecording_;
414 1442 : out << YAML::Key << AUDIO_API_KEY << YAML::Value << audioApi_;
415 1442 : out << YAML::Key << CAPTURE_MUTED_KEY << YAML::Value << captureMuted_;
416 1442 : out << YAML::Key << PLAYBACK_MUTED_KEY << YAML::Value << playbackMuted_;
417 :
418 : // pulse submap
419 1442 : out << YAML::Key << PULSEMAP_KEY << YAML::Value << YAML::BeginMap;
420 1442 : out << YAML::Key << DEVICE_PLAYBACK_KEY << YAML::Value << pulseDevicePlayback_;
421 1442 : out << YAML::Key << DEVICE_RECORD_KEY << YAML::Value << pulseDeviceRecord_;
422 1442 : out << YAML::Key << DEVICE_RINGTONE_KEY << YAML::Value << pulseDeviceRingtone_;
423 1442 : out << YAML::EndMap;
424 :
425 : // portaudio submap
426 1442 : out << YAML::Key << PORTAUDIO_KEY << YAML::Value << YAML::BeginMap;
427 1442 : out << YAML::Key << DEVICE_PLAYBACK_KEY << YAML::Value << portaudioDevicePlayback_;
428 1442 : out << YAML::Key << DEVICE_RECORD_KEY << YAML::Value << portaudioDeviceRecord_;
429 1442 : out << YAML::Key << DEVICE_RINGTONE_KEY << YAML::Value << portaudioDeviceRingtone_;
430 1442 : out << YAML::EndMap;
431 :
432 : // more common options!
433 1442 : out << YAML::Key << RECORDPATH_KEY << YAML::Value << recordpath_;
434 1442 : out << YAML::Key << VOLUMEMIC_KEY << YAML::Value << volumemic_;
435 1442 : out << YAML::Key << VOLUMESPKR_KEY << YAML::Value << volumespkr_;
436 :
437 : // audio processor options, not in a submap
438 1442 : out << YAML::Key << AUDIO_PROCESSOR_KEY << YAML::Value << audioProcessor_;
439 1442 : out << YAML::Key << AGC_KEY << YAML::Value << agcEnabled_;
440 1442 : out << YAML::Key << VAD_KEY << YAML::Value << vadEnabled_;
441 1442 : out << YAML::Key << NOISE_REDUCE_KEY << YAML::Value << denoise_;
442 1442 : out << YAML::Key << ECHO_CANCEL_KEY << YAML::Value << echoCanceller_;
443 1442 : out << YAML::EndMap;
444 1442 : }
445 :
446 : bool
447 5 : AudioPreference::setRecordPath(const std::string& r)
448 : {
449 5 : std::string path = fileutils::expand_path(r);
450 5 : if (fileutils::isDirectoryWritable(path)) {
451 5 : recordpath_ = path;
452 5 : return true;
453 : } else {
454 0 : JAMI_ERR("%s is not writable, unable to be the recording path", path.c_str());
455 0 : return false;
456 : }
457 5 : }
458 :
459 : void
460 30 : AudioPreference::unserialize(const YAML::Node& in)
461 : {
462 30 : const auto& node = in[CONFIG_LABEL];
463 :
464 : // alsa submap
465 30 : const auto& alsa = node[ALSAMAP_KEY];
466 :
467 30 : parseValue(alsa, CARDIN_KEY, alsaCardin_);
468 30 : parseValue(alsa, CARDOUT_KEY, alsaCardout_);
469 30 : parseValue(alsa, CARLIBJAMI_KEY, alsaCardRingtone_);
470 30 : parseValue(alsa, PLUGIN_KEY, alsaPlugin_);
471 30 : parseValue(alsa, SMPLRATE_KEY, alsaSmplrate_);
472 :
473 : // common options
474 30 : parseValue(node, ALWAYS_RECORDING_KEY, alwaysRecording_);
475 30 : parseValue(node, AUDIO_API_KEY, audioApi_);
476 30 : parseValue(node, AGC_KEY, agcEnabled_);
477 30 : parseValue(node, CAPTURE_MUTED_KEY, captureMuted_);
478 30 : parseValue(node, NOISE_REDUCE_KEY, denoise_);
479 30 : parseValue(node, PLAYBACK_MUTED_KEY, playbackMuted_);
480 :
481 : // pulse submap
482 30 : const auto& pulse = node[PULSEMAP_KEY];
483 30 : parseValue(pulse, DEVICE_PLAYBACK_KEY, pulseDevicePlayback_);
484 30 : parseValue(pulse, DEVICE_RECORD_KEY, pulseDeviceRecord_);
485 30 : parseValue(pulse, DEVICE_RINGTONE_KEY, pulseDeviceRingtone_);
486 :
487 : // portaudio submap
488 30 : const auto& portaudio = node[PORTAUDIO_KEY];
489 30 : parseValue(portaudio, DEVICE_PLAYBACK_KEY, portaudioDevicePlayback_);
490 30 : parseValue(portaudio, DEVICE_RECORD_KEY, portaudioDeviceRecord_);
491 30 : parseValue(portaudio, DEVICE_RINGTONE_KEY, portaudioDeviceRingtone_);
492 :
493 : // more common options!
494 30 : parseValue(node, RECORDPATH_KEY, recordpath_);
495 30 : parseValue(node, VOLUMEMIC_KEY, volumemic_);
496 30 : parseValue(node, VOLUMESPKR_KEY, volumespkr_);
497 30 : parseValue(node, AUDIO_PROCESSOR_KEY, audioProcessor_);
498 30 : parseValue(node, VAD_KEY, vadEnabled_);
499 30 : parseValue(node, ECHO_CANCEL_KEY, echoCanceller_);
500 30 : }
501 :
502 : #ifdef ENABLE_VIDEO
503 39 : VideoPreferences::VideoPreferences()
504 39 : : decodingAccelerated_(true)
505 39 : , encodingAccelerated_(false)
506 39 : , recordPreview_(true)
507 39 : , recordQuality_(0)
508 39 : , conferenceResolution_(DEFAULT_CONFERENCE_RESOLUTION)
509 39 : {}
510 :
511 : void
512 1442 : VideoPreferences::serialize(YAML::Emitter& out) const
513 : {
514 1442 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
515 1442 : out << YAML::Key << RECORD_PREVIEW_KEY << YAML::Value << recordPreview_;
516 1442 : out << YAML::Key << RECORD_QUALITY_KEY << YAML::Value << recordQuality_;
517 : #ifdef ENABLE_HWACCEL
518 1442 : out << YAML::Key << DECODING_ACCELERATED_KEY << YAML::Value << decodingAccelerated_;
519 1442 : out << YAML::Key << ENCODING_ACCELERATED_KEY << YAML::Value << encodingAccelerated_;
520 : #endif
521 1442 : out << YAML::Key << CONFERENCE_RESOLUTION_KEY << YAML::Value << conferenceResolution_;
522 1442 : if (auto dm = getVideoDeviceMonitor())
523 1436 : dm->serialize(out);
524 1442 : out << YAML::EndMap;
525 1442 : }
526 :
527 : void
528 30 : VideoPreferences::unserialize(const YAML::Node& in)
529 : {
530 : // values may or may not be present
531 30 : const auto& node = in[CONFIG_LABEL];
532 : try {
533 30 : parseValue(node, RECORD_PREVIEW_KEY, recordPreview_);
534 30 : parseValue(node, RECORD_QUALITY_KEY, recordQuality_);
535 0 : } catch (...) {
536 0 : recordPreview_ = true;
537 0 : recordQuality_ = 0;
538 0 : }
539 : #ifdef ENABLE_HWACCEL
540 : try {
541 30 : parseValue(node, DECODING_ACCELERATED_KEY, decodingAccelerated_);
542 30 : parseValue(node, ENCODING_ACCELERATED_KEY, encodingAccelerated_);
543 0 : } catch (...) {
544 0 : decodingAccelerated_ = true;
545 0 : encodingAccelerated_ = false;
546 0 : }
547 : #endif
548 : try {
549 30 : parseValue(node, CONFERENCE_RESOLUTION_KEY, conferenceResolution_);
550 0 : } catch (...) {
551 0 : conferenceResolution_ = DEFAULT_CONFERENCE_RESOLUTION;
552 0 : }
553 30 : if (auto dm = getVideoDeviceMonitor())
554 0 : dm->unserialize(in);
555 30 : }
556 : #endif // ENABLE_VIDEO
557 :
558 : #ifdef ENABLE_PLUGIN
559 39 : PluginPreferences::PluginPreferences()
560 39 : : pluginsEnabled_(false)
561 39 : {}
562 :
563 : void
564 1442 : PluginPreferences::serialize(YAML::Emitter& out) const
565 : {
566 1442 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
567 1442 : out << YAML::Key << JAMI_PLUGIN_KEY << YAML::Value << pluginsEnabled_;
568 1442 : out << YAML::Key << JAMI_PLUGINS_INSTALLED_KEY << YAML::Value << installedPlugins_;
569 1442 : out << YAML::Key << JAMI_PLUGINS_LOADED_KEY << YAML::Value << loadedPlugins_;
570 1442 : out << YAML::EndMap;
571 1442 : }
572 :
573 : void
574 30 : PluginPreferences::unserialize(const YAML::Node& in)
575 : {
576 : // values may or may not be present
577 30 : const auto& node = in[CONFIG_LABEL];
578 : try {
579 30 : parseValue(node, JAMI_PLUGIN_KEY, pluginsEnabled_);
580 0 : } catch (...) {
581 0 : pluginsEnabled_ = false;
582 0 : }
583 :
584 30 : const auto& installedPluginsNode = node[JAMI_PLUGINS_INSTALLED_KEY];
585 : try {
586 30 : installedPlugins_ = yaml_utils::parseVector(installedPluginsNode);
587 0 : } catch (...) {
588 0 : }
589 :
590 30 : const auto& loadedPluginsNode = node[JAMI_PLUGINS_LOADED_KEY];
591 : try {
592 30 : loadedPlugins_ = yaml_utils::parseVector(loadedPluginsNode);
593 0 : } catch (...) {
594 : // loadedPlugins_ = {};
595 0 : }
596 30 : }
597 : #endif // ENABLE_PLUGIN
598 :
599 : } // namespace jami
|