wmvcodec.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. #ifndef _XBOX
  2. #include "wmvcodec.h"
  3. // обращение к выделению памяти через движок
  4. void * _cdecl IWMVMemoryManager::CoreAlloc(size_t size) {
  5. return api->Reallocate(0,size,_FL_);
  6. }
  7. void _cdecl IWMVMemoryManager::CoreFree(void * ptr) {
  8. api->Free(ptr,_FL_);
  9. }
  10. // вывод лога через движок
  11. void IWMVMemoryManager::LogTrace(const char* pcText) {
  12. api->Trace("%s", pcText);
  13. }
  14. // установленная в движке громкость звука
  15. float IWMVMemoryManager::GetVolume()
  16. {
  17. float fGlobVol = api->Storage().GetFloat("Options.GlobalVolume",1.f);
  18. float fFXVol = api->Storage().GetFloat("Options.FxVolume",1.f);
  19. return powf(fGlobVol * fFXVol, 0.4f);
  20. }
  21. // класс обертка для текстуры
  22. // используется как в движковом рендере, так и для работы видеокодека
  23. // свопит для использования две текстуры: пока одна заполняется видеокодеком, другая выводиться в рендер движка
  24. class WMVTexture : public IWMVTexture
  25. {
  26. CritSection critSect;
  27. int nUseIdx;
  28. int nRefCount;
  29. bool bReady;
  30. RENDERLOCKED_RECT lr;
  31. public:
  32. WMVTexture()
  33. {
  34. m_pTexture[0] = m_pTexture[1] = 0;
  35. nUseIdx = 0;
  36. nRefCount = 1;
  37. bReady = false;
  38. lr.pBits = NULL;
  39. }
  40. virtual void Release() {
  41. if(--nRefCount <= 0) delete this;
  42. }
  43. void AddRef() {
  44. nRefCount++;
  45. }
  46. // лочится текстура из видеокодека
  47. virtual bool Lock(void* &pTxtBuffer, int &lTxtPitch)
  48. {
  49. // see free texture
  50. int n = 1 - nUseIdx;
  51. if( !m_pTexture[n] )
  52. {
  53. return false;
  54. }
  55. if( !m_pTexture[n]->LockRect(0,&lr,null,LOCK_DISCARD) )
  56. {
  57. return false;
  58. }
  59. AddRef();
  60. pTxtBuffer = lr.pBits;
  61. lTxtPitch = lr.Pitch;
  62. return true;
  63. }
  64. // анлочится текстура в видеокодеке
  65. virtual void Unlock()
  66. {
  67. bReady = true;
  68. int n = 1 - nUseIdx;
  69. if(m_pTexture[n]) {
  70. m_pTexture[n]->UnlockRect(0);
  71. }
  72. critSect.Enter();
  73. nUseIdx = n;
  74. critSect.Leave();
  75. Release();
  76. }
  77. // включить использование текстуры (используется в рендере видео)
  78. ITexture* UsageTexture(bool use)
  79. {
  80. if( !bReady )
  81. return null;
  82. // начать использование (входим в крит секцию)
  83. if( use )
  84. {
  85. critSect.Enter();
  86. return m_pTexture[nUseIdx];
  87. }
  88. // закончить использование (выходим из крит секции)
  89. else
  90. {
  91. critSect.Leave();
  92. return null;
  93. }
  94. }
  95. static IRender* render;
  96. static WMVCodec* codec;
  97. static IFileService* pFileService;
  98. ITexture* m_pTexture[2];
  99. protected:
  100. virtual ~WMVTexture()
  101. {
  102. RELEASE(m_pTexture[0]);
  103. RELEASE(m_pTexture[1]);
  104. }
  105. };
  106. IRender* WMVTexture::render = NULL;
  107. WMVCodec* WMVTexture::codec = NULL;
  108. IFileService* WMVTexture::pFileService = NULL;
  109. IWMVTexture* IWMVTexture::Create(unsigned int& w, unsigned int& h)
  110. {
  111. if( !WMVTexture::render ) return NULL;
  112. if( !WMVTexture::codec ) return NULL;
  113. WMVTexture* pTexture = NEW WMVTexture();
  114. if( !pTexture ) return NULL;
  115. pTexture->m_pTexture[0] = WMVTexture::render->CreateTexture( w, h, 1, USAGE_DYNAMIC, FMT_L8, _FL_, POOL_DEFAULT );
  116. pTexture->m_pTexture[1] = WMVTexture::render->CreateTexture( w, h, 1, USAGE_DYNAMIC, FMT_L8, _FL_, POOL_DEFAULT );
  117. WMVTexture::codec->SetWMVTexture(pTexture);
  118. return pTexture;
  119. }
  120. void WMVCodec::SetWMVTexture(WMVTexture* pTex)
  121. {
  122. RELEASE( pWMVTexture );
  123. pWMVTexture = pTex;
  124. if( pTex ) pTex->AddRef();
  125. }
  126. WMVCodec::WMVCodec(IRender* _pRender) : IVideoCodec(_pRender)
  127. {
  128. shaderID = NULL;
  129. textureVar = NULL;
  130. WMVTexture::render = _pRender;
  131. WMVTexture::pFileService = (IFileService*)api->GetService("FileService");
  132. m_bLoopPlay = false;
  133. bMakeUninitializeDD = false;
  134. m_pGraph = NULL;
  135. pWMVTexture = NULL;
  136. Init();
  137. }
  138. WMVCodec::~WMVCodec()
  139. {
  140. Release();
  141. }
  142. bool WMVCodec::OpenFile(const char* pcVideoFile,bool bLoopPlay)
  143. {
  144. CloseFile();
  145. DELETE(m_pGraph);
  146. m_bLoopPlay = bLoopPlay;
  147. RELEASE( pWMVTexture );
  148. WMVTexture::codec = this;
  149. m_pGraph = IWMVGraph::CreateWMVGraphInstance();
  150. Assert(m_pGraph);
  151. if( WMVTexture::pFileService && WMVTexture::pFileService->SystemIni() )
  152. {
  153. if( WMVTexture::pFileService->SystemIni()->GetLong("sound","off",0) == 1 )
  154. m_pGraph->SoundOff(true);
  155. }
  156. if( !m_pGraph->OpenFile(pcVideoFile) )
  157. {
  158. DELETE(m_pGraph);
  159. WMVTexture::codec = null;
  160. return false;
  161. }
  162. // ok return
  163. IVideoCodec::OpenFile(pcVideoFile,bLoopPlay);
  164. //Play();
  165. WMVTexture::codec = null;
  166. return true;
  167. }
  168. bool WMVCodec::Frame(bool bPause)
  169. {
  170. if( !IVideoCodec::Frame(bPause) ) return false;
  171. if( IsSystemPause() )
  172. bPause = true;
  173. if( bPause != this->bPause )
  174. {
  175. this->bPause = bPause;
  176. if( m_pGraph )
  177. if(bPause)
  178. m_pGraph->Stop();
  179. else
  180. m_pGraph->Play();
  181. }
  182. if( m_pGraph && m_pGraph->IsFinish() && !bPause )
  183. {
  184. if( m_bLoopPlay )
  185. m_pGraph->Restart();
  186. else
  187. {
  188. Stop();
  189. return IsProcessed();
  190. }
  191. }
  192. if( pWMVTexture )
  193. {
  194. ITexture* pTexture = pWMVTexture->UsageTexture(true);
  195. if( pTexture )
  196. {
  197. IRender* pRS = GetRender();
  198. textureVar->SetTexture(pTexture);
  199. pRS->DrawPrimitiveUP(shaderID, PT_TRIANGLESTRIP, 2, pVideoVertex, sizeof(VideoVertex));
  200. }
  201. pWMVTexture->UsageTexture(false);
  202. }
  203. return IsProcessed();
  204. }
  205. void WMVCodec::CloseFile()
  206. {
  207. if( m_pGraph )
  208. m_pGraph->CloseFile();
  209. IVideoCodec::CloseFile();
  210. }
  211. void WMVCodec::SetViewPosition(float fx, float fy, float fw, float fh, bool bModifyAspect)
  212. {
  213. IRender* pRS = GetRender();
  214. float fWidthMultipler = 1.f;
  215. float fHeightMultipler = 1.f;
  216. float cx = (float)pRS->GetFullScreenViewPort_2D().Width;
  217. float cy = (float)pRS->GetFullScreenViewPort_2D().Height;
  218. float scr_aspect = cx / cy;
  219. const float def_aspect = 16.0f / 9.0f;
  220. fWidthMultipler = def_aspect / scr_aspect * pRS->GetWideScreenAspectWidthMultipler();
  221. if( !bModifyAspect )
  222. {
  223. if( fWidthMultipler > 1.f )
  224. {
  225. fHeightMultipler = 1.f / fWidthMultipler;
  226. fWidthMultipler = 1.f;
  227. }
  228. }
  229. float HalfPixelSizeX = 1.0f / (float)pRS->GetScreenInfo2D().dwWidth;
  230. float HalfPixelSizeY = 1.0f / (float)pRS->GetScreenInfo2D().dwHeight;
  231. //Находим границы для рисования...
  232. float fl = (fx * 2.f - 1.f - HalfPixelSizeX) * fWidthMultipler;
  233. float fr = fl + fw * 2.f * fWidthMultipler;
  234. float ft = (1.f - fy * 2.f - HalfPixelSizeY) * fHeightMultipler;
  235. float fb = ft - fh * 2.f * fHeightMultipler;
  236. pVideoVertex[2].vPos = Vector (fl, fb, 1.0f);
  237. pVideoVertex[0].vPos = Vector (fr, fb, 1.0f);
  238. pVideoVertex[1].vPos = Vector (fr, ft, 1.0f);
  239. pVideoVertex[3].vPos = Vector (fl, ft, 1.0f);
  240. }
  241. void WMVCodec::Stop()
  242. {
  243. if(m_pGraph)
  244. m_pGraph->Stop();
  245. IVideoCodec::Stop();
  246. }
  247. void WMVCodec::Pause(bool bPause)
  248. {
  249. IVideoCodec::Pause(bPause);
  250. }
  251. bool WMVCodec::Init()
  252. {
  253. IRender* pRS = GetRender();
  254. pRS->GetShaderId("VideoSprite", shaderID);
  255. textureVar = pRS->GetTechniqueGlobalVariable("VideoTex", _FL_);
  256. pVideoVertex[2].vPos = Vector (0.5f, 1.0f, 0.0f);
  257. pVideoVertex[0].vPos = Vector (1.0f, 1.0f, 0.0f);
  258. pVideoVertex[1].vPos = Vector (1.0f, 0.5f, 0.0f);
  259. pVideoVertex[3].vPos = Vector (0.5f, 0.5f, 0.0f);
  260. pVideoVertex[2].tu = 0.0f; pVideoVertex[2].tv = 0.0f;
  261. pVideoVertex[0].tu = 1.0f; pVideoVertex[0].tv = 0.0f;
  262. pVideoVertex[1].tu = 1.0f; pVideoVertex[1].tv = 1.0f;
  263. pVideoVertex[3].tu = 0.0f; pVideoVertex[3].tv = 1.0f;
  264. HRESULT hr = S_OK;
  265. if (FAILED(hr = CoInitialize(NULL)))
  266. return false;
  267. bMakeUninitializeDD = true;
  268. return true;
  269. }
  270. void WMVCodec::Release()
  271. {
  272. CloseFile();
  273. DELETE(m_pGraph);
  274. RELEASE(pWMVTexture);
  275. if( bMakeUninitializeDD ) CoUninitialize();
  276. bMakeUninitializeDD = false;
  277. }
  278. void WMVCodec::Play()
  279. {
  280. if( m_pGraph )
  281. m_pGraph->Play();
  282. }
  283. #endif