source-engine/video/video_webm/webm_video.cpp
2022-10-13 17:47:27 +03:00

354 lines
9.8 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "webm_video.h"
#include "webm_recorder.h"
#include "filesystem.h"
#include "tier0/icommandline.h"
#include "tier1/strtools.h"
#include "tier1/utllinkedlist.h"
#include "tier1/KeyValues.h"
#include "materialsystem/imaterial.h"
#include "materialsystem/imaterialsystem.h"
#include "materialsystem/MaterialSystemUtil.h"
#include "materialsystem/itexture.h"
#include "vtf/vtf.h"
#include "pixelwriter.h"
#include "tier2/tier2.h"
#include "platform.h"
#include "tier0/memdbgon.h"
// ===========================================================================
// Singleton to expose WebM video subsystem
// ===========================================================================
static CWebMVideoSubSystem g_WebMSystem;
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CWebMVideoSubSystem, IVideoSubSystem, VIDEO_SUBSYSTEM_INTERFACE_VERSION, g_WebMSystem );
// ===========================================================================
// List of file extensions and features supported by this subsystem
// ===========================================================================
VideoFileExtensionInfo_t s_WebMExtensions[] =
{
{ ".webm", VideoSystem::WEBM, VideoSystemFeature::FULL_ENCODE },
};
const int s_WebMExtensionCount = ARRAYSIZE( s_WebMExtensions );
const VideoSystemFeature_t CWebMVideoSubSystem::DEFAULT_FEATURE_SET = VideoSystemFeature::FULL_ENCODE;
// ===========================================================================
// CWebMVideoSubSystem class
// ===========================================================================
CWebMVideoSubSystem::CWebMVideoSubSystem() :
m_bWebMInitialized( false ),
m_LastResult( VideoResult::SUCCESS ),
m_CurrentStatus( VideoSystemStatus::NOT_INITIALIZED ),
m_AvailableFeatures( CWebMVideoSubSystem::DEFAULT_FEATURE_SET ),
m_pCommonServices( nullptr )
{
}
CWebMVideoSubSystem::~CWebMVideoSubSystem()
{
ShutdownWebM(); // Super redundant safety check
}
// ===========================================================================
// IAppSystem methods
// ===========================================================================
bool CWebMVideoSubSystem::Connect( CreateInterfaceFn factory )
{
if ( !BaseClass::Connect( factory ) )
{
return false;
}
if ( g_pFullFileSystem == nullptr || materials == nullptr )
{
Msg( "WebM video subsystem failed to connect to missing a required system\n" );
return false;
}
return true;
}
void CWebMVideoSubSystem::Disconnect()
{
BaseClass::Disconnect();
}
void* CWebMVideoSubSystem::QueryInterface( const char *pInterfaceName )
{
if ( IS_NOT_EMPTY( pInterfaceName ) )
{
if ( V_strncmp( pInterfaceName, VIDEO_SUBSYSTEM_INTERFACE_VERSION, Q_strlen( VIDEO_SUBSYSTEM_INTERFACE_VERSION ) + 1) == STRINGS_MATCH )
{
return (IVideoSubSystem*) this;
}
}
return nullptr;
}
InitReturnVal_t CWebMVideoSubSystem::Init()
{
InitReturnVal_t nRetVal = BaseClass::Init();
if ( nRetVal != INIT_OK )
{
return nRetVal;
}
return INIT_OK;
}
void CWebMVideoSubSystem::Shutdown()
{
// Make sure we shut down WebM
ShutdownWebM();
BaseClass::Shutdown();
}
// ===========================================================================
// IVideoSubSystem identification methods
// ===========================================================================
VideoSystem_t CWebMVideoSubSystem::GetSystemID()
{
return VideoSystem::WEBM;
}
VideoSystemStatus_t CWebMVideoSubSystem::GetSystemStatus()
{
return m_CurrentStatus;
}
VideoSystemFeature_t CWebMVideoSubSystem::GetSupportedFeatures()
{
return m_AvailableFeatures;
}
const char* CWebMVideoSubSystem::GetVideoSystemName()
{
return "WebM";
}
// ===========================================================================
// IVideoSubSystem setup and shutdown services
// ===========================================================================
bool CWebMVideoSubSystem::InitializeVideoSystem( IVideoCommonServices *pCommonServices )
{
m_AvailableFeatures = DEFAULT_FEATURE_SET; // Put here because of issue with static const int, binary OR and DEBUG builds
AssertPtr( pCommonServices );
m_pCommonServices = pCommonServices;
return ( m_bWebMInitialized ) ? true : SetupWebM();
}
bool CWebMVideoSubSystem::ShutdownVideoSystem()
{
return ( m_bWebMInitialized ) ? ShutdownWebM() : true;
}
VideoResult_t CWebMVideoSubSystem::VideoSoundDeviceCMD( VideoSoundDeviceOperation_t operation, void *pDevice, void *pData )
{
switch ( operation )
{
case VideoSoundDeviceOperation::SET_DIRECT_SOUND_DEVICE:
{
return SetResult( VideoResult::OPERATION_NOT_SUPPORTED );
}
case VideoSoundDeviceOperation::SET_MILES_SOUND_DEVICE:
case VideoSoundDeviceOperation::HOOK_X_AUDIO:
{
return SetResult( VideoResult::OPERATION_NOT_SUPPORTED );
}
default:
{
return SetResult( VideoResult::UNKNOWN_OPERATION );
}
}
}
// ===========================================================================
// IVideoSubSystem supported extensions & features
// ===========================================================================
int CWebMVideoSubSystem::GetSupportedFileExtensionCount()
{
return s_WebMExtensionCount;
}
const char* CWebMVideoSubSystem::GetSupportedFileExtension( int num )
{
return ( num < 0 || num >= s_WebMExtensionCount ) ? nullptr : s_WebMExtensions[num].m_FileExtension;
}
VideoSystemFeature_t CWebMVideoSubSystem::GetSupportedFileExtensionFeatures( int num )
{
return ( num < 0 || num >= s_WebMExtensionCount ) ? VideoSystemFeature::NO_FEATURES : s_WebMExtensions[num].m_VideoFeatures;
}
// ===========================================================================
// IVideoSubSystem Video Playback and Recording Services
// ===========================================================================
VideoResult_t CWebMVideoSubSystem::PlayVideoFileFullScreen( const char *filename, void *mainWindow, int windowWidth, int windowHeight, int desktopWidth, int desktopHeight, bool windowed, float forcedMinTime, VideoPlaybackFlags_t playbackFlags )
{
return SetResult( VideoResult::FEATURE_NOT_AVAILABLE );
}
// ===========================================================================
// IVideoSubSystem Video Material Services
// note that the filename is absolute and has already resolved any paths
// ===========================================================================
IVideoMaterial* CWebMVideoSubSystem::CreateVideoMaterial( const char *pMaterialName, const char *pVideoFileName, VideoPlaybackFlags_t flags )
{
SetResult( VideoResult::FEATURE_NOT_AVAILABLE );
return NULL;
}
VideoResult_t CWebMVideoSubSystem::DestroyVideoMaterial( IVideoMaterial *pVideoMaterial )
{
return SetResult (VideoResult::FEATURE_NOT_AVAILABLE );
}
// ===========================================================================
// IVideoSubSystem Video Recorder Services
// ===========================================================================
IVideoRecorder* CWebMVideoSubSystem::CreateVideoRecorder()
{
SetResult( VideoResult::SYSTEM_NOT_AVAILABLE );
AssertExitN( m_CurrentStatus == VideoSystemStatus::OK );
CWebMVideoRecorder *pVideoRecorder = new CWebMVideoRecorder();
if ( pVideoRecorder != nullptr )
{
IVideoRecorder *pInterface = (IVideoRecorder*) pVideoRecorder;
m_RecorderList.AddToTail( pInterface );
SetResult( VideoResult::SUCCESS );
return pInterface;
}
SetResult( VideoResult::VIDEO_ERROR_OCCURED );
return nullptr;
}
VideoResult_t CWebMVideoSubSystem::DestroyVideoRecorder( IVideoRecorder *pRecorder )
{
AssertExitV( m_CurrentStatus == VideoSystemStatus::OK, SetResult( VideoResult::SYSTEM_NOT_AVAILABLE ) );
AssertPtrExitV( pRecorder, SetResult( VideoResult::BAD_INPUT_PARAMETERS ) );
if ( m_RecorderList.Find( pRecorder ) != -1 )
{
CWebMVideoRecorder *pVideoRecorder = (CWebMVideoRecorder*) pRecorder;
delete pVideoRecorder;
m_RecorderList.FindAndFastRemove( pRecorder );
return SetResult( VideoResult::SUCCESS );
}
return SetResult( VideoResult::RECORDER_NOT_FOUND );
}
VideoResult_t CWebMVideoSubSystem::CheckCodecAvailability( VideoEncodeCodec_t codec )
{
AssertExitV( m_CurrentStatus == VideoSystemStatus::OK, SetResult( VideoResult::SYSTEM_NOT_AVAILABLE ) );
AssertExitV( codec >= VideoEncodeCodec::DEFAULT_CODEC && codec < VideoEncodeCodec::CODEC_COUNT, SetResult( VideoResult::BAD_INPUT_PARAMETERS ) );
return SetResult( VideoResult::FEATURE_NOT_AVAILABLE );
}
// ===========================================================================
// Status support
// ===========================================================================
VideoResult_t CWebMVideoSubSystem::GetLastResult()
{
return m_LastResult;
}
VideoResult_t CWebMVideoSubSystem::SetResult( VideoResult_t status )
{
m_LastResult = status;
return status;
}
// ===========================================================================
// WebM Initialization & Shutdown
// ===========================================================================
bool CWebMVideoSubSystem::SetupWebM()
{
SetResult( VideoResult::INITIALIZATION_ERROR_OCCURED);
AssertExitF( m_bWebMInitialized == false );
// This is set early to indicate we have already been through here, even if we error out for some reason
m_bWebMInitialized = true;
m_CurrentStatus = VideoSystemStatus::OK;
m_AvailableFeatures = DEFAULT_FEATURE_SET;
// $$INIT CODE HERE$$
// Note that we are now open for business....
m_bWebMInitialized = true;
SetResult( VideoResult::SUCCESS );
return true;
}
bool CWebMVideoSubSystem::ShutdownWebM()
{
if ( m_bWebMInitialized && m_CurrentStatus == VideoSystemStatus::OK )
{
}
m_bWebMInitialized = false;
m_CurrentStatus = VideoSystemStatus::NOT_INITIALIZED;
m_AvailableFeatures = VideoSystemFeature::NO_FEATURES;
SetResult( VideoResult::SUCCESS );
return true;
}