[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