ZZLFileReader.cpp
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:14k
源码类别:

P2P编程

开发平台:

Visual C++

  1. /*
  2.  *  Openmysee
  3.  *
  4.  *  This program is free software; you can redistribute it and/or modify
  5.  *  it under the terms of the GNU General Public License as published by
  6.  *  the Free Software Foundation; either version 2 of the License, or
  7.  *  (at your option) any later version.
  8.  *
  9.  *  This program is distributed in the hope that it will be useful,
  10.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *  GNU General Public License for more details.
  13.  *
  14.  *  You should have received a copy of the GNU General Public License
  15.  *  along with this program; if not, write to the Free Software
  16.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17.  *
  18.  */
  19. #include "stdafx.h"
  20. #include "ZZLFileReader.h"
  21. #ifndef SAFE_DELETE
  22. #define SAFE_DELETE( x) 
  23. if( NULL != x )        
  24. {                      
  25. delete x;       
  26. x = NULL;          
  27. }
  28. #endif
  29. #ifndef SAFE_ARRAYDELETE
  30. #define SAFE_ARRAYDELETE( x )  
  31. if( NULL != x )        
  32. {                      
  33. delete [] x;       
  34. x = NULL;          
  35. }
  36. #endif
  37. ZZLFileReader::ZZLFileReader() :
  38.    FILE_VERSION(1.0f),
  39.    MAX_HEADER_SIZE(1024),
  40.    LIMIT_DOWN_SPEED(150.0f),
  41.                m_VideoEndTime(0),
  42.                m_AudioEndTime(0)
  43. {
  44. m_hFile           = INVALID_HANDLE_VALUE;
  45. m_iHeaderSize     = 0;
  46. m_iFileSize       = 0;
  47. m_iDownloadedSize = 0;
  48. //
  49. m_pAudioFormat      = NULL;
  50. m_pVideoFormat      = NULL;
  51. m_startTime       = 0; 
  52. m_endTime         = 0;
  53. A_currBlockID     = 0;
  54. V_currBlockID     = 0;
  55. m_hDownThread     = NULL;
  56. m_isStopped       = FALSE;
  57. //
  58. A_iLeftDataInCurrBlock = 0;
  59. V_iLeftDataInCurrBlock = 0;
  60. }
  61. ZZLFileReader::~ZZLFileReader(void) 
  62. {
  63. m_iHeaderSize = 0;
  64. m_isStopped   = TRUE; // stop thread
  65. if (INVALID_HANDLE_VALUE != m_hFile )
  66. {
  67. CloseHandle(m_hFile);
  68. m_hFile = INVALID_HANDLE_VALUE;
  69. }
  70. //
  71. //
  72. SAFE_ARRAYDELETE(m_pAudioFormat);
  73. SAFE_ARRAYDELETE(m_pVideoFormat);
  74. }
  75. bool ZZLFileReader::Init(const char* filename)
  76. {
  77. CAutoLock l(&m_pLock);
  78. //
  79. if(!filename)
  80. {
  81. ASSERT(FALSE);
  82. return false;
  83. }
  84. //
  85.     if(m_hFile != INVALID_HANDLE_VALUE)
  86.         return true;
  87. // 打开文件句柄
  88. m_hFile = CreateFile(filename, GENERIC_READ, 
  89. FILE_SHARE_READ, NULL, 
  90. OPEN_EXISTING,  // 本地文件
  91. FILE_ATTRIBUTE_NORMAL, NULL);
  92. //
  93. if(m_hFile == INVALID_HANDLE_VALUE)
  94. {
  95. int xxx = GetLastError();
  96. return false;
  97. }
  98. m_iFileSize = GetFileSize(m_hFile, NULL);
  99. m_iDownloadedSize = m_iFileSize; // 本地文件!当然数据是全的
  100. // 本地文件,直接读取文件头
  101. if(!ReadFileHeader())
  102. {
  103. ASSERT(FALSE);
  104. return false;
  105. }
  106. //
  107. return true;
  108. }
  109. void __stdcall ZZLFileReader::RunHttpDownload(ZZLFileReader* reader)
  110. {
  111.     return;
  112. }
  113. bool ZZLFileReader::ReadFileHeader()
  114. {
  115. CAutoLock l(&m_pLock);
  116. if(m_iDownloadedSize < MAX_HEADER_SIZE)
  117. {
  118. return false;
  119. }
  120. //
  121. if(IsInited())
  122. {
  123. return true;
  124. }
  125. //
  126. DWORD readBytes = 0;
  127. float version;
  128. // 1. check "ZZLD"
  129. char fcc[5] = "";
  130. fcc[4] = 0;
  131. //
  132. if(INVALID_SET_FILE_POINTER == SetFilePointer(m_hFile, 0, 0, FILE_BEGIN))
  133. {
  134. return false;
  135. }
  136. //
  137. if(!ReadFile(m_hFile, fcc, 4, &readBytes, NULL))
  138. {
  139. return false;
  140. }
  141. //
  142. if(readBytes != 4 || stricmp(fcc, "ZZLD") != 0)
  143. {
  144. return false;
  145. }
  146. // 2. check file version
  147. if(!ReadFile(m_hFile, &version, sizeof(version), &readBytes, NULL))
  148. {
  149. return false;
  150. }
  151. //
  152. if(readBytes != sizeof(version) || version > FILE_VERSION)
  153. {
  154. return false;
  155. }
  156. // 3. read video type
  157. if(!ReadFile(m_hFile, &m_VideoType, sizeof(m_VideoType), &readBytes, NULL))
  158. {
  159. return false;
  160. }
  161. //
  162. if(readBytes != sizeof(m_VideoType) && m_VideoType.cbFormat > 1024)
  163. {
  164. return false;
  165. }
  166. //
  167. SAFE_DELETE(m_pVideoFormat);
  168. //
  169. m_pVideoFormat = new BYTE[m_VideoType.cbFormat];
  170. //
  171. if(!ReadFile(m_hFile, m_pVideoFormat, m_VideoType.cbFormat, &readBytes, NULL))
  172. {
  173. return false;
  174. }
  175. //
  176. if(readBytes != m_VideoType.cbFormat)
  177. {
  178. return false;
  179. }
  180. // 4. read audio type
  181. if(!ReadFile(m_hFile, &m_AudioType, sizeof(m_AudioType), &readBytes, NULL))
  182. {
  183. return false;
  184. }
  185. //
  186. if(readBytes != sizeof(m_AudioType) && m_AudioType.cbFormat > 1024)
  187. {
  188. return false;
  189. }
  190. //
  191. SAFE_DELETE(m_pAudioFormat);
  192. //
  193. m_pAudioFormat = new BYTE[m_AudioType.cbFormat];
  194. //
  195. if(!ReadFile(m_hFile, m_pAudioFormat, m_AudioType.cbFormat, &readBytes, NULL))
  196. {
  197. return false;
  198. }
  199. //
  200. if(readBytes != m_AudioType.cbFormat)
  201. {
  202. return false;
  203. }
  204. // 5. read start time, end time
  205. time_t temp = 0;
  206. if(!ReadFile(m_hFile, &temp, sizeof(temp), &readBytes, NULL))
  207. {
  208. return false;
  209. }
  210. //
  211. if(readBytes != sizeof(temp))
  212. {
  213. return false;
  214. }
  215. //
  216. m_startTime  = temp;
  217. m_startTime *= 10000000;
  218. if(!ReadFile(m_hFile, &temp, sizeof(temp), &readBytes, NULL))
  219. {
  220. return false;
  221. }
  222. //
  223. if(readBytes != sizeof(temp))
  224. {
  225. return false;
  226. }
  227. //
  228. m_endTime  = temp;
  229. m_endTime *= 10000000;
  230. //
  231. if(m_endTime < m_startTime || m_endTime == 0)
  232. {
  233. return false;
  234. }
  235. m_iHeaderSize = 4 + sizeof(version) + sizeof(m_AudioType) + 
  236. m_AudioType.cbFormat  + sizeof(m_VideoType) +
  237. m_VideoType.cbFormat + 
  238. sizeof(temp) +
  239. sizeof(temp);
  240. //
  241. //m_pFilter->SetBaseRef(m_startTime);
  242. //
  243.     if((m_iFileSize - m_iHeaderSize)%BLOCK_SIZE != 0)
  244.         assert(0);
  245. return true;
  246. }
  247. // 获取媒体类型
  248. int ZZLFileReader::GetMediaType(TVMEDIATYPESECTION& mediatype, BOOL isAudio)
  249. {
  250. CAutoLock l(&m_pLock);
  251. //
  252. if(!IsInited())
  253. {
  254. if(!ReadFileHeader())
  255. {
  256. return FALSE;
  257. }
  258. }
  259. //
  260. if(isAudio)
  261. {
  262. if(!m_pAudioFormat)
  263. {
  264. return FALSE;
  265. }
  266. //
  267. mediatype = m_AudioType;
  268. }
  269. else 
  270. {
  271. if(!m_pVideoFormat)
  272. {
  273. return FALSE;
  274. }
  275. //
  276. mediatype = m_VideoType;
  277. }
  278. //
  279. return TRUE;
  280. }
  281. // 获取媒体数据
  282. int ZZLFileReader::GetMediaData(PBYTE data, BOOL isAudio)
  283. {
  284. CAutoLock l(&m_pLock);
  285. //
  286. if(!data)
  287. {
  288. ASSERT(NULL != data);
  289. return FALSE;
  290. }
  291. //
  292. if(!IsInited()) 
  293. {
  294. if(!ReadFileHeader())
  295. {
  296. ASSERT(FALSE);
  297. return FALSE;
  298. }
  299. }
  300. //
  301. if(isAudio) 
  302. {
  303. if(!m_pAudioFormat)
  304. {
  305. ASSERT(NULL != m_pAudioFormat);
  306. return FALSE;
  307. }
  308. //
  309. memcpy(data, m_pAudioFormat, m_AudioType.cbFormat);
  310. }
  311. else
  312. {
  313. if(!m_pVideoFormat)
  314. {
  315. return FALSE;
  316. }
  317. //
  318. memcpy(data, m_pVideoFormat, m_VideoType.cbFormat);
  319. }
  320. //
  321. return TRUE;
  322. }
  323. STDMETHODIMP ZZLFileReader::GetAvailable(LONGLONG& pEarliest,LONGLONG& pLatest)
  324. {
  325. CAutoLock l(&m_pLock);
  326. //
  327. if(!IsInited())
  328. {
  329. if(!ReadFileHeader())
  330. {
  331. ASSERT(FALSE);
  332. return S_FALSE;
  333. }
  334. }
  335. //
  336. pEarliest = 0;
  337. pLatest   = m_endTime - m_startTime;
  338. //
  339. return S_OK;
  340. }
  341. STDMETHODIMP ZZLFileReader::GetDuration(LONGLONG& pDuration)
  342. {
  343. CAutoLock l(&m_pLock);
  344. //
  345. if(!IsInited()) 
  346. {
  347. if(!ReadFileHeader())
  348. {
  349. ASSERT(FALSE);
  350. return S_FALSE;
  351. }
  352. }
  353. //
  354. pDuration = m_endTime - m_startTime;
  355. //
  356. return S_OK;
  357. }
  358. //
  359. STDMETHODIMP ZZLFileReader::GetStopPosition(LONGLONG& pStop) 
  360. {
  361. CAutoLock l(&m_pLock);
  362. //
  363. if(!IsInited()) 
  364. {
  365. if(!ReadFileHeader())
  366. {
  367. ASSERT(FALSE);
  368. return S_FALSE;
  369. }
  370. }
  371. //
  372. pStop = m_endTime-m_startTime;
  373. return S_OK;
  374. }
  375. // Seek到某个时间
  376. bool ZZLFileReader::SeekTo(LONGLONG seekTime, int pin)
  377. {
  378. CAutoLock l(&m_pLock);
  379. if(!IsInited()) 
  380. {
  381. if(!ReadFileHeader())
  382. {
  383. ASSERT(FALSE);
  384. return false;
  385. }
  386. }
  387. //
  388. UINT targetBlockID;
  389. if(seekTime > m_endTime)
  390. {
  391. seekTime = m_endTime;
  392. targetBlockID = (m_iFileSize - m_iHeaderSize)/BLOCK_SIZE;
  393. }
  394. else if(seekTime == 0 || seekTime <= m_startTime) 
  395. {
  396.  seekTime  = m_startTime;
  397.  targetBlockID = 0;
  398. }
  399. else
  400. {
  401. // TODO: 使用二分查找
  402. targetBlockID = (UINT)(((double)(seekTime - m_startTime)/(m_endTime - m_startTime)*(m_iFileSize-m_iHeaderSize))/BLOCK_SIZE);
  403. }
  404. //
  405.     if((pin & 1) == 1)
  406.     {
  407.     A_currBlockID = targetBlockID;
  408.         A_iLeftDataInCurrBlock = 0;
  409.     }
  410.     if((pin & 2) == 2)
  411.     {
  412.     V_currBlockID = targetBlockID;
  413.         V_iLeftDataInCurrBlock = 0;
  414.     }
  415. //
  416. //
  417. return true;
  418. }
  419. bool ZZLFileReader::SeekVideoTo(LONGLONG seekTime)
  420. {
  421.     return SeekTo(seekTime, 2);
  422. }
  423. bool ZZLFileReader::SeekAudioTo(LONGLONG seekTime)
  424. {
  425.     return SeekTo(seekTime, 1);
  426. }
  427. // 获取Sample. 
  428. // m_startTime != _I64_MAX的话,寻找m_startTime之后的第一个Sample,
  429. // 视频Sample的话还要满足是关键帧的条件
  430. P2P_RETURN_TYPE ZZLFileReader::GetSample(SampleHeader& header, // Sample头
  431.  PBYTE& pData, // Sample数据
  432.  const UINT maxSize, // Sample的最大值
  433.  LONGLONG seekTime) // Seek的目标时间
  434. {
  435. CAutoLock l(&m_pLock);
  436. if(!IsInited())
  437. {
  438. if(!ReadFileHeader())
  439. return PRT_NOT_INIT;
  440. }
  441. //
  442.     if(m_hFile == NULL || m_hFile == INVALID_HANDLE_VALUE)
  443.         return PRT_SYS;
  444. //
  445. const bool isAudio = header.bAudioSample;
  446. for(;;) 
  447. {
  448. P2P_RETURN_TYPE ret = LoadSample(header, pData, 0, maxSize, isAudio);
  449. if(ret != PRT_OK)
  450. return ret;
  451.             // 节目开始的标志Sample,在ZZL文件中略过,不用处理
  452.         if(header.length == 0xffffffff || header.start == 0xffffffffffffffff)
  453.             continue;
  454. if(isAudio == header.bAudioSample)
  455.      {
  456. break;
  457. }
  458. }
  459.     //计算最准确的结束时间
  460.     if(header.start != -1)
  461.     {
  462.         LONGLONG tmp = header.start + header.length;
  463.         if(isAudio)
  464.         {
  465.         if(tmp > m_AudioEndTime)
  466.                 m_AudioEndTime = tmp;
  467.         }
  468.         else
  469.         {
  470.             if(tmp > m_VideoEndTime)
  471.                 m_VideoEndTime = tmp;
  472.         }
  473.     }  
  474. //
  475. return PRT_OK;
  476. }
  477. //
  478. P2P_RETURN_TYPE ZZLFileReader::LoadSample(SampleHeader& header, // Sample头
  479. PBYTE& sampleData, // Sample数据
  480. UINT sampleOff, // 已经读取的长度
  481. const UINT maxSize, // Sample最大长度
  482. const bool isAudio) // 视频还是音频 
  483. {
  484. UINT& currBlockID = isAudio ? A_currBlockID : V_currBlockID;
  485. BYTE *currBlock   = isAudio ? A_currBlock   : V_currBlock;
  486. //
  487. UINT& leftDataInCurrBlock = isAudio ? A_iLeftDataInCurrBlock : V_iLeftDataInCurrBlock;
  488. DWORD readBytes = 0;
  489. //
  490. UINT  iCurrentPos = m_iHeaderSize + currBlockID*BLOCK_SIZE; 
  491. //
  492. while(0 == leftDataInCurrBlock)
  493. { // not data in current block, load next
  494. // 读取当前块数据
  495.         if(iCurrentPos >= m_iFileSize)  //文件已经读到头了
  496.         {
  497.             return PRT_ENDOFFILE;
  498.         }
  499. if(INVALID_SET_FILE_POINTER == SetFilePointer(m_hFile, iCurrentPos, NULL, FILE_BEGIN))
  500. {
  501. ASSERT(FALSE);
  502. return PRT_SYS;
  503. }
  504. if(iCurrentPos + BLOCK_SIZE > m_iFileSize)
  505. {
  506. //ASSERT(FALSE);
  507. return PRT_SYS; // 超出了文件大小,不正常
  508. }
  509. //
  510. if(iCurrentPos + BLOCK_SIZE > m_iDownloadedSize)
  511. {
  512. ASSERT(FALSE);
  513. return PRT_BLOCK_NOTFOUND; // 尚未下载到这里呢
  514. }
  515. //
  516. if(!ReadFile(m_hFile, currBlock, BLOCK_SIZE, &readBytes, NULL))
  517. {
  518. ASSERT(FALSE);
  519. return PRT_SYS;
  520. }
  521. //
  522. currBlockID++;
  523. //
  524. // 第4~8个字节是first sample offset
  525. UINT sampleOffset = *((UINT*)currBlock+1);
  526. // 注意:8是keySampleOffset和sampleOffset占用的空间大小
  527. if(sampleOffset != UINT_MAX &&
  528.   (sampleOffset < 8 || sampleOffset > BLOCK_SIZE)) 
  529. {
  530. assert(0);
  531. continue; // 错误的SampleOffset,抛弃当前块
  532. }
  533. // 由于CaptureServer的一个BUG,这里作一个修正,随着所有CaptureServer的更新,这里可以去除。 2005.04.18
  534. if(sampleOffset == BLOCK_SIZE)
  535. {
  536. sampleOffset = UINT_MAX;
  537. }
  538. //
  539. if(sampleOff == 0) 
  540. { // 开始读取新的Sample
  541. if(sampleOffset == UINT_MAX)
  542. {
  543. continue; // 新的Sample不在当前Block中,继续寻找下一个
  544. }
  545. else 
  546. {
  547. leftDataInCurrBlock = BLOCK_SIZE-sampleOffset; // 新的Sample位置
  548. }
  549. }
  550. else
  551. {
  552. // 继续读取剩余的数据
  553. leftDataInCurrBlock = BLOCK_SIZE-8; 
  554. assert(sampleOffset==UINT_MAX || sampleOff < sizeof(SampleHeader) || sampleOffset == 8+header.size-sampleOff);
  555. }
  556. //
  557. assert(leftDataInCurrBlock <= BLOCK_SIZE);
  558. break;
  559. }
  560. //
  561. BYTE* startOff = currBlock + (BLOCK_SIZE - leftDataInCurrBlock);
  562. // 尝试读取SampleHeader,直到读取了sizeof(SampleHeader)个字节,即dataOff == sizeof(SampleHeader)
  563. if(sampleOff < sizeof(SampleHeader)) 
  564. {
  565. if(leftDataInCurrBlock < sizeof(SampleHeader)-sampleOff) 
  566. {
  567. // 数据仍然不足sizeof(SampleHeader),继续读取下一个块
  568. memcpy((BYTE*)&header + sampleOff, startOff, leftDataInCurrBlock);
  569. sampleOff += leftDataInCurrBlock;
  570. leftDataInCurrBlock = 0;
  571. //
  572. return LoadSample(header, sampleData, sampleOff, maxSize, isAudio);
  573. }else
  574. {
  575. // 数据已经足够,读取完整的sample header
  576. memcpy((BYTE*)&header + sampleOff, startOff, sizeof(SampleHeader)-sampleOff);
  577. assert(header.size >= sizeof(SampleHeader) && header.size <= maxSize);
  578. //
  579. if(header.size < sizeof(SampleHeader) || header.size > maxSize)
  580. {
  581. // 错误的Header,抛弃当前块,重新读取新的Sample
  582. sampleOff = 0;
  583. leftDataInCurrBlock = 0;
  584. return LoadSample(header, sampleData, sampleOff, maxSize, isAudio);
  585. }
  586. //
  587. leftDataInCurrBlock -= (sizeof(SampleHeader)-sampleOff);
  588. sampleOff = sizeof(SampleHeader);
  589. }
  590. }
  591. startOff = currBlock+(BLOCK_SIZE - leftDataInCurrBlock); 
  592. // 读取SampleHeader之外的数据
  593. if(sampleOff >= sizeof(SampleHeader)) 
  594. {
  595. if(leftDataInCurrBlock < header.size-sampleOff)
  596. {
  597. // 当前块中剩下的数据不足,继续读取下一块
  598. memcpy(sampleData+sampleOff-sizeof(SampleHeader), startOff, leftDataInCurrBlock);
  599. sampleOff += leftDataInCurrBlock;
  600. leftDataInCurrBlock = 0;
  601. return LoadSample(header, sampleData, sampleOff, maxSize, isAudio);
  602. }else
  603. {
  604. // 读取到完整的Sample
  605. memcpy(sampleData+sampleOff-sizeof(SampleHeader), startOff, header.size-sampleOff);
  606. leftDataInCurrBlock -= (header.size-sampleOff);
  607. }
  608. }
  609. //
  610. assert(leftDataInCurrBlock <= BLOCK_SIZE);
  611. return PRT_OK;
  612. }