mpg.c
资源名称:tcpmp.rar [点击查看]
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:7k
源码类别:
Windows CE
开发平台:
C/C++
- /*****************************************************************************
- *
- * This program is free software ; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id: mpg.c 607 2006-01-22 20:58:29Z picard $
- *
- * The Core Pocket Media Player
- * Copyright (c) 2004-2005 Gabor Kovacs
- *
- ****************************************************************************/
- #include "../common/common.h"
- #include "mpg.h"
- typedef struct mpeg
- {
- format_base Format;
- bool_t ErrorShowed;
- } mpeg;
- static int Init(mpeg* p)
- {
- p->Format.TimeStamps = 1;
- p->Format.StartTime = 0;
- p->ErrorShowed = 0;
- return ERR_NONE;
- }
- static int findcode(format_reader* p)
- {
- int n;
- int32_t code = -1;
- for (n=0;n<0x4000;++n)
- {
- int v = p->Read8(p);
- if (v<0)
- break;
- code = (code<<8)|v;
- if ((code >> 8)==1)
- return code;
- }
- return -1;
- }
- static int64_t readtime(format_reader* p,int i)
- {
- int64_t t;
- t = (int64_t)((i >> 1) & 0x07) << 30;
- t |= (p->ReadBE16(p) >> 1) << 15;
- t |= (p->ReadBE16(p) >> 1);
- return t;
- }
- static int ReadPacket(mpeg* p, format_reader* Reader, format_packet* Packet)
- {
- format_stream* s;
- int PCM = 0;
- int code = findcode(Reader);
- int i;
- int64_t time;
- filepos_t end;
- if (code == 0x1BE || code == 0x1BF)
- {
- i = Reader->ReadBE16(Reader);
- Reader->Skip(Reader,i);
- return ERR_NONE;
- }
- if (code != 0x1BD && (code<0x1C0 || code>=0x1F0))
- return ERR_NONE;
- end = Reader->ReadBE16(Reader);
- end += Reader->FilePos;
- time = -1;
- while ((i = Reader->Read8(Reader))==255)
- if (Reader->FilePos >= end)
- return ERR_NONE;
- if ((i>>6)==1)
- {
- Reader->Read8(Reader);
- i = Reader->Read8(Reader);
- }
- if ((i>>5)==1)
- {
- time = readtime(Reader,i);
- if (i&16)
- time = readtime(Reader,Reader->Read8(Reader));
- }
- else
- if ((i>>6)==2)
- {
- filepos_t end2;
- if ((i>>4)!=8)
- {
- if (!p->ErrorShowed)
- {
- p->ErrorShowed = 1;
- ShowError(p->Format.Format.Class,MPG_ID,MPG_ENCRYPTED);
- }
- return ERR_END_OF_FILE;
- }
- i = Reader->Read8(Reader);
- end2 = Reader->Read8(Reader);
- end2 += Reader->FilePos;
- if (end2 > end)
- return ERR_NONE;
- if (i&128)
- {
- time = readtime(Reader,Reader->Read8(Reader));
- if (i&64)
- time = readtime(Reader,Reader->Read8(Reader));
- }
- Reader->Skip(Reader,end2-Reader->FilePos);
- }
- if (code == 0x1BD)
- {
- code = Reader->Read8(Reader);
- if (code >= 0x80 && code <= 0xBF)
- Reader->Skip(Reader,3);
- if (code >= 0xA0 && code <= 0xBF)
- {
- Reader->Skip(Reader,1);
- PCM = Reader->Read8(Reader);
- Reader->Skip(Reader,1);
- }
- }
- if (time>=0)
- {
- Packet->RefTime = (tick_t)((time * TICKSPERSEC) / 90000) - p->Format.StartTime;
- if (Packet->RefTime < 0)
- Packet->RefTime = 0;
- }
- else
- Packet->RefTime = TIME_UNKNOWN;
- s = NULL;
- for (i=0;i<p->Format.StreamCount;++i)
- if (p->Format.Streams[i]->Id == code)
- {
- s = p->Format.Streams[i];
- break;
- }
- if (!s)
- {
- if (Packet->RefTime < 0) //skip
- return ERR_NONE;
- if (!p->Format.StartTime)
- {
- p->Format.StartTime = Packet->RefTime;
- Packet->RefTime = 0;
- }
- switch (code>>4)
- {
- case 8:
- case 9:
- s = Format_AddStream(&p->Format,sizeof(format_stream));
- if (s)
- {
- s->Id = code;
- PacketFormatClear(&s->Format);
- s->Format.Type = PACKET_AUDIO;
- s->Format.Format.Audio.Format = AUDIOFMT_A52;
- Format_PrepairStream(&p->Format,s);
- }
- break;
- case 10:
- case 11:
- s = Format_AddStream(&p->Format,sizeof(format_stream));
- if (s)
- {
- static const int Freq[4] = { 48000, 96000, 44100, 32000 };
- s->Id = code;
- PacketFormatClear(&s->Format);
- s->Format.Type = PACKET_AUDIO;
- s->Format.Format.Audio.Format = AUDIOFMT_PCM;
- s->Format.Format.Audio.SampleRate = Freq[(PCM >> 4) & 3];
- s->Format.Format.Audio.Channels = 1 + (PCM & 7);
- s->Format.Format.Audio.Bits = 16;
- s->Format.Format.Audio.FracBits = 15;
- s->Format.ByteRate = s->Format.Format.Audio.SampleRate * s->Format.Format.Audio.Channels * 2;
- Format_PrepairStream(&p->Format,s);
- }
- break;
- case 28:
- case 29:
- s = Format_AddStream(&p->Format,sizeof(format_stream));
- if (s)
- {
- s->Id = code;
- PacketFormatClear(&s->Format);
- s->Format.Type = PACKET_AUDIO;
- s->Format.Format.Audio.Format = AUDIOFMT_MP2;
- Format_PrepairStream(&p->Format,s);
- }
- break;
- case 30:
- s = Format_AddStream(&p->Format,sizeof(format_stream));
- if (s)
- {
- // minimal mpeg4 detection
- int32_t code1 = 0;
- int32_t code2 = 0;
- filepos_t pos = Reader->FilePos;
- if (end >= pos+8)
- {
- code1 = Reader->ReadBE32(Reader);
- if (code1 == 0x100)
- code2 = Reader->ReadBE32(Reader);
- Reader->Seek(Reader,pos,SEEK_SET);
- }
- s->Id = code;
- PacketFormatClear(&s->Format);
- s->Format.Type = PACKET_VIDEO;
- s->Format.Format.Video.Pixel.Flags = PF_FOURCC | PF_FRAGMENTED;
- if ((code1 == 0x100 && code2 == 0x120) || code1 == 0x120)
- s->Format.Format.Video.Pixel.FourCC = FOURCC('M','P','4','V');
- else
- s->Format.Format.Video.Pixel.FourCC = FOURCC('M','P','E','G');
- Format_PrepairStream(&p->Format,s);
- }
- break;
- }
- if (!s)
- {
- Reader->Skip(Reader,end - Reader->FilePos);
- return ERR_NONE;
- }
- }
- Packet->Stream = s;
- Packet->Data = Reader->ReadAsRef(Reader,end - Reader->FilePos);
- return ERR_NONE;
- }
- static int Create(mpeg* p)
- {
- p->Format.Init = (fmtfunc)Init;
- p->Format.Seek = (fmtseek)Format_SeekByPacket;
- p->Format.ReadPacket = (fmtreadpacket)ReadPacket;
- p->Format.MinHeaderLoad = MINBUFFER/2;
- return ERR_NONE;
- }
- static const nodedef MPG =
- {
- sizeof(mpeg),
- MPG_ID,
- FORMATBASE_CLASS,
- PRI_DEFAULT-10, // lower priority so others can override
- (nodecreate)Create,
- NULL,
- };
- void MPG_Init()
- {
- NodeRegisterClass(&MPG);
- }
- void MPG_Done()
- {
- NodeUnRegisterClass(MPG_ID);
- }