Counter Strike : Global Offensive Source Code
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.

251 lines
7.7 KiB

  1. //========= Copyright (c), Valve Corporation, All rights reserved. ============//
  2. #ifndef HLTV_BROADCAST_PLAYER_HDR
  3. #define HLTV_BROADCAST_PLAYER_HDR
  4. #include "tier1/utlincrementalvector.h"
  5. #include "steam/steam_api.h"
  6. #include "steam/isteamhttp.h"
  7. #include "tier1/utlhashtable.h"
  8. #include "tier1/smartptr.h"
  9. #include "demostream.h"
  10. #include "demofile/gotvhttpstream.h"
  11. struct HTTPRequestCompleted_t;
  12. class CDemoStreamHttp: public IDemoStream
  13. {
  14. public:
  15. CDemoStreamHttp();
  16. void SetClient( IDemoStreamClient *pClient ) { m_pClient = pClient; }
  17. struct SyncParams_t
  18. {
  19. SyncParams_t(int nStartFragment = 0) :m_nStartFragment( nStartFragment ){}
  20. int m_nStartFragment;
  21. void PrintSyncRequest(char *buffer, int nBufSize ) const;
  22. };
  23. void StartStreaming( const char *pUrl, SyncParams_t syncParams = SyncParams_t() );
  24. void StartStreamingCached( const char *pUrl, int nFragment = 1);
  25. bool PrepareForStreaming( const char * pUrl );
  26. void SendSync( int nResync = 0 );
  27. bool OnEngineGotvSyncPacket( const CEngineGotvSyncPacket *pPkt );
  28. void StopStreaming();
  29. bool IsIdle()const { return m_nState == STATE_IDLE; }
  30. void Resync( );
  31. void Update();
  32. virtual const char* GetUrl( void ) OVERRIDE { return m_Url.Get(); }
  33. virtual float GetTicksPerSecond( void )OVERRIDE { return m_SyncResponse.flTicksPerSecond; }
  34. int GetDemoProtocol()const { return m_nDemoProtocol; }
  35. virtual float GetTicksPerFrame( void ) OVERRIDE { return 1.0f; } // 1 network frame per 1 tick in broadcast - there's not much reason to do otherwise
  36. virtual void Close() OVERRIDE { StopStreaming(); }
  37. virtual int GetTotalTicks( void ) { return 0; }
  38. enum FragmentTypeEnum_t
  39. {
  40. //FRAGMENT_START,
  41. FRAGMENT_DELTA,
  42. FRAGMENT_FULL,
  43. FRAGMENT_COUNT
  44. };
  45. static const char *FragmentTypeToString( FragmentTypeEnum_t nType );
  46. static const char *AsString( FragmentTypeEnum_t nType ){ return nType == FRAGMENT_DELTA ? "delta" : "full"; }
  47. struct Buffer_t
  48. {
  49. Buffer_t()
  50. {
  51. m_nRefCount = 0;
  52. m_nSize = 0;
  53. }
  54. static void AddRef( Buffer_t *pObj )
  55. {
  56. pObj->m_nRefCount++;
  57. }
  58. static void Release( Buffer_t *pObj )
  59. {
  60. if ( 0 == --pObj->m_nRefCount )
  61. {
  62. delete[]( uint8* )pObj;
  63. }
  64. }
  65. uint m_nRefCount;
  66. uint m_nSize;
  67. uint8 *Base() { return ( uint8* )( this + 1 ); }
  68. uint8 *End() { return Base() + m_nSize; }
  69. };
  70. typedef CSmartPtr< Buffer_t, Buffer_t > BufferRef;
  71. Buffer_t *GetStreamSignupBuffer() { return m_pStreamSignup.GetObject(); }
  72. Buffer_t *GetFragmentBuffer( int nFragment, FragmentTypeEnum_t nFragmentType );
  73. void RequestFragment( int nFragment, FragmentTypeEnum_t nType );
  74. void ReleaseFragment( int nFragment );
  75. static GotvHttpStreamId_t GetStreamId( const char *pUrl );
  76. float GetBroadcastKeyframeInterval() const { return m_flBroadcastKeyframeInterval; }
  77. IDemoStreamClient::DemoStreamReference_t GetStreamStartReference( bool bLagCompensation = false );
  78. void BeginBuffering( int nFragment );
  79. protected:
  80. struct SyncResponse_t
  81. {
  82. int nStartTick ;
  83. float flKeyframeInterval;
  84. float flRealTimeDelay ;
  85. float flReceiveAge;
  86. int nFragment ;
  87. int nSignupFragment;
  88. float flTicksPerSecond;
  89. double dPlatTimeReceived;
  90. };
  91. bool OnSync( int nResync );
  92. void OnStart( HTTPRequestHandle hRequest );
  93. void OnFragmentRequestSuccess( HTTPRequestHandle hRequest, int nFragment, FragmentTypeEnum_t nType );
  94. void OnFragmentRequestFailure( EHTTPStatusCode nErrorCode, int nFragment, FragmentTypeEnum_t nType );
  95. bool OnSync( const char *pBuffer, int nBufferSize, int nResync );
  96. void RequestDeltaFrame( int nFragment );
  97. protected:
  98. typedef void( CDemoStreamHttp::*FnHttpCallback )( const HTTPRequestCompleted_t * pResponse );
  99. class CPendingRequest : public CCallbackBase
  100. {
  101. public:
  102. CPendingRequest( );
  103. void Init( CDemoStreamHttp *pParent, HTTPRequestHandle hRequest, SteamAPICall_t hCall );
  104. virtual void Run( void *pvParam ) OVERRIDE; // success; HTTPRequestCompleted_t
  105. virtual void Run( void *pvParam, bool bIOFailure, SteamAPICall_t hSteamAPICall ) OVERRIDE; // result; HTTPRequestCompleted_t
  106. void Cancel();
  107. virtual void OnSuccess( const HTTPRequestCompleted_t * pResponse ) = 0;
  108. virtual void OnFailure( const HTTPRequestCompleted_t * pResponse );
  109. public:
  110. int m_nIncrementalVectorIndex;
  111. protected:
  112. ~CPendingRequest(); // only this object can delete itself
  113. virtual int GetCallbackSizeBytes() OVERRIDE { return sizeof( HTTPRequestCompleted_t ); }
  114. CDemoStreamHttp *m_pParent;
  115. HTTPRequestHandle m_hRequest;
  116. SteamAPICall_t m_hCall;
  117. };
  118. friend class CPendingRequest;
  119. class CSyncRequest : public CPendingRequest
  120. {
  121. int m_nResync;
  122. SyncParams_t m_SyncParams;
  123. public:
  124. CSyncRequest( SyncParams_t syncParams, int nResync = 0 ) : m_nResync( nResync ), m_SyncParams( syncParams ) { }
  125. virtual void OnSuccess( const HTTPRequestCompleted_t * pResponse ) OVERRIDE;
  126. virtual void OnFailure( const HTTPRequestCompleted_t * pResponse ) OVERRIDE;
  127. };
  128. class CStartRequest : public CPendingRequest
  129. {
  130. public:
  131. virtual void OnSuccess( const HTTPRequestCompleted_t * pResponse ) OVERRIDE;
  132. //virtual void OnFailure( const HTTPRequestCompleted_t * pResponse ) OVERRIDE;
  133. };
  134. class CFragmentRequest : public CPendingRequest
  135. {
  136. int m_nFragment;
  137. FragmentTypeEnum_t m_nType;
  138. public:
  139. CFragmentRequest( int nFragment , FragmentTypeEnum_t nType ) : m_nFragment( nFragment ), m_nType ( nType ){}
  140. virtual void OnSuccess( const HTTPRequestCompleted_t * pResponse ) OVERRIDE;
  141. virtual void OnFailure( const HTTPRequestCompleted_t * pResponse ) OVERRIDE;
  142. };
  143. enum StateEnum_t
  144. {
  145. STATE_IDLE,
  146. STATE_SYNC,
  147. STATE_RANDOM_WAIT_AND_SYNC,
  148. STATE_START,
  149. STATE_STREAMING
  150. };
  151. static Buffer_t *MakeBuffer( HTTPRequestHandle hRequest ); // returns a buffer with 0 refcount
  152. struct Fragment_t
  153. {
  154. protected:
  155. Buffer_t *m_pField[ FRAGMENT_COUNT ];
  156. uint m_nStreaming;
  157. public:
  158. Fragment_t()
  159. {
  160. for ( int i = 0; i < FRAGMENT_COUNT; ++i )
  161. m_pField[ i ] = NULL;
  162. m_nStreaming = 0;
  163. }
  164. void ResetBuffers();
  165. //const uint8 *Start() const { return pField[ FRAGMENT_START ] ? pField[ FRAGMENT_START ]->Base() : NULL; }
  166. //uint StartSize()const { return pField[ FRAGMENT_START ] ? pField[ FRAGMENT_START ]->nSize : 0; }
  167. void SetField( FragmentTypeEnum_t nFragment, Buffer_t *pBuffer );
  168. Buffer_t *GetField( FragmentTypeEnum_t nFragment ) { return m_pField[ nFragment ]; }
  169. const uint8 *Delta() const { return m_pField[ FRAGMENT_DELTA ] ? m_pField[ FRAGMENT_DELTA ]->Base() : NULL; }
  170. uint DeltaSize()const { return m_pField[ FRAGMENT_DELTA ] ? m_pField[ FRAGMENT_DELTA ]->m_nSize : 0; }
  171. const uint8 *Full() const { return m_pField[ FRAGMENT_FULL ] ? m_pField[ FRAGMENT_FULL ]->Base() : NULL; }
  172. uint FullSize()const { return m_pField[ FRAGMENT_FULL ] ? m_pField[ FRAGMENT_FULL ]->m_nSize : 0; }
  173. uint IsStreaming( FragmentTypeEnum_t nType ){ return ( m_nStreaming >> nType ) & 1; }
  174. void SetStreaming( FragmentTypeEnum_t nType ){ m_nStreaming |= ( 1 << nType ); }
  175. void ClearStreaming( FragmentTypeEnum_t nType ){ m_nStreaming &= ~( 1 << nType ); }
  176. };
  177. protected:
  178. void SendGet( const char *pPath, CPendingRequest *pRequest );
  179. Fragment_t &Fragment( int nFragment );
  180. protected:
  181. CUtlString m_Url;
  182. bool m_bSyncFromGc;
  183. CUtlIncrementalVector< CPendingRequest > m_PendingRequests;
  184. StateEnum_t m_nState;
  185. BufferRef m_pStreamSignup;
  186. int m_nStreamSignupFragment; // the fragment where the signup/start fragment starts
  187. int m_nDemoProtocol;
  188. IDemoStreamClient *m_pClient;
  189. CUtlHashtable< int, Fragment_t, IdentityHashFunctor > m_FragmentCache; // TODO: implement freeing old buffers
  190. // STATE_SYNC : when to stop streaming
  191. // STATE_RANDOM_WAIT_AND_SYNC: when to retry sync
  192. double m_dSyncTimeoutEnd;
  193. SyncParams_t m_SyncParams;
  194. SyncResponse_t m_SyncResponse;
  195. float m_flBroadcastKeyframeInterval;
  196. //int m_nFragment;
  197. };
  198. #endif // HLTV_BROADCAST_PLAYER_HDR