static bool_t SpeexHeader(ogg* p, oggstream* s, const char* Data, int Length ) { if (Length<80 && strncmp(Data,"Speex ",8)!=0) return 0; PacketFormatClear(&s->Stream.Format); s->Stream.Format.Type = PACKET_AUDIO; s->Stream.Format.Format.Audio.Format = AUDIOFMT_SPEEX; s->Stream.Format.Format.Audio.Channels = INT32LE(*(int32_t*)(Data+48)); s->Stream.Format.ByteRate = INT32LE(*(int32_t*)(Data+52))/8; s->Stream.Format.Format.Audio.SampleRate = INT32LE(*(int32_t*)(Data+36)); s->MediaRateDen = TICKSPERSEC; s->MediaRateNum = s->Stream.Format.Format.Audio.SampleRate; s->Native = 1; if (PacketFormatExtra(&s->Stream.Format,Length)) memcpy(s->Stream.Format.Extra,Data,s->Stream.Format.ExtraLength); return 1; }
static bool_t OGMHeader(ogg* p, oggstream* s, const char* Data, int Length ) { int i; if (Length<40 || (*Data & PACKET_TYPE_BITS) != PACKET_TYPE_HEADER) return 0; if (strncmp(Data+1, "Direct Show Samples embedded in Ogg", 35) == 0) { // old header if (INT32LE(*(int32_t*)(Data+96)) == 0x05589F80) { PacketFormatClear(&s->Stream.Format); s->Stream.Format.Type = PACKET_VIDEO; s->Stream.Format.Format.Video.Width = INT32LE(*(int32_t*)(Data+176)); s->Stream.Format.Format.Video.Height = INT32LE(*(int32_t*)(Data+180)); s->Stream.Format.Format.Video.Pixel.FourCC = INT32LE(*(int32_t*)(Data+68)); s->Stream.Format.Format.Video.Pixel.BitCount = INT16LE(*(int16_t*)(Data+182)); i = INT16LE(*(int16_t*)(Data+136)); // extrasize if (i && PacketFormatExtra(&s->Stream.Format,i)) memcpy(s->Stream.Format.Extra,Data+142,s->Stream.Format.ExtraLength); s->MediaRateDen = INT64LE(*(int32_t*)(Data+164))*TICKSPERSEC; s->MediaRateNum = 10000000; s->DefaultLen = 1; FrameRate(&s->Stream.Format.PacketRate,s->MediaRateNum,s->MediaRateDen/TICKSPERSEC); return 1; } if (INT32LE(*(int32_t*)(Data+96)) == 0x05589F81) { PacketFormatClear(&s->Stream.Format); s->Stream.Format.Type = PACKET_AUDIO; s->Stream.Format.Format.Audio.Format = INT16LE(*(int16_t*)(Data+124)); s->Stream.Format.Format.Audio.Channels = INT16LE(*(int16_t*)(Data+126)); s->Stream.Format.Format.Audio.BlockAlign = INT16LE(*(int16_t*)(Data+136)); s->Stream.Format.Format.Audio.Bits = INT16LE(*(int16_t*)(Data+138)); s->Stream.Format.Format.Audio.SampleRate = INT32LE(*(int32_t*)(Data+128)); s->Stream.Format.ByteRate = INT32LE(*(int32_t*)(p+132)); i = INT16LE(*(int16_t*)(Data+136)); // extrasize if (i && PacketFormatExtra(&s->Stream.Format,i)) memcpy(s->Stream.Format.Extra,Data+142,s->Stream.Format.ExtraLength); s->MediaRateDen = TICKSPERSEC; s->MediaRateNum = INT32LE(*(int32_t*)(Data+128)); s->DefaultLen = 1; return 1; } } else if (Length >= sizeof(ogm_header)+1) { ogm_header Head; memcpy(&Head,Data+1,sizeof(Head)); // new header if (strncmp(Head.streamtype, MT_Video, strlen(MT_Video)) == 0) { PacketFormatClear(&s->Stream.Format); s->Stream.Format.Type = PACKET_VIDEO; s->Stream.Format.Format.Video.Width = INT32LE(Head.format.video.width); s->Stream.Format.Format.Video.Height = INT32LE(Head.format.video.height); s->Stream.Format.Format.Video.Pixel.FourCC = INT32LE(*(int32_t*)Head.subtype); s->Stream.Format.Format.Video.Pixel.BitCount = INT16LE(Head.bits_per_sample); s->MediaRateDen = INT64LE(Head.time_unit)*TICKSPERSEC; s->MediaRateNum = INT64LE(Head.samples_per_unit) * 10000000; s->DefaultLen = INT32LE(Head.default_len); FrameRate(&s->Stream.Format.PacketRate,s->MediaRateNum,s->MediaRateDen/TICKSPERSEC); i = Length - (sizeof(ogm_header)+1); if (i && PacketFormatExtra(&s->Stream.Format,i)) memcpy(s->Stream.Format.Extra,Data+1+sizeof(ogm_header),s->Stream.Format.ExtraLength); return 1; } if (strncmp(Head.streamtype, MT_Audio, strlen(MT_Audio)) == 0) { PacketFormatClear(&s->Stream.Format); s->Stream.Format.Type = PACKET_AUDIO; s->Stream.Format.Format.Audio.Format = 0; for (i=0;i<4;++i) if (Head.subtype[i]) s->Stream.Format.Format.Audio.Format = s->Stream.Format.Format.Audio.Format*16+Hex(Head.subtype[i]); s->Stream.Format.Format.Audio.Channels = INT16LE(Head.format.audio.channels); s->Stream.Format.Format.Audio.Bits = INT16LE(Head.bits_per_sample); s->Stream.Format.Format.Audio.BlockAlign = INT16LE(Head.format.audio.blockalign); s->Stream.Format.ByteRate = INT32LE(Head.format.audio.avgbytespersec); s->Stream.Format.Format.Audio.SampleRate = (int)INT64LE(Head.samples_per_unit); s->MediaRateDen = INT64LE(Head.time_unit)*TICKSPERSEC; s->MediaRateNum = INT64LE(Head.samples_per_unit) * 10000000; s->DefaultLen = INT32LE(Head.default_len); i = Length - (sizeof(ogm_header)+1); if (i && PacketFormatExtra(&s->Stream.Format,i)) memcpy(s->Stream.Format.Extra,Data+1+sizeof(ogm_header),s->Stream.Format.ExtraLength); return 1; } if (strncmp(Data+1, MT_Text, strlen(MT_Text)) == 0) { PacketFormatClear(&s->Stream.Format); s->Stream.Format.Type = PACKET_SUBTITLE; s->Stream.Format.Format.Subtitle.FourCC = SUBTITLE_OEM; //??? s->MediaRateDen = INT64LE(Head.time_unit)*TICKSPERSEC; s->MediaRateNum = INT64LE(Head.samples_per_unit) * 10000000; s->DefaultLen = INT32LE(Head.default_len); i = Length - (sizeof(ogm_header)+1); if (i && PacketFormatExtra(&s->Stream.Format,i)) memcpy(s->Stream.Format.Extra,Data+1+sizeof(ogm_header),s->Stream.Format.ExtraLength); return 1; } } return 0; }
static int ReadPacket(flv* p, format_reader* Reader, format_packet* Packet) { format_stream* s; int i, type, size, TimeStamp, flags, is_audio; int64_t next; bool_t isNewStream = 0; filepos_t startfilepos; startfilepos = Reader->FilePos; for (;;) { Reader->Skip(Reader, 4);//prvious type size type = Reader->Read8(Reader); size = ReadBE24(Reader); TimeStamp = ReadBE24(Reader); if (Reader->Eof(Reader)) { return ERR_END_OF_FILE; } // Reserved Reader->Skip(Reader, 4); flags = 0; if (size == 0) continue; next = size + Reader->FilePos; if (type == FLV_TAG_TYPE_AUDIO) { is_audio = 1; flags = Reader->Read8(Reader); size--; p->bHasA = 1; } else if (type == FLV_TAG_TYPE_VIDEO) { is_audio = 0; flags = Reader->Read8(Reader); size--; p->bHasV = 1; } else if (type == FLV_TAG_TYPE_META && size > 13+1+4) { if(flv_read_metabody(p,Reader, next)<0) { Reader->Seek(Reader,(filepos_t)next,SEEK_SET); } continue; } else { // Skip the packet Reader->Skip(Reader, size); continue; } // Now find stream s = NULL; for (i=0;i<p->Format.StreamCount;++i) { if (p->Format.Streams[i]->Id == is_audio) { s = p->Format.Streams[i]; break; } } if (!s) { s = Format_AddStream(&p->Format,sizeof(format_stream)); if (!s) return ERR_OUT_OF_MEMORY; s->Id = is_audio; isNewStream = 1; s->Format.PacketRate.Den = 24; s->Format.PacketRate.Num = 1000; } break; } if(is_audio) { if (isNewStream) { int bInited = 0; PacketFormatClear(&s->Format); s->Format.Type = PACKET_AUDIO; s->Format.Format.Audio.Channels = (flags&1)+1; if((flags >> 4) == 5) s->Format.Format.Audio.SampleRate = 8000; else s->Format.Format.Audio.SampleRate = (44100<<((flags>>2)&3))>>3; switch(flags >> 4) {/* 0: uncompressed 1: ADPCM 2: mp3 5: Nellymoser 8kHz mono 6: Nellymoser */ case FLV_CODECID_PCM: s->Format.Format.Audio.Format = AUDIOFMT_PCM; if (!(flags&2)) { s->Format.Format.Audio.Bits = 8; s->Format.Format.Audio.FracBits = 7; bInited = 1; } break; case FLV_CODECID_ADPCM: s->Format.Format.Audio.Format = AUDIOFMT_ADPCM_SWF; break; case FLV_CODECID_MP3: s->Format.Format.Audio.Format = AUDIOFMT_MP3; break; case FLV_CODECID_PCM_LE: s->Format.Format.Audio.Format = AUDIOFMT_PCM; if (!(flags&2)) { s->Format.Format.Audio.Bits = 8; s->Format.Format.Audio.FracBits = 7; bInited = 1; } break; case FLV_CODECID_NELLYMOSER_8KHZ_MONO: s->Format.Format.Audio.SampleRate = 8000; case FLV_CODECID_NELLYMOSER: s->Format.Format.Audio.Format = AUDIOFMT_NELLYMOSER; break; case FLV_CODECID_AAC: { format_stream* s; int type = Reader->Read8(Reader); size--; if(type == 0) { s = p->Format.Streams[p->Format.StreamCount-1]; if (PacketFormatExtra(&s->Format,size)) Reader->Read(Reader,s->Format.Extra,size); } s->Format.Format.Audio.Format = AUDIOFMT_AAC; Format_PrepairStream(&p->Format, s); } return ERR_NONE; case FLV_CODECID_SPEEX: s->Format.Format.Audio.Format = AUDIOFMT_SPEEX; s->Format.Format.Audio.SampleRate = 16000; break; default: return ERR_NOT_SUPPORTED; } if(!bInited) { 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); } }