- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# 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 }