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

多媒体编程

开发平台:

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. namespace MatroskaWriter
  26. {
  27. typedef unsigned __int64 QWORD;
  28. class CID
  29. {
  30. protected:
  31. DWORD m_id;
  32. QWORD HeaderSize(QWORD len);
  33. HRESULT HeaderWrite(IStream* pStream);
  34. public:
  35. CID(DWORD id);
  36. DWORD GetID() {return m_id;}
  37. virtual QWORD Size(bool fWithHeader = true);
  38. virtual HRESULT Write(IStream* pStream);
  39. };
  40. class CLength : public CID
  41. {
  42. UINT64 m_len;
  43. public: 
  44. CLength(UINT64 len = 0) : CID(0), m_len(len) {}
  45. operator UINT64() {return m_len;}
  46. QWORD Size(bool fWithHeader = false);
  47. HRESULT Write(IStream* pStream);
  48. };
  49. class CBinary : public CArray<BYTE>, public CID
  50. {
  51. public:
  52. CBinary(DWORD id) : CID(id) {}
  53. CBinary& operator = (const CBinary& b) {Copy(b); return(*this);}
  54. operator BYTE*() {return (BYTE*)GetData();}
  55. CBinary& Set(CStringA str) {SetSize(str.GetLength()+1); strcpy((char*)GetData(), str); return(*this);}
  56. // CBinary& Set(CStringA str) {SetSize(str.GetLength()); memcpy((char*)GetData(), str, str.GetLength()); return(*this);}
  57. QWORD Size(bool fWithHeader = true);
  58. HRESULT Write(IStream* pStream);
  59. };
  60. class CANSI : public CStringA, public CID
  61. {
  62. public: 
  63. CANSI(DWORD id) : CID(id) {}
  64. CANSI& Set(CStringA str) {CStringA::operator = (str); return(*this);}
  65. QWORD Size(bool fWithHeader = true);
  66. HRESULT Write(IStream* pStream);
  67. };
  68. class CUTF8 : public CStringW, public CID
  69. {
  70. public: 
  71. CUTF8(DWORD id) : CID(id) {}
  72. CUTF8& Set(CStringW str) {CStringW::operator = (str); return(*this);}
  73. QWORD Size(bool fWithHeader = true); 
  74. HRESULT Write(IStream* pStream);
  75. };
  76. template<class T, class BASE>
  77. class CSimpleVar : public CID
  78. {
  79. protected:
  80. T m_val;
  81. bool m_fSet;
  82. public:
  83. explicit CSimpleVar(DWORD id, T val = 0) : CID(id), m_val(val) {m_fSet = !!val;}
  84. operator T() {return m_val;}
  85. BASE& Set(T val) {m_val = val; m_fSet = true; return(*(BASE*)this);}
  86. void UnSet() {m_fSet = false;}
  87. QWORD Size(bool fWithHeader = true);
  88. HRESULT Write(IStream* pStream);
  89. };
  90. class CUInt : public CSimpleVar<UINT64, CUInt>
  91. {
  92. public:
  93. explicit CUInt(DWORD id, UINT64 val = 0) : CSimpleVar<UINT64, CUInt>(id, val) {}
  94. QWORD Size(bool fWithHeader = true); 
  95. HRESULT Write(IStream* pStream);
  96. };
  97. class CInt : public CSimpleVar<INT64, CInt>
  98. {
  99. public: 
  100. explicit CInt(DWORD id, INT64 val = 0) : CSimpleVar<INT64, CInt>(id, val) {}
  101. QWORD Size(bool fWithHeader = true);
  102. HRESULT Write(IStream* pStream);
  103. };
  104. class CByte : public CSimpleVar<BYTE, CByte>
  105. {
  106. public: 
  107. explicit CByte(DWORD id, BYTE val = 0) : CSimpleVar<BYTE, CByte>(id, val) {}
  108. };
  109. class CShort : public CSimpleVar<short, CShort>
  110. {
  111. public: 
  112. explicit CShort(DWORD id, short val = 0) : CSimpleVar<short, CShort>(id, val) {}
  113. };
  114. class CFloat : public CSimpleVar<float, CFloat>
  115. {
  116. public: 
  117. explicit CFloat(DWORD id, float val = 0) : CSimpleVar<float, CFloat>(id, val) {}
  118. };
  119. template<class T>
  120. class CNode : public CAutoPtrList<T>
  121. {
  122. public: 
  123. QWORD Size(bool fWithHeader = true)
  124. {
  125. QWORD len = 0;
  126. POSITION pos = GetHeadPosition();
  127. while(pos) len += GetNext(pos)->Size(fWithHeader);
  128. return len;
  129. }
  130. HRESULT Write(IStream* pStream)
  131. {
  132. HRESULT hr;
  133. POSITION pos = GetHeadPosition();
  134. while(pos) if(FAILED(hr = GetNext(pos)->Write(pStream))) return hr;
  135. return S_OK;
  136. }
  137. };
  138. class EBML : public CID
  139. {
  140. public:
  141. CUInt EBMLVersion, EBMLReadVersion;
  142. CUInt EBMLMaxIDLength, EBMLMaxSizeLength;
  143. CANSI DocType;
  144. CUInt DocTypeVersion, DocTypeReadVersion;
  145. EBML(DWORD id = 0x1A45DFA3);
  146. QWORD Size(bool fWithHeader = true);
  147. HRESULT Write(IStream* pStream);
  148. };
  149. class Info : public CID
  150. {
  151. public:
  152. CBinary SegmentUID, PrevUID, NextUID;
  153. CUTF8 SegmentFilename, PrevFilename, NextFilename;
  154. CUInt TimeCodeScale; // [ns], default: 1.000.000
  155. CFloat Duration;
  156. CInt DateUTC;
  157. CUTF8 Title, MuxingApp, WritingApp;
  158. Info(DWORD id = 0x1549A966);
  159. QWORD Size(bool fWithHeader = true);
  160. HRESULT Write(IStream* pStream);
  161. };
  162. class Video : public CID
  163. {
  164. public:
  165. CUInt FlagInterlaced, StereoMode;
  166. CUInt PixelWidth, PixelHeight, DisplayWidth, DisplayHeight, DisplayUnit;
  167. CUInt AspectRatioType;
  168. CUInt ColourSpace;
  169. CFloat GammaValue;
  170. CFloat FramePerSec;
  171. Video(DWORD id = 0xE0);
  172. QWORD Size(bool fWithHeader = true);
  173. HRESULT Write(IStream* pStream);
  174. };
  175. class Audio : public CID
  176. {
  177. public:
  178. CFloat SamplingFrequency;
  179. CFloat OutputSamplingFrequency;
  180. CUInt Channels;
  181. CBinary ChannelPositions;
  182. CUInt BitDepth;
  183. Audio(DWORD id = 0xE1);
  184. QWORD Size(bool fWithHeader = true);
  185. HRESULT Write(IStream* pStream);
  186. };
  187. class TrackEntry : public CID
  188. {
  189. public:
  190. enum {TypeVideo = 1, TypeAudio = 2, TypeComplex = 3, TypeLogo = 0x10, TypeSubtitle = 0x11, TypeControl = 0x20};
  191. CUInt TrackNumber, TrackUID, TrackType;
  192. CUInt FlagEnabled, FlagDefault, FlagLacing;
  193. CUInt MinCache, MaxCache;
  194. CUTF8 Name;
  195. CANSI Language;
  196. CBinary CodecID;
  197. CBinary CodecPrivate;
  198. CUTF8 CodecName;
  199. CUTF8 CodecSettings;
  200. CANSI CodecInfoURL;
  201. CANSI CodecDownloadURL;
  202. CUInt CodecDecodeAll;
  203. CUInt TrackOverlay;
  204. CUInt DefaultDuration;
  205. enum {NoDesc = 0, DescVideo = 1, DescAudio = 2};
  206. int DescType;
  207. Video v;
  208. Audio a;
  209. TrackEntry(DWORD id = 0xAE);
  210. QWORD Size(bool fWithHeader = true);
  211. HRESULT Write(IStream* pStream);
  212. };
  213. class Track : public CID
  214. {
  215. public:
  216. CNode<TrackEntry> TrackEntries;
  217. Track(DWORD id = 0x1654AE6B);
  218. QWORD Size(bool fWithHeader = true);
  219. HRESULT Write(IStream* pStream);
  220. };
  221. class CBlock : public CID
  222. {
  223. public:
  224. CLength TrackNumber;
  225. REFERENCE_TIME TimeCode, TimeCodeStop;
  226. CNode<CBinary> BlockData;
  227. CBlock(DWORD id = 0xA1);
  228. QWORD Size(bool fWithHeader = true);
  229. HRESULT Write(IStream* pStream);
  230. };
  231. class BlockGroup : public CID
  232. {
  233. public:
  234. CUInt BlockDuration;
  235. CUInt ReferencePriority;
  236. CInt ReferenceBlock;
  237. CInt ReferenceVirtual;
  238. CBinary CodecState;
  239. CBlock Block;
  240. // CNode<TimeSlice> TimeSlices;
  241. BlockGroup(DWORD id = 0xA0);
  242. QWORD Size(bool fWithHeader = true);
  243. HRESULT Write(IStream* pStream);
  244. };
  245. class Cluster : public CID
  246. {
  247. public:
  248. CUInt TimeCode, Position, PrevSize;
  249. CNode<BlockGroup> BlockGroups;
  250. Cluster(DWORD id = 0x1F43B675);
  251. QWORD Size(bool fWithHeader = true);
  252. HRESULT Write(IStream* pStream);
  253. };
  254. /* class CueReference : public CID
  255. {
  256. public:
  257. CUInt CueRefTime, CueRefCluster, CueRefNumber, CueRefCodecState;
  258. CueReference(DWORD id = 0xDB);
  259. QWORD Size(bool fWithHeader = true);
  260. HRESULT Write(IStream* pStream);
  261. };
  262. */
  263. class CueTrackPosition : public CID
  264. {
  265. public:
  266. CUInt CueTrack, CueClusterPosition, CueBlockNumber, CueCodecState;
  267. // CNode<CueReference> CueReferences;
  268. CueTrackPosition(DWORD id = 0xB7);
  269. QWORD Size(bool fWithHeader = true);
  270. HRESULT Write(IStream* pStream);
  271. };
  272. class CuePoint : public CID
  273. {
  274. public:
  275. CUInt CueTime;
  276. CNode<CueTrackPosition> CueTrackPositions;
  277. CuePoint(DWORD id = 0xBB);
  278. QWORD Size(bool fWithHeader = true);
  279. HRESULT Write(IStream* pStream);
  280. };
  281. class Cue : public CID
  282. {
  283. public:
  284. CNode<CuePoint> CuePoints;
  285. Cue(DWORD id = 0x1C53BB6B);
  286. QWORD Size(bool fWithHeader = true);
  287. HRESULT Write(IStream* pStream);
  288. };
  289. class SeekID : public CID
  290. {
  291. CID m_id;
  292. public:
  293. SeekID(DWORD id = 0x53AB);
  294. void Set(DWORD id) {m_id = id;}
  295. QWORD Size(bool fWithHeader = true);
  296. HRESULT Write(IStream* pStream);
  297. };
  298. class SeekHead : public CID
  299. {
  300. public:
  301. SeekID ID;
  302. CUInt Position;
  303. SeekHead(DWORD id = 0x4DBB);
  304. QWORD Size(bool fWithHeader = true);
  305. HRESULT Write(IStream* pStream);
  306. };
  307. class Seek : public CID
  308. {
  309. public:
  310. CNode<SeekHead> SeekHeads;
  311. Seek(DWORD id = 0x114D9B74);
  312. QWORD Size(bool fWithHeader = true);
  313. HRESULT Write(IStream* pStream);
  314. };
  315. class Segment : public CID
  316. {
  317. public:
  318. Segment(DWORD id = 0x18538067);
  319. QWORD Size(bool fWithHeader = true);
  320. HRESULT Write(IStream* pStream);
  321. };
  322. class Tags : public CID
  323. {
  324. public:
  325. // TODO
  326. Tags(DWORD id = 0x1254C367);
  327. QWORD Size(bool fWithHeader = true);
  328. HRESULT Write(IStream* pStream);
  329. };
  330. class Void : public CID
  331. {
  332. QWORD m_len;
  333. public:
  334. Void(QWORD len, DWORD id = 0xEC);
  335. QWORD Size(bool fWithHeader = true);
  336. HRESULT Write(IStream* pStream);
  337. };
  338. }