[xiph-cvs] cvs commit: theora/lib toplevel.c

Monty xiphmont at xiph.org
Tue Sep 24 19:38:11 PDT 2002



xiphmont    02/09/24 22:38:11

  Modified:    examples Makefile.am player_example.c
               include/theora theora.h
               lib      toplevel.c
  Log:
  Minor fixes;
  
  Add granulepos tracking in libtheora; it will need to be much smarter
  when seek support is added.
  
  Fix video fast timeing problem due to incorrect granulepos
  
  Add status indicator to player_example
  
  Fix Makefile.am link order bug in examples/

Revision  Changes    Path
1.5       +1 -1      theora/examples/Makefile.am

Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/theora/examples/Makefile.am,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Makefile.am	24 Sep 2002 11:18:22 -0000	1.4
+++ Makefile.am	25 Sep 2002 02:38:10 -0000	1.5
@@ -7,7 +7,7 @@
 noinst_PROGRAMS = encoder_example player_example 
 
 LDFLAGS = -all-static 
-LDADD = ../lib/libtheora.la -lm -logg -lvorbis
+LDADD = ../lib/libtheora.la -logg -lvorbis -lm
 
 player_example_SOURCES = player_example.c
 player_example_LDADD = $(LDADD) -lSDL -lpthread

<p><p>1.4       +45 -30    theora/examples/player_example.c

Index: player_example.c
===================================================================
RCS file: /usr/local/cvsroot/theora/examples/player_example.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- player_example.c	25 Sep 2002 01:08:15 -0000	1.3
+++ player_example.c	25 Sep 2002 02:38:10 -0000	1.4
@@ -12,7 +12,7 @@
 
   function: example SDL player application; plays Ogg Theora files (with
             optional Vorbis audio second stream)
-  last mod: $Id: player_example.c,v 1.3 2002/09/25 01:08:15 xiphmont Exp $
+  last mod: $Id: player_example.c,v 1.4 2002/09/25 02:38:10 xiphmont Exp $
 
  ********************************************************************/
 
@@ -55,13 +55,6 @@
   return(bytes);
 }
 
-/* clean quit on Ctrl-C for SDL and thread shutdown as per SDL example
-   (we don't use any threads, but libSDL does) */
-int got_sigint=0;
-static void sigint_handler (int signal) {
-  got_sigint = 1;
-}
-
 /* never forget that globals are a one-way ticket to Hell */
 /* Ogg and codec state for demux/decode */
 ogg_sync_state   oy; 
@@ -75,6 +68,10 @@
 vorbis_block     vb;
 vorbis_comment   vc;
 
+int              theora_p=0;
+int              vorbis_p=0;
+int              stateflag=0;
+
 /* SDL Video playback structures */
 SDL_Surface *screen;
 SDL_Overlay *yuv_overlay;
@@ -82,7 +79,7 @@
 
 /* single frame video buffering */
 int          videobuf_ready=0;
-ogg_int64_t  videobuf_granulepos=0;
+ogg_int64_t  videobuf_granulepos=-1;
 double       videobuf_time=0;
 
 /* single audio fragment audio buffering */
@@ -129,7 +126,6 @@
                                        switch */
 int          audiofd=-1;
 ogg_int64_t  audiofd_timer_calibrate=-1;
-long         audiofd_drift=0;
 
 static void open_audio(){
   audio_buf_info info;
@@ -188,17 +184,12 @@
   new_time=tv.tv_sec*1000+tv.tv_usec/1000;
 
   if(restart){
-    fprintf(stderr,"audio playback start: calibrating clock.\n");
     current_sample=audiobuf_granulepos-audiobuf_fill/2/vi.channels;
   }else
     current_sample=audiobuf_granulepos-
       (audiobuf_fill+audiofd_totalsize-audiofd_fragsize)/2/vi.channels;
   
   new_time-=1000*current_sample/vi.rate;
-  audiofd_drift+=audiofd_timer_calibrate-new_time;
-
-  fprintf(stderr,"calibration drift: %d \n",
-	  audiofd_timer_calibrate-new_time);
 
   audiofd_timer_calibrate=new_time;
 }
@@ -207,16 +198,17 @@
    drift */
 double get_time(){
   static ogg_int64_t last=0;
+  static ogg_int64_t up=0;
   ogg_int64_t now;
   struct timeval tv;
 
   gettimeofday(&tv,0);
   now=tv.tv_sec*1000+tv.tv_usec/1000;
 
+  if(audiofd_timer_calibrate==-1)audiofd_timer_calibrate=last=now;
+
   if(audiofd<0){
     /* no audio timer to worry about, we can just use the system clock */
-    if(audiofd_timer_calibrate==-1)audiofd_timer_calibrate=last=now;
-
     /* only one complication: If the process is suspended, we should
        reset timing to account for the gap in play time.  Do it the
        easy/hack way */
@@ -224,6 +216,18 @@
     last=now;
   }
 
+  if(now-up>200){
+    double timebase=(now-audiofd_timer_calibrate)*.001;
+    int hundredths=timebase*100-(long)timebase*100;
+    int seconds=(long)timebase%60;
+    int minutes=((long)timebase/60)%60;
+    int hours=(long)timebase/3600;
+    
+    fprintf(stderr,"   Playing: %d:%02d:%02d.%02d                       \r",
+	    hours,minutes,seconds,hundredths);
+    up=now;
+  }
+
   return (now-audiofd_timer_calibrate)*.001;
 
 }
@@ -240,7 +244,7 @@
     bytes=info.bytes;
     if(bytes>=audiofd_fragsize){
       if(bytes==audiofd_totalsize)audio_calibrate_timer(1);
-
+   
       while(1){
         bytes=write(audiofd,audiobuf+(audiofd_fragsize-audiobuf_fill),
                     audiofd_fragsize);
@@ -262,6 +266,14 @@
   } 
 }
 
+/* clean quit on Ctrl-C for SDL and thread shutdown as per SDL example
+   (we don't use any threads, but libSDL does) */
+int got_sigint=0;
+static void sigint_handler (int signal) {
+  got_sigint = 1;
+  if(audiofd>-1)ioctl(audiofd,SNDCTL_DSP_RESET,NULL);
+}
+
 static void open_video(void){
   
   screen = SDL_SetVideoMode(ti.width, ti.height, 0, SDL_SWSURFACE);
@@ -329,9 +341,6 @@
 
 int main(void){
   
-  int theora_p=0;
-  int vorbis_p=0;
-  int stateflag=0;
   int i,j;
   ogg_packet op;
 
@@ -499,20 +508,26 @@
       }
     }
       
-    if(theora_p && !videobuf_ready){
+    while(theora_p && !videobuf_ready){
       /* theora is one in, one out... */
       if(ogg_stream_packetout(&to,&op)>0){
+   
         theora_decode_packetin(&td,&op);
-	videobuf_ready=1;
-	
-	if(op.granulepos>=0)
-	  videobuf_granulepos=op.granulepos;
-	else
-	  videobuf_granulepos++;
+	videobuf_granulepos=td.granulepos;
         
         videobuf_time=theora_granule_time(&td,videobuf_granulepos);
-	
-      }
+
+	/* is it already too old to be useful?  This is only actually
+           useful cosmetically after a SIGSTOP.  Note that we have to
+           decode the frame even if we don't show it (for now) due to
+           keyframing.  Soon enough libtheora will be able to deal
+           with non-keyframe seeks.  */
+
+	if(videobuf_time>=get_time())
+	  videobuf_ready=1;
+		
+      }else
+	break;
     }
     
     if(!videobuf_ready && !audiobuf_ready && feof(stdin))break;
@@ -571,7 +586,7 @@
     if((!theora_p || videobuf_ready) && 
        (!vorbis_p || audiobuf_ready))stateflag=1;
     if(feof(stdin))stateflag=1; 
-    
+
   }
 
   /* tear it all down */

<p><p>1.4       +9 -6      theora/include/theora/theora.h

Index: theora.h
===================================================================
RCS file: /usr/local/cvsroot/theora/include/theora/theora.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- theora.h	23 Sep 2002 23:18:06 -0000	1.3
+++ theora.h	25 Sep 2002 02:38:10 -0000	1.4
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function: 
-  last mod: $Id: theora.h,v 1.3 2002/09/23 23:18:06 xiphmont Exp $
+  last mod: $Id: theora.h,v 1.4 2002/09/25 02:38:10 xiphmont Exp $
 
  ********************************************************************/
 
@@ -20,11 +20,6 @@
 
 #include <ogg/ogg.h>
 
-typedef struct{
-  void *internal_encode;
-  void *internal_decode;
-} theora_state;
-
 typedef struct {
     int   y_width;
     int   y_height;
@@ -69,6 +64,14 @@
   ogg_int32_t   sharpness;
 
 } theora_info;
+
+typedef struct{
+  theora_info *i;
+  ogg_int64_t granulepos;
+
+  void *internal_encode;
+  void *internal_decode;
+} theora_state;
 
 #define OC_FAULT       -1
 #define OC_EINVAL      -10

<p><p>1.12      +27 -5     theora/lib/toplevel.c

Index: toplevel.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/toplevel.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- toplevel.c	24 Sep 2002 11:18:22 -0000	1.11
+++ toplevel.c	25 Sep 2002 02:38:10 -0000	1.12
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function: 
-  last mod: $Id: toplevel.c,v 1.11 2002/09/24 11:18:22 xiphmont Exp $
+  last mod: $Id: toplevel.c,v 1.12 2002/09/25 02:38:10 xiphmont Exp $
 
  ********************************************************************/
 
@@ -840,6 +840,8 @@
 
   /* copy in config */
   memcpy(&cpi->pb.info,c,sizeof(*c));
+  th->i=&cpi->pb.info;
+  th->granulepos=-1;
 
   /* Set up default values for QTargetModifier[Q_TABLE_SIZE] table */
   for ( i = 0; i < Q_TABLE_SIZE; i++ ) 
@@ -975,6 +977,10 @@
   cpi->LastFrameSize = oggpackB_bytes(&cpi->oggbuffer);
   cpi->CurrentFrame++;
   cpi->packetflag=1;
+
+  t->granulepos=
+    ((cpi->CurrentFrame-cpi->LastKeyFrame-1)<<cpi->pb.keyframe_granule_shift)+ 
+    cpi->LastKeyFrame-1;
   
   return 0;
 }
@@ -993,10 +999,7 @@
   op->e_o_s=last_p;
   
   op->packetno=cpi->CurrentFrame;
-
-  op->granulepos=
-    ((cpi->CurrentFrame-cpi->LastKeyFrame-1)<<cpi->pb.keyframe_granule_shift)+ 
-    cpi->LastKeyFrame-1;
+  op->granulepos=t->granulepos;
 
   cpi->packetflag=0;
   if(last_p)cpi->doneflag=1;
@@ -1128,6 +1131,8 @@
   
   InitPBInstance(pbi);
   memcpy(&pbi->info,c,sizeof(*c));
+  th->i=&pbi->info;
+  th->granulepos=-1;
         
   InitFrameDetails(pbi);
 
@@ -1160,10 +1165,27 @@
   /* verify that this is a video frame */
   if(oggpackB_read(&pbi->opb,1)==0){
     ret=LoadAndDecode(pbi);
+
     if(ret)return ret;
     
     if(pbi->PostProcessingLevel)
       PostProcess(pbi);
+
+    if(op->granulepos>-1)
+      th->granulepos=op->granulepos;
+    else{
+      if(th->granulepos==-1){
+	th->granulepos=0;
+      }else{
+	if(pbi->FrameType==BASE_FRAME){
+	  long frames= th->granulepos & ((1<<pbi->keyframe_granule_shift)-1);
+	  th->granulepos>>=pbi->keyframe_granule_shift;
+	  th->granulepos+=frames+1;
+	  th->granulepos<<=pbi->keyframe_granule_shift;
+	}else
+	  th->granulepos++;
+      }
+    }
            
     return(0);
   }

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list