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 }

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