- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# MatroskaFile.cpp

    00001 /*
    00002  *      Copyright (C) 2003-2005 Gabest
    00003  *      http://www.gabest.org
    00004  *
    00005  *  This Program is free software; you can redistribute it and/or modify
    00006  *  it under the terms of the GNU General Public License as published by
    00007  *  the Free Software Foundation; either version 2, or (at your option)
    00008  *  any later version.
    00009  *
    00010  *  This Program is distributed in the hope that it will be useful,
    00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    00013  *  GNU General Public License for more details.
    00014  *
    00015  *  You should have received a copy of the GNU General Public License
    00016  *  along with GNU Make; see the file COPYING.  If not, write to
    00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
    00018  *  http://www.gnu.org/copyleft/gpl.html
    00019  *
    00020  */
    00021
    00022 #include "stdafx.h"
    00023 #include "MatroskaFile.h"
    00024 #include "..\..\..\DSUtil\DSUtil.h"
    00025
    00026 using namespace MatroskaWriter;
    00027
    00028 static void bswap(BYTE* s, int len)
    00029 {
    00030         for(BYTE* d = s + len-1; s < d; s++, d--)
    00031                 *s ^= *d, *d ^= *s, *s ^= *d;
    00032 }
    00033
    00034 //
    00035
    00036 CID::CID(DWORD id) : m_id(id)
    00037 {
    00038 }
    00039
    00040 QWORD CID::Size(bool fWithHeader)
    00041 {
    00042         return CUInt(0, m_id).Size(false);
    00043 }
    00044
    00045 HRESULT CID::Write(IStream* pStream)
    00046 {
    00047         QWORD len = CID::Size();
    00048         DWORD id = m_id;
    00049         bswap((BYTE*)&id, (int)len);
    00050         *(BYTE*)&id = ((*(BYTE*)&id)&(1<<(8-len))-1)|(1<<(8-len));
    00051         return pStream->Write(&id, (ULONG)len, NULL);
    00052 }
    00053
    00054 QWORD CID::HeaderSize(QWORD len)
    00055 {
    00056         return CID::Size() + CLength(len).Size();
    00057 }
    00058
    00059 HRESULT CID::HeaderWrite(IStream* pStream)
    00060 {
    00061         CID::Write(pStream);
    00062         CLength(Size(false)).Write(pStream);
    00063         return S_OK;
    00064 }
    00065
    00066 QWORD CBinary::Size(bool fWithHeader)
    00067 {
    00068         if(GetSize() == 0) return 0;
    00069
    00070         QWORD len = 0;
    00071         len += GetSize();
    00072         if(fWithHeader) len += HeaderSize(len);
    00073         return len;
    00074 }
    00075
    00076 HRESULT CBinary::Write(IStream* pStream)
    00077 {
    00078         if(GetSize() == 0) return S_OK;
    00079
    00080         HeaderWrite(pStream);
    00081         return pStream->Write(GetData(), GetSize(), NULL);
    00082 }
    00083
    00084 QWORD CANSI::Size(bool fWithHeader)
    00085 {
    00086         if(GetLength() == 0) return 0;
    00087
    00088         QWORD len = 0;
    00089         len += GetLength();
    00090         if(fWithHeader) len += HeaderSize(len);
    00091         return len;
    00092 }
    00093
    00094 HRESULT CANSI::Write(IStream* pStream)
    00095 {
    00096         if(GetLength() == 0) return S_OK;
    00097
    00098         HeaderWrite(pStream);
    00099         return pStream->Write((LPCSTR)*this, GetLength(), NULL);
    00100 }
    00101
    00102 QWORD CUTF8::Size(bool fWithHeader)
    00103 {
    00104         if(GetLength() == 0) return 0;
    00105
    00106         QWORD len = 0;
    00107         len += UTF16To8(*this).GetLength();
    00108         if(fWithHeader) len += HeaderSize(len);
    00109         return len;
    00110 }
    00111
    00112 HRESULT CUTF8::Write(IStream* pStream)
    00113 {
    00114         if(GetLength() == 0) return S_OK;
    00115
    00116         HeaderWrite(pStream);
    00117         CStringA str = UTF16To8(*this);
    00118         return pStream->Write((BYTE*)(LPCSTR)str, str.GetLength(), NULL);
    00119 }
    00120
    00121 template<class T, class BASE>
    00122 QWORD CSimpleVar<T, BASE>::Size(bool fWithHeader)
    00123 {
    00124         if(!m_fSet) return 0;
    00125
    00126         QWORD len = 0;
    00127         len += sizeof(T);
    00128         if(fWithHeader) len += HeaderSize(len);
    00129         return len;
    00130 }
    00131
    00132 template<class T, class BASE>
    00133 HRESULT CSimpleVar<T, BASE>::Write(IStream* pStream)
    00134 {
    00135         if(!m_fSet) return S_OK;
    00136
    00137         HeaderWrite(pStream);
    00138         T val = m_val;
    00139         bswap((BYTE*)&val, sizeof(T));
    00140         return pStream->Write(&val, sizeof(T), NULL);
    00141 }
    00142
    00143 QWORD CUInt::Size(bool fWithHeader)
    00144 {
    00145         if(!m_fSet) return 0;
    00146
    00147         QWORD len = 0;
    00148
    00149         if(m_val == 0)
    00150         {
    00151                 len++;
    00152         }
    00153         else
    00154         {
    00155                 for(int i = 8; i > 0; i--)
    00156                 {
    00157                         if(((0xffi64<<((i-1)*8))&m_val))
    00158                         {
    00159                                 len += i;
    00160                                 break;
    00161                         }
    00162                 }
    00163         }
    00164         if(fWithHeader) len += HeaderSize(len);
    00165         return len;
    00166 }
    00167
    00168 HRESULT CUInt::Write(IStream* pStream)
    00169 {
    00170         if(!m_fSet) return S_OK;
    00171
    00172         CID::Write(pStream);
    00173         CLength l(Size(false));
    00174         l.Write(pStream);
    00175         UINT64 val = m_val;
    00176         bswap((BYTE*)&val, (int)l);
    00177         return pStream->Write(&val, (ULONG)l, NULL);
    00178 }
    00179
    00180 QWORD CInt::Size(bool fWithHeader)
    00181 {
    00182         if(!m_fSet) return 0;
    00183
    00184         QWORD len = 0;
    00185
    00186         if(m_val == 0)
    00187         {
    00188                 len++;
    00189         }
    00190         else
    00191         {
    00192                 UINT64 val = m_val >= 0 ? m_val : -m_val;
    00193                 for(int i = 8; i > 0; i--)
    00194                 {
    00195                         if(((0xffi64<<((i-1)*8))&val))
    00196                         {
    00197                                 len += i;
    00198                                 if(m_val < 0 && !(m_val&(0x80<<(i-1))))
    00199                                         len++;
    00200                                 break;
    00201                         }
    00202                 }
    00203         }
    00204         if(fWithHeader) len += HeaderSize(len);
    00205         return len;
    00206 }
    00207
    00208 HRESULT CInt::Write(IStream* pStream)
    00209 {
    00210         if(!m_fSet) return S_OK;
    00211
    00212         CID::Write(pStream);
    00213         CLength l(Size(false));
    00214         l.Write(pStream);
    00215         UINT64 val = m_val;
    00216         bswap((BYTE*)&val, (int)l);
    00217         return pStream->Write(&val, (ULONG)l, NULL);
    00218 }
    00219
    00220 QWORD CLength::Size(bool fWithHeader)
    00221 {
    00222         if(m_len == 0x00FFFFFFFFFFFFFFi64)
    00223                 return 8;
    00224
    00225         QWORD len = 0;
    00226         for(int i = 1; i <= 8; i++)
    00227         {
    00228                 if(!(m_len&(~((1i64<<(7*i))-1))) && (m_len&((1i64<<(7*i))-1)) != ((1i64<<(7*i))-1))
    00229                 {
    00230                         len += i;
    00231                         break;
    00232                 }
    00233         }
    00234         return len;
    00235 }
    00236
    00237 HRESULT CLength::Write(IStream* pStream)
    00238 {
    00239         QWORD len = Size(false);
    00240         UINT64 val = m_len;
    00241         bswap((BYTE*)&val, (int)len);
    00242         *(BYTE*)&val = ((*(BYTE*)&val)&(1<<(8-len))-1)|(1<<(8-len));
    00243         return pStream->Write(&val, (ULONG)len, NULL);
    00244 }
    00245
    00246 //
    00247
    00248 EBML::EBML(DWORD id)
    00249         : CID(id)
    00250         , EBMLVersion(0x4286)
    00251         , EBMLReadVersion(0x42F7)
    00252         , EBMLMaxIDLength(0x42F2)
    00253         , EBMLMaxSizeLength(0x42F3)
    00254         , DocType(0x4282)
    00255         , DocTypeVersion(0x4287)
    00256         , DocTypeReadVersion(0x4285)
    00257 {
    00258 }
    00259
    00260 QWORD EBML::Size(bool fWithHeader)
    00261 {
    00262         QWORD len = 0;
    00263         len += EBMLVersion.Size();
    00264         len += EBMLReadVersion.Size();
    00265         len += EBMLMaxIDLength.Size();
    00266         len += EBMLMaxSizeLength.Size();
    00267         len += DocType.Size();
    00268         len += DocTypeVersion.Size();
    00269         len += DocTypeReadVersion.Size();
    00270         if(fWithHeader) len += HeaderSize(len);
    00271         return len;
    00272 }
    00273
    00274 HRESULT EBML::Write(IStream* pStream)
    00275 {
    00276         HeaderWrite(pStream);
    00277         EBMLVersion.Write(pStream);
    00278         EBMLReadVersion.Write(pStream);
    00279         EBMLMaxIDLength.Write(pStream);
    00280         EBMLMaxSizeLength.Write(pStream);
    00281         DocType.Write(pStream);
    00282         DocTypeVersion.Write(pStream);
    00283         DocTypeReadVersion.Write(pStream);
    00284         return S_OK;
    00285 }
    00286
    00287 Info::Info(DWORD id)
    00288         : CID(id)
    00289         , SegmentUID(0x73A4)
    00290         , SegmentFilename(0x7384)
    00291         , PrevUID(0x3CB923)
    00292         , PrevFilename(0x3C83AB)
    00293         , NextUID(0x3EB923)
    00294         , NextFilename(0x3E83BB)
    00295         , TimeCodeScale(0x2AD7B1, 1000000ui64)
    00296         , Duration(0x4489)
    00297         , DateUTC(0x4461)
    00298         , Title(0x7BA9)
    00299         , MuxingApp(0x4D80)
    00300         , WritingApp(0x5741)
    00301 {
    00302 }
    00303
    00304 QWORD Info::Size(bool fWithHeader)
    00305 {
    00306         QWORD len = 0;
    00307         len += SegmentUID.Size();
    00308         len += PrevUID.Size();
    00309         len += NextUID.Size();
    00310         len += SegmentFilename.Size();
    00311         len += PrevFilename.Size();
    00312         len += NextFilename.Size();
    00313         len += TimeCodeScale.Size();
    00314         len += Duration.Size();
    00315         len += DateUTC.Size();
    00316         len += Title.Size();
    00317         len += MuxingApp.Size();
    00318         len += WritingApp.Size();
    00319         if(fWithHeader) len += HeaderSize(len);
    00320         return len;
    00321 }
    00322
    00323 HRESULT Info::Write(IStream* pStream)
    00324 {
    00325         HeaderWrite(pStream);
    00326         SegmentUID.Write(pStream);
    00327         PrevUID.Write(pStream);
    00328         NextUID.Write(pStream);
    00329         SegmentFilename.Write(pStream);
    00330         PrevFilename.Write(pStream);
    00331         NextFilename.Write(pStream);
    00332         TimeCodeScale.Write(pStream);
    00333         Duration.Write(pStream);
    00334         DateUTC.Write(pStream);
    00335         Title.Write(pStream);
    00336         MuxingApp.Write(pStream);
    00337         WritingApp.Write(pStream);
    00338         return S_OK;
    00339 }
    00340
    00341 Segment::Segment(DWORD id)
    00342         : CID(id)
    00343 {
    00344 }
    00345
    00346 QWORD Segment::Size(bool fWithHeader)
    00347 {
    00348         return 0x00FFFFFFFFFFFFFFi64;
    00349 /*
    00350         QWORD len = 0;
    00351         if(fWithHeader) len += HeaderSize(len);
    00352         return len;
    00353 */
    00354 }
    00355
    00356 HRESULT Segment::Write(IStream* pStream)
    00357 {
    00358         HeaderWrite(pStream);
    00359         return S_OK;
    00360 }
    00361
    00362 Track::Track(DWORD id)
    00363         : CID(id)
    00364 {
    00365 }
    00366
    00367 QWORD Track::Size(bool fWithHeader)
    00368 {
    00369         QWORD len = 0;
    00370         len += TrackEntries.Size();
    00371         if(fWithHeader) len += HeaderSize(len);
    00372         return len;
    00373 }
    00374
    00375 HRESULT Track::Write(IStream* pStream)
    00376 {
    00377         HeaderWrite(pStream);
    00378         TrackEntries.Write(pStream);
    00379         return S_OK;
    00380 }
    00381
    00382 TrackEntry::TrackEntry(DWORD id)
    00383         : CID(id)
    00384         , TrackNumber(0xD7)
    00385         , TrackUID(0x73C5)
    00386         , TrackType(0x83)
    00387         , FlagEnabled(0xB9)
    00388         , FlagDefault(0x88)
    00389         , FlagLacing(0x9C)
    00390         , MinCache(0x6DE7)
    00391         , MaxCache(0x6DF8)
    00392         , Name(0x536E)
    00393         , Language(0x22B59C)
    00394         , CodecID(0x86)
    00395         , CodecPrivate(0x63A2)
    00396         , CodecName(0x258688)
    00397         , CodecSettings(0x3A9697)
    00398         , CodecInfoURL(0x3B4040)
    00399         , CodecDownloadURL(0x26B240)
    00400         , CodecDecodeAll(0xAA)
    00401         , TrackOverlay(0x6FAB)
    00402         , DefaultDuration(0x23E383)
    00403         , v(0xE0)
    00404         , a(0xE1)
    00405 {
    00406         DescType = NoDesc;
    00407 }
    00408
    00409 QWORD TrackEntry::Size(bool fWithHeader)
    00410 {
    00411         QWORD len = 0;
    00412         len += TrackNumber.Size();
    00413         len += TrackUID.Size();
    00414         len += TrackType.Size();
    00415         len += FlagEnabled.Size();
    00416         len += FlagDefault.Size();
    00417         len += FlagLacing.Size();
    00418         len += MinCache.Size();
    00419         len += MaxCache.Size();
    00420         len += Name.Size();
    00421         len += Language.Size();
    00422         len += CodecID.Size();
    00423         len += CodecPrivate.Size();
    00424         len += CodecName.Size();
    00425         len += CodecSettings.Size();
    00426         len += CodecInfoURL.Size();
    00427         len += CodecDownloadURL.Size();
    00428         len += CodecDecodeAll.Size();
    00429         len += TrackOverlay.Size();
    00430         len += DefaultDuration.Size();
    00431         if(DescType == TypeVideo) len += v.Size();
    00432         if(DescType == TypeAudio) len += a.Size();
    00433         if(fWithHeader) len += HeaderSize(len);
    00434         return len;
    00435 }
    00436
    00437 HRESULT TrackEntry::Write(IStream* pStream)
    00438 {
    00439         HeaderWrite(pStream);
    00440         TrackNumber.Write(pStream);
    00441         TrackUID.Write(pStream);
    00442         TrackType.Write(pStream);
    00443         FlagEnabled.Write(pStream);
    00444         FlagDefault.Write(pStream);
    00445         FlagLacing.Write(pStream);
    00446         MinCache.Write(pStream);
    00447         MaxCache.Write(pStream);
    00448         Name.Write(pStream);
    00449         Language.Write(pStream);
    00450         CodecID.Write(pStream);
    00451         CodecPrivate.Write(pStream);
    00452         CodecName.Write(pStream);
    00453         CodecSettings.Write(pStream);
    00454         CodecInfoURL.Write(pStream);
    00455         CodecDownloadURL.Write(pStream);
    00456         CodecDecodeAll.Write(pStream);
    00457         TrackOverlay.Write(pStream);
    00458         DefaultDuration.Write(pStream);
    00459         if(DescType == TypeVideo) v.Write(pStream);
    00460         if(DescType == TypeAudio) a.Write(pStream);
    00461         return S_OK;
    00462 }
    00463
    00464 Video::Video(DWORD id)
    00465         : CID(id)
    00466         , FlagInterlaced(0x9A)
    00467         , StereoMode(0x53B8)
    00468         , PixelWidth(0xB0)
    00469         , PixelHeight(0xBA)
    00470         , DisplayWidth(0x54B0)
    00471         , DisplayHeight(0x54BA)
    00472         , DisplayUnit(0x54B2)
    00473         , AspectRatioType(0x54B3)
    00474         , ColourSpace(0x2EB524)
    00475         , GammaValue(0x2FB523)
    00476         , FramePerSec(0x2383E3)
    00477 {
    00478 }
    00479
    00480 QWORD Video::Size(bool fWithHeader)
    00481 {
    00482         QWORD len = 0;
    00483         len += FlagInterlaced.Size();
    00484         len += StereoMode.Size();
    00485         len += PixelWidth.Size();
    00486         len += PixelHeight.Size();
    00487         len += DisplayWidth.Size();
    00488         len += DisplayHeight.Size();
    00489         len += DisplayUnit.Size();
    00490         len += AspectRatioType.Size();
    00491         len += ColourSpace.Size();
    00492         len += GammaValue.Size();
    00493         len += FramePerSec.Size();
    00494         if(fWithHeader) len += HeaderSize(len);
    00495         return len;
    00496 }
    00497
    00498 HRESULT Video::Write(IStream* pStream)
    00499 {
    00500         HeaderWrite(pStream);
    00501         FlagInterlaced.Write(pStream);
    00502         StereoMode.Write(pStream);
    00503         PixelWidth.Write(pStream);
    00504         PixelHeight.Write(pStream);
    00505         DisplayWidth.Write(pStream);
    00506         DisplayHeight.Write(pStream);
    00507         DisplayUnit.Write(pStream);
    00508         AspectRatioType.Write(pStream);
    00509         ColourSpace.Write(pStream);
    00510         GammaValue.Write(pStream);
    00511         FramePerSec.Write(pStream);
    00512         return S_OK;
    00513 }
    00514
    00515 Audio::Audio(DWORD id)
    00516         : CID(id)
    00517         , SamplingFrequency(0xB5)
    00518         , OutputSamplingFrequency(0x78B5)
    00519         , Channels(0x9F)
    00520         , ChannelPositions(0x7D7B)
    00521         , BitDepth(0x6264)
    00522 {
    00523 }
    00524
    00525 QWORD Audio::Size(bool fWithHeader)
    00526 {
    00527         QWORD len = 0;
    00528         len += SamplingFrequency.Size();
    00529         len += OutputSamplingFrequency.Size();
    00530         len += Channels.Size();
    00531         len += ChannelPositions.Size();
    00532         len += BitDepth.Size();
    00533         if(fWithHeader) len += HeaderSize(len);
    00534         return len;
    00535 }
    00536
    00537 HRESULT Audio::Write(IStream* pStream)
    00538 {
    00539         HeaderWrite(pStream);
    00540         SamplingFrequency.Write(pStream);
    00541         OutputSamplingFrequency.Write(pStream);
    00542         Channels.Write(pStream);
    00543         ChannelPositions.Write(pStream);
    00544         BitDepth.Write(pStream);
    00545         return S_OK;
    00546 }
    00547
    00548 Cluster::Cluster(DWORD id)
    00549         : CID(id)
    00550         , TimeCode(0xE7)
    00551         , Position(0xA7)
    00552         , PrevSize(0xAB)
    00553 {
    00554 }
    00555
    00556 QWORD Cluster::Size(bool fWithHeader)
    00557 {
    00558         QWORD len = 0;
    00559         len += TimeCode.Size();
    00560         len += Position.Size();
    00561         len += PrevSize.Size();
    00562         len += BlockGroups.Size();
    00563         if(fWithHeader) len += HeaderSize(len);
    00564         return len;
    00565 }
    00566
    00567 HRESULT Cluster::Write(IStream* pStream)
    00568 {
    00569         HeaderWrite(pStream);
    00570         TimeCode.Write(pStream);
    00571         Position.Write(pStream);
    00572         PrevSize.Write(pStream);
    00573         BlockGroups.Write(pStream);
    00574         return S_OK;
    00575 }
    00576
    00577 BlockGroup::BlockGroup(DWORD id)
    00578         : CID(id)
    00579         , BlockDuration(0x9B)
    00580         , ReferencePriority(0xFA)
    00581         , ReferenceBlock(0xFB)
    00582         , ReferenceVirtual(0xFD)
    00583         , CodecState(0xA4)
    00584 {
    00585 }
    00586
    00587 QWORD BlockGroup::Size(bool fWithHeader)
    00588 {
    00589         QWORD len = 0;
    00590         len += BlockDuration.Size();
    00591         len += ReferencePriority.Size();
    00592         len += ReferenceBlock.Size();
    00593         len += ReferenceVirtual.Size();
    00594         len += CodecState.Size();
    00595         len += Block.Size();
    00596         if(fWithHeader) len += HeaderSize(len);
    00597         return len;
    00598 }
    00599
    00600 HRESULT BlockGroup::Write(IStream* pStream)
    00601 {
    00602         HeaderWrite(pStream);
    00603         BlockDuration.Write(pStream);
    00604         ReferencePriority.Write(pStream);
    00605         ReferenceBlock.Write(pStream);
    00606         ReferenceVirtual.Write(pStream);
    00607         CodecState.Write(pStream);
    00608         Block.Write(pStream);
    00609         return S_OK;
    00610 }
    00611
    00612 CBlock::CBlock(DWORD id)
    00613         : CID(id)
    00614         , TimeCode(0)
    00615 {
    00616 }
    00617
    00618 QWORD CBlock::Size(bool fWithHeader)
    00619 {
    00620         QWORD len = 0;
    00621         len += TrackNumber.Size() + 2 + 1; // TrackNumber + TimeCode + Lacing
    00622         if(BlockData.GetCount() > 1)
    00623         {
    00624                 len += 1; // nBlockData
    00625                 POSITION pos = BlockData.GetHeadPosition();
    00626                 while(pos)
    00627                 {
    00628                         CBinary* b = BlockData.GetNext(pos);
    00629                         if(pos) len += b->GetCount()/255 + 1;
    00630                 }
    00631         }
    00632         POSITION pos = BlockData.GetHeadPosition();
    00633         while(pos)
    00634         {
    00635                 CBinary* b = BlockData.GetNext(pos);
    00636                 len += b->GetCount();
    00637         }
    00638         if(fWithHeader) len += HeaderSize(len);
    00639         return len;
    00640 }
    00641
    00642 HRESULT CBlock::Write(IStream* pStream)
    00643 {
    00644         HeaderWrite(pStream);
    00645         TrackNumber.Write(pStream);
    00646         short t = (short)TimeCode;
    00647         bswap((BYTE*)&t, 2);
    00648         pStream->Write(&t, 2, NULL);
    00649         BYTE Lacing = 0;
    00650         BYTE n = BlockData.GetCount();
    00651         if(n > 1) Lacing |= 2;
    00652         pStream->Write(&Lacing, 1, NULL);
    00653         if(n > 1)
    00654         {
    00655                 pStream->Write(&n, 1, NULL);
    00656                 POSITION pos = BlockData.GetHeadPosition();
    00657                 while(pos)
    00658                 {
    00659                         CBinary* b = BlockData.GetNext(pos);
    00660                         if(pos)
    00661                         {
    00662                                 int len = b->GetCount();
    00663                                 while(len >= 0)
    00664                                 {
    00665                                         n = min(len, 255);
    00666                                         pStream->Write(&n, 1, NULL);
    00667                                         len -= 255;
    00668                                 }
    00669                         }
    00670                 }
    00671         }
    00672         POSITION pos = BlockData.GetHeadPosition();
    00673         while(pos)
    00674         {
    00675                 CBinary* b = BlockData.GetNext(pos);
    00676                 pStream->Write(b->GetData(), b->GetCount(), NULL);
    00677         }
    00678         return S_OK;
    00679 }
    00680
    00681 Cue::Cue(DWORD id)
    00682         : CID(id)
    00683 {
    00684 }
    00685
    00686 QWORD Cue::Size(bool fWithHeader)
    00687 {
    00688         QWORD len = 0;
    00689         len += CuePoints.Size();
    00690         if(fWithHeader) len += HeaderSize(len);
    00691         return len;
    00692 }
    00693
    00694 HRESULT Cue::Write(IStream* pStream)
    00695 {
    00696         HeaderWrite(pStream);
    00697         CuePoints.Write(pStream);
    00698         return S_OK;
    00699 }
    00700
    00701 CuePoint::CuePoint(DWORD id)
    00702         : CID(id)
    00703         , CueTime(0xB3)
    00704 {
    00705 }
    00706
    00707 QWORD CuePoint::Size(bool fWithHeader)
    00708 {
    00709         QWORD len = 0;
    00710         len += CueTime.Size();
    00711         len += CueTrackPositions.Size();
    00712         if(fWithHeader) len += HeaderSize(len);
    00713         return len;
    00714 }
    00715
    00716 HRESULT CuePoint::Write(IStream* pStream)
    00717 {
    00718         HeaderWrite(pStream);
    00719         CueTime.Write(pStream);
    00720         CueTrackPositions.Write(pStream);
    00721         return S_OK;
    00722 }
    00723
    00724 CueTrackPosition::CueTrackPosition(DWORD id)
    00725         : CID(id)
    00726         , CueTrack(0xF7)
    00727         , CueClusterPosition(0xF1)
    00728         , CueBlockNumber(0x5387)
    00729         , CueCodecState(0xEA)
    00730 {
    00731 }
    00732
    00733 QWORD CueTrackPosition::Size(bool fWithHeader)
    00734 {
    00735         QWORD len = 0;
    00736         len += CueTrack.Size();
    00737         len += CueClusterPosition.Size();
    00738         len += CueBlockNumber.Size();
    00739         len += CueCodecState.Size();
    00740 //      len += CueReferences.Size();
    00741         if(fWithHeader) len += HeaderSize(len);
    00742         return len;
    00743 }
    00744
    00745 HRESULT CueTrackPosition::Write(IStream* pStream)
    00746 {
    00747         HeaderWrite(pStream);
    00748         CueTrack.Write(pStream);
    00749         CueClusterPosition.Write(pStream);
    00750         CueBlockNumber.Write(pStream);
    00751         CueCodecState.Write(pStream);
    00752 //      CueReferences.Write(pStream);
    00753         return S_OK;
    00754 }
    00755
    00756 Seek::Seek(DWORD id)
    00757         : CID(id)
    00758 {
    00759 }
    00760
    00761 QWORD Seek::Size(bool fWithHeader)
    00762 {
    00763         QWORD len = 0;
    00764         len += SeekHeads.Size();
    00765         if(fWithHeader) len += HeaderSize(len);
    00766         return len;
    00767 }
    00768
    00769 HRESULT Seek::Write(IStream* pStream)
    00770 {
    00771         HeaderWrite(pStream);
    00772         SeekHeads.Write(pStream);
    00773         return S_OK;
    00774 }
    00775
    00776 SeekID::SeekID(DWORD id)
    00777         : CID(id)
    00778         , m_id(0)
    00779 {
    00780 }
    00781
    00782 QWORD SeekID::Size(bool fWithHeader)
    00783 {
    00784         QWORD len = 0;
    00785         len += m_id.Size();
    00786         if(fWithHeader) len += HeaderSize(len);
    00787         return len;
    00788 }
    00789
    00790 HRESULT SeekID::Write(IStream* pStream)
    00791 {
    00792         HeaderWrite(pStream);
    00793         m_id.Write(pStream);
    00794         return S_OK;
    00795 }
    00796
    00797 SeekHead::SeekHead(DWORD id)
    00798         : CID(id)
    00799         , Position(0x53AC)
    00800 {
    00801 }
    00802
    00803 QWORD SeekHead::Size(bool fWithHeader)
    00804 {
    00805         QWORD len = 0;
    00806         len += ID.Size();
    00807         len += Position.Size();
    00808         if(fWithHeader) len += HeaderSize(len);
    00809         return len;
    00810 }
    00811
    00812 HRESULT SeekHead::Write(IStream* pStream)
    00813 {
    00814         HeaderWrite(pStream);
    00815         ID.Write(pStream);
    00816         Position.Write(pStream);
    00817         return S_OK;
    00818 }
    00819
    00820 Tags::Tags(DWORD id)
    00821         : CID(id)
    00822 {
    00823 }
    00824
    00825 QWORD Tags::Size(bool fWithHeader)
    00826 {
    00827         QWORD len = 0;
    00828 //      len += .Size();
    00829         if(fWithHeader) len += HeaderSize(len);
    00830         return len;
    00831 }
    00832
    00833 HRESULT Tags::Write(IStream* pStream)
    00834 {
    00835         HeaderWrite(pStream);
    00836 //      .Write(pStream);
    00837         return S_OK;
    00838 }
    00839
    00840 Void::Void(QWORD len, DWORD id)
    00841         : CID(id)
    00842         , m_len(len)
    00843 {
    00844 }
    00845
    00846 QWORD Void::Size(bool fWithHeader)
    00847 {
    00848         QWORD len = 0;
    00849         len += m_len;
    00850         if(fWithHeader) len += HeaderSize(len);
    00851         return len;
    00852 }
    00853
    00854 HRESULT Void::Write(IStream* pStream)
    00855 {
    00856         HeaderWrite(pStream);
    00857         BYTE buff[64];
    00858         memset(buff, 0x80, sizeof(buff));
    00859         for(int len = (int)m_len; len > 0; len -= sizeof(buff))
    00860                 pStream->Write(buff, (ULONG)min(sizeof(buff), len), NULL);
    00861         return S_OK;
    00862 }