[xiph-commits] r7649 - trunk/theora/examples
giles at motherfish-iii.xiph.org
giles at motherfish-iii.xiph.org
Fri Aug 27 11:51:43 PDT 2004
Author: giles
Date: 2004-08-27 11:51:43 -0700 (Fri, 27 Aug 2004)
New Revision: 7649
Modified:
trunk/theora/examples/dump_video.c
Log:
Add some comments about the decode process, mostly about the
complexities of unpacking from the Ogg stream.
Modified: trunk/theora/examples/dump_video.c
===================================================================
--- trunk/theora/examples/dump_video.c 2004-08-27 18:30:38 UTC (rev 7648)
+++ trunk/theora/examples/dump_video.c 2004-08-27 18:51:43 UTC (rev 7649)
@@ -190,6 +190,20 @@
}
}
+
+ /*
+ Ok, Ogg parsing. The idea here is we have a bitstream
+ that is made up of Ogg pages. The libogg sync layer will
+ find them for us. There may be pages from several logical
+ streams interleaved; we find the first theora stream and
+ ignore any others.
+
+ Then we pass the pages for our stream to the libogg stream
+ layer which assembles our original set of packets out of
+ them. It's the packets that libtheora actually knows how
+ to handle.
+ */
+
/* start up Ogg stream synchronization layer */
ogg_sync_init(&oy);
@@ -198,7 +212,12 @@
theora_info_init(&ti);
/* Ogg file open; parse the headers */
- /* Only interested in Vorbis/Theora streams */
+
+ /* Vorbis and Theora both depend on some initial header packets
+ for decoder setup and initialization. We retrieve these first
+ before entering the main decode loop. */
+
+ /* Only interested in Theora streams */
while(!stateflag){
int ret=buffer_data(infile,&oy);
if(ret==0)break;
@@ -219,7 +238,7 @@
/* identify the codec: try theora */
if(!theora_p && theora_decode_header(&ti,&tc,&op)>=0){
- /* it is theora */
+ /* it is theora -- save this stream state */
memcpy(&to,&test,sizeof(test));
theora_p=1;
}else{
@@ -227,7 +246,7 @@
ogg_stream_clear(&test);
}
}
- /* fall through to non-bos page parsing */
+ /* fall through to non-initial page parsing */
}
/* we're expecting more header packets. */
@@ -263,7 +282,7 @@
}
}
- /* and now we have it all. initialize decoder */
+ /* Now we have all the required headers. initialize the decoder. */
if(theora_p){
theora_decode_init(&td,&ti);
fprintf(stderr,"Ogg logical stream %x is Theora %dx%d %.02f fps video\nEncoded frame content is %dx%d with %dx%d offset\n",
@@ -281,8 +300,27 @@
/* install signal handler */
signal (SIGINT, sigint_handler);
- /* on to the main decode loop.*/
+ /* Finally the main decode loop.
+ It's one Theora packet per frame, so this is pretty
+ straightforward if we're not trying to maintain sync
+ with other multiplexed streams.
+
+ the videobuf_ready flag is used to maintain the input
+ buffer in the libogg stream state. If there's no output
+ frame available at the end of the decode step, we must
+ need more input data. We could simplify this by just
+ using the return code on ogg_page_packetout(), but the
+ flag system extends easily to the case were you care
+ about more than one multiplexed stream (like with audio
+ playback). In that case, just maintain a flag for each
+ decoder you care about, and pull data when any one of
+ them stalls.
+
+ videobuf_time holds the presentation time of the currently
+ buffered video frame. We ignore this value.
+ */
+
stateflag=0; /* playback has not begun */
/* queue any remaining pages from data we buffered but that did not
contain headers */
@@ -304,9 +342,9 @@
break;
}
- if(!videobuf_ready && feof(infile))break;
+ if(!videobuf_ready && feof(infile))break;
- if(!videobuf_ready ){
+ if(!videobuf_ready){
/* no data yet for somebody. Grab another page */
int ret=buffer_data(infile,&oy);
while(ogg_sync_pageout(&oy,&og)>0){
@@ -319,7 +357,7 @@
videobuf_ready=0;
}
- /* close everything */
+ /* end of decoder loop -- close everything */
if(theora_p){
ogg_stream_clear(&to);
More information about the commits
mailing list