- 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 #include "..\BaseSplitter\BaseSplitter.h"
    00028
    00029 namespace MatroskaReader
    00030 {
    00031         class CMatroskaNode;
    00032
    00033         typedef unsigned __int64 QWORD;
    00034
    00035         class CANSI : public CStringA {public: HRESULT Parse(CMatroskaNode* pMN);};
    00036         class CUTF8 : public CStringW {public: HRESULT Parse(CMatroskaNode* pMN);};
    00037
    00038         template<class T, class BASE>
    00039         class CSimpleVar
    00040         {
    00041         protected:
    00042                 T m_val;
    00043                 bool m_fValid;
    00044         public:
    00045                 CSimpleVar(T val = 0) : m_val(val), m_fValid(false) {}
    00046                 BASE& operator = (const BASE& v) {m_val = v.m_val; m_fValid = true; return(*this);}
    00047                 BASE& operator = (T val) {m_val = val; m_fValid = true; return(*this);}
    00048                 operator T() {return m_val;}
    00049                 BASE& Set(T val) {m_val = val; m_fValid = true; return(*(BASE*)this);}
    00050                 bool IsValid() {return m_fValid;}
    00051                 virtual HRESULT Parse(CMatroskaNode* pMN);
    00052         };
    00053
    00054         class CUInt : public CSimpleVar<UINT64, CUInt> {public: HRESULT Parse(CMatroskaNode* pMN);};
    00055         class CInt : public CSimpleVar<INT64, CInt> {public: HRESULT Parse(CMatroskaNode* pMN);};
    00056         class CByte : public CSimpleVar<BYTE, CByte> {};
    00057         class CShort : public CSimpleVar<short, CShort> {};
    00058         class CFloat : public CSimpleVar<double, CFloat> {public: HRESULT Parse(CMatroskaNode* pMN);};
    00059         class CID : public CSimpleVar<DWORD, CID> {public: HRESULT Parse(CMatroskaNode* pMN);};
    00060         class CLength : public CSimpleVar<UINT64, CLength> {bool m_fSigned; public: CLength(bool fSigned = false) : m_fSigned(fSigned) {} HRESULT Parse(CMatroskaNode* pMN);};
    00061         class CSignedLength : public CLength {public: CSignedLength() : CLength(true) {}};
    00062
    00063         class ContentCompression;
    00064
    00065         class CBinary : public CArray<BYTE>
    00066         {
    00067         public:
    00068                 CBinary& operator = (const CBinary& b) {Copy(b); return(*this);}
    00069                 operator BYTE*() {return (BYTE*)GetData();}
    00070                 CStringA ToString() {return CStringA((LPCSTR)GetData(), GetCount());}
    00071                 bool Compress(ContentCompression& cc), Decompress(ContentCompression& cc);
    00072                 HRESULT Parse(CMatroskaNode* pMN);
    00073         };
    00074
    00075         template<class T>
    00076         class CNode : public CAutoPtrList<T> {public: HRESULT Parse(CMatroskaNode* pMN);};
    00077
    00078         class EBML
    00079         {
    00080         public:
    00081                 CUInt EBMLVersion, EBMLReadVersion;
    00082                 CUInt EBMLMaxIDLength, EBMLMaxSizeLength;
    00083                 CANSI DocType;
    00084                 CUInt DocTypeVersion, DocTypeReadVersion;
    00085
    00086                 HRESULT Parse(CMatroskaNode* pMN);
    00087         };
    00088
    00089                 class Info
    00090                 {
    00091                 public:
    00092                         CBinary SegmentUID, PrevUID, NextUID;
    00093                         CUTF8 SegmentFilename, PrevFilename, NextFilename;
    00094                         CUInt TimeCodeScale; // [ns], default: 1.000.000
    00095                         CFloat Duration;
    00096                         CInt DateUTC;
    00097                         CUTF8 Title, MuxingApp, WritingApp;
    00098
    00099                         Info() {TimeCodeScale.Set(1000000ui64);}
    00100                         HRESULT Parse(CMatroskaNode* pMN);
    00101                 };
    00102
    00103                         class SeekHead
    00104                         {
    00105                         public:
    00106                                 CID SeekID;
    00107                                 CUInt SeekPosition;
    00108
    00109                                 HRESULT Parse(CMatroskaNode* pMN);
    00110                         };
    00111
    00112                 class Seek
    00113                 {
    00114                 public:
    00115                         CNode<SeekHead> SeekHeads;
    00116
    00117                         HRESULT Parse(CMatroskaNode* pMN);
    00118                 };
    00119
    00120                                 class TimeSlice
    00121                                 {
    00122                                 public:
    00123                                         CUInt LaceNumber, FrameNumber;
    00124                                         CUInt Delay, Duration;
    00125
    00126                                         HRESULT Parse(CMatroskaNode* pMN);
    00127                                 };
    00128
    00129                                 class SimpleBlock
    00130                                 {
    00131                                 public:
    00132                                         CLength TrackNumber;
    00133                                         CInt TimeCode;
    00134                                         CByte Lacing;
    00135                                         CAutoPtrList<CBinary> BlockData;
    00136
    00137                                         HRESULT Parse(CMatroskaNode* pMN, bool fFull);
    00138                                 };
    00139
    00140                         class BlockGroup
    00141                         {
    00142                         public:
    00143                                 SimpleBlock Block;
    00144 //                              BlockVirtual
    00145                                 CUInt BlockDuration;
    00146                                 CUInt ReferencePriority;
    00147                                 CInt ReferenceBlock;
    00148                                 CInt ReferenceVirtual;
    00149                                 CBinary CodecState;
    00150                                 CNode<TimeSlice> TimeSlices;
    00151
    00152                                 HRESULT Parse(CMatroskaNode* pMN, bool fFull);
    00153                         };
    00154
    00155                         class CBlockGroupNode : public CNode<BlockGroup>
    00156                         {
    00157                         public:
    00158                                 HRESULT Parse(CMatroskaNode* pMN, bool fFull);
    00159                         };
    00160
    00161                         class CSimpleBlockNode : public CNode<SimpleBlock>
    00162                         {
    00163                         public:
    00164                                 HRESULT Parse(CMatroskaNode* pMN, bool fFull);
    00165                         };
    00166
    00167                 class Cluster
    00168                 {
    00169                 public:
    00170                         CUInt TimeCode, Position, PrevSize;
    00171                         CBlockGroupNode BlockGroups;
    00172                         CSimpleBlockNode SimpleBlocks;
    00173
    00174                         HRESULT Parse(CMatroskaNode* pMN);
    00175                         HRESULT ParseTimeCode(CMatroskaNode* pMN);
    00176                 };
    00177
    00178                                 class Video
    00179                                 {
    00180                                 public:
    00181                                         CUInt FlagInterlaced, StereoMode;
    00182                                         CUInt PixelWidth, PixelHeight, DisplayWidth, DisplayHeight, DisplayUnit;
    00183                                         CUInt AspectRatioType;
    00184                                         CUInt ColourSpace;
    00185                                         CFloat GammaValue;
    00186                                         CFloat FramePerSec;
    00187
    00188                                         HRESULT Parse(CMatroskaNode* pMN);
    00189                                 };
    00190
    00191                                 class Audio
    00192                                 {
    00193                                 public:
    00194                                         CFloat SamplingFrequency;
    00195                                         CFloat OutputSamplingFrequency;
    00196                                         CUInt Channels;
    00197                                         CBinary ChannelPositions;
    00198                                         CUInt BitDepth;
    00199
    00200                                         Audio() {SamplingFrequency.Set(8000.0); Channels.Set(1);}
    00201                                         HRESULT Parse(CMatroskaNode* pMN);
    00202                                 };
    00203
    00204                                                 class ContentCompression
    00205                                                 {
    00206                                                 public:
    00207                                                         CUInt ContentCompAlgo; enum {ZLIB, BZLIB, LZO1X, HDRSTRIP};
    00208                                                         CBinary ContentCompSettings;
    00209
    00210                                                         ContentCompression() {ContentCompAlgo.Set(ZLIB);}
    00211                                                         HRESULT Parse(CMatroskaNode* pMN);
    00212                                                 };
    00213
    00214                                                 class ContentEncryption
    00215                                                 {
    00216                                                 public:
    00217                                                         CUInt ContentEncAlgo; enum {UNKE, DES, THREEDES, TWOFISH, BLOWFISH, AES};
    00218                                                         CBinary ContentEncKeyID, ContentSignature, ContentSigKeyID;
    00219                                                         CUInt ContentSigAlgo; enum {UNKS, RSA};
    00220                                                         CUInt ContentSigHashAlgo; enum {UNKSH, SHA1_160, MD5};
    00221
    00222                                                         ContentEncryption() {ContentEncAlgo.Set(0); ContentSigAlgo.Set(0); ContentSigHashAlgo.Set(0);}
    00223                                                         HRESULT Parse(CMatroskaNode* pMN);
    00224                                                 };
    00225
    00226                                         class ContentEncoding
    00227                                         {
    00228                                         public:
    00229                                                 CUInt ContentEncodingOrder;
    00230                                                 CUInt ContentEncodingScope; enum {AllFrameContents = 1, TracksPrivateData = 2};
    00231                                                 CUInt ContentEncodingType; enum {Compression, Encryption};
    00232                                                 ContentCompression cc;
    00233                                                 ContentEncryption ce;
    00234
    00235                                                 ContentEncoding() {ContentEncodingOrder.Set(0); ContentEncodingScope.Set(AllFrameContents); ContentEncodingType.Set(Compression);}
    00236                                                 HRESULT Parse(CMatroskaNode* pMN);
    00237                                         };
    00238
    00239                                 class ContentEncodings
    00240                                 {
    00241                                 public:
    00242                                         CNode<ContentEncoding> ce;
    00243
    00244                                         ContentEncodings() {}
    00245                                         HRESULT Parse(CMatroskaNode* pMN);
    00246                                 };
    00247
    00248                         class TrackEntry
    00249                         {
    00250                         public:
    00251                                 enum {TypeVideo = 1, TypeAudio = 2, TypeComplex = 3, TypeLogo = 0x10, TypeSubtitle = 0x11, TypeControl = 0x20};
    00252                                 CUInt TrackNumber, TrackUID, TrackType;
    00253                                 CUInt FlagEnabled, FlagDefault, FlagLacing;
    00254                                 CUInt MinCache, MaxCache;
    00255                                 CUTF8 Name;
    00256                                 CANSI Language;
    00257                                 CBinary CodecID;
    00258                                 CBinary CodecPrivate;
    00259                                 CUTF8 CodecName;
    00260                                 CUTF8 CodecSettings;
    00261                                 CANSI CodecInfoURL;
    00262                                 CANSI CodecDownloadURL;
    00263                                 CUInt CodecDecodeAll;
    00264                                 CUInt TrackOverlay;
    00265                                 CUInt DefaultDuration;
    00266                                 CFloat TrackTimecodeScale;
    00267                                 enum {NoDesc = 0, DescVideo = 1, DescAudio = 2};
    00268                                 int DescType;
    00269                                 Video v;
    00270                                 Audio a;
    00271                                 ContentEncodings ces;
    00272                                 TrackEntry() {DescType = NoDesc; FlagEnabled.Set(1); FlagDefault.Set(1); FlagLacing.Set(1); }
    00273                                 HRESULT Parse(CMatroskaNode* pMN);
    00274
    00275                                 bool Expand(CBinary& data, UINT64 Scope);
    00276                         };
    00277
    00278                 class Track
    00279                 {
    00280                 public:
    00281                         CNode<TrackEntry> TrackEntries;
    00282
    00283                         HRESULT Parse(CMatroskaNode* pMN);
    00284                 };
    00285
    00286                                 class CueReference
    00287                                 {
    00288                                 public:
    00289                                         CUInt CueRefTime, CueRefCluster, CueRefNumber, CueRefCodecState;
    00290
    00291                                         HRESULT Parse(CMatroskaNode* pMN);
    00292                                 };
    00293
    00294                         class CueTrackPosition
    00295                         {
    00296                         public:
    00297                                 CUInt CueTrack, CueClusterPosition, CueBlockNumber, CueCodecState;
    00298                                 CNode<CueReference> CueReferences;
    00299
    00300                                 HRESULT Parse(CMatroskaNode* pMN);
    00301                         };
    00302
    00303                 class CuePoint
    00304                 {
    00305                 public:
    00306                         CUInt CueTime;
    00307                         CNode<CueTrackPosition> CueTrackPositions;
    00308
    00309                         HRESULT Parse(CMatroskaNode* pMN);
    00310                 };
    00311
    00312                 class Cue
    00313                 {
    00314                 public:
    00315                         CNode<CuePoint> CuePoints;
    00316
    00317                         HRESULT Parse(CMatroskaNode* pMN);
    00318                 };
    00319
    00320                         class AttachedFile
    00321                         {
    00322                         public:
    00323                                 CUTF8 FileDescription;
    00324                                 CUTF8 FileName;
    00325                                 CANSI FileMimeType;
    00326                                 QWORD FileDataPos, FileDataLen; // BYTE* FileData
    00327                                 CUInt FileUID;
    00328
    00329                                 AttachedFile() {FileDataPos = FileDataLen = 0;}
    00330                                 HRESULT Parse(CMatroskaNode* pMN);
    00331                         };
    00332
    00333                 class Attachment
    00334                 {
    00335                 public:
    00336                         CNode<AttachedFile> AttachedFiles;
    00337
    00338                         HRESULT Parse(CMatroskaNode* pMN);
    00339                 };
    00340
    00341                                         class ChapterDisplay
    00342                                         {
    00343                                         public:
    00344                                                 CUTF8 ChapString;
    00345                                                 CANSI ChapLanguage;
    00346                                                 CANSI ChapCountry;
    00347
    00348                                                 ChapterDisplay() {ChapLanguage.CStringA::operator = ("eng");}
    00349                                                 HRESULT Parse(CMatroskaNode* pMN);
    00350                                         };
    00351
    00352                                 class ChapterAtom
    00353                                 {
    00354                                 public:
    00355                                         CUInt ChapterUID;
    00356                                         CUInt ChapterTimeStart, ChapterTimeEnd, ChapterFlagHidden, ChapterFlagEnabled;
    00357 //                                      CNode<CUInt> ChapterTracks; // TODO
    00358                                         CNode<ChapterDisplay> ChapterDisplays;
    00359                                         CNode<ChapterAtom> ChapterAtoms;
    00360
    00361                                         ChapterAtom() {ChapterUID.Set(rand());ChapterFlagHidden.Set(0);ChapterFlagEnabled.Set(1);}
    00362                                         HRESULT Parse(CMatroskaNode* pMN);
    00363                                         ChapterAtom* FindChapterAtom(UINT64 id);
    00364                                 };
    00365
    00366                         class EditionEntry : public ChapterAtom
    00367                         {
    00368                         public:
    00369                                 HRESULT Parse(CMatroskaNode* pMN);
    00370                         };
    00371
    00372                 class Chapter
    00373                 {
    00374                 public:
    00375                         CNode<EditionEntry> EditionEntries;
    00376
    00377                         HRESULT Parse(CMatroskaNode* pMN);
    00378                 };
    00379
    00380         class Segment
    00381         {
    00382         public:
    00383                 QWORD pos, len;
    00384                 Info SegmentInfo;
    00385                 CNode<Seek> MetaSeekInfo;
    00386                 CNode<Cluster> Clusters;
    00387                 CNode<Track> Tracks;
    00388                 CNode<Cue> Cues;
    00389                 CNode<Attachment> Attachments;
    00390                 CNode<Chapter> Chapters;
    00391                 // TODO: Chapters
    00392                 // TODO: Tags
    00393
    00394                 HRESULT Parse(CMatroskaNode* pMN);
    00395                 HRESULT ParseMinimal(CMatroskaNode* pMN);
    00396
    00397                 UINT64 GetMasterTrack();
    00398
    00399                 REFERENCE_TIME GetRefTime(INT64 t) {return t*(REFERENCE_TIME)(SegmentInfo.TimeCodeScale)/100;}
    00400                 ChapterAtom* FindChapterAtom(UINT64 id, int nEditionEntry = 0);
    00401         };
    00402
    00403         class CMatroskaFile : public CBaseSplitterFile
    00404         {
    00405         public:
    00406                 CMatroskaFile(IAsyncReader* pAsyncReader, HRESULT& hr);
    00407                 virtual ~CMatroskaFile() {}
    00408
    00409                 HRESULT Init();
    00410
    00411                 using CBaseSplitterFile::Read;
    00412                 template <class T> HRESULT Read(T& var);
    00413
    00414                 EBML m_ebml;
    00415                 Segment m_segment;
    00416                 REFERENCE_TIME m_rtOffset;
    00417
    00418                 HRESULT Parse(CMatroskaNode* pMN);
    00419         };
    00420
    00421         class CMatroskaNode
    00422         {
    00423                 CMatroskaNode* m_pParent;
    00424                 CMatroskaFile* m_pMF;
    00425
    00426                 bool Resync();
    00427
    00428         public:
    00429                 CID m_id;
    00430                 CLength m_len;
    00431                 QWORD m_filepos, m_start;
    00432
    00433                 HRESULT Parse();
    00434
    00435         public:
    00436                 CMatroskaNode(CMatroskaFile* pMF); // creates the root
    00437                 CMatroskaNode(CMatroskaNode* pParent);
    00438
    00439                 CMatroskaNode* Parent() {return m_pParent;}
    00440                 CAutoPtr<CMatroskaNode> Child(DWORD id = 0, bool fSearch = true);
    00441                 bool Next(bool fSame = false);
    00442                 bool Find(DWORD id, bool fSearch = true);
    00443
    00444                 QWORD FindPos(DWORD id, QWORD start = 0);
    00445
    00446                 void SeekTo(QWORD pos);
    00447                 QWORD GetPos(), GetLength();
    00448                 template <class T> HRESULT Read(T& var);
    00449                 HRESULT Read(BYTE* pData, QWORD len);
    00450
    00451                 CAutoPtr<CMatroskaNode> Copy();
    00452
    00453                 CAutoPtr<CMatroskaNode> GetFirstBlock();
    00454                 bool NextBlock();
    00455         };
    00456 }