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

P2P编程

开发平台:

Visual C++

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