Changeset 75488 in vbox for trunk/src/VBox/Main/src-client
- Timestamp:
- Nov 15, 2018 4:12:07 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 126645
- Location:
- trunk/src/VBox/Main/src-client
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
r75419 r75488 5641 5641 LogRel(("Recording: %s\n", fEnable ? "Enabling" : "Disabling")); 5642 5642 5643 pDisplay->i_recordingInvalidate();5644 5645 5643 if (fEnable) 5646 5644 { … … 5661 5659 && Recording.mpCtx->IsReady()) /* Any video recording (audio and/or video) feature enabled? */ 5662 5660 { 5663 vrc = i_recordingStart(); 5661 vrc = pDisplay->i_recordingInvalidate(); 5662 if (RT_SUCCESS(vrc)) 5663 vrc = i_recordingStart(pAutoLock); 5664 5664 } 5665 5665 } 5666 5667 if (RT_FAILURE(vrc)) 5668 LogRel(("Recording: Failed to enable with %Rrc\n", vrc)); 5666 5669 } 5667 5670 else 5668 5671 { 5669 i_recordingStop( );5672 i_recordingStop(pAutoLock); 5670 5673 # ifdef VBOX_WITH_AUDIO_RECORDING 5671 Recording.mAudioRec->doDetachDriverViaEmt(mpUVM, pAutoLock); 5674 if (Recording.mAudioRec) 5675 Recording.mAudioRec->doDetachDriverViaEmt(mpUVM, pAutoLock); 5672 5676 # endif 5673 5677 i_recordingDestroy(); … … 5685 5689 #endif /* VBOX_WITH_RECORDING */ 5686 5690 5687 HRESULT Console::i_onRecordingChange() 5691 /** 5692 * Called by IInternalSessionControl::OnRecordingChange(). 5693 */ 5694 HRESULT Console::i_onRecordingChange(BOOL fEnabled) 5688 5695 { 5689 5696 AutoCaller autoCaller(this); … … 5698 5705 if (ptrVM.isOk()) 5699 5706 { 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))); 5707 5708 5708 5709 int vrc = i_recordingEnable(fEnabled, &alock); … … 6974 6975 AssertReturn(Recording.mpCtx == NULL, VERR_WRONG_ORDER); 6975 6976 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); 6993 6979 if (RT_SUCCESS(rc)) 6994 6980 { 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 } 6997 6993 } 6998 6994 … … 7020 7016 * @returns IPRT status code. 7021 7017 */ 7022 int Console::i_recordingStart(void) 7023 { 7018 int Console::i_recordingStart(util::AutoWriteLock *pAutoLock /* = NULL */) 7019 { 7020 RT_NOREF(pAutoLock); 7024 7021 AssertPtrReturn(Recording.mpCtx, VERR_WRONG_ORDER); 7025 7022 … … 7043 7040 * Stops recording. Does nothing if recording is not active. 7044 7041 */ 7045 int Console::i_recordingStop( void)7042 int Console::i_recordingStop(util::AutoWriteLock *pAutoLock /* = NULL */) 7046 7043 { 7047 7044 if ( !Recording.mpCtx … … 7058 7055 mDisplay->i_recordingScreenChanged(uScreen); 7059 7056 7057 if (pAutoLock) 7058 pAutoLock->release(); 7059 7060 7060 ComPtr<IRecordingSettings> pRecordSettings; 7061 7061 HRESULT hrc = mMachine->COMGETTER(RecordingSettings)(pRecordSettings.asOutParam()); 7062 7062 ComAssertComRC(hrc); 7063 hrc = pRecordSettings->COMSETTER(Enabled)( false);7063 hrc = pRecordSettings->COMSETTER(Enabled)(FALSE); 7064 7064 ComAssertComRC(hrc); 7065 7066 if (pAutoLock) 7067 pAutoLock->acquire(); 7065 7068 } 7066 7069 -
trunk/src/VBox/Main/src-client/DisplayImpl.cpp
r75448 r75488 3432 3432 # endif /* VBOX_WITH_HGCM && VBOX_WITH_CROGL */ 3433 3433 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 3434 3442 uint64_t tsNowMs = RTTimeProgramMilliTS(); 3435 3443 for (uScreenId = 0; uScreenId < pDisplay->mcMonitors; uScreenId++) … … 3437 3445 if (!pDisplay->maRecordingEnabled[uScreenId]) 3438 3446 continue; 3439 3440 if (pCtx->IsLimitReached(uScreenId, tsNowMs))3441 {3442 pDisplay->mParent->i_recordingStop();3443 break;3444 }3445 3447 3446 3448 DISPLAYFBINFO *pFBInfo = &pDisplay->maFramebuffers[uScreenId]; -
trunk/src/VBox/Main/src-client/Recording.cpp
r75441 r75488 90 90 91 91 92 RecordingContext::RecordingContext(Console *a_pConsole)93 : pConsole(a_pConsole)94 , enmState(RECORDINGSTS_UNINITIALIZED)95 , cStreamsEnabled(0) { }96 97 92 RecordingContext::RecordingContext(Console *a_pConsole, const settings::RecordingSettings &a_Settings) 98 93 : pConsole(a_pConsole) … … 373 368 } 374 369 370 int RecordingContext::lock(void) 371 { 372 int rc = RTCritSectEnter(&this->CritSect); 373 AssertRC(rc); 374 return rc; 375 } 376 377 int RecordingContext::unlock(void) 378 { 379 int rc = RTCritSectLeave(&this->CritSect); 380 AssertRC(rc); 381 return rc; 382 } 383 375 384 /** 376 385 * Retrieves a specific recording stream of a recording context. … … 440 449 * @param enmFeature Recording feature to check for. 441 450 */ 442 bool RecordingContext::IsFeatureEnabled(RecordingFeature_T enmFeature) const 443 { 451 bool RecordingContext::IsFeatureEnabled(RecordingFeature_T enmFeature) 452 { 453 lock(); 454 444 455 RecordingStreams::const_iterator itStream = this->vecStreams.begin(); 445 456 while (itStream != this->vecStreams.end()) 446 457 { 447 458 if ((*itStream)->GetConfig().isFeatureEnabled(enmFeature)) 459 { 460 unlock(); 448 461 return true; 462 } 449 463 ++itStream; 450 464 } 465 466 unlock(); 451 467 452 468 return false; … … 470 486 * @param uTimeStampMs Current time stamp (in ms). Currently not being used. 471 487 */ 472 bool RecordingContext::IsReady(uint32_t uScreen, uint64_t uTimeStampMs) const488 bool RecordingContext::IsReady(uint32_t uScreen, uint64_t uTimeStampMs) 473 489 { 474 490 RT_NOREF(uTimeStampMs); 475 491 492 lock(); 493 494 bool fIsReady = false; 495 476 496 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(); 488 508 489 509 return fIsReady; … … 495 515 * @returns true if active, false if not. 496 516 */ 497 bool RecordingContext::IsStarted(void) const 498 { 499 return (this->enmState == RECORDINGSTS_STARTED); 517 bool 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 */ 533 bool 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; 500 544 } 501 545 … … 505 549 * @returns true if any limit has been reached. 506 550 * @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 */ 553 bool RecordingContext::IsLimitReached(uint32_t uScreen, uint64_t uTimeStampMs) 554 { 555 lock(); 556 557 bool fLimitReached = false; 558 559 const RecordingStream *pStream = getStreamInternal(uScreen); 512 560 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 571 DECLCALLBACK(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; 519 586 } 520 587 … … 629 696 AssertRC(rc); 630 697 698 AssertFailed(); 631 699 return VERR_NOT_FOUND; 632 700 } … … 638 706 639 707 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. */ 641 709 { 642 710 threadNotify(); -
trunk/src/VBox/Main/src-client/RecordingStream.cpp
r75454 r75488 263 263 264 264 /** 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. 266 266 * 267 267 * @returns true if any limit has been reached. 268 * @param tsNowMs Current time stamp (in ms).269 */ 270 bool RecordingStream:: IsLimitReached(uint64_t tsNowMs) const271 { 272 if (!IsReady())273 return true;268 * @param uTimeStampMs Timestamp (in ms) to check for. 269 */ 270 bool RecordingStream::isLimitReachedInternal(uint64_t uTimeStampMs) const 271 { 272 LogFlowThisFunc(("uTimeStampMs=%RU64, ulMaxTimeS=%RU32, tsStartMs=%RU64\n", 273 uTimeStampMs, this->ScreenSettings.ulMaxTimeS, this->tsStartMs)); 274 274 275 275 if ( this->ScreenSettings.ulMaxTimeS 276 && tsNowMs >= this->tsStartMs + (this->ScreenSettings.ulMaxTimeS * RT_MS_1SEC))276 && uTimeStampMs >= this->tsStartMs + (this->ScreenSettings.ulMaxTimeS * RT_MS_1SEC)) 277 277 { 278 278 LogRel(("Recording: Time limit for stream #%RU16 has been reached (%RU32s)\n", … … 304 304 305 305 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 */ 315 int 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 */ 356 bool RecordingStream::IsLimitReached(uint64_t uTimeStampMs) const 357 { 358 if (!IsReady()) 359 return true; 360 361 return isLimitReachedInternal(uTimeStampMs); 306 362 } 307 363 … … 449 505 * Sends a raw (e.g. not yet encoded) video frame to the recording stream. 450 506 * 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. 452 510 * @param x Upper left (X) coordinate where the video frame starts. 453 511 * @param y Upper left (Y) coordinate where the video frame starts. … … 465 523 lock(); 466 524 525 LogFlowFunc(("uTimeStampMs=%RU64\n", uTimeStampMs)); 526 467 527 PRECORDINGVIDEOFRAME pFrame = NULL; 468 528 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 } 470 535 471 536 do 472 537 { 473 if (!this->fEnabled)474 {475 rc = VINF_TRY_AGAIN; /* Not (yet) enabled. */476 break;477 }478 479 538 if (uTimeStampMs < this->Video.uLastTimeStampMs + this->Video.uDelayMs) 480 539 { 481 rc = VINF_ TRY_AGAIN; /* Respect maximum frames per second. */540 rc = VINF_RECORDING_THROTTLED; /* Respect maximum frames per second. */ 482 541 break; 483 542 } … … 710 769 return rc; 711 770 712 constsettings::RecordingScreenSettings *pSettings = &this->ScreenSettings;771 settings::RecordingScreenSettings *pSettings = &this->ScreenSettings; 713 772 714 773 rc = RTCritSectInit(&this->CritSect); … … 823 882 this->enmState = RECORDINGSTREAMSTATE_INITIALIZED; 824 883 this->fEnabled = true; 825 this->tsStartMs = RTTime MilliTS();884 this->tsStartMs = RTTimeProgramMilliTS(); 826 885 } 827 886 else … … 846 905 int rc = VINF_SUCCESS; 847 906 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)); 868 924 869 925 if (RT_FAILURE(rc)) -
trunk/src/VBox/Main/src-client/SessionImpl.cpp
r75361 r75488 725 725 } 726 726 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( );727 HRESULT 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); 738 738 #else 739 739 return S_OK;
Note:
See TracChangeset
for help on using the changeset viewer.