[xiph-commits] r9563 - in branches/theora-mmx: . doc doc/spec include/theora lib

j at svn.xiph.org j at svn.xiph.org
Tue Jul 12 13:07:46 PDT 2005


Author: j
Date: 2005-07-12 13:07:16 -0700 (Tue, 12 Jul 2005)
New Revision: 9563

Added:
   branches/theora-mmx/SConstruct
Modified:
   branches/theora-mmx/
   branches/theora-mmx/CHANGES
   branches/theora-mmx/autogen.sh
   branches/theora-mmx/configure.ac
   branches/theora-mmx/doc/Makefile.am
   branches/theora-mmx/doc/spec/
   branches/theora-mmx/doc/spec/spec.bib
   branches/theora-mmx/doc/spec/spec.tex
   branches/theora-mmx/doc/vp3-format.txt
   branches/theora-mmx/include/theora/theora.h
   branches/theora-mmx/lib/Makefile.am
   branches/theora-mmx/lib/dct_decode.c
   branches/theora-mmx/lib/dct_encode.c
   branches/theora-mmx/lib/decode.c
   branches/theora-mmx/lib/encode.c
   branches/theora-mmx/lib/encoder_internal.h
   branches/theora-mmx/lib/encoder_toplevel.c
   branches/theora-mmx/lib/frarray.c
   branches/theora-mmx/lib/misc_common.c
   branches/theora-mmx/lib/quant.c
   branches/theora-mmx/lib/toplevel.c
Log:
- merge changes from trunk to theora-mmx




Property changes on: branches/theora-mmx
___________________________________________________________________
Name: branch-point
   - 9243
   + 9562

Modified: branches/theora-mmx/CHANGES
===================================================================
--- branches/theora-mmx/CHANGES	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/CHANGES	2005-07-12 20:07:16 UTC (rev 9563)
@@ -1,3 +1,9 @@
+libtheora 1.0alpha5 (unreleased)
+
+ * Fixed bitrate management bugs that caused popping and encode
+   errors
+ * new theora_granule_shift() utility function
+
 libtheora 1.0alpha4 (2004 December 15)
 
  * first draft of the Theora I Format Specification

Copied: branches/theora-mmx/SConstruct (from rev 9562, trunk/theora/SConstruct)

Modified: branches/theora-mmx/autogen.sh
===================================================================
--- branches/theora-mmx/autogen.sh	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/autogen.sh	2005-07-12 20:07:16 UTC (rev 9563)
@@ -112,5 +112,11 @@
 echo "  autoconf"
 autoconf || exit 1
 
+# this search and replace hack is specifically for MacOSX where automake
+# picks up changelog in debian/ because of filesystem
+# case-not-quite-sensitivity breaking make distcheck
+perl -i -p -e 's/DIST_COMMON = ChangeLog/DIST_COMMON =/g' debian/Makefile.in
+
+cd 
 cd $olddir
-$srcdir/configure "$@" && echo
+$srcdir/configure --enable-maintainer-mode "$@" && echo

Modified: branches/theora-mmx/configure.ac
===================================================================
--- branches/theora-mmx/configure.ac	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/configure.ac	2005-07-12 20:07:16 UTC (rev 9563)
@@ -76,59 +76,9 @@
 LDFLAGS="$LDFLAGS $ldflags_save"
 
 dnl --------------------------------------------------
-dnl Overall build configuration options
+dnl Checks for support libraries and headers
 dnl --------------------------------------------------
 
-dnl Configuration option for building of floating point code.
-
-ac_enable_float=yes
-AC_ARG_ENABLE(float,
-     [  --disable-float         disable use of floating point code ],
-     [ ac_enable_float=no ], [ ac_enable_float=yes] )
-
-if test "x${ac_enable_float}" = xyes ; then
-    AC_DEFINE(THEORA_SUPPORT_FLOAT, [1], [Build floating point code])
-else
-    AC_DEFINE(THEORA_SUPPORT_FLOAT, [0], [Do not build floating point code])
-fi
-AM_CONDITIONAL(THEORA_SUPPORT_FLOAT, [test "x${ac_enable_float}" = "xyes"])
-
-dnl Configuration option for building of encoding support.
-
-ac_enable_encode=yes
-AC_ARG_ENABLE(encode,
-     [  --disable-encode        disable encoding support ],
-     [ ac_enable_encode=no ], [ ac_enable_encode=yes] )
-
-if test "x${ac_enable_encode}" = xyes ; then
-    BUILDABLE_EXAMPLES="$BUILDABLE_EXAMPLES encoder_example"
-    AC_DEFINE(THEORA_SUPPORT_ENCODE, [1], [Build encoding support])
-else
-    AC_DEFINE(THEORA_SUPPORT_ENCODE, [0], [Do not build encoding support])
-fi
-AM_CONDITIONAL(THEORA_SUPPORT_ENCODE, [test "x${ac_enable_encode}" = "xyes"])
-
-dnl --------------------------------------------------
-dnl Check for headers
-dnl --------------------------------------------------
-
-dnl none here
-
-dnl --------------------------------------------------
-dnl Check for typedefs, structures, etc
-dnl --------------------------------------------------
-
-dnl none
-
-dnl --------------------------------------------------
-dnl Check for library functions
-dnl --------------------------------------------------
-
-dnl substitue the included getopt if the system doesn't support long options
-AC_CHECK_FUNC(getopt_long, [GETOPT_OBJS=''], [GETOPT_OBJS='getopt.$(OBJEXT) getopt1.$(OBJEXT)'])
-AC_SUBST(GETOPT_OBJS)
-
-
 dnl check for Ogg
 HAVE_OGG=no
 
@@ -159,7 +109,7 @@
   LIBS=$libs_save
 fi
 
-dnl the examples use Vorbis and SDL
+
 dnl check for Vorbis
 HAVE_VORBIS=no
 
@@ -180,12 +130,17 @@
   XIPH_PATH_VORBIS(HAVE_VORBIS=yes, HAVE_VORBIS=no)
 fi
 
+dnl check for SDL
+HAVE_SDL=no
 
 AM_PATH_SDL(,[
 	HAVE_SDL=yes
 	SDL_LIBS=`$SDL_CONFIG --libs`
 ],AC_MSG_WARN([*** Unable to find SDL -- Not compiling example players ***]))
 
+dnl check for OSS
+HAVE_OSS=no
+
 AC_CHECK_HEADERS([sys/soundcard.h soundcard.h machine/soundcard.h],[
   HAVE_OSS=yes
   break
@@ -194,7 +149,65 @@
   AC_MSG_WARN([OSS audio support not found -- not compiling player_example])
 fi
 
-if test x$HAVE_SDL = xyes -a x$HAVE_OSS = xyes; then
+dnl --------------------------------------------------
+dnl Overall build configuration options
+dnl --------------------------------------------------
+
+dnl Configuration option for building of floating point code.
+
+ac_enable_float=yes
+AC_ARG_ENABLE(float,
+     [  --disable-float         disable use of floating point code ],
+     [ ac_enable_float=$enableval ], [ ac_enable_float=yes] )
+
+if test "x${ac_enable_float}" != xyes ; then
+    AC_DEFINE([THEORA_DISABLE_FLOAT], [], 
+	[Define to exclude floating point code from the build])
+fi
+AM_CONDITIONAL(THEORA_DISABLE_FLOAT, [test "x${ac_enable_float}" != xyes])
+
+dnl Configuration option for building of encoding support.
+
+ac_enable_encode=yes
+AC_ARG_ENABLE(encode,
+     [  --disable-encode        disable encoding support ],
+     [ ac_enable_encode=$enableval ], [ ac_enable_encode=yes] )
+
+if test "x${ac_enable_encode}" != xyes ; then
+    AC_DEFINE([THEORA_DISABLE_ENCODE], [],
+	[Define to exclude encode support from the build])
+else
+    if test x$HAVE_VORBIS = xyes; then
+      BUILDABLE_EXAMPLES="$BUILDABLE_EXAMPLES encoder_example"
+    else
+      AC_MSG_NOTICE([Vorbis missing, cannot build example encoder])
+    fi
+fi
+AM_CONDITIONAL(THEORA_DISABLE_ENCODE, [test "x${ac_enable_encode}" != xyes])
+
+dnl --------------------------------------------------
+dnl Check for headers
+dnl --------------------------------------------------
+
+dnl none here
+
+dnl --------------------------------------------------
+dnl Check for typedefs, structures, etc
+dnl --------------------------------------------------
+
+dnl none
+
+dnl --------------------------------------------------
+dnl Check for library functions
+dnl --------------------------------------------------
+
+dnl substitute the included getopt if the system doesn't support long options
+AC_CHECK_FUNC(getopt_long,
+              [GETOPT_OBJS=''],
+              [GETOPT_OBJS='getopt.$(OBJEXT) getopt1.$(OBJEXT)'])
+AC_SUBST(GETOPT_OBJS)
+
+if test x$HAVE_SDL = xyes -a x$HAVE_OSS = xyes -a x$HAVE_VORBIS = xyes; then
   BUILDABLE_EXAMPLES="$BUILDABLE_EXAMPLES player_example"
 fi
 AC_SUBST(BUILDABLE_EXAMPLES)

Modified: branches/theora-mmx/doc/Makefile.am
===================================================================
--- branches/theora-mmx/doc/Makefile.am	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/doc/Makefile.am	2005-07-12 20:07:16 UTC (rev 9563)
@@ -44,23 +44,22 @@
 
 
 install-data-local: doxygen-build.stamp
-	$(mkinstalldirs) $(docdir)
+	$(mkinstalldirs) $(DESTDIR)$(docdir)
 	if test -d libtheora; then \
 	  for dir in libtheora/*; do \
 	    if test -d $$dir; then \
 	      b=`basename $$dir`; \
-	      $(mkinstalldirs) $(docdir)/$$b; \
+	      $(mkinstalldirs) $(DESTDIR)$(docdir)/$$b; \
 	      for f in $$dir/*; do \
-		$(INSTALL_DATA) $$f $(docdir)/$$b; \
+		$(INSTALL_DATA) $$f $(DESTDIR)$(docdir)/$$b; \
 	      done \
 	    fi \
 	  done \
 	fi
 
 uninstall-local:
-	rm -rf $(docdir)
+	rm -rf $(DESTDIR)$(docdir)
 
 clean-local:
 	if test -d libtheora; then rm -rf libtheora; fi
 	if test -f doxygen-build.stamp; then rm -f doxygen-build.stamp; fi
-


Property changes on: branches/theora-mmx/doc/spec
___________________________________________________________________
Name: svn:ignore
   + Theora_I_spec.pdf


Modified: branches/theora-mmx/doc/spec/spec.bib
===================================================================
--- branches/theora-mmx/doc/spec/spec.bib	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/doc/spec/spec.bib	2005-07-12 20:07:16 UTC (rev 9563)
@@ -21,7 +21,7 @@
 @MISC{Mel04,
   author="Mike Melanson",
   title="{VP3} Bitstream Format and Decoding Process",
-  howpublished="\url{http://home.pcisys.net/~melanson/codecs/vp3-format.txt}",
+  howpublished="\url{http://www.multimedia.cx/vp3-format.txt}",
   month=mar,
   year=2004
 }

Modified: branches/theora-mmx/doc/spec/spec.tex
===================================================================
--- branches/theora-mmx/doc/spec/spec.tex	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/doc/spec/spec.tex	2005-07-12 20:07:16 UTC (rev 9563)
@@ -7695,14 +7695,6 @@
 Frame data pages MUST be marked with a granule index corresponding to
  the display time of the last frame/packet that finishes in that page.
 
-{\bf Note:}
-This scheme is still under discussion.
-It has also been proposed that pages be labeled with a granule corresponding to
- the first frame that begins on that page.
-This simplifies seeking and mux, but is different from the published
- definition of the Ogg granule field.
-This document will be updated when the issue is settled.
-
 %TODO: \subsection{Granule position}
 
 \section{Multiplexed stream mapping}

Modified: branches/theora-mmx/doc/vp3-format.txt
===================================================================
--- branches/theora-mmx/doc/vp3-format.txt	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/doc/vp3-format.txt	2005-07-12 20:07:16 UTC (rev 9563)
@@ -1,10 +1,12 @@
 VP3 Bitstream Format and Decoding Process
-by Mike Melanson (melanson at pcisys.net)
-v0.4: March 2, 2004
+by Mike Melanson (mike at multimedia.cx)
+v0.5: December 8, 2004
 
 
-  [This document is still categorized as a "work-in-progess" and has
-   many incomplete sections.]
+[December 8, 2004: Note that this document is not complete and likely
+will never be completed. However, it helped form the basis of Theora I 
+specification available at
+  http://www.theora.org/doc/Theora_I_spec.pdf ]
 
 
 Contents
@@ -91,7 +93,7 @@
 
 This indicates that a run of 4 zeroes is followed by a coefficient of 5;
 then a run of 1 zero is followed by 2; then a run of 3 zeroes is
-followed by a 9.
+followed by 9.
 
 * Zigzag Ordering: After transforming and quantizing a block of samples,
 the samples are not in an optimal order for run length encoding. Zigzag
@@ -182,7 +184,7 @@
 
  * chunk header
  * block coding information
- * coding mode information
+ * macroblock coding mode information
  * motion vectors
  * DC coefficients
  * 1st AC coefficients
@@ -943,58 +945,82 @@
 If the decoder only finds one valid candidate predictor, then it is used
 by itself. When the decoder finds multiple valid candidate fragments
 from which to predict DC, it applies a weighting function to the
-surrounding fragments' DC coefficients.
+surrounding fragments' DC coefficients. The following table presents all 
+16 possible combinations of available/not available predictors and what 
+to do in each case:
 
-If the up-right and left predictors are available:
+    ul   u  ur   l
+    --  --  --  --
+     0   0   0   0    no predictors available:
+                        use the last predictor saved for the frame type
+                        (either intra, inter, or golden)
 
-  pred = (53 * ur.dc) + (75 * l.dc)
-         --------------------------
-                    128
+     0   0   0   1    left predictor available:
+                        pred = l.dc
 
-If the up, up-right, and left predictors are available, the up
-predictor is discarded and the predictor calculation is the same as for 
-[ur l] prediction.
+     0   0   1   0    up-right predictor available:
+                        pred = ur.dc
 
-If the up-left, up-right, and left predictors are available, the up-left
-predictor is discarded and the predictor calculation is the same as for 
-[ur l] prediction.
+     0   0   1   1    up-right, left predictors available:
+                        pred = (53 * ur.dc) + (75 * l.dc)
+                               --------------------------
+                                         128
 
-If the up and left predictors are available:
+     0   1   0   0    up predictor available:
+                        pred = u.dc
 
-  pred = (u.dc + l.dc)
-         -------------
-               2
+     0   1   0   1    up, left predictors available:
+                        pred = (u.dc + l.dc)
+                               -------------
+                                     2
 
-If the up and up-right predictors are available, the up-right predictor
-is discarded and the up predictor is used by itself.
+     0   1   1   0    up, up-right predictors available:
+                        discard up-right predictor
+                        pred = u.dc
 
-If the up-left and left predictors are available, the up-left predictor
-is discarded and the left predictor is used by itself.
+     0   1   1   1    up, up-right, left predictors available:
+                        discard up predictor
+                        pred = (53 * ur.dc) + (75 * l.dc)
+                               --------------------------
+                                         128
 
-If the up-left and up predictors are available, the up-left predictor is
-discarded and the left predictor is used by itself.
+     1   0   0   0    up-left predictor available:
+                        pred = ul.dc
 
-If the up-left and up-right predictors are available:
+     1   0   0   1    up-left, left predictors available:
+                        discard up-left predictor
+                        pred = l.dc
 
-  pred = (ul.dc + ur.dc)
-         ---------------
-                2
+     1   0   1   0    up-left, up-right predictors available:
+                        pred = (ul.dc + ur.dc)
+                               ---------------
+                                      2
 
-If the up-left, up, and up-right predictors are available:
+     1   0   1   1    up-left, up-right, left predictors available:
+                        discard up-left predictor
+                        pred = (53 * ur.dc) + (75 * l.dc)
+                               --------------------------
+                                         128
 
-  pred = (3 * ul.dc + 10 * u.dc + 3 * ur.dc)
-         -----------------------------------
-                         16
+     1   1   0   0    up-left, up predictors available:
+                        discard up-left
+                        pred = u.dc
 
-If the up-left, up, and left predictors are available:
+     1   1   0   1    up-left, up, left predictors available:
+                        pred = (-26 * ul.dc + 29 * u.dc + 29 * l.dc)
+                               -------------------------------------
+                                                 32
 
-  pred = (-26 * ul.dc + 29 * u.dc + 29 * l.dc)
-         -------------------------------------
-                          32
+     1   1   1   0    up-left, up, up-right predictors available:
+                        pred = (3 * ul.dc + 10 * u.dc + 3 * ur.dc)
+                               -----------------------------------
+                                                16
 
-If all 4 predictors are available (up-left, up, up-right, and left), the
-up-right predictor is discarded and the predictor calculation is the
-same as for [ul u l].
+     1   1   1   1    all 4 predictors available:
+                        discard up-right predictor
+                        pred = (-26 * ul.dc + 29 * u.dc + 29 * l.dc)
+                               -------------------------------------
+                                                 32
 
 Note that this final prediction case ([ul u l]) risks outranging. The
 difference of the predicted DC is checked against u.dc, l.dc, and ul.dc,
@@ -1070,7 +1096,8 @@
 into the VP31 coding standard. These tables can vary according to the
 setup information transported along with a Theora file.
 
-Base quantization matrix for golden frame Y fragments:
+Base quantization matrix for golden frame Y fragments (note that this 
+is the same as JPEG):
 
     16  11  10  16  24  40  51  61
     12  12  14  19  26  58  60  55
@@ -1082,7 +1109,8 @@
     72  92  95  98 112 100 103  99
 
 
-Base quantization matrix for golden frame C fragments:
+Base quantization matrix for golden frame C fragments (note that this 
+is the same as JPEG):
     
     17  18  24  47  99  99  99  99
     18  21  26  66  99  99  99  99
@@ -1231,7 +1259,8 @@
 format.
 
 Timothy B. Terriberry (tterribe at vt dot edu) for clarification about the
-differences between VP3 and Theora
+differences between VP3 and Theora, detailed explanation of motion 
+vector mechanics.
 
 
 References
@@ -1251,6 +1280,10 @@
 
 ChangeLog
 ---------
+v0.5: December 8, 2004
+- reworked section "Reversing The DC Prediction" to include a tabular 
+representation of all 16 prediction modes
+
 v0.4: March 2, 2004
 - renamed and expanded section "Initializing The Quantization Matrices"
 - outlined section "Reconstructing The Frame"

Modified: branches/theora-mmx/include/theora/theora.h
===================================================================
--- branches/theora-mmx/include/theora/theora.h	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/include/theora/theora.h	2005-07-12 20:07:16 UTC (rev 9563)
@@ -347,6 +347,7 @@
  * Input a packet containing encoded data into the theora decoder.
  * \param th A theora_state handle previously initialized for decoding.
  * \param op An ogg_packet containing encoded theora data.
+ * \retval 0 Success
  * \retval OC_BADPACKET \a op does not contain encoded video data
  */
 extern int theora_decode_packetin(theora_state *th,ogg_packet *op);
@@ -386,13 +387,40 @@
 extern int theora_packet_iskeyframe(ogg_packet *op);
 
 /**
+ * Report the granulepos shift radix
+ *
+ * When embedded in Ogg, Theora uses a two-part granulepos, 
+ * splitting the 64-bit field into two pieces. The more-significant
+ * section represents the frame count at the last keyframe,
+ * and the less-significant section represents the count of
+ * frames since the last keyframe. In this way the overall
+ * field is still non-decreasing with time, but usefully encodes
+ * a pointer to the last keyframe, which is necessary for
+ * correctly restarting decode after a seek. 
+ *
+ * This function reports the number of bits used to represent
+ * the distance to the last keyframe, and thus how the granulepos
+ * field must be shifted or masked to obtain the two parts.
+ * 
+ * Since libtheora returns compressed data in an ogg_packet
+ * structure, this may be generally useful even if the Theora
+ * packets are not being used in an Ogg container. 
+ *
+ * \param ti A previously initialized theora_info struct
+ * \returns The bit shift dividing the two granulepos fields
+ *
+ * This function was added inthe 1.0alpha5 release.
+ */
+int theora_granule_shift(theora_info *ti);
+
+/**
  * Convert a granulepos to an absolute frame number. The granulepos is
  * interpreted in the context of a given theora_state handle.
  *
  * \param th A previously initialized theora_state handle (encode or decode)
  * \param granulepos The granulepos to convert.
  * \returns The frame number corresponding to \a granulepos.
- * \retval -1 The given granulepos is invalid (ie. negative)
+ * \retval -1 The given granulepos is undefined (i.e. negative)
  *
  * Thus function was added in the 1.0alpha4 release.
  */
@@ -404,7 +432,9 @@
  * \param th A previously initialized theora_state handle (encode or decode)
  * \param granulepos The granulepos to convert.
  * \returns The absolute time in seconds corresponding to \a granulepos.
- * \retval -1 The given granulepos is invalid (ie. negative)
+ * \retval -1. The given granulepos is undefined (i.e. negative), or
+ * \retval -1. The function has been disabled because floating 
+ *		point support is not available.
  */
 extern double theora_granule_time(theora_state *th,ogg_int64_t granulepos);
 

Modified: branches/theora-mmx/lib/Makefile.am
===================================================================
--- branches/theora-mmx/lib/Makefile.am	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/lib/Makefile.am	2005-07-12 20:07:16 UTC (rev 9563)
@@ -2,10 +2,10 @@
 
 lib_LTLIBRARIES = libtheora.la
 
-if THEORA_SUPPORT_ENCODE
+if THEORA_DISABLE_ENCODE
+encoder_sources = encoder_disabled.c
+else
 encoder_sources = dct_encode.c encode.c encoder_toplevel.c
-else
-encoder_sources = encoder_disabled.c
 endif
 
 libtheora_la_SOURCES = \

Modified: branches/theora-mmx/lib/dct_decode.c
===================================================================
--- branches/theora-mmx/lib/dct_decode.c	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/lib/dct_decode.c	2005-07-12 20:07:16 UTC (rev 9563)
@@ -168,7 +168,7 @@
                                         pixel is used */
 
   /* Get coding mode for this block */
-  if ( GetFrameType(pbi) == BASE_FRAME ){
+  if ( GetFrameType(pbi) == KEY_FRAME ){
     pbi->CodingMode = CODE_INTRA;
   }else{
     /* Get Motion vector and mode for this block. */
@@ -1068,7 +1068,7 @@
 
   void (*ExpandBlockA) ( PB_INSTANCE *pbi, ogg_int32_t FragmentNumber );
 
-  if ( GetFrameType(pbi) == BASE_FRAME )
+  if ( GetFrameType(pbi) == KEY_FRAME )
     ExpandBlockA=ExpandKFBlock;
   else
     ExpandBlockA=ExpandBlock;
@@ -1112,7 +1112,7 @@
 
         /* only do 2 prediction if fragment coded and on non intra or
            if all fragments are intra */
-        if( pbi->display_fragments[i] || (GetFrameType(pbi) == BASE_FRAME) ){
+        if( pbi->display_fragments[i] || (GetFrameType(pbi) == KEY_FRAME) ){
           /* Type of Fragment */
           WhichFrame = Mode2Frame[pbi->FragCodingMethod[i]];
 
@@ -1205,7 +1205,7 @@
 
   /* Reconstruct the golden frame if necessary.
      For VFW codec only on key frames */
-  if ( GetFrameType(pbi) == BASE_FRAME ){
+  if ( GetFrameType(pbi) == KEY_FRAME ){
     CopyRecon( pbi, pbi->GoldenFrame, pbi->LastFrameRecon );
     /* We may need to update the UMV border */
     UpdateUMVBorder(pbi, pbi->GoldenFrame);

Modified: branches/theora-mmx/lib/dct_encode.c
===================================================================
--- branches/theora-mmx/lib/dct_encode.c	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/lib/dct_encode.c	2005-07-12 20:07:16 UTC (rev 9563)
@@ -248,7 +248,7 @@
                                 ogg_int32_t FragIndex){
   ogg_uint32_t  token_count;
 
-  if ( GetFrameType(&cpi->pb) == BASE_FRAME ){
+  if ( GetFrameType(&cpi->pb) == KEY_FRAME ){
     /* Key frame so code block in INTRA mode. */
     cpi->pb.CodingMode = CODE_INTRA;
   }else{
@@ -393,7 +393,7 @@
   /* adjusted / filtered pointers */
   FiltPtr = &cpi->ConvDestBuffer[cpi->pb.pixel_index_table[FragIndex]];
 
-  if ( GetFrameType(&cpi->pb) == BASE_FRAME ) {
+  if ( GetFrameType(&cpi->pb) == KEY_FRAME ) {
     /* Key frame so code block in INTRA mode. */
     cpi->pb.CodingMode = CODE_INTRA;
   }else{

Modified: branches/theora-mmx/lib/decode.c
===================================================================
--- branches/theora-mmx/lib/decode.c	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/lib/decode.c	2005-07-12 20:07:16 UTC (rev 9563)
@@ -76,7 +76,7 @@
   theora_read(pbi->opb,1,&ret);
   SpareBits = (unsigned char)ret;
 
-  if ( (pbi->FrameType == BASE_FRAME) ){
+  if ( (pbi->FrameType == KEY_FRAME) ){
     /* Read the type / coding method for the key frame. */
     theora_read(pbi->opb,1,&ret);
     pbi->KeyFrameType = (unsigned char)ret;
@@ -96,7 +96,7 @@
   /* Set the appropriate frame type according to the request. */
   switch ( FrType ){
 
-  case BASE_FRAME:
+  case KEY_FRAME:
     pbi->FrameType = FrType;
     break;
 
@@ -140,7 +140,7 @@
   ogg_uint32_t  i;
 
   /* If the frame is an intra frame then all blocks have mode intra. */
-  if ( GetFrameType(pbi) == BASE_FRAME ){
+  if ( GetFrameType(pbi) == KEY_FRAME ){
     for ( i = 0; i < pbi->UnitFragments; i++ ){
       pbi->FragCodingMethod[i] = CODE_INTRA;
     }
@@ -322,7 +322,7 @@
   ogg_uint32_t  MBListIndex = 0;
 
   /* Should not be decoding motion vectors if in INTRA only mode. */
-  if ( GetFrameType(pbi) == BASE_FRAME ){
+  if ( GetFrameType(pbi) == KEY_FRAME ){
     return;
   }
 

Modified: branches/theora-mmx/lib/encode.c
===================================================================
--- branches/theora-mmx/lib/encode.c	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/lib/encode.c	2005-07-12 20:07:16 UTC (rev 9563)
@@ -578,7 +578,7 @@
   ClearDownQFragData(&cpi->pb);
 
   /* The tree is not needed (implicit) for key frames */
-  if ( GetFrameType(&cpi->pb) != BASE_FRAME ){
+  if ( GetFrameType(&cpi->pb) != KEY_FRAME ){
     /* Pack the quad tree fragment mapping. */
     PackAndWriteDFArray( cpi );
   }
@@ -587,7 +587,7 @@
   cpi->FrameBitCount = oggpackB_bytes(cpi->oggbuffer) << 3;
 
   /* Mode and MV data not needed for key frames. */
-  if ( GetFrameType(&cpi->pb) != BASE_FRAME ){
+  if ( GetFrameType(&cpi->pb) != KEY_FRAME ){
     /* Pack and code the mode list. */
     PackModes(cpi);
     /* Pack the motion vectors */
@@ -801,7 +801,7 @@
         /* only do 2 prediction if fragment coded and on non intra or
            if all fragments are intra */
         if( cpi->pb.display_fragments[i] ||
-            (GetFrameType(&cpi->pb) == BASE_FRAME) ) {
+            (GetFrameType(&cpi->pb) == KEY_FRAME) ) {
           /* Type of Fragment */
           WhichFrame = Mode2Frame[cpi->pb.FragCodingMethod[i]];
 
@@ -1471,7 +1471,7 @@
   oggpackB_write( opb, 0, 1 );
 
   /* If the frame was a base frame then write out the frame dimensions. */
-  if ( cpi->pb.FrameType == BASE_FRAME ) {
+  if ( cpi->pb.FrameType == KEY_FRAME ) {
     /* Key frame type / method */
     oggpackB_write( opb, cpi->pb.KeyFrameType, 1 );
 

Modified: branches/theora-mmx/lib/encoder_internal.h
===================================================================
--- branches/theora-mmx/lib/encoder_internal.h	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/lib/encoder_internal.h	2005-07-12 20:07:16 UTC (rev 9563)
@@ -5,7 +5,7 @@
  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  *                                                                  *
- * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2005                *
  * by the Xiph.Org Foundation http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
@@ -46,10 +46,11 @@
 /* Border is for unrestricted mv's */
 #define UMV_BORDER              16
 #define STRIDE_EXTRA            (UMV_BORDER * 2)
+
 #define Q_TABLE_SIZE            64
 
-#define BASE_FRAME              0
-#define NORMAL_FRAME            1
+#define KEY_FRAME              0
+#define DELTA_FRAME            1
 
 #define MAX_MODES               8
 #define MODE_BITS               3
@@ -251,11 +252,19 @@
 
 } HUFF_ENTRY;
 
+typedef struct qmat_range_table {
+  int startq, startqi; /* index where this range starts */
+  Q_LIST_ENTRY *qmat;  /* qmat at this range boundary */
+} qmat_range_table;
+
 typedef struct codec_setup_info {
   ogg_uint32_t QThreshTable[Q_TABLE_SIZE];
   Q_LIST_ENTRY DcScaleFactorTable[Q_TABLE_SIZE];
+
   int MaxQMatrixIndex;
   Q_LIST_ENTRY *qmats;
+  qmat_range_table *range_table[6];
+
   Q_LIST_ENTRY Y_coeffs[64];
   Q_LIST_ENTRY UV_coeffs[64];
   Q_LIST_ENTRY Inter_coeffs[64];
@@ -614,7 +623,7 @@
 
   ogg_uint32_t      RunLength;
   ogg_uint32_t      MaxBitTarget;     /* Cut off target for rate capping */
-  double            BitRateCapFactor; /* Factor relating normal frame target
+  double            BitRateCapFactor; /* Factor relating delta frame target
                                          to cut off target. */
 
   unsigned char     MBCodingMode;     /* Coding mode flags */

Modified: branches/theora-mmx/lib/encoder_toplevel.c
===================================================================
--- branches/theora-mmx/lib/encoder_toplevel.c	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/lib/encoder_toplevel.c	2005-07-12 20:07:16 UTC (rev 9563)
@@ -228,8 +228,8 @@
   memset( cpi->pb.display_fragments, 1, cpi->pb.UnitFragments );
   memset( cpi->extra_fragments, 1, cpi->pb.UnitFragments );
 
-  /* Set up for a BASE/KEY FRAME */
-  SetFrameType( &cpi->pb,BASE_FRAME );
+  /* Set up for a KEY FRAME */
+  SetFrameType( &cpi->pb,KEY_FRAME );
 }
 
 static void AdjustKeyFrameContext(CP_INSTANCE *cpi) {
@@ -326,7 +326,7 @@
   EncodeData(cpi);
 
   /* Adjust drop frame trigger. */
-  if ( GetFrameType(&cpi->pb) != BASE_FRAME ) {
+  if ( GetFrameType(&cpi->pb) != KEY_FRAME ) {
     /* Apply decay factor then add in the last frame size. */
     cpi->DropFrameTriggerBytes =
       ((cpi->DropFrameTriggerBytes * (DF_CANDIDATE_WINDOW-1)) /
@@ -359,7 +359,7 @@
 
   /* Update the BpbCorrectionFactor variable according to whether or
      not we were close enough with our selection of DCT quantiser.  */
-  if ( GetFrameType(&cpi->pb) != BASE_FRAME ) {
+  if ( GetFrameType(&cpi->pb) != KEY_FRAME ) {
     /* Work out a size correction factor. */
     CorrectionFactor = (double)oggpackB_bytes(cpi->oggbuffer) /
       (double)cpi->ThisFrameTargetBytes;
@@ -391,7 +391,7 @@
   }
 
   /* Adjust carry over and or key frame context. */
-  if ( GetFrameType(&cpi->pb) == BASE_FRAME ) {
+  if ( GetFrameType(&cpi->pb) == KEY_FRAME ) {
     /* Adjust the key frame context unless the key frame was very small */
     AdjustKeyFrameContext(cpi);
   } else {
@@ -542,8 +542,8 @@
     cpi->pb.FragMVect[i].y = 0;
   }
 
-  /* Default to normal frames. */
-  SetFrameType( &cpi->pb, NORMAL_FRAME );
+  /* Default to delta frames. */
+  SetFrameType( &cpi->pb, DELTA_FRAME );
 
   /* Clear down the difference arrays for the current frame. */
   memset( cpi->pb.display_fragments, 0, cpi->pb.UnitFragments );

Modified: branches/theora-mmx/lib/frarray.c
===================================================================
--- branches/theora-mmx/lib/frarray.c	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/lib/frarray.c	2005-07-12 20:07:16 UTC (rev 9563)
@@ -456,7 +456,7 @@
 
   /* For "Key frames" mark all blocks as coded and return. */
   /* Else initialise the ArrayPtr array to 0 (all blocks uncoded by default) */
-  if ( GetFrameType(pbi) == BASE_FRAME ) {
+  if ( GetFrameType(pbi) == KEY_FRAME ) {
     memset( pbi->SBFullyFlags, 1, pbi->SuperBlocks );
     memset( pbi->SBCodedFlags, 1, pbi->SuperBlocks );
         memset( pbi->MBCodedFlags, 0, pbi->MacroBlocks );

Modified: branches/theora-mmx/lib/misc_common.c
===================================================================
--- branches/theora-mmx/lib/misc_common.c	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/lib/misc_common.c	2005-07-12 20:07:16 UTC (rev 9563)
@@ -59,7 +59,7 @@
   }
 
   /* Adjust according to Q shift and type of frame */
-  if ( GetFrameType(&cpi->pb) == BASE_FRAME ) {
+  if ( GetFrameType(&cpi->pb) == KEY_FRAME ) {
     /* Get primary prediction */
     BytesPerBlock = KfBpbTable[ThreshTableIndex];
   } else {
@@ -258,7 +258,7 @@
   cpi->pb.ThisFrameQualityValue = cpi->pb.QThreshTable[QIndex];
 
   /* Apply range restrictions for key frames. */
-  if ( GetFrameType(&cpi->pb) == BASE_FRAME ) {
+  if ( GetFrameType(&cpi->pb) == KEY_FRAME ) {
     if ( cpi->pb.ThisFrameQualityValue > cpi->pb.QThreshTable[20] )
       cpi->pb.ThisFrameQualityValue = cpi->pb.QThreshTable[20];
     else if ( cpi->pb.ThisFrameQualityValue < cpi->pb.QThreshTable[50] )
@@ -273,7 +273,7 @@
   }
 
   if(cpi->FixedQ) {
-    if ( GetFrameType(&cpi->pb) == BASE_FRAME ) {
+    if ( GetFrameType(&cpi->pb) == KEY_FRAME ) {
       cpi->pb.ThisFrameQualityValue = cpi->pb.QThreshTable[43];
       cpi->pb.ThisFrameQualityValue = cpi->FixedQ;
     } else {

Modified: branches/theora-mmx/lib/quant.c
===================================================================
--- branches/theora-mmx/lib/quant.c	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/lib/quant.c	2005-07-12 20:07:16 UTC (rev 9563)
@@ -5,7 +5,7 @@
  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  *                                                                  *
- * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2005                *
  * by the Xiph.Org Foundation http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
@@ -15,12 +15,13 @@
 
  ********************************************************************/
 
-//#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "encoder_internal.h"
 #include "quant_lookup.h"
 
+/* the *V1 tables are the originals used by the VP3 codec */
+
 static const ogg_uint32_t QThreshTableV1[Q_TABLE_SIZE] = {
   500,  450,  400,  370,  340,  310, 285, 265,
   245,  225,  210,  195,  185,  180, 170, 160,
@@ -70,7 +71,6 @@
         99,     99,     99,     99,     99,     99,     99,     99
 };
 
-/* Different matrices for different encoder versions */
 static const Q_LIST_ENTRY Inter_coeffsV1[64] =
 {
         12, 16,  16,  16,  20,  20,  20,  20,
@@ -107,7 +107,6 @@
   99,   99,     99,     99,     99,     99,     99,     99
 };
 
-/* Different matrices for different encoder versions */
 static const Q_LIST_ENTRY Inter_coeffsV1[64] ={
   16,  16,  16,  20,  24,  28,  32,  40,
   16,  16,  20,  24,  28,  32,  40,  48,
@@ -168,30 +167,40 @@
   oggpackB_write(opb, 0, 2);  /* inter V the same */
 }
 
-static int _read_qtable_range(codec_setup_info *ci, oggpack_buffer* opb, int N) 
+static int _read_qtable_range(codec_setup_info *ci, oggpack_buffer* opb,
+	 int N, int type) 
 {
   int index, range;
   int qi = 0;
+  int count = 0;
+  qmat_range_table table[65];
 
   theora_read(opb,_ilog(N-1),&index); /* qi=0 index */
-  //fprintf(stderr, " [%d]",index);
+  table[count].startqi = 0;
+  table[count++].qmat = ci->qmats + index * Q_TABLE_SIZE;
   while(qi<63) {
     theora_read(opb,_ilog(62-qi),&range); /* range to next code q matrix */
     range++;
-    //fprintf(stderr," %d",range);
     if(range<=0) return OC_BADHEADER;
     qi+=range;
     theora_read(opb,_ilog(N-1),&index); /* next index */
-    //fprintf(stderr, " [%d]",index);
+    table[count].startqi = qi;
+    table[count++].qmat = ci->qmats + index * Q_TABLE_SIZE;
   }
 
-  return 0;
+  ci->range_table[type] = _ogg_malloc(count * sizeof(qmat_range_table));
+  if (ci->range_table[type] != NULL) {
+    memcpy(&ci->range_table[type], table, count * sizeof(qmat_range_table)); 
+    return 0;
+  }
+  
+  return OC_FAULT; /* allocation failed */
 }
 
 int ReadQTables(codec_setup_info *ci, oggpack_buffer* opb) {
   long bits,value;
   int x,y, N;
-  //fprintf(stderr, "Reading Q tables...\n");
+
   /* AC scale table */
   theora_read(opb,4,&bits); bits++;
   for(x=0; x<Q_TABLE_SIZE; x++) {
@@ -208,104 +217,87 @@
   }
   /* base matricies */
   theora_read(opb,9,&N); N++;
-  //fprintf(stderr, "  max q matrix index %d\n", N);
   if(N!=3)return OC_BADHEADER; /* we only support the VP3 config */
   ci->qmats=_ogg_malloc(N*64*sizeof(Q_LIST_ENTRY));
   ci->MaxQMatrixIndex = N;
   for(y=0; y<N; y++) {
-    //fprintf(stderr," q matrix %d:\n  ", y);
     for(x=0; x<64; x++) {
       theora_read(opb,8,&value);
       if(bits<0)return OC_BADHEADER;
       ci->qmats[(y<<6)+x]=(Q_LIST_ENTRY)value;
-      //fprintf(stderr," %03d", (Q_LIST_ENTRY)value);
-      //if((x+1)%8==0)fprintf(stderr,"\n  ");
     }
-    //fprintf(stderr,"\n");
   }
   /* table mapping */
+  for(x=0; x<6; x++) {
+    ci->range_table[x] = NULL;
+  }
   {
     int flag, ret;
     /* intra Y */
-    //fprintf(stderr,"\n Intra Y:");
-    if((ret=_read_qtable_range(ci,opb,N))<0) return ret;
+    if((ret=_read_qtable_range(ci,opb,N,0))<0) return ret;
     /* intra U */
-    //fprintf(stderr, "\n Intra U:");
     theora_read(opb,1,&flag);
     if(flag<0) return OC_BADHEADER;
     if(flag) {
       /* explicitly coded */
-      if((ret=_read_qtable_range(ci,opb,N))<0) return ret;
+      if((ret=_read_qtable_range(ci,opb,N,1))<0) return ret;
     } else {
       /* same as previous */
-      //fprintf(stderr," same as above");
     }
     /* intra V */
-    //fprintf(stderr,"\n Intra V:");
     theora_read(opb,1,&flag);
     if(flag<0) return OC_BADHEADER;
     if(flag) {
       /* explicitly coded */
-      if((ret=_read_qtable_range(ci,opb,N))<0) return ret;
+      if((ret=_read_qtable_range(ci,opb,N,2))<0) return ret;
     } else {
        /* same as previous */
-      //fprintf(stderr," same as above");
     }
     /* inter Y */
-    //fprintf(stderr,"\n Inter Y:");
     theora_read(opb,1,&flag);
     if(flag<0) return OC_BADHEADER;
     if(flag) {
       /* explicitly coded */
-      if((ret=_read_qtable_range(ci,opb,N))<0) return ret;
+      if((ret=_read_qtable_range(ci,opb,N,3))<0) return ret;
     } else {
       theora_read(opb,1,&flag);
       if(flag<0) return OC_BADHEADER;
       if(flag) {
         /* same as corresponding intra */
-        //fprintf(stderr," same as intra");
       } else {
         /* same as previous */
-        //fprintf(stderr," same as above");
       }
     }
     /* inter U */
-    //fprintf(stderr,"\n Inter U:");
     theora_read(opb,1,&flag);
     if(flag<0) return OC_BADHEADER;
     if(flag) {
       /* explicitly coded */
-      if((ret=_read_qtable_range(ci,opb,N))<0) return ret;
+      if((ret=_read_qtable_range(ci,opb,N,4))<0) return ret;
     } else {
       theora_read(opb,1,&flag);
       if(flag<0) return OC_BADHEADER;
       if(flag) {
         /* same as corresponding intra */
-        //fprintf(stderr," same as intra");
       } else {
         /* same as previous */
-        //fprintf(stderr," same as above");
       }
     }
     /* inter V */
-    //fprintf(stderr,"\n Inter V:");
     theora_read(opb,1,&flag);
     if(flag<0) return OC_BADHEADER;
     if(flag) {
       /* explicitly coded */
-      if((ret=_read_qtable_range(ci,opb,N))<0) return ret;
+      if((ret=_read_qtable_range(ci,opb,N,5))<0) return ret;
     } else {
       theora_read(opb,1,&flag);
       if(flag<0) return OC_BADHEADER;
       if(flag) {
         /* same as corresponding intra */
-        //fprintf(stderr," same as intra");
       } else {
         /* same as previous */
-        //fprintf(stderr," same as above");
       }
     }
-    //fprintf(stderr,"\n");
   }
   
   /* ignore the range table and reference the matricies we use */
@@ -327,7 +319,7 @@
 
 /* Initialize custom qtables using the VP31 values.
    Someday we can change the quant tables to be adaptive, or just plain
-    better.*/
+    better. */
 void InitQTables( PB_INSTANCE *pbi ){
   memcpy(pbi->QThreshTable, QThreshTableV1, sizeof(pbi->QThreshTable));
   memcpy(pbi->DcScaleFactorTable, DcScaleFactorTableV1,

Modified: branches/theora-mmx/lib/toplevel.c
===================================================================
--- branches/theora-mmx/lib/toplevel.c	2005-07-12 19:56:06 UTC (rev 9562)
+++ branches/theora-mmx/lib/toplevel.c	2005-07-12 20:07:16 UTC (rev 9563)
@@ -5,7 +5,7 @@
  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  *                                                                  *
- * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2005                *
  * by the Xiph.Org Foundation http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
@@ -71,8 +71,11 @@
 
 void theora_info_clear(theora_info *c) {
   codec_setup_info *ci=c->codec_setup;
+  int i;
   if(ci){
     if(ci->qmats) _ogg_free(ci->qmats);
+    for(i=0;i<6;i++)
+      if(ci->range_table[i]) _ogg_free(ci->range_table[i]);
     ClearHuffmanTrees(ci->HuffRoot);
     _ogg_free(ci);
   }
@@ -161,9 +164,9 @@
 
 static int _theora_unpack_comment(theora_comment *tc, oggpack_buffer *opb){
   int i;
-  int len;
+  long len;
 
-   _tp_readlsbint(opb,(long *) &len);
+   _tp_readlsbint(opb,&len);
   if(len<0)return(OC_BADHEADER);
   tc->vendor=_ogg_calloc(1,len+1);
   _tp_readbuffer(opb,tc->vendor, len);
@@ -174,7 +177,7 @@
   tc->user_comments=_ogg_calloc(tc->comments,sizeof(*tc->user_comments));
   tc->comment_lengths=_ogg_calloc(tc->comments,sizeof(*tc->comment_lengths));
   for(i=0;i<tc->comments;i++){
-    _tp_readlsbint(opb,(long *)&len);
+    _tp_readlsbint(opb,&len);
     if(len<0)goto parse_err;
     tc->user_comments[i]=_ogg_calloc(1,len+1);
     _tp_readbuffer(opb,tc->user_comments[i],len);
@@ -298,6 +301,7 @@
   ci=(codec_setup_info *)c->codec_setup;
   memset(th, 0, sizeof(*th));
   th->internal_decode=pbi=_ogg_calloc(1,sizeof(*pbi));
+  th->internal_encode=NULL;
 
   InitPBInstance(pbi);
   memcpy(&pbi->info,c,sizeof(*c));
@@ -355,7 +359,7 @@
       if(th->granulepos==-1){
         th->granulepos=0;
       }else{
-        if(pbi->FrameType==BASE_FRAME){
+        if(pbi->FrameType==KEY_FRAME){
           long frames= th->granulepos & ((1<<pbi->keyframe_granule_shift)-1);
           th->granulepos>>=pbi->keyframe_granule_shift;
           th->granulepos+=frames+1;
@@ -406,7 +410,7 @@
 /* returns, in seconds, absolute time of current packet in given
    logical stream */
 double theora_granule_time(theora_state *th,ogg_int64_t granulepos){
-#if THEORA_SUPPORT_FLOAT
+#ifndef THEORA_DISABLE_FLOAT
   CP_INSTANCE *cpi=(CP_INSTANCE *)(th->internal_encode);
   PB_INSTANCE *pbi=(PB_INSTANCE *)(th->internal_decode);
 
@@ -422,7 +426,7 @@
   }
 #endif
 
-  return(-1);
+  return(-1); /* negative granulepos or float calculations disabled */
 }
 
 /* check for header flag */
@@ -438,6 +442,12 @@
   return (op->packet[0] & 0x40) ? 0 : 1; /* inter or intra */
 }
 
+/* returns the shift radix used to split the granulepos into two fields */
+int theora_granule_shift(theora_info *ti)
+{
+  return _ilog(ti->keyframe_frequency_force - 1);
+}
+
 /* returns frame number of current packet in given logical stream */
 ogg_int64_t theora_granule_frame(theora_state *th,ogg_int64_t granulepos){
   CP_INSTANCE *cpi=(CP_INSTANCE *)(th->internal_encode);



More information about the commits mailing list