MatroskaFile.h

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 #pragma once
00023 
00024 #include <atlbase.h>
00025 #include <atlcoll.h>
00026 #include <afxtempl.h>
00027 
00028 namespace MatroskaWriter
00029 {
00030         typedef unsigned __int64 QWORD;
00031 
00032         class CID
00033         {
00034         protected:
00035                 DWORD m_id;
00036                 QWORD HeaderSize(QWORD len);
00037                 HRESULT HeaderWrite(IStream* pStream);
00038 
00039         public:
00040                 CID(DWORD id);
00041                 DWORD GetID() {return m_id;}
00042                 virtual QWORD Size(bool fWithHeader = true);
00043                 virtual HRESULT Write(IStream* pStream);
00044         };
00045 
00046         class CLength : public CID
00047         {
00048                 UINT64 m_len;
00049         public: 
00050                 CLength(UINT64 len = 0) : CID(0), m_len(len) {}
00051                 operator UINT64() {return m_len;}
00052                 QWORD Size(bool fWithHeader = false);
00053                 HRESULT Write(IStream* pStream);
00054         };
00055 
00056         class CBinary : public CArray<BYTE>, public CID
00057         {
00058         public:
00059                 CBinary(DWORD id) : CID(id) {}
00060                 CBinary& operator = (const CBinary& b) {Copy(b); return(*this);}
00061                 operator BYTE*() {return (BYTE*)GetData();}
00062                 CBinary& Set(CStringA str) {SetSize(str.GetLength()+1); strcpy((char*)GetData(), str); return(*this);}
00063 //              CBinary& Set(CStringA str) {SetSize(str.GetLength()); memcpy((char*)GetData(), str, str.GetLength()); return(*this);}
00064                 QWORD Size(bool fWithHeader = true);
00065                 HRESULT Write(IStream* pStream);
00066         };
00067 
00068         class CANSI : public CStringA, public CID
00069         {
00070         public: 
00071                 CANSI(DWORD id) : CID(id) {}
00072                 CANSI& Set(CStringA str) {CStringA::operator = (str); return(*this);}
00073                 QWORD Size(bool fWithHeader = true);
00074                 HRESULT Write(IStream* pStream);
00075         };
00076 
00077         class CUTF8 : public CStringW, public CID
00078         {
00079         public: 
00080                 CUTF8(DWORD id) : CID(id) {}
00081                 CUTF8& Set(CStringW str) {CStringW::operator = (str); return(*this);}
00082                 QWORD Size(bool fWithHeader = true); 
00083                 HRESULT Write(IStream* pStream);
00084         };
00085 
00086         template<class T, class BASE>
00087         class CSimpleVar : public CID
00088         {
00089         protected:
00090                 T m_val;
00091                 bool m_fSet;
00092         public:
00093                 explicit CSimpleVar(DWORD id, T val = 0) : CID(id), m_val(val) {m_fSet = !!val;}
00094                 operator T() {return m_val;}
00095                 BASE& Set(T val) {m_val = val; m_fSet = true; return(*(BASE*)this);}
00096                 void UnSet() {m_fSet = false;}
00097                 QWORD Size(bool fWithHeader = true);
00098                 HRESULT Write(IStream* pStream);
00099         };
00100 
00101         class CUInt : public CSimpleVar<UINT64, CUInt>
00102         {
00103         public:
00104                 explicit CUInt(DWORD id, UINT64 val = 0) : CSimpleVar<UINT64, CUInt>(id, val) {}
00105                 QWORD Size(bool fWithHeader = true); 
00106                 HRESULT Write(IStream* pStream);
00107         };
00108 
00109         class CInt : public CSimpleVar<INT64, CInt>
00110         {
00111         public: 
00112                 explicit CInt(DWORD id, INT64 val = 0) : CSimpleVar<INT64, CInt>(id, val) {}
00113                 QWORD Size(bool fWithHeader = true);
00114                 HRESULT Write(IStream* pStream);
00115         };
00116 
00117         class CByte : public CSimpleVar<BYTE, CByte>
00118         {
00119         public: 
00120                 explicit CByte(DWORD id, BYTE val = 0) : CSimpleVar<BYTE, CByte>(id, val) {}
00121         };
00122 
00123         class CShort : public CSimpleVar<short, CShort>
00124         {
00125         public: 
00126                 explicit CShort(DWORD id, short val = 0) : CSimpleVar<short, CShort>(id, val) {}
00127         };
00128 
00129         class CFloat : public CSimpleVar<float, CFloat>
00130         {
00131         public: 
00132                 explicit CFloat(DWORD id, float val = 0) : CSimpleVar<float, CFloat>(id, val) {}
00133         };
00134 
00135         template<class T>
00136         class CNode : public CAutoPtrList<T>
00137         {
00138         public: 
00139                 QWORD Size(bool fWithHeader = true)
00140                 {
00141                         QWORD len = 0;
00142                         POSITION pos = GetHeadPosition();
00143                         while(pos) len += GetNext(pos)->Size(fWithHeader);
00144                         return len;
00145                 }
00146                 HRESULT Write(IStream* pStream)
00147                 {
00148                         HRESULT hr;
00149                         POSITION pos = GetHeadPosition();
00150                         while(pos) if(FAILED(hr = GetNext(pos)->Write(pStream))) return hr;
00151                         return S_OK;
00152                 }
00153         };
00154 
00155         class EBML : public CID
00156         {
00157         public:
00158                 CUInt EBMLVersion, EBMLReadVersion;
00159                 CUInt EBMLMaxIDLength, EBMLMaxSizeLength;
00160                 CANSI DocType;
00161                 CUInt DocTypeVersion, DocTypeReadVersion;
00162 
00163                 EBML(DWORD id = 0x1A45DFA3);
00164                 QWORD Size(bool fWithHeader = true);
00165                 HRESULT Write(IStream* pStream);
00166         };
00167 
00168                 class Info : public CID
00169                 {
00170                 public:
00171                         CBinary SegmentUID, PrevUID, NextUID;
00172                         CUTF8 SegmentFilename, PrevFilename, NextFilename;
00173                         CUInt TimeCodeScale; // [ns], default: 1.000.000
00174                         CFloat Duration;
00175                         CInt DateUTC;
00176                         CUTF8 Title, MuxingApp, WritingApp;
00177 
00178                         Info(DWORD id = 0x1549A966);
00179                         QWORD Size(bool fWithHeader = true);
00180                         HRESULT Write(IStream* pStream);
00181                 };
00182 
00183                                 class Video : public CID
00184                                 {
00185                                 public:
00186                                         CUInt FlagInterlaced, StereoMode;
00187                                         CUInt PixelWidth, PixelHeight, DisplayWidth, DisplayHeight, DisplayUnit;
00188                                         CUInt AspectRatioType;
00189                                         CUInt ColourSpace;
00190                                         CFloat GammaValue;
00191                                         CFloat FramePerSec;
00192 
00193                                         Video(DWORD id = 0xE0);
00194                                         QWORD Size(bool fWithHeader = true);
00195                                         HRESULT Write(IStream* pStream);
00196                                 };
00197 
00198                                 class Audio : public CID
00199                                 {
00200                                 public:
00201                                         CFloat SamplingFrequency;
00202                                         CFloat OutputSamplingFrequency;
00203                                         CUInt Channels;
00204                                         CBinary ChannelPositions;
00205                                         CUInt BitDepth;
00206 
00207                                         Audio(DWORD id = 0xE1);
00208                                         QWORD Size(bool fWithHeader = true);
00209                                         HRESULT Write(IStream* pStream);
00210                                 };
00211 
00212                         class TrackEntry : public CID
00213                         {
00214                         public:
00215                                 enum {TypeVideo = 1, TypeAudio = 2, TypeComplex = 3, TypeLogo = 0x10, TypeSubtitle = 0x11, TypeControl = 0x20};
00216                                 CUInt TrackNumber, TrackUID, TrackType;
00217                                 CUInt FlagEnabled, FlagDefault, FlagLacing;
00218                                 CUInt MinCache, MaxCache;
00219                                 CUTF8 Name;
00220                                 CANSI Language;
00221                                 CBinary CodecID;
00222                                 CBinary CodecPrivate;
00223                                 CUTF8 CodecName;
00224                                 CUTF8 CodecSettings;
00225                                 CANSI CodecInfoURL;
00226                                 CANSI CodecDownloadURL;
00227                                 CUInt CodecDecodeAll;
00228                                 CUInt TrackOverlay;
00229                                 CUInt DefaultDuration;
00230                                 enum {NoDesc = 0, DescVideo = 1, DescAudio = 2};
00231                                 int DescType;
00232                                 Video v;
00233                                 Audio a;
00234 
00235                                 TrackEntry(DWORD id = 0xAE);
00236                                 QWORD Size(bool fWithHeader = true);
00237                                 HRESULT Write(IStream* pStream);
00238                         };
00239 
00240                 class Track : public CID
00241                 {
00242                 public:
00243                         CNode<TrackEntry> TrackEntries;
00244 
00245                         Track(DWORD id = 0x1654AE6B);
00246                         QWORD Size(bool fWithHeader = true);
00247                         HRESULT Write(IStream* pStream);
00248                 };
00249 
00250                                 class CBlock : public CID
00251                                 {
00252                                 public:
00253                                         CLength TrackNumber;
00254                                         REFERENCE_TIME TimeCode, TimeCodeStop;
00255                                         CNode<CBinary> BlockData;
00256 
00257                                         CBlock(DWORD id = 0xA1);
00258                                         QWORD Size(bool fWithHeader = true);
00259                                         HRESULT Write(IStream* pStream);
00260                                 };
00261 
00262                         class BlockGroup : public CID
00263                         {
00264                         public:
00265                                 CUInt BlockDuration;
00266                                 CUInt ReferencePriority;
00267                                 CInt ReferenceBlock;
00268                                 CInt ReferenceVirtual;
00269                                 CBinary CodecState;
00270                                 CBlock Block;
00271 //                              CNode<TimeSlice> TimeSlices;
00272 
00273                                 BlockGroup(DWORD id = 0xA0);
00274                                 QWORD Size(bool fWithHeader = true);
00275                                 HRESULT Write(IStream* pStream);
00276                         };
00277 
00278                 class Cluster : public CID
00279                 {
00280                 public:
00281                         CUInt TimeCode, Position, PrevSize;
00282                         CNode<BlockGroup> BlockGroups;
00283 
00284                         Cluster(DWORD id = 0x1F43B675);
00285                         QWORD Size(bool fWithHeader = true);
00286                         HRESULT Write(IStream* pStream);
00287                 };
00288 
00289 /*                                      class CueReference : public CID
00290                                         {
00291                                         public:
00292                                                 CUInt CueRefTime, CueRefCluster, CueRefNumber, CueRefCodecState;
00293 
00294                                                 CueReference(DWORD id = 0xDB);
00295                                                 QWORD Size(bool fWithHeader = true);
00296                                                 HRESULT Write(IStream* pStream);
00297                                         };
00298 */
00299                                 class CueTrackPosition : public CID
00300                                 {
00301                                 public:
00302                                         CUInt CueTrack, CueClusterPosition, CueBlockNumber, CueCodecState;
00303 //                                      CNode<CueReference> CueReferences;
00304 
00305                                         CueTrackPosition(DWORD id = 0xB7);
00306                                         QWORD Size(bool fWithHeader = true);
00307                                         HRESULT Write(IStream* pStream);
00308                                 };
00309 
00310                         class CuePoint : public CID
00311                         {
00312                         public:
00313                                 CUInt CueTime;
00314                                 CNode<CueTrackPosition> CueTrackPositions;
00315 
00316                                 CuePoint(DWORD id = 0xBB);
00317                                 QWORD Size(bool fWithHeader = true);
00318                                 HRESULT Write(IStream* pStream);
00319                         };
00320 
00321                 class Cue : public CID
00322                 {
00323                 public:
00324                         CNode<CuePoint> CuePoints;
00325 
00326                         Cue(DWORD id = 0x1C53BB6B);
00327                         QWORD Size(bool fWithHeader = true);
00328                         HRESULT Write(IStream* pStream);
00329                 };
00330 
00331                                 class SeekID : public CID
00332                                 {
00333                                         CID m_id;
00334                                 public:
00335                                         SeekID(DWORD id = 0x53AB);
00336                                         void Set(DWORD id) {m_id = id;}
00337                                         QWORD Size(bool fWithHeader = true);
00338                                         HRESULT Write(IStream* pStream);
00339                                 };
00340 
00341                         class SeekHead : public CID
00342                         {
00343                         public:
00344                                 SeekID ID;
00345                                 CUInt Position;
00346 
00347                                 SeekHead(DWORD id = 0x4DBB);
00348                                 QWORD Size(bool fWithHeader = true);
00349                                 HRESULT Write(IStream* pStream);
00350                         };
00351 
00352                 class Seek : public CID
00353                 {
00354                 public:
00355                         CNode<SeekHead> SeekHeads;
00356 
00357                         Seek(DWORD id = 0x114D9B74);
00358                         QWORD Size(bool fWithHeader = true);
00359                         HRESULT Write(IStream* pStream);
00360                 };
00361 
00362         class Segment : public CID
00363         {
00364         public:
00365                 Segment(DWORD id = 0x18538067);
00366                 QWORD Size(bool fWithHeader = true);
00367                 HRESULT Write(IStream* pStream);
00368         };
00369 
00370         class Tags : public CID
00371         {
00372         public:
00373                 // TODO
00374 
00375                 Tags(DWORD id = 0x1254C367);
00376                 QWORD Size(bool fWithHeader = true);
00377                 HRESULT Write(IStream* pStream);
00378         };
00379 
00380         class Void : public CID
00381         {
00382                 QWORD m_len;
00383         public:
00384                 Void(QWORD len, DWORD id = 0xEC);
00385                 QWORD Size(bool fWithHeader = true);
00386                 HRESULT Write(IStream* pStream);
00387         };
00388 }

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