VirtualBox

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

Last change on this file since 77863 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

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