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

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: mpg.c 607 2006-01-22 20:58:29Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../common/common.h"
  24. #include "mpg.h"
  25. typedef struct mpeg
  26. {
  27. format_base Format;
  28. bool_t ErrorShowed;
  29. } mpeg;
  30. static int Init(mpeg* p)
  31. {
  32. p->Format.TimeStamps = 1;
  33. p->Format.StartTime = 0;
  34. p->ErrorShowed = 0;
  35. return ERR_NONE;
  36. }
  37. static int findcode(format_reader* p)
  38. {
  39. int n;
  40. int32_t code = -1;
  41. for (n=0;n<0x4000;++n)
  42. {
  43.         int v = p->Read8(p);
  44. if (v<0)
  45. break;
  46. code = (code<<8)|v;
  47. if ((code >> 8)==1)
  48. return code;
  49.     }
  50.     return -1;
  51. }
  52. static int64_t readtime(format_reader* p,int i)
  53. {
  54.     int64_t t;
  55.     t = (int64_t)((i >> 1) & 0x07) << 30;
  56.     t |= (p->ReadBE16(p) >> 1) << 15;
  57.     t |= (p->ReadBE16(p) >> 1);
  58.     return t;
  59. }
  60. static int ReadPacket(mpeg* p, format_reader* Reader, format_packet* Packet)
  61. {
  62. format_stream* s;
  63. int PCM = 0;
  64. int code = findcode(Reader);
  65. int i;
  66. int64_t time;
  67. filepos_t end;
  68.     if (code == 0x1BE || code == 0x1BF) 
  69. {
  70. i = Reader->ReadBE16(Reader);
  71. Reader->Skip(Reader,i);
  72. return ERR_NONE;
  73.     }
  74.     if (code != 0x1BD && (code<0x1C0 || code>=0x1F0))
  75.         return ERR_NONE;
  76.     end = Reader->ReadBE16(Reader);
  77. end += Reader->FilePos;
  78.     time = -1;
  79.  
  80.     while ((i = Reader->Read8(Reader))==255)
  81. if (Reader->FilePos >= end)
  82. return ERR_NONE;
  83.     if ((i>>6)==1) 
  84. {
  85. Reader->Read8(Reader);
  86.         i = Reader->Read8(Reader);
  87.     }
  88. if ((i>>5)==1)
  89. {
  90. time = readtime(Reader,i);
  91. if (i&16)
  92. time = readtime(Reader,Reader->Read8(Reader));
  93. }
  94. else 
  95. if ((i>>6)==2) 
  96. {
  97. filepos_t end2;
  98. if ((i>>4)!=8) 
  99. {
  100. if (!p->ErrorShowed)
  101. {
  102. p->ErrorShowed = 1;
  103. ShowError(p->Format.Format.Class,MPG_ID,MPG_ENCRYPTED);
  104. }
  105.         return ERR_END_OF_FILE;
  106. }
  107.         i = Reader->Read8(Reader);
  108.         end2 = Reader->Read8(Reader);
  109. end2 += Reader->FilePos;
  110. if (end2 > end)
  111. return ERR_NONE;
  112.         if (i&128) 
  113. {
  114.             time = readtime(Reader,Reader->Read8(Reader));
  115. if (i&64)
  116. time = readtime(Reader,Reader->Read8(Reader));
  117. }
  118. Reader->Skip(Reader,end2-Reader->FilePos);
  119.     }
  120.     if (code == 0x1BD)
  121. {
  122.         code = Reader->Read8(Reader);
  123.         if (code >= 0x80 && code <= 0xBF) 
  124. Reader->Skip(Reader,3);
  125. if (code >= 0xA0 && code <= 0xBF) 
  126. {
  127. Reader->Skip(Reader,1);
  128. PCM = Reader->Read8(Reader);
  129. Reader->Skip(Reader,1);
  130. }
  131.     }
  132. if (time>=0)
  133. {
  134. Packet->RefTime = (tick_t)((time * TICKSPERSEC) / 90000) - p->Format.StartTime;
  135. if (Packet->RefTime < 0)
  136. Packet->RefTime = 0;
  137. }
  138. else
  139. Packet->RefTime = TIME_UNKNOWN;
  140. s = NULL;
  141. for (i=0;i<p->Format.StreamCount;++i)
  142. if (p->Format.Streams[i]->Id == code)
  143. {
  144. s = p->Format.Streams[i];
  145. break;
  146. }
  147. if (!s)
  148. {
  149. if (Packet->RefTime < 0) //skip
  150. return ERR_NONE;
  151. if (!p->Format.StartTime)
  152. {
  153. p->Format.StartTime = Packet->RefTime;
  154. Packet->RefTime = 0;
  155. }
  156. switch (code>>4)
  157. {
  158. case 8:
  159. case 9:
  160. s = Format_AddStream(&p->Format,sizeof(format_stream));
  161. if (s)
  162. {
  163. s->Id = code;
  164. PacketFormatClear(&s->Format);
  165. s->Format.Type = PACKET_AUDIO;
  166. s->Format.Format.Audio.Format = AUDIOFMT_A52;
  167. Format_PrepairStream(&p->Format,s);
  168. }
  169. break;
  170. case 10:
  171. case 11:
  172. s = Format_AddStream(&p->Format,sizeof(format_stream));
  173. if (s)
  174. {
  175. static const int Freq[4] = { 48000, 96000, 44100, 32000 };
  176. s->Id = code;
  177. PacketFormatClear(&s->Format);
  178. s->Format.Type = PACKET_AUDIO;
  179. s->Format.Format.Audio.Format = AUDIOFMT_PCM;
  180. s->Format.Format.Audio.SampleRate = Freq[(PCM >> 4) & 3];
  181. s->Format.Format.Audio.Channels = 1 + (PCM & 7);
  182. s->Format.Format.Audio.Bits = 16;
  183. s->Format.Format.Audio.FracBits = 15;
  184. s->Format.ByteRate = s->Format.Format.Audio.SampleRate * s->Format.Format.Audio.Channels * 2;
  185. Format_PrepairStream(&p->Format,s);
  186. }
  187. break;
  188. case 28:
  189. case 29:
  190. s = Format_AddStream(&p->Format,sizeof(format_stream));
  191. if (s)
  192. {
  193. s->Id = code;
  194. PacketFormatClear(&s->Format);
  195. s->Format.Type = PACKET_AUDIO;
  196. s->Format.Format.Audio.Format = AUDIOFMT_MP2;
  197. Format_PrepairStream(&p->Format,s);
  198. }
  199. break;
  200. case 30:
  201. s = Format_AddStream(&p->Format,sizeof(format_stream));
  202. if (s)
  203. {
  204. // minimal mpeg4 detection
  205. int32_t code1 = 0;
  206. int32_t code2 = 0;
  207. filepos_t pos = Reader->FilePos;
  208. if (end >= pos+8)
  209. {
  210. code1 = Reader->ReadBE32(Reader);
  211. if (code1 == 0x100)
  212. code2 = Reader->ReadBE32(Reader);
  213. Reader->Seek(Reader,pos,SEEK_SET);
  214. }
  215. s->Id = code;
  216. PacketFormatClear(&s->Format);
  217. s->Format.Type = PACKET_VIDEO;
  218. s->Format.Format.Video.Pixel.Flags = PF_FOURCC | PF_FRAGMENTED;
  219. if ((code1 == 0x100 && code2 == 0x120) || code1 == 0x120)
  220. s->Format.Format.Video.Pixel.FourCC = FOURCC('M','P','4','V');
  221. else
  222. s->Format.Format.Video.Pixel.FourCC = FOURCC('M','P','E','G');
  223. Format_PrepairStream(&p->Format,s);
  224. }
  225. break;
  226. if (!s)
  227. {
  228. Reader->Skip(Reader,end - Reader->FilePos);
  229. return ERR_NONE;
  230. }
  231. }
  232. Packet->Stream = s;
  233. Packet->Data = Reader->ReadAsRef(Reader,end - Reader->FilePos);
  234. return ERR_NONE;
  235. }
  236. static int Create(mpeg* p)
  237. {
  238. p->Format.Init = (fmtfunc)Init;
  239. p->Format.Seek = (fmtseek)Format_SeekByPacket;
  240. p->Format.ReadPacket = (fmtreadpacket)ReadPacket;
  241. p->Format.MinHeaderLoad = MINBUFFER/2;
  242. return ERR_NONE;
  243. }
  244. static const nodedef MPG =
  245. {
  246. sizeof(mpeg),
  247. MPG_ID,
  248. FORMATBASE_CLASS,
  249. PRI_DEFAULT-10, // lower priority so others can override
  250. (nodecreate)Create,
  251. NULL,
  252. };
  253. void MPG_Init()
  254. {
  255. NodeRegisterClass(&MPG);
  256. }
  257. void MPG_Done()
  258. {
  259. NodeUnRegisterClass(MPG_ID);
  260. }