VirtualBox

Changeset 75488 in vbox


Ignore:
Timestamp:
Nov 15, 2018 4:12:07 PM (6 years ago)
Author:
vboxsync
Message:

Recording/Main: Implemented better support for recording limits (also now configurable per screen).

Location:
trunk/src/VBox/Main
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r75459 r75488  
    2068520685  <interface
    2068620686    name="IInternalSessionControl" extends="$unknown"
    20687     uuid="DE773CFC-B679-4225-8EAE-938D294B73D2"
     20687    uuid="B1C3994E-F8CD-4D02-94D0-1AAF884751ED"
    2068820688    internal="yes"
    2068920689    wsmap="suppress"
     
    2098920989        Triggered when recording settings have changed.
    2099020990      </desc>
     20991      <param name="enable" type="boolean" dir="in">
     20992        <desc>TODO</desc>
     20993      </param>
    2099120994    </method>
    2099220995
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r75380 r75488  
    146146    int i_recordingEnable(BOOL fEnable, util::AutoWriteLock *pAutoLock);
    147147    int i_recordingGetSettings(settings::RecordingSettings &Settings);
    148     int i_recordingStart(void);
    149     int i_recordingStop(void);
     148    int i_recordingStart(util::AutoWriteLock *pAutoLock = NULL);
     149    int i_recordingStop(util::AutoWriteLock *pAutoLock = NULL);
    150150    AudioVideoRec *i_recordingGetAudioDrv(void) const { return Recording.mAudioRec; }
    151151    RecordingContext *i_recordingGetContext(void) const { return Recording.mpCtx; }
     
    179179    HRESULT i_onDnDModeChange(DnDMode_T aDnDMode);
    180180    HRESULT i_onVRDEServerChange(BOOL aRestart);
    181     HRESULT i_onRecordingChange();
     181    HRESULT i_onRecordingChange(BOOL fEnable);
    182182    HRESULT i_onUSBControllerChange();
    183183    HRESULT i_onSharedFolderChange(BOOL aGlobal);
     
    10421042
    10431043        /** The recording context. */
    1044         RecordingContext       *mpCtx;
     1044        RecordingContext     *mpCtx;
    10451045# ifdef VBOX_WITH_AUDIO_RECORDING
    10461046        /** Pointer to capturing audio backend. */
  • trunk/src/VBox/Main/include/MachineImpl.h

    r75455 r75488  
    524524    virtual HRESULT i_onStorageDeviceChange(IMediumAttachment * /* mediumAttachment */, BOOL /* remove */,
    525525                                            BOOL /* silent */) { return S_OK; }
    526     virtual HRESULT i_onRecordingChange() { return S_OK; }
     526    virtual HRESULT i_onRecordingChange(BOOL /* aEnable */) { return S_OK; }
    527527
    528528    HRESULT i_saveRegistryEntry(settings::MachineRegistryEntry &data);
     
    13271327    HRESULT i_onCPUChange(ULONG aCPU, BOOL aRemove);
    13281328    HRESULT i_onVRDEServerChange(BOOL aRestart);
    1329     HRESULT i_onRecordingChange();
     1329    HRESULT i_onRecordingChange(BOOL aEnable);
    13301330    HRESULT i_onUSBControllerChange();
    13311331    HRESULT i_onUSBDeviceAttach(IUSBDevice *aDevice,
  • trunk/src/VBox/Main/include/Recording.h

    r75441 r75488  
    3939public:
    4040
    41     RecordingContext(Console *pConsole);
    42 
    4341    RecordingContext(Console *pConsole, const settings::RecordingSettings &a_Settings);
    4442
     
    6462public:
    6563
    66     bool IsFeatureEnabled(RecordingFeature_T enmFeature) const;
     64    bool IsFeatureEnabled(RecordingFeature_T enmFeature);
    6765    bool IsReady(void) const;
    68     bool IsReady(uint32_t uScreen, uint64_t uTimeStampMs) const;
    69     bool IsStarted(void) const;
    70     bool IsLimitReached(uint32_t uScreen, uint64_t tsNowMs) const;
     66    bool IsReady(uint32_t uScreen, uint64_t uTimeStampMs);
     67    bool IsStarted(void);
     68    bool IsLimitReached(void);
     69    bool IsLimitReached(uint32_t uScreen, uint64_t uTimeStampMs);
     70
     71    DECLCALLBACK(int) OnLimitReached(uint32_t uScreen, int rc);
    7172
    7273protected:
     
    7980
    8081    RecordingStream *getStreamInternal(unsigned uScreen) const;
     82
     83    int lock(void);
     84    int unlock(void);
    8185
    8286    static DECLCALLBACK(int) threadMain(RTTHREAD hThreadSelf, void *pvUser);
     
    102106
    103107    /** Pointer to the console object. */
    104     Console                  *pConsole;
     108    Console                     *pConsole;
    105109    /** Used recording configuration. */
    106110    settings::RecordingSettings  Settings;
    107111    /** The current state. */
    108     RECORDINGSTS              enmState;
     112    RECORDINGSTS                 enmState;
    109113    /** Critical section to serialize access. */
    110     RTCRITSECT                CritSect;
     114    RTCRITSECT                   CritSect;
    111115    /** Semaphore to signal the encoding worker thread. */
    112     RTSEMEVENT                WaitEvent;
     116    RTSEMEVENT                   WaitEvent;
    113117    /** Shutdown indicator. */
    114     bool                      fShutdown;
     118    bool                         fShutdown;
    115119    /** Worker thread. */
    116     RTTHREAD                  Thread;
     120    RTTHREAD                     Thread;
    117121    /** Vector of current recording streams.
    118122     *  Per VM screen (display) one recording stream is being used. */
    119     RecordingStreams          vecStreams;
     123    RecordingStreams             vecStreams;
    120124    /** Number of streams in vecStreams which currently are enabled for recording. */
    121     uint16_t                  cStreamsEnabled;
     125    uint16_t                     cStreamsEnabled;
    122126    /** Timestamp (in ms) of when recording has been started. */
    123     uint64_t                  tsStartMs;
     127    uint64_t                     tsStartMs;
    124128    /** Block map of common blocks which need to get multiplexed
    125129     *  to all recording streams. This common block maps should help
     
    129133     *  For now this only affects audio, e.g. all recording streams
    130134     *  need to have the same audio data at a specific point in time. */
    131     RecordingBlockMap         mapBlocksCommon;
     135    RecordingBlockMap            mapBlocksCommon;
    132136};
    133137#endif /* !____H_RECORDING */
  • trunk/src/VBox/Main/include/RecordingInternals.h

    r75441 r75488  
    4848            /** Pointer to the codec's internal YUV buffer. */
    4949            uint8_t            *pu8YuvBuf;
     50            /** The encoder's deadline (in ms).
     51             *  The more time the encoder is allowed to spend encoding, the better the encoded
     52             *  result, in exchange for higher CPU usage and time spent encoding. */
    5053            unsigned int        uEncoderDeadline;
    5154        } VPX;
  • trunk/src/VBox/Main/include/RecordingStream.h

    r75441 r75488  
    126126    const settings::RecordingScreenSettings &GetConfig(void) const;
    127127    uint16_t GetID(void) const { return this->uScreenID; };
    128     bool IsLimitReached(uint64_t tsNowMs) const;
     128    bool IsLimitReached(uint64_t uTimeStampMs) const;
    129129    bool IsReady(void) const;
    130130
     
    141141
    142142    int initAudio(void);
     143
     144    bool isLimitReachedInternal(uint64_t uTimeStampMs) const;
     145    int iterateInternal(uint64_t uTimeStampMs);
    143146
    144147#ifdef VBOX_WITH_LIBVPX
  • trunk/src/VBox/Main/include/SessionImpl.h

    r75361 r75488  
    102102    HRESULT onCPUExecutionCapChange(ULONG aExecutionCap);
    103103    HRESULT onVRDEServerChange(BOOL aRestart);
    104     HRESULT onRecordingChange();
     104    HRESULT onRecordingChange(BOOL aEnable);
    105105    HRESULT onUSBControllerChange();
    106106    HRESULT onSharedFolderChange(BOOL aGlobal);
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r75419 r75488  
    56415641            LogRel(("Recording: %s\n", fEnable ? "Enabling" : "Disabling"));
    56425642
    5643             pDisplay->i_recordingInvalidate();
    5644 
    56455643            if (fEnable)
    56465644            {
     
    56615659                        && Recording.mpCtx->IsReady()) /* Any video recording (audio and/or video) feature enabled? */
    56625660                    {
    5663                         vrc = i_recordingStart();
     5661                        vrc = pDisplay->i_recordingInvalidate();
     5662                        if (RT_SUCCESS(vrc))
     5663                            vrc = i_recordingStart(pAutoLock);
    56645664                    }
    56655665                }
     5666
     5667                if (RT_FAILURE(vrc))
     5668                    LogRel(("Recording: Failed to enable with %Rrc\n", vrc));
    56665669            }
    56675670            else
    56685671            {
    5669                 i_recordingStop();
     5672                i_recordingStop(pAutoLock);
    56705673# ifdef VBOX_WITH_AUDIO_RECORDING
    5671                 Recording.mAudioRec->doDetachDriverViaEmt(mpUVM, pAutoLock);
     5674                if (Recording.mAudioRec)
     5675                    Recording.mAudioRec->doDetachDriverViaEmt(mpUVM, pAutoLock);
    56725676# endif
    56735677                i_recordingDestroy();
     
    56855689#endif /* VBOX_WITH_RECORDING */
    56865690
    5687 HRESULT Console::i_onRecordingChange()
     5691/**
     5692 * Called by IInternalSessionControl::OnRecordingChange().
     5693 */
     5694HRESULT Console::i_onRecordingChange(BOOL fEnabled)
    56885695{
    56895696    AutoCaller autoCaller(this);
     
    56985705    if (ptrVM.isOk())
    56995706    {
    5700         ComPtr<IRecordingSettings> recordingSettings;
    5701         rc = mMachine->COMGETTER(RecordingSettings)(recordingSettings.asOutParam());
    5702         AssertComRCReturnRC(rc);
    5703 
    5704         BOOL fEnabled;
    5705         rc = recordingSettings->COMGETTER(Enabled)(&fEnabled);
    5706         AssertComRCReturnRC(rc);
     5707        LogFlowThisFunc(("fEnabled=%RTbool\n", RT_BOOL(fEnabled)));
    57075708
    57085709        int vrc = i_recordingEnable(fEnabled, &alock);
     
    69746975    AssertReturn(Recording.mpCtx == NULL, VERR_WRONG_ORDER);
    69756976
    6976     int rc = VINF_SUCCESS;
    6977 
    6978     try
    6979     {
    6980         Recording.mpCtx = new RecordingContext(this);
    6981     }
    6982     catch (std::bad_alloc &)
    6983     {
    6984         return VERR_NO_MEMORY;
    6985     }
    6986     catch (int &rc2)
    6987     {
    6988         return rc2;
    6989     }
    6990 
    6991     settings::RecordingSettings Settings;
    6992     rc = i_recordingGetSettings(Settings);
     6977    settings::RecordingSettings recordingSettings;
     6978    int rc = i_recordingGetSettings(recordingSettings);
    69936979    if (RT_SUCCESS(rc))
    69946980    {
    6995         AssertPtr(Recording.mpCtx);
    6996         rc = Recording.mpCtx->Create(Settings);
     6981        try
     6982        {
     6983            Recording.mpCtx = new RecordingContext(this /* pConsole */, recordingSettings);
     6984        }
     6985        catch (std::bad_alloc &)
     6986        {
     6987            return VERR_NO_MEMORY;
     6988        }
     6989        catch (int &rc2)
     6990        {
     6991            return rc2;
     6992        }
    69976993    }
    69986994
     
    70207016 * @returns IPRT status code.
    70217017 */
    7022 int Console::i_recordingStart(void)
    7023 {
     7018int Console::i_recordingStart(util::AutoWriteLock *pAutoLock /* = NULL */)
     7019{
     7020    RT_NOREF(pAutoLock);
    70247021    AssertPtrReturn(Recording.mpCtx, VERR_WRONG_ORDER);
    70257022
     
    70437040 * Stops recording. Does nothing if recording is not active.
    70447041 */
    7045 int Console::i_recordingStop(void)
     7042int Console::i_recordingStop(util::AutoWriteLock *pAutoLock /* = NULL */)
    70467043{
    70477044    if (   !Recording.mpCtx
     
    70587055            mDisplay->i_recordingScreenChanged(uScreen);
    70597056
     7057        if (pAutoLock)
     7058            pAutoLock->release();
     7059
    70607060        ComPtr<IRecordingSettings> pRecordSettings;
    70617061        HRESULT hrc = mMachine->COMGETTER(RecordingSettings)(pRecordSettings.asOutParam());
    70627062        ComAssertComRC(hrc);
    7063         hrc = pRecordSettings->COMSETTER(Enabled)(false);
     7063        hrc = pRecordSettings->COMSETTER(Enabled)(FALSE);
    70647064        ComAssertComRC(hrc);
     7065
     7066        if (pAutoLock)
     7067            pAutoLock->acquire();
    70657068    }
    70667069
  • trunk/src/VBox/Main/src-client/DisplayImpl.cpp

    r75448 r75488  
    34323432# endif /* VBOX_WITH_HGCM && VBOX_WITH_CROGL */
    34333433
     3434            /* If the recording context has reached the configured recording
     3435             * limit, disable recording. */
     3436            if (pCtx->IsLimitReached())
     3437            {
     3438                pDisplay->mParent->i_onRecordingChange(FALSE /* Disable */);
     3439                break;
     3440            }
     3441
    34343442            uint64_t tsNowMs = RTTimeProgramMilliTS();
    34353443            for (uScreenId = 0; uScreenId < pDisplay->mcMonitors; uScreenId++)
     
    34373445                if (!pDisplay->maRecordingEnabled[uScreenId])
    34383446                    continue;
    3439 
    3440                 if (pCtx->IsLimitReached(uScreenId, tsNowMs))
    3441                 {
    3442                     pDisplay->mParent->i_recordingStop();
    3443                     break;
    3444                 }
    34453447
    34463448                DISPLAYFBINFO *pFBInfo = &pDisplay->maFramebuffers[uScreenId];
  • trunk/src/VBox/Main/src-client/Recording.cpp

    r75441 r75488  
    9090
    9191
    92 RecordingContext::RecordingContext(Console *a_pConsole)
    93     : pConsole(a_pConsole)
    94     , enmState(RECORDINGSTS_UNINITIALIZED)
    95     , cStreamsEnabled(0) { }
    96 
    9792RecordingContext::RecordingContext(Console *a_pConsole, const settings::RecordingSettings &a_Settings)
    9893    : pConsole(a_pConsole)
     
    373368}
    374369
     370int RecordingContext::lock(void)
     371{
     372    int rc = RTCritSectEnter(&this->CritSect);
     373    AssertRC(rc);
     374    return rc;
     375}
     376
     377int RecordingContext::unlock(void)
     378{
     379    int rc = RTCritSectLeave(&this->CritSect);
     380    AssertRC(rc);
     381    return rc;
     382}
     383
    375384/**
    376385 * Retrieves a specific recording stream of a recording context.
     
    440449 * @param   enmFeature          Recording feature to check for.
    441450 */
    442 bool RecordingContext::IsFeatureEnabled(RecordingFeature_T enmFeature) const
    443 {
     451bool RecordingContext::IsFeatureEnabled(RecordingFeature_T enmFeature)
     452{
     453    lock();
     454
    444455    RecordingStreams::const_iterator itStream = this->vecStreams.begin();
    445456    while (itStream != this->vecStreams.end())
    446457    {
    447458        if ((*itStream)->GetConfig().isFeatureEnabled(enmFeature))
     459        {
     460            unlock();
    448461            return true;
     462        }
    449463        ++itStream;
    450464    }
     465
     466    unlock();
    451467
    452468    return false;
     
    470486 * @param   uTimeStampMs        Current time stamp (in ms). Currently not being used.
    471487 */
    472 bool RecordingContext::IsReady(uint32_t uScreen, uint64_t uTimeStampMs) const
     488bool RecordingContext::IsReady(uint32_t uScreen, uint64_t uTimeStampMs)
    473489{
    474490    RT_NOREF(uTimeStampMs);
    475491
     492    lock();
     493
     494    bool fIsReady = false;
     495
    476496    if (this->enmState != RECORDINGSTS_STARTED)
    477         return false;
    478 
    479     bool fIsReady = false;
    480 
    481     const RecordingStream *pStream = GetStream(uScreen);
    482     if (pStream)
    483         fIsReady = pStream->IsReady();
    484 
    485     /* Note: Do not check for other constraints like the video FPS rate here,
    486      *       as this check then also would affect other (non-FPS related) stuff
    487      *       like audio data. */
     497    {
     498        const RecordingStream *pStream = GetStream(uScreen);
     499        if (pStream)
     500            fIsReady = pStream->IsReady();
     501
     502        /* Note: Do not check for other constraints like the video FPS rate here,
     503         *       as this check then also would affect other (non-FPS related) stuff
     504         *       like audio data. */
     505    }
     506
     507    unlock();
    488508
    489509    return fIsReady;
     
    495515 * @returns true if active, false if not.
    496516 */
    497 bool RecordingContext::IsStarted(void) const
    498 {
    499     return (this->enmState == RECORDINGSTS_STARTED);
     517bool RecordingContext::IsStarted(void)
     518{
     519    lock();
     520
     521    const bool fIsStarted = this->enmState == RECORDINGSTS_STARTED;
     522
     523    unlock();
     524
     525    return fIsStarted;
     526}
     527
     528/**
     529 * Checks if a specified limit for recording has been reached.
     530 *
     531 * @returns true if any limit has been reached.
     532 */
     533bool RecordingContext::IsLimitReached(void)
     534{
     535    lock();
     536
     537    LogFlowThisFunc(("cStreamsEnabled=%RU16\n", this->cStreamsEnabled));
     538
     539    const bool fLimitReached = this->cStreamsEnabled == 0;
     540
     541    unlock();
     542
     543    return fLimitReached;
    500544}
    501545
     
    505549 * @returns true if any limit has been reached.
    506550 * @param   uScreen             Screen ID.
    507  * @param   tsNowMs             Current time stamp (in ms).
    508  */
    509 bool RecordingContext::IsLimitReached(uint32_t uScreen, uint64_t tsNowMs) const
    510 {
    511     const RecordingStream *pStream = GetStream(uScreen);
     551 * @param   uTimeStampMs        Timestamp (in ms) to check for.
     552 */
     553bool RecordingContext::IsLimitReached(uint32_t uScreen, uint64_t uTimeStampMs)
     554{
     555    lock();
     556
     557    bool fLimitReached = false;
     558
     559    const RecordingStream *pStream = getStreamInternal(uScreen);
    512560    if (   !pStream
    513         || pStream->IsLimitReached(tsNowMs))
    514     {
    515         return true;
    516     }
    517 
    518     return false;
     561        || pStream->IsLimitReached(uTimeStampMs))
     562    {
     563        fLimitReached = true;
     564    }
     565
     566    unlock();
     567
     568    return fLimitReached;
     569}
     570
     571DECLCALLBACK(int) RecordingContext::OnLimitReached(uint32_t uScreen, int rc)
     572{
     573    RT_NOREF(uScreen);
     574    LogFlowThisFunc(("Stream %RU32 has reached its limit (%Rrc)\n", uScreen, rc));
     575
     576    lock();
     577
     578    Assert(this->cStreamsEnabled);
     579    this->cStreamsEnabled--;
     580
     581    LogFlowThisFunc(("cStreamsEnabled=%RU16\n", cStreamsEnabled));
     582
     583    unlock();
     584
     585    return VINF_SUCCESS;
    519586}
    520587
     
    629696        AssertRC(rc);
    630697
     698        AssertFailed();
    631699        return VERR_NOT_FOUND;
    632700    }
     
    638706
    639707    if (   RT_SUCCESS(rc)
    640         && rc != VINF_TRY_AGAIN) /* Only signal the thread if operation was successful. */
     708        && rc != VINF_RECORDING_THROTTLED) /* Only signal the thread if operation was successful. */
    641709    {
    642710        threadNotify();
  • trunk/src/VBox/Main/src-client/RecordingStream.cpp

    r75454 r75488  
    263263
    264264/**
    265  * Checks if a specified limit for a recording stream has been reached.
     265 * Checks if a specified limit for a recording stream has been reached, internal version.
    266266 *
    267267 * @returns true if any limit has been reached.
    268  * @param   tsNowMs             Current time stamp (in ms).
    269  */
    270 bool RecordingStream::IsLimitReached(uint64_t tsNowMs) const
    271 {
    272     if (!IsReady())
    273         return true;
     268 * @param   uTimeStampMs        Timestamp (in ms) to check for.
     269 */
     270bool RecordingStream::isLimitReachedInternal(uint64_t uTimeStampMs) const
     271{
     272    LogFlowThisFunc(("uTimeStampMs=%RU64, ulMaxTimeS=%RU32, tsStartMs=%RU64\n",
     273                     uTimeStampMs, this->ScreenSettings.ulMaxTimeS, this->tsStartMs));
    274274
    275275    if (   this->ScreenSettings.ulMaxTimeS
    276         && tsNowMs >= this->tsStartMs + (this->ScreenSettings.ulMaxTimeS * RT_MS_1SEC))
     276        && uTimeStampMs >= this->tsStartMs + (this->ScreenSettings.ulMaxTimeS * RT_MS_1SEC))
    277277    {
    278278        LogRel(("Recording: Time limit for stream #%RU16 has been reached (%RU32s)\n",
     
    304304
    305305    return false;
     306}
     307
     308/**
     309 * Internal iteration main loop.
     310 * Does housekeeping and recording context notification.
     311 *
     312 * @returns IPRT status code.
     313 * @param   uTimeStampMs        Current timestamp (in ms).
     314 */
     315int RecordingStream::iterateInternal(uint64_t uTimeStampMs)
     316{
     317    if (!this->fEnabled)
     318        return VINF_SUCCESS;
     319
     320    int rc;
     321
     322    if (isLimitReachedInternal(uTimeStampMs))
     323    {
     324        rc = VINF_RECORDING_LIMIT_REACHED;
     325    }
     326    else
     327        rc = VINF_SUCCESS;
     328
     329    AssertPtr(this->pCtx);
     330
     331    switch (rc)
     332    {
     333        case VINF_RECORDING_LIMIT_REACHED:
     334        {
     335            this->fEnabled = false;
     336
     337            int rc2 = this->pCtx->OnLimitReached(this->uScreenID, VINF_SUCCESS /* rc */);
     338            AssertRC(rc2);
     339            break;
     340        }
     341
     342        default:
     343            break;
     344    }
     345
     346    LogFlowFuncLeaveRC(rc);
     347    return rc;
     348}
     349
     350/**
     351 * Checks if a specified limit for a recording stream has been reached.
     352 *
     353 * @returns true if any limit has been reached.
     354 * @param   uTimeStampMs        Timestamp (in ms) to check for.
     355 */
     356bool RecordingStream::IsLimitReached(uint64_t uTimeStampMs) const
     357{
     358    if (!IsReady())
     359        return true;
     360
     361    return isLimitReachedInternal(uTimeStampMs);
    306362}
    307363
     
    449505 * Sends a raw (e.g. not yet encoded) video frame to the recording stream.
    450506 *
    451  * @returns IPRT status code.
     507 * @returns IPRT status code. Will return VINF_RECORDING_LIMIT_REACHED if the stream's recording
     508 *          limit has been reached or VINF_RECORDING_THROTTLED if the frame is too early for the current
     509 *          FPS setting.
    452510 * @param   x                   Upper left (X) coordinate where the video frame starts.
    453511 * @param   y                   Upper left (Y) coordinate where the video frame starts.
     
    465523    lock();
    466524
     525    LogFlowFunc(("uTimeStampMs=%RU64\n", uTimeStampMs));
     526
    467527    PRECORDINGVIDEOFRAME pFrame = NULL;
    468528
    469     int rc = VINF_SUCCESS;
     529    int rc = iterateInternal(uTimeStampMs);
     530    if (rc != VINF_SUCCESS) /* Can return VINF_RECORDING_LIMIT_REACHED. */
     531    {
     532        unlock();
     533        return rc;
     534    }
    470535
    471536    do
    472537    {
    473         if (!this->fEnabled)
    474         {
    475             rc = VINF_TRY_AGAIN; /* Not (yet) enabled. */
    476             break;
    477         }
    478 
    479538        if (uTimeStampMs < this->Video.uLastTimeStampMs + this->Video.uDelayMs)
    480539        {
    481             rc = VINF_TRY_AGAIN; /* Respect maximum frames per second. */
     540            rc = VINF_RECORDING_THROTTLED; /* Respect maximum frames per second. */
    482541            break;
    483542        }
     
    710769        return rc;
    711770
    712     const settings::RecordingScreenSettings *pSettings = &this->ScreenSettings;
     771    settings::RecordingScreenSettings *pSettings = &this->ScreenSettings;
    713772
    714773    rc = RTCritSectInit(&this->CritSect);
     
    823882        this->enmState  = RECORDINGSTREAMSTATE_INITIALIZED;
    824883        this->fEnabled  = true;
    825         this->tsStartMs = RTTimeMilliTS();
     884        this->tsStartMs = RTTimeProgramMilliTS();
    826885    }
    827886    else
     
    846905    int rc = VINF_SUCCESS;
    847906
    848     if (this->fEnabled)
    849     {
    850         switch (this->ScreenSettings.enmDest)
    851         {
    852             case RecordingDestination_File:
    853             {
    854                 if (this->File.pWEBM)
    855                     rc = this->File.pWEBM->Close();
    856                 break;
    857             }
    858 
    859             default:
    860                 AssertFailed(); /* Should never happen. */
    861                 break;
    862         }
    863 
    864         this->Blocks.Clear();
    865 
    866         LogRel(("Recording: Recording screen #%u stopped\n", this->uScreenID));
    867     }
     907    switch (this->ScreenSettings.enmDest)
     908    {
     909        case RecordingDestination_File:
     910        {
     911            if (this->File.pWEBM)
     912                rc = this->File.pWEBM->Close();
     913            break;
     914        }
     915
     916        default:
     917            AssertFailed(); /* Should never happen. */
     918            break;
     919    }
     920
     921    this->Blocks.Clear();
     922
     923    LogRel(("Recording: Recording screen #%u stopped\n", this->uScreenID));
    868924
    869925    if (RT_FAILURE(rc))
  • trunk/src/VBox/Main/src-client/SessionImpl.cpp

    r75361 r75488  
    725725}
    726726
    727 HRESULT Session::onRecordingChange()
    728 {
    729     LogFlowThisFunc(("\n"));
    730 
    731     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    732     AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
    733     AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
    734 #ifndef VBOX_COM_INPROC_API_CLIENT
    735     AssertReturn(mConsole, VBOX_E_INVALID_OBJECT_STATE);
    736 
    737     return mConsole->i_onRecordingChange();
     727HRESULT Session::onRecordingChange(BOOL aEnable)
     728{
     729    LogFlowThisFunc(("\n"));
     730
     731    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     732    AssertReturn(mState == SessionState_Locked, VBOX_E_INVALID_VM_STATE);
     733    AssertReturn(mType == SessionType_WriteLock, VBOX_E_INVALID_OBJECT_STATE);
     734#ifndef VBOX_COM_INPROC_API_CLIENT
     735    AssertReturn(mConsole, VBOX_E_INVALID_OBJECT_STATE);
     736
     737    return mConsole->i_onRecordingChange(aEnable);
    738738#else
    739739    return S_OK;
  • trunk/src/VBox/Main/src-server/MachineImpl.cpp

    r75455 r75488  
    1410214102 * @note Locks this object for reading.
    1410314103 */
    14104 HRESULT SessionMachine::i_onRecordingChange()
     14104HRESULT SessionMachine::i_onRecordingChange(BOOL aEnable)
    1410514105{
    1410614106    LogFlowThisFunc(("\n"));
     
    1412014120        return S_OK;
    1412114121
    14122     return directControl->OnRecordingChange();
     14122    return directControl->OnRecordingChange(aEnable);
    1412314123}
    1412414124
  • trunk/src/VBox/Main/src-server/RecordingSettingsImpl.cpp

    r75455 r75488  
    4646    ComObjPtr<RecordingSettings> pPeer;
    4747    RecordScreenSettingsMap      mapScreenObj;
    48     bool                         fHasMachineLock;
    4948
    5049    // use the XML settings structure in the members for simplicity
     
    8786
    8887    m->bd.allocate();
    89     m->fHasMachineLock = false;
    9088
    9189    autoInitSpan.setSucceeded();
     
    123121    m->bd.share(that->m->bd);
    124122    m->mapScreenObj = that->m->mapScreenObj;
    125     m->fHasMachineLock = false;
    126123
    127124    autoInitSpan.setSucceeded();
     
    156153    m->bd.attachCopy(that->m->bd);
    157154    m->mapScreenObj = that->m->mapScreenObj;
    158     m->fHasMachineLock = false;
    159155
    160156    autoInitSpan.setSucceeded();
     
    219215
    220216        alock.release();
    221         rc = m->pMachine->i_onRecordingChange();
     217        rc = m->pMachine->i_onRecordingChange(enable);
    222218        if (FAILED(rc))
    223219        {
     
    236232            m->pMachine->i_setModified(Machine::IsModified_Recording);
    237233
    238             /* We need to indicate here that we just took the machine lock, as Machine::i_saveSettings() will
    239              * call i_commit(), which in turn also wants to lock the machine for writing. */
    240             m->fHasMachineLock = true;
    241 
    242234            /** Save settings if online - @todo why is this required? -- @bugref{6818} */
    243235            if (Global::IsOnline(m->pMachine->i_getMachineState()))
    244236                rc = m->pMachine->i_saveSettings(NULL);
    245 
    246             m->fHasMachineLock = false;
    247237        }
    248238    }
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