MatroskaFile.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:17k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #include "stdafx.h"
  22. #include "MatroskaFile.h"
  23. #include "......DSUtilDSUtil.h"
  24. using namespace MatroskaWriter;
  25. static void bswap(BYTE* s, int len)
  26. {
  27. for(BYTE* d = s + len-1; s < d; s++, d--)
  28. *s ^= *d, *d ^= *s, *s ^= *d;
  29. }
  30. //
  31. CID::CID(DWORD id) : m_id(id)
  32. {
  33. }
  34. QWORD CID::Size(bool fWithHeader)
  35. {
  36. return CUInt(0, m_id).Size(false);
  37. }
  38. HRESULT CID::Write(IStream* pStream)
  39. {
  40. QWORD len = CID::Size();
  41. DWORD id = m_id;
  42. bswap((BYTE*)&id, (int)len);
  43. *(BYTE*)&id = ((*(BYTE*)&id)&(1<<(8-len))-1)|(1<<(8-len));
  44. return pStream->Write(&id, (ULONG)len, NULL);
  45. }
  46. QWORD CID::HeaderSize(QWORD len)
  47. {
  48. return CID::Size() + CLength(len).Size();
  49. }
  50. HRESULT CID::HeaderWrite(IStream* pStream)
  51. {
  52. CID::Write(pStream);
  53. CLength(Size(false)).Write(pStream);
  54. return S_OK;
  55. }
  56. QWORD CBinary::Size(bool fWithHeader)
  57. {
  58. if(GetSize() == 0) return 0;
  59. QWORD len = 0;
  60. len += GetSize();
  61. if(fWithHeader) len += HeaderSize(len);
  62. return len;
  63. }
  64. HRESULT CBinary::Write(IStream* pStream)
  65. {
  66. if(GetSize() == 0) return S_OK;
  67. HeaderWrite(pStream);
  68. return pStream->Write(GetData(), GetSize(), NULL);
  69. }
  70. QWORD CANSI::Size(bool fWithHeader)
  71. {
  72. if(GetLength() == 0) return 0;
  73. QWORD len = 0;
  74. len += GetLength();
  75. if(fWithHeader) len += HeaderSize(len);
  76. return len;
  77. }
  78. HRESULT CANSI::Write(IStream* pStream)
  79. {
  80. if(GetLength() == 0) return S_OK;
  81. HeaderWrite(pStream);
  82. return pStream->Write((LPCSTR)*this, GetLength(), NULL);
  83. }
  84. QWORD CUTF8::Size(bool fWithHeader)
  85. {
  86. if(GetLength() == 0) return 0;
  87. QWORD len = 0;
  88. len += UTF16To8(*this).GetLength();
  89. if(fWithHeader) len += HeaderSize(len);
  90. return len;
  91. }
  92. HRESULT CUTF8::Write(IStream* pStream)
  93. {
  94. if(GetLength() == 0) return S_OK;
  95. HeaderWrite(pStream);
  96. CStringA str = UTF16To8(*this);
  97. return pStream->Write((BYTE*)(LPCSTR)str, str.GetLength(), NULL);
  98. }
  99. template<class T, class BASE>
  100. QWORD CSimpleVar<T, BASE>::Size(bool fWithHeader)
  101. {
  102. if(!m_fSet) return 0;
  103. QWORD len = 0;
  104. len += sizeof(T);
  105. if(fWithHeader) len += HeaderSize(len);
  106. return len;
  107. }
  108. template<class T, class BASE>
  109. HRESULT CSimpleVar<T, BASE>::Write(IStream* pStream)
  110. {
  111. if(!m_fSet) return S_OK;
  112. HeaderWrite(pStream);
  113. T val = m_val;
  114. bswap((BYTE*)&val, sizeof(T));
  115. return pStream->Write(&val, sizeof(T), NULL);
  116. }
  117. QWORD CUInt::Size(bool fWithHeader)
  118. {
  119. if(!m_fSet) return 0;
  120. QWORD len = 0;
  121. if(m_val == 0)
  122. {
  123. len++;
  124. }
  125. else
  126. {
  127. for(int i = 8; i > 0; i--)
  128. {
  129. if(((0xffi64<<((i-1)*8))&m_val))
  130. {
  131. len += i; 
  132. break;
  133. }
  134. }
  135. }
  136. if(fWithHeader) len += HeaderSize(len);
  137. return len;
  138. }
  139. HRESULT CUInt::Write(IStream* pStream)
  140. {
  141. if(!m_fSet) return S_OK;
  142. CID::Write(pStream);
  143. CLength l(Size(false));
  144. l.Write(pStream);
  145. UINT64 val = m_val;
  146. bswap((BYTE*)&val, (int)l);
  147. return pStream->Write(&val, (ULONG)l, NULL);
  148. }
  149. QWORD CInt::Size(bool fWithHeader)
  150. {
  151. if(!m_fSet) return 0;
  152. QWORD len = 0;
  153. if(m_val == 0)
  154. {
  155. len++;
  156. }
  157. else
  158. {
  159. UINT64 val = m_val >= 0 ? m_val : -m_val;
  160. for(int i = 8; i > 0; i--)
  161. {
  162. if(((0xffi64<<((i-1)*8))&val))
  163. {
  164. len += i; 
  165. if(m_val < 0 && !(m_val&(0x80<<(i-1))))
  166. len++;
  167. break;
  168. }
  169. }
  170. }
  171. if(fWithHeader) len += HeaderSize(len);
  172. return len;
  173. }
  174. HRESULT CInt::Write(IStream* pStream)
  175. {
  176. if(!m_fSet) return S_OK;
  177. CID::Write(pStream);
  178. CLength l(Size(false));
  179. l.Write(pStream);
  180. UINT64 val = m_val;
  181. bswap((BYTE*)&val, (int)l);
  182. return pStream->Write(&val, (ULONG)l, NULL);
  183. }
  184. QWORD CLength::Size(bool fWithHeader)
  185. {
  186. if(m_len == 0x00FFFFFFFFFFFFFFi64)
  187. return 8;
  188. QWORD len = 0;
  189. for(int i = 1; i <= 8; i++)
  190. {
  191. if(!(m_len&(~((1i64<<(7*i))-1))) && (m_len&((1i64<<(7*i))-1)) != ((1i64<<(7*i))-1))
  192. {
  193. len += i; 
  194. break;
  195. }
  196. }
  197. return len;
  198. }
  199. HRESULT CLength::Write(IStream* pStream)
  200. {
  201. QWORD len = Size(false);
  202. UINT64 val = m_len;
  203. bswap((BYTE*)&val, (int)len);
  204. *(BYTE*)&val = ((*(BYTE*)&val)&(1<<(8-len))-1)|(1<<(8-len));
  205. return pStream->Write(&val, (ULONG)len, NULL);
  206. }
  207. //
  208. EBML::EBML(DWORD id) 
  209. : CID(id)
  210. , EBMLVersion(0x4286)
  211. , EBMLReadVersion(0x42F7)
  212. , EBMLMaxIDLength(0x42F2)
  213. , EBMLMaxSizeLength(0x42F3)
  214. , DocType(0x4282)
  215. , DocTypeVersion(0x4287)
  216. , DocTypeReadVersion(0x4285)
  217. {
  218. }
  219. QWORD EBML::Size(bool fWithHeader)
  220. {
  221. QWORD len = 0;
  222. len += EBMLVersion.Size();
  223. len += EBMLReadVersion.Size();
  224. len += EBMLMaxIDLength.Size();
  225. len += EBMLMaxSizeLength.Size();
  226. len += DocType.Size();
  227. len += DocTypeVersion.Size();
  228. len += DocTypeReadVersion.Size();
  229. if(fWithHeader) len += HeaderSize(len);
  230. return len;
  231. }
  232. HRESULT EBML::Write(IStream* pStream)
  233. {
  234. HeaderWrite(pStream);
  235. EBMLVersion.Write(pStream);
  236. EBMLReadVersion.Write(pStream);
  237. EBMLMaxIDLength.Write(pStream);
  238. EBMLMaxSizeLength.Write(pStream);
  239. DocType.Write(pStream);
  240. DocTypeVersion.Write(pStream);
  241. DocTypeReadVersion.Write(pStream);
  242. return S_OK;
  243. }
  244. Info::Info(DWORD id)
  245. : CID(id)
  246. , SegmentUID(0x73A4)
  247. , SegmentFilename(0x7384)
  248. , PrevUID(0x3CB923)
  249. , PrevFilename(0x3C83AB)
  250. , NextUID(0x3EB923)
  251. , NextFilename(0x3E83BB)
  252. , TimeCodeScale(0x2AD7B1, 1000000ui64)
  253. , Duration(0x4489)
  254. , DateUTC(0x4461)
  255. , Title(0x7BA9)
  256. , MuxingApp(0x4D80)
  257. , WritingApp(0x5741)
  258. {
  259. }
  260. QWORD Info::Size(bool fWithHeader)
  261. {
  262. QWORD len = 0;
  263. len += SegmentUID.Size();
  264. len += PrevUID.Size();
  265. len += NextUID.Size();
  266. len += SegmentFilename.Size();
  267. len += PrevFilename.Size();
  268. len += NextFilename.Size();
  269. len += TimeCodeScale.Size();
  270. len += Duration.Size();
  271. len += DateUTC.Size();
  272. len += Title.Size();
  273. len += MuxingApp.Size();
  274. len += WritingApp.Size();
  275. if(fWithHeader) len += HeaderSize(len);
  276. return len;
  277. }
  278. HRESULT Info::Write(IStream* pStream)
  279. {
  280. HeaderWrite(pStream);
  281. SegmentUID.Write(pStream);
  282. PrevUID.Write(pStream);
  283. NextUID.Write(pStream);
  284. SegmentFilename.Write(pStream);
  285. PrevFilename.Write(pStream);
  286. NextFilename.Write(pStream);
  287. TimeCodeScale.Write(pStream);
  288. Duration.Write(pStream);
  289. DateUTC.Write(pStream);
  290. Title.Write(pStream);
  291. MuxingApp.Write(pStream);
  292. WritingApp.Write(pStream);
  293. return S_OK;
  294. }
  295. Segment::Segment(DWORD id)
  296. : CID(id)
  297. {
  298. }
  299. QWORD Segment::Size(bool fWithHeader)
  300. {
  301. return 0x00FFFFFFFFFFFFFFi64;
  302. /*
  303. QWORD len = 0;
  304. if(fWithHeader) len += HeaderSize(len);
  305. return len;
  306. */
  307. }
  308. HRESULT Segment::Write(IStream* pStream)
  309. {
  310. HeaderWrite(pStream);
  311. return S_OK;
  312. }
  313. Track::Track(DWORD id)
  314. : CID(id)
  315. {
  316. }
  317. QWORD Track::Size(bool fWithHeader)
  318. {
  319. QWORD len = 0;
  320. len += TrackEntries.Size();
  321. if(fWithHeader) len += HeaderSize(len);
  322. return len;
  323. }
  324. HRESULT Track::Write(IStream* pStream)
  325. {
  326. HeaderWrite(pStream);
  327. TrackEntries.Write(pStream);
  328. return S_OK;
  329. }
  330. TrackEntry::TrackEntry(DWORD id) 
  331. : CID(id)
  332. , TrackNumber(0xD7)
  333. , TrackUID(0x73C5)
  334. , TrackType(0x83)
  335. , FlagEnabled(0xB9)
  336. , FlagDefault(0x88)
  337. , FlagLacing(0x9C)
  338. , MinCache(0x6DE7)
  339. , MaxCache(0x6DF8)
  340. , Name(0x536E)
  341. , Language(0x22B59C)
  342. , CodecID(0x86)
  343. , CodecPrivate(0x63A2)
  344. , CodecName(0x258688)
  345. , CodecSettings(0x3A9697)
  346. , CodecInfoURL(0x3B4040)
  347. , CodecDownloadURL(0x26B240)
  348. , CodecDecodeAll(0xAA)
  349. , TrackOverlay(0x6FAB)
  350. , DefaultDuration(0x23E383)
  351. , v(0xE0)
  352. , a(0xE1)
  353. {
  354. DescType = NoDesc;
  355. }
  356. QWORD TrackEntry::Size(bool fWithHeader)
  357. {
  358. QWORD len = 0;
  359. len += TrackNumber.Size();
  360. len += TrackUID.Size();
  361. len += TrackType.Size();
  362. len += FlagEnabled.Size();
  363. len += FlagDefault.Size();
  364. len += FlagLacing.Size();
  365. len += MinCache.Size();
  366. len += MaxCache.Size();
  367. len += Name.Size();
  368. len += Language.Size();
  369. len += CodecID.Size();
  370. len += CodecPrivate.Size();
  371. len += CodecName.Size();
  372. len += CodecSettings.Size();
  373. len += CodecInfoURL.Size();
  374. len += CodecDownloadURL.Size();
  375. len += CodecDecodeAll.Size();
  376. len += TrackOverlay.Size();
  377. len += DefaultDuration.Size();
  378. if(DescType == TypeVideo) len += v.Size();
  379. if(DescType == TypeAudio) len += a.Size();
  380. if(fWithHeader) len += HeaderSize(len);
  381. return len;
  382. }
  383. HRESULT TrackEntry::Write(IStream* pStream)
  384. {
  385. HeaderWrite(pStream);
  386. TrackNumber.Write(pStream);
  387. TrackUID.Write(pStream);
  388. TrackType.Write(pStream);
  389. FlagEnabled.Write(pStream);
  390. FlagDefault.Write(pStream);
  391. FlagLacing.Write(pStream);
  392. MinCache.Write(pStream);
  393. MaxCache.Write(pStream);
  394. Name.Write(pStream);
  395. Language.Write(pStream);
  396. CodecID.Write(pStream);
  397. CodecPrivate.Write(pStream);
  398. CodecName.Write(pStream);
  399. CodecSettings.Write(pStream);
  400. CodecInfoURL.Write(pStream);
  401. CodecDownloadURL.Write(pStream);
  402. CodecDecodeAll.Write(pStream);
  403. TrackOverlay.Write(pStream);
  404. DefaultDuration.Write(pStream);
  405. if(DescType == TypeVideo) v.Write(pStream);
  406. if(DescType == TypeAudio) a.Write(pStream);
  407. return S_OK;
  408. }
  409. Video::Video(DWORD id)
  410. : CID(id)
  411. , FlagInterlaced(0x9A)
  412. , StereoMode(0x53B8)
  413. , PixelWidth(0xB0)
  414. , PixelHeight(0xBA)
  415. , DisplayWidth(0x54B0)
  416. , DisplayHeight(0x54BA)
  417. , DisplayUnit(0x54B2)
  418. , AspectRatioType(0x54B3)
  419. , ColourSpace(0x2EB524)
  420. , GammaValue(0x2FB523)
  421. , FramePerSec(0x2383E3)
  422. {
  423. }
  424. QWORD Video::Size(bool fWithHeader)
  425. {
  426. QWORD len = 0;
  427. len += FlagInterlaced.Size();
  428. len += StereoMode.Size();
  429. len += PixelWidth.Size();
  430. len += PixelHeight.Size();
  431. len += DisplayWidth.Size();
  432. len += DisplayHeight.Size();
  433. len += DisplayUnit.Size();
  434. len += AspectRatioType.Size();
  435. len += ColourSpace.Size();
  436. len += GammaValue.Size();
  437. len += FramePerSec.Size();
  438. if(fWithHeader) len += HeaderSize(len);
  439. return len;
  440. }
  441. HRESULT Video::Write(IStream* pStream)
  442. {
  443. HeaderWrite(pStream);
  444. FlagInterlaced.Write(pStream);
  445. StereoMode.Write(pStream);
  446. PixelWidth.Write(pStream);
  447. PixelHeight.Write(pStream);
  448. DisplayWidth.Write(pStream);
  449. DisplayHeight.Write(pStream);
  450. DisplayUnit.Write(pStream);
  451. AspectRatioType.Write(pStream);
  452. ColourSpace.Write(pStream);
  453. GammaValue.Write(pStream);
  454. FramePerSec.Write(pStream);
  455. return S_OK;
  456. }
  457. Audio::Audio(DWORD id)
  458. : CID(id)
  459. , SamplingFrequency(0xB5)
  460. , OutputSamplingFrequency(0x78B5)
  461. , Channels(0x9F)
  462. , ChannelPositions(0x7D7B)
  463. , BitDepth(0x6264)
  464. {
  465. }
  466. QWORD Audio::Size(bool fWithHeader)
  467. {
  468. QWORD len = 0;
  469. len += SamplingFrequency.Size();
  470. len += OutputSamplingFrequency.Size();
  471. len += Channels.Size();
  472. len += ChannelPositions.Size();
  473. len += BitDepth.Size();
  474. if(fWithHeader) len += HeaderSize(len);
  475. return len;
  476. }
  477. HRESULT Audio::Write(IStream* pStream)
  478. {
  479. HeaderWrite(pStream);
  480. SamplingFrequency.Write(pStream);
  481. OutputSamplingFrequency.Write(pStream);
  482. Channels.Write(pStream);
  483. ChannelPositions.Write(pStream);
  484. BitDepth.Write(pStream);
  485. return S_OK;
  486. }
  487. Cluster::Cluster(DWORD id)
  488. : CID(id)
  489. , TimeCode(0xE7)
  490. , Position(0xA7)
  491. , PrevSize(0xAB)
  492. {
  493. }
  494. QWORD Cluster::Size(bool fWithHeader)
  495. {
  496. QWORD len = 0;
  497. len += TimeCode.Size();
  498. len += Position.Size();
  499. len += PrevSize.Size();
  500. len += BlockGroups.Size();
  501. if(fWithHeader) len += HeaderSize(len);
  502. return len;
  503. }
  504. HRESULT Cluster::Write(IStream* pStream)
  505. {
  506. HeaderWrite(pStream);
  507. TimeCode.Write(pStream);
  508. Position.Write(pStream);
  509. PrevSize.Write(pStream);
  510. BlockGroups.Write(pStream);
  511. return S_OK;
  512. }
  513. BlockGroup::BlockGroup(DWORD id)
  514. : CID(id)
  515. , BlockDuration(0x9B)
  516. , ReferencePriority(0xFA)
  517. , ReferenceBlock(0xFB)
  518. , ReferenceVirtual(0xFD)
  519. , CodecState(0xA4)
  520. {
  521. }
  522. QWORD BlockGroup::Size(bool fWithHeader)
  523. {
  524. QWORD len = 0;
  525. len += BlockDuration.Size();
  526. len += ReferencePriority.Size();
  527. len += ReferenceBlock.Size();
  528. len += ReferenceVirtual.Size();
  529. len += CodecState.Size();
  530. len += Block.Size();
  531. if(fWithHeader) len += HeaderSize(len);
  532. return len;
  533. }
  534. HRESULT BlockGroup::Write(IStream* pStream)
  535. {
  536. HeaderWrite(pStream);
  537. BlockDuration.Write(pStream);
  538. ReferencePriority.Write(pStream);
  539. ReferenceBlock.Write(pStream);
  540. ReferenceVirtual.Write(pStream);
  541. CodecState.Write(pStream);
  542. Block.Write(pStream);
  543. return S_OK;
  544. }
  545. CBlock::CBlock(DWORD id)
  546. : CID(id)
  547. , TimeCode(0)
  548. {
  549. }
  550. QWORD CBlock::Size(bool fWithHeader)
  551. {
  552. QWORD len = 0;
  553. len += TrackNumber.Size() + 2 + 1; // TrackNumber + TimeCode + Lacing
  554. if(BlockData.GetCount() > 1)
  555. {
  556. len += 1; // nBlockData
  557. POSITION pos = BlockData.GetHeadPosition();
  558. while(pos)
  559. {
  560. CBinary* b = BlockData.GetNext(pos);
  561. if(pos) len += b->GetCount()/255 + 1;
  562. }
  563. }
  564. POSITION pos = BlockData.GetHeadPosition();
  565. while(pos)
  566. {
  567. CBinary* b = BlockData.GetNext(pos);
  568. len += b->GetCount();
  569. }
  570. if(fWithHeader) len += HeaderSize(len);
  571. return len;
  572. }
  573. HRESULT CBlock::Write(IStream* pStream)
  574. {
  575. HeaderWrite(pStream);
  576. TrackNumber.Write(pStream);
  577. short t = (short)TimeCode;
  578. bswap((BYTE*)&t, 2);
  579. pStream->Write(&t, 2, NULL);
  580. BYTE Lacing = 0;
  581. BYTE n = BlockData.GetCount();
  582. if(n > 1) Lacing |= 2;
  583. pStream->Write(&Lacing, 1, NULL);
  584. if(n > 1)
  585. {
  586. pStream->Write(&n, 1, NULL);
  587. POSITION pos = BlockData.GetHeadPosition();
  588. while(pos)
  589. {
  590. CBinary* b = BlockData.GetNext(pos);
  591. if(pos)
  592. {
  593. int len = b->GetCount();
  594. while(len >= 0)
  595. {
  596. n = min(len, 255);
  597. pStream->Write(&n, 1, NULL);
  598. len -= 255;
  599. }
  600. }
  601. }
  602. }
  603. POSITION pos = BlockData.GetHeadPosition();
  604. while(pos)
  605. {
  606. CBinary* b = BlockData.GetNext(pos);
  607. pStream->Write(b->GetData(), b->GetCount(), NULL);
  608. }
  609. return S_OK;
  610. }
  611. Cue::Cue(DWORD id)
  612. : CID(id)
  613. {
  614. }
  615. QWORD Cue::Size(bool fWithHeader)
  616. {
  617. QWORD len = 0;
  618. len += CuePoints.Size();
  619. if(fWithHeader) len += HeaderSize(len);
  620. return len;
  621. }
  622. HRESULT Cue::Write(IStream* pStream)
  623. {
  624. HeaderWrite(pStream);
  625. CuePoints.Write(pStream);
  626. return S_OK;
  627. }
  628. CuePoint::CuePoint(DWORD id)
  629. : CID(id)
  630. , CueTime(0xB3)
  631. {
  632. }
  633. QWORD CuePoint::Size(bool fWithHeader)
  634. {
  635. QWORD len = 0;
  636. len += CueTime.Size();
  637. len += CueTrackPositions.Size();
  638. if(fWithHeader) len += HeaderSize(len);
  639. return len;
  640. }
  641. HRESULT CuePoint::Write(IStream* pStream)
  642. {
  643. HeaderWrite(pStream);
  644. CueTime.Write(pStream);
  645. CueTrackPositions.Write(pStream);
  646. return S_OK;
  647. }
  648. CueTrackPosition::CueTrackPosition(DWORD id)
  649. : CID(id)
  650. , CueTrack(0xF7)
  651. , CueClusterPosition(0xF1)
  652. , CueBlockNumber(0x5387)
  653. , CueCodecState(0xEA)
  654. {
  655. }
  656. QWORD CueTrackPosition::Size(bool fWithHeader)
  657. {
  658. QWORD len = 0;
  659. len += CueTrack.Size();
  660. len += CueClusterPosition.Size();
  661. len += CueBlockNumber.Size();
  662. len += CueCodecState.Size();
  663. // len += CueReferences.Size();
  664. if(fWithHeader) len += HeaderSize(len);
  665. return len;
  666. }
  667. HRESULT CueTrackPosition::Write(IStream* pStream)
  668. {
  669. HeaderWrite(pStream);
  670. CueTrack.Write(pStream);
  671. CueClusterPosition.Write(pStream);
  672. CueBlockNumber.Write(pStream);
  673. CueCodecState.Write(pStream);
  674. // CueReferences.Write(pStream);
  675. return S_OK;
  676. }
  677. Seek::Seek(DWORD id)
  678. : CID(id)
  679. {
  680. }
  681. QWORD Seek::Size(bool fWithHeader)
  682. {
  683. QWORD len = 0;
  684. len += SeekHeads.Size();
  685. if(fWithHeader) len += HeaderSize(len);
  686. return len;
  687. }
  688. HRESULT Seek::Write(IStream* pStream)
  689. {
  690. HeaderWrite(pStream);
  691. SeekHeads.Write(pStream);
  692. return S_OK;
  693. }
  694. SeekID::SeekID(DWORD id)
  695. : CID(id)
  696. , m_id(0)
  697. {
  698. }
  699. QWORD SeekID::Size(bool fWithHeader)
  700. {
  701. QWORD len = 0;
  702. len += m_id.Size();
  703. if(fWithHeader) len += HeaderSize(len);
  704. return len;
  705. }
  706. HRESULT SeekID::Write(IStream* pStream)
  707. {
  708. HeaderWrite(pStream);
  709. m_id.Write(pStream);
  710. return S_OK;
  711. }
  712. SeekHead::SeekHead(DWORD id)
  713. : CID(id)
  714. , Position(0x53AC)
  715. {
  716. }
  717. QWORD SeekHead::Size(bool fWithHeader)
  718. {
  719. QWORD len = 0;
  720. len += ID.Size();
  721. len += Position.Size();
  722. if(fWithHeader) len += HeaderSize(len);
  723. return len;
  724. }
  725. HRESULT SeekHead::Write(IStream* pStream)
  726. {
  727. HeaderWrite(pStream);
  728. ID.Write(pStream);
  729. Position.Write(pStream);
  730. return S_OK;
  731. }
  732. Tags::Tags(DWORD id)
  733. : CID(id)
  734. {
  735. }
  736. QWORD Tags::Size(bool fWithHeader)
  737. {
  738. QWORD len = 0;
  739. // len += .Size();
  740. if(fWithHeader) len += HeaderSize(len);
  741. return len;
  742. }
  743. HRESULT Tags::Write(IStream* pStream)
  744. {
  745. HeaderWrite(pStream);
  746. // .Write(pStream);
  747. return S_OK;
  748. }
  749. Void::Void(QWORD len, DWORD id)
  750. : CID(id)
  751. , m_len(len)
  752. {
  753. }
  754. QWORD Void::Size(bool fWithHeader)
  755. {
  756. QWORD len = 0;
  757. len += m_len;
  758. if(fWithHeader) len += HeaderSize(len);
  759. return len;
  760. }
  761. HRESULT Void::Write(IStream* pStream)
  762. {
  763. HeaderWrite(pStream);
  764. BYTE buff[64];
  765. memset(buff, 0x80, sizeof(buff));
  766. for(int len = (int)m_len; len > 0; len -= sizeof(buff))
  767. pStream->Write(buff, (ULONG)min(sizeof(buff), len), NULL);
  768. return S_OK;
  769. }