Avi.cpp
上传用户:cydong117
上传日期:2009-11-10
资源大小:638k
文件大小:12k
源码类别:

模拟服务器

开发平台:

Visual C++

  1. #include "StdAfx.h"
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // CAvi Constructor
  4. //////////////////////////////////////////////////////////////////////////////////
  5. CAvi::CAvi(void)
  6. {
  7. m_AviFile = NULL;
  8. m_lpDDS = NULL;
  9. m_AviStream = NULL;
  10. ZeroMemory(&m_StreamInfo, sizeof(m_StreamInfo));
  11. m_Index = 0;
  12. m_nFrames = 0;
  13. m_Decompressor = 0;
  14. m_Input = m_Output = 0;
  15. m_AviSound = NULL;
  16. ZeroMemory(&m_SoundInfo, sizeof(m_SoundInfo));
  17. m_SoundFormat = 0;
  18. m_LoadPos = 0;
  19. m_LoadSize = 0;
  20. m_SoundFramesAhead = 0;
  21. m_nStopFrame = -1;
  22. m_bIsPlaying = FALSE;
  23. m_SoundBuffer = NULL;
  24. }
  25. //////////////////////////////////////////////////////////////////////////////////
  26. // CAvi Destructor
  27. //////////////////////////////////////////////////////////////////////////////////
  28. CAvi::~CAvi(void)
  29. {
  30. // CAvi::ReleaseAvi();
  31. }
  32. void CAvi::InitAvi(LPDIRECTSOUND lpDS)
  33. {
  34. m_lpDS = lpDS;
  35. InitializeCriticalSection(&m_AccessBuffer);
  36. }
  37. void CAvi::ReleaseAvi( void )
  38. {
  39. CAvi::Stop( );
  40. Sleep(1);
  41. if(m_Decompressor)
  42. {
  43. ICDecompressEnd(m_Decompressor);
  44. ICClose(m_Decompressor);
  45. }
  46. if( m_InputFormat ) FREE(m_InputFormat);
  47. if( m_TargetFormat ) FREE(m_TargetFormat);
  48. if( m_Input ) FREE(m_Input);
  49. if( m_Output ) FREE(m_Output);
  50. if( m_lpDDS )
  51. AVIFileExit();
  52. RELEASE( m_SoundBuffer );
  53. RELEASE( m_lpDDS );
  54. if( m_AviStream )
  55. {
  56. AVIStreamRelease(m_AviStream);
  57. m_AviStream = NULL;
  58. }
  59. if( m_AviSound )
  60. {
  61. AVIStreamRelease(m_AviSound );
  62. m_AviSound = NULL;
  63. }
  64. if( m_AviFile )
  65. {
  66. AVIFileRelease(m_AviFile);
  67. m_AviFile = NULL;
  68. }
  69. if(m_SoundFormat)
  70. {
  71. FREE(m_SoundFormat);
  72. m_SoundFormat = NULL;
  73. }
  74. DeleteCriticalSection(&m_AccessBuffer);
  75. }
  76. //////////////////////////////////////////////////////////////////////////////////
  77. // CAvi Create
  78. //////////////////////////////////////////////////////////////////////////////////
  79. BOOL CAvi::Create(const char* Filename, BOOL bLoop, BOOL bPlayBack)
  80. {
  81. if(Filename == NULL) return FALSE;
  82. AVIFileInit();
  83. m_bLoop = bLoop;
  84. m_bPlayDirection = bPlayBack;
  85. if( AVIFileOpen( &m_AviFile, Filename, OF_READ, 0 ) )
  86. {
  87. AVIFileExit( );
  88. return FALSE; 
  89. }
  90. if( AVIFileGetStream( m_AviFile, &m_AviStream, streamtypeVIDEO, 0 ) )
  91. {
  92. AVIFileExit( );
  93.         return FALSE;
  94. }
  95. LONG FmtLenght;
  96. AVIStreamFormatSize(m_AviStream, 0, &FmtLenght);
  97. m_InputFormat = (LPBITMAPINFOHEADER)malloc(FmtLenght);
  98. m_TargetFormat = (LPBITMAPV4HEADER)malloc(max(FmtLenght, sizeof(BITMAPV4HEADER)));
  99. ZeroMemory(m_TargetFormat, sizeof(BITMAPV4HEADER));
  100. AVIStreamReadFormat(m_AviStream, 0, m_InputFormat, &FmtLenght);
  101. m_nFrames = AVIStreamLength(m_AviStream);
  102. AVIStreamInfo(m_AviStream, &m_StreamInfo, sizeof(AVISTREAMINFO));
  103. HRESULT rval;
  104. ZeroMemory(&m_DDSD, sizeof(m_DDSD));
  105. m_DDSD.dwSize = sizeof(m_DDSD);
  106. m_DDSD.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
  107. m_DDSD.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
  108. m_DDSD.dwWidth = m_InputFormat->biWidth;
  109. m_DDSD.dwHeight = m_InputFormat->biHeight;
  110. rval = g_xMainWnd.GetDirectDraw()->CreateSurface(&m_DDSD, &m_lpDDS, NULL);
  111. if(rval != DD_OK)
  112. {
  113. AVIFileExit();
  114. return FALSE;
  115. }
  116. m_lpDDS->GetSurfaceDesc(&m_DDSD);
  117. memcpy(m_TargetFormat, m_InputFormat, FmtLenght);
  118. m_TargetFormat->bV4Size = max(FmtLenght, sizeof(BITMAPV4HEADER));
  119. m_TargetFormat->bV4BitCount = (WORD)m_DDSD.ddpfPixelFormat.dwRGBBitCount;
  120. m_TargetFormat->bV4V4Compression = BI_BITFIELDS;
  121. if(m_TargetFormat->bV4BitCount==24) m_TargetFormat->bV4V4Compression = BI_RGB;
  122. m_TargetFormat->bV4ClrUsed = 0;
  123. m_TargetFormat->bV4RedMask = m_DDSD.ddpfPixelFormat.dwRBitMask;
  124. m_TargetFormat->bV4GreenMask = m_DDSD.ddpfPixelFormat.dwGBitMask;
  125. m_TargetFormat->bV4BlueMask  = m_DDSD.ddpfPixelFormat.dwBBitMask;
  126. m_TargetFormat->bV4AlphaMask = m_DDSD.ddpfPixelFormat.dwRGBAlphaBitMask;
  127. m_TargetFormat->bV4SizeImage = ((m_TargetFormat->bV4Width +3)&0xFFFFFFFC) *
  128.  m_TargetFormat->bV4Height * (m_TargetFormat->bV4BitCount>>3);
  129. m_Length = m_InputFormat->biWidth * m_InputFormat->biHeight * (m_InputFormat->biBitCount >> 3);
  130. if(m_StreamInfo.dwSuggestedBufferSize) m_Length = (LONG)m_StreamInfo.dwSuggestedBufferSize;
  131. m_Decompressor = ICDecompressOpen(ICTYPE_VIDEO, m_StreamInfo.fccHandler, m_InputFormat,
  132.  (LPBITMAPINFOHEADER)m_TargetFormat);
  133. m_Input = (BYTE *)calloc(m_Length, 1);
  134. ZeroMemory(m_Input, m_Length);
  135. m_Output = (BYTE *)calloc(m_TargetFormat->bV4SizeImage, 1);
  136. ZeroMemory(m_Output, m_TargetFormat->bV4SizeImage);
  137. if(!m_Decompressor) return FALSE;
  138. m_LinePitch = m_TargetFormat->bV4Width * (m_TargetFormat->bV4BitCount >> 3);
  139. ICDecompressBegin(m_Decompressor, m_InputFormat, (LPBITMAPINFOHEADER)m_TargetFormat);
  140. m_Fps = m_StreamInfo.dwRate / m_StreamInfo.dwScale;
  141. m_TimeTick = (1000 * m_StreamInfo.dwScale + (m_StreamInfo.dwRate >> 1)) / m_StreamInfo.dwRate;
  142. m_SrcRect.top = 0;
  143. m_SrcRect.left = 0;
  144. m_SrcRect.bottom = m_TargetFormat->bV4Height;
  145. m_SrcRect.right = m_TargetFormat->bV4Width;
  146. m_DstRect.top = 0;
  147. m_DstRect.left = 0;
  148. m_DstRect.right = 800;
  149. m_DstRect.bottom = 600;
  150. if(m_lpDS)
  151. {
  152. UINT hResult = 0;
  153. hResult  = AVIFileGetStream( m_AviFile, &m_AviSound, streamtypeAUDIO, 0 );
  154. if(hResult  ==0 )
  155. DSBUFFERDESC dsbd;
  156. ZeroMemory((VOID*)&dsbd, sizeof(DSBUFFERDESC));
  157. AVIStreamFormatSize(m_AviSound, 0, &FmtLenght);
  158. m_SoundFormat = (WAVEFORMATEX *)malloc(FmtLenght);
  159. AVIStreamReadFormat(m_AviSound, 0, m_SoundFormat, &FmtLenght);
  160. AVIStreamInfo(m_AviSound, &m_SoundInfo, sizeof(AVISTREAMINFO));
  161. m_LoadSize = (m_SoundInfo.dwSuggestedBufferSize)/(m_Fps);//(m_SoundFormat->nAvgBytesPerSec) / (m_Fps+1);
  162. dsbd.dwSize = sizeof(dsbd);
  163. dsbd.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY;
  164. dsbd.dwBufferBytes = m_SoundInfo.dwSuggestedBufferSize;//m_LoadSize * (m_Fps)-2;
  165. dsbd.dwReserved = 0;
  166. dsbd.lpwfxFormat = m_SoundFormat;
  167. hResult = m_lpDS->CreateSoundBuffer(&dsbd, &m_SoundBuffer, NULL);
  168. if( hResult != DS_OK )
  169. {
  170. AVIFileExit();
  171. return FALSE;
  172. }
  173. }
  174. }
  175. m_Index = (m_bPlayDirection ? 0 : m_nFrames);
  176. return TRUE;
  177. }
  178. //////////////////////////////////////////////////////////////////////////////////
  179. // CAvi Start
  180. //////////////////////////////////////////////////////////////////////////////////
  181. void CAvi::Start(void)
  182. {
  183. if( !GetSound() ) return;
  184. m_bPlaying = TRUE;
  185. CAvi::ReadFrame(m_Index);
  186. m_bIsPlaying = TRUE;
  187. if( m_SoundBuffer )
  188. {
  189. m_SoundFramesAhead = m_SoundInfo.dwInitialFrames / m_SoundInfo.dwScale;
  190. m_SoundBuffer->SetVolume(-200);
  191. if(m_SoundBuffer->Play(0, 0, DSBPLAY_LOOPING) != DS_OK) return;
  192. }
  193. }
  194. //////////////////////////////////////////////////////////////////////////////////
  195. // CAvi Stop
  196. //////////////////////////////////////////////////////////////////////////////////
  197. void CAvi::Stop(void)
  198. {
  199. m_bPlaying = FALSE;
  200. if( m_SoundBuffer)
  201. m_SoundBuffer->Stop();
  202. }
  203. //////////////////////////////////////////////////////////////////////////////////
  204. // CAvi NextFrame
  205. //////////////////////////////////////////////////////////////////////////////////
  206. void CAvi::NextFrame(void)
  207. {
  208. m_Index = m_Index + (m_bPlayDirection? 1 : -1);
  209. if(m_Index == (m_bPlayDirection ? m_nFrames : 0) )
  210. {
  211. CAvi::Stop( );
  212. if(m_bLoop)
  213. {
  214. m_Index = (m_bPlayDirection ? 0 : m_nFrames);
  215. m_LoadPos = (m_bPlayDirection ? 0 : m_nFrames);
  216. m_bPlaying = TRUE;
  217. if( m_SoundBuffer )
  218. {
  219. m_SoundBuffer->SetCurrentPosition(0);
  220. GetSound();
  221. m_SoundBuffer->Play(0, 0, DSBPLAY_LOOPING);
  222. }
  223. }
  224. else
  225. {
  226. m_bIsPlaying = FALSE;
  227. }
  228. }
  229. if( (m_nStopFrame > 0 ) && ( m_Index == m_nStopFrame ))
  230. {
  231. m_bIsPlaying = FALSE;
  232. m_nStopFrame = -1;
  233. }
  234. else
  235. {
  236. GetSound();
  237. ReadFrame(m_Index);
  238. }
  239. }
  240. //////////////////////////////////////////////////////////////////////////////////
  241. // CAvi ReadFrame
  242. //////////////////////////////////////////////////////////////////////////////////
  243. void CAvi::ReadFrame(LONG Frame)
  244. {
  245. Frame -= m_SoundFramesAhead;
  246. if(Frame < 0) return;
  247. if(Frame < m_nFrames)
  248. {
  249. AVIStreamRead(m_AviStream, Frame, 1, m_Input, m_Length, NULL, NULL);
  250. EnterCriticalSection(&m_AccessBuffer);
  251. ICDecompress(m_Decompressor, ICDECOMPRESS_HURRYUP, m_InputFormat, m_Input, (LPBITMAPINFOHEADER)m_TargetFormat, m_Output);
  252. LeaveCriticalSection(&m_AccessBuffer);
  253. }
  254. }
  255. //////////////////////////////////////////////////////////////////////////////////
  256. // CDXAvi GetSound
  257. //////////////////////////////////////////////////////////////////////////////////
  258. BOOL CAvi::GetSound(VOID)
  259. {
  260. HRESULT rval;
  261. DWORD dwSize,dwSize2;
  262. LPVOID Data,Data2;
  263. dwSize = 0;
  264. dwSize2 = 0;
  265. rval = 0;
  266. Data = NULL;
  267. Data2 = NULL;
  268. if( m_SoundBuffer )
  269. {
  270. rval = m_SoundBuffer->Lock(m_LoadPos * m_LoadSize, m_LoadSize, &Data, &dwSize, 0, 0, 0);// &Data2, &dwSize2, 0);
  271. if(rval != DS_OK) return FALSE;
  272. AVIStreamRead(m_AviSound, m_Index * (m_LoadSize >> 2), m_LoadSize, Data, m_LoadSize, NULL, NULL);
  273. rval = m_SoundBuffer->Unlock(Data, dwSize, 0, 0);// Data2, dwSize2);
  274. m_LoadPos++;
  275. m_LoadPos %= m_Fps;
  276. }
  277. return TRUE;
  278. }
  279. //////////////////////////////////////////////////////////////////////////////////
  280. // CAvi DrawBuffer
  281. //////////////////////////////////////////////////////////////////////////////////
  282. HRESULT CAvi::DrawBuffer(void)
  283. {
  284. HRESULT rval;
  285. ZeroMemory(&m_DDSD, sizeof(m_DDSD));
  286. m_DDSD.dwSize = sizeof(m_DDSD);
  287. rval = m_lpDDS->Lock(NULL, &m_DDSD, DDLOCK_WAIT, NULL);
  288. while(rval == DDERR_SURFACELOST) 
  289. {
  290. // Restore();
  291. ZeroMemory(&m_DDSD, sizeof(m_DDSD));
  292. m_DDSD.dwSize = sizeof(m_DDSD);
  293. rval = m_lpDDS->Lock(NULL, &m_DDSD, DDLOCK_WAIT, NULL);
  294. }
  295. if(rval == DD_OK)
  296. {
  297. BYTE *lpSource = m_Output + m_LinePitch * (m_TargetFormat->bV4Height - 1);
  298.         BYTE *lpDest = (LPBYTE)m_DDSD.lpSurface;
  299.         int xs = m_LinePitch>>2,
  300.             xm = m_LinePitch*2,
  301.             y = m_TargetFormat->bV4Height,
  302.             z = m_DDSD.lPitch-m_LinePitch;
  303.         EnterCriticalSection(&m_AccessBuffer);
  304. // I was to lazy to do the optimaization for all sizes
  305. // and all my AVI's are DWORD align i had no problem
  306. // i just putted back the old part for the odd AVIS ;)
  307. if( m_TargetFormat->bV4Width%4 )
  308. { for(int i = 0; i < (int)m_TargetFormat->bV4Height; i++)
  309. { memcpy(lpDest, lpSource, m_LinePitch);
  310. lpDest += m_DDSD.lPitch;
  311. lpSource -= m_LinePitch;
  312. }
  313. }
  314. else
  315. {
  316. __asm
  317. {   mov ebx, [y]
  318. mov esi, lpSource
  319. mov edi, lpDest
  320. cld
  321. lp: mov ecx, [xs]
  322. rep movsd
  323. sub esi, [xm]
  324. add edi, [z]
  325. dec ebx
  326. jnz lp
  327. }
  328. }
  329.         LeaveCriticalSection(&m_AccessBuffer);
  330. rval = m_lpDDS->Unlock(NULL);
  331. while(rval == DDERR_SURFACELOST) 
  332. {
  333. // Restore();
  334. rval = m_lpDDS->Unlock(NULL);
  335. }
  336. }
  337. return rval;
  338. }
  339. //////////////////////////////////////////////////////////////////////////////////
  340. // CAvi DrawBuffer
  341. //////////////////////////////////////////////////////////////////////////////////
  342. BOOL CAvi::Draw(INT nLoopTime)
  343. {
  344. BOOL rval = 0;
  345. ReadDatas(nLoopTime);
  346. rval = CAvi::DrawBuffer();
  347. if(rval != DD_OK) return rval;
  348. g_xMainWnd.GetBackBuffer()->Blt(&m_DstRect, m_lpDDS, &m_SrcRect, DDBLT_WAIT, NULL);
  349. return m_bIsPlaying;
  350. }
  351. //////////////////////////////////////////////////////////////////////////////////
  352. // CAvi DrawBuffer
  353. //////////////////////////////////////////////////////////////////////////////////
  354. HRESULT CAvi::DrawFast(INT nLoopTime,int X, int Y)
  355. {
  356. HRESULT rval;
  357. ReadDatas(nLoopTime);
  358. rval = CAvi::DrawBuffer();
  359. if(rval != DD_OK) return rval;
  360. rval = g_xMainWnd.GetBackBuffer()->BltFast(X, Y, m_lpDDS, &m_SrcRect, DDBLTFAST_WAIT|DDBLTFAST_NOCOLORKEY);
  361. // if(rval == DDERR_SURFACELOST) Restore();
  362. return rval;
  363. }
  364. BOOL CAvi::ReadDatas(INT nLoopTime)
  365. {
  366. static DWORD dwDelay = 0;
  367. INT nDivider;
  368. if(m_bPlaying)
  369. {
  370. dwDelay += nLoopTime;
  371. nDivider = 1000/m_Fps;
  372. if(dwDelay>nDivider)
  373. {
  374. NextFrame();
  375. dwDelay = 0;
  376. return TRUE;
  377. }
  378. }
  379. return FALSE;
  380. }