Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

353 lines
9.8 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "webm_video.h"
  7. #include "webm_recorder.h"
  8. #include "filesystem.h"
  9. #include "tier0/icommandline.h"
  10. #include "tier1/strtools.h"
  11. #include "tier1/utllinkedlist.h"
  12. #include "tier1/KeyValues.h"
  13. #include "materialsystem/imaterial.h"
  14. #include "materialsystem/imaterialsystem.h"
  15. #include "materialsystem/MaterialSystemUtil.h"
  16. #include "materialsystem/itexture.h"
  17. #include "vtf/vtf.h"
  18. #include "pixelwriter.h"
  19. #include "tier2/tier2.h"
  20. #include "platform.h"
  21. #include "tier0/memdbgon.h"
  22. // ===========================================================================
  23. // Singleton to expose WebM video subsystem
  24. // ===========================================================================
  25. static CWebMVideoSubSystem g_WebMSystem;
  26. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CWebMVideoSubSystem, IVideoSubSystem, VIDEO_SUBSYSTEM_INTERFACE_VERSION, g_WebMSystem );
  27. // ===========================================================================
  28. // List of file extensions and features supported by this subsystem
  29. // ===========================================================================
  30. VideoFileExtensionInfo_t s_WebMExtensions[] =
  31. {
  32. { ".webm", VideoSystem::WEBM, VideoSystemFeature::FULL_ENCODE },
  33. };
  34. const int s_WebMExtensionCount = ARRAYSIZE( s_WebMExtensions );
  35. const VideoSystemFeature_t CWebMVideoSubSystem::DEFAULT_FEATURE_SET = VideoSystemFeature::FULL_ENCODE;
  36. // ===========================================================================
  37. // CWebMVideoSubSystem class
  38. // ===========================================================================
  39. CWebMVideoSubSystem::CWebMVideoSubSystem() :
  40. m_bWebMInitialized( false ),
  41. m_LastResult( VideoResult::SUCCESS ),
  42. m_CurrentStatus( VideoSystemStatus::NOT_INITIALIZED ),
  43. m_AvailableFeatures( CWebMVideoSubSystem::DEFAULT_FEATURE_SET ),
  44. m_pCommonServices( nullptr )
  45. {
  46. }
  47. CWebMVideoSubSystem::~CWebMVideoSubSystem()
  48. {
  49. ShutdownWebM(); // Super redundant safety check
  50. }
  51. // ===========================================================================
  52. // IAppSystem methods
  53. // ===========================================================================
  54. bool CWebMVideoSubSystem::Connect( CreateInterfaceFn factory )
  55. {
  56. if ( !BaseClass::Connect( factory ) )
  57. {
  58. return false;
  59. }
  60. if ( g_pFullFileSystem == nullptr || materials == nullptr )
  61. {
  62. Msg( "WebM video subsystem failed to connect to missing a required system\n" );
  63. return false;
  64. }
  65. return true;
  66. }
  67. void CWebMVideoSubSystem::Disconnect()
  68. {
  69. BaseClass::Disconnect();
  70. }
  71. void* CWebMVideoSubSystem::QueryInterface( const char *pInterfaceName )
  72. {
  73. if ( IS_NOT_EMPTY( pInterfaceName ) )
  74. {
  75. if ( V_strncmp( pInterfaceName, VIDEO_SUBSYSTEM_INTERFACE_VERSION, Q_strlen( VIDEO_SUBSYSTEM_INTERFACE_VERSION ) + 1) == STRINGS_MATCH )
  76. {
  77. return (IVideoSubSystem*) this;
  78. }
  79. }
  80. return nullptr;
  81. }
  82. InitReturnVal_t CWebMVideoSubSystem::Init()
  83. {
  84. InitReturnVal_t nRetVal = BaseClass::Init();
  85. if ( nRetVal != INIT_OK )
  86. {
  87. return nRetVal;
  88. }
  89. return INIT_OK;
  90. }
  91. void CWebMVideoSubSystem::Shutdown()
  92. {
  93. // Make sure we shut down WebM
  94. ShutdownWebM();
  95. BaseClass::Shutdown();
  96. }
  97. // ===========================================================================
  98. // IVideoSubSystem identification methods
  99. // ===========================================================================
  100. VideoSystem_t CWebMVideoSubSystem::GetSystemID()
  101. {
  102. return VideoSystem::WEBM;
  103. }
  104. VideoSystemStatus_t CWebMVideoSubSystem::GetSystemStatus()
  105. {
  106. return m_CurrentStatus;
  107. }
  108. VideoSystemFeature_t CWebMVideoSubSystem::GetSupportedFeatures()
  109. {
  110. return m_AvailableFeatures;
  111. }
  112. const char* CWebMVideoSubSystem::GetVideoSystemName()
  113. {
  114. return "WebM";
  115. }
  116. // ===========================================================================
  117. // IVideoSubSystem setup and shutdown services
  118. // ===========================================================================
  119. bool CWebMVideoSubSystem::InitializeVideoSystem( IVideoCommonServices *pCommonServices )
  120. {
  121. m_AvailableFeatures = DEFAULT_FEATURE_SET; // Put here because of issue with static const int, binary OR and DEBUG builds
  122. AssertPtr( pCommonServices );
  123. m_pCommonServices = pCommonServices;
  124. return ( m_bWebMInitialized ) ? true : SetupWebM();
  125. }
  126. bool CWebMVideoSubSystem::ShutdownVideoSystem()
  127. {
  128. return ( m_bWebMInitialized ) ? ShutdownWebM() : true;
  129. }
  130. VideoResult_t CWebMVideoSubSystem::VideoSoundDeviceCMD( VideoSoundDeviceOperation_t operation, void *pDevice, void *pData )
  131. {
  132. switch ( operation )
  133. {
  134. case VideoSoundDeviceOperation::SET_DIRECT_SOUND_DEVICE:
  135. {
  136. return SetResult( VideoResult::OPERATION_NOT_SUPPORTED );
  137. }
  138. case VideoSoundDeviceOperation::SET_MILES_SOUND_DEVICE:
  139. case VideoSoundDeviceOperation::HOOK_X_AUDIO:
  140. {
  141. return SetResult( VideoResult::OPERATION_NOT_SUPPORTED );
  142. }
  143. default:
  144. {
  145. return SetResult( VideoResult::UNKNOWN_OPERATION );
  146. }
  147. }
  148. }
  149. // ===========================================================================
  150. // IVideoSubSystem supported extensions & features
  151. // ===========================================================================
  152. int CWebMVideoSubSystem::GetSupportedFileExtensionCount()
  153. {
  154. return s_WebMExtensionCount;
  155. }
  156. const char* CWebMVideoSubSystem::GetSupportedFileExtension( int num )
  157. {
  158. return ( num < 0 || num >= s_WebMExtensionCount ) ? nullptr : s_WebMExtensions[num].m_FileExtension;
  159. }
  160. VideoSystemFeature_t CWebMVideoSubSystem::GetSupportedFileExtensionFeatures( int num )
  161. {
  162. return ( num < 0 || num >= s_WebMExtensionCount ) ? VideoSystemFeature::NO_FEATURES : s_WebMExtensions[num].m_VideoFeatures;
  163. }
  164. // ===========================================================================
  165. // IVideoSubSystem Video Playback and Recording Services
  166. // ===========================================================================
  167. VideoResult_t CWebMVideoSubSystem::PlayVideoFileFullScreen( const char *filename, void *mainWindow, int windowWidth, int windowHeight, int desktopWidth, int desktopHeight, bool windowed, float forcedMinTime, VideoPlaybackFlags_t playbackFlags )
  168. {
  169. return SetResult( VideoResult::FEATURE_NOT_AVAILABLE );
  170. }
  171. // ===========================================================================
  172. // IVideoSubSystem Video Material Services
  173. // note that the filename is absolute and has already resolved any paths
  174. // ===========================================================================
  175. IVideoMaterial* CWebMVideoSubSystem::CreateVideoMaterial( const char *pMaterialName, const char *pVideoFileName, VideoPlaybackFlags_t flags )
  176. {
  177. SetResult( VideoResult::FEATURE_NOT_AVAILABLE );
  178. return NULL;
  179. }
  180. VideoResult_t CWebMVideoSubSystem::DestroyVideoMaterial( IVideoMaterial *pVideoMaterial )
  181. {
  182. return SetResult (VideoResult::FEATURE_NOT_AVAILABLE );
  183. }
  184. // ===========================================================================
  185. // IVideoSubSystem Video Recorder Services
  186. // ===========================================================================
  187. IVideoRecorder* CWebMVideoSubSystem::CreateVideoRecorder()
  188. {
  189. SetResult( VideoResult::SYSTEM_NOT_AVAILABLE );
  190. AssertExitN( m_CurrentStatus == VideoSystemStatus::OK );
  191. CWebMVideoRecorder *pVideoRecorder = new CWebMVideoRecorder();
  192. if ( pVideoRecorder != nullptr )
  193. {
  194. IVideoRecorder *pInterface = (IVideoRecorder*) pVideoRecorder;
  195. m_RecorderList.AddToTail( pInterface );
  196. SetResult( VideoResult::SUCCESS );
  197. return pInterface;
  198. }
  199. SetResult( VideoResult::VIDEO_ERROR_OCCURED );
  200. return nullptr;
  201. }
  202. VideoResult_t CWebMVideoSubSystem::DestroyVideoRecorder( IVideoRecorder *pRecorder )
  203. {
  204. AssertExitV( m_CurrentStatus == VideoSystemStatus::OK, SetResult( VideoResult::SYSTEM_NOT_AVAILABLE ) );
  205. AssertPtrExitV( pRecorder, SetResult( VideoResult::BAD_INPUT_PARAMETERS ) );
  206. if ( m_RecorderList.Find( pRecorder ) != -1 )
  207. {
  208. CWebMVideoRecorder *pVideoRecorder = (CWebMVideoRecorder*) pRecorder;
  209. delete pVideoRecorder;
  210. m_RecorderList.FindAndFastRemove( pRecorder );
  211. return SetResult( VideoResult::SUCCESS );
  212. }
  213. return SetResult( VideoResult::RECORDER_NOT_FOUND );
  214. }
  215. VideoResult_t CWebMVideoSubSystem::CheckCodecAvailability( VideoEncodeCodec_t codec )
  216. {
  217. AssertExitV( m_CurrentStatus == VideoSystemStatus::OK, SetResult( VideoResult::SYSTEM_NOT_AVAILABLE ) );
  218. AssertExitV( codec >= VideoEncodeCodec::DEFAULT_CODEC && codec < VideoEncodeCodec::CODEC_COUNT, SetResult( VideoResult::BAD_INPUT_PARAMETERS ) );
  219. return SetResult( VideoResult::FEATURE_NOT_AVAILABLE );
  220. }
  221. // ===========================================================================
  222. // Status support
  223. // ===========================================================================
  224. VideoResult_t CWebMVideoSubSystem::GetLastResult()
  225. {
  226. return m_LastResult;
  227. }
  228. VideoResult_t CWebMVideoSubSystem::SetResult( VideoResult_t status )
  229. {
  230. m_LastResult = status;
  231. return status;
  232. }
  233. // ===========================================================================
  234. // WebM Initialization & Shutdown
  235. // ===========================================================================
  236. bool CWebMVideoSubSystem::SetupWebM()
  237. {
  238. SetResult( VideoResult::INITIALIZATION_ERROR_OCCURED);
  239. AssertExitF( m_bWebMInitialized == false );
  240. // This is set early to indicate we have already been through here, even if we error out for some reason
  241. m_bWebMInitialized = true;
  242. m_CurrentStatus = VideoSystemStatus::OK;
  243. m_AvailableFeatures = DEFAULT_FEATURE_SET;
  244. // $$INIT CODE HERE$$
  245. // Note that we are now open for business....
  246. m_bWebMInitialized = true;
  247. SetResult( VideoResult::SUCCESS );
  248. return true;
  249. }
  250. bool CWebMVideoSubSystem::ShutdownWebM()
  251. {
  252. if ( m_bWebMInitialized && m_CurrentStatus == VideoSystemStatus::OK )
  253. {
  254. }
  255. m_bWebMInitialized = false;
  256. m_CurrentStatus = VideoSystemStatus::NOT_INITIALIZED;
  257. m_AvailableFeatures = VideoSystemFeature::NO_FEATURES;
  258. SetResult( VideoResult::SUCCESS );
  259. return true;
  260. }