MatroskaFile.h
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:12k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #pragma once
  22. #include <atlbase.h>
  23. #include <atlcoll.h>
  24. #include <afxtempl.h>
  25. #include "..BaseSplitterBaseSplitter.h"
  26. namespace MatroskaReader
  27. {
  28. class CMatroskaNode;
  29. typedef unsigned __int64 QWORD;
  30. class CANSI : public CStringA {public: HRESULT Parse(CMatroskaNode* pMN);};
  31. class CUTF8 : public CStringW {public: HRESULT Parse(CMatroskaNode* pMN);};
  32. template<class T, class BASE>
  33. class CSimpleVar
  34. {
  35. protected:
  36. T m_val;
  37. bool m_fValid;
  38. public:
  39. CSimpleVar(T val = 0) : m_val(val), m_fValid(false) {}
  40. BASE& operator = (const BASE& v) {m_val = v.m_val; m_fValid = true; return(*this);}
  41. BASE& operator = (T val) {m_val = val; m_fValid = true; return(*this);}
  42. operator T() {return m_val;}
  43. BASE& Set(T val) {m_val = val; m_fValid = true; return(*(BASE*)this);}
  44. bool IsValid() {return m_fValid;}
  45. virtual HRESULT Parse(CMatroskaNode* pMN);
  46. };
  47. class CUInt : public CSimpleVar<UINT64, CUInt> {public: HRESULT Parse(CMatroskaNode* pMN);};
  48. class CInt : public CSimpleVar<INT64, CInt> {public: HRESULT Parse(CMatroskaNode* pMN);};
  49. class CByte : public CSimpleVar<BYTE, CByte> {};
  50. class CShort : public CSimpleVar<short, CShort> {};
  51. class CFloat : public CSimpleVar<double, CFloat> {public: HRESULT Parse(CMatroskaNode* pMN);};
  52. class CID : public CSimpleVar<DWORD, CID> {public: HRESULT Parse(CMatroskaNode* pMN);};
  53. class CLength : public CSimpleVar<UINT64, CLength> {bool m_fSigned; public: CLength(bool fSigned = false) : m_fSigned(fSigned) {} HRESULT Parse(CMatroskaNode* pMN);};
  54. class CSignedLength : public CLength {public: CSignedLength() : CLength(true) {}};
  55. class ContentCompression;
  56. class CBinary : public CArray<BYTE>
  57. {
  58. public:
  59. CBinary& operator = (const CBinary& b) {Copy(b); return(*this);}
  60. operator BYTE*() {return (BYTE*)GetData();}
  61. CStringA ToString() {return CStringA((LPCSTR)GetData(), GetCount());}
  62. bool Compress(ContentCompression& cc), Decompress(ContentCompression& cc);
  63. HRESULT Parse(CMatroskaNode* pMN);
  64. };
  65. template<class T>
  66. class CNode : public CAutoPtrList<T> {public: HRESULT Parse(CMatroskaNode* pMN);};
  67. class EBML
  68. {
  69. public:
  70. CUInt EBMLVersion, EBMLReadVersion;
  71. CUInt EBMLMaxIDLength, EBMLMaxSizeLength;
  72. CANSI DocType;
  73. CUInt DocTypeVersion, DocTypeReadVersion;
  74. HRESULT Parse(CMatroskaNode* pMN);
  75. };
  76. class Info
  77. {
  78. public:
  79. CBinary SegmentUID, PrevUID, NextUID;
  80. CUTF8 SegmentFilename, PrevFilename, NextFilename;
  81. CUInt TimeCodeScale; // [ns], default: 1.000.000
  82. CFloat Duration;
  83. CInt DateUTC;
  84. CUTF8 Title, MuxingApp, WritingApp;
  85. Info() {TimeCodeScale.Set(1000000ui64);}
  86. HRESULT Parse(CMatroskaNode* pMN);
  87. };
  88. class SeekHead
  89. {
  90. public:
  91. CID SeekID;
  92. CUInt SeekPosition;
  93. HRESULT Parse(CMatroskaNode* pMN);
  94. };
  95. class Seek
  96. {
  97. public:
  98. CNode<SeekHead> SeekHeads;
  99. HRESULT Parse(CMatroskaNode* pMN);
  100. };
  101. class TimeSlice
  102. {
  103. public:
  104. CUInt LaceNumber, FrameNumber;
  105. CUInt Delay, Duration;
  106. HRESULT Parse(CMatroskaNode* pMN);
  107. };
  108. class SimpleBlock
  109. {
  110. public:
  111. CLength TrackNumber;
  112. CInt TimeCode;
  113. CByte Lacing;
  114. CAutoPtrList<CBinary> BlockData;
  115. HRESULT Parse(CMatroskaNode* pMN, bool fFull);
  116. };
  117. class BlockGroup
  118. {
  119. public:
  120. SimpleBlock Block;
  121. // BlockVirtual
  122. CUInt BlockDuration;
  123. CUInt ReferencePriority;
  124. CInt ReferenceBlock;
  125. CInt ReferenceVirtual;
  126. CBinary CodecState;
  127. CNode<TimeSlice> TimeSlices;
  128. HRESULT Parse(CMatroskaNode* pMN, bool fFull);
  129. };
  130. class CBlockGroupNode : public CNode<BlockGroup>
  131. {
  132. public:
  133. HRESULT Parse(CMatroskaNode* pMN, bool fFull);
  134. };
  135. class CSimpleBlockNode : public CNode<SimpleBlock>
  136. {
  137. public:
  138. HRESULT Parse(CMatroskaNode* pMN, bool fFull);
  139. };
  140. class Cluster
  141. {
  142. public:
  143. CUInt TimeCode, Position, PrevSize;
  144. CBlockGroupNode BlockGroups;
  145. CSimpleBlockNode SimpleBlocks;
  146. HRESULT Parse(CMatroskaNode* pMN);
  147. HRESULT ParseTimeCode(CMatroskaNode* pMN);
  148. };
  149. class Video
  150. {
  151. public:
  152. CUInt FlagInterlaced, StereoMode;
  153. CUInt PixelWidth, PixelHeight, DisplayWidth, DisplayHeight, DisplayUnit;
  154. CUInt AspectRatioType;
  155. CUInt ColourSpace;
  156. CFloat GammaValue;
  157. CFloat FramePerSec;
  158. HRESULT Parse(CMatroskaNode* pMN);
  159. };
  160. class Audio
  161. {
  162. public:
  163. CFloat SamplingFrequency;
  164. CFloat OutputSamplingFrequency;
  165. CUInt Channels;
  166. CBinary ChannelPositions;
  167. CUInt BitDepth;
  168. Audio() {SamplingFrequency.Set(8000.0); Channels.Set(1);}
  169. HRESULT Parse(CMatroskaNode* pMN);
  170. };
  171. class ContentCompression
  172. {
  173. public:
  174. CUInt ContentCompAlgo; enum {ZLIB, BZLIB, LZO1X, HDRSTRIP};
  175. CBinary ContentCompSettings;
  176. ContentCompression() {ContentCompAlgo.Set(ZLIB);}
  177. HRESULT Parse(CMatroskaNode* pMN);
  178. };
  179. class ContentEncryption
  180. {
  181. public:
  182. CUInt ContentEncAlgo; enum {UNKE, DES, THREEDES, TWOFISH, BLOWFISH, AES};
  183. CBinary ContentEncKeyID, ContentSignature, ContentSigKeyID;
  184. CUInt ContentSigAlgo; enum {UNKS, RSA};
  185. CUInt ContentSigHashAlgo; enum {UNKSH, SHA1_160, MD5};
  186. ContentEncryption() {ContentEncAlgo.Set(0); ContentSigAlgo.Set(0); ContentSigHashAlgo.Set(0);}
  187. HRESULT Parse(CMatroskaNode* pMN);
  188. };
  189. class ContentEncoding
  190. {
  191. public:
  192. CUInt ContentEncodingOrder;
  193. CUInt ContentEncodingScope; enum {AllFrameContents = 1, TracksPrivateData = 2};
  194. CUInt ContentEncodingType; enum {Compression, Encryption};
  195. ContentCompression cc;
  196. ContentEncryption ce;
  197. ContentEncoding() {ContentEncodingOrder.Set(0); ContentEncodingScope.Set(AllFrameContents); ContentEncodingType.Set(Compression);}
  198. HRESULT Parse(CMatroskaNode* pMN);
  199. };
  200. class ContentEncodings
  201. {
  202. public:
  203. CNode<ContentEncoding> ce;
  204. ContentEncodings() {}
  205. HRESULT Parse(CMatroskaNode* pMN);
  206. };
  207. class TrackEntry
  208. {
  209. public:
  210. enum {TypeVideo = 1, TypeAudio = 2, TypeComplex = 3, TypeLogo = 0x10, TypeSubtitle = 0x11, TypeControl = 0x20};
  211. CUInt TrackNumber, TrackUID, TrackType;
  212. CUInt FlagEnabled, FlagDefault, FlagLacing;
  213. CUInt MinCache, MaxCache;
  214. CUTF8 Name;
  215. CANSI Language;
  216. CBinary CodecID;
  217. CBinary CodecPrivate;
  218. CUTF8 CodecName;
  219. CUTF8 CodecSettings;
  220. CANSI CodecInfoURL;
  221. CANSI CodecDownloadURL;
  222. CUInt CodecDecodeAll;
  223. CUInt TrackOverlay;
  224. CUInt DefaultDuration;
  225. CFloat TrackTimecodeScale;
  226. enum {NoDesc = 0, DescVideo = 1, DescAudio = 2};
  227. int DescType;
  228. Video v;
  229. Audio a;
  230. ContentEncodings ces;
  231. TrackEntry() {DescType = NoDesc; FlagEnabled.Set(1); FlagDefault.Set(1); FlagLacing.Set(1); }
  232. HRESULT Parse(CMatroskaNode* pMN);
  233. bool Expand(CBinary& data, UINT64 Scope);
  234. };
  235. class Track
  236. {
  237. public:
  238. CNode<TrackEntry> TrackEntries;
  239. HRESULT Parse(CMatroskaNode* pMN);
  240. };
  241. class CueReference
  242. {
  243. public:
  244. CUInt CueRefTime, CueRefCluster, CueRefNumber, CueRefCodecState;
  245. HRESULT Parse(CMatroskaNode* pMN);
  246. };
  247. class CueTrackPosition
  248. {
  249. public:
  250. CUInt CueTrack, CueClusterPosition, CueBlockNumber, CueCodecState;
  251. CNode<CueReference> CueReferences;
  252. HRESULT Parse(CMatroskaNode* pMN);
  253. };
  254. class CuePoint
  255. {
  256. public:
  257. CUInt CueTime;
  258. CNode<CueTrackPosition> CueTrackPositions;
  259. HRESULT Parse(CMatroskaNode* pMN);
  260. };
  261. class Cue
  262. {
  263. public:
  264. CNode<CuePoint> CuePoints;
  265. HRESULT Parse(CMatroskaNode* pMN);
  266. };
  267. class AttachedFile
  268. {
  269. public:
  270. CUTF8 FileDescription;
  271. CUTF8 FileName;
  272. CANSI FileMimeType;
  273. QWORD FileDataPos, FileDataLen; // BYTE* FileData
  274. CUInt FileUID;
  275. AttachedFile() {FileDataPos = FileDataLen = 0;}
  276. HRESULT Parse(CMatroskaNode* pMN);
  277. };
  278. class Attachment
  279. {
  280. public:
  281. CNode<AttachedFile> AttachedFiles;
  282. HRESULT Parse(CMatroskaNode* pMN);
  283. };
  284. class ChapterDisplay
  285. {
  286. public:
  287. CUTF8 ChapString;
  288. CANSI ChapLanguage;
  289. CANSI ChapCountry;
  290. ChapterDisplay() {ChapLanguage.CStringA::operator = ("eng");}
  291. HRESULT Parse(CMatroskaNode* pMN);
  292. };
  293. class ChapterAtom
  294. {
  295. public:
  296. CUInt ChapterUID;
  297. CUInt ChapterTimeStart, ChapterTimeEnd, ChapterFlagHidden, ChapterFlagEnabled;
  298. // CNode<CUInt> ChapterTracks; // TODO
  299. CNode<ChapterDisplay> ChapterDisplays;
  300. CNode<ChapterAtom> ChapterAtoms;
  301. ChapterAtom() {ChapterUID.Set(rand());ChapterFlagHidden.Set(0);ChapterFlagEnabled.Set(1);}
  302. HRESULT Parse(CMatroskaNode* pMN);
  303. ChapterAtom* FindChapterAtom(UINT64 id);
  304. };
  305. class EditionEntry : public ChapterAtom
  306. {
  307. public:
  308. HRESULT Parse(CMatroskaNode* pMN);
  309. };
  310. class Chapter
  311. {
  312. public:
  313. CNode<EditionEntry> EditionEntries;
  314. HRESULT Parse(CMatroskaNode* pMN);
  315. };
  316. class Segment
  317. {
  318. public:
  319. QWORD pos, len;
  320. Info SegmentInfo;
  321. CNode<Seek> MetaSeekInfo;
  322. CNode<Cluster> Clusters;
  323. CNode<Track> Tracks;
  324. CNode<Cue> Cues;
  325. CNode<Attachment> Attachments;
  326. CNode<Chapter> Chapters;
  327. // TODO: Chapters
  328. // TODO: Tags
  329. HRESULT Parse(CMatroskaNode* pMN);
  330. HRESULT ParseMinimal(CMatroskaNode* pMN);
  331. UINT64 GetMasterTrack();
  332. REFERENCE_TIME GetRefTime(INT64 t) {return t*(REFERENCE_TIME)(SegmentInfo.TimeCodeScale)/100;}
  333. ChapterAtom* FindChapterAtom(UINT64 id, int nEditionEntry = 0);
  334. };
  335. class CMatroskaFile : public CBaseSplitterFile
  336. {
  337. public:
  338. CMatroskaFile(IAsyncReader* pAsyncReader, HRESULT& hr);
  339. virtual ~CMatroskaFile() {}
  340. HRESULT Init();
  341. using CBaseSplitterFile::Read;
  342. template <class T> HRESULT Read(T& var);
  343. EBML m_ebml;
  344. Segment m_segment;
  345. REFERENCE_TIME m_rtOffset;
  346. HRESULT Parse(CMatroskaNode* pMN);
  347. };
  348. class CMatroskaNode
  349. {
  350. CMatroskaNode* m_pParent;
  351. CMatroskaFile* m_pMF;
  352. bool Resync();
  353. public:
  354. CID m_id;
  355. CLength m_len;
  356. QWORD m_filepos, m_start;
  357. HRESULT Parse();
  358. public:
  359. CMatroskaNode(CMatroskaFile* pMF); // creates the root
  360. CMatroskaNode(CMatroskaNode* pParent);
  361. CMatroskaNode* Parent() {return m_pParent;}
  362. CAutoPtr<CMatroskaNode> Child(DWORD id = 0, bool fSearch = true);
  363. bool Next(bool fSame = false);
  364. bool Find(DWORD id, bool fSearch = true);
  365. QWORD FindPos(DWORD id, QWORD start = 0);
  366. void SeekTo(QWORD pos);
  367. QWORD GetPos(), GetLength();
  368. template <class T> HRESULT Read(T& var);
  369. HRESULT Read(BYTE* pData, QWORD len);
  370. CAutoPtr<CMatroskaNode> Copy();
  371. CAutoPtr<CMatroskaNode> GetFirstBlock();
  372. bool NextBlock();
  373. };
  374. }