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 }

Generated on Tue Dec 13 14:47:08 2005 for guliverkli by  doxygen 1.4.5