Line data Source code
1 : /*
2 : * Copyright (C) 2004-2024 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 1738 : Preferences::verifyAccountOrder(const std::vector<std::string>& accountIDs)
158 : {
159 1738 : std::vector<std::string> tokens;
160 1738 : std::string token;
161 1738 : bool drop = false;
162 :
163 56306 : for (const auto c : accountOrder_) {
164 54568 : if (c != '/') {
165 51357 : token += c;
166 : } else {
167 3211 : if (find(accountIDs.begin(), accountIDs.end(), token) != accountIDs.end())
168 3211 : tokens.push_back(token);
169 : else {
170 0 : JAMI_DBG("Dropping nonexistent account %s", token.c_str());
171 0 : drop = true;
172 : }
173 3211 : token.clear();
174 : }
175 : }
176 :
177 1738 : if (drop) {
178 0 : accountOrder_.clear();
179 0 : for (const auto& t : tokens)
180 0 : accountOrder_ += t + '/';
181 : }
182 1738 : }
183 :
184 : void
185 803 : Preferences::addAccount(const std::string& newAccountID)
186 : {
187 : // Add the newly created account in the account order list
188 803 : if (not accountOrder_.empty())
189 535 : accountOrder_.insert(0, newAccountID + "/");
190 : else
191 268 : accountOrder_ = newAccountID + "/";
192 803 : }
193 :
194 : void
195 803 : Preferences::removeAccount(const std::string& oldAccountID)
196 : {
197 : // include the slash since we don't want to remove a partial match
198 803 : const size_t start = accountOrder_.find(oldAccountID + "/");
199 803 : if (start != std::string::npos)
200 803 : accountOrder_.erase(start, oldAccountID.length() + 1);
201 803 : }
202 :
203 : void
204 1738 : Preferences::serialize(YAML::Emitter& out) const
205 : {
206 1738 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
207 :
208 1738 : out << YAML::Key << HISTORY_LIMIT_KEY << YAML::Value << historyLimit_;
209 1738 : out << YAML::Key << RINGING_TIMEOUT << YAML::Value << ringingTimeout_;
210 1738 : out << YAML::Key << HISTORY_MAX_CALLS_KEY << YAML::Value << historyMaxCalls_;
211 1738 : out << YAML::Key << MD5_HASH_KEY << YAML::Value << md5Hash_;
212 1738 : out << YAML::Key << ORDER_KEY << YAML::Value << accountOrder_;
213 1738 : out << YAML::Key << PORT_NUM_KEY << YAML::Value << portNum_;
214 1738 : out << YAML::Key << SEARCH_BAR_DISPLAY_KEY << YAML::Value << searchBarDisplay_;
215 1738 : out << YAML::Key << ZONE_TONE_CHOICE_KEY << YAML::Value << zoneToneChoice_;
216 1738 : out << YAML::EndMap;
217 1738 : }
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 38 : VoipPreference::VoipPreference()
235 38 : : playDtmf_(true)
236 38 : , playTones_(true)
237 38 : , pulseLength_(PULSE_LENGTH_DEFAULT)
238 38 : {}
239 :
240 : void
241 1738 : VoipPreference::serialize(YAML::Emitter& out) const
242 : {
243 1738 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
244 1738 : out << YAML::Key << PLAY_DTMF_KEY << YAML::Value << playDtmf_;
245 1738 : out << YAML::Key << PLAY_TONES_KEY << YAML::Value << playTones_;
246 1738 : out << YAML::Key << PULSE_LENGTH_KEY << YAML::Value << pulseLength_;
247 1738 : out << YAML::EndMap;
248 1738 : }
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 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 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 1738 : AudioPreference::serialize(YAML::Emitter& out) const
401 : {
402 1738 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
403 : // alsa submap
404 1738 : out << YAML::Key << ALSAMAP_KEY << YAML::Value << YAML::BeginMap;
405 1738 : out << YAML::Key << CARDIN_KEY << YAML::Value << alsaCardin_;
406 1738 : out << YAML::Key << CARDOUT_KEY << YAML::Value << alsaCardout_;
407 1738 : out << YAML::Key << CARLIBJAMI_KEY << YAML::Value << alsaCardRingtone_;
408 1738 : out << YAML::Key << PLUGIN_KEY << YAML::Value << alsaPlugin_;
409 1738 : out << YAML::Key << SMPLRATE_KEY << YAML::Value << alsaSmplrate_;
410 1738 : out << YAML::EndMap;
411 :
412 : // common options
413 1738 : out << YAML::Key << ALWAYS_RECORDING_KEY << YAML::Value << alwaysRecording_;
414 1738 : out << YAML::Key << AUDIO_API_KEY << YAML::Value << audioApi_;
415 1738 : out << YAML::Key << CAPTURE_MUTED_KEY << YAML::Value << captureMuted_;
416 1738 : out << YAML::Key << PLAYBACK_MUTED_KEY << YAML::Value << playbackMuted_;
417 :
418 : // pulse submap
419 1738 : out << YAML::Key << PULSEMAP_KEY << YAML::Value << YAML::BeginMap;
420 1738 : out << YAML::Key << DEVICE_PLAYBACK_KEY << YAML::Value << pulseDevicePlayback_;
421 1738 : out << YAML::Key << DEVICE_RECORD_KEY << YAML::Value << pulseDeviceRecord_;
422 1738 : out << YAML::Key << DEVICE_RINGTONE_KEY << YAML::Value << pulseDeviceRingtone_;
423 1738 : out << YAML::EndMap;
424 :
425 : // portaudio submap
426 1738 : out << YAML::Key << PORTAUDIO_KEY << YAML::Value << YAML::BeginMap;
427 1738 : out << YAML::Key << DEVICE_PLAYBACK_KEY << YAML::Value << portaudioDevicePlayback_;
428 1738 : out << YAML::Key << DEVICE_RECORD_KEY << YAML::Value << portaudioDeviceRecord_;
429 1738 : out << YAML::Key << DEVICE_RINGTONE_KEY << YAML::Value << portaudioDeviceRingtone_;
430 1738 : out << YAML::EndMap;
431 :
432 : // more common options!
433 1738 : out << YAML::Key << RECORDPATH_KEY << YAML::Value << recordpath_;
434 1738 : out << YAML::Key << VOLUMEMIC_KEY << YAML::Value << volumemic_;
435 1738 : out << YAML::Key << VOLUMESPKR_KEY << YAML::Value << volumespkr_;
436 :
437 : // audio processor options, not in a submap
438 1738 : out << YAML::Key << AUDIO_PROCESSOR_KEY << YAML::Value << audioProcessor_;
439 1738 : out << YAML::Key << AGC_KEY << YAML::Value << agcEnabled_;
440 1738 : out << YAML::Key << VAD_KEY << YAML::Value << vadEnabled_;
441 1738 : out << YAML::Key << NOISE_REDUCE_KEY << YAML::Value << denoise_;
442 1738 : out << YAML::Key << ECHO_CANCEL_KEY << YAML::Value << echoCanceller_;
443 1738 : out << YAML::EndMap;
444 1738 : }
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 38 : VideoPreferences::VideoPreferences()
504 38 : : decodingAccelerated_(true)
505 38 : , encodingAccelerated_(false)
506 38 : , recordPreview_(true)
507 38 : , recordQuality_(0)
508 38 : , conferenceResolution_(DEFAULT_CONFERENCE_RESOLUTION)
509 38 : {}
510 :
511 : void
512 1738 : VideoPreferences::serialize(YAML::Emitter& out) const
513 : {
514 1738 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
515 1738 : out << YAML::Key << RECORD_PREVIEW_KEY << YAML::Value << recordPreview_;
516 1738 : out << YAML::Key << RECORD_QUALITY_KEY << YAML::Value << recordQuality_;
517 : #ifdef RING_ACCEL
518 1738 : out << YAML::Key << DECODING_ACCELERATED_KEY << YAML::Value << decodingAccelerated_;
519 1738 : out << YAML::Key << ENCODING_ACCELERATED_KEY << YAML::Value << encodingAccelerated_;
520 : #endif
521 1738 : out << YAML::Key << CONFERENCE_RESOLUTION_KEY << YAML::Value << conferenceResolution_;
522 1738 : getVideoDeviceMonitor().serialize(out);
523 1738 : out << YAML::EndMap;
524 1738 : }
525 :
526 : void
527 30 : VideoPreferences::unserialize(const YAML::Node& in)
528 : {
529 : // values may or may not be present
530 30 : const auto& node = in[CONFIG_LABEL];
531 : try {
532 30 : parseValue(node, RECORD_PREVIEW_KEY, recordPreview_);
533 30 : parseValue(node, RECORD_QUALITY_KEY, recordQuality_);
534 0 : } catch (...) {
535 0 : recordPreview_ = true;
536 0 : recordQuality_ = 0;
537 0 : }
538 : #ifdef RING_ACCEL
539 : try {
540 30 : parseValue(node, DECODING_ACCELERATED_KEY, decodingAccelerated_);
541 30 : parseValue(node, ENCODING_ACCELERATED_KEY, encodingAccelerated_);
542 0 : } catch (...) {
543 0 : decodingAccelerated_ = true;
544 0 : encodingAccelerated_ = false;
545 0 : }
546 : #endif
547 : try {
548 30 : parseValue(node, CONFERENCE_RESOLUTION_KEY, conferenceResolution_);
549 0 : } catch (...) {
550 0 : conferenceResolution_ = DEFAULT_CONFERENCE_RESOLUTION;
551 0 : }
552 30 : getVideoDeviceMonitor().unserialize(in);
553 30 : }
554 : #endif // ENABLE_VIDEO
555 :
556 : #ifdef ENABLE_PLUGIN
557 38 : PluginPreferences::PluginPreferences()
558 38 : : pluginsEnabled_(false)
559 38 : {}
560 :
561 : void
562 1738 : PluginPreferences::serialize(YAML::Emitter& out) const
563 : {
564 1738 : out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
565 1738 : out << YAML::Key << JAMI_PLUGIN_KEY << YAML::Value << pluginsEnabled_;
566 1738 : out << YAML::Key << JAMI_PLUGINS_INSTALLED_KEY << YAML::Value << installedPlugins_;
567 1738 : out << YAML::Key << JAMI_PLUGINS_LOADED_KEY << YAML::Value << loadedPlugins_;
568 1738 : out << YAML::EndMap;
569 1738 : }
570 :
571 : void
572 30 : PluginPreferences::unserialize(const YAML::Node& in)
573 : {
574 : // values may or may not be present
575 30 : const auto& node = in[CONFIG_LABEL];
576 : try {
577 30 : parseValue(node, JAMI_PLUGIN_KEY, pluginsEnabled_);
578 0 : } catch (...) {
579 0 : pluginsEnabled_ = false;
580 0 : }
581 :
582 30 : const auto& installedPluginsNode = node[JAMI_PLUGINS_INSTALLED_KEY];
583 : try {
584 30 : installedPlugins_ = yaml_utils::parseVector(installedPluginsNode);
585 0 : } catch (...) {
586 0 : }
587 :
588 30 : const auto& loadedPluginsNode = node[JAMI_PLUGINS_LOADED_KEY];
589 : try {
590 30 : loadedPlugins_ = yaml_utils::parseVector(loadedPluginsNode);
591 0 : } catch (...) {
592 : // loadedPlugins_ = {};
593 0 : }
594 30 : }
595 : #endif // ENABLE_PLUGIN
596 :
597 : } // namespace jami
|