VirtualBox

Changeset 95639 in vbox for trunk/src/VBox/Main/xml


Ignore:
Timestamp:
Jul 14, 2022 8:30:45 AM (3 years ago)
Author:
vboxsync
Message:

Recording: Settings handling fixes / overhaul. This adds the ability to handle per-screen settings, which can be different from the first screen (screen 0). Also fixed a couple of bugs regarding snapshot handling and persistence (committing, rolling back, ++) in that area. FE/VBoxManage now can also list the per-screen settings. Added some further @todos. bugref:9286

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/xml/Settings.cpp

    r95395 r95639  
    27792779
    27802780/**
     2781 * Returns the default options string for screen recording settings.
     2782 */
     2783/* static */
     2784const 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/**
    27812791 * Applies the default settings.
    27822792 */
     
    27872797     */
    27882798
    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;
    28042814
    28052815    featureMap[RecordingFeature_Video] = true;
     
    28122822bool RecordingScreenSettings::areDefaultSettings(void) const
    28132823{
    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;
    28292841}
    28302842
     
    28562868           && ulMaxTimeS          == d.ulMaxTimeS
    28572869           && strOptions          == d.strOptions
     2870           && File.strName        == d.File.strName
    28582871           && File.ulMaxSizeMB    == d.File.ulMaxSizeMB
    28592872           && Video.enmCodec      == d.Video.enmCodec
     
    28652878           && Audio.cBits         == d.Audio.cBits
    28662879           && Audio.cChannels     == d.Audio.cChannels
    2867            && Audio.uHz           == d.Audio.uHz;
     2880           && Audio.uHz           == d.Audio.uHz
     2881           && featureMap          == d.featureMap;
    28682882}
    28692883
     
    28712885 * Constructor. Needs to set sane defaults which stand the test of time.
    28722886 */
    2873 RecordingSettings::RecordingSettings()
     2887RecordingCommonSettings::RecordingCommonSettings()
    28742888{
    28752889    applyDefaults();
     
    28792893 * Applies the default settings.
    28802894 */
    2881 void RecordingSettings::applyDefaults(void)
     2895void RecordingCommonSettings::applyDefaults(void)
    28822896{
    28832897    fEnabled = false;
    2884 
    2885     mapScreens.clear();
    2886 
    2887     try
    2888     {
    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     }
    28982898}
    28992899
     
    29012901 * Check if all settings have default values.
    29022902 */
    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();
     2903bool RecordingCommonSettings::areDefaultSettings(void) const
     2904{
     2905    return fEnabled == false;
    29132906}
    29142907
     
    29182911 * machine settings have really changed and thus need to be written out to disk.
    29192912 */
    2920 bool RecordingSettings::operator==(const RecordingSettings &d) const
     2913bool RecordingCommonSettings::operator==(const RecordingCommonSettings &d) const
    29212914{
    29222915    if (this == &d)
    29232916        return true;
    29242917
    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 */
     2924RecordingSettings::RecordingSettings()
     2925{
     2926    applyDefaults();
     2927}
     2928
     2929/**
     2930 * Applies the default settings.
     2931 */
     2932void 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 */
     2953bool RecordingSettings::areDefaultSettings(void) const
     2954{
     2955    AssertReturn(mapScreens.size() >= 1, false); /* The first screen always must be present. */
     2956
     2957    if (!common.areDefaultSettings())
    29272958        return false;
    29282959
    2929     RecordingScreenMap::const_iterator itScreen = mapScreens.begin();
    2930     uint32_t i = 0;
     2960    RecordingScreenSettingsMap::const_iterator itScreen = mapScreens.begin();
    29312961    while (itScreen != mapScreens.end())
    29322962    {
    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 */
     2976bool 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    {
    29342996        if (itScreen->second == itScreenThat->second)
    29352997        {
     
    29403002
    29413003        ++itScreen;
    2942         ++i;
     3004        ++itScreenThat;
    29433005    }
    29443006
     
    39343996            && strStateFile          == s.strStateFile
    39353997            && hardware              == s.hardware                  // deep compare
     3998            && recordingSettings     == s.recordingSettings         // deep compare
    39363999            && llChildSnapshots      == s.llChildSnapshots          // deep compare
    39374000            && debugging             == s.debugging
     
    41144177            // skip mapExtraDataItems! there is no old state available as it's always forced
    41154178            && llFirstSnapshot            == c.llFirstSnapshot     // this one's deep
     4179            && recordingSettings          == c.recordingSettings   // this one's deep
    41164180            && strKeyId                   == c.strKeyId
    41174181            && strKeyStore                == c.strKeyStore
     
    47144778 * the IDE and SATA controllers used to be defined under \<Hardware\>.
    47154779 *
    4716  * @param elmHardware
    4717  * @param hw
     4780 * @param elmHardware           Hardware node to read from.
     4781 * @param hw                    Where to store the hardware settings.
    47184782 */
    47194783void MachineConfigFile::readHardware(const xml::ElementNode &elmHardware,
     
    50785142                pelmHwChild->getAttributeValue("Accelerate3D", hw.graphicsAdapter.fAccelerate3D);   // pre-v1.5 variant
    50795143            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 enabled
    5086              * 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 screens
    5091              * 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             }
    51125144        }
    51135145        else if (pelmHwChild->nameEquals("RemoteDisplay"))
     
    59495981
    59505982/**
     5983 * Called for reading the \<VideoCapture\> element under \<Machine|Hardware\>,
     5984 * or \<Recording\> under \<Machine\>,
     5985 */
     5986void 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/**
    59516062 * Called for reading the \<Groups\> element under \<Machine\>.
    59526063 */
     
    60646175            readDVDAndFloppies_pre1_9(*pelmHardware, pSnap->hardware.storage);
    60656176
    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! */
    60676178        if (pelmDebugging)
    60686179            readDebugging(*pelmDebugging, pSnap->debugging);
    6069         const xml::ElementNode *pelmAutostart = elmSnapshot.findChildElement("Autostart");
     6180        const xml::ElementNode *pelmAutostart = elmSnapshot.findChildElement("Autostart"); /** @todo r=andy Ditto. */
    60706181        if (pelmAutostart)
    60716182            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        }
    60726196        // note: Groups exist only for Machine, not for Snapshot
    60736197
     
    62576381            else if (pelmMachineChild->nameEquals("Autostart"))
    62586382                readAutostart(*pelmMachineChild, autostart);
     6383            else if (pelmMachineChild->nameEquals("Recording"))
     6384                readRecordingSettings(*pelmMachineChild, recordingSettings);
    62596385            else if (pelmMachineChild->nameEquals("Groups"))
    62606386                readGroups(*pelmMachineChild, machineUserData.llGroups);
     
    66836809                pelmDisplay->setAttribute("accelerate2DVideo", hw.graphicsAdapter.fAccelerate2DVideo);
    66846810        }
    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 enabled
    6695          * 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 screens
    6709          * 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  != 1024
    6725             || 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);
    67346811    }
    67356812
     
    79197996}
    79207997
     7998void 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
    79218106/**
    79228107 * Creates a \<Groups\> node under elmParent and then writes out the XML
     
    79918176        buildDebuggingXML(*pelmSnapshot, pSnap->debugging);
    79928177        buildAutostartXML(*pelmSnapshot, pSnap->autostart);
     8178        buildRecordingXML(*pelmSnapshot, pSnap->recordingSettings);
    79938179        // note: Groups exist only for Machine, not for Snapshot
    79948180
     
    81578343    buildDebuggingXML(elmMachine, debugging);
    81588344    buildAutostartXML(elmMachine, autostart);
     8345    buildRecordingXML(elmMachine, recordingSettings);
    81598346    buildGroupsXML(elmMachine, machineUserData.llGroups);
    81608347}
     
    83718558            || hardwareMachine.nvramSettings.strKeyId.isNotEmpty()
    83728559            || hardwareMachine.nvramSettings.strKeyStore.isNotEmpty()
     8560            || recordingSettings.areDefaultSettings() == false
    83738561            || strLogKeyId.isNotEmpty()
    83748562            || strLogKeyStore.isEmpty())
     
    86358823            || hardwareMachine.enmLongMode != Hardware::LongMode_Legacy
    86368824            || machineUserData.ovIcon.size() > 0
    8637             || hardwareMachine.recordingSettings.fEnabled)
     8825            || recordingSettings.common.fEnabled)
    86388826        {
    86398827            m->sv = SettingsVersion_v1_14;
Note: See TracChangeset for help on using the changeset viewer.

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