static int Seek(flv* p, tick_t Time, filepos_t FilePos,bool_t PrevKey) { int i=0; tick_t preIndexNum = -1; if(Time>=0) { for( i = 0; i < p->IndexNum; i++) { tick_t RefTime = Scale(((flvindex*)IndexBuffer(p,i))->times, TICKSPERSEC, 1); if(Time<=RefTime) break; preIndexNum = i; } } if(PrevKey&&preIndexNum!=-1) i = preIndexNum; if(p->IndexNum == 0) { if(Time>=0 && p->Format.Duration > 0) return SeekNoIndex(p,Time,FilePos,PrevKey); return ERR_NOT_SUPPORTED; } else if(i >= 0 && i < p->IndexNum) { FilePos = ((flvindex*)IndexBuffer(p,i))->pos-4; } else { FilePos = p->StartOffset; } return Format_Seek(&p->Format,FilePos,SEEK_SET); }
static int Seek(asap* p, tick_t Time, int FilePos, bool_t PrevKey) { if (Time>0 || FilePos>0) return ERR_NOT_SUPPORTED; if (Format_Seek(&p->Format,0,SEEK_SET) != ERR_NONE) return ERR_NOT_SUPPORTED; Load(p); return ERR_NONE; }
int RawAudioSeek(rawaudio* p, tick_t Time, filepos_t FilePos,bool_t PrevKey) { format_stream* Stream = p->Format.Streams[0]; if (FilePos < 0) { if (Time > 0) { if (Stream->Format.ByteRate) FilePos = p->Head + Scale(Time,Stream->Format.ByteRate,TICKSPERSEC); else return ERR_NOT_SUPPORTED; } else FilePos = 0; } p->SeekTime = Time>0?Time:TIME_UNKNOWN; p->SeekPos = FilePos; return Format_Seek(&p->Format,FilePos,SEEK_SET); }
static int SeekNoIndex(flv* p, tick_t Time, filepos_t FilePos,bool_t PrevKey) { filepos_t LastFilePos; bool_t fAudio = p->bHasA; bool_t fVideo = p->bHasV; Tag t; AudioTag at; VideoTag vt; format_reader* Reader = p->Format.Reader; if(Time < 0 || p->Format.Duration <= 0) return ERR_NOT_SUPPORTED; LastFilePos = p->StartOffset + 1.0 * Time/p->Format.Duration*(p->Format.FileSize - p->StartOffset); if(!Sync(p,Reader,LastFilePos)) { Format_Seek(&p->Format,p->StartOffset,SEEK_SET); return ERR_NONE; } while(ReadTag(p,Reader,&t)) { tick_t TagTime = Scale(t.TimeStamp,TICKSPERSEC,1000); if(TagTime >= Time) { LastFilePos = Reader->FilePos - 15; Reader->Seek(Reader,Reader->FilePos - 15,SEEK_SET); break; } LastFilePos = Reader->FilePos + t.DataSize; Reader->Seek(Reader,Reader->FilePos + t.DataSize,SEEK_SET); } while(Reader->FilePos >= p->StartOffset && (fAudio || fVideo) && ReadTag(p,Reader,&t)) { filepos_t prev = Reader->FilePos - 15 - t.PreviousTagSize - 4; tick_t TimeStamp = Scale(t.TimeStamp,TICKSPERSEC,1000); if(TimeStamp <= Time) { if(t.TagType == 8 && ReadATag(p,Reader,&at)) { fAudio = 0; } else if(t.TagType == 9 && ReadVTag(p,Reader,&vt) && vt.FrameType == 1) { fVideo = 0; } } LastFilePos = prev; Reader->Seek(Reader,prev,SEEK_SET); } if(fAudio || fVideo) { LastFilePos = p->StartOffset; Format_Seek(&p->Format,p->StartOffset,SEEK_SET); return ERR_NONE; } return Format_Seek(&p->Format,LastFilePos,SEEK_SET); }