KLMp4Video.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:13k
源码类别:

模拟服务器

开发平台:

C/C++

  1. //---------------------------------------------------------------------------
  2. // Sword3 Engine (c) 1999-2000 by Kingsoft
  3. //
  4. // File: KLMp4Video.cpp
  5. // Date: 2000.08.08
  6. // Code: Daniel Wang
  7. // Desc: Mpeg4 Video Class
  8. //---------------------------------------------------------------------------
  9. #include <stdafx.h>
  10. #include "decore.h"
  11. #include "KLTimer.h"
  12. #include "KLMp4Video.h"
  13. #include "KLVideo.h"
  14. //---------------------------------------------------------------------------
  15. // 函数: KLMp4Video
  16. // 功能: 构造函数
  17. // 参数: void
  18. // 返回: void
  19. //---------------------------------------------------------------------------
  20. KLMp4Video::KLMp4Video()
  21. {
  22. m_dwHandle = 0;
  23. m_hEvent[0] = 0;
  24. m_hEvent[1] = 0;
  25. m_hMutex = NULL;
  26. m_nX = 0;
  27. m_nY = 0;
  28. m_nWidth = 0;
  29. m_nHeight = 0;
  30. m_pVideo = NULL;
  31. m_pFrame = NULL;
  32. m_nFrameSize = 0;
  33. m_nFrameRate = 20;
  34. m_nFrameTime = 50;
  35. m_uTimeID = 0;
  36. m_bZoomToWin = FALSE;
  37. m_bWait = false;
  38. }
  39. //---------------------------------------------------------------------------
  40. // 函数: ~KLMp4Video
  41. // 功能: 析构函数
  42. // 参数: void
  43. // 返回: void
  44. //---------------------------------------------------------------------------
  45. KLMp4Video::~KLMp4Video()
  46. {
  47. Close();
  48. }
  49. //---------------------------------------------------------------------------
  50. // 函数: ThreadFunction
  51. // 功能: 播放线程
  52. // 参数: void
  53. // 返回: void
  54. //---------------------------------------------------------------------------
  55. void KLMp4Video::ThreadFunction(void* lpParam)
  56. {
  57. KLMp4Video* pVideo = (KLMp4Video*)lpParam;
  58. while (TRUE)
  59. {
  60. if (!pVideo->HandleNotify())
  61. break;
  62. }
  63. }
  64. //---------------------------------------------------------------------------
  65. // 函数: Open
  66. // 功能: 打开AVI文件
  67. // 参数: FileName 文件名
  68. // 返回: TRUE-成功 FALSE-失败
  69. //---------------------------------------------------------------------------
  70. BOOL KLMp4Video::Open(LPSTR FileName)
  71. {
  72. if (m_pVideo)
  73. Close();
  74. if (!m_AviFile.Open(FileName))
  75. return FALSE;
  76. if (!m_AviFile.GetVideoIndex())
  77. return FALSE;
  78. if (m_dwHandle)
  79. DivXExit();
  80. if (!DivXInit())
  81. return FALSE;
  82. return Init();
  83. }
  84. //---------------------------------------------------------------------------
  85. // 函数: Init
  86. // 功能: 初始化
  87. // 参数:
  88. // 返回: TRUE-成功 FALSE-失败
  89. //---------------------------------------------------------------------------
  90. BOOL KLMp4Video::Init()
  91. {
  92. // create event handle
  93. if (!InitEventHandle())
  94. return FALSE;
  95. // create play thread
  96. m_Thread.Create(ThreadFunction, this);
  97. return TRUE;
  98. }
  99. //---------------------------------------------------------------------------
  100. // 函数: InitEventHandle
  101. // 功能: 创建事件句柄
  102. // 参数: void
  103. // 返回: TRUE-成功 FALSE-失败
  104. //---------------------------------------------------------------------------
  105. BOOL KLMp4Video::InitEventHandle()
  106. {
  107. for (int i = 0; i < 2; i++)
  108. {
  109. if (m_hEvent[i] == NULL)
  110. m_hEvent[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
  111. if (m_hEvent[i] == NULL)
  112. {
  113. return FALSE;
  114. }
  115. }
  116. if(m_hMutex == NULL)
  117. m_hMutex = CreateMutex(NULL, // no security attributes
  118.    FALSE, // initially not owned
  119.    NULL); // name of mutex
  120. if (m_hMutex == NULL) 
  121. {
  122. return FALSE;
  123. }
  124. return TRUE;
  125. }
  126. //---------------------------------------------------------------------------
  127. // 函数: FreeEventHandle
  128. // 功能: 释放事件句柄
  129. // 参数: void
  130. // 返回: TRUE-成功 FALSE-失败
  131. //---------------------------------------------------------------------------
  132. void KLMp4Video::FreeEventHandle()
  133. {
  134. for (int i = 0; i < 2; i++)
  135. {
  136. if (m_hEvent[i])
  137. {
  138. CloseHandle(m_hEvent[i]);
  139. m_hEvent[i] = NULL;
  140. }
  141. }
  142. if (m_hMutex)
  143. {
  144. CloseHandle(m_hMutex);
  145. m_hMutex = NULL;
  146. }
  147. }
  148. //---------------------------------------------------------------------------
  149. // 函数: HandleNotify
  150. // 功能: 处理音乐播放中的通告消息
  151. // 参数: void
  152. // 返回: void
  153. //---------------------------------------------------------------------------
  154. BOOL KLMp4Video::HandleNotify()
  155. {
  156. DWORD dwEvent;
  157. // wait for event[0..3] to be signaled
  158. dwEvent = WaitForMultipleObjects(
  159. 2, // How many possible events
  160. m_hEvent, // Location of handles
  161. FALSE, // Wait for all?
  162. INFINITE); // How long to wait
  163.     // WAIT_OBJECT_0 == 0 but is properly treated as an arbitrary
  164.     // index value assigned to the first event, therefore we subtract
  165.     // it from dwEvent to get the zero-based index of the event.
  166. dwEvent -= WAIT_OBJECT_0;
  167. // If event[0] was set then goto next frame
  168. if (dwEvent == 0)
  169. {
  170. m_bWait = true;
  171. BOOL bRet = NextFrame();
  172. m_bWait = false;
  173. return bRet;
  174. }
  175. // If the event[1] was set then exit thread
  176. return (dwEvent != 1);
  177. }
  178. //---------------------------------------------------------------------------
  179. // 函数: Close
  180. // 功能: 关闭文件,释放资源
  181. // 参数: void
  182. // 返回: void
  183. //---------------------------------------------------------------------------
  184. void KLMp4Video::Close()
  185. {
  186. // 必须先等线程结束,再释放内存,防止非法操作
  187. Stop();
  188. SetEvent(m_hEvent[1]);
  189. m_Thread.WaitForExit();
  190. FreeEventHandle();
  191. DivXExit();
  192. }
  193. //---------------------------------------------------------------------------
  194. // 函数: Seek
  195. // 功能: 移动当前帧
  196. // 参数: void
  197. // 返回: void
  198. //---------------------------------------------------------------------------
  199. void KLMp4Video::Seek(int nPercent)
  200. {
  201. m_AviFile.VideoSeek(nPercent);
  202. }
  203. //---------------------------------------------------------------------------
  204. // 函数: Rewind
  205. // 功能:
  206. // 参数: void
  207. // 返回: void
  208. //---------------------------------------------------------------------------
  209. void KLMp4Video::Rewind()
  210. {
  211. m_AviFile.Rewind();
  212. }
  213. //---------------------------------------------------------------------------
  214. // 函数: NextFrame
  215. // 功能: 下一帧
  216. // 参数: void
  217. // 返回: BOOL
  218. //---------------------------------------------------------------------------
  219. BOOL KLMp4Video::NextFrame()
  220. {
  221. BOOL bRender = TRUE;
  222. // read next video frame
  223. m_nFrameSize = m_AviFile.NextFrame(m_pVideo);
  224. // drop this frame if necessary
  225. if ((DWORD)m_AviFile.CurrentFrame() * 1000 < m_Timer.GetElapse() * m_nFrameRate)
  226. {
  227. bRender = FALSE;
  228. SetEvent(m_hEvent[0]);
  229. }
  230. // if reach the video end
  231. if (m_nFrameSize >= 0)
  232. {
  233. DivXDecode(bRender);
  234. return TRUE;
  235. }
  236. else
  237. {
  238. //播放完毕
  239. Stop();
  240. return FALSE;
  241. }
  242. }
  243. inline void RGB32TO555(LPBYTE pDes, LPBYTE pSrc, uint32 nCount)
  244. {
  245. WORD *p = (WORD*)pDes;
  246. BYTE a,r,g,b;
  247. for(uint32 i=0; i<nCount; i++)
  248. {
  249. b = *(pSrc), g = *(pSrc+1), r = *(pSrc+2), a = *(pSrc+3), 
  250. *p++ = (((WORD)(b&0xf8))>>3) + (((WORD)(g&0xf8))<<2) + (((WORD)(r&0xf8))<<7);
  251. pSrc += 4;
  252. }
  253. }
  254. inline void RGB32TO565(LPBYTE pDes, LPBYTE pSrc, uint32 nCount)
  255. {
  256. WORD *p = (WORD*)pDes;
  257. BYTE a,r,g,b;
  258. for(uint32 i=0; i<nCount; i++)
  259. {
  260. b = *(pSrc), g = *(pSrc+1), r = *(pSrc+2), a = *(pSrc+3), 
  261. *p++ = (((WORD)(b&0xf8))>>3) + (((WORD)(g&0xfc))<<3) + (((WORD)(r&0xf8))<<8);
  262. pSrc += 4;
  263. }
  264. }
  265. inline void RGB32TO32(LPBYTE pDes, LPBYTE pSrc, uint32 nCount)
  266. {
  267. DWORD *ps = (DWORD*)pSrc;
  268. DWORD *pd = (DWORD*)pDes;
  269. for(uint32 i=0; i<nCount; i++)
  270. {
  271. *pd++ = *ps++;
  272. }
  273. }
  274. inline void RGB32TO32R(LPBYTE pDes, LPBYTE pSrc, uint32 nCount)
  275. {
  276. for(uint32 i=0; i<nCount; i++)
  277. {
  278. *pDes++ = *(pSrc+3);
  279. *pDes++ = *(pSrc+2);
  280. *pDes++ = *(pSrc+1);
  281. *pDes++ = *pSrc;
  282. pSrc += 4;
  283. }
  284. }
  285. typedef void (*COLORCONVERTFN)(LPBYTE pDes, LPBYTE pSrc, uint32 nCount);
  286. void KLMp4Video::VideoCopyToBuffer(void *buf,uint32 left,uint32 top,uint32 Pitch,
  287. uint32 destheight,uint32 Flags)
  288. {
  289. WaitForSingleObject( m_hMutex, INFINITE);
  290. u32 nBytePerPixel;
  291. COLORCONVERTFN ColorConvertFn;
  292. if(Flags == KLVIDEOSURFACE555)
  293. {
  294. nBytePerPixel = 2;
  295. ColorConvertFn = RGB32TO555;
  296. }
  297. else if(Flags == KLVIDEOSURFACE565)
  298. {
  299. nBytePerPixel = 2;
  300. ColorConvertFn = RGB32TO565;
  301. }
  302. else if(Flags == KLVIDEOSURFACE32)
  303. {
  304. nBytePerPixel = 4;
  305. ColorConvertFn = RGB32TO32;
  306. }
  307. else if(Flags == KLVIDEOSURFACE32R)
  308. {
  309. nBytePerPixel = 4;
  310. ColorConvertFn = RGB32TO32R;
  311. }
  312. u32 i;
  313. LPBYTE pByte;
  314. LPBYTE pFrame;
  315. u32 nLineWidth;
  316. _ASSERT(left * nBytePerPixel < Pitch);
  317. nLineWidth = Pitch / nBytePerPixel - left;
  318. if(nLineWidth > (uint32)m_nWidth) nLineWidth = m_nWidth;
  319. if(destheight > (uint32)m_nHeight)
  320. destheight = m_nHeight;
  321. pByte = ((BYTE*)buf) + Pitch * top + left * nBytePerPixel;
  322. pFrame = m_pFrame + (m_nHeight-1)*m_nWidth*4;
  323. for(i=0 ; i<destheight ; i++)
  324. {
  325. ColorConvertFn(pByte, pFrame, nLineWidth);
  326. pByte += Pitch;
  327. pFrame -= m_nWidth*4;
  328. }
  329. ReleaseMutex(m_hMutex);
  330. }
  331. //---------------------------------------------------------------------------
  332. // 函数: SetPos
  333. // 功能:
  334. // 参数:
  335. // 返回: void
  336. //---------------------------------------------------------------------------
  337. void KLMp4Video::SetPos(int nX, int nY)
  338. {
  339. m_nX = nX;
  340. m_nY = nY;
  341. }
  342. //---------------------------------------------------------------------------
  343. // 函数: DivXInit
  344. // 功能: 初始化解码器
  345. // 参数: void
  346. // 返回: void
  347. //---------------------------------------------------------------------------
  348. BOOL KLMp4Video::DivXInit()
  349. {
  350. char szMethod[8];
  351. BITMAPINFOHEADER BmpInfoHead;
  352. // check avi compress method
  353. m_AviFile.GetCompressMethod(szMethod);
  354. if (memcmp(szMethod, "divx", 4) != 0)
  355. {
  356. return FALSE;
  357. }
  358. // get frame delay
  359. m_nFrameRate = m_AviFile.FrameRate();
  360. m_nFrameTime = (1000 + m_nFrameRate - 1) / m_nFrameRate;
  361. // get bitmap info header
  362. m_AviFile.GetBitmapInfoHeader(&BmpInfoHead);
  363. // check compress method
  364. if (memcmp(&BmpInfoHead.biCompression, "DIVX", 4) != 0)
  365. {
  366. return FALSE;
  367. }
  368. // get frame width an height
  369. m_nWidth = BmpInfoHead.biWidth;
  370. m_nHeight = BmpInfoHead.biHeight;
  371. if(m_nWidth < m_nHeight)
  372. return FALSE;
  373. // get video buffer
  374. if(!m_pVideo)
  375. m_pVideo = (LPBYTE)new BYTE[m_nWidth * m_nHeight * 4];
  376. if(!m_pVideo)
  377. return FALSE;
  378. // get frame buffer
  379. if(!m_pFrame)
  380. m_pFrame = (LPBYTE)new BYTE[m_nWidth * m_nHeight * 4];
  381. if(!m_pFrame)
  382. {
  383. delete[] m_pVideo;
  384. m_pVideo = NULL;
  385. return FALSE;
  386. }
  387. // get a unique decore handle
  388. if (m_dwHandle == 0)
  389. m_dwHandle = GetTickCount();
  390. // init decore
  391. DEC_PARAM dec_param;
  392. dec_param.x_dim         = m_nWidth;
  393. dec_param.y_dim         = m_nHeight;
  394. dec_param.color_depth   = NULL;
  395. dec_param.output_format = RGB32;
  396. if (decore(m_dwHandle, DEC_OPT_INIT, &dec_param, NULL) != DEC_OK)
  397. {
  398. return FALSE;
  399. }
  400. return TRUE;
  401. }
  402. //---------------------------------------------------------------------------
  403. // 函数: DivXDecode
  404. // 功能: 解码
  405. // 参数: void
  406. // 返回: void
  407. //---------------------------------------------------------------------------
  408. void KLMp4Video::DivXDecode(BOOL bRender)
  409. {
  410. WaitForSingleObject( m_hMutex, INFINITE);  
  411. DEC_FRAME dec_frame;
  412. dec_frame.length      = m_nFrameSize;
  413. dec_frame.bitstream   = m_pVideo;
  414. dec_frame.bmp         = m_pFrame;
  415. dec_frame.render_flag = bRender;
  416. decore(m_dwHandle, 0, &dec_frame, NULL);
  417. ReleaseMutex(m_hMutex);
  418. }
  419. //---------------------------------------------------------------------------
  420. // 函数: DivXExit
  421. // 功能: 释放解码器
  422. // 参数: void
  423. // 返回: void
  424. //---------------------------------------------------------------------------
  425. void KLMp4Video::DivXExit()
  426. {
  427. if (m_dwHandle)
  428. {
  429. decore(m_dwHandle, DEC_OPT_RELEASE, NULL, NULL);
  430. m_dwHandle = 0;
  431. }
  432. if(m_pVideo)
  433. {
  434. delete[] m_pVideo;
  435. m_pVideo = NULL;
  436. }
  437. if(m_pFrame)
  438. {
  439. delete[] m_pFrame;
  440. m_pFrame = NULL;
  441. }
  442. }
  443. //---------------------------------------------------------------------------
  444. // 函数: Play
  445. // 功能: 播放
  446. // 参数: void
  447. // 返回: void
  448. //---------------------------------------------------------------------------
  449. void KLMp4Video::Play(BOOL bZoom)
  450. {
  451. if (m_pVideo == NULL)
  452. return;
  453. NextFrame();
  454. if (m_uTimeID == 0)
  455. {
  456. m_uTimeID = timeSetEvent(
  457. m_nFrameTime, // delay time in ms
  458. 1, // resolution
  459. (LPTIMECALLBACK)m_hEvent[0],
  460. 0, // user data
  461. TIME_PERIODIC | TIME_CALLBACK_EVENT_SET);
  462. m_Timer.Start();
  463. m_bZoomToWin = bZoom;
  464. }
  465. }
  466. //---------------------------------------------------------------------------
  467. // 函数: Stop
  468. // 功能: 停止
  469. // 参数: void
  470. // 返回: void
  471. //---------------------------------------------------------------------------
  472. void KLMp4Video::Stop()
  473. {
  474. if (m_uTimeID)
  475. {
  476. timeKillEvent(m_uTimeID);
  477. m_uTimeID = 0;
  478. m_Timer.Stop();
  479. }
  480. }
  481. //---------------------------------------------------------------------------
  482. // 函数: IsPlaying
  483. // 功能: 是否在播放
  484. // 参数: void
  485. // 返回: BOOL
  486. //---------------------------------------------------------------------------
  487. BOOL KLMp4Video::IsPlaying()
  488. {
  489. return (m_uTimeID != 0);
  490. }