matroska.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:15k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: matroska.c 548 2006-01-08 22:41:57Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../common/common.h"
  24. #include "matroska.h"
  25. #include "MatroskaParser/MatroskaParser.h"
  26. typedef struct matroska
  27. {
  28. format_base Format;
  29. InputStream IO;
  30. MatroskaFile* File;
  31. } matroska;
  32. #define MK(p) ((matroska*)((char*)(p)-OFS(matroska,IO)))
  33. static void AudioTrackMS(format_stream* s,TrackInfo* Info)
  34. {
  35. s->Fragmented = 1;
  36. Format_WaveFormatMem(s,Info->CodecPrivate,Info->CodecPrivateSize);
  37. }
  38. static void AudioTrack(format_stream* s,TrackInfo* Info,int Format,bool_t PacketBased)
  39. {
  40. PacketFormatClear(&s->Format);
  41. s->Format.Type = PACKET_AUDIO;
  42. s->Format.Format.Audio.Format = Format;
  43. s->Format.Format.Audio.Channels = Info->Audio.Channels;
  44. s->Format.Format.Audio.SampleRate = mkv_TruncFloat(Info->Audio.SamplingFreq);
  45. s->Format.Format.Audio.Bits = Info->Audio.BitDepth;
  46. s->Fragmented = !PacketBased;
  47. if (PacketBased)
  48. s->Format.Format.Audio.Flags |= PCM_PACKET_BASED;
  49. PacketFormatDefault(&s->Format);
  50. }
  51. static void SetPacketRate(format_stream* s,TrackInfo* Info)
  52. {
  53. if (Info->DefaultDuration)
  54. {
  55. longlong v = Info->DefaultDuration;
  56. s->Format.PacketRate.Num = 1000000000;
  57. while (v > MAX_INT)
  58. {
  59. v >>= 1;
  60. s->Format.PacketRate.Num >>= 1;
  61. }
  62. s->Format.PacketRate.Den = (int)v;
  63.    }
  64. }
  65. static NOINLINE void VideoAspect(format_stream* s,TrackInfo* Info)
  66. {
  67. if (Info->Video.PixelWidth>0 && Info->Video.PixelHeight>0 &&
  68. Info->Video.DisplayWidth>0 && Info->Video.DisplayHeight>0)
  69. s->Format.Format.Video.Aspect = (int)((ASPECT_ONE*(int64_t)Info->Video.DisplayWidth*(int64_t)Info->Video.PixelHeight)/
  70. ((int64_t)Info->Video.PixelWidth*(int64_t)Info->Video.DisplayHeight));
  71. }
  72. static NOINLINE void VideoTrackMS(format_stream* s,TrackInfo* Info)
  73. {
  74. Format_BitmapInfoMem(s,Info->CodecPrivate,Info->CodecPrivateSize);
  75. VideoAspect(s,Info);
  76. SetPacketRate(s,Info);
  77. }
  78. static NOINLINE void SubtitleTrack(format_stream* s,int FourCC)
  79. {
  80. PacketFormatClear(&s->Format);
  81. s->Format.Type = PACKET_SUBTITLE;
  82. s->Format.Format.Subtitle.FourCC = FourCC;
  83. }
  84. static NOINLINE void VideoTrack(format_stream* s,TrackInfo* Info,int FourCC)
  85. {
  86. PacketFormatClear(&s->Format);
  87. s->Format.Type = PACKET_VIDEO;
  88. s->Format.Format.Video.Pixel.Flags = PF_FOURCC;
  89. s->Format.Format.Video.Pixel.FourCC = FourCC;
  90. s->Format.Format.Video.Width = Info->Video.PixelWidth;
  91. s->Format.Format.Video.Height = Info->Video.PixelHeight;
  92. s->Format.Format.Video.Aspect = ASPECT_ONE;
  93. VideoAspect(s,Info);
  94. SetPacketRate(s,Info);
  95. }
  96. static NOINLINE void AddChapter(pin* Comment,ulonglong Start,struct ChapterDisplay* p,int No)
  97. {
  98. tchar_t s[256];
  99. stprintf_s(s,TSIZEOF(s),T("CHAPTER%02dNAME="),No);
  100. UTF8ToTcs(s+tcslen(s),TSIZEOF(s)-tcslen(s),p->String);
  101. Comment->Node->Set(Comment->Node,Comment->No,s,sizeof(s));
  102. BuildChapter(s,TSIZEOF(s),No,Start,1000000);
  103. Comment->Node->Set(Comment->Node,Comment->No,s,sizeof(s));
  104. }
  105. static NOINLINE void AddAttachment(pin* Comment,Attachment *At) 
  106. {
  107. tchar_t MimeType[32];
  108. StrToTcs(MimeType,TSIZEOF(MimeType),At->MimeType);
  109. if (tcsnicmp(MimeType,T("image"),5)==0)
  110. {
  111. tchar_t s[256];
  112. stprintf_s(s,TSIZEOF(s),T("%s=:%d:%d:%s"),PlayerComment(COMMENT_COVER),(int)At->Position,(int)At->Length,MimeType);
  113. Comment->Node->Set(Comment->Node,Comment->No,s,sizeof(s));
  114. }
  115. }
  116. static int AddChapters(pin* Comment,Chapter *Ch,int No) 
  117. {
  118. uint32_t i,j;
  119. if (Ch)
  120. for (i=0;i<Ch->nChildren;++i) 
  121. {
  122. for (j=0;j<Ch->Children[i].nDisplay;++i)
  123. if (Ch->Children[i].Display[j].String)
  124. {
  125. AddChapter(Comment,Ch->Children[i].Start,
  126. &Ch->Children[i].Display[j],No++);
  127. break;
  128. }
  129. No = AddChapters(Comment,&Ch->Children[i],No);
  130. }
  131. return No;
  132. }
  133. static void AddComment(pin* Comment,tchar_t* Name,char* Value) 
  134. {
  135. if (Comment->Node && Value)
  136. {
  137. tchar_t s[256];
  138. tcscpy_s(s,TSIZEOF(s),Name);
  139. tcscat_s(s,TSIZEOF(s),T("="));
  140. UTF8ToTcs(s+tcslen(s),TSIZEOF(s)-tcslen(s),Value);
  141. Comment->Node->Set(Comment->Node,Comment->No,s,sizeof(s));
  142. }
  143. }
  144. static void BuildConfig(format_stream* s,const char* CodecID,int OutputFreq)
  145. {
  146. static const int Rates[12] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000};
  147. int Rate;
  148. int Profile;
  149. uint8_t* Config;
  150. int Len = 2;
  151. bool_t SBR = 0;
  152. if (OutputFreq > s->Format.Format.Audio.SampleRate)
  153. {
  154. if (OutputFreq > 24000)
  155. OutputFreq >>= 1;
  156. s->Format.Format.Audio.SampleRate = OutputFreq;
  157. SBR = 1;
  158. }
  159. for (Rate=0;Rate<11;++Rate)
  160. if (s->Format.Format.Audio.SampleRate >= Rates[Rate])
  161. break;
  162. if (strcmp(CodecID+12, "MAIN")==0)
  163. Profile = 1;
  164. else if (strcmp(CodecID+12, "SSR")==0)
  165. Profile = 3;
  166. else if (strcmp(CodecID+12, "LTP")==0)
  167. Profile = 4;
  168. else if (strcmp(CodecID+12, "SBR")==0)
  169. Profile = 5;
  170. else if (strcmp(CodecID+12, "LC/SBR")==0 || SBR)
  171. {
  172. Profile = 2;
  173. Len = 5;
  174. }
  175. else
  176. Profile = 2; //assuming LC
  177. if (PacketFormatExtra(&s->Format,Len))
  178. {
  179. Config = (uint8_t*)s->Format.Extra;
  180.     Config[0] = (uint8_t)(Profile << 3);
  181.     Config[0] |= (uint8_t)(Rate >> 1);
  182.     Config[1] = (uint8_t)(Rate << 7);
  183.     Config[1] |= (uint8_t)(s->Format.Format.Audio.Channels << 3);
  184. if (Len>2)
  185. {
  186. if (s->Format.Format.Audio.SampleRate <= 24000)
  187. s->Format.Format.Audio.SampleRate <<= 1;
  188. for (Rate=0;Rate<11;++Rate)
  189. if (s->Format.Format.Audio.SampleRate >= Rates[Rate])
  190. break;
  191. Config[2] = 0x56;
  192. Config[3] = 0xE5;
  193. Config[4] = 0x80;
  194. Config[4] |= (uint8_t)(Rate << 3);
  195. }
  196. }
  197. }
  198. static int Init(matroska* p)
  199. {
  200. unsigned n,Count;
  201. SegmentInfo* Info;
  202. p->File = mkv_Open(&p->IO,NULL,0);
  203. if (!p->File)
  204. return ERR_INVALID_DATA;
  205. Info = mkv_GetFileInfo(p->File);
  206. if (Info)
  207. p->Format.Duration = (tick_t)((Info->Duration * TICKSPERSEC) / 1000000000);
  208. Count = mkv_GetNumTracks(p->File);
  209. for (n=0;n<Count;++n)
  210. {
  211. format_stream* s = Format_AddStream(&p->Format,sizeof(format_stream));
  212. if (s)
  213. {
  214. TrackInfo *Info = mkv_GetTrackInfo(p->File,n);
  215. if (Info)
  216. {
  217. int CodecPrivateSize = Info->CodecPrivateSize;
  218. if (strcmp(Info->CodecID, "V_MS/VFW/FOURCC")==0)
  219. {
  220. VideoTrackMS(s,Info);
  221. CodecPrivateSize = 0;
  222. }
  223. else if (strncmp(Info->CodecID, "V_REAL/RV", 9)==0)
  224. VideoTrack(s,Info,LOAD32LE(Info->CodecID+7));
  225. else if (strncmp(Info->CodecID, "V_MPEG4/ISO/AVC", 14)==0)
  226. {
  227. VideoTrack(s,Info,FOURCC('A','V','C','1'));
  228. s->Format.Format.Video.Pixel.Flags |= PF_PTS;
  229. }
  230. else if (strncmp(Info->CodecID, "V_MPEG4/ISO", 11)==0)
  231. VideoTrack(s,Info,FOURCC('M','P','4','V'));
  232. else if (strcmp(Info->CodecID, "V_MPEG4/MS/V3")==0)
  233. VideoTrack(s,Info,FOURCC('M','P','4','3'));
  234. else if (strcmp(Info->CodecID, "V_MPEG1")==0 || strcmp(Info->CodecID, "V_MPEG2")==0)
  235. VideoTrack(s,Info,FOURCC('M','P','E','G'));
  236. else if (strcmp(Info->CodecID, "V_MJPEG")==0)
  237. VideoTrack(s,Info,FOURCC('M','J','P','G'));
  238. else if (strcmp(Info->CodecID, "A_MPEG/L3")==0)
  239. AudioTrack(s,Info,AUDIOFMT_MP3,0);
  240. else if (strcmp(Info->CodecID, "A_MPEG/L2")==0 || strcmp(Info->CodecID, "A_MPEG/L1")==0)
  241. AudioTrack(s,Info,AUDIOFMT_MP2,0);
  242. else if (strcmp(Info->CodecID, "A_PCM/INT/LIT")==0)
  243. AudioTrack(s,Info,AUDIOFMT_PCM,0);
  244. else if (strstr(Info->CodecID, "A_AC3")!=NULL || strcmp(Info->CodecID, "A_DTS")==0)
  245. AudioTrack(s,Info,AUDIOFMT_A52,0);
  246. else if (strstr(Info->CodecID, "A_AAC")!=NULL)
  247. {
  248. AudioTrack(s,Info,AUDIOFMT_AAC,1);
  249. if (!CodecPrivateSize)
  250. BuildConfig(s,Info->CodecID,mkv_TruncFloat(Info->Audio.OutputSamplingFreq));
  251. }
  252. else if (strcmp(Info->CodecID, "A_VORBIS")==0)
  253. AudioTrack(s,Info,AUDIOFMT_VORBIS_PACKET,1);
  254. else if (strcmp(Info->CodecID, "A_QUICKTIME/QDM2")==0)
  255. AudioTrack(s,Info,AUDIOFMT_QDESIGN2,1);
  256. else if (strcmp(Info->CodecID, "A_TTA1")==0)
  257. AudioTrack(s,Info,AUDIOFMT_TTA,1);
  258. else if (strcmp(Info->CodecID, "A_MS/ACM")==0)
  259. {
  260. AudioTrackMS(s,Info);
  261. CodecPrivateSize = 0;
  262. }
  263. else if (strcmp(Info->CodecID, "S_TEXT/UTF8")==0)
  264. SubtitleTrack(s,SUBTITLE_UTF8);
  265. else if (strcmp(Info->CodecID, "S_TEXT/SSA")==0)
  266. SubtitleTrack(s,SUBTITLE_SSA);
  267. else if (strcmp(Info->CodecID, "S_TEXT/ASS")==0)
  268. SubtitleTrack(s,SUBTITLE_ASS);
  269. else if (strcmp(Info->CodecID, "S_TEXT/USF")==0)
  270. SubtitleTrack(s,SUBTITLE_USF);
  271. if (CodecPrivateSize && PacketFormatExtra(&s->Format,CodecPrivateSize))
  272. memcpy(s->Format.Extra,Info->CodecPrivate,s->Format.ExtraLength);
  273. }
  274. Format_PrepairStream(&p->Format,s);
  275. AddComment(&s->Comment,T("TITLE"),Info->Name);
  276. AddComment(&s->Comment,T("LANGUAGE"),Info->Language);
  277. }
  278. }
  279. if (p->Format.StreamCount)
  280. {
  281. pin* Comment = &p->Format.Streams[0]->Comment;
  282. Tag* Tags;
  283. Chapter* Ch;
  284. Attachment* At;
  285. mkv_GetTags(p->File,&Tags,&Count);
  286. if (Tags && Comment->Node)
  287. for (n=0;n<Count;++n,++Tags)
  288. {
  289. uint32_t i;
  290. for (i=0;i<Tags->nSimpleTags;++i)
  291. {
  292. tchar_t s[256];
  293. UTF8ToTcs(s,TSIZEOF(s),Tags->SimpleTags[i].Name);
  294. tcscat_s(s,TSIZEOF(s),T("="));
  295. UTF8ToTcs(s+tcslen(s),TSIZEOF(s)-tcslen(s),Tags->SimpleTags[i].Value);
  296. Comment->Node->Set(Comment->Node,Comment->No,s,sizeof(s));
  297. }
  298. }
  299. mkv_GetAttachments(p->File,&At,&Count);
  300. if (Count>0)
  301. for (n=0;n<Count;++n)
  302. AddAttachment(Comment,At+n);
  303. mkv_GetChapters(p->File,&Ch,&Count);
  304. if (Count>0 && Info)
  305. AddChapters(Comment,Ch,1);
  306. }
  307. mkv_SetTrackMask(p->File,0);
  308. p->Format.HeaderLoaded = 1;
  309. return ERR_NONE;
  310. }
  311. static void Done(matroska* p)
  312. {
  313. if (p->File)
  314. {
  315. mkv_Close(p->File);
  316. p->File = NULL;
  317. }
  318. }
  319. static int ReadPacket(matroska* p, format_reader* Reader, format_packet* Packet)
  320. {
  321. ulonglong Start,End;
  322. void* Ref;
  323. ulonglong Pos;
  324. unsigned int Flags,Track,Size;
  325. int Result = mkv_ReadFrame(p->File,0,&Track,&Start,&End,&Pos,&Size,&Ref,&Flags);
  326. if (Result == EOF)
  327. return ERR_END_OF_FILE;
  328. if (Result != 0)
  329. return ERR_INVALID_DATA;
  330. Packet->Data = (format_ref*)Ref;
  331. Packet->Key = (Flags & FRAME_KF) != 0;
  332. Packet->Stream = p->Format.Streams[Track];
  333. if (!(Flags & FRAME_UNKNOWN_START))
  334. {
  335. Packet->RefTime = (tick_t)((Start * TICKSPERSEC) / 1000000000);
  336. if (Packet->Stream->Format.Type == PACKET_SUBTITLE && !(Flags & FRAME_UNKNOWN_END))
  337. Packet->EndRefTime = (tick_t)((End * TICKSPERSEC) / 1000000000);
  338. }
  339. return ERR_NONE;
  340. }
  341. static int Seek(matroska* p, tick_t Time, filepos_t FilePos,bool_t PrevKey)
  342. {
  343. if (Time < 0 && FilePos >= 0 && p->Format.Duration > 0 && p->Format.FileSize > 0)
  344. Time = Scale(FilePos, p->Format.Duration, p->Format.FileSize);
  345. if (Time >= 0)
  346. {
  347. p->Format.SyncRead = 0; // don't use partial buffers
  348. mkv_Seek(p->File,((ulonglong)Time * 1000000000 + (TICKSPERSEC/2))/TICKSPERSEC,PrevKey?MKVF_SEEK_TO_PREV_KEYFRAME:0);
  349. Format_AfterSeek(&p->Format);
  350. return ERR_NONE;
  351. }
  352. return ERR_NOT_SUPPORTED;
  353. }
  354. static int Read(struct InputStream *cc,ulonglong pos,void *buffer,int count)
  355. {
  356. format_reader* Reader = &MK(cc)->Format.Reader[0];
  357. if (Reader->FilePos != pos && Reader->Seek(Reader,(filepos_t)pos,SEEK_SET) != ERR_NONE)
  358. return -1;
  359. return Reader->Read(Reader,buffer,count);
  360. }
  361. static longlong Scan(struct InputStream *cc,ulonglong start,unsigned signature)
  362. {
  363. format_reader* Reader = &MK(cc)->Format.Reader[0];
  364. unsigned v = ~signature;
  365. int ch;
  366. if (Reader->FilePos != start && Reader->Seek(Reader,(filepos_t)start,SEEK_SET) != ERR_NONE)
  367. return -1;
  368. while ((ch = Reader->Read8(Reader)) >= 0)
  369. {
  370. v = ((v << 8) | ch) & 0xFFFFFFFF;
  371. if (v == signature)
  372. return Reader->FilePos - 4;
  373. }
  374. return -1;
  375. }
  376. static unsigned GetSize(struct InputStream *cc)
  377. {
  378. return MK(cc)->Format.Reader->BufferAvailable;
  379. }
  380. static const char* GetError(struct InputStream *cc)
  381. {
  382. return "";
  383. }
  384. static void* MemAlloc(struct InputStream *cc,size_t size)
  385. {
  386. return malloc(size);
  387. }
  388. static void* MemReAlloc(struct InputStream *cc,void *mem,size_t newsize)
  389. {
  390. return realloc(mem,newsize);
  391. }
  392. static void MemFree(struct InputStream *cc,void *mem)
  393. {
  394. free(mem);
  395. }
  396. static int Progress(struct InputStream *cc,ulonglong cur,ulonglong max)
  397. {
  398. return 1;
  399. }
  400. static int IOReadCh(struct InputStream *IO)
  401. {
  402. return MK(IO)->Format.Reader->Read8(MK(IO)->Format.Reader);
  403. }
  404. static int IORead(struct InputStream *IO,void *buffer,int count)
  405. {
  406. return MK(IO)->Format.Reader->Read(MK(IO)->Format.Reader,buffer,count);
  407. }
  408. static void IOSeek(struct InputStream *IO,longlong where,int how)
  409. {
  410.     MK(IO)->Format.Reader->Seek(MK(IO)->Format.Reader,(filepos_t)where,how);
  411. }
  412. static longlong IOTell(struct InputStream *IO)
  413. {
  414. return MK(IO)->Format.Reader->FilePos;
  415. }
  416. static void* IOMakeRef(struct InputStream *IO,int count)
  417. {
  418. return MK(IO)->Format.Reader->ReadAsRef(MK(IO)->Format.Reader,count);
  419. }
  420. static void IOReleaseRef(struct InputStream *IO,void* ref)
  421. {
  422. Format_ReleaseRef(&MK(IO)->Format,(format_ref*)ref);
  423. }
  424. static int Create(matroska* p)
  425. {
  426. p->Format.Init = (fmtfunc)Init;
  427. p->Format.Done = (fmtvoid)Done;
  428. p->Format.Seek = (fmtseek)Seek;
  429. p->Format.ReadPacket = (fmtreadpacket) ReadPacket;
  430.    p->IO.read = Read;
  431. p->IO.scan = Scan;
  432. p->IO.getsize = GetSize;
  433. p->IO.geterror = GetError;
  434. p->IO.memalloc = MemAlloc;
  435. p->IO.memrealloc = MemReAlloc;
  436. p->IO.memfree = MemFree;
  437. p->IO.progress = Progress;
  438. p->IO.ioread = IORead;
  439. p->IO.ioreadch = IOReadCh;
  440. p->IO.ioseek = IOSeek;
  441. p->IO.iotell = IOTell;
  442. p->IO.makeref = IOMakeRef;
  443. p->IO.releaseref = IOReleaseRef;
  444. return ERR_NONE;
  445. }
  446. static const nodedef Matroska = 
  447. {
  448. sizeof(matroska),
  449. MATROSKA_ID,
  450. FORMATBASE_CLASS,
  451. PRI_DEFAULT,
  452. (nodecreate)Create,
  453. };
  454. void Matroska_Init()
  455. {
  456. NodeRegisterClass(&Matroska);
  457. }
  458. void Matroska_Done()
  459. {
  460. NodeUnRegisterClass(MATROSKA_ID);
  461. }