VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/RecordingScreenSettingsImpl.cpp@ 79812

Last change on this file since 79812 was 78072, checked in by vboxsync, 6 years ago

Recording/Main: Settings locking fixes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.1 KB
Line 
1/* $Id: RecordingScreenSettingsImpl.cpp 78072 2019-04-10 10:04:06Z vboxsync $ */
2/** @file
3 *
4 * VirtualBox COM class implementation - Recording settings of one virtual screen.
5 */
6
7/*
8 * Copyright (C) 2018-2019 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#define LOG_GROUP LOG_GROUP_MAIN_RECORDINGSCREENSETTINGS
20#include "LoggingNew.h"
21
22#include "RecordingScreenSettingsImpl.h"
23#include "RecordingSettingsImpl.h"
24#include "MachineImpl.h"
25
26#include <iprt/path.h>
27#include <iprt/cpp/utils.h>
28#include <VBox/settings.h>
29
30#include "AutoStateDep.h"
31#include "AutoCaller.h"
32#include "Global.h"
33
34////////////////////////////////////////////////////////////////////////////////
35//
36// RecordScreenSettings private data definition
37//
38////////////////////////////////////////////////////////////////////////////////
39
40struct RecordingScreenSettings::Data
41{
42 Data()
43 : pParent(NULL)
44 { }
45
46 RecordingSettings * const pParent;
47 const ComObjPtr<RecordingScreenSettings> pPeer;
48 uint32_t uScreenId;
49
50 // use the XML settings structure in the members for simplicity
51 Backupable<settings::RecordingScreenSettings> bd;
52};
53
54// constructor / destructor
55/////////////////////////////////////////////////////////////////////////////
56
57DEFINE_EMPTY_CTOR_DTOR(RecordingScreenSettings)
58
59HRESULT RecordingScreenSettings::FinalConstruct()
60{
61 return BaseFinalConstruct();
62}
63
64void RecordingScreenSettings::FinalRelease()
65{
66 uninit();
67 BaseFinalRelease();
68}
69
70// public initializer/uninitializer for internal purposes only
71/////////////////////////////////////////////////////////////////////////////
72
73/**
74 * Initializes the recording screen settings object.
75 *
76 * @returns COM result indicator
77 */
78HRESULT RecordingScreenSettings::init(RecordingSettings *aParent, uint32_t uScreenId,
79 const settings::RecordingScreenSettings& aThat)
80{
81 LogFlowThisFuncEnter();
82 LogFlowThisFunc(("aParent: %p\n", aParent));
83
84 ComAssertRet(aParent, E_INVALIDARG);
85
86 /* Enclose the state transition NotReady->InInit->Ready */
87 AutoInitSpan autoInitSpan(this);
88 AssertReturn(autoInitSpan.isOk(), E_FAIL);
89
90 m = new Data();
91
92 /* Share the parent & machine weakly. */
93 unconst(m->pParent) = aParent;
94 /* mPeer is left null. */
95
96 /* Simply copy the settings data. */
97 m->uScreenId = uScreenId;
98 m->bd.allocate();
99 m->bd->operator=(aThat);
100
101 HRESULT rc = S_OK;
102
103 int vrc = i_initInternal();
104 if (RT_SUCCESS(vrc))
105 {
106 autoInitSpan.setSucceeded();
107 }
108 else
109 {
110 autoInitSpan.setFailed();
111 rc = E_UNEXPECTED;
112 }
113
114 LogFlowThisFuncLeave();
115 return rc;
116}
117
118/**
119 * Initializes the recording settings object given another recording settings object
120 * (a kind of copy constructor). This object shares data with
121 * the object passed as an argument.
122 *
123 * @note This object must be destroyed before the original object
124 * it shares data with is destroyed.
125 */
126HRESULT RecordingScreenSettings::init(RecordingSettings *aParent, RecordingScreenSettings *aThat)
127{
128 LogFlowThisFuncEnter();
129 LogFlowThisFunc(("aParent: %p, aThat: %p\n", aParent, aThat));
130
131 ComAssertRet(aParent && aThat, E_INVALIDARG);
132
133 /* Enclose the state transition NotReady->InInit->Ready */
134 AutoInitSpan autoInitSpan(this);
135 AssertReturn(autoInitSpan.isOk(), E_FAIL);
136
137 m = new Data();
138
139 unconst(m->pParent) = aParent;
140 unconst(m->pPeer) = aThat;
141
142 AutoCaller thatCaller(aThat);
143 AssertComRCReturnRC(thatCaller.rc());
144
145 AutoReadLock thatlock(aThat COMMA_LOCKVAL_SRC_POS);
146
147 m->uScreenId = aThat->m->uScreenId;
148 m->bd.share(aThat->m->bd);
149
150 HRESULT rc = S_OK;
151
152 int vrc = i_initInternal();
153 if (RT_SUCCESS(vrc))
154 {
155 autoInitSpan.setSucceeded();
156 }
157 else
158 {
159 autoInitSpan.setFailed();
160 rc = E_UNEXPECTED;
161 }
162
163 LogFlowThisFuncLeave();
164 return rc;
165}
166
167/**
168 * Initializes the guest object given another guest object
169 * (a kind of copy constructor). This object makes a private copy of data
170 * of the original object passed as an argument.
171 */
172HRESULT RecordingScreenSettings::initCopy(RecordingSettings *aParent, RecordingScreenSettings *aThat)
173{
174 LogFlowThisFuncEnter();
175 LogFlowThisFunc(("aParent: %p, aThat: %p\n", aParent, aThat));
176
177 ComAssertRet(aParent && aThat, E_INVALIDARG);
178
179 /* Enclose the state transition NotReady->InInit->Ready */
180 AutoInitSpan autoInitSpan(this);
181 AssertReturn(autoInitSpan.isOk(), E_FAIL);
182
183 m = new Data();
184
185 unconst(m->pParent) = aParent;
186 /* mPeer is left null. */
187
188 AutoCaller thatCaller(aThat);
189 AssertComRCReturnRC(thatCaller.rc());
190
191 AutoReadLock thatlock(aThat COMMA_LOCKVAL_SRC_POS);
192
193 m->uScreenId = aThat->m->uScreenId;
194 m->bd.attachCopy(aThat->m->bd);
195
196 HRESULT rc = S_OK;
197
198 int vrc = i_initInternal();
199 if (RT_SUCCESS(vrc))
200 {
201 autoInitSpan.setSucceeded();
202 }
203 else
204 {
205 autoInitSpan.setFailed();
206 rc = E_UNEXPECTED;
207 }
208
209 LogFlowThisFuncLeave();
210 return rc;
211}
212
213/**
214 * Uninitializes the instance and sets the ready flag to FALSE.
215 * Called either from FinalRelease() or by the parent when it gets destroyed.
216 */
217void RecordingScreenSettings::uninit()
218{
219 LogFlowThisFuncEnter();
220
221 /* Enclose the state transition Ready->InUninit->NotReady */
222 AutoUninitSpan autoUninitSpan(this);
223 if (autoUninitSpan.uninitDone())
224 return;
225
226 m->bd.free();
227
228 unconst(m->pPeer) = NULL;
229 unconst(m->pParent) = NULL;
230
231 delete m;
232 m = NULL;
233
234 LogFlowThisFuncLeave();
235}
236
237HRESULT RecordingScreenSettings::isFeatureEnabled(RecordingFeature_T aFeature, BOOL *aEnabled)
238{
239 AutoCaller autoCaller(this);
240 if (FAILED(autoCaller.rc())) return autoCaller.rc();
241
242 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
243
244 settings::RecordingFeatureMap::const_iterator itFeature = m->bd->featureMap.find(aFeature);
245
246 *aEnabled = ( itFeature != m->bd->featureMap.end()
247 && itFeature->second == true);
248
249 return S_OK;
250}
251
252HRESULT RecordingScreenSettings::getId(ULONG *id)
253{
254 AutoCaller autoCaller(this);
255 if (FAILED(autoCaller.rc())) return autoCaller.rc();
256
257 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
258
259 *id = m->uScreenId;
260
261 return S_OK;
262}
263
264HRESULT RecordingScreenSettings::getEnabled(BOOL *enabled)
265{
266 AutoCaller autoCaller(this);
267 if (FAILED(autoCaller.rc())) return autoCaller.rc();
268
269 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
270
271 *enabled = m->bd->fEnabled ? TRUE : FALSE;
272
273 return S_OK;
274}
275
276HRESULT RecordingScreenSettings::setEnabled(BOOL enabled)
277{
278 AutoCaller autoCaller(this);
279 if (FAILED(autoCaller.rc())) return autoCaller.rc();
280
281 LogFlowThisFunc(("Screen %RU32\n", m->uScreenId));
282
283 if (!m->pParent->i_canChangeSettings())
284 return setError(E_INVALIDARG, tr("Cannot change enabled state of screen while recording is enabled"));
285
286 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
287
288 if (m->bd->fEnabled != RT_BOOL(enabled))
289 {
290 m->bd.backup();
291 m->bd->fEnabled = RT_BOOL(enabled);
292 alock.release();
293
294 m->pParent->i_onSettingsChanged();
295 }
296
297 LogFlowThisFunc(("Screen %RU32\n", m->uScreenId));
298 return S_OK;
299}
300
301HRESULT RecordingScreenSettings::getFeatures(ULONG *aFeatures)
302{
303 AutoCaller autoCaller(this);
304 if (FAILED(autoCaller.rc())) return autoCaller.rc();
305
306 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
307
308 *aFeatures = 0;
309
310 settings::RecordingFeatureMap::const_iterator itFeature = m->bd->featureMap.begin();
311 while (itFeature != m->bd->featureMap.end())
312 {
313 if (itFeature->second) /* Is feature enable? */
314 *aFeatures |= (ULONG)itFeature->first;
315
316 ++itFeature;
317 }
318
319 return S_OK;
320}
321
322HRESULT RecordingScreenSettings::setFeatures(ULONG aFeatures)
323{
324 AutoCaller autoCaller(this);
325 if (FAILED(autoCaller.rc())) return autoCaller.rc();
326
327 if (!m->pParent->i_canChangeSettings())
328 return setError(E_INVALIDARG, tr("Cannot change features while recording is enabled"));
329
330 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
331
332 m->bd.backup();
333 m->bd->featureMap.clear();
334
335 if (aFeatures & RecordingFeature_Audio)
336 m->bd->featureMap[RecordingFeature_Audio] = true;
337 if (aFeatures & RecordingFeature_Video)
338 m->bd->featureMap[RecordingFeature_Video] = true;
339
340 alock.release();
341
342 return S_OK;
343}
344
345HRESULT RecordingScreenSettings::getDestination(RecordingDestination_T *aDestination)
346{
347 AutoCaller autoCaller(this);
348 if (FAILED(autoCaller.rc())) return autoCaller.rc();
349
350 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
351
352 *aDestination = m->bd->enmDest;
353
354 return S_OK;
355}
356
357HRESULT RecordingScreenSettings::setDestination(RecordingDestination_T aDestination)
358{
359 AutoCaller autoCaller(this);
360 if (FAILED(autoCaller.rc())) return autoCaller.rc();
361
362 if (!m->pParent->i_canChangeSettings())
363 return setError(E_INVALIDARG, tr("Cannot change destination type while recording is enabled"));
364
365 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
366
367 m->bd.backup();
368 m->bd->enmDest = aDestination;
369
370 return S_OK;
371}
372
373HRESULT RecordingScreenSettings::getFilename(com::Utf8Str &aFilename)
374{
375 AutoCaller autoCaller(this);
376 if (FAILED(autoCaller.rc())) return autoCaller.rc();
377
378 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
379
380 /* Get default file name if an empty string or a single "." is set. */
381 if ( m->bd->File.strName.isEmpty()
382 || m->bd->File.strName.equals("."))
383 {
384 int vrc = m->pParent->i_getDefaultFilename(m->bd->File.strName, true /* fWithFileExtension */);
385 if (RT_FAILURE(vrc))
386 return setError(E_INVALIDARG, tr("Error retrieving default file name"));
387 }
388
389 aFilename = m->bd->File.strName;
390
391 return S_OK;
392}
393
394HRESULT RecordingScreenSettings::setFilename(const com::Utf8Str &aFilename)
395{
396 AutoCaller autoCaller(this);
397 if (FAILED(autoCaller.rc())) return autoCaller.rc();
398
399 if (!m->pParent->i_canChangeSettings())
400 return setError(E_INVALIDARG, tr("Cannot change file name while recording is enabled"));
401
402 Utf8Str strFile(aFilename);
403 if (!RTPathStartsWithRoot(strFile.c_str()))
404 return setError(E_INVALIDARG, tr("Recording file name '%s' is not absolute"), strFile.c_str());
405
406 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
407
408 m->bd.backup();
409 m->bd->File.strName = strFile;
410
411 return S_OK;
412}
413
414HRESULT RecordingScreenSettings::getMaxTime(ULONG *aMaxTimeS)
415{
416 AutoCaller autoCaller(this);
417 if (FAILED(autoCaller.rc())) return autoCaller.rc();
418
419 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
420
421 *aMaxTimeS = m->bd->ulMaxTimeS;
422
423 return S_OK;
424}
425
426HRESULT RecordingScreenSettings::setMaxTime(ULONG aMaxTimeS)
427{
428 AutoCaller autoCaller(this);
429 if (FAILED(autoCaller.rc())) return autoCaller.rc();
430
431 if (!m->pParent->i_canChangeSettings())
432 return setError(E_INVALIDARG, tr("Cannot change maximum time while recording is enabled"));
433
434 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
435
436 m->bd.backup();
437 m->bd->ulMaxTimeS = aMaxTimeS;
438
439 return S_OK;
440}
441
442HRESULT RecordingScreenSettings::getMaxFileSize(ULONG *aMaxFileSizeMB)
443{
444 AutoCaller autoCaller(this);
445 if (FAILED(autoCaller.rc())) return autoCaller.rc();
446
447 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
448
449 *aMaxFileSizeMB = m->bd->File.ulMaxSizeMB;
450
451 return S_OK;
452}
453
454HRESULT RecordingScreenSettings::setMaxFileSize(ULONG aMaxFileSize)
455{
456 AutoCaller autoCaller(this);
457 if (FAILED(autoCaller.rc())) return autoCaller.rc();
458
459 if (!m->pParent->i_canChangeSettings())
460 return setError(E_INVALIDARG, tr("Cannot change maximum file size while recording is enabled"));
461
462 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
463
464 m->bd.backup();
465 m->bd->File.ulMaxSizeMB = aMaxFileSize;
466
467 return S_OK;
468}
469
470HRESULT RecordingScreenSettings::getOptions(com::Utf8Str &aOptions)
471{
472 AutoCaller autoCaller(this);
473 if (FAILED(autoCaller.rc())) return autoCaller.rc();
474
475 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
476
477 aOptions = m->bd->strOptions;
478
479 return S_OK;
480}
481
482HRESULT RecordingScreenSettings::setOptions(const com::Utf8Str &aOptions)
483{
484 AutoCaller autoCaller(this);
485 if (FAILED(autoCaller.rc())) return autoCaller.rc();
486
487 if (!m->pParent->i_canChangeSettings())
488 return setError(E_INVALIDARG, tr("Cannot change options while recording is enabled"));
489
490 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
491
492 m->bd.backup();
493 m->bd->strOptions = aOptions;
494
495 int vrc = RecordingScreenSettings::i_parseOptionsString(aOptions, *m->bd.data());
496 if (RT_FAILURE(vrc))
497 return setError(E_INVALIDARG, tr("Invalid option specified"));
498
499 return S_OK;
500}
501
502HRESULT RecordingScreenSettings::getAudioCodec(RecordingAudioCodec_T *aCodec)
503{
504 AutoCaller autoCaller(this);
505 if (FAILED(autoCaller.rc())) return autoCaller.rc();
506
507 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
508
509 *aCodec = m->bd->Audio.enmAudioCodec;
510
511 return S_OK;
512}
513
514HRESULT RecordingScreenSettings::setAudioCodec(RecordingAudioCodec_T aCodec)
515{
516 AutoCaller autoCaller(this);
517 if (FAILED(autoCaller.rc())) return autoCaller.rc();
518
519 if (!m->pParent->i_canChangeSettings())
520 return setError(E_INVALIDARG, tr("Cannot change audio codec while recording is enabled"));
521
522 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
523
524 m->bd.backup();
525 m->bd->Audio.enmAudioCodec = aCodec;
526
527 return S_OK;
528}
529
530HRESULT RecordingScreenSettings::getAudioHz(ULONG *aHz)
531{
532 AutoCaller autoCaller(this);
533 if (FAILED(autoCaller.rc())) return autoCaller.rc();
534
535 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
536
537 *aHz = m->bd->Audio.uHz;
538
539 return S_OK;
540}
541
542HRESULT RecordingScreenSettings::setAudioHz(ULONG aHz)
543{
544 AutoCaller autoCaller(this);
545 if (FAILED(autoCaller.rc())) return autoCaller.rc();
546
547 if (!m->pParent->i_canChangeSettings())
548 return setError(E_INVALIDARG, tr("Cannot change audio Hertz rate while recording is enabled"));
549
550 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
551
552 m->bd.backup();
553 m->bd->Audio.uHz = (uint16_t)aHz;
554
555 return S_OK;
556}
557
558HRESULT RecordingScreenSettings::getAudioBits(ULONG *aBits)
559{
560 AutoCaller autoCaller(this);
561 if (FAILED(autoCaller.rc())) return autoCaller.rc();
562
563 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
564
565 *aBits = m->bd->Audio.cBits;
566
567 return S_OK;
568}
569
570HRESULT RecordingScreenSettings::setAudioBits(ULONG aBits)
571{
572 AutoCaller autoCaller(this);
573 if (FAILED(autoCaller.rc())) return autoCaller.rc();
574
575 if (!m->pParent->i_canChangeSettings())
576 return setError(E_INVALIDARG, tr("Cannot change audio bits while recording is enabled"));
577
578 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
579
580 m->bd.backup();
581 m->bd->Audio.cBits = (uint8_t)aBits;
582
583 return S_OK;
584}
585
586HRESULT RecordingScreenSettings::getAudioChannels(ULONG *aChannels)
587{
588 AutoCaller autoCaller(this);
589 if (FAILED(autoCaller.rc())) return autoCaller.rc();
590
591 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
592
593 *aChannels = m->bd->Audio.cChannels;
594
595 return S_OK;
596}
597
598HRESULT RecordingScreenSettings::setAudioChannels(ULONG aChannels)
599{
600 AutoCaller autoCaller(this);
601 if (FAILED(autoCaller.rc())) return autoCaller.rc();
602
603 if (!m->pParent->i_canChangeSettings())
604 return setError(E_INVALIDARG, tr("Cannot change audio channels while recording is enabled"));
605
606 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
607
608 m->bd.backup();
609 m->bd->Audio.cChannels = (uint8_t)aChannels;
610
611 return S_OK;
612}
613
614HRESULT RecordingScreenSettings::getVideoCodec(RecordingVideoCodec_T *aCodec)
615{
616 AutoCaller autoCaller(this);
617 if (FAILED(autoCaller.rc())) return autoCaller.rc();
618
619 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
620
621 *aCodec = m->bd->Video.enmCodec;
622
623 return S_OK;
624}
625
626HRESULT RecordingScreenSettings::setVideoCodec(RecordingVideoCodec_T aCodec)
627{
628 AutoCaller autoCaller(this);
629 if (FAILED(autoCaller.rc())) return autoCaller.rc();
630
631 if (!m->pParent->i_canChangeSettings())
632 return setError(E_INVALIDARG, tr("Cannot change video codec while recording is enabled"));
633
634 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
635
636 m->bd.backup();
637 m->bd->Video.enmCodec = aCodec;
638
639 return S_OK;
640}
641
642HRESULT RecordingScreenSettings::getVideoWidth(ULONG *aVideoWidth)
643{
644 AutoCaller autoCaller(this);
645 if (FAILED(autoCaller.rc())) return autoCaller.rc();
646
647 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
648
649 *aVideoWidth = m->bd->Video.ulWidth;
650
651 return S_OK;
652}
653
654HRESULT RecordingScreenSettings::setVideoWidth(ULONG aVideoWidth)
655{
656 AutoCaller autoCaller(this);
657 if (FAILED(autoCaller.rc())) return autoCaller.rc();
658
659 if (!m->pParent->i_canChangeSettings())
660 return setError(E_INVALIDARG, tr("Cannot change video width while recording is enabled"));
661
662 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
663
664 m->bd.backup();
665 m->bd->Video.ulWidth = aVideoWidth;
666
667 return S_OK;
668}
669
670HRESULT RecordingScreenSettings::getVideoHeight(ULONG *aVideoHeight)
671{
672 AutoCaller autoCaller(this);
673 if (FAILED(autoCaller.rc())) return autoCaller.rc();
674
675 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
676
677 *aVideoHeight = m->bd->Video.ulHeight;
678
679 return S_OK;
680}
681
682HRESULT RecordingScreenSettings::setVideoHeight(ULONG aVideoHeight)
683{
684 AutoCaller autoCaller(this);
685 if (FAILED(autoCaller.rc())) return autoCaller.rc();
686
687 if (!m->pParent->i_canChangeSettings())
688 return setError(E_INVALIDARG, tr("Cannot change video height while recording is enabled"));
689
690 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
691
692 m->bd.backup();
693 m->bd->Video.ulHeight = aVideoHeight;
694
695 return S_OK;
696}
697
698HRESULT RecordingScreenSettings::getVideoRate(ULONG *aVideoRate)
699{
700 AutoCaller autoCaller(this);
701 if (FAILED(autoCaller.rc())) return autoCaller.rc();
702
703 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
704
705 *aVideoRate = m->bd->Video.ulRate;
706
707 return S_OK;
708}
709
710HRESULT RecordingScreenSettings::setVideoRate(ULONG aVideoRate)
711{
712 AutoCaller autoCaller(this);
713 if (FAILED(autoCaller.rc())) return autoCaller.rc();
714
715 if (!m->pParent->i_canChangeSettings())
716 return setError(E_INVALIDARG, tr("Cannot change video rate while recording is enabled"));
717
718 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
719
720 m->bd.backup();
721 m->bd->Video.ulRate = aVideoRate;
722
723 return S_OK;
724}
725
726HRESULT RecordingScreenSettings::getVideoRateControlMode(RecordingVideoRateControlMode_T *aMode)
727{
728 AutoCaller autoCaller(this);
729 if (FAILED(autoCaller.rc())) return autoCaller.rc();
730
731 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
732
733 *aMode = RecordingVideoRateControlMode_CBR; /** @todo Implement VBR. */
734
735 return S_OK;
736}
737
738HRESULT RecordingScreenSettings::setVideoRateControlMode(RecordingVideoRateControlMode_T aMode)
739{
740 AutoCaller autoCaller(this);
741 if (FAILED(autoCaller.rc())) return autoCaller.rc();
742
743 if (!m->pParent->i_canChangeSettings())
744 return setError(E_INVALIDARG, tr("Cannot change video rate control mode while recording is enabled"));
745
746 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
747
748 /** @todo Implement this. */
749 RT_NOREF(aMode);
750
751 return E_NOTIMPL;
752}
753
754HRESULT RecordingScreenSettings::getVideoFPS(ULONG *aVideoFPS)
755{
756 AutoCaller autoCaller(this);
757 if (FAILED(autoCaller.rc())) return autoCaller.rc();
758
759 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
760
761 *aVideoFPS = m->bd->Video.ulFPS;
762
763 return S_OK;
764}
765
766HRESULT RecordingScreenSettings::setVideoFPS(ULONG aVideoFPS)
767{
768 AutoCaller autoCaller(this);
769 if (FAILED(autoCaller.rc())) return autoCaller.rc();
770
771 if (!m->pParent->i_canChangeSettings())
772 return setError(E_INVALIDARG, tr("Cannot change video FPS while recording is enabled"));
773
774 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
775
776 m->bd.backup();
777 m->bd->Video.ulFPS = aVideoFPS;
778
779 return S_OK;
780}
781
782HRESULT RecordingScreenSettings::getVideoScalingMethod(RecordingVideoScalingMethod_T *aMode)
783{
784 AutoCaller autoCaller(this);
785 if (FAILED(autoCaller.rc())) return autoCaller.rc();
786
787 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
788
789 *aMode = RecordingVideoScalingMethod_None; /** @todo Implement this. */
790
791 return S_OK;
792}
793
794HRESULT RecordingScreenSettings::setVideoScalingMethod(RecordingVideoScalingMethod_T aMode)
795{
796 AutoCaller autoCaller(this);
797 if (FAILED(autoCaller.rc())) return autoCaller.rc();
798
799 if (!m->pParent->i_canChangeSettings())
800 return setError(E_INVALIDARG, tr("Cannot change video rate scaling method while recording is enabled"));
801
802 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
803
804 /** @todo Implement this. */
805 RT_NOREF(aMode);
806
807 return E_NOTIMPL;
808}
809
810/**
811 * Initializes data, internal version.
812 *
813 * @returns IPRT status code.
814 */
815int RecordingScreenSettings::i_initInternal(void)
816{
817 Assert(m);
818
819 int rc = i_parseOptionsString(m->bd->strOptions, *m->bd.data());
820 if (RT_FAILURE(rc))
821 return rc;
822
823 switch (m->bd->enmDest)
824 {
825 case RecordingDestination_File:
826 {
827 if (m->bd->File.strName.isEmpty())
828 rc = m->pParent->i_getDefaultFilename(m->bd->File.strName, true /* fWithExtension */);
829 break;
830 }
831
832 default:
833 break;
834 }
835
836 return rc;
837}
838
839/**
840 * Parses a recording screen options string and stores the parsed result in the specified screen settings.
841 *
842 * @returns IPRT status code.
843 * @param strOptions Options string to parse.
844 * @param screenSettings Where to store the parsed result into.
845 */
846/* static */
847int RecordingScreenSettings::i_parseOptionsString(const com::Utf8Str &strOptions,
848 settings::RecordingScreenSettings &screenSettings)
849{
850 /*
851 * Parse options string.
852 */
853 size_t pos = 0;
854 com::Utf8Str key, value;
855 while ((pos = strOptions.parseKeyValue(key, value, pos)) != com::Utf8Str::npos)
856 {
857 if (key.compare("vc_quality", Utf8Str::CaseInsensitive) == 0)
858 {
859#ifdef VBOX_WITH_LIBVPX
860 if (value.compare("realtime", Utf8Str::CaseInsensitive) == 0)
861 mVideoRecCfg.Video.Codec.VPX.uEncoderDeadline = VPX_DL_REALTIME;
862 else if (value.compare("good", Utf8Str::CaseInsensitive) == 0)
863 mVideoRecCfg.Video.Codec.VPX.uEncoderDeadline = 1000000 / mVideoRecCfg.Video.uFPS;
864 else if (value.compare("best", Utf8Str::CaseInsensitive) == 0)
865 mVideoRecCfg.Video.Codec.VPX.uEncoderDeadline = VPX_DL_BEST_QUALITY;
866 else
867 {
868 mVideoRecCfg.Video.Codec.VPX.uEncoderDeadline = value.toUInt32();
869 }
870#endif
871 }
872 else if (key.compare("vc_enabled", Utf8Str::CaseInsensitive) == 0)
873 {
874 if (value.compare("false", Utf8Str::CaseInsensitive) == 0)
875 {
876 screenSettings.featureMap[RecordingFeature_Video] = false;
877 }
878 }
879 else if (key.compare("ac_enabled", Utf8Str::CaseInsensitive) == 0)
880 {
881#ifdef VBOX_WITH_AUDIO_RECORDING
882 if (value.compare("true", Utf8Str::CaseInsensitive) == 0)
883 {
884 screenSettings.featureMap[RecordingFeature_Audio] = true;
885 }
886#endif
887 }
888 else if (key.compare("ac_profile", Utf8Str::CaseInsensitive) == 0)
889 {
890#ifdef VBOX_WITH_AUDIO_RECORDING
891 if (value.compare("low", Utf8Str::CaseInsensitive) == 0)
892 {
893 screenSettings.Audio.uHz = 8000;
894 screenSettings.Audio.cBits = 16;
895 screenSettings.Audio.cChannels = 1;
896 }
897 else if (value.startsWith("med" /* "med[ium]" */, Utf8Str::CaseInsensitive) == 0)
898 {
899 /* Stay with the default set above. */
900 }
901 else if (value.compare("high", Utf8Str::CaseInsensitive) == 0)
902 {
903 screenSettings.Audio.uHz = 48000;
904 screenSettings.Audio.cBits = 16;
905 screenSettings.Audio.cChannels = 2;
906 }
907#endif
908 }
909 /* else just ignore. */
910
911 } /* while */
912
913 return VINF_SUCCESS;
914}
915
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette