00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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;
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
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
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 class CueTrackPosition : public CID
00300 {
00301 public:
00302 CUInt CueTrack, CueClusterPosition, CueBlockNumber, CueCodecState;
00303
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
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 }