Changeset 95639 in vbox for trunk/src/VBox/Main
- Timestamp:
- Jul 14, 2022 8:30:45 AM (3 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/ConsoleImpl.h
r95423 r95639 168 168 void i_recordingDestroy(void); 169 169 int i_recordingEnable(BOOL fEnable, util::AutoWriteLock *pAutoLock); 170 int i_recordingGetSettings(settings::RecordingSettings & Settings);170 int i_recordingGetSettings(settings::RecordingSettings &recording); 171 171 int i_recordingStart(util::AutoWriteLock *pAutoLock = NULL); 172 172 int i_recordingStop(util::AutoWriteLock *pAutoLock = NULL); -
trunk/src/VBox/Main/include/MachineImpl.h
r95450 r95639 679 679 const settings::Hardware &data, 680 680 const settings::Debugging *pDbg, 681 const settings::Autostart *pAutostart); 681 const settings::Autostart *pAutostart, 682 const settings::RecordingSettings &recording); 682 683 HRESULT i_loadDebugging(const settings::Debugging *pDbg); 683 684 HRESULT i_loadAutostart(const settings::Autostart *pAutostart); … … 718 719 HRESULT i_saveAllSnapshots(settings::MachineConfigFile &config); 719 720 HRESULT i_saveHardware(settings::Hardware &data, settings::Debugging *pDbg, 720 settings::Autostart *pAutostart );721 settings::Autostart *pAutostart, settings::RecordingSettings &recording); 721 722 HRESULT i_saveStorageControllers(settings::Storage &data); 722 723 HRESULT i_saveStorageDevices(ComObjPtr<StorageController> aStorageController, … … 1627 1628 const settings::Debugging *pDbg, 1628 1629 const settings::Autostart *pAutostart, 1630 const settings::RecordingSettings &recording, 1629 1631 IN_GUID aSnapshotId, 1630 1632 const Utf8Str &aStateFilePath); -
trunk/src/VBox/Main/include/RecordingScreenSettingsImpl.h
r93115 r95639 47 47 HRESULT init(RecordingSettings *aParent, RecordingScreenSettings *aThat); 48 48 HRESULT initCopy(RecordingSettings *aParent, RecordingScreenSettings *aThat); 49 void uninit(); 49 void uninit(void); 50 51 // public methods only for internal purposes 52 HRESULT i_loadSettings(const settings::RecordingScreenSettings &data); 53 HRESULT i_saveSettings(settings::RecordingScreenSettings &data); 54 55 void i_rollback(void); 56 void i_commit(void); 57 void i_copyFrom(RecordingScreenSettings *aThat); 58 void i_applyDefaults(void); 59 60 settings::RecordingScreenSettings &i_getData(void); 50 61 51 62 private: -
trunk/src/VBox/Main/include/RecordingSettingsImpl.h
r93115 r95639 52 52 HRESULT i_saveSettings(settings::RecordingSettings &data); 53 53 54 void i_rollback();55 void i_commit();56 voidi_copyFrom(RecordingSettings *aThat);57 void i_applyDefaults(void);54 void i_rollback(void); 55 void i_commit(void); 56 HRESULT i_copyFrom(RecordingSettings *aThat); 57 void i_applyDefaults(void); 58 58 59 int i_getDefaultFilename(Utf8Str &strFile, bool fWithFileExtension);59 int i_getDefaultFilename(Utf8Str &strFile, uint32_t idScreen, bool fWithFileExtension); 60 60 bool i_canChangeSettings(void); 61 61 void i_onSettingsChanged(void); … … 64 64 65 65 /** Map of screen settings objects. The key specifies the screen ID. */ 66 typedef std::map <uint32_t, ComObjPtr<RecordingScreenSettings> > Record ScreenSettingsMap;66 typedef std::map <uint32_t, ComObjPtr<RecordingScreenSettings> > RecordingScreenSettingsObjMap; 67 67 68 68 void i_reset(void); 69 int i_syncToMachineDisplays(uint32_t c Monitors);70 int i_createScreenObj(Record ScreenSettingsMap &screenSettingsMap, uint32_t uScreenId, const settings::RecordingScreenSettings &data);71 int i_destroyScreenObj(Record ScreenSettingsMap &screenSettingsMap, uint32_t uScreenId);72 int i_destroyAllScreenObj(Record ScreenSettingsMap &screenSettingsMap);69 int i_syncToMachineDisplays(uint32_t cDisplays); 70 int i_createScreenObj(RecordingScreenSettingsObjMap &screenSettingsMap, uint32_t idScreen, const settings::RecordingScreenSettings &data); 71 int i_destroyScreenObj(RecordingScreenSettingsObjMap &screenSettingsMap, uint32_t idScreen); 72 int i_destroyAllScreenObj(RecordingScreenSettingsObjMap &screenSettingsMap); 73 73 74 74 private: -
trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
r95423 r95639 7248 7248 #ifdef VBOX_WITH_RECORDING 7249 7249 7250 int Console::i_recordingGetSettings(settings::RecordingSettings & Settings)7250 int Console::i_recordingGetSettings(settings::RecordingSettings &recording) 7251 7251 { 7252 7252 Assert(mMachine.isNotNull()); 7253 7253 7254 Settings.applyDefaults();7254 recording.applyDefaults(); 7255 7255 7256 7256 ComPtr<IRecordingSettings> pRecordSettings; … … 7261 7261 hrc = pRecordSettings->COMGETTER(Enabled)(&fTemp); 7262 7262 AssertComRCReturn(hrc, VERR_INVALID_PARAMETER); 7263 Settings.fEnabled = RT_BOOL(fTemp);7264 7265 SafeIfaceArray<IRecordingScreenSettings> paRec ordingScreens;7266 hrc = pRecordSettings->COMGETTER(Screens)(ComSafeArrayAsOutParam(paRec ordingScreens));7263 recording.common.fEnabled = RT_BOOL(fTemp); 7264 7265 SafeIfaceArray<IRecordingScreenSettings> paRecScreens; 7266 hrc = pRecordSettings->COMGETTER(Screens)(ComSafeArrayAsOutParam(paRecScreens)); 7267 7267 AssertComRCReturn(hrc, VERR_INVALID_PARAMETER); 7268 7268 7269 for (unsigned long i = 0; i < (unsigned long)paRec ordingScreens.size(); ++i)7270 { 7271 settings::RecordingScreenSettings RecordScreenSettings;7272 ComPtr<IRecordingScreenSettings> pRec ordScreenSettings = paRecordingScreens[i];7273 7274 hrc = pRec ordScreenSettings->COMGETTER(Enabled)(&fTemp);7269 for (unsigned long i = 0; i < (unsigned long)paRecScreens.size(); ++i) 7270 { 7271 settings::RecordingScreenSettings recScreenSettings; 7272 ComPtr<IRecordingScreenSettings> pRecScreenSettings = paRecScreens[i]; 7273 7274 hrc = pRecScreenSettings->COMGETTER(Enabled)(&fTemp); 7275 7275 AssertComRCReturn(hrc, VERR_INVALID_PARAMETER); 7276 RecordScreenSettings.fEnabled = RT_BOOL(fTemp);7277 hrc = pRec ordScreenSettings->COMGETTER(MaxTime)((ULONG *)&RecordScreenSettings.ulMaxTimeS);7276 recScreenSettings.fEnabled = RT_BOOL(fTemp); 7277 hrc = pRecScreenSettings->COMGETTER(MaxTime)((ULONG *)&recScreenSettings.ulMaxTimeS); 7278 7278 AssertComRCReturn(hrc, VERR_INVALID_PARAMETER); 7279 hrc = pRec ordScreenSettings->COMGETTER(MaxFileSize)((ULONG *)&RecordScreenSettings.File.ulMaxSizeMB);7279 hrc = pRecScreenSettings->COMGETTER(MaxFileSize)((ULONG *)&recScreenSettings.File.ulMaxSizeMB); 7280 7280 AssertComRCReturn(hrc, VERR_INVALID_PARAMETER); 7281 7281 Bstr bstrTemp; 7282 hrc = pRec ordScreenSettings->COMGETTER(Filename)(bstrTemp.asOutParam());7282 hrc = pRecScreenSettings->COMGETTER(Filename)(bstrTemp.asOutParam()); 7283 7283 AssertComRCReturn(hrc, VERR_INVALID_PARAMETER); 7284 RecordScreenSettings.File.strName = bstrTemp;7285 hrc = pRec ordScreenSettings->COMGETTER(Options)(bstrTemp.asOutParam());7284 recScreenSettings.File.strName = bstrTemp; 7285 hrc = pRecScreenSettings->COMGETTER(Options)(bstrTemp.asOutParam()); 7286 7286 AssertComRCReturn(hrc, VERR_INVALID_PARAMETER); 7287 RecordScreenSettings.strOptions = bstrTemp;7288 hrc = pRec ordScreenSettings->COMGETTER(VideoWidth)((ULONG *)&RecordScreenSettings.Video.ulWidth);7287 recScreenSettings.strOptions = bstrTemp; 7288 hrc = pRecScreenSettings->COMGETTER(VideoWidth)((ULONG *)&recScreenSettings.Video.ulWidth); 7289 7289 AssertComRCReturn(hrc, VERR_INVALID_PARAMETER); 7290 hrc = pRec ordScreenSettings->COMGETTER(VideoHeight)((ULONG *)&RecordScreenSettings.Video.ulHeight);7290 hrc = pRecScreenSettings->COMGETTER(VideoHeight)((ULONG *)&recScreenSettings.Video.ulHeight); 7291 7291 AssertComRCReturn(hrc, VERR_INVALID_PARAMETER); 7292 hrc = pRec ordScreenSettings->COMGETTER(VideoRate)((ULONG *)&RecordScreenSettings.Video.ulRate);7292 hrc = pRecScreenSettings->COMGETTER(VideoRate)((ULONG *)&recScreenSettings.Video.ulRate); 7293 7293 AssertComRCReturn(hrc, VERR_INVALID_PARAMETER); 7294 hrc = pRec ordScreenSettings->COMGETTER(VideoFPS)((ULONG *)&RecordScreenSettings.Video.ulFPS);7294 hrc = pRecScreenSettings->COMGETTER(VideoFPS)((ULONG *)&recScreenSettings.Video.ulFPS); 7295 7295 AssertComRCReturn(hrc, VERR_INVALID_PARAMETER); 7296 7296 7297 Settings.mapScreens[i] = RecordScreenSettings;7298 } 7299 7300 Assert( Settings.mapScreens.size() == paRecordingScreens.size());7297 recording.mapScreens[i] = recScreenSettings; 7298 } 7299 7300 Assert(recording.mapScreens.size() == paRecScreens.size()); 7301 7301 7302 7302 return VINF_SUCCESS; -
trunk/src/VBox/Main/src-client/Recording.cpp
r94950 r95639 151 151 return vrc; 152 152 153 settings::RecordingScreen Map::const_iterator itScreen = a_Settings.mapScreens.begin();153 settings::RecordingScreenSettingsMap::const_iterator itScreen = a_Settings.mapScreens.begin(); 154 154 while (itScreen != a_Settings.mapScreens.end()) 155 155 { … … 206 206 207 207 if (RT_SUCCESS(vrc)) /* Wait for the thread to start. */ 208 vrc = RTThreadUserWait(this->Thread, 30 * RT_MS_1SEC /* 30s timeout */);208 vrc = RTThreadUserWait(this->Thread, RT_MS_30SEC /* 30s timeout */); 209 209 210 210 if (RT_SUCCESS(vrc)) … … 237 237 int vrc = threadNotify(); 238 238 if (RT_SUCCESS(vrc)) 239 vrc = RTThreadWait(this->Thread, 30 * 1000 /* 10s timeout */, NULL);239 vrc = RTThreadWait(this->Thread, RT_MS_30SEC /* 30s timeout */, NULL); 240 240 241 241 lock(); … … 295 295 296 296 if (RTCritSectIsInitialized(&this->CritSect)) 297 {298 Assert(RTCritSectGetWaiters(&this->CritSect) == -1);299 297 RTCritSectDelete(&this->CritSect); 300 }301 298 302 299 this->enmState = RECORDINGSTS_UNINITIALIZED; -
trunk/src/VBox/Main/src-server/MachineImpl.cpp
r95556 r95639 510 510 mTrustedPlatformModule->i_applyDefaults(aOsType); 511 511 512 /* Apply record defaults. */512 /* Apply recording defaults. */ 513 513 mRecordingSettings->i_applyDefaults(); 514 514 … … 8632 8632 mBIOSSettings->init(this); 8633 8633 8634 /* create associated recording settings object */ 8635 unconst(mRecordingSettings).createObject(); 8636 mRecordingSettings->init(this); 8637 8634 8638 /* create associated trusted platform module object */ 8635 8639 unconst(mTrustedPlatformModule).createObject(); … … 8639 8643 unconst(mNvramStore).createObject(); 8640 8644 mNvramStore->init(this); 8641 8642 /* create associated record settings object */8643 unconst(mRecordingSettings).createObject();8644 mRecordingSettings->init(this);8645 8645 8646 8646 /* create the graphics adapter object (always present) */ … … 8771 8771 } 8772 8772 8773 if (mRecordingSettings) 8774 { 8775 mRecordingSettings->uninit(); 8776 unconst(mRecordingSettings).setNull(); 8777 } 8778 8773 8779 if (mTrustedPlatformModule) 8774 8780 { … … 8781 8787 mNvramStore->uninit(); 8782 8788 unconst(mNvramStore).setNull(); 8783 }8784 8785 if (mRecordingSettings)8786 {8787 mRecordingSettings->uninit();8788 unconst(mRecordingSettings).setNull();8789 8789 } 8790 8790 … … 9082 9082 9083 9083 // hardware data 9084 rc = i_loadHardware(puuidRegistry, NULL, config.hardwareMachine, &config.debugging, &config.autostart); 9084 rc = i_loadHardware(puuidRegistry, NULL, config.hardwareMachine, &config.debugging, &config.autostart, 9085 config.recordingSettings); 9085 9086 if (FAILED(rc)) return rc; 9086 9087 … … 9164 9165 ¤t->debugging, 9165 9166 ¤t->autostart, 9167 current->recordingSettings, 9166 9168 current->uuid.ref(), 9167 9169 strStateFile); … … 9214 9216 * @param data Reference to the hardware settings. 9215 9217 * @param pDbg Pointer to the debugging settings. 9216 * @param pAutostart Pointer to the autostart settings. 9218 * @param pAutostart Pointer to the autostart settings 9219 * @param recording Reference to recording settings. 9217 9220 */ 9218 9221 HRESULT Machine::i_loadHardware(const Guid *puuidRegistry, … … 9220 9223 const settings::Hardware &data, 9221 9224 const settings::Debugging *pDbg, 9222 const settings::Autostart *pAutostart) 9225 const settings::Autostart *pAutostart, 9226 const settings::RecordingSettings &recording) 9223 9227 { 9224 9228 AssertReturn(!i_isSessionMachine(), E_FAIL); … … 9326 9330 if (FAILED(rc)) return rc; 9327 9331 9332 /* Recording */ 9333 rc = mRecordingSettings->i_loadSettings(recording); 9334 if (FAILED(rc)) return rc; 9335 9328 9336 /* Trusted Platform Module */ 9329 9337 rc = mTrustedPlatformModule->i_loadSettings(data.tpmSettings); … … 9331 9339 9332 9340 rc = mNvramStore->i_loadSettings(data.nvramSettings); 9333 if (FAILED(rc)) return rc;9334 9335 /* Recording settings */9336 rc = mRecordingSettings->i_loadSettings(data.recordingSettings);9337 9341 if (FAILED(rc)) return rc; 9338 9342 … … 10578 10582 /// @todo Live Migration: config.fTeleported = (mData->mMachineState == MachineState_Teleported); 10579 10583 10580 HRESULT rc = i_saveHardware(config.hardwareMachine, &config.debugging, &config.autostart);10581 if (FAILED( rc)) throwrc;10584 HRESULT hrc = i_saveHardware(config.hardwareMachine, &config.debugging, &config.autostart, config.recordingSettings); 10585 if (FAILED(hrc)) throw hrc; 10582 10586 10583 10587 // save machine's media registry if this is VirtualBox 4.0 or later … … 10594 10598 10595 10599 // save snapshots 10596 rc = i_saveAllSnapshots(config);10597 if (FAILED( rc)) throwrc;10600 hrc = i_saveAllSnapshots(config); 10601 if (FAILED(hrc)) throw hrc; 10598 10602 } 10599 10603 … … 10651 10655 * @param pAutostart Pointer to the settings object for the autostart config 10652 10656 * which happens to live in mHWData. 10657 * @param recording Reference to reecording settings. 10653 10658 */ 10654 10659 HRESULT Machine::i_saveHardware(settings::Hardware &data, settings::Debugging *pDbg, 10655 settings::Autostart *pAutostart )10660 settings::Autostart *pAutostart, settings::RecordingSettings &recording) 10656 10661 { 10657 10662 HRESULT rc = S_OK; … … 10757 10762 if (FAILED(rc)) throw rc; 10758 10763 10764 /* Recording settings. */ 10765 rc = mRecordingSettings->i_saveSettings(recording); 10766 if (FAILED(rc)) throw rc; 10767 10759 10768 /* Trusted Platform Module settings (required) */ 10760 10769 rc = mTrustedPlatformModule->i_saveSettings(data.tpmSettings); … … 10763 10772 /* NVRAM settings (required) */ 10764 10773 rc = mNvramStore->i_saveSettings(data.nvramSettings); 10765 if (FAILED(rc)) throw rc;10766 10767 /* Recording settings (required) */10768 rc = mRecordingSettings->i_saveSettings(data.recordingSettings);10769 10774 if (FAILED(rc)) throw rc; 10770 10775 … … 12325 12330 mBIOSSettings->i_rollback(); 12326 12331 12332 if (mRecordingSettings && (mData->flModifications & IsModified_Recording)) 12333 mRecordingSettings->i_rollback(); 12334 12327 12335 if (mTrustedPlatformModule) 12328 12336 mTrustedPlatformModule->i_rollback(); … … 12330 12338 if (mNvramStore) 12331 12339 mNvramStore->i_rollback(); 12332 12333 if (mRecordingSettings && (mData->flModifications & IsModified_Recording))12334 mRecordingSettings->i_rollback();12335 12340 12336 12341 if (mGraphicsAdapter && (mData->flModifications & IsModified_GraphicsAdapter)) … … 12456 12461 12457 12462 mBIOSSettings->i_commit(); 12463 mRecordingSettings->i_commit(); 12458 12464 mTrustedPlatformModule->i_commit(); 12459 12465 mNvramStore->i_commit(); 12460 mRecordingSettings->i_commit();12461 12466 mGraphicsAdapter->i_commit(); 12462 12467 mVRDEServer->i_commit(); … … 12712 12717 12713 12718 mBIOSSettings->i_copyFrom(aThat->mBIOSSettings); 12719 mRecordingSettings->i_copyFrom(aThat->mRecordingSettings); 12714 12720 mTrustedPlatformModule->i_copyFrom(aThat->mTrustedPlatformModule); 12715 12721 mNvramStore->i_copyFrom(aThat->mNvramStore); 12716 mRecordingSettings->i_copyFrom(aThat->mRecordingSettings);12717 12722 mGraphicsAdapter->i_copyFrom(aThat->mGraphicsAdapter); 12718 12723 mVRDEServer->i_copyFrom(aThat->mVRDEServer); … … 13090 13095 mBIOSSettings->init(this, aMachine->mBIOSSettings); 13091 13096 13097 unconst(mRecordingSettings).createObject(); 13098 mRecordingSettings->init(this, aMachine->mRecordingSettings); 13099 13092 13100 unconst(mTrustedPlatformModule).createObject(); 13093 13101 mTrustedPlatformModule->init(this, aMachine->mTrustedPlatformModule); … … 13096 13104 mNvramStore->init(this, aMachine->mNvramStore); 13097 13105 13098 unconst(mRecordingSettings).createObject();13099 mRecordingSettings->init(this, aMachine->mRecordingSettings);13100 13106 /* create another GraphicsAdapter object that will be mutable */ 13101 13107 unconst(mGraphicsAdapter).createObject(); -
trunk/src/VBox/Main/src-server/RecordingScreenSettingsImpl.cpp
r93115 r95639 53 53 54 54 // constructor / destructor 55 ///////////////////////////////////////////////////////////////////////////// 55 //////////////////////////////////////////////////////////////////////////////// 56 56 57 57 DEFINE_EMPTY_CTOR_DTOR(RecordingScreenSettings) … … 69 69 70 70 // public initializer/uninitializer for internal purposes only 71 ///////////////////////////////////////////////////////////////////////////// 71 //////////////////////////////////////////////////////////////////////////////// 72 72 73 73 /** … … 79 79 const settings::RecordingScreenSettings& aThat) 80 80 { 81 LogFlowThisFuncEnter();82 81 LogFlowThisFunc(("aParent: %p\n", aParent)); 83 82 … … 99 98 m->bd->operator=(aThat); 100 99 101 HRESULT rc = S_OK;100 HRESULT hrc = S_OK; 102 101 103 102 int vrc = i_initInternal(); … … 109 108 { 110 109 autoInitSpan.setFailed(); 111 rc = E_UNEXPECTED;110 hrc = E_UNEXPECTED; 112 111 } 113 112 114 113 LogFlowThisFuncLeave(); 115 return rc;114 return hrc; 116 115 } 117 116 … … 122 121 * 123 122 * @note This object must be destroyed before the original object 124 * it shares data with is destroyed.123 * it shares data with is destroyed. 125 124 */ 126 125 HRESULT RecordingScreenSettings::init(RecordingSettings *aParent, RecordingScreenSettings *aThat) 127 126 { 128 LogFlowThisFuncEnter();129 127 LogFlowThisFunc(("aParent: %p, aThat: %p\n", aParent, aThat)); 130 128 … … 172 170 HRESULT RecordingScreenSettings::initCopy(RecordingSettings *aParent, RecordingScreenSettings *aThat) 173 171 { 174 LogFlowThisFuncEnter();175 172 LogFlowThisFunc(("aParent: %p, aThat: %p\n", aParent, aThat)); 176 173 … … 194 191 m->bd.attachCopy(aThat->m->bd); 195 192 196 HRESULT rc = S_OK;193 HRESULT hrc = S_OK; 197 194 198 195 int vrc = i_initInternal(); … … 204 201 { 205 202 autoInitSpan.setFailed(); 206 rc = E_UNEXPECTED;203 hrc = E_UNEXPECTED; 207 204 } 208 205 209 206 LogFlowThisFuncLeave(); 210 return rc;207 return hrc; 211 208 } 212 209 … … 331 328 332 329 m->bd.backup(); 330 331 settings::RecordingFeatureMap featureMapOld = m->bd->featureMap; 333 332 m->bd->featureMap.clear(); 334 333 … … 338 337 m->bd->featureMap[RecordingFeature_Video] = true; 339 338 340 alock.release(); 339 if (m->bd->featureMap != featureMapOld) 340 { 341 alock.release(); 342 343 m->pParent->i_onSettingsChanged(); 344 } 341 345 342 346 return S_OK; … … 363 367 return setError(E_INVALIDARG, tr("Cannot change destination type while recording is enabled")); 364 368 365 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 366 367 m->bd.backup(); 368 m->bd->enmDest = aDestination; 369 if (aDestination != RecordingDestination_File) 370 return setError(E_INVALIDARG, tr("Destination type invalid / not supported")); 371 372 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 373 374 if (m->bd->enmDest != aDestination) 375 { 376 m->bd.backup(); 377 m->bd->enmDest = aDestination; 378 379 m->pParent->i_onSettingsChanged(); 380 } 369 381 370 382 return S_OK; … … 382 394 || m->bd->File.strName.equals(".")) 383 395 { 384 int vrc = m->pParent->i_getDefaultFilename( m->bd->File.strName, true /* fWithFileExtension */);396 int vrc = m->pParent->i_getDefaultFilename(aFilename, m->uScreenId, true /* fWithFileExtension */); 385 397 if (RT_FAILURE(vrc)) 386 return setError(E_INVALIDARG, tr("Error retrieving default file name")); 387 } 388 389 aFilename = m->bd->File.strName; 398 return setErrorBoth(E_INVALIDARG, vrc, tr("Error retrieving default file name")); 399 400 /* Important: Don't assign the default file name to File.strName, as this woulnd't be considered 401 * as default settings anymore! */ 402 } 403 else /* Return custom file name. */ 404 aFilename = m->bd->File.strName; 390 405 391 406 return S_OK; … … 400 415 return setError(E_INVALIDARG, tr("Cannot change file name while recording is enabled")); 401 416 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; 417 if (aFilename.isNotEmpty()) 418 { 419 if (!RTPathStartsWithRoot(aFilename.c_str())) 420 return setError(E_INVALIDARG, tr("Recording file name '%s' is not absolute"), aFilename.c_str()); 421 } 422 423 /** @todo Add more sanity? */ 424 425 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 426 427 /* Note: When setting an empty file name, this will return the screen's default file name when using ::getFileName(). */ 428 if (m->bd->File.strName != aFilename) 429 { 430 m->bd.backup(); 431 m->bd->File.strName = aFilename; 432 433 alock.release(); 434 435 m->pParent->i_onSettingsChanged(); 436 } 410 437 411 438 return S_OK; … … 434 461 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 435 462 436 m->bd.backup(); 437 m->bd->ulMaxTimeS = aMaxTimeS; 463 if (m->bd->ulMaxTimeS != aMaxTimeS) 464 { 465 m->bd.backup(); 466 m->bd->ulMaxTimeS = aMaxTimeS; 467 468 alock.release(); 469 470 m->pParent->i_onSettingsChanged(); 471 } 438 472 439 473 return S_OK; … … 462 496 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 463 497 464 m->bd.backup(); 465 m->bd->File.ulMaxSizeMB = aMaxFileSize; 498 if (m->bd->File.ulMaxSizeMB != aMaxFileSize) 499 { 500 m->bd.backup(); 501 m->bd->File.ulMaxSizeMB = aMaxFileSize; 502 503 alock.release(); 504 505 m->pParent->i_onSettingsChanged(); 506 } 466 507 467 508 return S_OK; … … 489 530 490 531 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 491 492 m->bd.backup();493 m->bd->strOptions = aOptions;494 532 495 533 int vrc = RecordingScreenSettings::i_parseOptionsString(aOptions, *m->bd.data()); … … 497 535 return setError(E_INVALIDARG, tr("Invalid option specified")); 498 536 537 m->bd.backup(); 538 m->bd->strOptions = aOptions; 539 540 alock.release(); 541 542 m->pParent->i_onSettingsChanged(); 543 499 544 return S_OK; 500 545 } … … 520 565 return setError(E_INVALIDARG, tr("Cannot change audio codec while recording is enabled")); 521 566 522 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 523 524 m->bd.backup(); 525 m->bd->Audio.enmAudioCodec = aCodec; 567 if (aCodec != RecordingAudioCodec_Opus) 568 return setError(E_INVALIDARG, tr("Audio codec not supported")); 569 570 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 571 572 if (m->bd->Audio.enmAudioCodec != aCodec) 573 { 574 m->bd.backup(); 575 m->bd->Audio.enmAudioCodec = aCodec; 576 577 alock.release(); 578 579 m->pParent->i_onSettingsChanged(); 580 } 526 581 527 582 return S_OK; … … 550 605 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 551 606 552 m->bd.backup(); 553 m->bd->Audio.uHz = (uint16_t)aHz; 607 if (m->bd->Audio.uHz != (uint16_t)aHz) 608 { 609 m->bd.backup(); 610 m->bd->Audio.uHz = (uint16_t)aHz; 611 612 alock.release(); 613 614 m->pParent->i_onSettingsChanged(); 615 } 554 616 555 617 return S_OK; … … 578 640 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 579 641 580 m->bd.backup(); 581 m->bd->Audio.cBits = (uint8_t)aBits; 642 if (m->bd->Audio.cBits != (uint8_t)aBits) 643 { 644 m->bd.backup(); 645 m->bd->Audio.cBits = (uint8_t)aBits; 646 647 alock.release(); 648 649 m->pParent->i_onSettingsChanged(); 650 } 582 651 583 652 return S_OK; … … 606 675 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 607 676 608 m->bd.backup(); 609 m->bd->Audio.cChannels = (uint8_t)aChannels; 677 if (m->bd->Audio.cChannels != (uint8_t)aChannels) 678 { 679 m->bd.backup(); 680 m->bd->Audio.cChannels = (uint8_t)aChannels; 681 682 alock.release(); 683 684 m->pParent->i_onSettingsChanged(); 685 } 610 686 611 687 return S_OK; … … 632 708 return setError(E_INVALIDARG, tr("Cannot change video codec while recording is enabled")); 633 709 634 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 635 636 m->bd.backup(); 637 m->bd->Video.enmCodec = aCodec; 710 if (aCodec != RecordingVideoCodec_VP8) 711 return setError(E_INVALIDARG, tr("Video codec not supported")); 712 713 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 714 715 if (m->bd->Video.enmCodec != aCodec) 716 { 717 m->bd.backup(); 718 m->bd->Video.enmCodec = aCodec; 719 720 alock.release(); 721 722 m->pParent->i_onSettingsChanged(); 723 } 638 724 639 725 return S_OK; … … 662 748 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 663 749 664 m->bd.backup(); 665 m->bd->Video.ulWidth = aVideoWidth; 750 if (m->bd->Video.ulWidth != aVideoWidth) 751 { 752 m->bd.backup(); 753 m->bd->Video.ulWidth = aVideoWidth; 754 755 alock.release(); 756 757 m->pParent->i_onSettingsChanged(); 758 } 666 759 667 760 return S_OK; … … 690 783 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 691 784 692 m->bd.backup(); 693 m->bd->Video.ulHeight = aVideoHeight; 785 if (m->bd->Video.ulHeight != aVideoHeight) 786 { 787 m->bd.backup(); 788 m->bd->Video.ulHeight = aVideoHeight; 789 790 alock.release(); 791 792 m->pParent->i_onSettingsChanged(); 793 } 694 794 695 795 return S_OK; … … 718 818 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 719 819 720 m->bd.backup(); 721 m->bd->Video.ulRate = aVideoRate; 820 if (m->bd->Video.ulRate != aVideoRate) 821 { 822 m->bd.backup(); 823 m->bd->Video.ulRate = aVideoRate; 824 825 alock.release(); 826 827 m->pParent->i_onSettingsChanged(); 828 } 722 829 723 830 return S_OK; … … 774 881 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 775 882 776 m->bd.backup(); 777 m->bd->Video.ulFPS = aVideoFPS; 883 if (m->bd->Video.ulFPS != aVideoFPS) 884 { 885 m->bd.backup(); 886 m->bd->Video.ulFPS = aVideoFPS; 887 888 alock.release(); 889 890 m->pParent->i_onSettingsChanged(); 891 } 778 892 779 893 return S_OK; … … 811 925 * Initializes data, internal version. 812 926 * 813 * @returns IPRTstatus code.927 * @returns VBox status code. 814 928 */ 815 929 int RecordingScreenSettings::i_initInternal(void) 816 930 { 817 Assert (m);818 819 int rc = i_parseOptionsString(m->bd->strOptions, *m->bd.data());820 if (RT_FAILURE( rc))821 return rc;931 AssertPtrReturn(m, VERR_INVALID_POINTER); 932 933 int vrc = i_parseOptionsString(m->bd->strOptions, *m->bd.data()); 934 if (RT_FAILURE(vrc)) 935 return vrc; 822 936 823 937 switch (m->bd->enmDest) … … 825 939 case RecordingDestination_File: 826 940 { 827 if (m->bd->File.strName.isEmpty())828 rc = m->pParent->i_getDefaultFilename(m->bd->File.strName, true /* fWithExtension */);941 /* Note: Leave the file name empty here, which means using the default setting. 942 * Important when comparing with the default settings! */ 829 943 break; 830 944 } … … 834 948 } 835 949 836 return rc; 950 return vrc; 951 } 952 953 954 // public methods only for internal purposes 955 //////////////////////////////////////////////////////////////////////////////// 956 957 /** 958 * Loads settings from the given machine node. 959 * May be called once right after this object creation. 960 * 961 * @returns HRESULT 962 * @param data Configuration settings to load. 963 */ 964 HRESULT RecordingScreenSettings::i_loadSettings(const settings::RecordingScreenSettings &data) 965 { 966 AutoCaller autoCaller(this); 967 AssertComRCReturnRC(autoCaller.rc()); 968 969 AutoReadLock mlock(m->pParent COMMA_LOCKVAL_SRC_POS); 970 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 971 972 // simply copy 973 m->bd.assignCopy(&data); 974 return S_OK; 975 } 976 977 /** 978 * Saves settings to the given machine node. 979 * 980 * @returns HRESULT 981 * @param data Configuration settings to save to. 982 */ 983 HRESULT RecordingScreenSettings::i_saveSettings(settings::RecordingScreenSettings &data) 984 { 985 /* sanity */ 986 AutoCaller autoCaller(this); 987 AssertComRCReturnRC(autoCaller.rc()); 988 989 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 990 991 data = *m->bd.data(); 992 993 return S_OK; 994 } 995 996 void RecordingScreenSettings::i_rollback(void) 997 { 998 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 999 m->bd.rollback(); 1000 } 1001 1002 void RecordingScreenSettings::i_commit(void) 1003 { 1004 /* sanity */ 1005 AutoCaller autoCaller(this); 1006 AssertComRCReturnVoid(autoCaller.rc()); 1007 1008 /* sanity too */ 1009 AutoCaller peerCaller(m->pPeer); 1010 AssertComRCReturnVoid(peerCaller.rc()); 1011 1012 /* lock both for writing since we modify both (mPeer is "master" so locked 1013 * first) */ 1014 AutoMultiWriteLock2 alock(m->pPeer, this COMMA_LOCKVAL_SRC_POS); 1015 1016 if (m->bd.isBackedUp()) 1017 { 1018 m->bd.commit(); 1019 if (m->pPeer) 1020 { 1021 /* attach new data to the peer and reshare it */ 1022 AutoWriteLock peerlock(m->pPeer COMMA_LOCKVAL_SRC_POS); 1023 m->pPeer->m->bd.attach(m->bd); 1024 } 1025 } 1026 } 1027 1028 void RecordingScreenSettings::i_copyFrom(RecordingScreenSettings *aThat) 1029 { 1030 AssertReturnVoid(aThat != NULL); 1031 1032 /* sanity */ 1033 AutoCaller autoCaller(this); 1034 AssertComRCReturnVoid(autoCaller.rc()); 1035 1036 /* sanity too */ 1037 AutoCaller thatCaller(aThat); 1038 AssertComRCReturnVoid(thatCaller.rc()); 1039 1040 /* peer is not modified, lock it for reading (aThat is "master" so locked 1041 * first) */ 1042 AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS); 1043 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS); 1044 1045 /* this will back up current data */ 1046 m->bd.assignCopy(aThat->m->bd); 1047 } 1048 1049 /** 1050 * Applies default screen recording settings. 1051 * 1052 * @note Locks this object for writing. 1053 */ 1054 void RecordingScreenSettings::i_applyDefaults(void) 1055 { 1056 /* sanity */ 1057 AutoCaller autoCaller(this); 1058 AssertComRCReturnVoid(autoCaller.rc()); 1059 1060 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1061 1062 m->bd->applyDefaults(); 1063 } 1064 1065 settings::RecordingScreenSettings &RecordingScreenSettings::i_getData(void) 1066 { 1067 /* sanity */ 1068 AutoCaller autoCaller(this); 1069 AssertComRC(autoCaller.rc()); 1070 1071 AssertPtr(m); 1072 return *m->bd.data(); 837 1073 } 838 1074 -
trunk/src/VBox/Main/src-server/RecordingSettingsImpl.cpp
r93115 r95639 43 43 { } 44 44 45 Machine * const pMachine;46 const ComObjPtr<RecordingSettings> pPeer;47 Record ScreenSettingsMapmapScreenObj;45 Machine * const pMachine; 46 const ComObjPtr<RecordingSettings> pPeer; 47 RecordingScreenSettingsObjMap mapScreenObj; 48 48 49 49 // use the XML settings structure in the members for simplicity 50 Backupable<settings::Recording Settings> bd;50 Backupable<settings::RecordingCommonSettings> bd; 51 51 }; 52 52 … … 87 87 m->bd.allocate(); 88 88 89 i_applyDefaults(); 90 89 91 autoInitSpan.setSucceeded(); 90 92 … … 99 101 * 100 102 * @note This object must be destroyed before the original object 101 * it shares data with is destroyed.103 * it shares data with is destroyed. 102 104 * 103 105 * @note Locks @a aThat object for reading. … … 157 159 158 160 AutoReadLock thatlock(aThat COMMA_LOCKVAL_SRC_POS); 159 160 161 m->bd.attachCopy(aThat->m->bd); 161 m->mapScreenObj = aThat->m->mapScreenObj; 162 163 autoInitSpan.setSucceeded(); 162 163 HRESULT hrc = S_OK; 164 165 for (RecordingScreenSettingsObjMap::const_iterator itScreenThat = aThat->m->mapScreenObj.begin(); 166 itScreenThat != aThat->m->mapScreenObj.end(); 167 ++itScreenThat) 168 { 169 ComObjPtr<RecordingScreenSettings> pSettings; 170 pSettings.createObject(); 171 hrc = pSettings->initCopy(this, itScreenThat->second); 172 if (FAILED(hrc)) return hrc; 173 174 try 175 { 176 m->mapScreenObj[itScreenThat->first] = pSettings; 177 } 178 catch (...) 179 { 180 hrc = E_OUTOFMEMORY; 181 } 182 } 183 184 if (SUCCEEDED(hrc)) 185 autoInitSpan.setSucceeded(); 164 186 165 187 LogFlowThisFuncLeave(); 166 return S_OK;188 return hrc; 167 189 } 168 190 … … 229 251 { 230 252 /* 231 * Normally we would do the actual change _after_ i_on CaptureChange() succeeded.253 * Normally we would do the actual change _after_ i_onRecordingChange() succeeded. 232 254 * We cannot do this because that function uses RecordSettings::GetEnabled to 233 255 * determine if it should start or stop capturing. Therefore we need to manually … … 270 292 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 271 293 272 aRecordScreenSettings.clear(); 273 aRecordScreenSettings.resize(m->mapScreenObj.size()); 274 275 RecordScreenSettingsMap::const_iterator itScreenSettings = m->mapScreenObj.begin(); 294 HRESULT hrc = S_OK; 295 296 try 297 { 298 aRecordScreenSettings.clear(); 299 aRecordScreenSettings.resize(m->mapScreenObj.size()); 300 } 301 catch (...) 302 { 303 hrc = E_OUTOFMEMORY; 304 } 305 306 if (FAILED(hrc)) 307 return hrc; 308 309 RecordingScreenSettingsObjMap::const_iterator itScreenObj = m->mapScreenObj.begin(); 276 310 size_t i = 0; 277 while (itScreen Settings!= m->mapScreenObj.end())278 { 279 itScreen Settings->second.queryInterfaceTo(aRecordScreenSettings[i].asOutParam());280 Assert (aRecordScreenSettings[i].isNotNull());311 while (itScreenObj != m->mapScreenObj.end()) 312 { 313 itScreenObj->second.queryInterfaceTo(aRecordScreenSettings[i].asOutParam()); 314 AssertBreakStmt(aRecordScreenSettings[i].isNotNull(), hrc = E_POINTER); 281 315 ++i; 282 ++itScreen Settings;316 ++itScreenObj; 283 317 } 284 318 285 319 Assert(aRecordScreenSettings.size() == m->mapScreenObj.size()); 286 320 287 return S_OK;321 return hrc; 288 322 } 289 323 … … 306 340 return setError(E_INVALIDARG, tr("Invalid screen ID specified")); 307 341 308 Record ScreenSettingsMap::const_iterator itScreenSettings= m->mapScreenObj.find(uScreenId);309 if (itScreen Settings!= m->mapScreenObj.end())310 { 311 itScreen Settings->second.queryInterfaceTo(aRecordScreenSettings.asOutParam());342 RecordingScreenSettingsObjMap::const_iterator itScreen = m->mapScreenObj.find(uScreenId); 343 if (itScreen != m->mapScreenObj.end()) 344 { 345 itScreen->second.queryInterfaceTo(aRecordScreenSettings.asOutParam()); 312 346 return S_OK; 313 347 } … … 327 361 * @returns IPRT status code. VERR_ALREADY_EXISTS if the object in question already exists. 328 362 * @param screenSettingsMap Map to add screen settings to. 329 * @param uScreenIdScreen ID to add settings for.363 * @param idScreen Screen ID to add settings for. 330 364 * @param data Recording screen settings to use for that screen. 331 365 */ 332 int RecordingSettings::i_createScreenObj(RecordScreenSettingsMap &screenSettingsMap, 333 uint32_t uScreenId, const settings::RecordingScreenSettings &data) 334 { 335 LogFlowThisFunc(("Screen %RU32\n", uScreenId)); 336 337 if (screenSettingsMap.find(uScreenId) != screenSettingsMap.end()) 338 { 339 AssertFailed(); 340 return VERR_ALREADY_EXISTS; 341 } 366 int RecordingSettings::i_createScreenObj(RecordingScreenSettingsObjMap &screenSettingsMap, 367 uint32_t idScreen, const settings::RecordingScreenSettings &data) 368 { 369 AssertReturn(screenSettingsMap.find(idScreen) == screenSettingsMap.end(), VERR_ALREADY_EXISTS); 370 371 LogFlowThisFunc(("Screen %RU32\n", idScreen)); 342 372 343 373 int vrc = VINF_SUCCESS; 344 374 345 375 ComObjPtr<RecordingScreenSettings> recordingScreenSettings; 346 HRESULT rc = recordingScreenSettings.createObject();347 if (SUCCEEDED( rc))348 { 349 rc = recordingScreenSettings->init(this, uScreenId, data);350 if (SUCCEEDED( rc))376 HRESULT hrc = recordingScreenSettings.createObject(); 377 if (SUCCEEDED(hrc)) 378 { 379 hrc = recordingScreenSettings->init(this, idScreen, data); 380 if (SUCCEEDED(hrc)) 351 381 { 352 382 try 353 383 { 354 screenSettingsMap[ uScreenId] = recordingScreenSettings;384 screenSettingsMap[idScreen] = recordingScreenSettings; 355 385 } 356 386 catch (std::bad_alloc &) … … 369 399 * @returns IPRT status code. VERR_NOT_FOUND if specified screen was not found. 370 400 * @param screenSettingsMap Map to remove screen settings from. 371 * @param uScreenId ID of screen to remove. 372 */ 373 int RecordingSettings::i_destroyScreenObj(RecordScreenSettingsMap &screenSettingsMap, uint32_t uScreenId) 374 { 375 LogFlowThisFunc(("Screen %RU32\n", uScreenId)); 376 377 AssertReturn(uScreenId > 0, VERR_INVALID_PARAMETER); /* Removing screen 0 isn't a good idea. */ 378 379 RecordScreenSettingsMap::iterator itScreen = screenSettingsMap.find(uScreenId); 380 if (itScreen == screenSettingsMap.end()) 381 { 382 AssertFailed(); 383 return VERR_NOT_FOUND; 384 } 401 * @param idScreen ID of screen to remove. 402 */ 403 int RecordingSettings::i_destroyScreenObj(RecordingScreenSettingsObjMap &screenSettingsMap, uint32_t idScreen) 404 { 405 LogFlowThisFunc(("Screen %RU32\n", idScreen)); 406 407 AssertReturn(idScreen > 0, VERR_INVALID_PARAMETER); /* Removing screen 0 isn't a good idea. */ 408 AssertReturn(screenSettingsMap.find(idScreen) == screenSettingsMap.end(), VERR_NOT_FOUND); 409 410 RecordingScreenSettingsObjMap::iterator itScreen = screenSettingsMap.find(idScreen); 385 411 386 412 /* Make sure to consume the pointer before the one of the … … 401 427 * @param screenSettingsMap Map to destroy screen settings objects for. 402 428 */ 403 int RecordingSettings::i_destroyAllScreenObj(Record ScreenSettingsMap &screenSettingsMap)404 { 405 LogFlowThisFuncEnter(); 406 407 Record ScreenSettingsMap::iterator itScreen= screenSettingsMap.begin();408 while (itScreen != screenSettingsMap.end())429 int RecordingSettings::i_destroyAllScreenObj(RecordingScreenSettingsObjMap &screenSettingsMap) 430 { 431 LogFlowThisFuncEnter(); 432 433 RecordingScreenSettingsObjMap::iterator itScreenObj = screenSettingsMap.begin(); 434 while (itScreenObj != screenSettingsMap.end()) 409 435 { 410 436 /* Make sure to consume the pointer before the one of the 411 437 * iterator gets released. */ 412 ComObjPtr<RecordingScreenSettings> pScreenSettings = itScreen->second; 413 414 screenSettingsMap.erase(itScreen); 415 438 ComObjPtr<RecordingScreenSettings> pScreenSettings = itScreenObj->second; 439 440 screenSettingsMap.erase(itScreenObj); 441 442 pScreenSettings->uninit(); 416 443 pScreenSettings.setNull(); 417 444 418 itScreen = screenSettingsMap.begin();445 itScreenObj = screenSettingsMap.begin(); 419 446 } 420 447 … … 440 467 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 441 468 442 HRESULT rc = S_OK; 443 444 i_reset(); 469 HRESULT hrc = S_OK; 445 470 446 471 LogFlowThisFunc(("Data has %zu screens\n", data.mapScreens.size())); 447 472 448 settings::RecordingScreenMap::const_iterator itScreen = data.mapScreens.begin(); 449 while (itScreen != data.mapScreens.end()) 450 { 451 int vrc = i_createScreenObj(m->mapScreenObj, 452 itScreen->first /* uScreenId */, itScreen->second /* Settings */); 453 if (RT_FAILURE(vrc)) 454 { 455 rc = E_OUTOFMEMORY; 456 break; 457 } 458 459 ++itScreen; 460 } 461 462 if (FAILED(rc)) 463 return rc; 464 465 ComAssertComRC(rc); 466 Assert(m->mapScreenObj.size() == data.mapScreens.size()); 467 468 // simply copy 469 m->bd.assignCopy(&data); 470 471 LogFlowThisFunc(("Returning %Rhrc\n", rc)); 472 return rc; 473 settings::RecordingScreenSettingsMap::const_iterator itScreenData = data.mapScreens.begin(); 474 while (itScreenData != data.mapScreens.end()) 475 { 476 RecordingScreenSettingsObjMap::iterator itScreen = m->mapScreenObj.find(itScreenData->first); 477 if (itScreen != m->mapScreenObj.end()) 478 { 479 hrc = itScreen->second->i_loadSettings(itScreenData->second); 480 if (FAILED(hrc)) 481 break; 482 } 483 else 484 { 485 int vrc = i_createScreenObj(m->mapScreenObj, 486 itScreenData->first /* uScreenId */, itScreenData->second /* Settings */); 487 if (RT_FAILURE(vrc)) 488 { 489 hrc = E_OUTOFMEMORY; /* Most likely. */ 490 break; 491 } 492 } 493 494 ++itScreenData; 495 } 496 497 if (SUCCEEDED(hrc)) 498 { 499 ComAssertComRCRet(hrc, hrc); 500 AssertReturn(m->mapScreenObj.size() == data.mapScreens.size(), E_UNEXPECTED); 501 502 // simply copy 503 m->bd.assignCopy(&data.common); 504 } 505 506 LogFlowThisFunc(("Returning %Rhrc\n", hrc)); 507 return hrc; 473 508 } 474 509 … … 481 516 482 517 i_destroyAllScreenObj(m->mapScreenObj); 483 m->bd->mapScreens.clear();484 518 } 485 519 … … 510 544 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 511 545 512 data = *m->bd.data(); 513 514 settings::RecordingScreenMap::iterator itScreen = data.mapScreens.begin(); 515 while (itScreen != data.mapScreens.end()) 516 { 517 /* Store relative path of capture file if possible. */ 518 m->pMachine->i_copyPathRelativeToMachine(itScreen->second.File.strName /* Source */, 519 itScreen->second.File.strName /* Target */); 520 ++itScreen; 546 data.common = *m->bd.data(); 547 548 HRESULT hrc; 549 550 for (RecordingScreenSettingsObjMap::const_iterator itScreen = m->mapScreenObj.begin(); 551 itScreen != m->mapScreenObj.end(); 552 ++itScreen) 553 { 554 hrc = itScreen->second->i_saveSettings(data.mapScreens[itScreen->first /* Screen ID */]); 555 if (FAILED(hrc)) 556 break; 521 557 } 522 558 523 559 LogFlowThisFuncLeave(); 524 return S_OK;525 } 526 527 void RecordingSettings::i_rollback( )560 return hrc; 561 } 562 563 void RecordingSettings::i_rollback(void) 528 564 { 529 565 /* sanity */ … … 532 568 533 569 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 570 534 571 m->bd.rollback(); 535 } 536 537 void RecordingSettings::i_commit() 572 573 for (RecordingScreenSettingsObjMap::const_iterator itScreen = m->mapScreenObj.begin(); 574 itScreen != m->mapScreenObj.end(); 575 ++itScreen) 576 { 577 itScreen->second->i_rollback(); 578 } 579 } 580 581 void RecordingSettings::i_commit(void) 538 582 { 539 583 /* sanity */ … … 557 601 m->pPeer->m->bd.attach(m->bd); 558 602 } 559 } 560 } 561 562 void RecordingSettings::i_copyFrom(RecordingSettings *aThat) 563 { 564 AssertReturnVoid(aThat != NULL); 603 604 for (RecordingScreenSettingsObjMap::const_iterator itScreenObj = m->mapScreenObj.begin(); 605 itScreenObj != m->mapScreenObj.end(); 606 ++itScreenObj) 607 { 608 itScreenObj->second->i_commit(); 609 if (m->pPeer) 610 m->pPeer->i_commit(); 611 } 612 } 613 } 614 615 HRESULT RecordingSettings::i_copyFrom(RecordingSettings *aThat) 616 { 617 AssertPtrReturn(aThat, E_INVALIDARG); 565 618 566 619 /* sanity */ 567 620 AutoCaller autoCaller(this); 568 AssertComRCReturn Void(autoCaller.rc());621 AssertComRCReturn(autoCaller.rc(), VBOX_E_INVALID_OBJECT_STATE); 569 622 570 623 /* sanity too */ 571 624 AutoCaller thatCaller(aThat); 572 AssertComRCReturn Void(thatCaller.rc());625 AssertComRCReturn(thatCaller.rc(), VBOX_E_INVALID_OBJECT_STATE); 573 626 574 627 /* peer is not modified, lock it for reading (aThat is "master" so locked … … 579 632 /* this will back up current data */ 580 633 m->bd.assignCopy(aThat->m->bd); 634 635 HRESULT hrc = S_OK; 636 637 for (RecordingScreenSettingsObjMap::const_iterator itScreenThat = aThat->m->mapScreenObj.begin(); 638 itScreenThat != aThat->m->mapScreenObj.end(); 639 ++itScreenThat) 640 { 641 RecordingScreenSettingsObjMap::iterator itScreen = m->mapScreenObj.find(itScreenThat->first); 642 if (itScreen != m->mapScreenObj.end()) 643 { 644 itScreen->second->i_copyFrom(itScreenThat->second); 645 } 646 else 647 { 648 int vrc = i_createScreenObj(m->mapScreenObj, 649 itScreenThat->first /* uScreenId */, itScreenThat->second->i_getData() /* Settings */); 650 if (RT_FAILURE(vrc)) 651 { 652 hrc = E_OUTOFMEMORY; /* Most likely. */ 653 break; 654 } 655 } 656 } 657 658 return hrc; 581 659 } 582 660 … … 606 684 607 685 /** 608 * Returns the full path to the default video capturefile.609 */ 610 int RecordingSettings::i_getDefaultFilename(Utf8Str &strFile, bool fWithFileExtension)686 * Returns the full path to the default recording file. 687 */ 688 int RecordingSettings::i_getDefaultFilename(Utf8Str &strFile, uint32_t idScreen, bool fWithFileExtension) 611 689 { 612 690 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 613 691 614 692 strFile = m->pMachine->i_getSettingsFileFull(); // path/to/machinesfolder/vmname/vmname.vbox 615 strFile.stripSuffix(); // path/to/machinesfolder/vmname/vmname 693 strFile.stripSuffix(); 694 strFile.append(Utf8StrFmt("-screen%RU32", idScreen)); 616 695 if (fWithFileExtension) 617 strFile.append(".webm"); // path/to/machinesfolder/vmname/vmname.webm696 strFile.append(".webm"); 618 697 619 698 return VINF_SUCCESS; … … 661 740 * Synchronizes the screen settings (COM) objects and configuration data 662 741 * to the number of the machine's configured displays. 663 */ 664 int RecordingSettings::i_syncToMachineDisplays(uint32_t cMonitors) 742 * 743 * Note: This function ASSUMES that we always have configured VM displays 744 * as a consequtive sequence with no holes in between. 745 */ 746 int RecordingSettings::i_syncToMachineDisplays(uint32_t cDisplays) 665 747 { 666 748 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 667 749 668 LogFlowThisFunc(("cMonitors=%RU32\n", cMonitors));669 LogFlowThisFunc(("Data screen count = %zu, COM object count = %zu\n", m->bd->mapScreens.size(), m->mapScreenObj.size()));670 671 750 /* If counts match, take a shortcut. */ 672 if (c Monitors == m->mapScreenObj.size())751 if (cDisplays == m->mapScreenObj.size()) 673 752 return VINF_SUCCESS; 674 753 675 754 /* Create all new screen settings objects which are not there yet. */ 676 for (ULONG i = 0; i < c Monitors; i++)755 for (ULONG i = 0; i < cDisplays; i++) 677 756 { 678 757 if (m->mapScreenObj.find(i) == m->mapScreenObj.end()) 679 758 { 680 settings::RecordingScreenMap::const_iterator itScreen = m->bd->mapScreens.find(i); 681 if (itScreen == m->bd->mapScreens.end()) 682 { 683 settings::RecordingScreenSettings defaultScreenSettings; /* Apply default settings. */ 684 m->bd->mapScreens[i] = defaultScreenSettings; 685 } 686 687 int vrc2 = i_createScreenObj(m->mapScreenObj, i /* Screen ID */, m->bd->mapScreens[i]); 759 settings::RecordingScreenSettings defaultScreenSettings; /* Apply default settings. */ 760 761 int vrc2 = i_createScreenObj(m->mapScreenObj, i /* Screen ID */, defaultScreenSettings); 688 762 AssertRC(vrc2); 689 763 } … … 691 765 692 766 /* Remove all left over screen settings objects which are not needed anymore. */ 693 const ULONG cSettings = (ULONG)m->mapScreenObj.size(); 694 for (ULONG i = cMonitors; i < cSettings; i++) 695 { 696 m->bd->mapScreens.erase(i); 767 for (ULONG i = cDisplays; i < (ULONG)m->mapScreenObj.size(); i++) 768 { 697 769 int vrc2 = i_destroyScreenObj(m->mapScreenObj, i /* Screen ID */); 698 770 AssertRC(vrc2); 699 771 } 700 772 701 Assert(m->mapScreenObj.size() == cMonitors); 702 Assert(m->bd->mapScreens.size() == cMonitors); 773 Assert(m->mapScreenObj.size() == cDisplays); 703 774 704 775 LogFlowThisFuncLeave(); -
trunk/src/VBox/Main/src-server/SnapshotImpl.cpp
r95476 r95639 867 867 data.strStateFile.setNull(); 868 868 869 HRESULT rc = m->pMachine->i_saveHardware(data.hardware, &data.debugging, &data.autostart); 870 if (FAILED(rc)) return rc; 871 872 return S_OK; 869 return m->pMachine->i_saveHardware(data.hardware, &data.debugging, &data.autostart, data.recordingSettings); 873 870 } 874 871 … … 1164 1161 if (FAILED(rc)) return rc; 1165 1162 1163 unconst(mRecordingSettings).createObject(); 1164 rc = mRecordingSettings->initCopy(this, pMachine->mRecordingSettings); 1165 if (FAILED(rc)) return rc; 1166 1166 1167 unconst(mTrustedPlatformModule).createObject(); 1167 1168 rc = mTrustedPlatformModule->initCopy(this, pMachine->mTrustedPlatformModule); … … 1170 1171 unconst(mNvramStore).createObject(); 1171 1172 rc = mNvramStore->initCopy(this, pMachine->mNvramStore); 1172 if (FAILED(rc)) return rc;1173 1174 unconst(mRecordingSettings).createObject();1175 rc = mRecordingSettings->initCopy(this, pMachine->mRecordingSettings);1176 1173 if (FAILED(rc)) return rc; 1177 1174 … … 1247 1244 * @param pDbg debuging settings 1248 1245 * @param pAutostart autostart settings 1246 * @param recording recording settings 1249 1247 * @param aSnapshotId snapshot ID of this snapshot machine 1250 1248 * @param aStateFilePath file where the execution state is saved … … 1257 1255 const settings::Debugging *pDbg, 1258 1256 const settings::Autostart *pAutostart, 1257 const settings::RecordingSettings &recording, 1259 1258 IN_GUID aSnapshotId, 1260 1259 const Utf8Str &aStateFilePath) … … 1302 1301 mBIOSSettings->init(this); 1303 1302 1303 unconst(mRecordingSettings).createObject(); 1304 mRecordingSettings->init(this); 1305 1304 1306 unconst(mTrustedPlatformModule).createObject(); 1305 1307 mTrustedPlatformModule->init(this); … … 1308 1310 mNvramStore->init(this); 1309 1311 1310 unconst(mRecordingSettings).createObject();1311 mRecordingSettings->init(this);1312 1313 1312 unconst(mGraphicsAdapter).createObject(); 1314 1313 mGraphicsAdapter->init(this); … … 1346 1345 1347 1346 /* load hardware and storage settings */ 1348 HRESULT rc = i_loadHardware(NULL, &mSnapshotId, hardware, pDbg, pAutostart); 1349 1350 if (SUCCEEDED(rc)) 1347 HRESULT hrc = i_loadHardware(NULL, &mSnapshotId, hardware, pDbg, pAutostart, recording); 1348 if (SUCCEEDED(hrc)) 1351 1349 /* commit all changes made during the initialization */ 1352 1350 i_commit(); /// @todo r=dj why do we need a commit in init?!? this is very expensive … … 1355 1353 1356 1354 /* Confirm a successful initialization when it's the case */ 1357 if (SUCCEEDED( rc))1355 if (SUCCEEDED(hrc)) 1358 1356 autoInitSpan.setSucceeded(); 1359 1357 1360 1358 LogFlowThisFuncLeave(); 1361 return rc;1359 return hrc; 1362 1360 } 1363 1361 -
trunk/src/VBox/Main/xml/Settings.cpp
r95395 r95639 2779 2779 2780 2780 /** 2781 * Returns the default options string for screen recording settings. 2782 */ 2783 /* static */ 2784 const char *RecordingScreenSettings::getDefaultOptions(void) 2785 { 2786 /* Note: Needs to be kept in sync with FE/Qt's UIMachineSettingsDisplay::putToCache()! */ 2787 return "vc_enabled=true,ac_enabled=false,ac_profile=med"; 2788 } 2789 2790 /** 2781 2791 * Applies the default settings. 2782 2792 */ … … 2787 2797 */ 2788 2798 2789 fEnabled = false;2790 enmDest = RecordingDestination_File;2791 ulMaxTimeS = 0;2792 strOptions = "";2793 File.ulMaxSizeMB = 0;2794 File.strName = "";2795 Video.enmCodec = RecordingVideoCodec_VP8;2796 Video.ulWidth = 1024;2797 Video.ulHeight = 768;2798 Video.ulRate = 512;2799 Video.ulFPS = 25;2800 Audio.enmAudioCodec = RecordingAudioCodec_Opus;2801 Audio.cBits = 16;2802 Audio.cChannels = 2;2803 Audio.uHz = 22050;2799 fEnabled = false; 2800 enmDest = RecordingDestination_File; 2801 ulMaxTimeS = 0; 2802 strOptions = RecordingScreenSettings::getDefaultOptions(); 2803 File.ulMaxSizeMB = 0; 2804 File.strName = ""; 2805 Video.enmCodec = RecordingVideoCodec_VP8; 2806 Video.ulWidth = 1024; 2807 Video.ulHeight = 768; 2808 Video.ulRate = 512; 2809 Video.ulFPS = 25; 2810 Audio.enmAudioCodec = RecordingAudioCodec_Opus; 2811 Audio.cBits = 16; 2812 Audio.cChannels = 2; 2813 Audio.uHz = 22050; 2804 2814 2805 2815 featureMap[RecordingFeature_Video] = true; … … 2812 2822 bool RecordingScreenSettings::areDefaultSettings(void) const 2813 2823 { 2814 return fEnabled == false 2815 && enmDest == RecordingDestination_File 2816 && ulMaxTimeS == 0 2817 && strOptions == "" 2818 && File.ulMaxSizeMB == 0 2819 && File.strName == "" 2820 && Video.enmCodec == RecordingVideoCodec_VP8 2821 && Video.ulWidth == 1024 2822 && Video.ulHeight == 768 2823 && Video.ulRate == 512 2824 && Video.ulFPS == 25 2825 && Audio.enmAudioCodec == RecordingAudioCodec_Opus 2826 && Audio.cBits == 16 2827 && Audio.cChannels == 2 2828 && Audio.uHz == 22050; 2824 return fEnabled == false 2825 && enmDest == RecordingDestination_File 2826 && ulMaxTimeS == 0 2827 && strOptions == RecordingScreenSettings::getDefaultOptions() 2828 && File.ulMaxSizeMB == 0 2829 && File.strName == "" 2830 && Video.enmCodec == RecordingVideoCodec_VP8 2831 && Video.ulWidth == 1024 2832 && Video.ulHeight == 768 2833 && Video.ulRate == 512 2834 && Video.ulFPS == 25 2835 && Audio.enmAudioCodec == RecordingAudioCodec_Opus 2836 && Audio.cBits == 16 2837 && Audio.cChannels == 2 2838 && Audio.uHz == 22050 2839 && featureMap.find(RecordingFeature_Video)->second == true 2840 && featureMap.find(RecordingFeature_Audio)->second == false; 2829 2841 } 2830 2842 … … 2856 2868 && ulMaxTimeS == d.ulMaxTimeS 2857 2869 && strOptions == d.strOptions 2870 && File.strName == d.File.strName 2858 2871 && File.ulMaxSizeMB == d.File.ulMaxSizeMB 2859 2872 && Video.enmCodec == d.Video.enmCodec … … 2865 2878 && Audio.cBits == d.Audio.cBits 2866 2879 && Audio.cChannels == d.Audio.cChannels 2867 && Audio.uHz == d.Audio.uHz; 2880 && Audio.uHz == d.Audio.uHz 2881 && featureMap == d.featureMap; 2868 2882 } 2869 2883 … … 2871 2885 * Constructor. Needs to set sane defaults which stand the test of time. 2872 2886 */ 2873 Recording Settings::RecordingSettings()2887 RecordingCommonSettings::RecordingCommonSettings() 2874 2888 { 2875 2889 applyDefaults(); … … 2879 2893 * Applies the default settings. 2880 2894 */ 2881 void Recording Settings::applyDefaults(void)2895 void RecordingCommonSettings::applyDefaults(void) 2882 2896 { 2883 2897 fEnabled = false; 2884 2885 mapScreens.clear();2886 2887 try2888 {2889 /* Always add screen 0 to the default configuration. */2890 RecordingScreenSettings screenSettings; /* Apply default settings for screen 0. */2891 screenSettings.fEnabled = true; /* Enabled by default. */2892 mapScreens[0] = screenSettings;2893 }2894 catch (std::bad_alloc &)2895 {2896 AssertFailed();2897 }2898 2898 } 2899 2899 … … 2901 2901 * Check if all settings have default values. 2902 2902 */ 2903 bool RecordingSettings::areDefaultSettings() const 2904 { 2905 const bool fDefault = fEnabled == false 2906 && mapScreens.size() == 1; 2907 if (!fDefault) 2908 return false; 2909 2910 RecordingScreenMap::const_iterator itScreen = mapScreens.begin(); 2911 return itScreen->first == 0 2912 && itScreen->second.areDefaultSettings(); 2903 bool RecordingCommonSettings::areDefaultSettings(void) const 2904 { 2905 return fEnabled == false; 2913 2906 } 2914 2907 … … 2918 2911 * machine settings have really changed and thus need to be written out to disk. 2919 2912 */ 2920 bool Recording Settings::operator==(const RecordingSettings &d) const2913 bool RecordingCommonSettings::operator==(const RecordingCommonSettings &d) const 2921 2914 { 2922 2915 if (this == &d) 2923 2916 return true; 2924 2917 2925 if ( fEnabled != d.fEnabled 2926 || mapScreens.size() != d.mapScreens.size()) 2918 return fEnabled == d.fEnabled; 2919 } 2920 2921 /** 2922 * Constructor. Needs to set sane defaults which stand the test of time. 2923 */ 2924 RecordingSettings::RecordingSettings() 2925 { 2926 applyDefaults(); 2927 } 2928 2929 /** 2930 * Applies the default settings. 2931 */ 2932 void RecordingSettings::applyDefaults(void) 2933 { 2934 common.applyDefaults(); 2935 2936 mapScreens.clear(); 2937 2938 try 2939 { 2940 /* Always add screen 0 to the default configuration. */ 2941 RecordingScreenSettings screenSettings; 2942 mapScreens[0] = screenSettings; 2943 } 2944 catch (std::bad_alloc &) 2945 { 2946 AssertFailed(); 2947 } 2948 } 2949 2950 /** 2951 * Check if all settings have default values. 2952 */ 2953 bool RecordingSettings::areDefaultSettings(void) const 2954 { 2955 AssertReturn(mapScreens.size() >= 1, false); /* The first screen always must be present. */ 2956 2957 if (!common.areDefaultSettings()) 2927 2958 return false; 2928 2959 2929 RecordingScreenMap::const_iterator itScreen = mapScreens.begin(); 2930 uint32_t i = 0; 2960 RecordingScreenSettingsMap::const_iterator itScreen = mapScreens.begin(); 2931 2961 while (itScreen != mapScreens.end()) 2932 2962 { 2933 RecordingScreenMap::const_iterator itScreenThat = d.mapScreens.find(i); 2963 if (!itScreen->second.areDefaultSettings()) 2964 return false; 2965 ++itScreen; 2966 } 2967 2968 return true; 2969 } 2970 2971 /** 2972 * Comparison operator. This gets called from MachineConfigFile::operator==, 2973 * which in turn gets called from Machine::saveSettings to figure out whether 2974 * machine settings have really changed and thus need to be written out to disk. 2975 */ 2976 bool RecordingSettings::operator==(const RecordingSettings &that) const 2977 { 2978 if (this == &that) /* If pointers match, take a shortcut. */ 2979 return true; 2980 2981 if (common == that.common) 2982 { 2983 /* Too lazy for a != operator. */ 2984 } 2985 else 2986 return false; 2987 2988 if (mapScreens.size() != that.mapScreens.size()) 2989 return false; 2990 2991 RecordingScreenSettingsMap::const_iterator itScreen = mapScreens.begin(); 2992 RecordingScreenSettingsMap::const_iterator itScreenThat = that.mapScreens.begin(); 2993 while ( itScreen != mapScreens.end() 2994 && itScreenThat != that.mapScreens.end()) 2995 { 2934 2996 if (itScreen->second == itScreenThat->second) 2935 2997 { … … 2940 3002 2941 3003 ++itScreen; 2942 ++i ;3004 ++itScreenThat; 2943 3005 } 2944 3006 … … 3934 3996 && strStateFile == s.strStateFile 3935 3997 && hardware == s.hardware // deep compare 3998 && recordingSettings == s.recordingSettings // deep compare 3936 3999 && llChildSnapshots == s.llChildSnapshots // deep compare 3937 4000 && debugging == s.debugging … … 4114 4177 // skip mapExtraDataItems! there is no old state available as it's always forced 4115 4178 && llFirstSnapshot == c.llFirstSnapshot // this one's deep 4179 && recordingSettings == c.recordingSettings // this one's deep 4116 4180 && strKeyId == c.strKeyId 4117 4181 && strKeyStore == c.strKeyStore … … 4714 4778 * the IDE and SATA controllers used to be defined under \<Hardware\>. 4715 4779 * 4716 * @param elmHardware 4717 * @param hw 4780 * @param elmHardware Hardware node to read from. 4781 * @param hw Where to store the hardware settings. 4718 4782 */ 4719 4783 void MachineConfigFile::readHardware(const xml::ElementNode &elmHardware, … … 5078 5142 pelmHwChild->getAttributeValue("Accelerate3D", hw.graphicsAdapter.fAccelerate3D); // pre-v1.5 variant 5079 5143 pelmHwChild->getAttributeValue("accelerate2DVideo", hw.graphicsAdapter.fAccelerate2DVideo); 5080 }5081 else if (pelmHwChild->nameEquals("VideoCapture"))5082 {5083 pelmHwChild->getAttributeValue("enabled", hw.recordingSettings.fEnabled);5084 5085 /* Right now I don't want to bump the settings version, so just convert the enabled5086 * screens to the former uint64t_t bit array and vice versa. */5087 uint64_t u64VideoCaptureScreens;5088 pelmHwChild->getAttributeValue("screens", u64VideoCaptureScreens);5089 5090 /* At the moment we only support one capturing configuration, that is, all screens5091 * have the same configuration. So load/save to/from screen 0. */5092 Assert(hw.recordingSettings.mapScreens.size()); /* At least screen must be present. */5093 RecordingScreenSettings &screen0Settings = hw.recordingSettings.mapScreens[0];5094 5095 pelmHwChild->getAttributeValue("maxTime", screen0Settings.ulMaxTimeS);5096 pelmHwChild->getAttributeValue("options", screen0Settings.strOptions);5097 pelmHwChild->getAttributeValuePath("file", screen0Settings.File.strName);5098 pelmHwChild->getAttributeValue("maxSize", screen0Settings.File.ulMaxSizeMB);5099 pelmHwChild->getAttributeValue("horzRes", screen0Settings.Video.ulWidth);5100 pelmHwChild->getAttributeValue("vertRes", screen0Settings.Video.ulHeight);5101 pelmHwChild->getAttributeValue("rate", screen0Settings.Video.ulRate);5102 pelmHwChild->getAttributeValue("fps", screen0Settings.Video.ulFPS);5103 5104 for (unsigned i = 0; i < hw.graphicsAdapter.cMonitors; i++) /* Don't add more settings than we have monitors configured. */5105 {5106 /* Add screen i to config in any case. */5107 hw.recordingSettings.mapScreens[i] = screen0Settings;5108 5109 if (u64VideoCaptureScreens & RT_BIT_64(i)) /* Screen i enabled? */5110 hw.recordingSettings.mapScreens[i].fEnabled = true;5111 }5112 5144 } 5113 5145 else if (pelmHwChild->nameEquals("RemoteDisplay")) … … 5949 5981 5950 5982 /** 5983 * Called for reading the \<VideoCapture\> element under \<Machine|Hardware\>, 5984 * or \<Recording\> under \<Machine\>, 5985 */ 5986 void MachineConfigFile::readRecordingSettings(const xml::ElementNode &elmRecording, RecordingSettings &recording) 5987 { 5988 elmRecording.getAttributeValue("enabled", recording.common.fEnabled); 5989 5990 /* Note: Since settings 1.19 the recording settings have a dedicated XML branch "Recording" outside of "Hardware". */ 5991 if (m->sv >= SettingsVersion_v1_19 /* VBox >= 7.0 */) 5992 { 5993 uint32_t cScreens = 0; 5994 elmRecording.getAttributeValue("screens", cScreens); 5995 5996 xml::ElementNodesList plstScreens; 5997 elmRecording.getChildElements(plstScreens, "Screen"); 5998 5999 /* Sanity checks. */ 6000 if (cScreens != plstScreens.size()) 6001 throw ConfigFileError(this, &elmRecording, N_("Recording/@screens attribute does not match stored screen objects")); 6002 6003 for (xml::ElementNodesList::iterator itScreen = plstScreens.begin(); 6004 itScreen != plstScreens.end(); 6005 ++itScreen) 6006 { 6007 /* The screen's stored ID is the monitor ID and also the key for the map. */ 6008 uint32_t idxScreen; 6009 (*itScreen)->getAttributeValue("id", idxScreen); 6010 6011 RecordingScreenSettings &screenSettings = recording.mapScreens[idxScreen]; 6012 6013 (*itScreen)->getAttributeValue("enabled", screenSettings.fEnabled); 6014 (*itScreen)->getAttributeValue("maxTimeS", screenSettings.ulMaxTimeS); 6015 (*itScreen)->getAttributeValue("options", screenSettings.strOptions); 6016 (*itScreen)->getAttributeValue("dest", (uint32_t &)screenSettings.enmDest); 6017 if (screenSettings.enmDest == RecordingDestination_File) 6018 (*itScreen)->getAttributeValuePath("file", screenSettings.File.strName); 6019 else 6020 throw ConfigFileError(this, (*itScreen), 6021 N_("Not supported Recording/@dest attribute '%#x'"), screenSettings.enmDest); 6022 (*itScreen)->getAttributeValue("maxSizeMB", screenSettings.File.ulMaxSizeMB); 6023 (*itScreen)->getAttributeValue("horzRes", screenSettings.Video.ulWidth); 6024 (*itScreen)->getAttributeValue("vertRes", screenSettings.Video.ulHeight); 6025 (*itScreen)->getAttributeValue("rateKbps", screenSettings.Video.ulRate); 6026 (*itScreen)->getAttributeValue("fps", screenSettings.Video.ulFPS); 6027 } 6028 } 6029 else if ( m->sv >= SettingsVersion_v1_14 6030 && m->sv < SettingsVersion_v1_19 /* VBox < 7.0 */) 6031 { 6032 /* For settings < 1.19 (< VBox 7.0) we only support one recording configuration, that is, 6033 * all screens have the same configuration. So load/save to/from screen 0. */ 6034 RecordingScreenSettings &screen0 = recording.mapScreens[0]; 6035 6036 elmRecording.getAttributeValue("maxTime", screen0.ulMaxTimeS); 6037 elmRecording.getAttributeValue("options", screen0.strOptions); 6038 elmRecording.getAttributeValuePath("file", screen0.File.strName); 6039 elmRecording.getAttributeValue("maxSize", screen0.File.ulMaxSizeMB); 6040 elmRecording.getAttributeValue("horzRes", screen0.Video.ulWidth); 6041 elmRecording.getAttributeValue("vertRes", screen0.Video.ulHeight); 6042 elmRecording.getAttributeValue("rate", screen0.Video.ulRate); 6043 elmRecording.getAttributeValue("fps", screen0.Video.ulFPS); 6044 6045 /* Convert the enabled screens to the former uint64_t bit array and vice versa. */ 6046 uint64_t cScreens = 0; 6047 elmRecording.getAttributeValue("screens", cScreens); 6048 6049 /* Propagate the settings from screen 0 to all other screens (= monitors). */ 6050 for (unsigned i = 0; i < cScreens; i++) 6051 { 6052 /* Add screen i to config in any case. */ 6053 recording.mapScreens[i] = screen0; 6054 6055 if (cScreens & RT_BIT_64(i)) /* Screen i enabled? */ 6056 recording.mapScreens[i].fEnabled = true; 6057 } 6058 } 6059 } 6060 6061 /** 5951 6062 * Called for reading the \<Groups\> element under \<Machine\>. 5952 6063 */ … … 6064 6175 readDVDAndFloppies_pre1_9(*pelmHardware, pSnap->hardware.storage); 6065 6176 6066 const xml::ElementNode *pelmDebugging = elmSnapshot.findChildElement("Debugging"); 6177 const xml::ElementNode *pelmDebugging = elmSnapshot.findChildElement("Debugging"); /** @todo r=andy Shouldn't this be pElement instead of elmSnapshot? Re-visit this! */ 6067 6178 if (pelmDebugging) 6068 6179 readDebugging(*pelmDebugging, pSnap->debugging); 6069 const xml::ElementNode *pelmAutostart = elmSnapshot.findChildElement("Autostart"); 6180 const xml::ElementNode *pelmAutostart = elmSnapshot.findChildElement("Autostart"); /** @todo r=andy Ditto. */ 6070 6181 if (pelmAutostart) 6071 6182 readAutostart(*pelmAutostart, pSnap->autostart); 6183 if (m->sv < SettingsVersion_v1_19) 6184 { 6185 /* The recording settings were part of the Hardware branch, called "VideoCapture". */ 6186 const xml::ElementNode *pelmVideoCapture = pelmHardware->findChildElement("VideoCapture"); 6187 if (pelmVideoCapture) 6188 readRecordingSettings(*pelmVideoCapture, pSnap->recordingSettings); 6189 } 6190 else /* >= VBox 7.0 */ 6191 { 6192 const xml::ElementNode *pelmRecording = pElement->findChildElement("Recording"); 6193 if (pelmRecording) 6194 readRecordingSettings(*pelmRecording, pSnap->recordingSettings); 6195 } 6072 6196 // note: Groups exist only for Machine, not for Snapshot 6073 6197 … … 6257 6381 else if (pelmMachineChild->nameEquals("Autostart")) 6258 6382 readAutostart(*pelmMachineChild, autostart); 6383 else if (pelmMachineChild->nameEquals("Recording")) 6384 readRecordingSettings(*pelmMachineChild, recordingSettings); 6259 6385 else if (pelmMachineChild->nameEquals("Groups")) 6260 6386 readGroups(*pelmMachineChild, machineUserData.llGroups); … … 6683 6809 pelmDisplay->setAttribute("accelerate2DVideo", hw.graphicsAdapter.fAccelerate2DVideo); 6684 6810 } 6685 }6686 6687 if (m->sv >= SettingsVersion_v1_14 && !hw.recordingSettings.areDefaultSettings())6688 {6689 xml::ElementNode *pelmVideoCapture = pelmHardware->createChild("VideoCapture");6690 6691 if (hw.recordingSettings.fEnabled)6692 pelmVideoCapture->setAttribute("enabled", hw.recordingSettings.fEnabled);6693 6694 /* Right now I don't want to bump the settings version, so just convert the enabled6695 * screens to the former uint64t_t bit array and vice versa. */6696 uint64_t u64VideoCaptureScreens = 0;6697 RecordingScreenMap::const_iterator itScreen = hw.recordingSettings.mapScreens.begin();6698 while (itScreen != hw.recordingSettings.mapScreens.end())6699 {6700 if (itScreen->second.fEnabled)6701 u64VideoCaptureScreens |= RT_BIT_64(itScreen->first);6702 ++itScreen;6703 }6704 6705 if (u64VideoCaptureScreens)6706 pelmVideoCapture->setAttribute("screens", u64VideoCaptureScreens);6707 6708 /* At the moment we only support one capturing configuration, that is, all screens6709 * have the same configuration. So load/save to/from screen 0. */6710 Assert(hw.recordingSettings.mapScreens.size());6711 const RecordingScreenMap::const_iterator itScreen0Settings = hw.recordingSettings.mapScreens.find(0);6712 Assert(itScreen0Settings != hw.recordingSettings.mapScreens.end());6713 6714 if (itScreen0Settings->second.ulMaxTimeS)6715 pelmVideoCapture->setAttribute("maxTime", itScreen0Settings->second.ulMaxTimeS);6716 if (itScreen0Settings->second.strOptions.isNotEmpty())6717 pelmVideoCapture->setAttributePath("options", itScreen0Settings->second.strOptions);6718 6719 if (!itScreen0Settings->second.File.strName.isEmpty())6720 pelmVideoCapture->setAttributePath("file", itScreen0Settings->second.File.strName);6721 if (itScreen0Settings->second.File.ulMaxSizeMB)6722 pelmVideoCapture->setAttribute("maxSize", itScreen0Settings->second.File.ulMaxSizeMB);6723 6724 if ( itScreen0Settings->second.Video.ulWidth != 10246725 || itScreen0Settings->second.Video.ulHeight != 768)6726 {6727 pelmVideoCapture->setAttribute("horzRes", itScreen0Settings->second.Video.ulWidth);6728 pelmVideoCapture->setAttribute("vertRes", itScreen0Settings->second.Video.ulHeight);6729 }6730 if (itScreen0Settings->second.Video.ulRate != 512)6731 pelmVideoCapture->setAttribute("rate", itScreen0Settings->second.Video.ulRate);6732 if (itScreen0Settings->second.Video.ulFPS)6733 pelmVideoCapture->setAttribute("fps", itScreen0Settings->second.Video.ulFPS);6734 6811 } 6735 6812 … … 7919 7996 } 7920 7997 7998 void MachineConfigFile::buildRecordingXML(xml::ElementNode &elmParent, const RecordingSettings &recording) 7999 { 8000 /* Note: Since settings 1.19 the recording settings have a dedicated XML branch outside of Hardware. */ 8001 if (m->sv >= SettingsVersion_v1_19 /* VBox >= 7.0 */) 8002 { 8003 /* Note: elmParent is Machine or Snapshot. */ 8004 xml::ElementNode *pelmRecording = elmParent.createChild("Recording"); 8005 8006 if (recordingSettings.common.fEnabled) 8007 pelmRecording->setAttribute("enabled", recording.common.fEnabled); 8008 8009 /* Only serialize screens which have non-default settings. */ 8010 size_t cScreensToWrite = 0; 8011 8012 RecordingScreenSettingsMap::const_iterator itScreen = recording.mapScreens.begin(); 8013 while (itScreen != recording.mapScreens.end()) 8014 { 8015 if (!itScreen->second.areDefaultSettings()) 8016 cScreensToWrite++; 8017 ++itScreen; 8018 } 8019 8020 if (cScreensToWrite) 8021 pelmRecording->setAttribute("screens", cScreensToWrite); 8022 8023 itScreen = recording.mapScreens.begin(); 8024 while (itScreen != recording.mapScreens.end()) 8025 { 8026 if (!itScreen->second.areDefaultSettings()) /* Skip serializing screen settings which have default settings. */ 8027 { 8028 xml::ElementNode *pelmScreen = pelmRecording->createChild("Screen"); 8029 8030 pelmScreen->setAttribute("id", itScreen->first); /* The key equals the monitor ID. */ 8031 pelmScreen->setAttribute("enabled", itScreen->second.fEnabled); 8032 if (itScreen->second.ulMaxTimeS) 8033 pelmScreen->setAttribute("maxTimeS", itScreen->second.ulMaxTimeS); 8034 if (itScreen->second.strOptions.isNotEmpty()) 8035 pelmScreen->setAttributePath("options", itScreen->second.strOptions); 8036 pelmScreen->setAttribute("dest", itScreen->second.enmDest); 8037 if (!itScreen->second.File.strName.isEmpty()) 8038 pelmScreen->setAttributePath("file", itScreen->second.File.strName); 8039 if (itScreen->second.File.ulMaxSizeMB) 8040 pelmScreen->setAttribute("maxSizeMB", itScreen->second.File.ulMaxSizeMB); 8041 8042 if ( itScreen->second.Video.ulWidth != 1024 8043 || itScreen->second.Video.ulHeight != 768) 8044 { 8045 pelmScreen->setAttribute("horzRes", itScreen->second.Video.ulWidth); 8046 pelmScreen->setAttribute("vertRes", itScreen->second.Video.ulHeight); 8047 } 8048 if (itScreen->second.Video.ulRate != 512) 8049 pelmScreen->setAttribute("rateKbps", itScreen->second.Video.ulRate); 8050 if (itScreen->second.Video.ulFPS) 8051 pelmScreen->setAttribute("fps", itScreen->second.Video.ulFPS); 8052 } 8053 ++itScreen; 8054 } 8055 } 8056 else if ( m->sv >= SettingsVersion_v1_14 8057 && m->sv < SettingsVersion_v1_19 /* VBox < 7.0 */ 8058 && !recording.areDefaultSettings()) 8059 { 8060 /* Note: elmParent is Hardware or Snapshot. */ 8061 xml::ElementNode *pelmVideoCapture = elmParent.createChild("VideoCapture"); 8062 8063 if (recording.common.fEnabled) 8064 pelmVideoCapture->setAttribute("enabled", recording.common.fEnabled); 8065 8066 /* Convert the enabled screens to the former uint64_t bit array and vice versa. */ 8067 uint64_t u64VideoCaptureScreens = 0; 8068 RecordingScreenSettingsMap::const_iterator itScreen = recording.mapScreens.begin(); 8069 while (itScreen != recording.mapScreens.end()) 8070 { 8071 if (itScreen->second.fEnabled) 8072 u64VideoCaptureScreens |= RT_BIT_64(itScreen->first); 8073 ++itScreen; 8074 } 8075 8076 if (u64VideoCaptureScreens) 8077 pelmVideoCapture->setAttribute("screens", u64VideoCaptureScreens); 8078 8079 Assert(recording.mapScreens.size()); 8080 const RecordingScreenSettingsMap::const_iterator itScreen0Settings = recording.mapScreens.find(0); 8081 Assert(itScreen0Settings != recording.mapScreens.end()); 8082 8083 if (itScreen0Settings->second.ulMaxTimeS) 8084 pelmVideoCapture->setAttribute("maxTime", itScreen0Settings->second.ulMaxTimeS); 8085 if (itScreen0Settings->second.strOptions.isNotEmpty()) 8086 pelmVideoCapture->setAttributePath("options", itScreen0Settings->second.strOptions); 8087 8088 if (!itScreen0Settings->second.File.strName.isEmpty()) 8089 pelmVideoCapture->setAttributePath("file", itScreen0Settings->second.File.strName); 8090 if (itScreen0Settings->second.File.ulMaxSizeMB) 8091 pelmVideoCapture->setAttribute("maxSize", itScreen0Settings->second.File.ulMaxSizeMB); 8092 8093 if ( itScreen0Settings->second.Video.ulWidth != 1024 8094 || itScreen0Settings->second.Video.ulHeight != 768) 8095 { 8096 pelmVideoCapture->setAttribute("horzRes", itScreen0Settings->second.Video.ulWidth); 8097 pelmVideoCapture->setAttribute("vertRes", itScreen0Settings->second.Video.ulHeight); 8098 } 8099 if (itScreen0Settings->second.Video.ulRate != 512) 8100 pelmVideoCapture->setAttribute("rate", itScreen0Settings->second.Video.ulRate); 8101 if (itScreen0Settings->second.Video.ulFPS) 8102 pelmVideoCapture->setAttribute("fps", itScreen0Settings->second.Video.ulFPS); 8103 } 8104 } 8105 7921 8106 /** 7922 8107 * Creates a \<Groups\> node under elmParent and then writes out the XML … … 7991 8176 buildDebuggingXML(*pelmSnapshot, pSnap->debugging); 7992 8177 buildAutostartXML(*pelmSnapshot, pSnap->autostart); 8178 buildRecordingXML(*pelmSnapshot, pSnap->recordingSettings); 7993 8179 // note: Groups exist only for Machine, not for Snapshot 7994 8180 … … 8157 8343 buildDebuggingXML(elmMachine, debugging); 8158 8344 buildAutostartXML(elmMachine, autostart); 8345 buildRecordingXML(elmMachine, recordingSettings); 8159 8346 buildGroupsXML(elmMachine, machineUserData.llGroups); 8160 8347 } … … 8371 8558 || hardwareMachine.nvramSettings.strKeyId.isNotEmpty() 8372 8559 || hardwareMachine.nvramSettings.strKeyStore.isNotEmpty() 8560 || recordingSettings.areDefaultSettings() == false 8373 8561 || strLogKeyId.isNotEmpty() 8374 8562 || strLogKeyStore.isEmpty()) … … 8635 8823 || hardwareMachine.enmLongMode != Hardware::LongMode_Legacy 8636 8824 || machineUserData.ovIcon.size() > 0 8637 || hardwareMachine.recordingSettings.fEnabled)8825 || recordingSettings.common.fEnabled) 8638 8826 { 8639 8827 m->sv = SettingsVersion_v1_14;
Note:
See TracChangeset
for help on using the changeset viewer.