[MPlayer-dev-eng] [PATCH] Ogg seeking fixed

Moritz Bunkus moritz at bunkus.org
Mon Dec 30 01:59:02 CET 2002


Hi everyone.

There has always been a problem with seeking in Ogg/Ogm files. Often
there was a broken frame right after seeking. The patch below fixes
this.

Explanation: The 'smallest' useful unit is an 'Ogg packet'. One packet
may e.g. contain one video frame. Packets are grouped together into
Ogg pages or - if they are bigger then a standard page - may even span
multiple Ogg pages. So a common case is:

page x   \
page x+1 |
page x+2 | = packet y
page x+3 /

In this case Ogg packet y spans four Ogg pages.

After seeking to a position the demuxer tries to resync to the Ogg
stream. That's done by searching page boundaries with ogg_page_sync.
But ogg_page_sync does not know anything about the packets in the
pages. Therefore the problem occured when the demuxer started reading
e.g. after page x+1. It found page x+2 and x+3 and delivered half of
packet y. Of course this was broken and could even have indicated that
it was a key frame.

The fix simply ignores this very first packet. All following packets
will be complete packets, so they are taken into account.

If no one has any objections I'll apply the patch myself.

-- 
 ==> Ciao, Mosu (Moritz Bunkus)
-------------- next part --------------
Index: demux_ogg.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demux_ogg.c,v
retrieving revision 1.22
diff -u -r1.22 demux_ogg.c
--- demux_ogg.c	28 Dec 2002 15:19:41 -0000	1.22
+++ demux_ogg.c	30 Dec 2002 00:53:41 -0000
@@ -901,7 +901,7 @@
   sh_audio_t* sh_audio = demuxer->audio->sh;
   ogg_packet op;
   float rate;
-  int i,sp;
+  int i,sp,first;
   vorbis_info* vi = NULL;
   int64_t gp = 0;
   off_t pos;
@@ -961,6 +961,7 @@
   ogg_d->pos = pos;
   ogg_d->last_size = 0;
 
+  first = 1;
   while(1) {
     int np;
     ogg_d->pos += ogg_d->last_size;
@@ -992,7 +993,11 @@
 	continue;
       else if(np == 0)
 	break;
-
+      if (first) {
+        first = 0;
+        break;
+      }
+      
       if( ((*op.packet & PACKET_IS_SYNCPOINT)  || os->vorbis )  &&
 	  (!ogg_d->syncpoints || op.granulepos >= gp) ) {
 	demux_ogg_add_packet(ds,os,&op);


More information about the MPlayer-dev-eng mailing list