862 lines
25 KiB
C++
862 lines
25 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// FILE : VideoEditorInterface.h
|
|
// PURPOSE : Abstraction layer for accessing the systems underlying the video editor.
|
|
//
|
|
// AUTHOR : james.strain
|
|
//
|
|
// Copyright (C) 1999-2013 Rockstar Games. All Rights Reserved.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
#include "VideoEditorInterface.h"
|
|
|
|
#if defined( GTA_REPLAY ) && GTA_REPLAY
|
|
|
|
// framework
|
|
#include "video/VideoPlayback.h"
|
|
#include "video/VideoPlaybackThumbnailManager.h"
|
|
#include "video/media_common.h"
|
|
|
|
// game
|
|
#include "control/videorecording/videorecording.h"
|
|
#include "frontend/ProfileSettings.h"
|
|
#include "frontend/VideoEditor/Core/ImposedImageHandler.h"
|
|
#include "frontend/VideoEditor/Core/VideoEditorUtil.h"
|
|
#include "frontend/VideoEditor/Core/VideoProjectAudioTrackProvider.h"
|
|
#include "replaycoordinator/ReplayCoordinator.h"
|
|
#include "replaycoordinator/ReplayMontageGenerator.h"
|
|
#include "system/controlMgr.h"
|
|
#include "Network/Live/NetworkTelemetry.h"
|
|
|
|
FRONTEND_OPTIMISATIONS();
|
|
|
|
CImposedImageHandler CVideoEditorInterface::ms_imposedImageHandler;
|
|
CRawClipFileDataProvider CVideoEditorInterface::ms_rawClipProvider( ms_imposedImageHandler );
|
|
CRawClipFileView CVideoEditorInterface::ms_rawClipView;
|
|
CVideoProjectFileDataProvider CVideoEditorInterface::ms_videoProjectProvider( ms_imposedImageHandler );
|
|
CVideoProjectFileView CVideoEditorInterface::ms_videoProjectView;
|
|
#if defined(VIDEO_PLAYBACK_ENABLED) && VIDEO_PLAYBACK_ENABLED
|
|
#if RSG_ORBIS
|
|
CVideoFileDataProvider CVideoEditorInterface::ms_videoProvider( ms_imposedImageHandler );
|
|
#else
|
|
CVideoFileDataProvider CVideoEditorInterface::ms_videoProvider( g_videoThumbnailLoader );
|
|
#endif
|
|
CVideoFileView CVideoEditorInterface::ms_videoView;
|
|
#endif
|
|
|
|
CVideoEditorProject CVideoEditorInterface::ms_activeProject( ms_imposedImageHandler );
|
|
CVideoProjectPlaybackController CVideoEditorInterface::ms_playbackController;
|
|
|
|
bool CVideoEditorInterface::ms_isInAutogeneratedBake = false;
|
|
CVideoEditorInterface::eProjectGenerateState CVideoEditorInterface::ms_projectGenState = CVideoEditorInterface::PROJ_GEN_INVALID;
|
|
|
|
const float c_extraSuggestedPercent = 0.10f;
|
|
|
|
void CVideoEditorInterface::Init( unsigned initMode )
|
|
{
|
|
UNUSED_VAR( initMode );
|
|
}
|
|
|
|
void CVideoEditorInterface::Update()
|
|
{
|
|
PF_AUTO_PUSH_TIMEBAR("CVideoEditorInterface Update");
|
|
|
|
if( ms_activeProject.IsInitialized() )
|
|
{
|
|
ms_activeProject.update();
|
|
ms_activeProject.UpdateBespokeThumbnailCaptures();
|
|
|
|
UpdateBakeProject();
|
|
}
|
|
else if( IsAutogeneratingProject() && !CReplayCoordinator::IsAutogeneratingProject() )
|
|
{
|
|
if( CReplayCoordinator::HasAutogenerationFailed() )
|
|
{
|
|
ms_projectGenState = PROJ_GEN_FAILED;
|
|
}
|
|
else
|
|
{
|
|
ms_activeProject.InitializeFromMontage( CReplayCoordinator::GetAutogeneratedMontage() );
|
|
ms_projectGenState = PROJ_GEN_LOADED;
|
|
}
|
|
}
|
|
|
|
if( canUpdate() )
|
|
{
|
|
if( ms_rawClipView.isInitialized() )
|
|
{
|
|
ms_rawClipView.update();
|
|
}
|
|
|
|
if( ms_videoProjectView.isInitialized() )
|
|
{
|
|
ms_videoProjectView.update();
|
|
}
|
|
|
|
#if defined(VIDEO_PLAYBACK_ENABLED) && VIDEO_PLAYBACK_ENABLED
|
|
if( ms_videoView.isInitialized() )
|
|
{
|
|
ms_videoView.update();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
CMissionMontageGenerator::ProcessMontages();
|
|
}
|
|
|
|
void CVideoEditorInterface::UpdatePreRender()
|
|
{
|
|
#if defined(VIDEO_PLAYBACK_ENABLED) && VIDEO_PLAYBACK_ENABLED
|
|
|
|
if( canUpdatePreRender() )
|
|
{
|
|
if( !VideoPlaybackThumbnailManager::IsActive() )
|
|
{
|
|
VideoPlaybackThumbnailManager::Activate();
|
|
}
|
|
}
|
|
else if( VideoPlaybackThumbnailManager::IsActive() )
|
|
{
|
|
VideoPlaybackThumbnailManager::Deactivate();
|
|
}
|
|
|
|
#endif // defined(VIDEO_PLAYBACK_ENABLED) && VIDEO_PLAYBACK_ENABLED
|
|
}
|
|
|
|
void CVideoEditorInterface::Shutdown( unsigned shutdownMode )
|
|
{
|
|
UNUSED_VAR(shutdownMode);
|
|
Deactivate();
|
|
}
|
|
|
|
void CVideoEditorInterface::Activate()
|
|
{
|
|
uiAssertf( !IsActive(), "CVideoEditorInterface::Activate - Double activiation. Logic Error?" );
|
|
if( !IsActive() )
|
|
{
|
|
#if defined(VIDEO_PLAYBACK_ENABLED) && VIDEO_PLAYBACK_ENABLED
|
|
VideoPlayback::Activate();
|
|
#endif
|
|
CReplayMgr::OnEditorActivate();
|
|
CReplayCoordinator::Activate();
|
|
ms_playbackController.Reset();
|
|
|
|
#if __WIN32PC
|
|
//Unload PC control scheme to handle replay inputs
|
|
CControlMgr::GetPlayerMappingControl().LoadVideoEditorScriptControlMappings();
|
|
#endif // __WIN32PC
|
|
}
|
|
}
|
|
|
|
bool CVideoEditorInterface::IsActive()
|
|
{
|
|
return CReplayCoordinator::IsActive();
|
|
}
|
|
|
|
void CVideoEditorInterface::Deactivate()
|
|
{
|
|
if( IsActive() )
|
|
{
|
|
uiAssertf( !ms_rawClipView.isInitialized() && !ms_rawClipProvider.isInitialized(),
|
|
"CVideoEditorInterface::Deactivate - Deactivating with raw clip view not cleaned up! Good luck" );
|
|
cleanupClipViewInternal();
|
|
|
|
uiAssertf( !ms_videoProjectView.isInitialized() && !ms_videoProjectProvider.isInitialized(),
|
|
"CVideoEditorInterface::Deactivate - Deactivating with video project view not cleaned up! Good luck" );
|
|
cleanupProjectViewInternal();
|
|
|
|
uiAssertf( !ms_activeProject.IsInitialized(),
|
|
"CVideoEditorInterface::Deactivate - Deactivating with an active project! Good luck" );
|
|
cleanupActiveProjectInternal();
|
|
|
|
ms_imposedImageHandler.cleanup();
|
|
ms_isInAutogeneratedBake = false;
|
|
|
|
CReplayCoordinator::Deactivate();
|
|
#if defined(VIDEO_PLAYBACK_ENABLED) && VIDEO_PLAYBACK_ENABLED
|
|
VideoPlayback::Deactivate();
|
|
#endif
|
|
|
|
CReplayMgr::OnEditorDeactivate();
|
|
|
|
// Flush the telemetry after using the editor
|
|
if(NetworkInterface::IsLocalPlayerOnline())
|
|
CNetworkTelemetry::FlushTelemetry();
|
|
|
|
#if __WIN32PC
|
|
//Unload PC control scheme to handle replay inputs
|
|
CControlMgr::GetPlayerMappingControl().UnloadVideoEditorScriptControlMappings();
|
|
#endif // __WIN32PC
|
|
}
|
|
}
|
|
|
|
bool CVideoEditorInterface::GrabRawClipFileView( char const * const directory, CRawClipFileView *& out_view )
|
|
{
|
|
bool success = false;
|
|
|
|
uiAssertf( IsActive(), "CVideoEditorInterface::GrabRawClipFileView - Editor not active!" );
|
|
if( IsActive() )
|
|
{
|
|
uiAssertf( directory, "CVideoEditorInterface::GrabRawClipFileView - Invalid directory specified!" );
|
|
uiAssertf( out_view == NULL, "CVideoEditorInterface::GrabRawClipFileView - out_view should be null!" );
|
|
uiAssertf( !ms_rawClipProvider.isInitialized(), "CVideoEditorInterface::GrabRawClipFileView - Provider already initialized!" );
|
|
uiAssertf( !ms_rawClipView.isInitialized(), "CVideoEditorInterface::GrabRawClipFileView - View already initialized!" );
|
|
|
|
if( directory && out_view == NULL && !ms_rawClipProvider.isInitialized() && !ms_rawClipView.isInitialized() )
|
|
{
|
|
u64 const c_activeUserId = CReplayCoordinator::GetActiveUserId();
|
|
|
|
success = ms_rawClipProvider.initialize( directory, RAW_CLIP_FILE_EXTENSION, c_activeUserId );
|
|
success = success ? ms_rawClipView.initialize( ms_rawClipProvider ) : false;
|
|
out_view = success ? &ms_rawClipView : NULL;
|
|
|
|
if( !success )
|
|
{
|
|
cleanupClipViewInternal();
|
|
}
|
|
}
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
void CVideoEditorInterface::ReleaseRawClipFileView( CRawClipFileView *& view )
|
|
{
|
|
uiAssertf( IsActive(), "CVideoEditorInterface::ReleaseRawClipFileView - Editor not active!" );
|
|
if( IsActive() )
|
|
{
|
|
if( view && view == &ms_rawClipView )
|
|
{
|
|
view = NULL;
|
|
|
|
cleanupClipViewInternal();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CVideoEditorInterface::GrabVideoProjectFileView( char const * const directory, CVideoProjectFileView *& out_view )
|
|
{
|
|
bool success = false;
|
|
|
|
uiAssertf( IsActive(), "CVideoEditorInterface::GrabVideoProjectFileView - Editor not active!" );
|
|
if( IsActive() )
|
|
{
|
|
uiAssertf( directory, "CVideoEditorInterface::GrabVideoProjectFileView - Invalid directory specified!" );
|
|
uiAssertf( out_view == NULL, "CVideoEditorInterface::GrabVideoProjectFileView - out_view should be null!" );
|
|
uiAssertf( !ms_videoProjectProvider.isInitialized(), "CVideoEditorInterface::GrabVideoProjectFileView - Provider already initialized!" );
|
|
uiAssertf( !ms_videoProjectView.isInitialized(), "CVideoEditorInterface::GrabVideoProjectFileView - View already initialized!" );
|
|
|
|
if( directory && out_view == NULL && !ms_videoProjectProvider.isInitialized() && !ms_videoProjectView.isInitialized() )
|
|
{
|
|
u64 const c_activeUserId = CReplayCoordinator::GetActiveUserId();
|
|
|
|
success = ms_videoProjectProvider.initialize( directory, VIDEO_PROJECT_FILE_EXTENSION, c_activeUserId );
|
|
success = success ? ms_videoProjectView.initialize( ms_videoProjectProvider ) : false;
|
|
out_view = success ? &ms_videoProjectView : NULL;
|
|
|
|
if( !success )
|
|
{
|
|
cleanupProjectViewInternal();
|
|
}
|
|
}
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
void CVideoEditorInterface::ReleaseVideoProjectFileView( CVideoProjectFileView *& view )
|
|
{
|
|
uiAssertf( IsActive(), "CVideoEditorInterface::ReleaseVideoProjectFileView - Editor not active!" );
|
|
if( IsActive() )
|
|
{
|
|
if( view && view == &ms_videoProjectView )
|
|
{
|
|
view = NULL;
|
|
cleanupProjectViewInternal();
|
|
}
|
|
}
|
|
}
|
|
|
|
#if defined(VIDEO_PLAYBACK_ENABLED) && VIDEO_PLAYBACK_ENABLED
|
|
|
|
bool CVideoEditorInterface::GrabVideoFileView( char const * const directory, CVideoFileView *& out_view )
|
|
{
|
|
bool success = false;
|
|
|
|
if( uiVerifyf( IsActive(), "CVideoEditorInterface::GrabVideoFileView - Editor not active!" ) &&
|
|
uiVerifyf( directory, "CVideoEditorInterface::GrabVideoFileView - Invalid directory specified!" ) &&
|
|
uiVerifyf( out_view == NULL, "CVideoEditorInterface::GrabVideoFileView - out_view should be null!" ) &&
|
|
uiVerifyf( !ms_videoProvider.isInitialized(), "CVideoEditorInterface::GrabVideoFileView - Provider already initialized!" ) &&
|
|
uiVerifyf( !ms_videoView.isInitialized(), "CVideoEditorInterface::GrabVideoFileView - View already initialized!" ) )
|
|
{
|
|
u64 const c_activeUserId = CReplayCoordinator::GetActiveUserId();
|
|
|
|
char const * const c_filter =
|
|
#if RSG_PC
|
|
NULL;
|
|
#else
|
|
"mp4";
|
|
#endif
|
|
|
|
success = ms_videoProvider.initialize( directory, c_filter, c_activeUserId );
|
|
success = success ? ms_videoView.initialize( ms_videoProvider ) : false;
|
|
out_view = success ? &ms_videoView : NULL;
|
|
|
|
if( !success )
|
|
{
|
|
cleanupVideoViewInternal();
|
|
}
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
void CVideoEditorInterface::ReleaseVideoFileView( CVideoFileView *& view )
|
|
{
|
|
if( uiVerifyf( IsActive(), "CVideoEditorInterface::ReleaseVideoFileView - Editor not active!" ) &&
|
|
view && view == &ms_videoView )
|
|
{
|
|
view = NULL;
|
|
cleanupVideoViewInternal();
|
|
}
|
|
}
|
|
|
|
#endif // defined(VIDEO_PLAYBACK_ENABLED) && VIDEO_PLAYBACK_ENABLED
|
|
|
|
bool CVideoEditorInterface::CanUpdateHelpText()
|
|
{
|
|
bool allowUpdate = ms_playbackController.IsEditing() && !CVideoEditorInterface::ShouldShowLoadingScreen();
|
|
return allowUpdate;
|
|
}
|
|
|
|
bool CVideoEditorInterface::HasSeenTutorial( eEditorTutorialFlags const tutorial )
|
|
{
|
|
CProfileSettings& settings = CProfileSettings::GetInstance();
|
|
|
|
int const c_tutorialFlags = settings.AreSettingsValid() ? settings.GetReplayTutorialFlags() : 0;
|
|
bool const c_hasSeenTutorial = ( c_tutorialFlags & tutorial ) != 0;
|
|
|
|
return c_hasSeenTutorial;
|
|
}
|
|
|
|
void CVideoEditorInterface::SetTutorialSeen( eEditorTutorialFlags const tutorial )
|
|
{
|
|
CProfileSettings& settings = CProfileSettings::GetInstance();
|
|
if( settings.AreSettingsValid() )
|
|
{
|
|
settings.UpdateReplayTutorialFlags( (s32)tutorial );
|
|
settings.Write();
|
|
}
|
|
}
|
|
|
|
u32 CVideoEditorInterface::GetTutorialDurationMs( eEditorTutorialFlags const tutorial )
|
|
{
|
|
//! TODO - Use the duration manager for this, when you get a chance to write it :)
|
|
static const u32 sc_tutorialDurationMs[ EDITOR_TUTORIAL_COUNT ] =
|
|
{
|
|
4000
|
|
};
|
|
|
|
u32 const c_result = tutorial >= 0 && tutorial < EDITOR_TUTORIAL_COUNT ? sc_tutorialDurationMs[ tutorial ] : sc_tutorialDurationMs[0];
|
|
return c_result;
|
|
}
|
|
|
|
u64 CVideoEditorInterface::GetActiveUserId()
|
|
{
|
|
return CReplayCoordinator::GetActiveUserId();
|
|
}
|
|
|
|
bool CVideoEditorInterface::HasMinSpaceToSaveNewProject()
|
|
{
|
|
size_t const c_minimalSizeNeeded = CVideoEditorProject::ApproximateMinimumSizeForSaving();
|
|
bool const c_hasSpaceForMinimalProject = CVideoEditorProject::IsSpaceAvailableForSaving( NULL, c_minimalSizeNeeded );
|
|
return c_hasSpaceForMinimalProject;
|
|
}
|
|
|
|
bool CVideoEditorInterface::HasReachedMaxProjectLimit( CVideoProjectFileView const& projectFileView )
|
|
{
|
|
bool hitLimit = true;
|
|
|
|
uiAssertf( IsActive(), "CVideoEditorInterface::HasReachedMaxProjectLimit - Editor not active!" );
|
|
if( IsActive() && projectFileView.isInitialized() )
|
|
{
|
|
|
|
u32 const c_maxProjects = projectFileView.getMaxProjectCount();
|
|
u32 const c_currentProjects = (u32)projectFileView.getUnfilteredFileCount( false );
|
|
|
|
hitLimit = c_currentProjects >= c_maxProjects;
|
|
}
|
|
|
|
return hitLimit;
|
|
}
|
|
|
|
bool CVideoEditorInterface::GenerateUniqueProjectName( char (&out_buffer)[ sc_nameBufferSize ], CVideoProjectFileView const& projectFileView )
|
|
{
|
|
bool success = false;
|
|
|
|
uiAssertf( IsActive(), "CVideoEditorInterface::GenerateUniqueProjectName - Editor not active!" );
|
|
if( IsActive() && projectFileView.isInitialized() )
|
|
{
|
|
u64 const c_activeUserId = CReplayCoordinator::GetActiveUserId();
|
|
|
|
out_buffer[0] = rage::TEXT_CHAR_TERMINATOR;
|
|
|
|
u32 uniqueNumber = (u32)projectFileView.getUnfilteredFileCount( true ) + 1;
|
|
u32 const c_loopTarget = uniqueNumber;
|
|
char const * const c_prefix = TheText.Get("VEUI_PROJ_FILENAME");
|
|
do
|
|
{
|
|
formatf( out_buffer, "%s %u", c_prefix, uniqueNumber, sc_nameBufferSize );
|
|
++uniqueNumber;
|
|
|
|
} while ( projectFileView.doesFileExistInProvider( out_buffer, false, c_activeUserId ) || c_loopTarget == uniqueNumber );
|
|
|
|
success = !projectFileView.doesFileExistInProvider( out_buffer, false, c_activeUserId );
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
bool CVideoEditorInterface::GrabNewProject( char const * const name, CVideoEditorProject *& out_project )
|
|
{
|
|
bool success = false;
|
|
|
|
uiAssertf( IsActive(), "CVideoEditorInterface::GrabNewProjectEditor - Editor not active!" );
|
|
if( IsActive() )
|
|
{
|
|
uiAssertf( name, "CVideoEditorInterface::GrabNewProjectEditor - Invalid name specified!" );
|
|
uiAssertf( out_project == NULL, "CVideoEditorInterface::GrabNewProjectEditor - out_project should be null!" );
|
|
uiAssertf( !ms_activeProject.IsInitialized(), "CVideoEditorInterface::GrabNewProjectEditor - Project already active!" );
|
|
|
|
if( name && out_project == NULL && !ms_activeProject.IsInitialized() )
|
|
{
|
|
CVideoProjectAudioTrackProvider::ClearTracksUsedInProject();
|
|
|
|
success = ms_activeProject.InitializeNew( name );
|
|
out_project = success ? &ms_activeProject : NULL;
|
|
|
|
if( !success )
|
|
{
|
|
cleanupActiveProjectInternal();
|
|
}
|
|
}
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
bool CVideoEditorInterface::StartLoadProject( char const * const path )
|
|
{
|
|
bool success = false;
|
|
|
|
uiAssertf( IsActive(), "CVideoEditorInterface::LoadAndGrabProjectEditor - Editor not active!" );
|
|
if( IsActive() )
|
|
{
|
|
uiAssertf( path, "CVideoEditorInterface::StartLoadProject - Invalid path specified!" );
|
|
uiAssertf( !ms_activeProject.IsInitialized(), "CVideoEditorInterface::StartLoadProject - Project already active!" );
|
|
uiAssertf( CanLoadProject(), "CVideoEditorInterface::StartLoadProject - Logic error; We shouldn't be loading a project right now" );
|
|
|
|
if( path && !ms_activeProject.IsInitialized() )
|
|
{
|
|
CVideoProjectAudioTrackProvider::ClearTracksUsedInProject();
|
|
success = ms_activeProject.StartLoad( path );
|
|
}
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
bool CVideoEditorInterface::CanLoadProject()
|
|
{
|
|
return !ms_activeProject.IsInitialized();
|
|
}
|
|
|
|
bool CVideoEditorInterface::IsLoadingProject()
|
|
{
|
|
return ms_activeProject.IsInitialized() && ms_activeProject.IsPendingLoad();
|
|
}
|
|
|
|
bool CVideoEditorInterface::HasLoadingProjectFailed()
|
|
{
|
|
return ms_activeProject.IsInitialized() && ms_activeProject.HasLoadFailed();
|
|
}
|
|
|
|
u64 CVideoEditorInterface::GetProjectLoadExtendedResultData()
|
|
{
|
|
return ms_activeProject.IsInitialized() ? ms_activeProject.GetProjectLoadExtendedResultData() : 0;
|
|
}
|
|
|
|
bool CVideoEditorInterface::GrabClipPreviewProject( u64 const ownerId, char const * const clipFileName, CVideoEditorProject *& out_previewProject )
|
|
{
|
|
bool success = false;
|
|
|
|
if( GrabNewProject( "raw_preview", out_previewProject ) )
|
|
{
|
|
success = out_previewProject->AddClip( ownerId, clipFileName, 0 );
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
bool CVideoEditorInterface::StartAutogeneratingProject( CReplayEditorParameters::eAutoGenerationDuration const duration )
|
|
{
|
|
bool started = false;
|
|
if( Verifyf( GetActiveProject() == NULL, "CVideoEditorInterface::StartAutogeneratingProject - Attempting Auto-generating montage"
|
|
" with active project!" ) &&
|
|
Verifyf( CanAutogenerateProject(), "CVideoEditorInterface::StartAutogeneratingProject - Pending auto-generate in progess?" ) )
|
|
{
|
|
started = CReplayCoordinator::StartAutogeneratingProject( duration );
|
|
ms_projectGenState = PROJ_GEN_PENDING;
|
|
}
|
|
|
|
return started;
|
|
}
|
|
|
|
bool CVideoEditorInterface::CanAutogenerateProject()
|
|
{
|
|
return CanLoadProject() && ms_projectGenState != PROJ_GEN_PENDING;
|
|
}
|
|
|
|
bool CVideoEditorInterface::IsAutogeneratingProject()
|
|
{
|
|
return ms_projectGenState == PROJ_GEN_PENDING;
|
|
}
|
|
|
|
bool CVideoEditorInterface::IsAutogeneratedProjectReady()
|
|
{
|
|
return ms_projectGenState == PROJ_GEN_LOADED;
|
|
}
|
|
|
|
bool CVideoEditorInterface::HasAutogenerationFailed()
|
|
{
|
|
return ms_projectGenState == PROJ_GEN_FAILED;
|
|
}
|
|
|
|
CVideoEditorProject* CVideoEditorInterface::GetActiveProject()
|
|
{
|
|
return ms_activeProject.IsInitialized() ? &ms_activeProject : NULL;
|
|
}
|
|
|
|
void CVideoEditorInterface::ReleaseActiveProject()
|
|
{
|
|
cleanupActiveProjectInternal();
|
|
}
|
|
|
|
bool CVideoEditorInterface::IsClipUsedInAnyProject( ClipUID const& uid )
|
|
{
|
|
return CReplayCoordinator::IsClipUsedInAnyProject( uid );
|
|
}
|
|
|
|
bool CVideoEditorInterface::IsCachingForPlayback()
|
|
{
|
|
return CReplayCoordinator::IsCachingForPlayback();
|
|
}
|
|
|
|
bool CVideoEditorInterface::IsPendingClipTransition()
|
|
{
|
|
return CReplayCoordinator::IsPendingNextClip();
|
|
}
|
|
|
|
bool CVideoEditorInterface::IsPreviewingVideo()
|
|
{
|
|
return CReplayCoordinator::IsPreviewingVideo();
|
|
}
|
|
|
|
bool CVideoEditorInterface::IsPreviewingClip()
|
|
{
|
|
return CReplayCoordinator::IsPreviewingClip();
|
|
}
|
|
|
|
bool CVideoEditorInterface::IsRenderingVideo()
|
|
{
|
|
return CReplayCoordinator::IsRenderingVideo();
|
|
}
|
|
|
|
bool CVideoEditorInterface::IsPendingVideoFinalization()
|
|
{
|
|
return CReplayCoordinator::IsPendingVideoFinalization();
|
|
}
|
|
|
|
bool CVideoEditorInterface::IsPendingCleanup()
|
|
{
|
|
return CReplayCoordinator::IsPendingCleanup();
|
|
}
|
|
|
|
bool CVideoEditorInterface::HasVideoRenderErrored()
|
|
{
|
|
return CReplayCoordinator::HasVideoRenderErrored();
|
|
}
|
|
|
|
char const * CVideoEditorInterface::GetVideoRenderErrorLngKey()
|
|
{
|
|
return CReplayCoordinator::GetVideoRenderErrorLngKey();
|
|
}
|
|
|
|
bool CVideoEditorInterface::HasVideoRenderSuspended()
|
|
{
|
|
return CReplayCoordinator::HasVideoRenderSuspended();
|
|
}
|
|
|
|
bool CVideoEditorInterface::HasVideoRenderBeenConstrained()
|
|
{
|
|
return CReplayCoordinator::HasVideoRenderBeenConstrained();
|
|
}
|
|
|
|
bool CVideoEditorInterface::IsRenderingPaused()
|
|
{
|
|
return CReplayCoordinator::IsRenderingPaused();
|
|
}
|
|
|
|
bool CVideoEditorInterface::ShouldShowLoadingScreen()
|
|
{
|
|
return CReplayCoordinator::ShouldShowLoadingScreen();
|
|
}
|
|
|
|
bool CVideoEditorInterface::ShouldShowProcessingText()
|
|
{
|
|
return CReplayCoordinator::ShouldShowProcessingText();
|
|
}
|
|
|
|
bool CVideoEditorInterface::HasClipLoadFailed()
|
|
{
|
|
return CReplayCoordinator::HasClipLoadFailed();
|
|
}
|
|
|
|
void CVideoEditorInterface::PlayClipPreview( u32 clipIndex, bool const isEditing )
|
|
{
|
|
if( canPreviewOrBakeProject() )
|
|
{
|
|
if( CReplayCoordinator::PlayClipPreview( clipIndex, *ms_activeProject.GetMontage() ) )
|
|
{
|
|
ms_playbackController.Initialize( CVideoProjectPlaybackController::PLAYBACK_CLIP, isEditing );
|
|
ms_playbackController.JumpToStart();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVideoEditorInterface::PlayProjectPreview()
|
|
{
|
|
if( canPreviewOrBakeProject() )
|
|
{
|
|
if( CReplayCoordinator::PlayProjectPreview( *ms_activeProject.GetMontage() ) )
|
|
{
|
|
ms_playbackController.Initialize( CVideoProjectPlaybackController::PLAYBACK_PROJECT, false );
|
|
ms_playbackController.JumpToStart();
|
|
}
|
|
}
|
|
}
|
|
|
|
CVideoProjectPlaybackController& CVideoEditorInterface::GetPlaybackController()
|
|
{
|
|
return ms_playbackController;
|
|
}
|
|
|
|
bool CVideoEditorInterface::AutogenerateAndBakeProject( CReplayEditorParameters::eAutoGenerationDuration const duration )
|
|
{
|
|
bool startedBake = false;
|
|
|
|
if( Verifyf( GetActiveProject() == NULL, "CVideoEditorInterface::AutogenerateAndBakeProject - Attempting Auto-generating montage"
|
|
" with active project!" ) )
|
|
{
|
|
if (StartAutogeneratingProject(duration))
|
|
{
|
|
ms_activeProject.SaveProject( ms_activeProject.GetName() );
|
|
StartBakeProject( ms_activeProject.GetName() );
|
|
ms_isInAutogeneratedBake = startedBake = true;
|
|
}
|
|
}
|
|
|
|
return startedBake;
|
|
}
|
|
|
|
bool CVideoEditorInterface::IsSpaceAvailableToBake( float const c_durationMs,
|
|
size_t& out_sizeBytesRequired, size_t& out_sizeBytesAvailable )
|
|
{
|
|
#if RSG_DURANGO || RSG_PC
|
|
bool success = false;
|
|
out_sizeBytesRequired = 0;
|
|
out_sizeBytesAvailable = 0;
|
|
size_t extraBytesRequired = MediaCommon::GetExtraBytesRequiredForEncode();
|
|
size_t extraBytesToBufferSuggestedSize = 0;
|
|
|
|
if( canPreviewOrBakeProject() )
|
|
{
|
|
// TODO - If we allow configurable quality, we need to hook this in to that
|
|
rage::MediaEncoderParams::eQualityLevel const c_qualityLevel = rage::MediaEncoderParams::QUALITY_DEFAULT;
|
|
out_sizeBytesRequired =
|
|
|
|
#if VIDEO_RECORDING_ENABLED
|
|
VideoRecording::EstimateSizeOfRecording( (u32)c_durationMs, c_qualityLevel );
|
|
#else
|
|
0;
|
|
|
|
(void)c_durationMs;
|
|
(void)c_qualityLevel;
|
|
#endif
|
|
|
|
if( Verifyf( CReplayCoordinator::GetSpaceForVideoBake( out_sizeBytesAvailable ),
|
|
"CVideoEditorInterface::IsSpaceAvailableToBake - Unable to calculate space available for video files" ) )
|
|
{
|
|
extraBytesToBufferSuggestedSize = (size_t) ( (float)out_sizeBytesRequired * c_extraSuggestedPercent);
|
|
|
|
success = (out_sizeBytesRequired + extraBytesRequired + extraBytesToBufferSuggestedSize) < out_sizeBytesAvailable;
|
|
}
|
|
}
|
|
|
|
return success;
|
|
#else
|
|
// Replay always returns 0 for size available on these platforms, so we just have to assume true and plod on.
|
|
UNUSED_VAR(c_durationMs); UNUSED_VAR(out_sizeBytesRequired); UNUSED_VAR(out_sizeBytesAvailable);
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
bool CVideoEditorInterface::StartBakeProject( char const * const outputName )
|
|
{
|
|
bool success = false;
|
|
|
|
if( canPreviewOrBakeProject() )
|
|
{
|
|
success = CReplayCoordinator::StartBakeProject( *ms_activeProject.GetMontage(), outputName );
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
void CVideoEditorInterface::UpdateBakeProject()
|
|
{
|
|
if( CReplayCoordinator::IsRenderingVideo() )
|
|
{
|
|
bool const c_preUpdatePendingBake = CReplayCoordinator::IsPendingPendingBakeStart();
|
|
CReplayCoordinator::UpdateBakeProject();
|
|
bool const c_postUpdatePendingBake = CReplayCoordinator::IsPendingPendingBakeStart();
|
|
|
|
if( c_preUpdatePendingBake && !c_postUpdatePendingBake )
|
|
{
|
|
ms_playbackController.Initialize( CVideoProjectPlaybackController::PLAYBACK_PROJECT, false );
|
|
ms_playbackController.JumpToStart();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVideoEditorInterface::PauseBake()
|
|
{
|
|
if( CReplayCoordinator::IsRenderingVideo() && !CReplayCoordinator::IsRenderingPaused() )
|
|
{
|
|
CReplayCoordinator::PauseBake();
|
|
}
|
|
}
|
|
|
|
void CVideoEditorInterface::ResumeBake()
|
|
{
|
|
if( CReplayCoordinator::IsRenderingVideo() && CReplayCoordinator::IsRenderingPaused() )
|
|
{
|
|
CReplayCoordinator::ResumeBake();
|
|
}
|
|
}
|
|
|
|
void CVideoEditorInterface::KillPlaybackOrBake(bool userCancelled)
|
|
{
|
|
if( CReplayCoordinator::IsPreviewingClip() || CReplayCoordinator::IsPreviewingVideo() || CReplayCoordinator::IsRenderingVideo() )
|
|
{
|
|
ms_playbackController.Pause();
|
|
CReplayCoordinator::KillPlaybackOrBake(userCancelled);
|
|
|
|
//! If it was an auto-generated bake, we want to clean-up the loaded project as
|
|
//! the UI should never have needed to interact with it.
|
|
if( ms_isInAutogeneratedBake )
|
|
{
|
|
cleanupActiveProjectInternal();
|
|
ms_isInAutogeneratedBake = false;
|
|
}
|
|
}
|
|
|
|
ms_playbackController.Reset();
|
|
}
|
|
|
|
void CVideoEditorInterface::CleanupPlayback()
|
|
{
|
|
CReplayCoordinator::CleanupPlayback();
|
|
}
|
|
|
|
void CVideoEditorInterface::ReleaseProject( CVideoEditorProject *& project )
|
|
{
|
|
uiAssertf( IsActive(), "CVideoEditorInterface::ReleaseProjectEditor - Editor not active!" );
|
|
if( IsActive() )
|
|
{
|
|
if( project && project == &ms_activeProject )
|
|
{
|
|
project = NULL;
|
|
|
|
cleanupActiveProjectInternal();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CVideoEditorInterface::canUpdate()
|
|
{
|
|
return IsActive() && CReplayCoordinator::IsIdle();
|
|
}
|
|
|
|
bool CVideoEditorInterface::canUpdatePreRender()
|
|
{
|
|
return IsActive() && CReplayCoordinator::IsIdle() && !ms_activeProject.IsInitialized();
|
|
}
|
|
|
|
bool CVideoEditorInterface::canPreviewOrBakeProject()
|
|
{
|
|
return CReplayCoordinator::IsIdle() && ms_activeProject.IsInitialized();
|
|
}
|
|
|
|
void CVideoEditorInterface::cleanupClipViewInternal()
|
|
{
|
|
if( ms_rawClipView.isInitialized() )
|
|
{
|
|
ms_rawClipView.shutdown();
|
|
}
|
|
|
|
if( ms_rawClipProvider.isInitialized() )
|
|
{
|
|
ms_rawClipProvider.shutdown();
|
|
}
|
|
}
|
|
|
|
void CVideoEditorInterface::cleanupProjectViewInternal()
|
|
{
|
|
if( ms_videoProjectView.isInitialized() )
|
|
{
|
|
ms_videoProjectView.shutdown();
|
|
}
|
|
|
|
if( ms_videoProjectProvider.isInitialized() )
|
|
{
|
|
ms_videoProjectProvider.shutdown();
|
|
}
|
|
}
|
|
|
|
void CVideoEditorInterface::cleanupVideoViewInternal()
|
|
{
|
|
#if defined(VIDEO_PLAYBACK_ENABLED) && VIDEO_PLAYBACK_ENABLED
|
|
if( ms_videoView.isInitialized() )
|
|
{
|
|
ms_videoView.shutdown();
|
|
}
|
|
|
|
if( ms_videoProvider.isInitialized() )
|
|
{
|
|
ms_videoProvider.shutdown();
|
|
}
|
|
#endif // defined(VIDEO_PLAYBACK_ENABLED) && VIDEO_PLAYBACK_ENABLED
|
|
}
|
|
|
|
void CVideoEditorInterface::cleanupActiveProjectInternal()
|
|
{
|
|
if( ms_activeProject.IsInitialized() )
|
|
{
|
|
KillPlaybackOrBake();
|
|
ms_activeProject.Shutdown();
|
|
}
|
|
}
|
|
|
|
#endif // defined( GTA_REPLAY ) && GTA_REPLAY
|