Mercurial > mplayer.hg
changeset 5809:4b24942acdbb
Add seeking without index (still not perfect). Use -forceidx for the
version with index.
author | albeu |
---|---|
date | Wed, 24 Apr 2002 12:28:03 +0000 |
parents | c746dada521c |
children | 8a357300d0ec |
files | libmpdemux/demux_ogg.c |
diffstat | 1 files changed, 83 insertions(+), 50 deletions(-) [+] |
line wrap: on
line diff
--- a/libmpdemux/demux_ogg.c Wed Apr 24 02:02:50 2002 +0000 +++ b/libmpdemux/demux_ogg.c Wed Apr 24 12:28:03 2002 +0000 @@ -32,7 +32,7 @@ #include <ogg/ogg.h> #include <vorbis/codec.h> -#define BLOCK_SIZE 1024 +#define BLOCK_SIZE 4096 /// Vorbis decoder context : we need the vorbis_info for vorbis timestamping /// Shall we put this struct def in a common header ? @@ -111,6 +111,7 @@ int num_sub; ogg_syncpoint_t* syncpoints; int num_syncpoint; + off_t pos, last_size; } ogg_demuxer_t; #define NUM_VORBIS_HDR_PACKETS 3 @@ -122,6 +123,8 @@ #define PACKET_LEN_BITS2 0x02 #define PACKET_IS_SYNCPOINT 0x08 +extern int index_mode; + // get the logical stream of the current page // fill os if non NULL and return the stream id @@ -294,10 +297,12 @@ } p++; } - if(p > 0) + if(p > 1 || (p == 1 && ! ogg_page_continued(page))) last_pos = pos; pos += np; + mp_msg(MSGT_DEMUX,MSGL_INFO,"Building syncpoint table %d%\r",pos*100/s->end_pos); } + mp_msg(MSGT_DEMUX,MSGL_INFO,"\n"); mp_msg(MSGT_DEMUX,MSGL_V,"Ogg syncpoints table builed: %d syncpoints\n",ogg_d->num_syncpoint); @@ -349,18 +354,19 @@ sync = &ogg_d->sync; page = &ogg_d->page; - ogg_sync_init(&ogg_d->sync); + ogg_sync_init(sync); while(1) { /// Try to get a page - np = ogg_sync_pageout(sync,page); + ogg_d->pos += ogg_d->last_size; + np = ogg_sync_pageseek(sync,page); /// Error if(np < 0) { mp_msg(MSGT_DEMUX,MSGL_DBG2,"OGG demuxer : Bad page sync\n"); return 0; } /// Need some more data - if(np <= 0) { + if(np == 0) { int len; buf = ogg_sync_buffer(sync,BLOCK_SIZE); len = stream_read(s,buf,BLOCK_SIZE); @@ -371,7 +377,7 @@ ogg_sync_wrote(sync,len); continue; } - + ogg_d->last_size = np; // We got one page now if( ! ogg_page_bos(page) ) { // It's not a begining page @@ -541,7 +547,7 @@ ds = demuxer->video; } /// Add the header packets if the stream isn't seekable - if(ds && !s->end_pos) { + if(ds && (!s->end_pos || index_mode != 2)) { /// Finish the page, otherwise packets will be lost do { demux_ogg_add_packet(ds,&ogg_d->subs[ogg_d->num_sub],&pack); @@ -564,7 +570,9 @@ else { demuxer->movi_start = 0; demuxer->movi_end = s->end_pos; - demux_ogg_build_syncpoints_table(demuxer); + demuxer->seekable = 1; + if(index_mode == 2) + demux_ogg_build_syncpoints_table(demuxer); } mp_msg(MSGT_DEMUX,MSGL_V,"OGG demuxer : found %d audio stream and %d video stream\n",n_audio,n_video); @@ -604,11 +612,13 @@ while(1) { int pa,len; char *buf; + ogg_d->pos += ogg_d->last_size; /// Get the next page from the physical stream - while( (pa = ogg_sync_pageout(sync,page)) != 1) { + while( (pa = ogg_sync_pageseek(sync,page)) <= 0) { /// Error : we skip some bytes if(pa < 0) { mp_msg(MSGT_DEMUX,MSGL_WARN,"OGG : Page out not synced, we skip some bytes\n"); + ogg_d->pos -= pa; continue; } /// We need more data @@ -620,7 +630,7 @@ } ogg_sync_wrote(sync,len); } /// Page loop - + ogg_d->last_size = pa; /// Find the page's logical stream if( (id = demux_ogg_get_page_stream(ogg_d,&os)) < 0) { mp_msg(MSGT_DEMUX,MSGL_ERR,"OGG demuxer error : we met an unknow stream\n"); @@ -631,6 +641,7 @@ break; /// Page was invalid => retry mp_msg(MSGT_DEMUX,MSGL_WARN,"OGG demuxer : got invalid page !!!!!\n"); + ogg_d->pos += ogg_d->last_size; } } else /// Packet was corrupted mp_msg(MSGT_DEMUX,MSGL_WARN,"OGG : bad packet in stream %d\n",id); @@ -645,6 +656,7 @@ if(ds) { if(!demux_ogg_add_packet(ds,&ogg_d->subs[id],&pack)) continue; /// Unuseful packet, get another + d->filepos = ogg_d->pos; return 1; } @@ -750,15 +762,12 @@ ogg_stream_t* os; demux_stream_t* ds; sh_audio_t* sh_audio = demuxer->audio->sh; - //sh_video_t* sh_video = demuxer->video->sh; ogg_packet op; - float time_pos,rate; + float rate; int i,sp; vorbis_info* vi = NULL; - int64_t gp; - - if(!ogg_d->syncpoints) - return; + int64_t gp = 0; + off_t pos; if(demuxer->video->id >= 0) { ds = demuxer->video; @@ -772,29 +781,57 @@ os = &ogg_d->subs[ds->id]; oss = &os->stream; - time_pos = flags & 1 ? 0 : os->lastpos/ rate; - if(flags & 2) - time_pos += ogg_d->syncpoints[ogg_d->num_syncpoint].granulepos / rate * rel_seek_secs; - else - time_pos += rel_seek_secs; + if(ogg_d->syncpoints) { + float time_pos = flags & 1 ? 0 : os->lastpos/ rate; + if(flags & 2) { + if(ogg_d->syncpoints) + time_pos += ogg_d->syncpoints[ogg_d->num_syncpoint].granulepos / rate * rel_seek_secs; + else + time_pos += (demuxer->movi_end - demuxer->movi_start) * rel_seek_secs; + } else + time_pos += rel_seek_secs; + + gp = time_pos * rate; - gp = time_pos * rate; + for(sp = 0; sp < ogg_d->num_syncpoint ; sp++) { + if(ogg_d->syncpoints[sp].granulepos >= gp) + break; + } + + if(sp >= ogg_d->num_syncpoint) + return; + pos = ogg_d->syncpoints[sp].page_pos; - for(sp = 0; sp < ogg_d->num_syncpoint ; sp++) { - if(ogg_d->syncpoints[sp].granulepos >= gp) - break; + } else { + pos = flags & 1 ? demuxer->movi_start : ogg_d->pos; + if(flags & 2) + pos += (demuxer->movi_end - demuxer->movi_start) * rel_seek_secs; + else + pos += rel_seek_secs * ogg_d->pos / (os->lastpos / rate); + + if(pos < demuxer->movi_start) + pos = demuxer->movi_start; + else if(pos > demuxer->movi_end) + return; } - if(sp >= ogg_d->num_syncpoint) - return; - - stream_seek(demuxer->stream,ogg_d->syncpoints[sp].page_pos); + stream_seek(demuxer->stream,pos); ogg_sync_reset(sync); - for(i = 0 ; i < ogg_d->num_sub ; i++) + for(i = 0 ; i < ogg_d->num_sub ; i++) { ogg_stream_reset(&ogg_d->subs[i].stream); + ogg_d->subs[i].lastpos = ogg_d->subs[i].lastsize = 0; + } + ogg_d->pos = pos; + ogg_d->last_size = 0; while(1) { - int np = ogg_sync_pageout(sync,page); + int np; + ogg_d->pos += ogg_d->last_size; + ogg_d->last_size = 0; + np = ogg_sync_pageseek(sync,page); + + if(np < 0) + ogg_d->pos -= np; if(np <= 0) { // We need more data char* buf = ogg_sync_buffer(sync,BLOCK_SIZE); int len = stream_read(demuxer->stream,buf,BLOCK_SIZE); @@ -805,32 +842,28 @@ ogg_sync_wrote(sync,len); continue; } + ogg_d->last_size = np; + if(ogg_page_serialno(page) != oss->serialno) + continue; - if(ogg_page_serialno(page) != os->stream.serialno) - continue; if(ogg_stream_pagein(oss,page) != 0) continue; - while(1) { - np = ogg_stream_packetpeek(oss,&op); - if(np < 0) { - ogg_stream_packetout(oss,&op); + while(1) { + np = ogg_stream_packetout(oss,&op); + if(np < 0) continue; - } else if(np == 0) + else if(np == 0) break; - else { - float pts; - int f; - demux_ogg_read_packet(os,&op,vi,&pts,&f); - if(f || (os->vorbis && op.granulepos >= gp)) { - if(sh_audio) - resync_audio_stream(sh_audio); - return; - } - ogg_stream_packetout(oss,&op); - demux_ogg_read_packet(os,&op,vi,&pts,&f); + + if( ((*op.packet & PACKET_IS_SYNCPOINT) || os->vorbis ) && + (!ogg_d->syncpoints || op.granulepos >= gp) ) { + demux_ogg_add_packet(ds,os,&op); + if(sh_audio) + resync_audio_stream(sh_audio); + return; } - } + } } mp_msg(MSGT_DEMUX,MSGL_ERR,"Can't find the good packet :(\n");