Bug 507554 - Update in-tree libtheora to 1.1.0 (Thusnelda) plus post-release fixes from SVN. r=chris.double, rs=roc
authorMatthew Gregan <kinetik@flim.org>
Mon, 28 Sep 2009 11:14:21 +1300
changeset 33226 04a5d978b06e333aeb4802f7ca620e60ece124fc
parent 33225 6c221a030a78b5dab815e32c0b31d3ebe03cecf7
child 33227 3fd26ee5928f37952224417e9f116469d072cfc6
push idunknown
push userunknown
push dateunknown
reviewerschris.double, roc
bugs507554
milestone1.9.3a1pre
Bug 507554 - Update in-tree libtheora to 1.1.0 (Thusnelda) plus post-release fixes from SVN. r=chris.double, rs=roc
media/libtheora/455357_wince_local_variable_macro_clash_patch
media/libtheora/AUTHORS
media/libtheora/CHANGES
media/libtheora/COPYING
media/libtheora/README
media/libtheora/README_MOZILLA
media/libtheora/bug498770.patch
media/libtheora/bug498815.patch
media/libtheora/bug498824.patch
media/libtheora/bug504613.patch
media/libtheora/include/theora/Makefile.in
media/libtheora/include/theora/codec.h
media/libtheora/include/theora/config.h
media/libtheora/include/theora/theora.h
media/libtheora/include/theora/theoradec.h
media/libtheora/include/theora/theoraenc.h
media/libtheora/lib/Makefile.in
media/libtheora/lib/apiwrapper.c
media/libtheora/lib/apiwrapper.h
media/libtheora/lib/bitpack.c
media/libtheora/lib/bitpack.h
media/libtheora/lib/config.h
media/libtheora/lib/cpu.c
media/libtheora/lib/cpu.h
media/libtheora/lib/dct.h
media/libtheora/lib/dec/apiwrapper.c
media/libtheora/lib/dec/apiwrapper.h
media/libtheora/lib/dec/bitpack.c
media/libtheora/lib/dec/bitpack.h
media/libtheora/lib/dec/dct.h
media/libtheora/lib/dec/decapiwrapper.c
media/libtheora/lib/dec/decinfo.c
media/libtheora/lib/dec/decint.h
media/libtheora/lib/dec/decode.c
media/libtheora/lib/dec/dequant.c
media/libtheora/lib/dec/dequant.h
media/libtheora/lib/dec/fragment.c
media/libtheora/lib/dec/huffdec.c
media/libtheora/lib/dec/huffdec.h
media/libtheora/lib/dec/huffman.h
media/libtheora/lib/dec/idct.c
media/libtheora/lib/dec/idct.h
media/libtheora/lib/dec/info.c
media/libtheora/lib/dec/internal.c
media/libtheora/lib/dec/ocintrin.h
media/libtheora/lib/dec/quant.c
media/libtheora/lib/dec/quant.h
media/libtheora/lib/dec/state.c
media/libtheora/lib/dec/x86/mmxfrag.c
media/libtheora/lib/dec/x86/mmxidct.c
media/libtheora/lib/dec/x86/mmxstate.c
media/libtheora/lib/dec/x86/x86int.h
media/libtheora/lib/dec/x86/x86state.c
media/libtheora/lib/dec/x86_vc/mmxfrag.c
media/libtheora/lib/dec/x86_vc/mmxidct.c
media/libtheora/lib/dec/x86_vc/mmxloopfilter.c
media/libtheora/lib/dec/x86_vc/mmxstate.c
media/libtheora/lib/dec/x86_vc/x86int.h
media/libtheora/lib/dec/x86_vc/x86state.c
media/libtheora/lib/decapiwrapper.c
media/libtheora/lib/decinfo.c
media/libtheora/lib/decint.h
media/libtheora/lib/decode.c
media/libtheora/lib/dequant.c
media/libtheora/lib/dequant.h
media/libtheora/lib/encint.h
media/libtheora/lib/encoder_disabled.c
media/libtheora/lib/enquant.h
media/libtheora/lib/fragment.c
media/libtheora/lib/huffdec.c
media/libtheora/lib/huffdec.h
media/libtheora/lib/huffenc.h
media/libtheora/lib/huffman.h
media/libtheora/lib/idct.c
media/libtheora/lib/info.c
media/libtheora/lib/internal.c
media/libtheora/lib/internal.h
media/libtheora/lib/mathops.h
media/libtheora/lib/ocintrin.h
media/libtheora/lib/quant.c
media/libtheora/lib/quant.h
media/libtheora/lib/state.c
media/libtheora/lib/x86/mmxfrag.c
media/libtheora/lib/x86/mmxfrag.h
media/libtheora/lib/x86/mmxidct.c
media/libtheora/lib/x86/mmxloop.h
media/libtheora/lib/x86/mmxstate.c
media/libtheora/lib/x86/x86int.h
media/libtheora/lib/x86/x86state.c
media/libtheora/lib/x86_vc/mmxfrag.c
media/libtheora/lib/x86_vc/mmxfrag.h
media/libtheora/lib/x86_vc/mmxidct.c
media/libtheora/lib/x86_vc/mmxloop.h
media/libtheora/lib/x86_vc/mmxstate.c
media/libtheora/lib/x86_vc/x86int.h
media/libtheora/lib/x86_vc/x86state.c
media/libtheora/update.sh
deleted file mode 100644
--- a/media/libtheora/455357_wince_local_variable_macro_clash_patch
+++ /dev/null
@@ -1,40 +0,0 @@
-diff --git a/media/libtheora/lib/dec/decode.c b/media/libtheora/lib/dec/decode.c
---- a/media/libtheora/lib/dec/decode.c
-+++ b/media/libtheora/lib/dec/decode.c
-@@ -1803,8 +1803,8 @@
- 
- static void oc_dering_block(unsigned char *_idata,int _ystride,int _b,
-  int _dc_scale,int _sharp_mod,int _strong){
--  static const int     MOD_MAX[2]={24,32};
--  static const int     MOD_SHIFT[2]={1,0};
-+  static const int     OCDB_MOD_MAX[2]={24,32};
-+  static const int     OCDB_MOD_SHIFT[2]={1,0};
-   const unsigned char *psrc;
-   const unsigned char *src;
-   const unsigned char *nsrc;
-@@ -1814,14 +1814,14 @@
-   int                  mod_hi;
-   int                  by;
-   int                  bx;
--  mod_hi=OC_MINI(3*_dc_scale,MOD_MAX[_strong]);
-+  mod_hi=OC_MINI(3*_dc_scale,OCDB_MOD_MAX[_strong]);
-   dst=_idata;
-   src=dst;
-   psrc=src-(_ystride&-!(_b&4));
-   for(by=0;by<9;by++){
-     for(bx=0;bx<8;bx++){
-       int mod;
--      mod=32+_dc_scale-(abs(src[bx]-psrc[bx])<<MOD_SHIFT[_strong]);
-+      mod=32+_dc_scale-(abs(src[bx]-psrc[bx])<<OCDB_MOD_SHIFT[_strong]);
-       vmod[(by<<3)+bx]=mod<-64?_sharp_mod:OC_CLAMPI(0,mod,mod_hi);
-     }
-     psrc=src;
-@@ -1833,7 +1833,7 @@
-     src=nsrc;
-     for(by=0;by<8;by++){
-       int mod;
--      mod=32+_dc_scale-(abs(*src-*psrc)<<MOD_SHIFT[_strong]);
-+      mod=32+_dc_scale-(abs(*src-*psrc)<<OCDB_MOD_SHIFT[_strong]);
-       hmod[(bx<<3)+by]=mod<-64?_sharp_mod:OC_CLAMPI(0,mod,mod_hi);
-       psrc+=_ystride;
-       src+=_ystride;
--- a/media/libtheora/AUTHORS
+++ b/media/libtheora/AUTHORS
@@ -1,48 +1,47 @@
 Monty <monty@xiph.org>
 	- Original VP3 port
 
 Ralph Giles
-Timothy B. Terriberry 
+Timothy B. Terriberry
+Monty
 	- Ongoing development
-
+	
 Dan B. Miller
 	- Pre alpha3 development
-
+	
+Rudolf Marek
 Wim Tayman
 Dan Lenski
+Nils Pipenbrinck
+Monty
 	- MMX optimized functions
-
+	
 Aaron Colwell
 Thomas Vander Stichele
 Jan Gerber
 Conrad Parker
+Cristian Adam
+Sebastian Pippin
+Simon Hosie
 	- Bug fixes, enhancements, build systems.
-
+	
 Mauricio Piacentini
 	- Original win32 projects and example ports
-	- dump_video example
 	- VP3->Theora transcoder
 
 Silvia Pfeiffer
 	- Figures for the spec
 
-Vegard Nossum
-	- Original png2theora implementation
-
-Rudolf Marek
-Nils Pipenbrinck
-	- MMX optimizations
-
 Michael Smith
 Andre Pang
 calc
-ccheney
-brendan
+Chris Cheney
+Brendan Cully
 Edward Hervey
 Adam Moss
 Colin Ward
 Jeremy C. Reed
 Arc Riley
 Rodolphe Ortalo
 	- Bug fixes
 
--- a/media/libtheora/CHANGES
+++ b/media/libtheora/CHANGES
@@ -1,8 +1,66 @@
+libtheora 1.1.1 (unreleased snapshot)
+
+ - No changes have been recorded
+
+libtheora 1.1.0 (2009 September 24)
+
+ - Fix various small issues with the example and telemetry code
+ - Fix handing a zero-byte packet as the first frame
+ - Documentation cleanup
+ - Two minor build fixes
+
+libtheora 1.1beta3 (2009 August 22)
+
+ - Rate control fixes to smooth quality
+ - MSVC build now exports all of the 1.0 api
+ - Assorted small bug fixes
+
+libtheora 1.1beta2 (2009 August 12)
+
+ - Fix a rate control problem with difficult input
+ - Build fixes for OpenBSD and Apple Xcode
+ - Examples now all use the 1.0 api
+ - TH_ENCCTL_SET_SPLEVEL works again
+ - Various bug fixes and source tree rearrangement
+
+libtheora 1.1beta1 (2009 August 5)
+
+ - Support for two-pass encoding
+ - Performance optimization of both encoder and decoder
+ - Encoder supports dynamic adjustment of quality and 
+   bitrate targets
+ - Encoder is generally more configurable, and all
+   rate control modes perform better
+ - Encoder now accepts 4:2:2 and 4:4:4 chroma sampling
+ - Decoder telemetry output shows quantization choice
+   and a breakdown of bitrate usage in the frame
+ - MSVC assembly optimizations up to date and functional
+
+libtheora 1.1alpha2 (2009 May 26)
+
+ - Reduce lambda for small quantizers.
+ - New encoder fDCT does better on smooth gradients
+ - Use SATD for mode decisions (1-2% bitrate reduction)
+ - Assembly rewrite for new features and general speed up
+ - Share code between the encoder and decoder for performance
+ - Fix 4:2:2 decoding and telemetry
+ - MSVC project files updated, but assembly is disabled.
+ - New configure option --disable-spec to work around toolchain
+   detection failures.
+ - Limit symbol exports on MacOS X.
+ - Port remaining unit tests from the 1.0 release.
+
+libtheora 1.1alpha1 (2009 March 27)
+
+ - Encoder rewrite with much improved vbr quality/bitrate and
+   better tracking of the target rate in cbr mode.
+ - MSVC project files do not work in this release.
+
 libtheora 1.0 (2008 November 3)
 
  - Merge x86 assembly for forward DCT from Thusnelda branch.
  - Update 32 bit MMX with loop filter fix.
  - Check for an uninitialized state before dereferencing in propagating
    decode calls.
  - Remove all TH_DEBUG statements.
  - Rename the bitpacker source files copied from libogg to avoid
--- a/media/libtheora/COPYING
+++ b/media/libtheora/COPYING
@@ -1,22 +1,22 @@
-Copyright (C) 2002-2008 Xiph.Org Foundation and contributors.
+Copyright (C) 2002-2009 Xiph.org Foundation
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 
 - Redistributions of source code must retain the above copyright
 notice, this list of conditions and the following disclaimer.
 
 - Redistributions in binary form must reproduce the above copyright
 notice, this list of conditions and the following disclaimer in the
 documentation and/or other materials provided with the distribution.
 
-- Neither the name of the Xiph.Org Foundation nor the names of its
+- Neither the name of the Xiph.org Foundation nor the names of its
 contributors may be used to endorse or promote products derived from
 this software without specific prior written permission.
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION
 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
--- a/media/libtheora/README
+++ b/media/libtheora/README
@@ -1,20 +1,26 @@
 -------------------------------------------------------------------------
-             The Xiph.org Foundation's libtheora 1.0 release
+             The Xiph.org Foundation's libtheora 1.1 beta release
 -------------------------------------------------------------------------
 
 *** What is Theora?
 
 Theora is Xiph.Org's first publicly released video codec, intended
 for use within the Foundation's Ogg multimedia streaming system.
-Theora is derived directly from On2's VP3 codec; Currently the 
-encoders are nearly identical, but Theora will make use of new
-features supported by the decoder to improve on what is possible
-with VP3.
+Theora is derived directly from On2's VP3 codec, adds new features
+while allow it a longer useful lifetime as an competitive codec.
+
+The 1.0 release decoder supports all the new features, but the
+encoder is nearly identical to the VP3 code.
+
+The 1.1 release features a completely rewritten encoder, offering
+better performance and compression, and making more complete use
+of the format's feature set. Files produced by both encoders can
+be decoded by either release.
 
 *** Where is Theora?
 
 Theora's main site is www.theora.org.  Theora and related libraries
 can be gotten from www.theora.org or the main Xiph.Org site at
 www.xiph.org.  Development source is kept in an open subversion 
 repository, see http://theora.org/svn/ for instructions.
 
@@ -53,17 +59,17 @@ Requirements summary:
 
 The provided build system is the GNU automake/autoconf system, and
 the main library, libtheora, should already build smoothly on any
 system.  Failure of libtheora to build on a GNU-enabled system is
 considered a bug; please report problems to theora-dev@xiph.org.
 
 Windows build support is included in the win32 directory.
 
-Project files for Apple XCode is included in the macosx directory.
+Project files for Apple XCode are included in the macosx directory.
 
 There is also an experimental scons build.
 
 *** How do I use the sample encoder?
 
 The sample encoder takes raw video in YUV4MPEG2 format, as used by
 lavtools, mjpeg-tools and other packages. The encoder expects audio,
 if any, in a separate wave WAV file. Try 'encoder_example -h' for a 
--- a/media/libtheora/README_MOZILLA
+++ b/media/libtheora/README_MOZILLA
@@ -1,18 +1,5 @@
-The source from this directory was copied from the libtheora-1.0
-source distribution using the update.sh script. The changes made were
-those applied by update.sh, the addition/update of Makefile.in files
-for the Mozilla build system and the patch in bug below.
+The source from this directory was copied from the theora subversion trunk
+using the update.sh script. The changes made were those applied by update.sh,
+the addition/update of Makefile.in files for the Mozilla build system.
 
-bug498770.patch - Enable optimized theora code in windows build
-Bug 455357 - WinCE LibTheora Pre-defined Macro usage in local variable
-  455357_wince_local_variable_macro_clash_patch
-  This patch is needed for building WinCE / WinMobile because the 
-  Mozilla WinCE Shunt Library currently includes windows.h header file,
-  which causes a conflict with local variables in the oc_dering_block()
-  function.  This issue should be cleared up soon, with a reworking of 
-  the WinCE Shunt Library (Bug 456788 - reduce windows ce shunt impact).  
-  Until then, this simple patch allows WinCE to finish compiling.
-
-bug498815.patch: Fix for this bug from libtheora svn r16143.
-bug498824.patch: Fix for this bug from libtheora thusnelda branch.
-bug504613.patch: Fix for this bug from libtheora svn r16557.
+The subversion revision used was r16584.
deleted file mode 100644
--- a/media/libtheora/bug498770.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-Index: lib/dec/x86_vc/mmxfrag.c
-===================================================================
---- lib/dec/x86_vc/mmxfrag.c	(revision 16142)
-+++ lib/dec/x86_vc/mmxfrag.c	(working copy)
-@@ -27,12 +27,14 @@
- 
- void oc_frag_recon_intra_mmx(unsigned char *_dst,int _dst_ystride,
-  const ogg_int16_t *_residue){
-+  int _save_ebx;
-   /* ---------------------------------------------------------------------
-   This function does the inter reconstruction step with 8 iterations
-   unrolled. The iteration for each instruction is noted by the #id in the
-   comments (in case you want to reconstruct it)
-   --------------------------------------------------------------------- */
-   _asm{
-+    mov       [_save_ebx], ebx
-     mov       edi, [_residue]     /* load residue ptr     */
-     mov       eax, 0x00800080     /* generate constant    */
-     mov       ebx, [_dst_ystride] /* load dst-stride      */
-@@ -93,6 +95,7 @@
-     packuswb  mm3, mm4            /* #8 pack to byte      */
-     movq      [edx + ecx*2], mm1  /* #7 write row         */
-     movq      [edx + eax], mm3    /* #8 write row         */
-+    mov       ebx, [_save_ebx]
-   }
- }
- 
-@@ -100,6 +103,7 @@
- 
- void oc_frag_recon_inter_mmx (unsigned char *_dst, int _dst_ystride,
-  const unsigned char *_src, int _src_ystride, const ogg_int16_t *_residue){
-+  int _save_ebx;
-   /* ---------------------------------------------------------------------
-   This function does the inter reconstruction step with two iterations
-   running in parallel to hide some load-latencies and break the dependency
-@@ -107,6 +111,7 @@
-   comments (in case you want to reconstruct it)
-   --------------------------------------------------------------------- */
-   _asm{
-+    mov       [_save_ebx], ebx
-     pxor      mm0, mm0          /* generate constant 0 */
-     mov       esi, [_src]
-     mov       edi, [_residue]
-@@ -143,6 +148,7 @@
-     movq      [edx + ebx], mm7  /* #2 write row          */
-     lea       edx, [edx+ebx*2]  /* dst += stride * 2     */
-     jne       nextchunk
-+    mov       ebx, [_save_ebx]
-   }
- }
- 
-@@ -150,6 +156,7 @@
- void oc_frag_recon_inter2_mmx(unsigned char *_dst,  int _dst_ystride,
-  const unsigned char *_src1,  int _src1_ystride, const unsigned char *_src2,
-  int _src2_ystride,const ogg_int16_t *_residue){
-+  int _save_ebx;
-   /* ---------------------------------------------------------------------
-   This function does the inter2 reconstruction step.The building of the
-   average is done with a bit-twiddeling trick to avoid excessive register
-@@ -166,6 +173,7 @@
-   using the pavgb instruction let me know and I'll do the 3dnow codepath.
-   --------------------------------------------------------------------- */
-  _asm{
-+   mov        [_save_ebx], ebx
-    mov        eax, 0xfefefefe
-    mov        esi, [_src1]
-    mov        edi, [_src2]
-@@ -204,6 +212,7 @@
-    packuswb   mm2,  mm3           /* pack and saturate   */
-    movq       [edx], mm2          /* write row           */
-    jne        nextrow
-+   mov        ebx, [_save_ebx]
-  }
- }
- 
-Index: lib/dec/x86_vc/mmxloopfilter.c
-===================================================================
---- lib/dec/x86_vc/mmxloopfilter.c	(revision 16142)
-+++ lib/dec/x86_vc/mmxloopfilter.c	(working copy)
-@@ -38,7 +38,7 @@
-   _asm {
-     mov       eax,  [_pix]
-     mov       edx,  [_ystride]
--    mov       ebx,  [_ll]
-+    mov       ecx,  [_ll]
- 
-     /* _pix -= ystride */
-     sub       eax,   edx
-@@ -104,7 +104,7 @@
-     /*Free up mm5.*/
-     packuswb  mm4, mm5
-     /*mm0=L L L L*/
--    movq      mm0, [ebx]
-+    movq      mm0, [ecx]
-     /*if(R_i<-2L||R_i>2L)R_i=0:*/
-     movq      mm5, mm2
-     pxor      mm6, mm6
deleted file mode 100644
--- a/media/libtheora/bug498815.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-Index: decinfo.c
-===================================================================
---- decinfo.c   (revision 16127)
-+++ decinfo.c   (working copy)
-@@ -70,12 +70,8 @@
-   _info->pic_height=(ogg_uint32_t)val;
-   theorapackB_read(_opb,8,&val);
-   _info->pic_x=(ogg_uint32_t)val;
--  /*Note: The sense of pic_y is inverted in what we pass back to the
--     application compared to how it is stored in the bitstream.
--    This is because the bitstream uses a right-handed coordinate system, while
--     applications expect a left-handed one.*/
-   theorapackB_read(_opb,8,&val);
--  _info->pic_y=_info->frame_height-_info->pic_height-(ogg_uint32_t)val;
-+  _info->pic_y=(ogg_uint32_t)val;
-   theorapackB_read(_opb,32,&val);
-   _info->fps_numerator=(ogg_uint32_t)val;
-   theorapackB_read(_opb,32,&val);
-@@ -86,6 +82,11 @@
-    _info->fps_numerator==0||_info->fps_denominator==0){
-     return TH_EBADHEADER;
-   }
-+  /*Note: The sense of pic_y is inverted in what we pass back to the
-+     application compared to how it is stored in the bitstream.
-+    This is because the bitstream uses a right-handed coordinate system, while
-+     applications expect a left-handed one.*/
-+  _info->pic_y=_info->frame_height-_info->pic_height-_info->pic_y;
-   theorapackB_read(_opb,24,&val);
-   _info->aspect_numerator=(ogg_uint32_t)val;
-   theorapackB_read(_opb,24,&val);
deleted file mode 100644
--- a/media/libtheora/bug498824.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-diff --git a/media/libtheora/lib/dec/decinfo.c b/media/libtheora/lib/dec/decinfo.c
-index e51d63e..d08d6b6 100644
---- a/media/libtheora/lib/dec/decinfo.c
-+++ b/media/libtheora/lib/dec/decinfo.c
-@@ -11,7 +11,7 @@
-  ********************************************************************
- 
-   function:
--    last mod: $Id: decinfo.c 15400 2008-10-15 12:10:58Z tterribe $
-+    last mod: $Id$
- 
-  ********************************************************************/
- 
-@@ -111,14 +111,15 @@ static int oc_comment_unpack(oggpack_buffer *_opb,th_comment *_tc){
-   int  i;
-   /*Read the vendor string.*/
-   len=oc_unpack_length(_opb);
--  if(len<0||theorapackB_bytes(_opb)+len>_opb->storage)return TH_EBADHEADER;
-+  if(len<0||len>_opb->storage-theorapackB_bytes(_opb))return TH_EBADHEADER;
-   _tc->vendor=_ogg_malloc((size_t)len+1);
-   oc_unpack_octets(_opb,_tc->vendor,len);
-   _tc->vendor[len]='\0';
-   /*Read the user comments.*/
-   _tc->comments=(int)oc_unpack_length(_opb);
--  if(_tc->comments<0||_tc->comments>(LONG_MAX>>2)||
--   theorapackB_bytes(_opb)+((long)_tc->comments<<2)>_opb->storage){
-+  len=_tc->comments;
-+  if(len<0||len>(LONG_MAX>>2)||len<<2>_opb->storage-theorapackB_bytes(_opb)){
-+    _tc->comments=0;
-     return TH_EBADHEADER;
-   }
-   _tc->comment_lengths=(int *)_ogg_malloc(
-@@ -127,7 +128,7 @@ static int oc_comment_unpack(oggpack_buffer *_opb,th_comment *_tc){
-    _tc->comments*sizeof(_tc->user_comments[0]));
-   for(i=0;i<_tc->comments;i++){
-     len=oc_unpack_length(_opb);
--    if(len<0||theorapackB_bytes(_opb)+len>_opb->storage){
-+    if(len<0||len>_opb->storage-theorapackB_bytes(_opb)){
-       _tc->comments=i;
-       return TH_EBADHEADER;
-     }
-@@ -224,12 +225,10 @@ static int oc_dec_headerin(oggpack_buffer *_opb,th_info *_info,
- int th_decode_headerin(th_info *_info,th_comment *_tc,
-  th_setup_info **_setup,ogg_packet *_op){
-   oggpack_buffer opb;
--  int            ret;
-   if(_op==NULL)return TH_EBADHEADER;
-   if(_info==NULL)return TH_EFAULT;
-   theorapackB_readinit(&opb,_op->packet,_op->bytes);
--  ret=oc_dec_headerin(&opb,_info,_tc,_setup,_op);
--  return ret;
-+  return oc_dec_headerin(&opb,_info,_tc,_setup,_op);
- }
- 
- void th_setup_free(th_setup_info *_setup){
deleted file mode 100644
--- a/media/libtheora/bug504613.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-# HG changeset patch
-# User Matthew Gregan <kinetik@flim.org>
-# Date 1252993590 -43200
-# Node ID 2fce745981185aecebad0366b4c2ff45e9f93e95
-# Parent  8dbe8de92cb46f64f8ff80d79f38961eb02e9cbd
-imported patch bug504613
-
-diff --git a/media/libtheora/lib/dec/decode.c b/media/libtheora/lib/dec/decode.c
---- a/media/libtheora/lib/dec/decode.c
-+++ b/media/libtheora/lib/dec/decode.c
-@@ -1846,16 +1846,40 @@ int th_decode_ctl(th_dec_ctx *_dec,int _
-       _dec->stripe_cb.ctx=cb->ctx;
-       _dec->stripe_cb.stripe_decoded=cb->stripe_decoded;
-       return 0;
-     }break;
-     default:return TH_EIMPL;
-   }
- }
- 
-+/*We're decoding an INTER frame, but have no initialized reference
-+   buffers (i.e., decoding did not start on a key frame).
-+  We initialize them to a solid gray here.*/
-+static void oc_dec_init_dummy_frame(th_dec_ctx *_dec){
-+  th_info *info;
-+  size_t   yplane_sz;
-+  size_t   cplane_sz;
-+  int      yhstride;
-+  int      yvstride;
-+  int      chstride;
-+  int      cvstride;
-+  _dec->state.ref_frame_idx[OC_FRAME_GOLD]=0;
-+  _dec->state.ref_frame_idx[OC_FRAME_PREV]=0;
-+  _dec->state.ref_frame_idx[OC_FRAME_SELF]=1;
-+  info=&_dec->state.info;
-+  yhstride=info->frame_width+2*OC_UMV_PADDING;
-+  yvstride=info->frame_height+2*OC_UMV_PADDING;
-+  chstride=yhstride>>!(info->pixel_fmt&1);
-+  cvstride=yvstride>>!(info->pixel_fmt&2);
-+  yplane_sz=(size_t)yhstride*yvstride;
-+  cplane_sz=(size_t)chstride*cvstride;
-+  memset(_dec->state.ref_frame_data,0x80,yplane_sz+2*cplane_sz);
-+}
-+
- int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op,
-  ogg_int64_t *_granpos){
-   int ret;
-   if(_dec==NULL||_op==NULL)return TH_EFAULT;
-   /*A completely empty packet indicates a dropped frame and is treated exactly
-      like an inter frame with no coded blocks.
-     Only proceed if we have a non-empty packet.*/
-   if(_op->bytes!=0){
-@@ -1869,37 +1893,19 @@ int th_decode_packetin(th_dec_ctx *_dec,
-     theorapackB_readinit(&_dec->opb,_op->packet,_op->bytes);
-     ret=oc_dec_frame_header_unpack(_dec);
-     if(ret<0)return ret;
-     /*Select a free buffer to use for the reconstructed version of this
-        frame.*/
-     if(_dec->state.frame_type!=OC_INTRA_FRAME&&
-      (_dec->state.ref_frame_idx[OC_FRAME_GOLD]<0||
-      _dec->state.ref_frame_idx[OC_FRAME_PREV]<0)){
--      th_info *info;
--      size_t       yplane_sz;
--      size_t       cplane_sz;
--      int          yhstride;
--      int          yvstride;
--      int          chstride;
--      int          cvstride;
--      /*We're decoding an INTER frame, but have no initialized reference
--         buffers (i.e., decoding did not start on a key frame).
--        We initialize them to a solid gray here.*/
--      _dec->state.ref_frame_idx[OC_FRAME_GOLD]=0;
--      _dec->state.ref_frame_idx[OC_FRAME_PREV]=0;
--      _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi=1;
--      info=&_dec->state.info;
--      yhstride=info->frame_width+2*OC_UMV_PADDING;
--      yvstride=info->frame_height+2*OC_UMV_PADDING;
--      chstride=yhstride>>!(info->pixel_fmt&1);
--      cvstride=yvstride>>!(info->pixel_fmt&2);
--      yplane_sz=(size_t)yhstride*yvstride;
--      cplane_sz=(size_t)chstride*cvstride;
--      memset(_dec->state.ref_frame_data,0x80,yplane_sz+2*cplane_sz);
-+      /*No reference frames yet!*/
-+      oc_dec_init_dummy_frame(_dec);
-+      refi=_dec->state.ref_frame_idx[OC_FRAME_SELF];
-     }
-     else{
-       for(refi=0;refi==_dec->state.ref_frame_idx[OC_FRAME_GOLD]||
-        refi==_dec->state.ref_frame_idx[OC_FRAME_PREV];refi++);
-       _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi;
-     }
-     if(_dec->state.frame_type==OC_INTRA_FRAME){
-       oc_dec_mark_all_intra(_dec);
-@@ -2036,16 +2042,26 @@ int th_decode_packetin(th_dec_ctx *_dec,
-     }
- #if defined(OC_DUMP_IMAGES)
-     /*Don't dump images for dropped frames.*/
-     oc_state_dump_frame(&_dec->state,OC_FRAME_SELF,"dec");
- #endif
-     return 0;
-   }
-   else{
-+    if(_dec->state.ref_frame_idx[OC_FRAME_GOLD]<0||
-+     _dec->state.ref_frame_idx[OC_FRAME_PREV]<0){
-+      int refi;
-+      /*No reference frames yet!*/
-+      oc_dec_init_dummy_frame(_dec);
-+      refi=_dec->state.ref_frame_idx[OC_FRAME_PREV];
-+      _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi;
-+      memcpy(_dec->pp_frame_buf,_dec->state.ref_frame_bufs[refi],
-+       sizeof(_dec->pp_frame_buf[0])*3);
-+    }
-     /*Just update the granule position and return.*/
-     _dec->state.granpos=
-      (_dec->state.keyframe_num<<_dec->state.info.keyframe_granule_shift)+
-      (_dec->state.curframe_num-_dec->state.keyframe_num);
-     _dec->state.curframe_num++;
-     if(_granpos!=NULL)*_granpos=_dec->state.granpos;
-     return TH_DUPFRAME;
-   }
--- a/media/libtheora/include/theora/Makefile.in
+++ b/media/libtheora/include/theora/Makefile.in
@@ -41,12 +41,13 @@ VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 EXPORTS_NAMESPACES = theora
 
 EXPORTS_theora = \
 		theora.h \
 		theoradec.h \
+		theoraenc.h \
 		codec.h \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/media/libtheora/include/theora/codec.h
+++ b/media/libtheora/include/theora/codec.h
@@ -1,16 +1,16 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
 
   function:
   last mod: $Id: theora.h,v 1.8 2004/03/15 22:17:32 derf Exp $
 
  ********************************************************************/
@@ -19,20 +19,20 @@
  * 
  * \section intro Introduction
  *
  * This is the documentation for <tt>libtheora</tt> C API.
  * The current reference
  * implementation for <a href="http://www.theora.org/">Theora</a>, a free,
  * patent-unencumbered video codec.
  * Theora is derived from On2's VP3 codec with additional features and
- *  integration for Ogg multimedia formats by
+ *  integration with Ogg multimedia formats by
  *  <a href="http://www.xiph.org/">the Xiph.Org Foundation</a>.
  * Complete documentation of the format itself is available in
- * <a href="http://www.theora.org/doc/Theora_I_spec.pdf">the Theora
+ * <a href="http://www.theora.org/doc/Theora.pdf">the Theora
  *  specification</a>.
  *
  * \subsection Organization
  *
  * The functions documented here are actually subdivided into three 
  * separate libraries:
  * - <tt>libtheoraenc</tt> contains the encoder interface,
  *   described in \ref encfuncs.
@@ -87,39 +87,39 @@ extern "C" {
 #define TH_EBADPACKET (-24)
 /**The decoded packet represented a dropped frame.
    The player can continue to display the current frame, as the contents of the
     decoded frame buffer have not changed.*/
 #define TH_DUPFRAME   (1)
 /*@}*/
 
 /**The currently defined color space tags.
- * See <a href="http://www.theora.org/doc/Theora_I_spec.pdf">the Theora
- *  specification</a>, Chapter 4, for exact details on the meaning of each of
- *  these color spaces.*/
+ * See <a href="http://www.theora.org/doc/Theora.pdf">the Theora
+ *  specification</a>, Chapter 4, for exact details on the meaning
+ *  of each of these color spaces.*/
 typedef enum{
   /**The color space was not specified at the encoder.
       It may be conveyed by an external means.*/
   TH_CS_UNSPECIFIED,
   /**A color space designed for NTSC content.*/
   TH_CS_ITU_REC_470M,
   /**A color space designed for PAL/SECAM content.*/
   TH_CS_ITU_REC_470BG,
   /**The total number of currently defined color spaces.*/
   TH_CS_NSPACES
 }th_colorspace;
 
 /**The currently defined pixel format tags.
- * See <a href="http://www.theora.org/doc/Theora_I_spec.pdf">the Theora
+ * See <a href="http://www.theora.org/doc/Theora.pdf">the Theora
  *  specification</a>, Section 4.4, for details on the precise sample
  *  locations.*/
 typedef enum{
   /**Chroma decimation by 2 in both the X and Y directions (4:2:0).
-     The Cb and Cr chroma planes are half the width and half the height of the
-      luma plane.*/
+     The Cb and Cr chroma planes are half the width and half the
+      height of the luma plane.*/
   TH_PF_420,
   /**Currently reserved.*/
   TH_PF_RSVD,
   /**Chroma decimation by 2 in the X direction (4:2:2).
      The Cb and Cr chroma planes are half the width of the luma plane, but full
       height.*/
   TH_PF_422,
   /**No chroma decimation (4:4:4).
@@ -128,46 +128,46 @@ typedef enum{
   /**The total number of currently defined pixel formats.*/
   TH_PF_NFORMATS
 }th_pixel_fmt;
 
 
 
 /**A buffer for a single color plane in an uncompressed image.
  * This contains the image data in a left-to-right, top-down format.
- * Each row of pixels is stored contiguously in memory, but successive rows
- *  need not be.
+ * Each row of pixels is stored contiguously in memory, but successive
+ *  rows need not be.
  * Use \a stride to compute the offset of the next row.
- * The encoder accepts both positive \a stride values (top-down in memory) and
- *  negative (bottom-up in memory).
+ * The encoder accepts both positive \a stride values (top-down in memory)
+ *  and negative (bottom-up in memory).
  * The decoder currently always generates images with positive strides.*/
 typedef struct{
   /**The width of this plane.*/
   int            width;
   /**The height of this plane.*/
   int            height;
   /**The offset in bytes between successive rows.*/
   int            stride;
   /**A pointer to the beginning of the first row.*/
   unsigned char *data;
 }th_img_plane;
 
 /**A complete image buffer for an uncompressed frame.
- * The chroma planes may be decimated by a factor of two in either direction,
- *  as indicated by th_info#pixel_fmt.
+ * The chroma planes may be decimated by a factor of two in either
+ *  direction, as indicated by th_info#pixel_fmt.
  * The width and height of the Y' plane must be multiples of 16.
- * They may need to be cropped for display, using the rectangle specified by
- *  th_info#pic_x, th_info#pic_y, th_info#pic_width, and
- *  th_info#pic_height.
+ * They may need to be cropped for display, using the rectangle
+ *  specified by th_info#pic_x, th_info#pic_y, th_info#pic_width,
+ *  and th_info#pic_height.
  * All samples are 8 bits.
  * \note The term YUV often used to describe a colorspace is ambiguous.
- * The exact parameters of the RGB to YUV conversion process aside, in many
- *  contexts the U and V channels actually have opposite meanings.
- * To avoid this confusion, we are explicit: the name of the color channels are
- *  Y'CbCr, and they appear in that order, always.
+ * The exact parameters of the RGB to YUV conversion process aside, in
+ *  many contexts the U and V channels actually have opposite meanings.
+ * To avoid this confusion, we are explicit: the name of the color
+ *  channels are Y'CbCr, and they appear in that order, always.
  * The prime symbol denotes that the Y channel is non-linear.
  * Cb and Cr stand for "Chroma blue" and "Chroma red", respectively.*/
 typedef th_img_plane th_ycbcr_buffer[3];
 
 /**Theora bitstream information.
  * This contains the basic playback parameters for a stream, and corresponds to 
  *  the initial 'info' header packet.
  * To initialize an encoder, the application fills in this structure and
@@ -187,17 +187,17 @@ typedef th_img_plane th_ycbcr_buffer[3];
  *  the cropped picture region, and the application does not need to fill them
  *  in.
  * The decoder <em>will</em> allocate storage for a full frame, but the
  *  application <em>should not</em> rely on the padding containing sensible
  *  data.
  *
  * It is also generally recommended that the offsets and sizes should still be
  *  multiples of 2 to avoid chroma sampling shifts when chroma is sub-sampled.
- * See <a href="http://www.theora.org/doc/Theora_I_spec.pdf">the Theora
+ * See <a href="http://www.theora.org/doc/Theora.pdf">the Theora
  *  specification</a>, Section 4.4, for more details.
  *
  * Frame rate, in frames per second, is stored as a rational fraction, as is
  *  the pixel aspect ratio.
  * Note that this refers to the aspect ratio of the individual pixels, not of
  *  the overall frame itself.
  * The frame aspect ratio can be computed from pixel aspect ratio using the
  *  image dimensions.*/
@@ -225,18 +225,18 @@ typedef struct{
    * This must be no larger than #frame_width-#pic_width or 255, whichever is
    *  smaller.*/
   ogg_uint32_t  pic_x;
   /**The Y offset of the displayed picture.
    * This must be no larger than #frame_height-#pic_height, and
    *  #frame_height-#pic_height-#pic_y must be no larger than 255.
    * This slightly funny restriction is due to the fact that the offset is
    *  specified from the top of the image for consistency with the standard
-   *  graphics left-handed coordinate system used throughout this API, while it
-   *  is stored in the encoded stream as an offset from the bottom.*/
+   *  graphics left-handed coordinate system used throughout this API, while
+   *  it is stored in the encoded stream as an offset from the bottom.*/
   ogg_uint32_t  pic_y;
   /**\name Frame rate
    * The frame rate, as a fraction.
    * If either is 0, the frame rate is undefined.*/
   /*@{*/
   ogg_uint32_t  fps_numerator;
   ogg_uint32_t  fps_denominator;
   /*@}*/
@@ -254,19 +254,16 @@ typedef struct{
   /*@}*/
   /**The color space.*/
   th_colorspace colorspace;
   /**The pixel format.*/
   th_pixel_fmt  pixel_fmt;
   /**The target bit-rate in bits per second.
      If initializing an encoder with this struct, set this field to a non-zero
       value to activate CBR encoding by default.*/
-  /*TODO: Current encoder does not support CBR mode, or anything like it.
-    We also don't really know what nominal rate each quality level
-     corresponds to yet.*/
   int           target_bitrate;
   /**The target quality level.
      Valid values range from 0 to 63, inclusive, with higher values giving
       higher quality.
      If initializing an encoder with this struct, and #target_bitrate is set
       to zero, VBR encoding at this quality will be activated by default.*/
   /*Currently this is set so that a qi of 0 corresponds to distortions of 24
      times the JND, and each increase by 16 halves that value.
@@ -309,17 +306,17 @@ typedef struct{
  *  words, but not more than a short paragraph.
  *
  * The metadata is stored as a series of (tag, value) pairs, in
  *  length-encoded string vectors.
  * The first occurrence of the '=' character delimits the tag and value.
  * A particular tag may occur more than once, and order is significant.
  * The character set encoding for the strings is always UTF-8, but the tag
  *  names are limited to ASCII, and treated as case-insensitive.
- * See <a href="http://www.theora.org/doc/Theora_I_spec.pdf">the Theora
+ * See <a href="http://www.theora.org/doc/Theora.pdf">the Theora
  *  specification</a>, Section 6.3.3 for details.
  *
  * In filling in this structure, th_decode_headerin() will null-terminate
  *  the user_comment strings for safety.
  * However, the bitstream format itself treats them as 8-bit clean vectors,
  *  possibly containing null characters, and so the length array should be
  *  treated as their authoritative length.
  */
--- a/media/libtheora/include/theora/config.h
+++ b/media/libtheora/include/theora/config.h
@@ -1,11 +1,14 @@
 /* config.h.  Generated from config.h.in by configure.  */
 /* config.h.in.  Generated from configure.ac by autoheader.  */
 
+/* libcairo is available for visual debugging output */
+/* #undef HAVE_CAIRO */
+
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #define HAVE_DLFCN_H 1
 
 /* Define to 1 if you have the <inttypes.h> header file. */
 #define HAVE_INTTYPES_H 1
 
 /* Define to 1 if you have the <machine/soundcard.h> header file. */
 /* #undef HAVE_MACHINE_SOUNDCARD_H */
@@ -24,57 +27,64 @@
 
 /* Define to 1 if you have the <strings.h> header file. */
 #define HAVE_STRINGS_H 1
 
 /* Define to 1 if you have the <string.h> header file. */
 #define HAVE_STRING_H 1
 
 /* Define to 1 if you have the <sys/soundcard.h> header file. */
-#define HAVE_SYS_SOUNDCARD_H 1
+/* #undef HAVE_SYS_SOUNDCARD_H */
 
 /* Define to 1 if you have the <sys/stat.h> header file. */
 #define HAVE_SYS_STAT_H 1
 
 /* Define to 1 if you have the <sys/types.h> header file. */
 #define HAVE_SYS_TYPES_H 1
 
 /* Define to 1 if you have the <unistd.h> header file. */
 #define HAVE_UNISTD_H 1
 
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#define LT_OBJDIR ".libs/"
+
 /* Define to 1 if your C compiler doesn't accept -c and -o together. */
 /* #undef NO_MINUS_C_MINUS_O */
 
-/* enable x86 assambler optimization */
- 
+/* make use of x86_64 asm optimization */
+/* #undef OC_X86_64_ASM */
+
+/* make use of x86 asm optimization */
+ /**/
 
 /* Name of package */
 #define PACKAGE "libtheora"
 
 /* Define to the address where bug reports for this package should be sent. */
 #define PACKAGE_BUGREPORT ""
 
 /* Define to the full name of this package. */
 #define PACKAGE_NAME "libtheora"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "libtheora 1.0"
+#define PACKAGE_STRING "libtheora 1.1.0"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "libtheora"
 
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "1.0"
+#define PACKAGE_VERSION "1.1.0"
 
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
 /* Define to exclude encode support from the build */
 /* #undef THEORA_DISABLE_ENCODE */
 
 /* Define to exclude floating point code from the build */
 /* #undef THEORA_DISABLE_FLOAT */
 
-/* make use of asm optimization */
- 
-
 /* Version number of package */
-#define VERSION "1.0"
+#define VERSION "1.1.0"
--- a/media/libtheora/include/theora/theora.h
+++ b/media/libtheora/include/theora/theora.h
@@ -1,16 +1,16 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
 
   function:
   last mod: $Id: theora.h,v 1.17 2003/12/06 18:06:19 arc Exp $
 
  ********************************************************************/
@@ -22,32 +22,32 @@
 extern "C"
 {
 #endif /* __cplusplus */
 
 #include <stddef.h>	/* for size_t */
 
 #include <ogg/ogg.h>
 
-/** \defgroup oldfuncs Legacy pre-1.0 C API */
-/*  @{ */
-
-/** \mainpage
- * 
+/** \file
+ * The libtheora pre-1.0 legacy C API.
+ *
+ * \ingroup oldfuncs
+ *
  * \section intro Introduction
  *
  * This is the documentation for the libtheora legacy C API, declared in 
  * the theora.h header, which describes the old interface used before
  * the 1.0 release. This API was widely deployed for several years and
  * remains supported, but for new code we recommend the cleaner API 
  * declared in theoradec.h and theoraenc.h.
  *
  * libtheora is the reference implementation for
  * <a href="http://www.theora.org/">Theora</a>, a free video codec.
- * Theora is derived from On2's VP3 codec with improved integration for
+ * Theora is derived from On2's VP3 codec with improved integration with
  * Ogg multimedia formats by <a href="http://www.xiph.org/">Xiph.Org</a>.
  * 
  * \section overview Overview
  *
  * This library will both decode and encode theora packets to/from raw YUV 
  * frames.  In either case, the packets will most likely either come from or
  * need to be embedded in an Ogg stream.  Use 
  * <a href="http://xiph.org/ogg/">libogg</a> or 
@@ -109,31 +109,21 @@ extern "C"
  *  - once you have found a theora b_o_s page then use the retrieved serial_no 
  *    to identify future packets belonging to the same theora stream.
  * 
  * Note that you \e cannot use theora_packet_isheader() to determine if a 
  * packet is a theora packet or not, as this function does not perform any
  * checking beyond whether a header bit is present.  Instead, use the
  * theora_decode_header() function and check the return value; or examine the
  * header bytes at the beginning of the Ogg page.
- *
- * \subsection example Example Decoder 
- *
- * See <a href="http://svn.xiph.org/trunk/theora/examples/dump_video.c">
- * examples/dump_video.c</a> for a simple decoder implementation.
- *
- * \section encoding Encoding Process
- *
- * See <a href="http://svn.xiph.org/trunk/theora/examples/encoder_example.c">
- * examples/encoder_example.c</a> for a simple encoder implementation.
  */
 
-/** \file
- * The libtheora pre-1.0 legacy C API.
- */
+
+/** \defgroup oldfuncs Legacy pre-1.0 C API */
+/*  @{ */
 
 /**
  * A YUV buffer for passing uncompressed frames to and from the codec.
  * This holds a Y'CbCr frame in planar format. The CbCr planes can be
  * subsampled and have their own separate dimensions and row stride
  * offsets. Note that the strides may be negative in some 
  * configurations. For theora the width and height of the largest plane
  * must be a multiple of 16. The actual meaningful picture size and 
@@ -287,24 +277,31 @@ typedef struct theora_comment{
   int   *comment_lengths;       /**< An array of corresponding string vector lengths in bytes */
   int    comments;              /**< The total number of comment string vectors */
   char  *vendor;                /**< The vendor string identifying the encoder, null terminated */
 
 } theora_comment;
 
 
 /**\name theora_control() codes */
-
-/**\anchor decctlcodes
+/* \anchor decctlcodes_old
  * These are the available request codes for theora_control()
  * when called with a decoder instance.
- * By convention, these are odd, to distinguish them from the
- *  \ref encctlcodes "encoder control codes".
+ * By convention decoder control codes are odd, to distinguish 
+ * them from \ref encctlcodes_old "encoder control codes" which
+ * are even.
+ *
+ * Note that since the 1.0 release, both the legacy and the final
+ * implementation accept all the same control codes, but only the
+ * final API declares the newer codes.
+ *
  * Keep any experimental or vendor-specific values above \c 0x8000.*/
 
+/*@{*/
+
 /**Get the maximum post-processing level.
  * The decoder supports a post-processing filter that can improve
  * the appearance of the decoded images. This returns the highest
  * level setting for this post-processor, corresponding to maximum
  * improvement and computational expense.
  */
 #define TH_DECCTL_GET_PPLEVEL_MAX (1)
 
@@ -319,57 +316,47 @@ typedef struct theora_comment{
  * This can be changed during an encode, but will be bounded by
  *  <tt>1<<th_info#keyframe_granule_shift</tt>.
  * If it is set before encoding begins, th_info#keyframe_granule_shift will
  *  be enlarged appropriately.
  *
  * \param[in]  buf <tt>ogg_uint32_t</tt>: The maximum distance between key
  *                   frames.
  * \param[out] buf <tt>ogg_uint32_t</tt>: The actual maximum distance set.
- * \retval TH_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
- * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(ogg_uint32_t)</tt>.
- * \retval TH_IMPL   Not supported by this implementation.*/
+ * \retval OC_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
+ * \retval OC_EINVAL \a buf_sz is not <tt>sizeof(ogg_uint32_t)</tt>.
+ * \retval OC_IMPL   Not supported by this implementation.*/
 #define TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE (4)
 
 /**Set the granule position.
  * Call this after a seek, to update the internal granulepos
  * in the decoder, to insure that subsequent frames are marked
  * properly. If you track timestamps yourself and do not use
  * the granule postion returned by the decoder, then you do
  * not need to use this control.
  */
 #define TH_DECCTL_SET_GRANPOS (5)
 
+/**\anchor encctlcodes_old */
 
-/**\anchor encctlcodes
- * These are the available request codes for theora_control()
- * when called with an encoder instance.
- * By convention, these are even, to distinguish them from the
- *  \ref decctlcodes "decoder control codes".
- * Keep any experimental or vendor-specific values above \c 0x8000.*/
-/*@{*/
 /**Sets the quantization parameters to use.
  * The parameters are copied, not stored by reference, so they can be freed
  *  after this call.
  * <tt>NULL</tt> may be specified to revert to the default parameters.
- * For the current encoder, <tt>scale[ci!=0][qi]</tt> must be no greater than
- *  <tt>scale[ci!=0][qi-1]</tt> and <tt>base[qti][pli][qi][ci]</tt> must be no
- *  greater than <tt>base[qti][pli][qi-1][ci]</tt>.
- * These two conditions ensure that the actual quantizer for a given \a qti,
- *  \a pli, and \a ci does not increase as \a qi increases.
  *
  * \param[in] buf #th_quant_info
- * \retval TH_FAULT  \a theora_state is <tt>NULL</tt>.
- * \retval TH_EINVAL Encoding has already begun, the quantization parameters
- *                    do not meet one of the above stated conditions, \a buf
- *                    is <tt>NULL</tt> and \a buf_sz is not zero, or \a buf
- *                    is non-<tt>NULL</tt> and \a buf_sz is not
- *                    <tt>sizeof(#th_quant_info)</tt>.
- * \retval TH_IMPL   Not supported by this implementation.*/
+ * \retval OC_FAULT  \a theora_state is <tt>NULL</tt>.
+ * \retval OC_EINVAL Encoding has already begun, the quantization parameters
+ *                    are not acceptable to this version of the encoder, 
+ *                    \a buf is <tt>NULL</tt> and \a buf_sz is not zero, 
+ *                    or \a buf is non-<tt>NULL</tt> and \a buf_sz is 
+ *                    not <tt>sizeof(#th_quant_info)</tt>.
+ * \retval OC_IMPL   Not supported by this implementation.*/
 #define TH_ENCCTL_SET_QUANT_PARAMS (2)
+
 /**Disables any encoder features that would prevent lossless transcoding back
  *  to VP3.
  * This primarily means disabling block-level QI values and not using 4MV mode
  *  when any of the luma blocks in a macro block are not coded.
  * It also includes using the VP3 quantization tables and Huffman codes; if you
  *  set them explicitly after calling this function, the resulting stream will
  *  not be VP3-compatible.
  * If you enable VP3-compatibility when encoding 4:2:2 or 4:4:4 source
@@ -384,48 +371,51 @@ typedef struct theora_comment{
  * \param[in]  buf <tt>int</tt>: a non-zero value to enable VP3 compatibility,
  *                   or 0 to disable it (the default).
  * \param[out] buf <tt>int</tt>: 1 if all bitstream features required for
  *                   VP3-compatibility could be set, and 0 otherwise.
  *                  The latter will be returned if the pixel format is not
  *                   4:2:0, the picture region is smaller than the full frame,
  *                   or if encoding has begun, preventing the quantization
  *                   tables and codebooks from being set.
- * \retval TH_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
- * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>.
- * \retval TH_IMPL   Not supported by this implementation.*/
+ * \retval OC_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
+ * \retval OC_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval OC_IMPL   Not supported by this implementation.*/
 #define TH_ENCCTL_SET_VP3_COMPATIBLE (10)
+
 /**Gets the maximum speed level.
  * Higher speed levels favor quicker encoding over better quality per bit.
  * Depending on the encoding mode, and the internal algorithms used, quality
  *  may actually improve, but in this case bitrate will also likely increase.
  * In any case, overall rate/distortion performance will probably decrease.
  * The maximum value, and the meaning of each value, may change depending on
  *  the current encoding mode (VBR vs. CQI, etc.).
  *
  * \param[out] buf int: The maximum encoding speed level.
- * \retval TH_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
- * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>.
- * \retval TH_IMPL   Not supported by this implementation in the current
+ * \retval OC_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
+ * \retval OC_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval OC_IMPL   Not supported by this implementation in the current
  *                    encoding mode.*/
 #define TH_ENCCTL_GET_SPLEVEL_MAX (12)
+
 /**Sets the speed level.
  * By default a speed value of 1 is used.
  *
  * \param[in] buf int: The new encoding speed level.
  *                      0 is slowest, larger values use less CPU.
- * \retval TH_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
- * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>, or the
+ * \retval OC_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
+ * \retval OC_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>, or the
  *                    encoding speed level is out of bounds.
  *                   The maximum encoding speed level may be
  *                    implementation- and encoding mode-specific, and can be
  *                    obtained via #TH_ENCCTL_GET_SPLEVEL_MAX.
- * \retval TH_IMPL   Not supported by this implementation in the current
+ * \retval OC_IMPL   Not supported by this implementation in the current
  *                    encoding mode.*/
 #define TH_ENCCTL_SET_SPLEVEL (14)
+
 /*@}*/
 
 #define OC_FAULT       -1       /**< General failure */
 #define OC_EINVAL      -10      /**< Library encountered invalid internal data */
 #define OC_DISABLED    -11      /**< Requested action is disabled */
 #define OC_BADHEADER   -20      /**< Header packet was corrupt/invalid */
 #define OC_NOTFORMAT   -21      /**< Packet is not a theora packet */
 #define OC_VERSION     -22      /**< Bitstream version is not handled */
@@ -774,18 +764,18 @@ extern int   theora_comment_query_count(
  * \param tc An allocated theora_comment structure.
  **/
 extern void  theora_comment_clear(theora_comment *tc);
 
 /**Encoder control function.
  * This is used to provide advanced control the encoding process.
  * \param th     A #theora_state handle.
  * \param req    The control code to process.
- *                See \ref encctlcodes "the list of available control codes"
- *                 for details.
+ *                See \ref encctlcodes_old "the list of available 
+ *			control codes" for details.
  * \param buf    The parameters for this control code.
  * \param buf_sz The size of the parameter buffer.*/
 extern int theora_control(theora_state *th,int req,void *buf,size_t buf_sz);
 
 /* @} */ /* end oldfuncs doxygen group */
 
 #ifdef __cplusplus
 }
--- a/media/libtheora/include/theora/theoradec.h
+++ b/media/libtheora/include/theora/theoradec.h
@@ -1,16 +1,16 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
 
   function:
   last mod: $Id: theora.h,v 1.8 2004/03/15 22:17:32 derf Exp $
 
  ********************************************************************/
@@ -33,25 +33,33 @@ extern "C" {
 /**\name th_decode_ctl() codes
  * \anchor decctlcodes
  * These are the available request codes for th_decode_ctl().
  * By convention, these are odd, to distinguish them from the
  *  \ref encctlcodes "encoder control codes".
  * Keep any experimental or vendor-specific values above \c 0x8000.*/
 /*@{*/
 /**Gets the maximum post-processing level.
+ * The decoder supports a post-processing filter that can improve
+ * the appearance of the decoded images. This returns the highest
+ * level setting for this post-processor, corresponding to maximum
+ * improvement and computational expense.
  *
  * \param[out] _buf int: The maximum post-processing level.
  * \retval TH_EFAULT  \a _dec_ctx or \a _buf is <tt>NULL</tt>.
  * \retval TH_EINVAL  \a _buf_sz is not <tt>sizeof(int)</tt>.
  * \retval TH_EIMPL   Not supported by this implementation.*/
 #define TH_DECCTL_GET_PPLEVEL_MAX (1)
 /**Sets the post-processing level.
  * By default, post-processing is disabled.
  *
+ * Sets the level of post-processing to use when decoding the
+ * compressed stream. This must be a value between zero (off)
+ * and the maximum returned by TH_DECCTL_GET_PPLEVEL_MAX.
+ *
  * \param[in] _buf int: The new post-processing level.
  *                      0 to disable; larger values use more CPU.
  * \retval TH_EFAULT  \a _dec_ctx or \a _buf is <tt>NULL</tt>.
  * \retval TH_EINVAL  \a _buf_sz is not <tt>sizeof(int)</tt>, or the
  *                     post-processing level is out of bounds.
  *                    The maximum post-processing level may be
  *                     implementation-specific, and can be obtained via
  *                     #TH_DECCTL_GET_PPLEVEL_MAX.
@@ -78,16 +86,25 @@ extern "C" {
  * Enabling striped decode does not prevent you from calling
  *  th_decode_ycbcr_out() after the frame is fully decoded.
  *
  * \param[in]  _buf #th_stripe_callback: The callback parameters.
  * \retval TH_EFAULT  \a _dec_ctx or \a _buf is <tt>NULL</tt>.
  * \retval TH_EINVAL  \a _buf_sz is not
  *                     <tt>sizeof(th_stripe_callback)</tt>.*/
 #define TH_DECCTL_SET_STRIPE_CB (7)
+
+/**Enables telemetry and sets the macroblock display mode */
+#define TH_DECCTL_SET_TELEMETRY_MBMODE (9)
+/**Enables telemetry and sets the motion vector display mode */
+#define TH_DECCTL_SET_TELEMETRY_MV (11)
+/**Enables telemetry and sets the adaptive quantization display mode */
+#define TH_DECCTL_SET_TELEMETRY_QI (13)
+/**Enables telemetry and sets the bitstream breakdown visualization mode */
+#define TH_DECCTL_SET_TELEMETRY_BITS (15)
 /*@}*/
 
 
 
 /**A callback function for striped decode.
  * This is a function pointer to an application-provided function that will be
  *  called each time a section of the image is fully decoded in
  *  th_decode_packetin().
@@ -284,16 +301,17 @@ extern int th_decode_packetin(th_dec_ctx
  *               <tt>libtheoradec</tt> will fill in all the members of this
  *                structure, including the pointers to the uncompressed video
  *                data.
  *               The memory for this video data is owned by
  *                <tt>libtheoradec</tt>.
  *               It may be freed or overwritten without notification when
  *                subsequent frames are decoded.
  * \retval 0 Success
+ * \retval TH_EFAULT     \a _dec or \a _ycbcr was <tt>NULL</tt>.
  */
 extern int th_decode_ycbcr_out(th_dec_ctx *_dec,
  th_ycbcr_buffer _ycbcr);
 /**Frees an allocated decoder instance.
  * \param _dec A #th_dec_ctx handle.*/
 extern void th_decode_free(th_dec_ctx *_dec);
 /*@}*/
 /*@}*/
new file mode 100644
--- /dev/null
+++ b/media/libtheora/include/theora/theoraenc.h
@@ -0,0 +1,486 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * 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-2009                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+  last mod: $Id: theora.h,v 1.8 2004/03/15 22:17:32 derf Exp $
+
+ ********************************************************************/
+
+/**\file
+ * The <tt>libtheoraenc</tt> C encoding API.*/
+
+#if !defined(_O_THEORA_THEORAENC_H_)
+# define _O_THEORA_THEORAENC_H_ (1)
+# include <stddef.h>
+# include <ogg/ogg.h>
+# include "codec.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+
+/**\name th_encode_ctl() codes
+ * \anchor encctlcodes
+ * These are the available request codes for th_encode_ctl().
+ * By convention, these are even, to distinguish them from the
+ *  \ref decctlcodes "decoder control codes".
+ * Keep any experimental or vendor-specific values above \c 0x8000.*/
+/*@{*/
+/**Sets the Huffman tables to use.
+ * The tables are copied, not stored by reference, so they can be freed after
+ *  this call.
+ * <tt>NULL</tt> may be specified to revert to the default tables.
+ *
+ * \param[in] _buf <tt>#th_huff_code[#TH_NHUFFMAN_TABLES][#TH_NDCT_TOKENS]</tt>
+ * \retval TH_EFAULT \a _enc_ctx is <tt>NULL</tt>.
+ * \retval TH_EINVAL Encoding has already begun or one or more of the given
+ *                     tables is not full or prefix-free, \a _buf is
+ *                     <tt>NULL</tt> and \a _buf_sz is not zero, or \a _buf is
+ *                     non-<tt>NULL</tt> and \a _buf_sz is not
+ *                     <tt>sizeof(#th_huff_code)*#TH_NHUFFMAN_TABLES*#TH_NDCT_TOKENS</tt>.
+ * \retval TH_EIMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_HUFFMAN_CODES (0)
+/**Sets the quantization parameters to use.
+ * The parameters are copied, not stored by reference, so they can be freed
+ *  after this call.
+ * <tt>NULL</tt> may be specified to revert to the default parameters.
+ *
+ * \param[in] _buf #th_quant_info
+ * \retval TH_EFAULT \a _enc_ctx is <tt>NULL</tt>.
+ * \retval TH_EINVAL Encoding has already begun, \a _buf is 
+ *                    <tt>NULL</tt> and \a _buf_sz is not zero,
+ *                    or \a _buf is non-<tt>NULL</tt> and
+ *                    \a _buf_sz is not <tt>sizeof(#th_quant_info)</tt>.
+ * \retval TH_EIMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_QUANT_PARAMS (2)
+/**Sets the maximum distance between key frames.
+ * This can be changed during an encode, but will be bounded by
+ *  <tt>1<<th_info#keyframe_granule_shift</tt>.
+ * If it is set before encoding begins, th_info#keyframe_granule_shift will
+ *  be enlarged appropriately.
+ *
+ * \param[in]  _buf <tt>ogg_uint32_t</tt>: The maximum distance between key
+ *                   frames.
+ * \param[out] _buf <tt>ogg_uint32_t</tt>: The actual maximum distance set.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(ogg_uint32_t)</tt>.
+ * \retval TH_EIMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE (4)
+/**Disables any encoder features that would prevent lossless transcoding back
+ *  to VP3.
+ * This primarily means disabling block-adaptive quantization and always coding
+ *  all four luma blocks in a macro block when 4MV is used.
+ * It also includes using the VP3 quantization tables and Huffman codes; if you
+ *  set them explicitly after calling this function, the resulting stream will
+ *  not be VP3-compatible.
+ * If you enable VP3-compatibility when encoding 4:2:2 or 4:4:4 source
+ *  material, or when using a picture region smaller than the full frame (e.g.
+ *  a non-multiple-of-16 width or height), then non-VP3 bitstream features will
+ *  still be disabled, but the stream will still not be VP3-compatible, as VP3
+ *  was not capable of encoding such formats.
+ * If you call this after encoding has already begun, then the quantization
+ *  tables and codebooks cannot be changed, but the frame-level features will
+ *  be enabled or disabled as requested.
+ *
+ * \param[in]  _buf <tt>int</tt>: a non-zero value to enable VP3 compatibility,
+ *                   or 0 to disable it (the default).
+ * \param[out] _buf <tt>int</tt>: 1 if all bitstream features required for
+ *                   VP3-compatibility could be set, and 0 otherwise.
+ *                  The latter will be returned if the pixel format is not
+ *                   4:2:0, the picture region is smaller than the full frame,
+ *                   or if encoding has begun, preventing the quantization
+ *                   tables and codebooks from being set.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval TH_EIMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_VP3_COMPATIBLE (10)
+/**Gets the maximum speed level.
+ * Higher speed levels favor quicker encoding over better quality per bit.
+ * Depending on the encoding mode, and the internal algorithms used, quality
+ *  may actually improve, but in this case bitrate will also likely increase.
+ * In any case, overall rate/distortion performance will probably decrease.
+ * The maximum value, and the meaning of each value, may change depending on
+ *  the current encoding mode (VBR vs. constant quality, etc.).
+ *
+ * \param[out] _buf <tt>int</tt>: The maximum encoding speed level.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval TH_EIMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_GET_SPLEVEL_MAX (12)
+/**Sets the speed level.
+ * The current speed level may be retrieved using #TH_ENCCTL_GET_SPLEVEL.
+ *
+ * \param[in] _buf <tt>int</tt>: The new encoding speed level.
+ *                 0 is slowest, larger values use less CPU.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>, or the
+ *                    encoding speed level is out of bounds.
+ *                   The maximum encoding speed level may be
+ *                    implementation- and encoding mode-specific, and can be
+ *                    obtained via #TH_ENCCTL_GET_SPLEVEL_MAX.
+ * \retval TH_EIMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_SET_SPLEVEL (14)
+/**Gets the current speed level.
+ * The default speed level may vary according to encoder implementation, but if
+ *  this control code is not supported (it returns #TH_EIMPL), the default may
+ *  be assumed to be the slowest available speed (0).
+ * The maximum encoding speed level may be implementation- and encoding
+ *  mode-specific, and can be obtained via #TH_ENCCTL_GET_SPLEVEL_MAX.
+ *
+ * \param[out] _buf <tt>int</tt>: The current encoding speed level.
+ *                  0 is slowest, larger values use less CPU.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval TH_EIMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_GET_SPLEVEL (16)
+/**Sets the number of duplicates of the next frame to produce.
+ * Although libtheora can encode duplicate frames very cheaply, it costs some
+ *  amount of CPU to detect them, and a run of duplicates cannot span a
+ *  keyframe boundary.
+ * This control code tells the encoder to produce the specified number of extra
+ *  duplicates of the next frame.
+ * This allows the encoder to make smarter keyframe placement decisions and
+ *  rate control decisions, and reduces CPU usage as well, when compared to
+ *  just submitting the same frame for encoding multiple times.
+ * This setting only applies to the next frame submitted for encoding.
+ * You MUST call th_encode_packetout() repeatedly until it returns 0, or the
+ *  extra duplicate frames will be lost.
+ *
+ * \param[in] _buf <tt>int</tt>: The number of duplicates to produce.
+ *                 If this is negative or zero, no duplicates will be produced.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>, or the
+ *                    number of duplicates is greater than or equal to the
+ *                    maximum keyframe interval.
+ *                   In the latter case, NO duplicate frames will be produced.
+ *                   You must ensure that the maximum keyframe interval is set
+ *                    larger than the maximum number of duplicates you will
+ *                    ever wish to insert prior to encoding.
+ * \retval TH_EIMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_SET_DUP_COUNT (18)
+/**Modifies the default bitrate management behavior.
+ * Use to allow or disallow frame dropping, and to enable or disable capping
+ *  bit reservoir overflows and underflows.
+ * See \ref encctlcodes "the list of available flags".
+ * The flags are set by default to
+ *  <tt>#TH_RATECTL_DROP_FRAMES|#TH_RATECTL_CAP_OVERFLOW</tt>.
+ *
+ * \param[in] _buf <tt>int</tt>: Any combination of
+ *                  \ref ratectlflags "the available flags":
+ *                 - #TH_RATECTL_DROP_FRAMES: Enable frame dropping.
+ *                 - #TH_RATECTL_CAP_OVERFLOW: Don't bank excess bits for later
+ *                    use.
+ *                 - #TH_RATECTL_CAP_UNDERFLOW: Don't try to make up shortfalls
+ *                    later.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt> or rate control
+ *                    is not enabled.
+ * \retval TH_EIMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_SET_RATE_FLAGS (20)
+/**Sets the size of the bitrate management bit reservoir as a function
+ *  of number of frames.
+ * The reservoir size affects how quickly bitrate management reacts to
+ *  instantaneous changes in the video complexity.
+ * Larger reservoirs react more slowly, and provide better overall quality, but
+ *  require more buffering by a client, adding more latency to live streams.
+ * By default, libtheora sets the reservoir to the maximum distance between
+ *  keyframes, subject to a minimum and maximum limit.
+ * This call may be used to increase or decrease the reservoir, increasing or
+ *  decreasing the allowed temporary variance in bitrate.
+ * An implementation may impose some limits on the size of a reservoir it can
+ *  handle, in which case the actual reservoir size may not be exactly what was
+ *  requested.
+ * The actual value set will be returned.
+ *
+ * \param[in]  _buf <tt>int</tt>: Requested size of the reservoir measured in
+ *                   frames.
+ * \param[out] _buf <tt>int</tt>: The actual size of the reservoir set.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>, or rate control
+ *                    is not enabled.  The buffer has an implementation
+ *                    defined minimum and maximum size and the value in _buf
+ *                    will be adjusted to match the actual value set.
+ * \retval TH_EIMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_SET_RATE_BUFFER (22)
+/**Enable pass 1 of two-pass encoding mode and retrieve the first pass metrics.
+ * Pass 1 mode must be enabled before the first frame is encoded, and a target
+ *  bitrate must have already been specified to the encoder.
+ * Although this does not have to be the exact rate that will be used in the
+ *  second pass, closer values may produce better results.
+ * The first call returns the size of the two-pass header data, along with some
+ *  placeholder content, and sets the encoder into pass 1 mode implicitly.
+ * This call sets the encoder to pass 1 mode implicitly.
+ * Then, a subsequent call must be made after each call to
+ *  th_encode_ycbcr_in() to retrieve the metrics for that frame.
+ * An additional, final call must be made to retrieve the summary data,
+ *  containing such information as the total number of frames, etc.
+ * This must be stored in place of the placeholder data that was returned
+ *  in the first call, before the frame metrics data.
+ * All of this data must be presented back to the encoder during pass 2 using
+ *  #TH_ENCCTL_2PASS_IN.
+ *
+ * \param[out] <tt>char *</tt>_buf: Returns a pointer to internal storage
+ *              containing the two pass metrics data.
+ *             This storage is only valid until the next call, or until the
+ *              encoder context is freed, and must be copied by the
+ *              application.
+ * \retval >=0       The number of bytes of metric data available in the
+ *                    returned buffer.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(char *)</tt>, no target
+ *                    bitrate has been set, or the first call was made after
+ *                    the first frame was submitted for encoding.
+ * \retval TH_EIMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_2PASS_OUT (24)
+/**Submits two-pass encoding metric data collected the first encoding pass to
+ *  the second pass.
+ * The first call must be made before the first frame is encoded, and a target
+ *  bitrate must have already been specified to the encoder.
+ * It sets the encoder to pass 2 mode implicitly; this cannot be disabled.
+ * The encoder may require reading data from some or all of the frames in
+ *  advance, depending on, e.g., the reservoir size used in the second pass.
+ * You must call this function repeatedly before each frame to provide data
+ *  until either a) it fails to consume all of the data presented or b) all of
+ *  the pass 1 data has been consumed.
+ * In the first case, you must save the remaining data to be presented after
+ *  the next frame.
+ * You can call this function with a NULL argument to get an upper bound on
+ *  the number of bytes that will be required before the next frame.
+ *
+ * When pass 2 is first enabled, the default bit reservoir is set to the entire
+ *  file; this gives maximum flexibility but can lead to very high peak rates.
+ * You can subsequently set it to another value with #TH_ENCCTL_SET_RATE_BUFFER
+ *  (e.g., to set it to the keyframe interval for non-live streaming), however,
+ *  you may then need to provide more data before the next frame.
+ *
+ * \param[in] _buf <tt>char[]</tt>: A buffer containing the data returned by
+ *                  #TH_ENCCTL_2PASS_OUT in pass 1.
+ *                 You may pass <tt>NULL</tt> for \a _buf to return an upper
+ *                  bound on the number of additional bytes needed before the
+ *                  next frame.
+ *                 The summary data returned at the end of pass 1 must be at
+ *                  the head of the buffer on the first call with a
+ *                  non-<tt>NULL</tt> \a _buf, and the placeholder data
+ *                  returned at the start of pass 1 should be omitted.
+ *                 After each call you should advance this buffer by the number
+ *                  of bytes consumed.
+ * \retval >0            The number of bytes of metric data required/consumed.
+ * \retval 0             No more data is required before the next frame.
+ * \retval TH_EFAULT     \a _enc_ctx is <tt>NULL</tt>.
+ * \retval TH_EINVAL     No target bitrate has been set, or the first call was
+ *                        made after the first frame was submitted for
+ *                        encoding.
+ * \retval TH_ENOTFORMAT The data did not appear to be pass 1 from a compatible
+ *                        implementation of this library.
+ * \retval TH_EBADHEADER The data was invalid; this may be returned when
+ *                        attempting to read an aborted pass 1 file that still
+ *                        has the placeholder data in place of the summary
+ *                        data.
+ * \retval TH_EIMPL       Not supported by this implementation.*/
+#define TH_ENCCTL_2PASS_IN (26)
+/**Sets the current encoding quality.
+ * This is only valid so long as no bitrate has been specified, either through
+ *  the #th_info struct used to initialize the encoder or through
+ *  #TH_ENCCTL_SET_BITRATE (this restriction may be relaxed in a future
+ *  version).
+ * If it is set before the headers are emitted, the target quality encoded in
+ *  them will be updated.
+ *
+ * \param[in] _buf <tt>int</tt>: The new target quality, in the range 0...63,
+ *                  inclusive.
+ * \retval 0             Success.
+ * \retval TH_EFAULT     \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL     A target bitrate has already been specified, or the
+ *                        quality index was not in the range 0...63.
+ * \retval TH_EIMPL       Not supported by this implementation.*/
+#define TH_ENCCTL_SET_QUALITY (28)
+/**Sets the current encoding bitrate.
+ * Once a bitrate is set, the encoder must use a rate-controlled mode for all
+ *  future frames (this restriction may be relaxed in a future version).
+ * If it is set before the headers are emitted, the target bitrate encoded in
+ *  them will be updated.
+ * Due to the buffer delay, the exact bitrate of each section of the encode is
+ *  not guaranteed.
+ * The encoder may have already used more bits than allowed for the frames it
+ *  has encoded, expecting to make them up in future frames, or it may have
+ *  used fewer, holding the excess in reserve.
+ * The exact transition between the two bitrates is not well-defined by this
+ *  API, but may be affected by flags set with #TH_ENCCTL_SET_RATE_FLAGS.
+ * After a number of frames equal to the buffer delay, one may expect further
+ *  output to average at the target bitrate.
+ *
+ * \param[in] _buf <tt>long</tt>: The new target bitrate, in bits per second.
+ * \retval 0             Success.
+ * \retval TH_EFAULT     \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL     The target bitrate was not positive.
+ * \retval TH_EIMPL       Not supported by this implementation.*/
+#define TH_ENCCTL_SET_BITRATE (30)
+
+/*@}*/
+
+
+/**\name TH_ENCCTL_SET_RATE_FLAGS flags
+ * \anchor ratectlflags
+ * These are the flags available for use with #TH_ENCCTL_SET_RATE_FLAGS.*/
+/*@{*/
+/**Drop frames to keep within bitrate buffer constraints.
+ * This can have a severe impact on quality, but is the only way to ensure that
+ *  bitrate targets are met at low rates during sudden bursts of activity.*/
+#define TH_RATECTL_DROP_FRAMES   (0x1)
+/**Ignore bitrate buffer overflows.
+ * If the encoder uses so few bits that the reservoir of available bits
+ *  overflows, ignore the excess.
+ * The encoder will not try to use these extra bits in future frames.
+ * At high rates this may cause the result to be undersized, but allows a
+ *  client to play the stream using a finite buffer; it should normally be
+ *  enabled.*/
+#define TH_RATECTL_CAP_OVERFLOW  (0x2)
+/**Ignore bitrate buffer underflows.
+ * If the encoder uses so many bits that the reservoir of available bits
+ *  underflows, ignore the deficit.
+ * The encoder will not try to make up these extra bits in future frames.
+ * At low rates this may cause the result to be oversized; it should normally
+ *  be disabled.*/
+#define TH_RATECTL_CAP_UNDERFLOW (0x4)
+/*@}*/
+
+
+
+/**The quantization parameters used by VP3.*/
+extern const th_quant_info TH_VP31_QUANT_INFO;
+
+/**The Huffman tables used by VP3.*/
+extern const th_huff_code
+ TH_VP31_HUFF_CODES[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS];
+
+
+
+/**\name Encoder state
+   The following data structure is opaque, and its contents are not publicly
+    defined by this API.
+   Referring to its internals directly is unsupported, and may break without
+    warning.*/
+/*@{*/
+/**The encoder context.*/
+typedef struct th_enc_ctx    th_enc_ctx;
+/*@}*/
+
+
+
+/**\defgroup encfuncs Functions for Encoding*/
+/*@{*/
+/**\name Functions for encoding
+ * You must link to <tt>libtheoraenc</tt> and <tt>libtheoradec</tt>
+ *  if you use any of the functions in this section.
+ *
+ * The functions are listed in the order they are used in a typical encode.
+ * The basic steps are:
+ * - Fill in a #th_info structure with details on the format of the video you
+ *    wish to encode.
+ * - Allocate a #th_enc_ctx handle with th_encode_alloc().
+ * - Perform any additional encoder configuration required with
+ *    th_encode_ctl().
+ * - Repeatedly call th_encode_flushheader() to retrieve all the header
+ *    packets.
+ * - For each uncompressed frame:
+ *   - Submit the uncompressed frame via th_encode_ycbcr_in()
+ *   - Repeatedly call th_encode_packetout() to retrieve any video data packets
+ *      that are ready.
+ * - Call th_encode_free() to release all encoder memory.*/
+/*@{*/
+/**Allocates an encoder instance.
+ * \param _info A #th_info struct filled with the desired encoding parameters.
+ * \return The initialized #th_enc_ctx handle.
+ * \retval NULL If the encoding parameters were invalid.*/
+extern th_enc_ctx *th_encode_alloc(const th_info *_info);
+/**Encoder control function.
+ * This is used to provide advanced control the encoding process.
+ * \param _enc    A #th_enc_ctx handle.
+ * \param _req    The control code to process.
+ *                See \ref encctlcodes "the list of available control codes"
+ *                 for details.
+ * \param _buf    The parameters for this control code.
+ * \param _buf_sz The size of the parameter buffer.*/
+extern int th_encode_ctl(th_enc_ctx *_enc,int _req,void *_buf,size_t _buf_sz);
+/**Outputs the next header packet.
+ * This should be called repeatedly after encoder initialization until it
+ *  returns 0 in order to get all of the header packets, in order, before
+ *  encoding actual video data.
+ * \param _enc      A #th_enc_ctx handle.
+ * \param _comments The metadata to place in the comment header, when it is
+ *                   encoded.
+ * \param _op       An <tt>ogg_packet</tt> structure to fill.
+ *                  All of the elements of this structure will be set,
+ *                   including a pointer to the header data.
+ *                  The memory for the header data is owned by
+ *                   <tt>libtheoraenc</tt>, and may be invalidated when the
+ *                   next encoder function is called.
+ * \return A positive value indicates that a header packet was successfully
+ *          produced.
+ * \retval 0         No packet was produced, and no more header packets remain.
+ * \retval TH_EFAULT \a _enc, \a _comments, or \a _op was <tt>NULL</tt>.*/
+extern int th_encode_flushheader(th_enc_ctx *_enc,
+ th_comment *_comments,ogg_packet *_op);
+/**Submits an uncompressed frame to the encoder.
+ * \param _enc   A #th_enc_ctx handle.
+ * \param _ycbcr A buffer of Y'CbCr data to encode.
+ * \retval 0         Success.
+ * \retval TH_EFAULT \a _enc or \a _ycbcr is <tt>NULL</tt>.
+ * \retval TH_EINVAL The buffer size does not match the frame size the encoder
+ *                    was initialized with, or encoding has already
+ *                    completed.*/
+extern int th_encode_ycbcr_in(th_enc_ctx *_enc,th_ycbcr_buffer _ycbcr);
+/**Retrieves encoded video data packets.
+ * This should be called repeatedly after each frame is submitted to flush any
+ *  encoded packets, until it returns 0.
+ * The encoder will not buffer these packets as subsequent frames are
+ *  compressed, so a failure to do so will result in lost video data.
+ * \note Currently the encoder operates in a one-frame-in, one-packet-out
+ *        manner.
+ *       However, this may be changed in the future.
+ * \param _enc  A #th_enc_ctx handle.
+ * \param _last Set this flag to a non-zero value if no more uncompressed
+ *               frames will be submitted.
+ *              This ensures that a proper EOS flag is set on the last packet.
+ * \param _op   An <tt>ogg_packet</tt> structure to fill.
+ *              All of the elements of this structure will be set, including a
+ *               pointer to the video data.
+ *              The memory for the video data is owned by
+ *               <tt>libtheoraenc</tt>, and may be invalidated when the next
+ *               encoder function is called.
+ * \return A positive value indicates that a video data packet was successfully
+ *          produced.
+ * \retval 0         No packet was produced, and no more encoded video data
+ *                    remains.
+ * \retval TH_EFAULT \a _enc or \a _op was <tt>NULL</tt>.*/
+extern int th_encode_packetout(th_enc_ctx *_enc,int _last,ogg_packet *_op);
+/**Frees an allocated encoder instance.
+ * \param _enc A #th_enc_ctx handle.*/
+extern void th_encode_free(th_enc_ctx *_enc);
+/*@}*/
+/*@}*/
+
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
--- a/media/libtheora/lib/Makefile.in
+++ b/media/libtheora/lib/Makefile.in
@@ -45,60 +45,59 @@ LIBRARY_NAME	= theora
 FORCE_STATIC_LIB= 1
 
 # The encoder is currently not included.
 DEFINES += -DTHEORA_DISABLE_ENCODE
 
 ifeq ($(findstring 86,$(OS_TEST)), 86)
 ifneq ($(OS_ARCH),SunOS)
 ifneq ($(OS_ARCH)$(OS_TEST),WINNTx86_64)
-DEFINES += -DOC_X86ASM -DUSE_ASM
+DEFINES += -DOC_X86_ASM -DUSE_ASM
 endif
 endif
 endif
 
-VPATH		:= $(srcdir) $(srcdir)/dec
+VPATH		:= $(srcdir)
 
 CSRCS		= \
-		cpu.c \
-		huffdec.c \
-		quant.c \
-		dequant.c \
+		apiwrapper.c \
 		bitpack.c \
-		internal.c \
+		decapiwrapper.c \
 		decinfo.c \
-		decapiwrapper.c \
+		decode.c \
+		dequant.c \
+		encoder_disabled.c \
+		fragment.c \
+		huffdec.c \
 		idct.c \
-		state.c \
 		info.c \
-		fragment.c \
-		apiwrapper.c \
-		decode.c \
+		internal.c \
+		quant.c \
+		state.c \
 		$(NULL)
 
 ifeq ($(findstring 86,$(OS_TEST)), 86)
 ifeq ($(OS_ARCH),WINNT)
 ifneq (64,$(findstring 64,$(OS_TEST)))
-VPATH		+= $(srcdir)/dec/x86_vc
+VPATH		+= $(srcdir)/x86_vc
 
 CSRCS		+= \
+		mmxidct.c \
 		mmxfrag.c \
-		mmxloopfilter.c \
+		mmxstate.c \
 		x86state.c \
-		mmxstate.c \
-		mmxidct.c \
 		$(NULL)
 endif
 else
-VPATH		+= $(srcdir)/dec/x86
+VPATH		+= $(srcdir)/x86
 
 CSRCS		+= \
+		mmxidct.c \
 		mmxfrag.c \
+		mmxstate.c \
 		x86state.c \
-		mmxstate.c \
-		mmxidct.c \
 		$(NULL)
 endif
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES = -I$(srcdir)
rename from media/libtheora/lib/dec/apiwrapper.c
rename to media/libtheora/lib/apiwrapper.c
--- a/media/libtheora/lib/dec/apiwrapper.c
+++ b/media/libtheora/lib/apiwrapper.c
@@ -1,22 +1,22 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function:
-    last mod: $Id: apiwrapper.c 15400 2008-10-15 12:10:58Z tterribe $
+    last mod: $Id: apiwrapper.c 16503 2009-08-22 18:14:02Z giles $
 
  ********************************************************************/
 
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
 #include "apiwrapper.h"
 
@@ -42,59 +42,59 @@ void theora_info_clear(theora_info *_ci)
     if(api->clear!=NULL)(*api->clear)(api);
     _ogg_free(api);
   }
 }
 
 void theora_clear(theora_state *_th){
   /*Provide compatibility with mixed encoder and decoder shared lib versions.*/
   if(_th->internal_decode!=NULL){
-    (*((oc_state_dispatch_vtbl *)_th->internal_decode)->clear)(_th);
+    (*((oc_state_dispatch_vtable *)_th->internal_decode)->clear)(_th);
   }
   if(_th->internal_encode!=NULL){
-    (*((oc_state_dispatch_vtbl *)_th->internal_encode)->clear)(_th);
+    (*((oc_state_dispatch_vtable *)_th->internal_encode)->clear)(_th);
   }
   if(_th->i!=NULL)theora_info_clear(_th->i);
   memset(_th,0,sizeof(*_th));
 }
 
 int theora_control(theora_state *_th,int _req,void *_buf,size_t _buf_sz){
   /*Provide compatibility with mixed encoder and decoder shared lib versions.*/
   if(_th->internal_decode!=NULL){
-    return (*((oc_state_dispatch_vtbl *)_th->internal_decode)->control)(_th,
+    return (*((oc_state_dispatch_vtable *)_th->internal_decode)->control)(_th,
      _req,_buf,_buf_sz);
   }
   else if(_th->internal_encode!=NULL){
-    return (*((oc_state_dispatch_vtbl *)_th->internal_encode)->control)(_th,
+    return (*((oc_state_dispatch_vtable *)_th->internal_encode)->control)(_th,
      _req,_buf,_buf_sz);
   }
   else return TH_EINVAL;
 }
 
 ogg_int64_t theora_granule_frame(theora_state *_th,ogg_int64_t _gp){
   /*Provide compatibility with mixed encoder and decoder shared lib versions.*/
   if(_th->internal_decode!=NULL){
-    return (*((oc_state_dispatch_vtbl *)_th->internal_decode)->granule_frame)(
+    return (*((oc_state_dispatch_vtable *)_th->internal_decode)->granule_frame)(
      _th,_gp);
   }
   else if(_th->internal_encode!=NULL){
-    return (*((oc_state_dispatch_vtbl *)_th->internal_encode)->granule_frame)(
+    return (*((oc_state_dispatch_vtable *)_th->internal_encode)->granule_frame)(
      _th,_gp);
   }
   else return -1;
 }
 
 double theora_granule_time(theora_state *_th, ogg_int64_t _gp){
   /*Provide compatibility with mixed encoder and decoder shared lib versions.*/
   if(_th->internal_decode!=NULL){
-    return (*((oc_state_dispatch_vtbl *)_th->internal_decode)->granule_time)(
+    return (*((oc_state_dispatch_vtable *)_th->internal_decode)->granule_time)(
      _th,_gp);
   }
   else if(_th->internal_encode!=NULL){
-    return (*((oc_state_dispatch_vtbl *)_th->internal_encode)->granule_time)(
+    return (*((oc_state_dispatch_vtable *)_th->internal_encode)->granule_time)(
      _th,_gp);
   }
   else return -1;
 }
 
 void oc_theora_info2th_info(th_info *_info,const theora_info *_ci){
   _info->version_major=_ci->version_major;
   _info->version_minor=_ci->version_minor;
rename from media/libtheora/lib/dec/apiwrapper.h
rename to media/libtheora/lib/apiwrapper.h
--- a/media/libtheora/lib/dec/apiwrapper.h
+++ b/media/libtheora/lib/apiwrapper.h
@@ -1,33 +1,32 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function:
     last mod: $Id: apiwrapper.h 13596 2007-08-23 20:05:38Z tterribe $
 
  ********************************************************************/
 
 #if !defined(_apiwrapper_H)
 # define _apiwrapper_H (1)
 # include <ogg/ogg.h>
 # include <theora/theora.h>
 # include "theora/theoradec.h"
-/*# include "theora/theoraenc.h"*/
-typedef struct th_enc_ctx th_enc_ctx;
-# include "../internal.h"
+# include "theora/theoraenc.h"
+# include "internal.h"
 
 typedef struct th_api_wrapper th_api_wrapper;
 typedef struct th_api_info    th_api_info;
 
 /*Provide an entry point for the codec setup to clear itself in case we ever
    want to break pieces off into a common base library shared by encoder and
    decoder.
   In addition, this makes several other pieces of the API wrapper cleaner.*/
rename from media/libtheora/lib/dec/bitpack.c
rename to media/libtheora/lib/bitpack.c
--- a/media/libtheora/lib/dec/bitpack.c
+++ b/media/libtheora/lib/bitpack.c
@@ -1,121 +1,111 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  *                                                                  *
- * THE OggTheora SOURCE CODE IS (C) COPYRIGHT 1994-2008             *
+ * THE OggTheora SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function: packing variable sized words into an octet stream
-  last mod: $Id: bitpack.c 15400 2008-10-15 12:10:58Z tterribe $
+  last mod: $Id: bitpack.c 16503 2009-08-22 18:14:02Z giles $
 
  ********************************************************************/
-
-/*We're 'MSb' endian; if we write a word but read individual bits,
-   then we'll read the MSb first.*/
-
 #include <string.h>
 #include <stdlib.h>
 #include "bitpack.h"
 
-void theorapackB_readinit(oggpack_buffer *_b,unsigned char *_buf,int _bytes){
+/*We're 'MSb' endian; if we write a word but read individual bits,
+   then we'll read the MSb first.*/
+
+void oc_pack_readinit(oc_pack_buf *_b,unsigned char *_buf,long _bytes){
   memset(_b,0,sizeof(*_b));
-  _b->buffer=_b->ptr=_buf;
-  _b->storage=_bytes;
+  _b->ptr=_buf;
+  _b->stop=_buf+_bytes;
 }
 
-int theorapackB_look1(oggpack_buffer *_b,long *_ret){
-  if(_b->endbyte>=_b->storage){
-    *_ret=0L;
-    return -1;
+static oc_pb_window oc_pack_refill(oc_pack_buf *_b,int _bits){
+  const unsigned char *ptr;
+  const unsigned char *stop;
+  oc_pb_window         window;
+  int                  available;
+  window=_b->window;
+  available=_b->bits;
+  ptr=_b->ptr;
+  stop=_b->stop;
+  while(available<=OC_PB_WINDOW_SIZE-8&&ptr<stop){
+    available+=8;
+    window|=(oc_pb_window)*ptr++<<OC_PB_WINDOW_SIZE-available;
   }
-  *_ret=(_b->ptr[0]>>7-_b->endbit)&1;
-  return 0;
+  _b->ptr=ptr;
+  if(_bits>available){
+    if(ptr>=stop){
+      _b->eof=1;
+      available=OC_LOTS_OF_BITS;
+    }
+    else window|=*ptr>>(available&7);
+  }
+  _b->bits=available;
+  return window;
 }
 
-void theorapackB_adv1(oggpack_buffer *_b){
-  if(++(_b->endbit)>7){
-    _b->endbit=0;
-    _b->ptr++;
-    _b->endbyte++;
-  }
+int oc_pack_look1(oc_pack_buf *_b){
+  oc_pb_window window;
+  int          available;
+  window=_b->window;
+  available=_b->bits;
+  if(available<1)_b->window=window=oc_pack_refill(_b,1);
+  return window>>OC_PB_WINDOW_SIZE-1;
+}
+
+void oc_pack_adv1(oc_pack_buf *_b){
+  _b->window<<=1;
+  _b->bits--;
 }
 
 /*Here we assume that 0<=_bits&&_bits<=32.*/
-int theorapackB_read(oggpack_buffer *_b,int _bits,long *_ret){
-  long ret;
-  long m;
-  long d;
-  int fail;
-  m=32-_bits;
-  _bits+=_b->endbit;
-  d=_b->storage-_b->endbyte;
-  if(d<=4){
-    /*Not the main path.*/
-    if(d*8<_bits){
-      *_ret=0L;
-      fail=-1;
-      goto overflow;
-    }
-    /*Special case to avoid reading _b->ptr[0], which might be past the end of
-       the buffer; also skips some useless accounting.*/
-    else if(!_bits){
-      *_ret=0L;
-      return 0;
-    }
+long oc_pack_read(oc_pack_buf *_b,int _bits){
+  oc_pb_window window;
+  int          available;
+  long         result;
+  window=_b->window;
+  available=_b->bits;
+  if(_bits==0)return 0;
+  if(available<_bits){
+    window=oc_pack_refill(_b,_bits);
+    available=_b->bits;
   }
-  ret=_b->ptr[0]<<24+_b->endbit;
-  if(_bits>8){
-    ret|=_b->ptr[1]<<16+_b->endbit;
-    if(_bits>16){
-      ret|=_b->ptr[2]<<8+_b->endbit;
-      if(_bits>24){
-        ret|=_b->ptr[3]<<_b->endbit;
-        if(_bits>32)ret|=_b->ptr[4]>>8-_b->endbit;
-      }
-    }
-  }
-  *_ret=((ret&0xFFFFFFFFUL)>>(m>>1))>>(m+1>>1);
-  fail=0;
-overflow:
-  _b->ptr+=_bits>>3;
-  _b->endbyte+=_bits>>3;
-  _b->endbit=_bits&7;
-  return fail;
+  result=window>>OC_PB_WINDOW_SIZE-_bits;
+  available-=_bits;
+  window<<=1;
+  window<<=_bits-1;
+  _b->bits=available;
+  _b->window=window;
+  return result;
 }
 
-int theorapackB_read1(oggpack_buffer *_b,long *_ret){
-  int fail;
-  if(_b->endbyte>=_b->storage){
-    /*Not the main path.*/
-    *_ret=0L;
-    fail=-1;
+int oc_pack_read1(oc_pack_buf *_b){
+  oc_pb_window window;
+  int          available;
+  int          result;
+  window=_b->window;
+  available=_b->bits;
+  if(available<1){
+    window=oc_pack_refill(_b,1);
+    available=_b->bits;
   }
-  else{
-    *_ret=(_b->ptr[0]>>7-_b->endbit)&1;
-    fail=0;
-  }
-  _b->endbit++;
-  if(_b->endbit>7){
-    _b->endbit=0;
-    _b->ptr++;
-    _b->endbyte++;
-  }
-  return fail;
+  result=window>>OC_PB_WINDOW_SIZE-1;
+  available--;
+  window<<=1;
+  _b->bits=available;
+  _b->window=window;
+  return result;
 }
 
-long theorapackB_bytes(oggpack_buffer *_b){
-  return _b->endbyte+(_b->endbit+7>>3);
+long oc_pack_bytes_left(oc_pack_buf *_b){
+  if(_b->eof)return -1;
+  return _b->stop-_b->ptr+(_b->bits>>3);
 }
-
-long theorapackB_bits(oggpack_buffer *_b){
-  return _b->endbyte*8+_b->endbit;
-}
-
-unsigned char *theorapackB_get_buffer(oggpack_buffer *_b){
-  return _b->buffer;
-}
rename from media/libtheora/lib/dec/bitpack.h
rename to media/libtheora/lib/bitpack.h
--- a/media/libtheora/lib/dec/bitpack.h
+++ b/media/libtheora/lib/bitpack.h
@@ -1,38 +1,59 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  *                                                                  *
- * THE OggTheora SOURCE CODE IS (C) COPYRIGHT 1994-2008             *
+ * THE OggTheora SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function: packing variable sized words into an octet stream
   last mod: $Id: bitwise.c 7675 2004-09-01 00:34:39Z xiphmont $
 
  ********************************************************************/
 #if !defined(_bitpack_H)
 # define _bitpack_H (1)
-# include <ogg/ogg.h>
+# include <limits.h>
+
+
+
+typedef unsigned long      oc_pb_window;
+typedef struct oc_pack_buf oc_pack_buf;
+
+
 
-void theorapackB_readinit(oggpack_buffer *_b,unsigned char *_buf,int _bytes);
-int theorapackB_look1(oggpack_buffer *_b,long *_ret);
-void theorapackB_adv1(oggpack_buffer *_b);
+# define OC_PB_WINDOW_SIZE ((int)sizeof(oc_pb_window)*CHAR_BIT)
+/*This is meant to be a large, positive constant that can still be efficiently
+   loaded as an immediate (on platforms like ARM, for example).
+  Even relatively modest values like 100 would work fine.*/
+# define OC_LOTS_OF_BITS (0x40000000)
+
+
+
+struct oc_pack_buf{
+  oc_pb_window         window;
+  const unsigned char *ptr;
+  const unsigned char *stop;
+  int                  bits;
+  int                  eof;
+};
+
+void oc_pack_readinit(oc_pack_buf *_b,unsigned char *_buf,long _bytes);
+int oc_pack_look1(oc_pack_buf *_b);
+void oc_pack_adv1(oc_pack_buf *_b);
 /*Here we assume 0<=_bits&&_bits<=32.*/
-int theorapackB_read(oggpack_buffer *_b,int _bits,long *_ret);
-int theorapackB_read1(oggpack_buffer *_b,long *_ret);
-long theorapackB_bytes(oggpack_buffer *_b);
-long theorapackB_bits(oggpack_buffer *_b);
-unsigned char *theorapackB_get_buffer(oggpack_buffer *_b);
+long oc_pack_read(oc_pack_buf *_b,int _bits);
+int oc_pack_read1(oc_pack_buf *_b);
+/* returns -1 for read beyond EOF, or the number of whole bytes available */
+long oc_pack_bytes_left(oc_pack_buf *_b);
 
 /*These two functions are implemented locally in huffdec.c*/
 /*Read in bits without advancing the bitptr.
   Here we assume 0<=_bits&&_bits<=32.*/
-/*static int theorapackB_look(oggpack_buffer *_b,int _bits,long *_ret);*/
-/*static void theorapackB_adv(oggpack_buffer *_b,int _bits);*/
-
+/*static int oc_pack_look(oc_pack_buf *_b,int _bits);*/
+/*static void oc_pack_adv(oc_pack_buf *_b,int _bits);*/
 
 #endif
--- a/media/libtheora/lib/config.h
+++ b/media/libtheora/lib/config.h
@@ -1,11 +1,14 @@
 /* config.h.  Generated from config.h.in by configure.  */
 /* config.h.in.  Generated from configure.ac by autoheader.  */
 
+/* libcairo is available for visual debugging output */
+/* #undef HAVE_CAIRO */
+
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #define HAVE_DLFCN_H 1
 
 /* Define to 1 if you have the <inttypes.h> header file. */
 #define HAVE_INTTYPES_H 1
 
 /* Define to 1 if you have the <machine/soundcard.h> header file. */
 /* #undef HAVE_MACHINE_SOUNDCARD_H */
@@ -24,57 +27,64 @@
 
 /* Define to 1 if you have the <strings.h> header file. */
 #define HAVE_STRINGS_H 1
 
 /* Define to 1 if you have the <string.h> header file. */
 #define HAVE_STRING_H 1
 
 /* Define to 1 if you have the <sys/soundcard.h> header file. */
-#define HAVE_SYS_SOUNDCARD_H 1
+/* #undef HAVE_SYS_SOUNDCARD_H */
 
 /* Define to 1 if you have the <sys/stat.h> header file. */
 #define HAVE_SYS_STAT_H 1
 
 /* Define to 1 if you have the <sys/types.h> header file. */
 #define HAVE_SYS_TYPES_H 1
 
 /* Define to 1 if you have the <unistd.h> header file. */
 #define HAVE_UNISTD_H 1
 
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#define LT_OBJDIR ".libs/"
+
 /* Define to 1 if your C compiler doesn't accept -c and -o together. */
 /* #undef NO_MINUS_C_MINUS_O */
 
-/* enable x86 assambler optimization */
- 
+/* make use of x86_64 asm optimization */
+/* #undef OC_X86_64_ASM */
+
+/* make use of x86 asm optimization */
+ /**/
 
 /* Name of package */
 #define PACKAGE "libtheora"
 
 /* Define to the address where bug reports for this package should be sent. */
 #define PACKAGE_BUGREPORT ""
 
 /* Define to the full name of this package. */
 #define PACKAGE_NAME "libtheora"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "libtheora 1.0"
+#define PACKAGE_STRING "libtheora 1.1.0"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "libtheora"
 
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "1.0"
+#define PACKAGE_VERSION "1.1.0"
 
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
 /* Define to exclude encode support from the build */
 /* #undef THEORA_DISABLE_ENCODE */
 
 /* Define to exclude floating point code from the build */
 /* #undef THEORA_DISABLE_FLOAT */
 
-/* make use of asm optimization */
- 
-
 /* Version number of package */
-#define VERSION "1.0"
+#define VERSION "1.1.0"
--- a/media/libtheora/lib/cpu.c
+++ b/media/libtheora/lib/cpu.c
@@ -1,31 +1,31 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2008                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
  CPU capability detection for x86 processors.
   Originally written by Rudolf Marek.
 
  function:
-  last mod: $Id: cpu.c 15427 2008-10-21 02:36:19Z xiphmont $
+  last mod: $Id: cpu.c 16503 2009-08-22 18:14:02Z giles $
 
  ********************************************************************/
 
 #include "cpu.h"
 
-#if !defined(USE_ASM)
+#if !defined(OC_X86_ASM)
 static ogg_uint32_t oc_cpu_flags_get(void){
   return 0;
 }
 #else
 # if !defined(_MSC_VER)
 #  if defined(__amd64__)||defined(__x86_64__)
 /*On x86-64, gcc seems to be able to figure out how to save %rbx for us when
    compiling with -fPIC.*/
@@ -161,17 +161,17 @@ static ogg_uint32_t oc_cpu_flags_get(voi
    ecx==0x3638784D&&edx==0x54656E69&&ebx==0x756E6547){
     /*Intel, Transmeta (tested with Crusoe TM5800):*/
     cpuid(1,eax,ebx,ecx,edx);
     flags=oc_parse_intel_flags(edx,ecx);
   }
   /*              D M A c          i t n e          h t u A*/
   else if(ecx==0x444D4163&&edx==0x69746E65&&ebx==0x68747541||
    /*      C S N            y b   e          d o e G*/
-   ecx==0x43534E20&&edx==0x79622065&&ebx==0x646F6547){
+   ecx==0x43534e20&&edx==0x79622065&&ebx==0x646f6547){
     /*AMD, Geode:*/
     cpuid(0x80000000,eax,ebx,ecx,edx);
     if(eax<0x80000001)flags=0;
     else{
       cpuid(0x80000001,eax,ebx,ecx,edx);
       flags=oc_parse_amd_flags(edx,ecx);
     }
     /*Also check for SSE.*/
@@ -187,17 +187,16 @@ static ogg_uint32_t oc_cpu_flags_get(voi
   else if(ecx==0x736C7561&&edx==0x48727561&&ebx==0x746E6543){
     /*VIA:*/
     /*I only have documentation for the C7 (Esther) and Isaiah (forthcoming)
        chips (thanks to the engineers from Centaur Technology who provided it).
       These chips support Intel-like cpuid info.
       The C3-2 (Nehemiah) cores appear to, as well.*/
     cpuid(1,eax,ebx,ecx,edx);
     flags=oc_parse_intel_flags(edx,ecx);
-    cpuid(0x80000000,eax,ebx,ecx,edx);
     if(eax>=0x80000001){
       /*The (non-Nehemiah) C3 processors support AMD-like cpuid info.
         We need to check this even if the Intel test succeeds to pick up 3DNow!
          support on these processors.
         Unlike actual AMD processors, we cannot _rely_ on this info, since
          some cores (e.g., the 693 stepping of the Nehemiah) claim to support
          this function, yet return edx=0, despite the Intel test indicating
          MMX support.
--- a/media/libtheora/lib/cpu.h
+++ b/media/libtheora/lib/cpu.h
@@ -1,21 +1,21 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
  function:
-    last mod: $Id: cpu.h 15430 2008-10-21 05:03:55Z giles $
+    last mod: $Id: cpu.h 16503 2009-08-22 18:14:02Z giles $
 
  ********************************************************************/
 
 #if !defined(_x86_cpu_H)
 # define _x86_cpu_H (1)
 #include "internal.h"
 
 #define OC_CPU_X86_MMX      (1<<0)
rename from media/libtheora/lib/dec/dct.h
rename to media/libtheora/lib/dct.h
--- a/media/libtheora/lib/dec/dct.h
+++ b/media/libtheora/lib/dct.h
@@ -1,22 +1,22 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function:
-  last mod: $Id: dct.h 15400 2008-10-15 12:10:58Z tterribe $
+  last mod: $Id: dct.h 16503 2009-08-22 18:14:02Z giles $
 
  ********************************************************************/
 
 /*Definitions shared by the forward and inverse DCT transforms.*/
 #if !defined(_dct_H)
 # define _dct_H (1)
 
 /*cos(n*pi/16) (resp. sin(m*pi/16)) scaled by 65536.*/
deleted file mode 100644
--- a/media/libtheora/lib/dec/idct.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/********************************************************************
- *                                                                  *
- * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
- * 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-2007                *
- * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
- *                                                                  *
- ********************************************************************
-
-  function:
-    last mod: $Id: idct.h 15400 2008-10-15 12:10:58Z tterribe $
-
- ********************************************************************/
-
-/*Inverse DCT transforms.*/
-#include <ogg/ogg.h>
-#if !defined(_idct_H)
-# define _idct_H (1)
-
-void oc_idct8x8_c(ogg_int16_t _y[64],const ogg_int16_t _x[64]);
-void oc_idct8x8_10_c(ogg_int16_t _y[64],const ogg_int16_t _x[64]);
-
-#endif
deleted file mode 100644
--- a/media/libtheora/lib/dec/x86_vc/mmxloopfilter.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/********************************************************************
- *                                                                  *
- * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
- * 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-2007                *
- * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
- *                                                                  *
- ********************************************************************
-
-  function:
-    last mod: $Id:
-
- ********************************************************************/
-
-/* -------------------------------------------------------------------
-  MMX based loop filter for the theora codec.
-
-  Originally written by Rudolf Marek, based on code from On2's VP3.
-  Converted to Visual Studio inline assembly by Nils Pipenbrinck.
-
-  Note: I can't test these since my example files never get into the
-  loop filters, but the code has been converted semi-automatic from
-  the GCC sources, so it ought to work.
-  ---------------------------------------------------------------------*/
-#include "../../internal.h"
-#include "x86int.h"
-#include <mmintrin.h>
-
-#if defined(USE_ASM)
-
-
-
-static void loop_filter_v(unsigned char *_pix,int _ystride,
-                          const ogg_int16_t *_ll){
-  _asm {
-    mov       eax,  [_pix]
-    mov       edx,  [_ystride]
-    mov       ecx,  [_ll]
-
-    /* _pix -= ystride */
-    sub       eax,   edx
-    /*  mm0=0          */
-    pxor      mm0,   mm0
-    /* _pix -= ystride */
-    sub       eax,   edx
-    /*  esi=_ystride*3 */
-    lea       esi, [edx + edx*2]
-
-    /*  mm7=_pix[0...8]*/
-    movq      mm7, [eax]
-    /*  mm4=_pix[0...8+_ystride*3]*/
-    movq      mm4, [eax + esi]
-    /*  mm6=_pix[0...8]*/
-    movq      mm6, mm7
-    /*  Expand unsigned _pix[0...3] to 16 bits.*/
-    punpcklbw mm6, mm0
-    movq      mm5, mm4
-    /*  Expand unsigned _pix[4...7] to 16 bits.*/
-    punpckhbw mm7, mm0
-    punpcklbw mm4, mm0
-    /*  Expand other arrays too.*/
-    punpckhbw mm5, mm0
-    /*mm7:mm6=_p[0...7]-_p[0...7+_ystride*3]:*/
-    psubw     mm6, mm4
-    psubw     mm7, mm5
-    /*mm5=mm4=_pix[0...7+_ystride]*/
-    movq      mm4, [eax + edx]
-    /*mm1=mm3=mm2=_pix[0..7]+_ystride*2]*/
-    movq      mm2, [eax + edx*2]
-    movq      mm5, mm4
-    movq      mm3, mm2
-    movq      mm1, mm2
-    /*Expand these arrays.*/
-    punpckhbw mm5, mm0
-    punpcklbw mm4, mm0
-    punpckhbw mm3, mm0
-    punpcklbw mm2, mm0
-    pcmpeqw   mm0, mm0
-    /*mm0=3 3 3 3
-    mm3:mm2=_pix[0...8+_ystride*2]-_pix[0...8+_ystride]*/
-    psubw     mm3, mm5
-    psrlw     mm0, 14
-    psubw     mm2, mm4
-    /*Scale by 3.*/
-    pmullw    mm3, mm0
-    pmullw    mm2, mm0
-    /*mm0=4 4 4 4
-    f=mm3:mm2==_pix[0...8]-_pix[0...8+_ystride*3]+
-     3*(_pix[0...8+_ystride*2]-_pix[0...8+_ystride])*/
-    psrlw     mm0, 1
-    paddw     mm3, mm7
-    psllw     mm0, 2
-    paddw     mm2, mm6
-    /*Add 4.*/
-    paddw     mm3, mm0
-    paddw     mm2, mm0
-    /*"Divide" by 8.*/
-    psraw     mm3, 3
-    psraw     mm2, 3
-    /*Now compute lflim of mm3:mm2 cf. Section 7.10 of the sepc.*/
-    /*Free up mm5.*/
-    packuswb  mm4, mm5
-    /*mm0=L L L L*/
-    movq      mm0, [ecx]
-    /*if(R_i<-2L||R_i>2L)R_i=0:*/
-    movq      mm5, mm2
-    pxor      mm6, mm6
-    movq      mm7, mm0
-    psubw     mm6, mm0
-    psllw     mm7, 1
-    psllw     mm6, 1
-    /*mm2==R_3 R_2 R_1 R_0*/
-    /*mm5==R_3 R_2 R_1 R_0*/
-    /*mm6==-2L -2L -2L -2L*/
-    /*mm7==2L 2L 2L 2L*/
-    pcmpgtw   mm7, mm2
-    pcmpgtw   mm5, mm6
-    pand      mm2, mm7
-    movq      mm7, mm0
-    pand      mm2, mm5
-    psllw     mm7, 1
-    movq      mm5, mm3
-    /*mm3==R_7 R_6 R_5 R_4*/
-    /*mm5==R_7 R_6 R_5 R_4*/
-    /*mm6==-2L -2L -2L -2L*/
-    /*mm7==2L 2L 2L 2L*/
-    pcmpgtw   mm7, mm3
-    pcmpgtw   mm5, mm6
-    pand      mm3, mm7
-    movq      mm7, mm0
-    pand      mm3, mm5
-   /*if(R_i<-L)R_i'=R_i+2L;
-     if(R_i>L)R_i'=R_i-2L;
-     if(R_i<-L||R_i>L)R_i=-R_i':*/
-    psraw     mm6, 1
-    movq      mm5, mm2
-    psllw     mm7, 1
-    /*mm2==R_3 R_2 R_1 R_0*/
-    /*mm5==R_3 R_2 R_1 R_0*/
-    /*mm6==-L -L -L -L*/
-    /*mm0==L L L L*/
-    /*mm5=R_i>L?FF:00*/
-    pcmpgtw   mm5, mm0
-    /*mm6=-L>R_i?FF:00*/
-    pcmpgtw   mm6, mm2
-    /*mm7=R_i>L?2L:0*/
-    pand      mm7, mm5
-    /*mm2=R_i>L?R_i-2L:R_i*/
-    psubw     mm2, mm7
-    movq      mm7, mm0
-    /*mm5=-L>R_i||R_i>L*/
-    por       mm5, mm6
-    psllw     mm7, 1
-    /*mm7=-L>R_i?2L:0*/
-    pand      mm7, mm6
-    pxor      mm6, mm6
-    /*mm2=-L>R_i?R_i+2L:R_i*/
-    paddw     mm2, mm7
-    psubw     mm6, mm0
-    /*mm5=-L>R_i||R_i>L?-R_i':0*/
-    pand      mm5, mm2
-    movq      mm7, mm0
-    /*mm2=-L>R_i||R_i>L?0:R_i*/
-    psubw     mm2, mm5
-    psllw     mm7, 1
-    /*mm2=-L>R_i||R_i>L?-R_i':R_i*/
-    psubw     mm2, mm5
-    movq      mm5, mm3
-    /*mm3==R_7 R_6 R_5 R_4*/
-    /*mm5==R_7 R_6 R_5 R_4*/
-    /*mm6==-L -L -L -L*/
-    /*mm0==L L L L*/
-    /*mm6=-L>R_i?FF:00*/
-    pcmpgtw   mm6, mm3
-    /*mm5=R_i>L?FF:00*/
-    pcmpgtw   mm5, mm0
-    /*mm7=R_i>L?2L:0*/
-    pand      mm7, mm5
-    /*mm2=R_i>L?R_i-2L:R_i*/
-    psubw     mm3, mm7
-    psllw     mm0, 1
-    /*mm5=-L>R_i||R_i>L*/
-    por       mm5, mm6
-    /*mm0=-L>R_i?2L:0*/
-    pand      mm0, mm6
-    /*mm3=-L>R_i?R_i+2L:R_i*/
-    paddw     mm3, mm0
-    /*mm5=-L>R_i||R_i>L?-R_i':0*/
-    pand      mm5, mm3
-    /*mm2=-L>R_i||R_i>L?0:R_i*/
-    psubw     mm3, mm5
-    /*mm3=-L>R_i||R_i>L?-R_i':R_i*/
-    psubw     mm3, mm5
-    /*Unfortunately, there's no unsigned byte+signed byte with unsigned
-       saturation op code, so we have to promote things back 16 bits.*/
-    pxor      mm0, mm0
-    movq      mm5, mm4
-    punpcklbw mm4, mm0
-    punpckhbw mm5, mm0
-    movq      mm6, mm1
-    punpcklbw mm1, mm0
-    punpckhbw mm6, mm0
-    /*_pix[0...8+_ystride]+=R_i*/
-    paddw     mm4, mm2
-    paddw     mm5, mm3
-    /*_pix[0...8+_ystride*2]-=R_i*/
-    psubw     mm1, mm2
-    psubw     mm6, mm3
-    packuswb  mm4, mm5
-    packuswb  mm1, mm6
-    /*Write it back out.*/
-    movq    [eax + edx], mm4
-    movq    [eax + edx*2], mm1
-  }
-}
-
-/*This code implements the bulk of loop_filter_h().
-  Data are striped p0 p1 p2 p3 ... p0 p1 p2 p3 ..., so in order to load all
-   four p0's to one register we must transpose the values in four mmx regs.
-  When half is done we repeat this for the rest.*/
-static void loop_filter_h4(unsigned char *_pix,long _ystride,
-                           const ogg_int16_t *_ll){
-  /* todo: merge the comments from the GCC sources */
-  _asm {
-    mov   ecx, [_pix]
-    mov   edx, [_ystride]
-    mov   eax, [_ll]
-    /*esi=_ystride*3*/
-    lea     esi, [edx + edx*2]
-
-    movd    mm0, dword ptr [ecx]
-    movd    mm1, dword ptr [ecx + edx]
-    movd    mm2, dword ptr [ecx + edx*2]
-    movd    mm3, dword ptr [ecx + esi]
-    punpcklbw mm0, mm1
-    punpcklbw mm2, mm3
-    movq    mm1, mm0
-    punpckhwd mm0, mm2
-    punpcklwd mm1, mm2
-    pxor    mm7, mm7
-    movq    mm5, mm1
-    punpcklbw mm1, mm7
-    punpckhbw mm5, mm7
-    movq    mm3, mm0
-    punpcklbw mm0, mm7
-    punpckhbw mm3, mm7
-    psubw   mm1, mm3
-    movq    mm4, mm0
-    pcmpeqw mm2, mm2
-    psubw   mm0, mm5
-    psrlw   mm2, 14
-    pmullw  mm0, mm2
-    psrlw   mm2, 1
-    paddw   mm0, mm1
-    psllw   mm2, 2
-    paddw   mm0, mm2
-    psraw   mm0, 3
-    movq    mm6, qword ptr [eax]
-    movq    mm1, mm0
-    pxor    mm2, mm2
-    movq    mm3, mm6
-    psubw   mm2, mm6
-    psllw   mm3, 1
-    psllw   mm2, 1
-    pcmpgtw mm3, mm0
-    pcmpgtw mm1, mm2
-    pand    mm0, mm3
-    pand    mm0, mm1
-    psraw   mm2, 1
-    movq    mm1, mm0
-    movq    mm3, mm6
-    pcmpgtw mm2, mm0
-    pcmpgtw mm1, mm6
-    psllw   mm3, 1
-    psllw   mm6, 1
-    pand    mm3, mm1
-    pand    mm6, mm2
-    psubw   mm0, mm3
-    por     mm1, mm2
-    paddw   mm0, mm6
-    pand    mm1, mm0
-    psubw   mm0, mm1
-    psubw   mm0, mm1
-    paddw   mm5, mm0
-    psubw   mm4, mm0
-    packuswb mm5, mm7
-    packuswb mm4, mm7
-    punpcklbw mm5, mm4
-    movd    edi, mm5
-    mov     word ptr [ecx + 01H], di
-    psrlq   mm5, 32
-    shr     edi, 16
-    mov     word ptr [ecx + edx + 01H], di
-    movd    edi, mm5
-    mov     word ptr [ecx + edx*2 + 01H], di
-    shr     edi, 16
-    mov     word ptr [ecx + esi + 01H], di
-  }
-}
-
-static void loop_filter_h(unsigned char *_pix,int _ystride,
-                          const ogg_int16_t *_ll){
-  _pix-=2;
-  loop_filter_h4(_pix,_ystride,_ll);
-  loop_filter_h4(_pix+(_ystride<<2),_ystride,_ll);
-}
-
-
-/*We copy the whole function because the MMX routines will be inlined 4 times,
-   and we can do just a single emms call at the end this way.
-  We also do not use the _bv lookup table, instead computing the values that
-   would lie in it on the fly.*/
-
-/*Apply the loop filter to a given set of fragment rows in the given plane.
-  The filter may be run on the bottom edge, affecting pixels in the next row of
-   fragments, so this row also needs to be available.
-  _bv:        The bounding values array.
-  _refi:      The index of the frame buffer to filter.
-  _pli:       The color plane to filter.
-  _fragy0:    The Y coordinate of the first fragment row to filter.
-  _fragy_end: The Y coordinate of the fragment row to stop filtering at.*/
-void oc_state_loop_filter_frag_rows_mmx(oc_theora_state *_state,int *_bv,
- int _refi,int _pli,int _fragy0,int _fragy_end){
-  ogg_int16_t __declspec(align(8))        ll[4];
-  th_img_plane                            *iplane;
-  oc_fragment_plane                       *fplane;
-  oc_fragment                             *frag_top;
-  oc_fragment                             *frag0;
-  oc_fragment                             *frag;
-  oc_fragment                             *frag_end;
-  oc_fragment                             *frag0_end;
-  oc_fragment                             *frag_bot;
-  ll[0]=ll[1]=ll[2]=ll[3]=
-   (ogg_int16_t)_state->loop_filter_limits[_state->qis[0]];
-  iplane=_state->ref_frame_bufs[_refi]+_pli;
-  fplane=_state->fplanes+_pli;
-  /*The following loops are constructed somewhat non-intuitively on purpose.
-    The main idea is: if a block boundary has at least one coded fragment on
-     it, the filter is applied to it.
-    However, the order that the filters are applied in matters, and VP3 chose
-     the somewhat strange ordering used below.*/
-  frag_top=_state->frags+fplane->froffset;
-  frag0=frag_top+_fragy0*fplane->nhfrags;
-  frag0_end=frag0+(_fragy_end-_fragy0)*fplane->nhfrags;
-  frag_bot=_state->frags+fplane->froffset+fplane->nfrags;
-  while(frag0<frag0_end){
-    frag=frag0;
-    frag_end=frag+fplane->nhfrags;
-    while(frag<frag_end){
-      if(frag->coded){
-        if(frag>frag0){
-          loop_filter_h(frag->buffer[_refi],iplane->stride,ll);
-        }
-        if(frag0>frag_top){
-          loop_filter_v(frag->buffer[_refi],iplane->stride,ll);
-        }
-        if(frag+1<frag_end&&!(frag+1)->coded){
-          loop_filter_h(frag->buffer[_refi]+8,iplane->stride,ll);
-        }
-        if(frag+fplane->nhfrags<frag_bot&&!(frag+fplane->nhfrags)->coded){
-          loop_filter_v((frag+fplane->nhfrags)->buffer[_refi],
-           iplane->stride,ll);
-        }
-      }
-      frag++;
-    }
-    frag0+=fplane->nhfrags;
-  }
-
-  /*This needs to be removed when decode specific functions are implemented:*/
-  _mm_empty();
-}
-
-#endif
rename from media/libtheora/lib/dec/decapiwrapper.c
rename to media/libtheora/lib/decapiwrapper.c
--- a/media/libtheora/lib/dec/decapiwrapper.c
+++ b/media/libtheora/lib/decapiwrapper.c
@@ -1,29 +1,30 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function:
     last mod: $Id: decapiwrapper.c 13596 2007-08-23 20:05:38Z tterribe $
 
  ********************************************************************/
 
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
 #include "apiwrapper.h"
+#include "decint.h"
 #include "theora/theoradec.h"
 
 static void th_dec_api_clear(th_api_wrapper *_api){
   if(_api->setup)th_setup_free(_api->setup);
   if(_api->decode)th_decode_free(_api->decode);
   memset(_api,0,sizeof(*_api));
 }
 
@@ -42,17 +43,17 @@ static ogg_int64_t theora_decode_granule
  ogg_int64_t _gp){
   return th_granule_frame(((th_api_wrapper *)_td->i->codec_setup)->decode,_gp);
 }
 
 static double theora_decode_granule_time(theora_state *_td,ogg_int64_t _gp){
   return th_granule_time(((th_api_wrapper *)_td->i->codec_setup)->decode,_gp);
 }
 
-static const oc_state_dispatch_vtbl OC_DEC_DISPATCH_VTBL={
+static const oc_state_dispatch_vtable OC_DEC_DISPATCH_VTBL={
   (oc_state_clear_func)theora_decode_clear,
   (oc_state_control_func)theora_decode_control,
   (oc_state_granule_frame_func)theora_decode_granule_frame,
   (oc_state_granule_time_func)theora_decode_granule_time,
 };
 
 static void th_info2theora_info(theora_info *_ci,const th_info *_info){
   _ci->version_major=_info->version_major;
@@ -90,16 +91,17 @@ int theora_decode_init(theora_state *_td
   th_info         info;
   api=(th_api_wrapper *)_ci->codec_setup;
   /*Allocate our own combined API wrapper/theora_info struct.
     We put them both in one malloc'd block so that when the API wrapper is
      freed, the info struct goes with it.
     This avoids having to figure out whether or not we need to free the info
      struct in either theora_info_clear() or theora_clear().*/
   apiinfo=(th_api_info *)_ogg_calloc(1,sizeof(*apiinfo));
+  if(apiinfo==NULL)return OC_FAULT;
   /*Make our own copy of the info struct, since its lifetime should be
      independent of the one we were passed in.*/
   *&apiinfo->info=*_ci;
   /*Convert the info struct now instead of saving the the one we decoded with
      theora_decode_header(), since the user might have modified values (i.e.,
      color space, aspect ratio, etc. can be specified from a higher level).
     The user also might be doing something "clever" with the header packets if
      they are not using an Ogg encapsulation.*/
@@ -125,16 +127,17 @@ int theora_decode_header(theora_info *_c
   th_api_wrapper *api;
   th_info         info;
   int             ret;
   api=(th_api_wrapper *)_ci->codec_setup;
   /*Allocate an API wrapper struct on demand, since it will not also include a
      theora_info struct like the ones that are used in a theora_state struct.*/
   if(api==NULL){
     _ci->codec_setup=_ogg_calloc(1,sizeof(*api));
+    if(_ci->codec_setup==NULL)return OC_FAULT;
     api=(th_api_wrapper *)_ci->codec_setup;
     api->clear=(oc_setup_clear_func)th_dec_api_clear;
   }
   /*Convert from the theora_info struct instead of saving our own th_info
      struct between calls.
     The user might be doing something "clever" with the header packets if they
      are not using an Ogg encapsulation, and we don't want to break this.*/
   oc_theora_info2th_info(&info,_ci);
@@ -162,22 +165,24 @@ int theora_decode_packetin(theora_state 
   ret=th_decode_packetin(api->decode,_op,&gp);
   if(ret<0)return OC_BADPACKET;
   _td->granulepos=gp;
   return 0;
 }
 
 int theora_decode_YUVout(theora_state *_td,yuv_buffer *_yuv){
   th_api_wrapper  *api;
+  th_dec_ctx      *decode;
   th_ycbcr_buffer  buf;
   int              ret;
   if(!_td||!_td->i||!_td->i->codec_setup)return OC_FAULT;
   api=(th_api_wrapper *)_td->i->codec_setup;
-  if(!api->decode)return OC_FAULT;
-  ret=th_decode_ycbcr_out(api->decode,buf);
+  decode=(th_dec_ctx *)api->decode;
+  if(!decode)return OC_FAULT;
+  ret=th_decode_ycbcr_out(decode,buf);
   if(ret>=0){
     _yuv->y_width=buf[0].width;
     _yuv->y_height=buf[0].height;
     _yuv->y_stride=buf[0].stride;
     _yuv->uv_width=buf[1].width;
     _yuv->uv_height=buf[1].height;
     _yuv->uv_stride=buf[1].stride;
     _yuv->y=buf[0].data;
rename from media/libtheora/lib/dec/decinfo.c
rename to media/libtheora/lib/decinfo.c
--- a/media/libtheora/lib/dec/decinfo.c
+++ b/media/libtheora/lib/decinfo.c
@@ -1,171 +1,177 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function:
-    last mod: $Id$
+    last mod: $Id: decinfo.c 16503 2009-08-22 18:14:02Z giles $
 
  ********************************************************************/
 
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
 #include "decint.h"
 
 
 
 /*Unpacks a series of octets from a given byte array into the pack buffer.
   No checking is done to ensure the buffer contains enough data.
   _opb: The pack buffer to read the octets from.
   _buf: The byte array to store the unpacked bytes in.
   _len: The number of octets to unpack.*/
-static void oc_unpack_octets(oggpack_buffer *_opb,char *_buf,size_t _len){
+static void oc_unpack_octets(oc_pack_buf *_opb,char *_buf,size_t _len){
   while(_len-->0){
     long val;
-    theorapackB_read(_opb,8,&val);
+    val=oc_pack_read(_opb,8);
     *_buf++=(char)val;
   }
 }
 
 /*Unpacks a 32-bit integer encoded by octets in little-endian form.*/
-static long oc_unpack_length(oggpack_buffer *_opb){
+static long oc_unpack_length(oc_pack_buf *_opb){
   long ret[4];
   int  i;
-  for(i=0;i<4;i++)theorapackB_read(_opb,8,ret+i);
+  for(i=0;i<4;i++)ret[i]=oc_pack_read(_opb,8);
   return ret[0]|ret[1]<<8|ret[2]<<16|ret[3]<<24;
 }
 
-static int oc_info_unpack(oggpack_buffer *_opb,th_info *_info){
+static int oc_info_unpack(oc_pack_buf *_opb,th_info *_info){
   long val;
   /*Check the codec bitstream version.*/
-  theorapackB_read(_opb,8,&val);
+  val=oc_pack_read(_opb,8);
   _info->version_major=(unsigned char)val;
-  theorapackB_read(_opb,8,&val);
+  val=oc_pack_read(_opb,8);
   _info->version_minor=(unsigned char)val;
-  theorapackB_read(_opb,8,&val);
+  val=oc_pack_read(_opb,8);
   _info->version_subminor=(unsigned char)val;
   /*verify we can parse this bitstream version.
      We accept earlier minors and all subminors, by spec*/
   if(_info->version_major>TH_VERSION_MAJOR||
    _info->version_major==TH_VERSION_MAJOR&&
    _info->version_minor>TH_VERSION_MINOR){
     return TH_EVERSION;
   }
   /*Read the encoded frame description.*/
-  theorapackB_read(_opb,16,&val);
+  val=oc_pack_read(_opb,16);
   _info->frame_width=(ogg_uint32_t)val<<4;
-  theorapackB_read(_opb,16,&val);
+  val=oc_pack_read(_opb,16);
   _info->frame_height=(ogg_uint32_t)val<<4;
-  theorapackB_read(_opb,24,&val);
+  val=oc_pack_read(_opb,24);
   _info->pic_width=(ogg_uint32_t)val;
-  theorapackB_read(_opb,24,&val);
+  val=oc_pack_read(_opb,24);
   _info->pic_height=(ogg_uint32_t)val;
-  theorapackB_read(_opb,8,&val);
+  val=oc_pack_read(_opb,8);
   _info->pic_x=(ogg_uint32_t)val;
-  theorapackB_read(_opb,8,&val);
+  val=oc_pack_read(_opb,8);
   _info->pic_y=(ogg_uint32_t)val;
-  theorapackB_read(_opb,32,&val);
+  val=oc_pack_read(_opb,32);
   _info->fps_numerator=(ogg_uint32_t)val;
-  theorapackB_read(_opb,32,&val);
+  val=oc_pack_read(_opb,32);
   _info->fps_denominator=(ogg_uint32_t)val;
   if(_info->frame_width==0||_info->frame_height==0||
    _info->pic_width+_info->pic_x>_info->frame_width||
    _info->pic_height+_info->pic_y>_info->frame_height||
    _info->fps_numerator==0||_info->fps_denominator==0){
     return TH_EBADHEADER;
   }
   /*Note: The sense of pic_y is inverted in what we pass back to the
      application compared to how it is stored in the bitstream.
     This is because the bitstream uses a right-handed coordinate system, while
      applications expect a left-handed one.*/
   _info->pic_y=_info->frame_height-_info->pic_height-_info->pic_y;
-  theorapackB_read(_opb,24,&val);
+  val=oc_pack_read(_opb,24);
   _info->aspect_numerator=(ogg_uint32_t)val;
-  theorapackB_read(_opb,24,&val);
+  val=oc_pack_read(_opb,24);
   _info->aspect_denominator=(ogg_uint32_t)val;
-  theorapackB_read(_opb,8,&val);
+  val=oc_pack_read(_opb,8);
   _info->colorspace=(th_colorspace)val;
-  theorapackB_read(_opb,24,&val);
+  val=oc_pack_read(_opb,24);
   _info->target_bitrate=(int)val;
-  theorapackB_read(_opb,6,&val);
+  val=oc_pack_read(_opb,6);
   _info->quality=(int)val;
-  theorapackB_read(_opb,5,&val);
+  val=oc_pack_read(_opb,5);
   _info->keyframe_granule_shift=(int)val;
-  theorapackB_read(_opb,2,&val);
+  val=oc_pack_read(_opb,2);
   _info->pixel_fmt=(th_pixel_fmt)val;
   if(_info->pixel_fmt==TH_PF_RSVD)return TH_EBADHEADER;
-  if(theorapackB_read(_opb,3,&val)<0||val!=0)return TH_EBADHEADER;
+  val=oc_pack_read(_opb,3);
+  if(val!=0||oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
   return 0;
 }
 
-static int oc_comment_unpack(oggpack_buffer *_opb,th_comment *_tc){
+static int oc_comment_unpack(oc_pack_buf *_opb,th_comment *_tc){
   long len;
   int  i;
   /*Read the vendor string.*/
   len=oc_unpack_length(_opb);
-  if(len<0||len>_opb->storage-theorapackB_bytes(_opb))return TH_EBADHEADER;
+  if(len<0||len>oc_pack_bytes_left(_opb))return TH_EBADHEADER;
   _tc->vendor=_ogg_malloc((size_t)len+1);
+  if(_tc->vendor==NULL)return TH_EFAULT;
   oc_unpack_octets(_opb,_tc->vendor,len);
   _tc->vendor[len]='\0';
   /*Read the user comments.*/
   _tc->comments=(int)oc_unpack_length(_opb);
   len=_tc->comments;
-  if(len<0||len>(LONG_MAX>>2)||len<<2>_opb->storage-theorapackB_bytes(_opb)){
+  if(len<0||len>(LONG_MAX>>2)||len<<2>oc_pack_bytes_left(_opb)){
     _tc->comments=0;
     return TH_EBADHEADER;
   }
   _tc->comment_lengths=(int *)_ogg_malloc(
    _tc->comments*sizeof(_tc->comment_lengths[0]));
   _tc->user_comments=(char **)_ogg_malloc(
    _tc->comments*sizeof(_tc->user_comments[0]));
   for(i=0;i<_tc->comments;i++){
     len=oc_unpack_length(_opb);
-    if(len<0||len>_opb->storage-theorapackB_bytes(_opb)){
+    if(len<0||len>oc_pack_bytes_left(_opb)){
       _tc->comments=i;
       return TH_EBADHEADER;
     }
     _tc->comment_lengths[i]=len;
     _tc->user_comments[i]=_ogg_malloc((size_t)len+1);
+    if(_tc->user_comments[i]==NULL){
+      _tc->comments=i;
+      return TH_EFAULT;
+    }
     oc_unpack_octets(_opb,_tc->user_comments[i],len);
     _tc->user_comments[i][len]='\0';
   }
-  return theorapackB_read(_opb,0,&len)<0?TH_EBADHEADER:0;
+  return oc_pack_bytes_left(_opb)<0?TH_EBADHEADER:0;
 }
 
-static int oc_setup_unpack(oggpack_buffer *_opb,th_setup_info *_setup){
+static int oc_setup_unpack(oc_pack_buf *_opb,th_setup_info *_setup){
   int ret;
   /*Read the quantizer tables.*/
   ret=oc_quant_params_unpack(_opb,&_setup->qinfo);
   if(ret<0)return ret;
   /*Read the Huffman trees.*/
   return oc_huff_trees_unpack(_opb,_setup->huff_tables);
 }
 
 static void oc_setup_clear(th_setup_info *_setup){
   oc_quant_params_clear(&_setup->qinfo);
   oc_huff_trees_clear(_setup->huff_tables);
 }
 
-static int oc_dec_headerin(oggpack_buffer *_opb,th_info *_info,
+static int oc_dec_headerin(oc_pack_buf *_opb,th_info *_info,
  th_comment *_tc,th_setup_info **_setup,ogg_packet *_op){
   char buffer[6];
   long val;
   int  packtype;
   int  ret;
-  theorapackB_read(_opb,8,&val);
+  val=oc_pack_read(_opb,8);
   packtype=(int)val;
   /*If we're at a data packet and we have received all three headers, we're
      done.*/
   if(!(packtype&0x80)&&_info->frame_width>0&&_tc->vendor!=NULL&&*_setup!=NULL){
     return 0;
   }
   /*Check the codec string.*/
   oc_unpack_octets(_opb,buffer,6);
@@ -195,16 +201,17 @@ static int oc_dec_headerin(oggpack_buffe
       oc_setup_info *setup;
       if(_tc==NULL||_setup==NULL)return TH_EFAULT;
       /*We should have already decoded the info header and the comment header,
          and should not yet have decoded the setup header.*/
       if(_info->frame_width==0||_tc->vendor==NULL||*_setup!=NULL){
         return TH_EBADHEADER;
       }
       setup=(oc_setup_info *)_ogg_calloc(1,sizeof(*setup));
+      if(setup==NULL)return TH_EFAULT;
       ret=oc_setup_unpack(_opb,setup);
       if(ret<0){
         oc_setup_clear(setup);
         _ogg_free(setup);
       }
       else{
         *_setup=setup;
         ret=1;
@@ -219,20 +226,20 @@ static int oc_dec_headerin(oggpack_buffe
 }
 
 
 /*Decodes one header packet.
   This should be called repeatedly with the packets at the beginning of the
    stream until it returns 0.*/
 int th_decode_headerin(th_info *_info,th_comment *_tc,
  th_setup_info **_setup,ogg_packet *_op){
-  oggpack_buffer opb;
+  oc_pack_buf opb;
   if(_op==NULL)return TH_EBADHEADER;
   if(_info==NULL)return TH_EFAULT;
-  theorapackB_readinit(&opb,_op->packet,_op->bytes);
+  oc_pack_readinit(&opb,_op->packet,_op->bytes);
   return oc_dec_headerin(&opb,_info,_tc,_setup,_op);
 }
 
 void th_setup_free(th_setup_info *_setup){
   if(_setup!=NULL){
     oc_setup_clear(_setup);
     _ogg_free(_setup);
   }
rename from media/libtheora/lib/dec/decint.h
rename to media/libtheora/lib/decint.h
--- a/media/libtheora/lib/dec/decint.h
+++ b/media/libtheora/lib/decint.h
@@ -1,36 +1,35 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function:
-    last mod: $Id: decint.h 15400 2008-10-15 12:10:58Z tterribe $
+    last mod: $Id: decint.h 16503 2009-08-22 18:14:02Z giles $
 
  ********************************************************************/
 
 #include <limits.h>
 #if !defined(_decint_H)
 # define _decint_H (1)
 # include "theora/theoradec.h"
-# include "../internal.h"
+# include "internal.h"
 # include "bitpack.h"
 
 typedef struct th_setup_info oc_setup_info;
 typedef struct th_dec_ctx    oc_dec_ctx;
 
-# include "idct.h"
 # include "huffdec.h"
 # include "dequant.h"
 
 /*Constants for the packet-in state machine specific to the decoder.*/
 
 /*Next packet to read: Data packet.*/
 #define OC_PACKET_DATA (0)
 
@@ -49,47 +48,60 @@ struct th_dec_ctx{
   /*Shared encoder/decoder state.*/
   oc_theora_state      state;
   /*Whether or not packets are ready to be emitted.
     This takes on negative values while there are remaining header packets to
      be emitted, reaches 0 when the codec is ready for input, and goes to 1
      when a frame has been processed and a data packet is ready.*/
   int                  packet_state;
   /*Buffer in which to assemble packets.*/
-  oggpack_buffer       opb;
+  oc_pack_buf          opb;
   /*Huffman decode trees.*/
   oc_huff_node        *huff_tables[TH_NHUFFMAN_TABLES];
-  /*The index of one past the last token in each plane for each coefficient.
-    The final entries are the total number of tokens for each coefficient.*/
-  int                  ti0[3][64];
-  /*The index of one past the last extra bits entry in each plane for each
-     coefficient.
-    The final entries are the total number of extra bits entries for each
-     coefficient.*/
-  int                  ebi0[3][64];
+  /*The index of the first token in each plane for each coefficient.*/
+  ptrdiff_t            ti0[3][64];
   /*The number of outstanding EOB runs at the start of each coefficient in each
      plane.*/
-  int                  eob_runs[3][64];
+  ptrdiff_t            eob_runs[3][64];
   /*The DCT token lists.*/
-  unsigned char      **dct_tokens;
+  unsigned char       *dct_tokens;
   /*The extra bits associated with DCT tokens.*/
-  ogg_uint16_t       **extra_bits;
+  unsigned char       *extra_bits;
+  /*The number of dct tokens unpacked so far.*/
+  int                  dct_tokens_count;
   /*The out-of-loop post-processing level.*/
   int                  pp_level;
   /*The DC scale used for out-of-loop deblocking.*/
   int                  pp_dc_scale[64];
   /*The sharpen modifier used for out-of-loop deringing.*/
   int                  pp_sharp_mod[64];
   /*The DC quantization index of each block.*/
   unsigned char       *dc_qis;
   /*The variance of each block.*/
   int                 *variances;
   /*The storage for the post-processed frame buffer.*/
   unsigned char       *pp_frame_data;
   /*Whether or not the post-processsed frame buffer has space for chroma.*/
-  int                  pp_frame_has_chroma;
-  /*The buffer used for the post-processed frame.*/
+  int                  pp_frame_state;
+  /*The buffer used for the post-processed frame.
+    Note that this is _not_ guaranteed to have the same strides and offsets as
+     the reference frame buffers.*/
   th_ycbcr_buffer      pp_frame_buf;
   /*The striped decode callback function.*/
   th_stripe_callback   stripe_cb;
+# if defined(HAVE_CAIRO)
+  /*Output metrics for debugging.*/
+  int                  telemetry;
+  int                  telemetry_mbmode;
+  int                  telemetry_mv;
+  int                  telemetry_qi;
+  int                  telemetry_bits;
+  int                  telemetry_frame_bytes;
+  int                  telemetry_coding_bytes;
+  int                  telemetry_mode_bytes;
+  int                  telemetry_mv_bytes;
+  int                  telemetry_qi_bytes;
+  int                  telemetry_dc_bytes;
+  unsigned char       *telemetry_frame_data;
+# endif
 };
 
 #endif
rename from media/libtheora/lib/dec/decode.c
rename to media/libtheora/lib/decode.c
--- a/media/libtheora/lib/dec/decode.c
+++ b/media/libtheora/lib/decode.c
@@ -1,33 +1,37 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function:
-    last mod: $Id: decode.c 15403 2008-10-16 12:44:05Z tterribe $
+    last mod: $Id: decode.c 16581 2009-09-25 22:56:16Z gmaxwell $
 
  ********************************************************************/
 
 #include <stdlib.h>
 #include <string.h>
 #include <ogg/ogg.h>
 #include "decint.h"
 #if defined(OC_DUMP_IMAGES)
 # include <stdio.h>
 # include "png.h"
 #endif
+#if defined(HAVE_CAIRO)
+# include <cairo.h>
+#endif
+
 
 /*No post-processing.*/
 #define OC_PP_LEVEL_DISABLED  (0)
 /*Keep track of DC qi for each block only.*/
 #define OC_PP_LEVEL_TRACKDCQI (1)
 /*Deblock the luma plane.*/
 #define OC_PP_LEVEL_DEBLOCKY  (2)
 /*Dering the luma plane.*/
@@ -42,17 +46,17 @@
 #define OC_PP_LEVEL_SDERINGC  (7)
 /*Maximum valid post-processing level.*/
 #define OC_PP_LEVEL_MAX       (7)
 
 
 
 /*The mode alphabets for the various mode coding schemes.
   Scheme 0 uses a custom alphabet, which is not stored in this table.*/
-static const int OC_MODE_ALPHABETS[7][OC_NMODES]={
+static const unsigned char OC_MODE_ALPHABETS[7][OC_NMODES]={
   /*Last MV dominates */
   {
     OC_MODE_INTER_MV_LAST,OC_MODE_INTER_MV_LAST2,OC_MODE_INTER_MV,
     OC_MODE_INTER_NOMV,OC_MODE_INTRA,OC_MODE_GOLDEN_NOMV,OC_MODE_GOLDEN_MV,
     OC_MODE_INTER_MV_FOUR
   },
   {
     OC_MODE_INTER_MV_LAST,OC_MODE_INTER_MV_LAST2,OC_MODE_INTER_NOMV,
@@ -84,1094 +88,1103 @@ static const int OC_MODE_ALPHABETS[7][OC
   {
     OC_MODE_INTER_NOMV,OC_MODE_INTRA,OC_MODE_INTER_MV,OC_MODE_INTER_MV_LAST,
     OC_MODE_INTER_MV_LAST2,OC_MODE_GOLDEN_NOMV,OC_MODE_GOLDEN_MV,
     OC_MODE_INTER_MV_FOUR
   }
 };
 
 
-static int oc_sb_run_unpack(oggpack_buffer *_opb){
+/*The original DCT tokens are extended and reordered during the construction of
+   the Huffman tables.
+  The extension means more bits can be read with fewer calls to the bitpacker
+   during the Huffman decoding process (at the cost of larger Huffman tables),
+   and fewer tokens require additional extra bits (reducing the average storage
+   per decoded token).
+  The revised ordering reveals essential information in the token value
+   itself; specifically, whether or not there are additional extra bits to read
+   and the parameter to which those extra bits are applied.
+  The token is used to fetch a code word from the OC_DCT_CODE_WORD table below.
+  The extra bits are added into code word at the bit position inferred from the
+   token value, giving the final code word from which all required parameters
+   are derived.
+  The number of EOBs and the leading zero run length can be extracted directly.
+  The coefficient magnitude is optionally negated before extraction, according
+   to a 'flip' bit.*/
+
+/*The number of additional extra bits that are decoded with each of the
+   internal DCT tokens.*/
+static const unsigned char OC_INTERNAL_DCT_TOKEN_EXTRA_BITS[15]={
+  12,4,3,3,4,4,5,5,8,8,8,8,3,3,6
+};
+
+/*Whether or not an internal token needs any additional extra bits.*/
+#define OC_DCT_TOKEN_NEEDS_MORE(token) \
+ (token<(sizeof(OC_INTERNAL_DCT_TOKEN_EXTRA_BITS)/ \
+  sizeof(*OC_INTERNAL_DCT_TOKEN_EXTRA_BITS)))
+
+/*This token (OC_DCT_REPEAT_RUN3_TOKEN) requires more than 8 extra bits.*/
+#define OC_DCT_TOKEN_FAT_EOB (0)
+
+/*The number of EOBs to use for an end-of-frame token.
+  Note: We want to set eobs to PTRDIFF_MAX here, but that requires C99, which
+   is not yet available everywhere; this should be equivalent.*/
+#define OC_DCT_EOB_FINISH (~(size_t)0>>1)
+
+/*The location of the (6) run legth bits in the code word.
+  These are placed at index 0 and given 8 bits (even though 6 would suffice)
+   because it may be faster to extract the lower byte on some platforms.*/
+#define OC_DCT_CW_RLEN_SHIFT (0)
+/*The location of the (12) EOB bits in the code word.*/
+#define OC_DCT_CW_EOB_SHIFT  (8)
+/*The location of the (1) flip bit in the code word.
+  This must be right under the magnitude bits.*/
+#define OC_DCT_CW_FLIP_BIT   (20)
+/*The location of the (11) token magnitude bits in the code word.
+  These must be last, and rely on a sign-extending right shift.*/
+#define OC_DCT_CW_MAG_SHIFT  (21)
+
+/*Pack the given fields into a code word.*/
+#define OC_DCT_CW_PACK(_eobs,_rlen,_mag,_flip) \
+ ((_eobs)<<OC_DCT_CW_EOB_SHIFT| \
+ (_rlen)<<OC_DCT_CW_RLEN_SHIFT| \
+ (_flip)<<OC_DCT_CW_FLIP_BIT| \
+ (_mag)-(_flip)<<OC_DCT_CW_MAG_SHIFT)
+
+/*A special code word value that signals the end of the frame (a long EOB run
+   of zero).*/
+#define OC_DCT_CW_FINISH (0)
+
+/*The position at which to insert the extra bits in the code word.
+  We use this formulation because Intel has no useful cmov.
+  A real architecture would probably do better with two of those.
+  This translates to 11 instructions(!), and is _still_ faster than either a
+   table lookup (just barely) or the naive double-ternary implementation (which
+   gcc translates to a jump and a cmov).
+  This assumes OC_DCT_CW_RLEN_SHIFT is zero, but could easily be reworked if
+   you want to make one of the other shifts zero.*/
+#define OC_DCT_TOKEN_EB_POS(_token) \
+ ((OC_DCT_CW_EOB_SHIFT-OC_DCT_CW_MAG_SHIFT&-((_token)<2)) \
+ +(OC_DCT_CW_MAG_SHIFT&-((_token)<12)))
+
+/*The code words for each internal token.
+  See the notes at OC_DCT_TOKEN_MAP for the reasons why things are out of
+   order.*/
+static const ogg_int32_t OC_DCT_CODE_WORD[92]={
+  /*These tokens require additional extra bits for the EOB count.*/
+  /*OC_DCT_REPEAT_RUN3_TOKEN (12 extra bits)*/
+  OC_DCT_CW_FINISH,
+  /*OC_DCT_REPEAT_RUN2_TOKEN (4 extra bits)*/
+  OC_DCT_CW_PACK(16, 0,  0,0),
+  /*These tokens require additional extra bits for the magnitude.*/
+  /*OC_DCT_VAL_CAT5 (4 extra bits-1 already read)*/
+  OC_DCT_CW_PACK( 0, 0, 13,0),
+  OC_DCT_CW_PACK( 0, 0, 13,1),
+  /*OC_DCT_VAL_CAT6 (5 extra bits-1 already read)*/
+  OC_DCT_CW_PACK( 0, 0, 21,0),
+  OC_DCT_CW_PACK( 0, 0, 21,1),
+  /*OC_DCT_VAL_CAT7 (6 extra bits-1 already read)*/
+  OC_DCT_CW_PACK( 0, 0, 37,0),
+  OC_DCT_CW_PACK( 0, 0, 37,1),
+  /*OC_DCT_VAL_CAT8 (10 extra bits-2 already read)*/
+  OC_DCT_CW_PACK( 0, 0, 69,0),
+  OC_DCT_CW_PACK( 0, 0,325,0),
+  OC_DCT_CW_PACK( 0, 0, 69,1),
+  OC_DCT_CW_PACK( 0, 0,325,1),
+  /*These tokens require additional extra bits for the run length.*/
+  /*OC_DCT_RUN_CAT1C (4 extra bits-1 already read)*/
+  OC_DCT_CW_PACK( 0,10, +1,0),
+  OC_DCT_CW_PACK( 0,10, -1,0),
+  /*OC_DCT_ZRL_TOKEN (6 extra bits)
+    Flip is set to distinguish this from OC_DCT_CW_FINISH.*/
+  OC_DCT_CW_PACK( 0, 0,  0,1),
+  /*The remaining tokens require no additional extra bits.*/
+  /*OC_DCT_EOB1_TOKEN (0 extra bits)*/
+  OC_DCT_CW_PACK( 1, 0,  0,0),
+  /*OC_DCT_EOB2_TOKEN (0 extra bits)*/
+  OC_DCT_CW_PACK( 2, 0,  0,0),
+  /*OC_DCT_EOB3_TOKEN (0 extra bits)*/
+  OC_DCT_CW_PACK( 3, 0,  0,0),
+  /*OC_DCT_RUN_CAT1A (1 extra bit-1 already read)x5*/
+  OC_DCT_CW_PACK( 0, 1, +1,0),
+  OC_DCT_CW_PACK( 0, 1, -1,0),
+  OC_DCT_CW_PACK( 0, 2, +1,0),
+  OC_DCT_CW_PACK( 0, 2, -1,0),
+  OC_DCT_CW_PACK( 0, 3, +1,0),
+  OC_DCT_CW_PACK( 0, 3, -1,0),
+  OC_DCT_CW_PACK( 0, 4, +1,0),
+  OC_DCT_CW_PACK( 0, 4, -1,0),
+  OC_DCT_CW_PACK( 0, 5, +1,0),
+  OC_DCT_CW_PACK( 0, 5, -1,0),
+  /*OC_DCT_RUN_CAT2A (2 extra bits-2 already read)*/
+  OC_DCT_CW_PACK( 0, 1, +2,0),
+  OC_DCT_CW_PACK( 0, 1, +3,0),
+  OC_DCT_CW_PACK( 0, 1, -2,0),
+  OC_DCT_CW_PACK( 0, 1, -3,0),
+  /*OC_DCT_RUN_CAT1B (3 extra bits-3 already read)*/
+  OC_DCT_CW_PACK( 0, 6, +1,0),
+  OC_DCT_CW_PACK( 0, 7, +1,0),
+  OC_DCT_CW_PACK( 0, 8, +1,0),
+  OC_DCT_CW_PACK( 0, 9, +1,0),
+  OC_DCT_CW_PACK( 0, 6, -1,0),
+  OC_DCT_CW_PACK( 0, 7, -1,0),
+  OC_DCT_CW_PACK( 0, 8, -1,0),
+  OC_DCT_CW_PACK( 0, 9, -1,0),
+  /*OC_DCT_RUN_CAT2B (3 extra bits-3 already read)*/
+  OC_DCT_CW_PACK( 0, 2, +2,0),
+  OC_DCT_CW_PACK( 0, 3, +2,0),
+  OC_DCT_CW_PACK( 0, 2, +3,0),
+  OC_DCT_CW_PACK( 0, 3, +3,0),
+  OC_DCT_CW_PACK( 0, 2, -2,0),
+  OC_DCT_CW_PACK( 0, 3, -2,0),
+  OC_DCT_CW_PACK( 0, 2, -3,0),
+  OC_DCT_CW_PACK( 0, 3, -3,0),
+  /*OC_DCT_SHORT_ZRL_TOKEN (3 extra bits-3 already read)
+    Flip is set on the first one to distinguish it from OC_DCT_CW_FINISH.*/
+  OC_DCT_CW_PACK( 0, 0,  0,1),
+  OC_DCT_CW_PACK( 0, 1,  0,0),
+  OC_DCT_CW_PACK( 0, 2,  0,0),
+  OC_DCT_CW_PACK( 0, 3,  0,0),
+  OC_DCT_CW_PACK( 0, 4,  0,0),
+  OC_DCT_CW_PACK( 0, 5,  0,0),
+  OC_DCT_CW_PACK( 0, 6,  0,0),
+  OC_DCT_CW_PACK( 0, 7,  0,0),
+  /*OC_ONE_TOKEN (0 extra bits)*/
+  OC_DCT_CW_PACK( 0, 0, +1,0),
+  /*OC_MINUS_ONE_TOKEN (0 extra bits)*/
+  OC_DCT_CW_PACK( 0, 0, -1,0),
+  /*OC_TWO_TOKEN (0 extra bits)*/
+  OC_DCT_CW_PACK( 0, 0, +2,0),
+  /*OC_MINUS_TWO_TOKEN (0 extra bits)*/
+  OC_DCT_CW_PACK( 0, 0, -2,0),
+  /*OC_DCT_VAL_CAT2 (1 extra bit-1 already read)x4*/
+  OC_DCT_CW_PACK( 0, 0, +3,0),
+  OC_DCT_CW_PACK( 0, 0, -3,0),
+  OC_DCT_CW_PACK( 0, 0, +4,0),
+  OC_DCT_CW_PACK( 0, 0, -4,0),
+  OC_DCT_CW_PACK( 0, 0, +5,0),
+  OC_DCT_CW_PACK( 0, 0, -5,0),
+  OC_DCT_CW_PACK( 0, 0, +6,0),
+  OC_DCT_CW_PACK( 0, 0, -6,0),
+  /*OC_DCT_VAL_CAT3 (2 extra bits-2 already read)*/
+  OC_DCT_CW_PACK( 0, 0, +7,0),
+  OC_DCT_CW_PACK( 0, 0, +8,0),
+  OC_DCT_CW_PACK( 0, 0, -7,0),
+  OC_DCT_CW_PACK( 0, 0, -8,0),
+  /*OC_DCT_VAL_CAT4 (3 extra bits-3 already read)*/
+  OC_DCT_CW_PACK( 0, 0, +9,0),
+  OC_DCT_CW_PACK( 0, 0,+10,0),
+  OC_DCT_CW_PACK( 0, 0,+11,0),
+  OC_DCT_CW_PACK( 0, 0,+12,0),
+  OC_DCT_CW_PACK( 0, 0, -9,0),
+  OC_DCT_CW_PACK( 0, 0,-10,0),
+  OC_DCT_CW_PACK( 0, 0,-11,0),
+  OC_DCT_CW_PACK( 0, 0,-12,0),
+  /*OC_DCT_REPEAT_RUN1_TOKEN (3 extra bits-3 already read)*/
+  OC_DCT_CW_PACK( 8, 0,  0,0),
+  OC_DCT_CW_PACK( 9, 0,  0,0),
+  OC_DCT_CW_PACK(10, 0,  0,0),
+  OC_DCT_CW_PACK(11, 0,  0,0),
+  OC_DCT_CW_PACK(12, 0,  0,0),
+  OC_DCT_CW_PACK(13, 0,  0,0),
+  OC_DCT_CW_PACK(14, 0,  0,0),
+  OC_DCT_CW_PACK(15, 0,  0,0),
+  /*OC_DCT_REPEAT_RUN0_TOKEN (2 extra bits-2 already read)*/
+  OC_DCT_CW_PACK( 4, 0,  0,0),
+  OC_DCT_CW_PACK( 5, 0,  0,0),
+  OC_DCT_CW_PACK( 6, 0,  0,0),
+  OC_DCT_CW_PACK( 7, 0,  0,0),
+};
+
+
+
+static int oc_sb_run_unpack(oc_pack_buf *_opb){
   long bits;
   int ret;
   /*Coding scheme:
        Codeword            Run Length
      0                       1
      10x                     2-3
      110x                    4-5
      1110xx                  6-9
      11110xxx                10-17
      111110xxxx              18-33
      111111xxxxxxxxxxxx      34-4129*/
-  theorapackB_read1(_opb,&bits);
+  bits=oc_pack_read1(_opb);
   if(bits==0)return 1;
-  theorapackB_read(_opb,2,&bits);
+  bits=oc_pack_read(_opb,2);
   if((bits&2)==0)return 2+(int)bits;
   else if((bits&1)==0){
-    theorapackB_read1(_opb,&bits);
+    bits=oc_pack_read1(_opb);
     return 4+(int)bits;
   }
-  theorapackB_read(_opb,3,&bits);
+  bits=oc_pack_read(_opb,3);
   if((bits&4)==0)return 6+(int)bits;
   else if((bits&2)==0){
     ret=10+((bits&1)<<2);
-    theorapackB_read(_opb,2,&bits);
+    bits=oc_pack_read(_opb,2);
     return ret+(int)bits;
   }
   else if((bits&1)==0){
-    theorapackB_read(_opb,4,&bits);
+    bits=oc_pack_read(_opb,4);
     return 18+(int)bits;
   }
-  theorapackB_read(_opb,12,&bits);
+  bits=oc_pack_read(_opb,12);
   return 34+(int)bits;
 }
 
-static int oc_block_run_unpack(oggpack_buffer *_opb){
+static int oc_block_run_unpack(oc_pack_buf *_opb){
   long bits;
   long bits2;
   /*Coding scheme:
      Codeword             Run Length
      0x                      1-2
      10x                     3-4
      110x                    5-6
      1110xx                  7-10
      11110xx                 11-14
      11111xxxx               15-30*/
-  theorapackB_read(_opb,2,&bits);
+  bits=oc_pack_read(_opb,2);
   if((bits&2)==0)return 1+(int)bits;
   else if((bits&1)==0){
-    theorapackB_read1(_opb,&bits);
+    bits=oc_pack_read1(_opb);
     return 3+(int)bits;
   }
-  theorapackB_read(_opb,2,&bits);
+  bits=oc_pack_read(_opb,2);
   if((bits&2)==0)return 5+(int)bits;
   else if((bits&1)==0){
-    theorapackB_read(_opb,2,&bits);
+    bits=oc_pack_read(_opb,2);
     return 7+(int)bits;
   }
-  theorapackB_read(_opb,3,&bits);
+  bits=oc_pack_read(_opb,3);
   if((bits&4)==0)return 11+bits;
-  theorapackB_read(_opb,2,&bits2);
+  bits2=oc_pack_read(_opb,2);
   return 15+((bits&3)<<2)+bits2;
 }
 
 
 
 static int oc_dec_init(oc_dec_ctx *_dec,const th_info *_info,
  const th_setup_info *_setup){
   int qti;
   int pli;
   int qi;
   int ret;
-  ret=oc_state_init(&_dec->state,_info);
+  ret=oc_state_init(&_dec->state,_info,3);
   if(ret<0)return ret;
-  oc_huff_trees_copy(_dec->huff_tables,
+  ret=oc_huff_trees_copy(_dec->huff_tables,
    (const oc_huff_node *const *)_setup->huff_tables);
-  for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){
-    _dec->state.dequant_tables[qti][pli]=
-     _dec->state.dequant_table_data[qti][pli];
+  if(ret<0){
+    oc_state_clear(&_dec->state);
+    return ret;
+  }
+  /*For each fragment, allocate one byte for every DCT coefficient token, plus
+     one byte for extra-bits for each token, plus one more byte for the long
+     EOB run, just in case it's the very last token and has a run length of
+     one.*/
+  _dec->dct_tokens=(unsigned char *)_ogg_malloc((64+64+1)*
+   _dec->state.nfrags*sizeof(_dec->dct_tokens[0]));
+  if(_dec->dct_tokens==NULL){
+    oc_huff_trees_clear(_dec->huff_tables);
+    oc_state_clear(&_dec->state);
+    return TH_EFAULT;
+  }
+  for(qi=0;qi<64;qi++)for(pli=0;pli<3;pli++)for(qti=0;qti<2;qti++){
+    _dec->state.dequant_tables[qi][pli][qti]=
+     _dec->state.dequant_table_data[qi][pli][qti];
   }
   oc_dequant_tables_init(_dec->state.dequant_tables,_dec->pp_dc_scale,
    &_setup->qinfo);
   for(qi=0;qi<64;qi++){
     int qsum;
     qsum=0;
     for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){
-      qsum+=_dec->state.dequant_tables[qti][pli][qi][18]+
-       _dec->state.dequant_tables[qti][pli][qi][19]+
-       _dec->state.dequant_tables[qti][pli][qi][26]+
-       _dec->state.dequant_tables[qti][pli][qi][27]<<(pli==0);
+      qsum+=_dec->state.dequant_tables[qti][pli][qi][12]+
+       _dec->state.dequant_tables[qti][pli][qi][17]+
+       _dec->state.dequant_tables[qti][pli][qi][18]+
+       _dec->state.dequant_tables[qti][pli][qi][24]<<(pli==0);
     }
     _dec->pp_sharp_mod[qi]=-(qsum>>11);
   }
-  _dec->dct_tokens=(unsigned char **)oc_calloc_2d(64,
-   _dec->state.nfrags,sizeof(_dec->dct_tokens[0][0]));
-  _dec->extra_bits=(ogg_uint16_t **)oc_calloc_2d(64,
-   _dec->state.nfrags,sizeof(_dec->extra_bits[0][0]));
   memcpy(_dec->state.loop_filter_limits,_setup->qinfo.loop_filter_limits,
    sizeof(_dec->state.loop_filter_limits));
   _dec->pp_level=OC_PP_LEVEL_DISABLED;
   _dec->dc_qis=NULL;
   _dec->variances=NULL;
   _dec->pp_frame_data=NULL;
   _dec->stripe_cb.ctx=NULL;
   _dec->stripe_cb.stripe_decoded=NULL;
+#if defined(HAVE_CAIRO)
+  _dec->telemetry=0;
+  _dec->telemetry_bits=0;
+  _dec->telemetry_qi=0;
+  _dec->telemetry_mbmode=0;
+  _dec->telemetry_mv=0;
+  _dec->telemetry_frame_data=NULL;
+#endif
   return 0;
 }
 
 static void oc_dec_clear(oc_dec_ctx *_dec){
+#if defined(HAVE_CAIRO)
+  _ogg_free(_dec->telemetry_frame_data);
+#endif
   _ogg_free(_dec->pp_frame_data);
   _ogg_free(_dec->variances);
   _ogg_free(_dec->dc_qis);
-  oc_free_2d(_dec->extra_bits);
-  oc_free_2d(_dec->dct_tokens);
+  _ogg_free(_dec->dct_tokens);
   oc_huff_trees_clear(_dec->huff_tables);
   oc_state_clear(&_dec->state);
 }
 
 
 static int oc_dec_frame_header_unpack(oc_dec_ctx *_dec){
   long val;
   /*Check to make sure this is a data packet.*/
-  theorapackB_read1(&_dec->opb,&val);
+  val=oc_pack_read1(&_dec->opb);
   if(val!=0)return TH_EBADPACKET;
   /*Read in the frame type (I or P).*/
-  theorapackB_read1(&_dec->opb,&val);
+  val=oc_pack_read1(&_dec->opb);
   _dec->state.frame_type=(int)val;
-  /*Read in the current qi.*/
-  theorapackB_read(&_dec->opb,6,&val);
-  _dec->state.qis[0]=(int)val;
-  theorapackB_read1(&_dec->opb,&val);
+  /*Read in the qi list.*/
+  val=oc_pack_read(&_dec->opb,6);
+  _dec->state.qis[0]=(unsigned char)val;
+  val=oc_pack_read1(&_dec->opb);
   if(!val)_dec->state.nqis=1;
   else{
-    theorapackB_read(&_dec->opb,6,&val);
-    _dec->state.qis[1]=(int)val;
-    theorapackB_read1(&_dec->opb,&val);
+    val=oc_pack_read(&_dec->opb,6);
+    _dec->state.qis[1]=(unsigned char)val;
+    val=oc_pack_read1(&_dec->opb);
     if(!val)_dec->state.nqis=2;
     else{
-      theorapackB_read(&_dec->opb,6,&val);
-      _dec->state.qis[2]=(int)val;
+      val=oc_pack_read(&_dec->opb,6);
+      _dec->state.qis[2]=(unsigned char)val;
       _dec->state.nqis=3;
     }
   }
   if(_dec->state.frame_type==OC_INTRA_FRAME){
     /*Keyframes have 3 unused configuration bits, holdovers from VP3 days.
       Most of the other unused bits in the VP3 headers were eliminated.
       I don't know why these remain.*/
-    /* I wanted to eliminate wasted bits, but not all config wiggle room --Monty */
-    theorapackB_read(&_dec->opb,3,&val);
+    /*I wanted to eliminate wasted bits, but not all config wiggle room
+       --Monty.*/
+    val=oc_pack_read(&_dec->opb,3);
     if(val!=0)return TH_EIMPL;
   }
   return 0;
 }
 
 /*Mark all fragments as coded and in OC_MODE_INTRA.
   This also builds up the coded fragment list (in coded order), and clears the
    uncoded fragment list.
-  It does not update the coded macro block list, as that is not used when
-   decoding INTRA frames.*/
+  It does not update the coded macro block list nor the super block flags, as
+   those are not used when decoding INTRA frames.*/
 static void oc_dec_mark_all_intra(oc_dec_ctx *_dec){
-  oc_sb *sb;
-  oc_sb *sb_end;
-  int    pli;
-  int    ncoded_fragis;
-  int    prev_ncoded_fragis;
+  const oc_sb_map   *sb_maps;
+  const oc_sb_flags *sb_flags;
+  oc_fragment       *frags;
+  ptrdiff_t         *coded_fragis;
+  ptrdiff_t          ncoded_fragis;
+  ptrdiff_t          prev_ncoded_fragis;
+  unsigned           nsbs;
+  unsigned           sbi;
+  int                pli;
+  coded_fragis=_dec->state.coded_fragis;
   prev_ncoded_fragis=ncoded_fragis=0;
-  sb=sb_end=_dec->state.sbs;
+  sb_maps=(const oc_sb_map *)_dec->state.sb_maps;
+  sb_flags=_dec->state.sb_flags;
+  frags=_dec->state.frags;
+  sbi=nsbs=0;
   for(pli=0;pli<3;pli++){
-    const oc_fragment_plane *fplane;
-    fplane=_dec->state.fplanes+pli;
-    sb_end+=fplane->nsbs;
-    for(;sb<sb_end;sb++){
+    nsbs+=_dec->state.fplanes[pli].nsbs;
+    for(;sbi<nsbs;sbi++){
       int quadi;
-      for(quadi=0;quadi<4;quadi++)if(sb->quad_valid&1<<quadi){
+      for(quadi=0;quadi<4;quadi++)if(sb_flags[sbi].quad_valid&1<<quadi){
         int bi;
         for(bi=0;bi<4;bi++){
-          int fragi;
-          fragi=sb->map[quadi][bi];
+          ptrdiff_t fragi;
+          fragi=sb_maps[sbi][quadi][bi];
           if(fragi>=0){
-            oc_fragment *frag;
-            frag=_dec->state.frags+fragi;
-            frag->coded=1;
-            frag->mbmode=OC_MODE_INTRA;
-            _dec->state.coded_fragis[ncoded_fragis++]=fragi;
+            frags[fragi].coded=1;
+            frags[fragi].mb_mode=OC_MODE_INTRA;
+            coded_fragis[ncoded_fragis++]=fragi;
           }
         }
       }
     }
     _dec->state.ncoded_fragis[pli]=ncoded_fragis-prev_ncoded_fragis;
     prev_ncoded_fragis=ncoded_fragis;
-    _dec->state.nuncoded_fragis[pli]=0;
   }
+  _dec->state.ntotal_coded_fragis=ncoded_fragis;
 }
 
-/*Decodes the bit flags for whether or not each super block is partially coded
+/*Decodes the bit flags indicating whether each super block is partially coded
    or not.
   Return: The number of partially coded super blocks.*/
-static int oc_dec_partial_sb_flags_unpack(oc_dec_ctx *_dec){
-  oc_sb *sb;
-  oc_sb *sb_end;
-  long   val;
-  int    flag;
-  int    npartial;
-  int    run_count;
-  theorapackB_read1(&_dec->opb,&val);
+static unsigned oc_dec_partial_sb_flags_unpack(oc_dec_ctx *_dec){
+  oc_sb_flags *sb_flags;
+  unsigned     nsbs;
+  unsigned     sbi;
+  unsigned     npartial;
+  unsigned     run_count;
+  long         val;
+  int          flag;
+  val=oc_pack_read1(&_dec->opb);
   flag=(int)val;
-  sb=_dec->state.sbs;
-  sb_end=sb+_dec->state.nsbs;
-  run_count=npartial=0;
-  while(sb<sb_end){
+  sb_flags=_dec->state.sb_flags;
+  nsbs=_dec->state.nsbs;
+  sbi=npartial=0;
+  while(sbi<nsbs){
     int full_run;
     run_count=oc_sb_run_unpack(&_dec->opb);
     full_run=run_count>=4129;
     do{
-      sb->coded_partially=flag;
-      sb->coded_fully=0;
+      sb_flags[sbi].coded_partially=flag;
+      sb_flags[sbi].coded_fully=0;
       npartial+=flag;
-      sb++;
+      sbi++;
     }
-    while(--run_count>0&&sb<sb_end);
-    if(full_run&&sb<sb_end){
-      theorapackB_read1(&_dec->opb,&val);
+    while(--run_count>0&&sbi<nsbs);
+    if(full_run&&sbi<nsbs){
+      val=oc_pack_read1(&_dec->opb);
       flag=(int)val;
     }
     else flag=!flag;
   }
   /*TODO: run_count should be 0 here.
     If it's not, we should issue a warning of some kind.*/
   return npartial;
 }
 
 /*Decodes the bit flags for whether or not each non-partially-coded super
    block is fully coded or not.
   This function should only be called if there is at least one
    non-partially-coded super block.
   Return: The number of partially coded super blocks.*/
 static void oc_dec_coded_sb_flags_unpack(oc_dec_ctx *_dec){
-  oc_sb *sb;
-  oc_sb *sb_end;
-  long   val;
-  int    flag;
-  int    run_count;
-  sb=_dec->state.sbs;
-  sb_end=sb+_dec->state.nsbs;
+  oc_sb_flags *sb_flags;
+  unsigned     nsbs;
+  unsigned     sbi;
+  unsigned     run_count;
+  long         val;
+  int          flag;
+  sb_flags=_dec->state.sb_flags;
+  nsbs=_dec->state.nsbs;
   /*Skip partially coded super blocks.*/
-  for(;sb->coded_partially;sb++);
-  theorapackB_read1(&_dec->opb,&val);
+  for(sbi=0;sb_flags[sbi].coded_partially;sbi++);
+  val=oc_pack_read1(&_dec->opb);
   flag=(int)val;
-  while(sb<sb_end){
+  do{
     int full_run;
     run_count=oc_sb_run_unpack(&_dec->opb);
     full_run=run_count>=4129;
-    for(;sb<sb_end;sb++){
-      if(sb->coded_partially)continue;
+    for(;sbi<nsbs;sbi++){
+      if(sb_flags[sbi].coded_partially)continue;
       if(run_count--<=0)break;
-      sb->coded_fully=flag;
+      sb_flags[sbi].coded_fully=flag;
     }
-    if(full_run&&sb<sb_end){
-      theorapackB_read1(&_dec->opb,&val);
+    if(full_run&&sbi<nsbs){
+      val=oc_pack_read1(&_dec->opb);
       flag=(int)val;
     }
     else flag=!flag;
   }
+  while(sbi<nsbs);
   /*TODO: run_count should be 0 here.
     If it's not, we should issue a warning of some kind.*/
 }
 
 static void oc_dec_coded_flags_unpack(oc_dec_ctx *_dec){
-  oc_sb *sb;
-  oc_sb *sb_end;
-  long   val;
-  int    npartial;
-  int    pli;
-  int    flag;
-  int    run_count;
-  int    ncoded_fragis;
-  int    prev_ncoded_fragis;
-  int    nuncoded_fragis;
-  int    prev_nuncoded_fragis;
+  const oc_sb_map   *sb_maps;
+  const oc_sb_flags *sb_flags;
+  oc_fragment       *frags;
+  unsigned           nsbs;
+  unsigned           sbi;
+  unsigned           npartial;
+  long               val;
+  int                pli;
+  int                flag;
+  int                run_count;
+  ptrdiff_t         *coded_fragis;
+  ptrdiff_t         *uncoded_fragis;
+  ptrdiff_t          ncoded_fragis;
+  ptrdiff_t          nuncoded_fragis;
+  ptrdiff_t          prev_ncoded_fragis;
   npartial=oc_dec_partial_sb_flags_unpack(_dec);
   if(npartial<_dec->state.nsbs)oc_dec_coded_sb_flags_unpack(_dec);
   if(npartial>0){
-    theorapackB_read1(&_dec->opb,&val);
+    val=oc_pack_read1(&_dec->opb);
     flag=!(int)val;
   }
   else flag=0;
-  run_count=0;
-  prev_ncoded_fragis=ncoded_fragis=prev_nuncoded_fragis=nuncoded_fragis=0;
-  sb=sb_end=_dec->state.sbs;
+  sb_maps=(const oc_sb_map *)_dec->state.sb_maps;
+  sb_flags=_dec->state.sb_flags;
+  frags=_dec->state.frags;
+  sbi=nsbs=run_count=0;
+  coded_fragis=_dec->state.coded_fragis;
+  uncoded_fragis=coded_fragis+_dec->state.nfrags;
+  prev_ncoded_fragis=ncoded_fragis=nuncoded_fragis=0;
   for(pli=0;pli<3;pli++){
-    const oc_fragment_plane *fplane;
-    fplane=_dec->state.fplanes+pli;
-    sb_end+=fplane->nsbs;
-    for(;sb<sb_end;sb++){
+    nsbs+=_dec->state.fplanes[pli].nsbs;
+    for(;sbi<nsbs;sbi++){
       int quadi;
-      for(quadi=0;quadi<4;quadi++)if(sb->quad_valid&1<<quadi){
+      for(quadi=0;quadi<4;quadi++)if(sb_flags[sbi].quad_valid&1<<quadi){
         int bi;
         for(bi=0;bi<4;bi++){
-          int fragi;
-          fragi=sb->map[quadi][bi];
+          ptrdiff_t fragi;
+          fragi=sb_maps[sbi][quadi][bi];
           if(fragi>=0){
-            oc_fragment *frag;
-            frag=_dec->state.frags+fragi;
-            if(sb->coded_fully)frag->coded=1;
-            else if(!sb->coded_partially)frag->coded=0;
+            int coded;
+            if(sb_flags[sbi].coded_fully)coded=1;
+            else if(!sb_flags[sbi].coded_partially)coded=0;
             else{
               if(run_count<=0){
                 run_count=oc_block_run_unpack(&_dec->opb);
                 flag=!flag;
               }
               run_count--;
-              frag->coded=flag;
+              coded=flag;
             }
-            if(frag->coded)_dec->state.coded_fragis[ncoded_fragis++]=fragi;
-            else *(_dec->state.uncoded_fragis-++nuncoded_fragis)=fragi;
+            if(coded)coded_fragis[ncoded_fragis++]=fragi;
+            else *(uncoded_fragis-++nuncoded_fragis)=fragi;
+            frags[fragi].coded=coded;
           }
         }
       }
     }
     _dec->state.ncoded_fragis[pli]=ncoded_fragis-prev_ncoded_fragis;
     prev_ncoded_fragis=ncoded_fragis;
-    _dec->state.nuncoded_fragis[pli]=nuncoded_fragis-prev_nuncoded_fragis;
-    prev_nuncoded_fragis=nuncoded_fragis;
   }
+  _dec->state.ntotal_coded_fragis=ncoded_fragis;
   /*TODO: run_count should be 0 here.
     If it's not, we should issue a warning of some kind.*/
 }
 
 
 
-typedef int (*oc_mode_unpack_func)(oggpack_buffer *_opb);
+typedef int (*oc_mode_unpack_func)(oc_pack_buf *_opb);
 
-static int oc_vlc_mode_unpack(oggpack_buffer *_opb){
+static int oc_vlc_mode_unpack(oc_pack_buf *_opb){
   long val;
   int  i;
   for(i=0;i<7;i++){
-    theorapackB_read1(_opb,&val);
+    val=oc_pack_read1(_opb);
     if(!val)break;
   }
   return i;
 }
 
-static int oc_clc_mode_unpack(oggpack_buffer *_opb){
+static int oc_clc_mode_unpack(oc_pack_buf *_opb){
   long val;
-  theorapackB_read(_opb,3,&val);
+  val=oc_pack_read(_opb,3);
   return (int)val;
 }
 
 /*Unpacks the list of macro block modes for INTER frames.*/
 static void oc_dec_mb_modes_unpack(oc_dec_ctx *_dec){
+  const oc_mb_map     *mb_maps;
+  signed char         *mb_modes;
+  const oc_fragment   *frags;
+  const unsigned char *alphabet;
+  unsigned char        scheme0_alphabet[8];
   oc_mode_unpack_func  mode_unpack;
-  oc_mb               *mb;
-  oc_mb               *mb_end;
-  const int           *alphabet;
+  size_t               nmbs;
+  size_t               mbi;
   long                 val;
-  int                  scheme0_alphabet[8];
   int                  mode_scheme;
-  theorapackB_read(&_dec->opb,3,&val);
+  val=oc_pack_read(&_dec->opb,3);
   mode_scheme=(int)val;
   if(mode_scheme==0){
     int mi;
     /*Just in case, initialize the modes to something.
       If the bitstream doesn't contain each index exactly once, it's likely
        corrupt and the rest of the packet is garbage anyway, but this way we
        won't crash, and we'll decode SOMETHING.*/
-    /*LOOP VECTORIZES.*/
+    /*LOOP VECTORIZES*/
     for(mi=0;mi<OC_NMODES;mi++)scheme0_alphabet[mi]=OC_MODE_INTER_NOMV;
     for(mi=0;mi<OC_NMODES;mi++){
-      theorapackB_read(&_dec->opb,3,&val);
+      val=oc_pack_read(&_dec->opb,3);
       scheme0_alphabet[val]=OC_MODE_ALPHABETS[6][mi];
     }
     alphabet=scheme0_alphabet;
   }
   else alphabet=OC_MODE_ALPHABETS[mode_scheme-1];
   if(mode_scheme==7)mode_unpack=oc_clc_mode_unpack;
   else mode_unpack=oc_vlc_mode_unpack;
-  mb=_dec->state.mbs;
-  mb_end=mb+_dec->state.nmbs;
-  for(;mb<mb_end;mb++){
-    if(mb->mode!=OC_MODE_INVALID){
+  mb_modes=_dec->state.mb_modes;
+  mb_maps=(const oc_mb_map *)_dec->state.mb_maps;
+  nmbs=_dec->state.nmbs;
+  frags=_dec->state.frags;
+  for(mbi=0;mbi<nmbs;mbi++){
+    if(mb_modes[mbi]!=OC_MODE_INVALID){
       int bi;
-      for(bi=0;bi<4;bi++){
-        int fragi;
-        fragi=mb->map[0][bi];
-        if(fragi>=0&&_dec->state.frags[fragi].coded)break;
-      }
-      if(bi<4)mb->mode=alphabet[(*mode_unpack)(&_dec->opb)];
-      else mb->mode=OC_MODE_INTER_NOMV;
+      /*Check for a coded luma block in this macro block.*/
+      for(bi=0;bi<4&&!frags[mb_maps[mbi][0][bi]].coded;bi++);
+      /*We found one, decode a mode.*/
+      if(bi<4)mb_modes[mbi]=alphabet[(*mode_unpack)(&_dec->opb)];
+      /*There were none: INTER_NOMV is forced.*/
+      else mb_modes[mbi]=OC_MODE_INTER_NOMV;
     }
   }
 }
 
 
 
-typedef int (*oc_mv_comp_unpack_func)(oggpack_buffer *_opb);
+typedef int (*oc_mv_comp_unpack_func)(oc_pack_buf *_opb);
 
-static int oc_vlc_mv_comp_unpack(oggpack_buffer *_opb){
+static int oc_vlc_mv_comp_unpack(oc_pack_buf *_opb){
   long bits;
-  int  mvsigned[2];
-  theorapackB_read(_opb,3,&bits);
+  int  mask;
+  int  mv;
+  bits=oc_pack_read(_opb,3);
   switch(bits){
     case  0:return 0;
     case  1:return 1;
     case  2:return -1;
     case  3:
     case  4:{
-      mvsigned[0]=(int)(bits-1);
-      theorapackB_read1(_opb,&bits);
+      mv=(int)(bits-1);
+      bits=oc_pack_read1(_opb);
     }break;
     /*case  5:
     case  6:
     case  7:*/
     default:{
-      mvsigned[0]=1<<bits-3;
-      theorapackB_read(_opb,bits-2,&bits);
-      mvsigned[0]+=(int)(bits>>1);
+      mv=1<<bits-3;
+      bits=oc_pack_read(_opb,bits-2);
+      mv+=(int)(bits>>1);
       bits&=1;
     }break;
   }
-  mvsigned[1]=-mvsigned[0];
-  return mvsigned[bits];
+  mask=-(int)bits;
+  return mv+mask^mask;
 }
 
-static int oc_clc_mv_comp_unpack(oggpack_buffer *_opb){
+static int oc_clc_mv_comp_unpack(oc_pack_buf *_opb){
   long bits;
-  int  mvsigned[2];
-  theorapackB_read(_opb,6,&bits);
-  mvsigned[0]=bits>>1;
-  mvsigned[1]=-mvsigned[0];
-  return mvsigned[bits&1];
+  int  mask;
+  int  mv;
+  bits=oc_pack_read(_opb,6);
+  mv=(int)bits>>1;
+  mask=-((int)bits&1);
+  return mv+mask^mask;
 }
 
 /*Unpacks the list of motion vectors for INTER frames, and propagtes the macro
    block modes and motion vectors to the individual fragments.*/
 static void oc_dec_mv_unpack_and_frag_modes_fill(oc_dec_ctx *_dec){
+  const oc_mb_map        *mb_maps;
+  const signed char      *mb_modes;
   oc_set_chroma_mvs_func  set_chroma_mvs;
   oc_mv_comp_unpack_func  mv_comp_unpack;
-  oc_mb                  *mb;
-  oc_mb                  *mb_end;
-  const int              *map_idxs;
-  long                    val;
+  oc_fragment            *frags;
+  oc_mv                  *frag_mvs;
+  const unsigned char    *map_idxs;
   int                     map_nidxs;
   oc_mv                   last_mv[2];
   oc_mv                   cbmvs[4];
+  size_t                  nmbs;
+  size_t                  mbi;
+  long                    val;
   set_chroma_mvs=OC_SET_CHROMA_MVS_TABLE[_dec->state.info.pixel_fmt];
-  theorapackB_read1(&_dec->opb,&val);
+  val=oc_pack_read1(&_dec->opb);
   mv_comp_unpack=val?oc_clc_mv_comp_unpack:oc_vlc_mv_comp_unpack;
   map_idxs=OC_MB_MAP_IDXS[_dec->state.info.pixel_fmt];
   map_nidxs=OC_MB_MAP_NIDXS[_dec->state.info.pixel_fmt];
   memset(last_mv,0,sizeof(last_mv));
-  mb=_dec->state.mbs;
-  mb_end=mb+_dec->state.nmbs;
-  for(;mb<mb_end;mb++)if(mb->mode!=OC_MODE_INVALID){
-    oc_fragment *frag;
-    oc_mv        mbmv;
-    int          coded[13];
-    int          codedi;
-    int          ncoded;
-    int          mapi;
-    int          mapii;
-    int          fragi;
+  frags=_dec->state.frags;
+  frag_mvs=_dec->state.frag_mvs;
+  mb_maps=(const oc_mb_map *)_dec->state.mb_maps;
+  mb_modes=_dec->state.mb_modes;
+  nmbs=_dec->state.nmbs;
+  for(mbi=0;mbi<nmbs;mbi++){
     int          mb_mode;
-    /*Search for at least one coded fragment.*/
-    ncoded=mapii=0;
-    do{
-      mapi=map_idxs[mapii];
-      fragi=mb->map[mapi>>2][mapi&3];
-      if(fragi>=0&&_dec->state.frags[fragi].coded)coded[ncoded++]=mapi;
-    }
-    while(++mapii<map_nidxs);
-    if(ncoded<=0)continue;
-    mb_mode=mb->mode;
-    switch(mb_mode){
-      case OC_MODE_INTER_MV_FOUR:{
-        oc_mv       lbmvs[4];
-        int         bi;
-        /*Mark the tail of the list, so we don't accidentally go past it.*/
-        coded[ncoded]=-1;
-        for(bi=codedi=0;bi<4;bi++){
-          if(coded[codedi]==bi){
-            codedi++;
-            frag=_dec->state.frags+mb->map[0][bi];
-            frag->mbmode=mb_mode;
-            frag->mv[0]=lbmvs[bi][0]=(signed char)(*mv_comp_unpack)(&_dec->opb);
-            frag->mv[1]=lbmvs[bi][1]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+    mb_mode=mb_modes[mbi];
+    if(mb_mode!=OC_MODE_INVALID){
+      oc_mv        mbmv;
+      ptrdiff_t    fragi;
+      int          coded[13];
+      int          codedi;
+      int          ncoded;
+      int          mapi;
+      int          mapii;
+      /*Search for at least one coded fragment.*/
+      ncoded=mapii=0;
+      do{
+        mapi=map_idxs[mapii];
+        fragi=mb_maps[mbi][mapi>>2][mapi&3];
+        if(frags[fragi].coded)coded[ncoded++]=mapi;
+      }
+      while(++mapii<map_nidxs);
+      if(ncoded<=0)continue;
+      switch(mb_mode){
+        case OC_MODE_INTER_MV_FOUR:{
+          oc_mv       lbmvs[4];
+          int         bi;
+          /*Mark the tail of the list, so we don't accidentally go past it.*/
+          coded[ncoded]=-1;
+          for(bi=codedi=0;bi<4;bi++){
+            if(coded[codedi]==bi){
+              codedi++;
+              fragi=mb_maps[mbi][0][bi];
+              frags[fragi].mb_mode=mb_mode;
+              lbmvs[bi][0]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+              lbmvs[bi][1]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+              memcpy(frag_mvs[fragi],lbmvs[bi],sizeof(lbmvs[bi]));
+            }
+            else lbmvs[bi][0]=lbmvs[bi][1]=0;
           }
-          else lbmvs[bi][0]=lbmvs[bi][1]=0;
-        }
-        if(codedi>0){
-          last_mv[1][0]=last_mv[0][0];
-          last_mv[1][1]=last_mv[0][1];
-          last_mv[0][0]=lbmvs[coded[codedi-1]][0];
-          last_mv[0][1]=lbmvs[coded[codedi-1]][1];
+          if(codedi>0){
+            memcpy(last_mv[1],last_mv[0],sizeof(last_mv[1]));
+            memcpy(last_mv[0],lbmvs[coded[codedi-1]],sizeof(last_mv[0]));
+          }
+          if(codedi<ncoded){
+            (*set_chroma_mvs)(cbmvs,(const oc_mv *)lbmvs);
+            for(;codedi<ncoded;codedi++){
+              mapi=coded[codedi];
+              bi=mapi&3;
+              fragi=mb_maps[mbi][mapi>>2][bi];
+              frags[fragi].mb_mode=mb_mode;
+              memcpy(frag_mvs[fragi],cbmvs[bi],sizeof(cbmvs[bi]));
+            }
+          }
+        }break;
+        case OC_MODE_INTER_MV:{
+          memcpy(last_mv[1],last_mv[0],sizeof(last_mv[1]));
+          mbmv[0]=last_mv[0][0]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+          mbmv[1]=last_mv[0][1]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+        }break;
+        case OC_MODE_INTER_MV_LAST:memcpy(mbmv,last_mv[0],sizeof(mbmv));break;
+        case OC_MODE_INTER_MV_LAST2:{
+          memcpy(mbmv,last_mv[1],sizeof(mbmv));
+          memcpy(last_mv[1],last_mv[0],sizeof(last_mv[1]));
+          memcpy(last_mv[0],mbmv,sizeof(last_mv[0]));
+        }break;
+        case OC_MODE_GOLDEN_MV:{
+          mbmv[0]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+          mbmv[1]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+        }break;
+        default:memset(mbmv,0,sizeof(mbmv));break;
+      }
+      /*4MV mode fills in the fragments itself.
+        For all other modes we can use this common code.*/
+      if(mb_mode!=OC_MODE_INTER_MV_FOUR){
+        for(codedi=0;codedi<ncoded;codedi++){
+          mapi=coded[codedi];
+          fragi=mb_maps[mbi][mapi>>2][mapi&3];
+          frags[fragi].mb_mode=mb_mode;
+          memcpy(frag_mvs[fragi],mbmv,sizeof(mbmv));
         }
-        if(codedi<ncoded){
-          (*set_chroma_mvs)(cbmvs,(const oc_mv *)lbmvs);
-          for(;codedi<ncoded;codedi++){
-            mapi=coded[codedi];
-            bi=mapi&3;
-            frag=_dec->state.frags+mb->map[mapi>>2][bi];
-            frag->mbmode=mb_mode;
-            frag->mv[0]=cbmvs[bi][0];
-            frag->mv[1]=cbmvs[bi][1];
-          }
-        }
-      }break;
-      case OC_MODE_INTER_MV:{
-        last_mv[1][0]=last_mv[0][0];
-        last_mv[1][1]=last_mv[0][1];
-        mbmv[0]=last_mv[0][0]=(signed char)(*mv_comp_unpack)(&_dec->opb);
-        mbmv[1]=last_mv[0][1]=(signed char)(*mv_comp_unpack)(&_dec->opb);
-      }break;
-      case OC_MODE_INTER_MV_LAST:{
-        mbmv[0]=last_mv[0][0];
-        mbmv[1]=last_mv[0][1];
-      }break;
-      case OC_MODE_INTER_MV_LAST2:{
-        mbmv[0]=last_mv[1][0];
-        mbmv[1]=last_mv[1][1];
-        last_mv[1][0]=last_mv[0][0];
-        last_mv[1][1]=last_mv[0][1];
-        last_mv[0][0]=mbmv[0];
-        last_mv[0][1]=mbmv[1];
-      }break;
-      case OC_MODE_GOLDEN_MV:{
-        mbmv[0]=(signed char)(*mv_comp_unpack)(&_dec->opb);
-        mbmv[1]=(signed char)(*mv_comp_unpack)(&_dec->opb);
-      }break;
-      default:mbmv[0]=mbmv[1]=0;break;
-    }
-    /*4MV mode fills in the fragments itself.
-      For all other modes we can use this common code.*/
-    if(mb_mode!=OC_MODE_INTER_MV_FOUR){
-      for(codedi=0;codedi<ncoded;codedi++){
-        mapi=coded[codedi];
-        fragi=mb->map[mapi>>2][mapi&3];
-        frag=_dec->state.frags+fragi;
-        frag->mbmode=mb_mode;
-        frag->mv[0]=mbmv[0];
-        frag->mv[1]=mbmv[1];
       }
     }
   }
 }
 
 static void oc_dec_block_qis_unpack(oc_dec_ctx *_dec){
-  oc_fragment *frag;
-  int         *coded_fragi;
-  int         *coded_fragi_end;
-  int          ncoded_fragis;
-  ncoded_fragis=_dec->state.ncoded_fragis[0]+
-   _dec->state.ncoded_fragis[1]+_dec->state.ncoded_fragis[2];
+  oc_fragment     *frags;
+  const ptrdiff_t *coded_fragis;
+  ptrdiff_t        ncoded_fragis;
+  ptrdiff_t        fragii;
+  ptrdiff_t        fragi;
+  ncoded_fragis=_dec->state.ntotal_coded_fragis;
   if(ncoded_fragis<=0)return;
-  coded_fragi=_dec->state.coded_fragis;
-  coded_fragi_end=coded_fragi+ncoded_fragis;
+  frags=_dec->state.frags;
+  coded_fragis=_dec->state.coded_fragis;
   if(_dec->state.nqis==1){
-    /*If this frame has only a single qi value, then just set it in all coded
+    /*If this frame has only a single qi value, then just use it for all coded
        fragments.*/
-    while(coded_fragi<coded_fragi_end){
-      _dec->state.frags[*coded_fragi++].qi=_dec->state.qis[0];
+    for(fragii=0;fragii<ncoded_fragis;fragii++){
+      frags[coded_fragis[fragii]].qii=0;
     }
   }
   else{
     long val;
     int  flag;
     int  nqi1;
     int  run_count;
     /*Otherwise, we decode a qi index for each fragment, using two passes of
       the same binary RLE scheme used for super-block coded bits.
      The first pass marks each fragment as having a qii of 0 or greater than
       0, and the second pass (if necessary), distinguishes between a qii of
       1 and 2.
      At first we just store the qii in the fragment.
      After all the qii's are decoded, we make a final pass to replace them
       with the corresponding qi's for this frame.*/
-    theorapackB_read1(&_dec->opb,&val);
+    val=oc_pack_read1(&_dec->opb);
     flag=(int)val;
-    run_count=nqi1=0;
-    while(coded_fragi<coded_fragi_end){
+    nqi1=0;
+    fragii=0;
+    while(fragii<ncoded_fragis){
       int full_run;
       run_count=oc_sb_run_unpack(&_dec->opb);
       full_run=run_count>=4129;
       do{
-        _dec->state.frags[*coded_fragi++].qi=flag;
+        frags[coded_fragis[fragii++]].qii=flag;
         nqi1+=flag;
       }
-      while(--run_count>0&&coded_fragi<coded_fragi_end);
-      if(full_run&&coded_fragi<coded_fragi_end){
-        theorapackB_read1(&_dec->opb,&val);
+      while(--run_count>0&&fragii<ncoded_fragis);
+      if(full_run&&fragii<ncoded_fragis){
+        val=oc_pack_read1(&_dec->opb);
         flag=(int)val;
       }
       else flag=!flag;
     }
     /*TODO: run_count should be 0 here.
       If it's not, we should issue a warning of some kind.*/
     /*If we have 3 different qi's for this frame, and there was at least one
        fragment with a non-zero qi, make the second pass.*/
     if(_dec->state.nqis==3&&nqi1>0){
       /*Skip qii==0 fragments.*/
-      for(coded_fragi=_dec->state.coded_fragis;
-       _dec->state.frags[*coded_fragi].qi==0;coded_fragi++);
-      theorapackB_read1(&_dec->opb,&val);
+      for(fragii=0;frags[coded_fragis[fragii]].qii==0;fragii++);
+      val=oc_pack_read1(&_dec->opb);
       flag=(int)val;
-      while(coded_fragi<coded_fragi_end){
+      do{
         int full_run;
         run_count=oc_sb_run_unpack(&_dec->opb);
         full_run=run_count>=4129;
-        for(;coded_fragi<coded_fragi_end;coded_fragi++){
-          oc_fragment *frag;
-          frag=_dec->state.frags+*coded_fragi;
-          if(frag->qi==0)continue;
+        for(;fragii<ncoded_fragis;fragii++){
+          fragi=coded_fragis[fragii];
+          if(frags[fragi].qii==0)continue;
           if(run_count--<=0)break;
-          frag->qi+=flag;
+          frags[fragi].qii+=flag;
         }
-        if(full_run&&coded_fragi<coded_fragi_end){
-          theorapackB_read1(&_dec->opb,&val);
+        if(full_run&&fragii<ncoded_fragis){
+          val=oc_pack_read1(&_dec->opb);
           flag=(int)val;
         }
         else flag=!flag;
       }
+      while(fragii<ncoded_fragis);
       /*TODO: run_count should be 0 here.
         If it's not, we should issue a warning of some kind.*/
     }
-    /*Finally, translate qii's to qi's.*/
-    for(coded_fragi=_dec->state.coded_fragis;coded_fragi<coded_fragi_end;
-     coded_fragi++){
-      frag=_dec->state.frags+*coded_fragi;
-      frag->qi=_dec->state.qis[frag->qi];
-    }
   }
 }
 
 
 
-/*Returns the decoded value of the given token.
-  It CANNOT be called for any of the EOB tokens.
-  _token:      The token value to skip.
-  _extra_bits: The extra bits attached to this token.
-  Return: The decoded coefficient value.*/
-typedef int (*oc_token_dec1val_func)(int _token,int _extra_bits);
-
-/*Handles zero run tokens.*/
-static int oc_token_dec1val_zrl(void){
-  return 0;
-}
-
-/*Handles 1, -1, 2 and -2 tokens.*/
-static int oc_token_dec1val_const(int _token){
-  static const int CONST_VALS[4]={1,-1,2,-2};
-  return CONST_VALS[_token-OC_NDCT_ZRL_TOKEN_MAX];
-}
-
-/*Handles DCT value tokens category 2.*/
-static int oc_token_dec1val_cat2(int _token,int _extra_bits){
-  int valsigned[2];
-  valsigned[0]=_token-OC_DCT_VAL_CAT2+3;
-  valsigned[1]=-valsigned[0];
-  return valsigned[_extra_bits];
-}
-
-/*Handles DCT value tokens categories 3 through 8.*/
-static int oc_token_dec1val_cati(int _token,int _extra_bits){
-  static const int VAL_CAT_OFFS[6]={
-    OC_NDCT_VAL_CAT2_SIZE+3,
-    OC_NDCT_VAL_CAT2_SIZE+5,
-    OC_NDCT_VAL_CAT2_SIZE+9,
-    OC_NDCT_VAL_CAT2_SIZE+17,
-    OC_NDCT_VAL_CAT2_SIZE+33,
-    OC_NDCT_VAL_CAT2_SIZE+65
-  };
-  static const int VAL_CAT_MASKS[6]={
-    0x001,0x003,0x007,0x00F,0x01F,0x1FF
-  };
-  static const int VAL_CAT_SHIFTS[6]={1,2,3,4,5,9};
-  int valsigned[2];
-  int cati;
-  cati=_token-OC_NDCT_VAL_CAT2_MAX;
-  valsigned[0]=VAL_CAT_OFFS[cati]+(_extra_bits&VAL_CAT_MASKS[cati]);
-  valsigned[1]=-valsigned[0];
-  return valsigned[_extra_bits>>VAL_CAT_SHIFTS[cati]&1];
-}
-
-/*A jump table for compute the first coefficient value the given token value
-   represents.*/
-static const oc_token_dec1val_func OC_TOKEN_DEC1VAL_TABLE[TH_NDCT_TOKENS-
- OC_NDCT_EOB_TOKEN_MAX]={
-  (oc_token_dec1val_func)oc_token_dec1val_zrl,
-  (oc_token_dec1val_func)oc_token_dec1val_zrl,
-  (oc_token_dec1val_func)oc_token_dec1val_const,
-  (oc_token_dec1val_func)oc_token_dec1val_const,
-  (oc_token_dec1val_func)oc_token_dec1val_const,
-  (oc_token_dec1val_func)oc_token_dec1val_const,
-  oc_token_dec1val_cat2,
-  oc_token_dec1val_cat2,
-  oc_token_dec1val_cat2,
-  oc_token_dec1val_cat2,
-  oc_token_dec1val_cati,
-  oc_token_dec1val_cati,
-  oc_token_dec1val_cati,
-  oc_token_dec1val_cati,
-  oc_token_dec1val_cati,
-  oc_token_dec1val_cati,
-  (oc_token_dec1val_func)oc_token_dec1val_zrl,
-  (oc_token_dec1val_func)oc_token_dec1val_zrl,
-  (oc_token_dec1val_func)oc_token_dec1val_zrl,
-  (oc_token_dec1val_func)oc_token_dec1val_zrl,
-  (oc_token_dec1val_func)oc_token_dec1val_zrl,
-  (oc_token_dec1val_func)oc_token_dec1val_zrl,
-  (oc_token_dec1val_func)oc_token_dec1val_zrl,
-  (oc_token_dec1val_func)oc_token_dec1val_zrl,
-  (oc_token_dec1val_func)oc_token_dec1val_zrl
-};
-
-/*Returns the decoded value of the given token.
-  It CANNOT be called for any of the EOB tokens.
-  _token:      The token value to skip.
-  _extra_bits: The extra bits attached to this token.
-  Return: The decoded coefficient value.*/
-static int oc_dct_token_dec1val(int _token,int _extra_bits){
-  return (*OC_TOKEN_DEC1VAL_TABLE[_token-OC_NDCT_EOB_TOKEN_MAX])(_token,
-   _extra_bits);
-}
-
 /*Unpacks the DC coefficient tokens.
   Unlike when unpacking the AC coefficient tokens, we actually need to decode
    the DC coefficient values now so that we can do DC prediction.
   _huff_idx:   The index of the Huffman table to use for each color plane.
   _ntoks_left: The number of tokens left to be decoded in each color plane for
                 each coefficient.
                This is updated as EOB tokens and zero run tokens are decoded.
   Return: The length of any outstanding EOB run.*/
-static int oc_dec_dc_coeff_unpack(oc_dec_ctx *_dec,int _huff_idxs[3],
- int _ntoks_left[3][64]){
-  long  val;
-  int  *coded_fragi;
-  int  *coded_fragi_end;
-  int   run_counts[64];
-  int   cfi;
-  int   eobi;
-  int   eobs;
-  int   ti;
-  int   ebi;
-  int   pli;
-  int   rli;
-  eobs=0;
-  ti=ebi=0;
-  coded_fragi_end=coded_fragi=_dec->state.coded_fragis;
+static ptrdiff_t oc_dec_dc_coeff_unpack(oc_dec_ctx *_dec,int _huff_idxs[2],
+ ptrdiff_t _ntoks_left[3][64]){
+  unsigned char   *dct_tokens;
+  oc_fragment     *frags;
+  const ptrdiff_t *coded_fragis;
+  ptrdiff_t        ncoded_fragis;
+  ptrdiff_t        fragii;
+  ptrdiff_t        eobs;
+  ptrdiff_t        ti;
+  int              pli;
+  dct_tokens=_dec->dct_tokens;
+  frags=_dec->state.frags;
+  coded_fragis=_dec->state.coded_fragis;
+  ncoded_fragis=fragii=eobs=ti=0;
   for(pli=0;pli<3;pli++){
-    coded_fragi_end+=_dec->state.ncoded_fragis[pli];
+    ptrdiff_t run_counts[64];
+    ptrdiff_t eob_count;
+    ptrdiff_t eobi;
+    int       rli;
+    ncoded_fragis+=_dec->state.ncoded_fragis[pli];
     memset(run_counts,0,sizeof(run_counts));
     _dec->eob_runs[pli][0]=eobs;
+    _dec->ti0[pli][0]=ti;
     /*Continue any previous EOB run, if there was one.*/
-    for(eobi=eobs;eobi-->0&&coded_fragi<coded_fragi_end;){
-      _dec->state.frags[*coded_fragi++].dc=0;
-    }
-    cfi=0;
-    while(eobs<_ntoks_left[pli][0]-cfi){
+    eobi=eobs;
+    if(ncoded_fragis-fragii<eobi)eobi=ncoded_fragis-fragii;
+    eob_count=eobi;
+    eobs-=eobi;
+    while(eobi-->0)frags[coded_fragis[fragii++]].dc=0;
+    while(fragii<ncoded_fragis){
       int token;
-      int neb;
+      int cw;
       int eb;
       int skip;
-      cfi+=eobs;
-      run_counts[63]+=eobs;
       token=oc_huff_token_decode(&_dec->opb,
-       _dec->huff_tables[_huff_idxs[pli]]);
-      _dec->dct_tokens[0][ti++]=(unsigned char)token;
-      neb=OC_DCT_TOKEN_EXTRA_BITS[token];
-      if(neb){
-        theorapackB_read(&_dec->opb,neb,&val);
-        eb=(int)val;
-        _dec->extra_bits[0][ebi++]=(ogg_uint16_t)eb;
+       _dec->huff_tables[_huff_idxs[pli+1>>1]]);
+      dct_tokens[ti++]=(unsigned char)token;
+      if(OC_DCT_TOKEN_NEEDS_MORE(token)){
+        eb=(int)oc_pack_read(&_dec->opb,
+         OC_INTERNAL_DCT_TOKEN_EXTRA_BITS[token]);
+        dct_tokens[ti++]=(unsigned char)eb;
+        if(token==OC_DCT_TOKEN_FAT_EOB)dct_tokens[ti++]=(unsigned char)(eb>>8);
+        eb<<=OC_DCT_TOKEN_EB_POS(token);
       }
       else eb=0;
-      skip=oc_dct_token_skip(token,eb);
-      if(skip<0){
-        eobs=eobi=-skip;
-        while(eobi-->0&&coded_fragi<coded_fragi_end){
-          _dec->state.frags[*coded_fragi++].dc=0;
-        }
+      cw=OC_DCT_CODE_WORD[token]+eb;
+      eobs=cw>>OC_DCT_CW_EOB_SHIFT&0xFFF;
+      if(cw==OC_DCT_CW_FINISH)eobs=OC_DCT_EOB_FINISH;
+      if(eobs){
+        eobi=OC_MINI(eobs,ncoded_fragis-fragii);
+        eob_count+=eobi;
+        eobs-=eobi;
+        while(eobi-->0)frags[coded_fragis[fragii++]].dc=0;
       }
       else{
-        run_counts[skip-1]++;
-        cfi++;
-        eobs=0;
-        _dec->state.frags[*coded_fragi++].dc=oc_dct_token_dec1val(token,eb);
+        int coeff;
+        skip=(unsigned char)(cw>>OC_DCT_CW_RLEN_SHIFT);
+        cw^=-(cw&1<<OC_DCT_CW_FLIP_BIT);
+        coeff=cw>>OC_DCT_CW_MAG_SHIFT;
+        if(skip)coeff=0;
+        run_counts[skip]++;
+        frags[coded_fragis[fragii++]].dc=coeff;
       }
     }
-    _dec->ti0[pli][0]=ti;
-    _dec->ebi0[pli][0]=ebi;
-    /*Set the EOB count to the portion of the last EOB run which extends past
-       this coefficient.*/
-    eobs=eobs+cfi-_ntoks_left[pli][0];
-    /*Add the portion of the last EOB which was included in this coefficient to
-       to the longest run length.*/
-    run_counts[63]+=_ntoks_left[pli][0]-cfi;
+    /*Add the total EOB count to the longest run length.*/
+    run_counts[63]+=eob_count;
     /*And convert the run_counts array to a moment table.*/
     for(rli=63;rli-->0;)run_counts[rli]+=run_counts[rli+1];
     /*Finally, subtract off the number of coefficients that have been
        accounted for by runs started in this coefficient.*/
     for(rli=64;rli-->0;)_ntoks_left[pli][rli]-=run_counts[rli];
   }
+  _dec->dct_tokens_count=ti;
   return eobs;
 }
 
 /*Unpacks the AC coefficient tokens.
   This can completely discard coefficient values while unpacking, and so is
    somewhat simpler than unpacking the DC coefficient tokens.
   _huff_idx:   The index of the Huffman table to use for each color plane.
   _ntoks_left: The number of tokens left to be decoded in each color plane for
                 each coefficient.
                This is updated as EOB tokens and zero run tokens are decoded.
   _eobs:       The length of any outstanding EOB run from previous
                 coefficients.
   Return: The length of any outstanding EOB run.*/
-static int oc_dec_ac_coeff_unpack(oc_dec_ctx *_dec,int _zzi,int _huff_idxs[3],
- int _ntoks_left[3][64],int _eobs){
-  long val;
-  int  run_counts[64];
-  int  cfi;
-  int  ti;
-  int  ebi;
-  int  pli;
-  int  rli;
-  ti=ebi=0;
+static int oc_dec_ac_coeff_unpack(oc_dec_ctx *_dec,int _zzi,int _huff_idxs[2],
+ ptrdiff_t _ntoks_left[3][64],ptrdiff_t _eobs){
+  unsigned char *dct_tokens;
+  ptrdiff_t      ti;
+  int            pli;
+  dct_tokens=_dec->dct_tokens;
+  ti=_dec->dct_tokens_count;
   for(pli=0;pli<3;pli++){
-    memset(run_counts,0,sizeof(run_counts));
+    ptrdiff_t run_counts[64];
+    ptrdiff_t eob_count;
+    size_t    ntoks_left;
+    size_t    ntoks;
+    int       rli;
     _dec->eob_runs[pli][_zzi]=_eobs;
-    cfi=0;
-    while(_eobs<_ntoks_left[pli][_zzi]-cfi){
+    _dec->ti0[pli][_zzi]=ti;
+    ntoks_left=_ntoks_left[pli][_zzi];
+    memset(run_counts,0,sizeof(run_counts));
+    eob_count=0;
+    ntoks=0;
+    while(ntoks+_eobs<ntoks_left){
       int token;
-      int neb;
+      int cw;
       int eb;
       int skip;
-      cfi+=_eobs;
-      run_counts[63]+=_eobs;
+      ntoks+=_eobs;
+      eob_count+=_eobs;
       token=oc_huff_token_decode(&_dec->opb,
-       _dec->huff_tables[_huff_idxs[pli]]);
-      _dec->dct_tokens[_zzi][ti++]=(unsigned char)token;
-      neb=OC_DCT_TOKEN_EXTRA_BITS[token];
-      if(neb){
-        theorapackB_read(&_dec->opb,neb,&val);
-        eb=(int)val;
-        _dec->extra_bits[_zzi][ebi++]=(ogg_uint16_t)eb;
+       _dec->huff_tables[_huff_idxs[pli+1>>1]]);
+      dct_tokens[ti++]=(unsigned char)token;
+      if(OC_DCT_TOKEN_NEEDS_MORE(token)){
+        eb=(int)oc_pack_read(&_dec->opb,
+         OC_INTERNAL_DCT_TOKEN_EXTRA_BITS[token]);
+        dct_tokens[ti++]=(unsigned char)eb;
+        if(token==OC_DCT_TOKEN_FAT_EOB)dct_tokens[ti++]=(unsigned char)(eb>>8);
+        eb<<=OC_DCT_TOKEN_EB_POS(token);
       }
       else eb=0;
-      skip=oc_dct_token_skip(token,eb);
-      if(skip<0)_eobs=-skip;
-      else{
-        run_counts[skip-1]++;
-        cfi++;
-        _eobs=0;
+      cw=OC_DCT_CODE_WORD[token]+eb;
+      skip=(unsigned char)(cw>>OC_DCT_CW_RLEN_SHIFT);
+      _eobs=cw>>OC_DCT_CW_EOB_SHIFT&0xFFF;
+      if(cw==OC_DCT_CW_FINISH)_eobs=OC_DCT_EOB_FINISH;
+      if(_eobs==0){
+        run_counts[skip]++;
+        ntoks++;
       }
     }
-    _dec->ti0[pli][_zzi]=ti;
-    _dec->ebi0[pli][_zzi]=ebi;
-    /*Set the EOB count to the portion of the last EOB run which extends past
-       this coefficient.*/
-    _eobs=_eobs+cfi-_ntoks_left[pli][_zzi];
-    /*Add the portion of the last EOB which was included in this coefficient to
-       to the longest run length.*/
-    run_counts[63]+=_ntoks_left[pli][_zzi]-cfi;
+    /*Add the portion of the last EOB run actually used by this coefficient.*/
+    eob_count+=ntoks_left-ntoks;
+    /*And remove it from the remaining EOB count.*/
+    _eobs-=ntoks_left-ntoks;
+    /*Add the total EOB count to the longest run length.*/
+    run_counts[63]+=eob_count;
     /*And convert the run_counts array to a moment table.*/
     for(rli=63;rli-->0;)run_counts[rli]+=run_counts[rli+1];
     /*Finally, subtract off the number of coefficients that have been
        accounted for by runs started in this coefficient.*/
     for(rli=64-_zzi;rli-->0;)_ntoks_left[pli][_zzi+rli]-=run_counts[rli];
   }
+  _dec->dct_tokens_count=ti;
   return _eobs;
 }
 
 /*Tokens describing the DCT coefficients that belong to each fragment are
    stored in the bitstream grouped by coefficient, not by fragment.
 
   This means that we either decode all the tokens in order, building up a
    separate coefficient list for each fragment as we go, and then go back and
    do the iDCT on each fragment, or we have to create separate lists of tokens
    for each coefficient, so that we can pull the next token required off the
    head of the appropriate list when decoding a specific fragment.
 
   The former was VP3's choice, and it meant 2*w*h extra storage for all the
    decoded coefficient values.
 
-  We take the second option, which lets us store just one or three bytes per
+  We take the second option, which lets us store just one to three bytes per
    token (generally far fewer than the number of coefficients, due to EOB
    tokens and zero runs), and which requires us to only maintain a counter for
    each of the 64 coefficients, instead of a counter for every fragment to
    determine where the next token goes.
 
-  Actually, we use 3 counters per coefficient, one for each color plane, so we
+  We actually use 3 counters per coefficient, one for each color plane, so we
    can decode all color planes simultaneously.
-
   This lets color conversion, etc., be done as soon as a full MCU (one or
    two super block rows) is decoded, while the image data is still in cache.*/
 
 static void oc_dec_residual_tokens_unpack(oc_dec_ctx *_dec){
-  static const int OC_HUFF_LIST_MAX[5]={1,6,15,28,64};
-  long val;
-  int  ntoks_left[3][64];
-  int  huff_idxs[3];
-  int  pli;
-  int  zzi;
-  int  hgi;
-  int  huffi_y;
-  int  huffi_c;
-  int  eobs;
+  static const unsigned char OC_HUFF_LIST_MAX[5]={1,6,15,28,64};
+  ptrdiff_t  ntoks_left[3][64];
+  int        huff_idxs[2];
+  ptrdiff_t  eobs;
+  long       val;
+  int        pli;
+  int        zzi;
+  int        hgi;
   for(pli=0;pli<3;pli++)for(zzi=0;zzi<64;zzi++){
     ntoks_left[pli][zzi]=_dec->state.ncoded_fragis[pli];
   }
-  theorapackB_read(&_dec->opb,4,&val);
-  huffi_y=(int)val;
-  theorapackB_read(&_dec->opb,4,&val);
-  huffi_c=(int)val;
-  huff_idxs[0]=huffi_y;
-  huff_idxs[1]=huff_idxs[2]=huffi_c;
+  val=oc_pack_read(&_dec->opb,4);
+  huff_idxs[0]=(int)val;
+  val=oc_pack_read(&_dec->opb,4);
+  huff_idxs[1]=(int)val;
   _dec->eob_runs[0][0]=0;
   eobs=oc_dec_dc_coeff_unpack(_dec,huff_idxs,ntoks_left);
-  theorapackB_read(&_dec->opb,4,&val);
-  huffi_y=(int)val;
-  theorapackB_read(&_dec->opb,4,&val);
-  huffi_c=(int)val;
+#if defined(HAVE_CAIRO)
+  _dec->telemetry_dc_bytes=oc_pack_bytes_left(&_dec->opb);
+#endif
+  val=oc_pack_read(&_dec->opb,4);
+  huff_idxs[0]=(int)val;
+  val=oc_pack_read(&_dec->opb,4);
+  huff_idxs[1]=(int)val;
   zzi=1;
   for(hgi=1;hgi<5;hgi++){
-    huff_idxs[0]=huffi_y+(hgi<<4);
-    huff_idxs[1]=huff_idxs[2]=huffi_c+(hgi<<4);
+    huff_idxs[0]+=16;
+    huff_idxs[1]+=16;
     for(;zzi<OC_HUFF_LIST_MAX[hgi];zzi++){
       eobs=oc_dec_ac_coeff_unpack(_dec,zzi,huff_idxs,ntoks_left,eobs);
     }
   }
   /*TODO: eobs should be exactly zero, or 4096 or greater.
     The second case occurs when an EOB run of size zero is encountered, which
-     gets treated as an infinite EOB run (where infinity is INT_MAX).
+     gets treated as an infinite EOB run (where infinity is PTRDIFF_MAX).
     If neither of these conditions holds, then a warning should be issued.*/
 }
 
 
-
-/*Expands a single token into the given coefficient list.
-  This fills in the zeros for zero runs as well as coefficient values, and
-   updates the index of the current coefficient.
-  It CANNOT be called for any of the EOB tokens.
-  _token:      The token value to expand.
-  _extra_bits: The extra bits associated with the token.
-  _dct_coeffs: The current list of coefficients, in zig-zag order.
-  _zzi:        A pointer to the zig-zag index of the next coefficient to write
-                to.
-               This is updated before the function returns.*/
-typedef void (*oc_token_expand_func)(int _token,int _extra_bits,
- ogg_int16_t _dct_coeffs[128],int *_zzi);
-
-/*Expands a zero run token.*/
-static void oc_token_expand_zrl(int _token,int _extra_bits,
- ogg_int16_t _dct_coeffs[128],int *_zzi){
-  int zzi;
-  zzi=*_zzi;
-  do _dct_coeffs[zzi++]=0;
-  while(_extra_bits-->0);
-  *_zzi=zzi;
-}
-
-/*Expands a constant, single-value token.*/
-static void oc_token_expand_const(int _token,int _extra_bits,
- ogg_int16_t _dct_coeffs[128],int *_zzi){
-  _dct_coeffs[(*_zzi)++]=(ogg_int16_t)oc_token_dec1val_const(_token);
-}
-
-/*Expands category 2 single-valued tokens.*/
-static void oc_token_expand_cat2(int _token,int _extra_bits,
- ogg_int16_t _dct_coeffs[128],int *_zzi){
-  _dct_coeffs[(*_zzi)++]=
-   (ogg_int16_t)oc_token_dec1val_cat2(_token,_extra_bits);
-}
-
-/*Expands category 3 through 8 single-valued tokens.*/
-static void oc_token_expand_cati(int _token,int _extra_bits,
- ogg_int16_t _dct_coeffs[128],int *_zzi){
-  _dct_coeffs[(*_zzi)++]=
-   (ogg_int16_t)oc_token_dec1val_cati(_token,_extra_bits);
-}
-
-/*Expands a category 1a zero run/value combo token.*/
-static void oc_token_expand_run_cat1a(int _token,int _extra_bits,
- ogg_int16_t _dct_coeffs[128],int *_zzi){
-  int zzi;
-  int rl;
-  zzi=*_zzi;
-  /*LOOP VECTORIZES.*/
-  for(rl=_token-OC_DCT_RUN_CAT1A+1;rl-->0;)_dct_coeffs[zzi++]=0;
-  _dct_coeffs[zzi++]=(ogg_int16_t)(1-(_extra_bits<<1));
-  *_zzi=zzi;
-}
-
-/*Expands all other zero run/value combo tokens.*/
-static void oc_token_expand_run(int _token,int _extra_bits,
- ogg_int16_t _dct_coeffs[128],int *_zzi){
-  static const int NZEROS_ADJUST[OC_NDCT_RUN_MAX-OC_DCT_RUN_CAT1B]={
-    6,10,1,2
-  };
-  static const int NZEROS_MASK[OC_NDCT_RUN_MAX-OC_DCT_RUN_CAT1B]={
-    3,7,0,1
-  };
-  static const int VALUE_SHIFT[OC_NDCT_RUN_MAX-OC_DCT_RUN_CAT1B]={
-    0,0,0,1
-  };
-  static const int VALUE_MASK[OC_NDCT_RUN_MAX-OC_DCT_RUN_CAT1B]={
-    0,0,1,1
-  };
-  static const int VALUE_ADJUST[OC_NDCT_RUN_MAX-OC_DCT_RUN_CAT1B]={
-    1,1,2,2
-  };
-  static const int SIGN_SHIFT[OC_NDCT_RUN_MAX-OC_DCT_RUN_CAT1B]={
-    2,3,1,2
-  };
-  int valsigned[2];
-  int zzi;
-  int rl;
-  _token-=OC_DCT_RUN_CAT1B;
-  rl=(_extra_bits&NZEROS_MASK[_token])+NZEROS_ADJUST[_token];
-  zzi=*_zzi;
-  /*LOOP VECTORIZES.*/
-  while(rl-->0)_dct_coeffs[zzi++]=0;
-  valsigned[0]=VALUE_ADJUST[_token]+
-   (_extra_bits>>VALUE_SHIFT[_token]&VALUE_MASK[_token]);
-  valsigned[1]=-valsigned[0];
-  _dct_coeffs[zzi++]=(ogg_int16_t)valsigned[
-   _extra_bits>>SIGN_SHIFT[_token]];
-  *_zzi=zzi;
-}
-
-/*A jump table for expanding token values into coefficient values.
-  This reduces all the conditional branches, etc., needed to parse these token
-   values down to one indirect jump.*/
-static const oc_token_expand_func OC_TOKEN_EXPAND_TABLE[TH_NDCT_TOKENS-
- OC_NDCT_EOB_TOKEN_MAX]={
-  oc_token_expand_zrl,
-  oc_token_expand_zrl,
-  oc_token_expand_const,
-  oc_token_expand_const,
-  oc_token_expand_const,
-  oc_token_expand_const,
-  oc_token_expand_cat2,
-  oc_token_expand_cat2,
-  oc_token_expand_cat2,
-  oc_token_expand_cat2,
-  oc_token_expand_cati,
-  oc_token_expand_cati,
-  oc_token_expand_cati,
-  oc_token_expand_cati,
-  oc_token_expand_cati,
-  oc_token_expand_cati,
-  oc_token_expand_run_cat1a,
-  oc_token_expand_run_cat1a,
-  oc_token_expand_run_cat1a,
-  oc_token_expand_run_cat1a,
-  oc_token_expand_run_cat1a,
-  oc_token_expand_run,
-  oc_token_expand_run,
-  oc_token_expand_run,
-  oc_token_expand_run
-};
-
-/*Expands a single token into the given coefficient list.
-  This fills in the zeros for zero runs as well as coefficient values, and
-   updates the index of the current coefficient.
-  It CANNOT be called for any of the EOB tokens.
-  _token:      The token value to expand.
-  _extra_bits: The extra bits associated with the token.
-  _dct_coeffs: The current list of coefficients, in zig-zag order.
-  _zzi:        A pointer to the zig-zag index of the next coefficient to write
-                to.
-               This is updated before the function returns.*/
-static void oc_dct_token_expand(int _token,int _extra_bits,
- ogg_int16_t *_dct_coeffs,int *_zzi){
-  (*OC_TOKEN_EXPAND_TABLE[_token-OC_NDCT_EOB_TOKEN_MAX])(_token,
-   _extra_bits,_dct_coeffs,_zzi);
-}
-
-
-
 static int oc_dec_postprocess_init(oc_dec_ctx *_dec){
   /*pp_level 0: disabled; free any memory used and return*/
   if(_dec->pp_level<=OC_PP_LEVEL_DISABLED){
     if(_dec->dc_qis!=NULL){
       _ogg_free(_dec->dc_qis);
       _dec->dc_qis=NULL;
       _ogg_free(_dec->variances);
       _dec->variances=NULL;
@@ -1181,143 +1194,173 @@ static int oc_dec_postprocess_init(oc_de
     return 1;
   }
   if(_dec->dc_qis==NULL){
     /*If we haven't been tracking DC quantization indices, there's no point in
        starting now.*/
     if(_dec->state.frame_type!=OC_INTRA_FRAME)return 1;
     _dec->dc_qis=(unsigned char *)_ogg_malloc(
      _dec->state.nfrags*sizeof(_dec->dc_qis[0]));
+    if(_dec->dc_qis==NULL)return 1;
     memset(_dec->dc_qis,_dec->state.qis[0],_dec->state.nfrags);
   }
   else{
-    int           *coded_fragi;
-    int           *coded_fragi_end;
-    unsigned char  qi0;
+    unsigned char   *dc_qis;
+    const ptrdiff_t *coded_fragis;
+    ptrdiff_t        ncoded_fragis;
+    ptrdiff_t        fragii;
+    unsigned char    qi0;
     /*Update the DC quantization index of each coded block.*/
+    dc_qis=_dec->dc_qis;
+    coded_fragis=_dec->state.coded_fragis;
+    ncoded_fragis=_dec->state.ncoded_fragis[0]+
+     _dec->state.ncoded_fragis[1]+_dec->state.ncoded_fragis[2];
     qi0=(unsigned char)_dec->state.qis[0];
-    coded_fragi_end=_dec->state.coded_fragis+_dec->state.ncoded_fragis[0]+
-     _dec->state.ncoded_fragis[1]+_dec->state.ncoded_fragis[2];
-    for(coded_fragi=_dec->state.coded_fragis;coded_fragi<coded_fragi_end;
-     coded_fragi++){
-      _dec->dc_qis[*coded_fragi]=qi0;
+    for(fragii=0;fragii<ncoded_fragis;fragii++){
+      dc_qis[coded_fragis[fragii]]=qi0;
     }
   }
   /*pp_level 1: Stop after updating DC quantization indices.*/
   if(_dec->pp_level<=OC_PP_LEVEL_TRACKDCQI){
     if(_dec->variances!=NULL){
       _ogg_free(_dec->variances);
       _dec->variances=NULL;
       _ogg_free(_dec->pp_frame_data);
       _dec->pp_frame_data=NULL;
     }
     return 1;
   }
-  if(_dec->variances==NULL||
-   _dec->pp_frame_has_chroma!=(_dec->pp_level>=OC_PP_LEVEL_DEBLOCKC)){
+  if(_dec->variances==NULL){
     size_t frame_sz;
-    frame_sz=_dec->state.info.frame_width*_dec->state.info.frame_height;
+    size_t c_sz;
+    int    c_w;
+    int    c_h;
+    frame_sz=_dec->state.info.frame_width*(size_t)_dec->state.info.frame_height;
+    c_w=_dec->state.info.frame_width>>!(_dec->state.info.pixel_fmt&1);
+    c_h=_dec->state.info.frame_height>>!(_dec->state.info.pixel_fmt&2);
+    c_sz=c_w*(size_t)c_h;
+    /*Allocate space for the chroma planes, even if we're not going to use
+       them; this simplifies allocation state management, though it may waste
+       memory on the few systems that don't overcommit pages.*/
+    frame_sz+=c_sz<<1;
+    _dec->pp_frame_data=(unsigned char *)_ogg_malloc(
+     frame_sz*sizeof(_dec->pp_frame_data[0]));
+    _dec->variances=(int *)_ogg_malloc(
+     _dec->state.nfrags*sizeof(_dec->variances[0]));
+    if(_dec->variances==NULL||_dec->pp_frame_data==NULL){
+      _ogg_free(_dec->pp_frame_data);
+      _dec->pp_frame_data=NULL;
+      _ogg_free(_dec->variances);
+      _dec->variances=NULL;
+      return 1;
+    }
+    /*Force an update of the PP buffer pointers.*/
+    _dec->pp_frame_state=0;
+  }
+  /*Update the PP buffer pointers if necessary.*/
+  if(_dec->pp_frame_state!=1+(_dec->pp_level>=OC_PP_LEVEL_DEBLOCKC)){
     if(_dec->pp_level<OC_PP_LEVEL_DEBLOCKC){
-      _dec->variances=(int *)_ogg_realloc(_dec->variances,
-       _dec->state.fplanes[0].nfrags*sizeof(_dec->variances[0]));
-      _dec->pp_frame_data=(unsigned char *)_ogg_realloc(
-       _dec->pp_frame_data,frame_sz*sizeof(_dec->pp_frame_data[0]));
+      /*If chroma processing is disabled, just use the PP luma plane.*/
       _dec->pp_frame_buf[0].width=_dec->state.info.frame_width;
       _dec->pp_frame_buf[0].height=_dec->state.info.frame_height;
       _dec->pp_frame_buf[0].stride=-_dec->pp_frame_buf[0].width;
       _dec->pp_frame_buf[0].data=_dec->pp_frame_data+
-       (1-_dec->pp_frame_buf[0].height)*_dec->pp_frame_buf[0].stride;
+       (1-_dec->pp_frame_buf[0].height)*(ptrdiff_t)_dec->pp_frame_buf[0].stride;
     }
     else{
       size_t y_sz;
       size_t c_sz;
       int    c_w;
       int    c_h;
-      _dec->variances=(int *)_ogg_realloc(_dec->variances,
-       _dec->state.nfrags*sizeof(_dec->variances[0]));
-      y_sz=frame_sz;
+      /*Otherwise, set up pointers to all three PP planes.*/
+      y_sz=_dec->state.info.frame_width*(size_t)_dec->state.info.frame_height;
       c_w=_dec->state.info.frame_width>>!(_dec->state.info.pixel_fmt&1);
       c_h=_dec->state.info.frame_height>>!(_dec->state.info.pixel_fmt&2);
-      c_sz=c_w*c_h;
-      frame_sz+=c_sz<<1;
-      _dec->pp_frame_data=(unsigned char *)_ogg_realloc(
-       _dec->pp_frame_data,frame_sz*sizeof(_dec->pp_frame_data[0]));
+      c_sz=c_w*(size_t)c_h;
       _dec->pp_frame_buf[0].width=_dec->state.info.frame_width;
       _dec->pp_frame_buf[0].height=_dec->state.info.frame_height;
       _dec->pp_frame_buf[0].stride=_dec->pp_frame_buf[0].width;
       _dec->pp_frame_buf[0].data=_dec->pp_frame_data;
       _dec->pp_frame_buf[1].width=c_w;
       _dec->pp_frame_buf[1].height=c_h;
       _dec->pp_frame_buf[1].stride=_dec->pp_frame_buf[1].width;
       _dec->pp_frame_buf[1].data=_dec->pp_frame_buf[0].data+y_sz;
       _dec->pp_frame_buf[2].width=c_w;
       _dec->pp_frame_buf[2].height=c_h;
       _dec->pp_frame_buf[2].stride=_dec->pp_frame_buf[2].width;
       _dec->pp_frame_buf[2].data=_dec->pp_frame_buf[1].data+c_sz;
       oc_ycbcr_buffer_flip(_dec->pp_frame_buf,_dec->pp_frame_buf);
     }
-    _dec->pp_frame_has_chroma=(_dec->pp_level>=OC_PP_LEVEL_DEBLOCKC);
+    _dec->pp_frame_state=1+(_dec->pp_level>=OC_PP_LEVEL_DEBLOCKC);
   }
   /*If we're not processing chroma, copy the reference frame's chroma planes.*/
   if(_dec->pp_level<OC_PP_LEVEL_DEBLOCKC){
     memcpy(_dec->pp_frame_buf+1,
      _dec->state.ref_frame_bufs[_dec->state.ref_frame_idx[OC_FRAME_SELF]]+1,
      sizeof(_dec->pp_frame_buf[1])*2);
   }
   return 0;
 }
 
 
 
 typedef struct{
-  int  ti[3][64];
-  int  ebi[3][64];
-  int  eob_runs[3][64];
-  int  bounding_values[256];
-  int *coded_fragis[3];
-  int *uncoded_fragis[3];
-  int  fragy0[3];
-  int  fragy_end[3];
-  int  ncoded_fragis[3];
-  int  nuncoded_fragis[3];
-  int  pred_last[3][3];
-  int  mcu_nvfrags;
-  int  loop_filter;
-  int  pp_level;
+  int                 bounding_values[256];
+  ptrdiff_t           ti[3][64];
+  ptrdiff_t           eob_runs[3][64];
+  const ptrdiff_t    *coded_fragis[3];
+  const ptrdiff_t    *uncoded_fragis[3];
+  ptrdiff_t           ncoded_fragis[3];
+  ptrdiff_t           nuncoded_fragis[3];
+  const ogg_uint16_t *dequant[3][3][2];
+  int                 fragy0[3];
+  int                 fragy_end[3];
+  int                 pred_last[3][3];
+  int                 mcu_nvfrags;
+  int                 loop_filter;
+  int                 pp_level;
 }oc_dec_pipeline_state;
 
 
 
 /*Initialize the main decoding pipeline.*/
 static void oc_dec_pipeline_init(oc_dec_ctx *_dec,
  oc_dec_pipeline_state *_pipe){
-  int *coded_fragi_end;
-  int *uncoded_fragi_end;
-  int  pli;
+  const ptrdiff_t *coded_fragis;
+  const ptrdiff_t *uncoded_fragis;
+  int              pli;
+  int              qii;
+  int              qti;
   /*If chroma is sub-sampled in the vertical direction, we have to decode two
      super block rows of Y' for each super block row of Cb and Cr.*/
   _pipe->mcu_nvfrags=4<<!(_dec->state.info.pixel_fmt&2);
   /*Initialize the token and extra bits indices for each plane and
      coefficient.*/
-  memset(_pipe->ti[0],0,sizeof(_pipe->ti[0]));
-  memset(_pipe->ebi[0],0,sizeof(_pipe->ebi[0]));
-  for(pli=1;pli<3;pli++){
-    memcpy(_pipe->ti[pli],_dec->ti0[pli-1],sizeof(_pipe->ti[0]));
-    memcpy(_pipe->ebi[pli],_dec->ebi0[pli-1],sizeof(_pipe->ebi[0]));
-  }
+  memcpy(_pipe->ti,_dec->ti0,sizeof(_pipe->ti));
   /*Also copy over the initial the EOB run counts.*/
   memcpy(_pipe->eob_runs,_dec->eob_runs,sizeof(_pipe->eob_runs));
   /*Set up per-plane pointers to the coded and uncoded fragments lists.*/
-  coded_fragi_end=_dec->state.coded_fragis;
-  uncoded_fragi_end=_dec->state.uncoded_fragis;
+  coded_fragis=_dec->state.coded_fragis;
+  uncoded_fragis=coded_fragis+_dec->state.nfrags;
   for(pli=0;pli<3;pli++){
-    _pipe->coded_fragis[pli]=coded_fragi_end;
-    _pipe->uncoded_fragis[pli]=uncoded_fragi_end;
-    coded_fragi_end+=_dec->state.ncoded_fragis[pli];
-    uncoded_fragi_end-=_dec->state.nuncoded_fragis[pli];
+    ptrdiff_t ncoded_fragis;
+    _pipe->coded_fragis[pli]=coded_fragis;
+    _pipe->uncoded_fragis[pli]=uncoded_fragis;
+    ncoded_fragis=_dec->state.ncoded_fragis[pli];
+    coded_fragis+=ncoded_fragis;
+    uncoded_fragis+=ncoded_fragis-_dec->state.fplanes[pli].nfrags;
+  }
+  /*Set up condensed quantizer tables.*/
+  for(pli=0;pli<3;pli++){
+    for(qii=0;qii<_dec->state.nqis;qii++){
+      for(qti=0;qti<2;qti++){
+        _pipe->dequant[pli][qii][qti]=
+         _dec->state.dequant_tables[_dec->state.qis[qii]][pli][qti];
+      }
+    }
   }
   /*Set the previous DC predictor to 0 for all color planes and frame types.*/
   memset(_pipe->pred_last,0,sizeof(_pipe->pred_last));
   /*Initialize the bounding value array for the loop filter.*/
   _pipe->loop_filter=!oc_state_loop_filter_init(&_dec->state,
    _pipe->bounding_values);
   /*Initialize any buffers needed for post-processing.
     We also save the current post-processing level, to guard against the user
@@ -1334,126 +1377,229 @@ static void oc_dec_pipeline_init(oc_dec_
 }
 
 /*Undo the DC prediction in a single plane of an MCU (one or two super block
    rows).
   As a side effect, the number of coded and uncoded fragments in this plane of
    the MCU is also computed.*/
 static void oc_dec_dc_unpredict_mcu_plane(oc_dec_ctx *_dec,
  oc_dec_pipeline_state *_pipe,int _pli){
-  /*Undo the DC prediction.*/
-  oc_fragment_plane *fplane;
-  oc_fragment       *frag;
-  int               *pred_last;
-  int                ncoded_fragis;
-  int                fragx;
-  int                fragy;
-  int                fragy0;
-  int                fragy_end;
+  const oc_fragment_plane *fplane;
+  oc_fragment             *frags;
+  int                     *pred_last;
+  ptrdiff_t                ncoded_fragis;
+  ptrdiff_t                fragi;
+  int                      fragx;
+  int                      fragy;
+  int                      fragy0;
+  int                      fragy_end;
+  int                      nhfrags;
   /*Compute the first and last fragment row of the current MCU for this
      plane.*/
   fplane=_dec->state.fplanes+_pli;
   fragy0=_pipe->fragy0[_pli];
   fragy_end=_pipe->fragy_end[_pli];
-  frag=_dec->state.frags+fplane->froffset+(fragy0*fplane->nhfrags);
+  nhfrags=fplane->nhfrags;
+  pred_last=_pipe->pred_last[_pli];
+  frags=_dec->state.frags;
   ncoded_fragis=0;
-  pred_last=_pipe->pred_last[_pli];
+  fragi=fplane->froffset+fragy0*(ptrdiff_t)nhfrags;
   for(fragy=fragy0;fragy<fragy_end;fragy++){
-    for(fragx=0;fragx<fplane->nhfrags;fragx++,frag++){
-      if(!frag->coded)continue;
-      pred_last[OC_FRAME_FOR_MODE[frag->mbmode]]=frag->dc+=
-       oc_frag_pred_dc(frag,fplane,fragx,fragy,pred_last);
-      ncoded_fragis++;
+    if(fragy==0){
+      /*For the first row, all of the cases reduce to just using the previous
+         predictor for the same reference frame.*/
+      for(fragx=0;fragx<nhfrags;fragx++,fragi++){
+        if(frags[fragi].coded){
+          int ref;
+          ref=OC_FRAME_FOR_MODE(frags[fragi].mb_mode);
+          pred_last[ref]=frags[fragi].dc+=pred_last[ref];
+          ncoded_fragis++;
+        }
+      }
+    }
+    else{
+      oc_fragment *u_frags;
+      int          l_ref;
+      int          ul_ref;
+      int          u_ref;
+      u_frags=frags-nhfrags;
+      l_ref=-1;
+      ul_ref=-1;
+      u_ref=u_frags[fragi].coded?OC_FRAME_FOR_MODE(u_frags[fragi].mb_mode):-1;
+      for(fragx=0;fragx<nhfrags;fragx++,fragi++){
+        int ur_ref;
+        if(fragx+1>=nhfrags)ur_ref=-1;
+        else{
+          ur_ref=u_frags[fragi+1].coded?
+           OC_FRAME_FOR_MODE(u_frags[fragi+1].mb_mode):-1;
+        }
+        if(frags[fragi].coded){
+          int pred;
+          int ref;
+          ref=OC_FRAME_FOR_MODE(frags[fragi].mb_mode);
+          /*We break out a separate case based on which of our neighbors use
+             the same reference frames.
+            This is somewhat faster than trying to make a generic case which
+             handles all of them, since it reduces lots of poorly predicted
+             jumps to one switch statement, and also lets a number of the
+             multiplications be optimized out by strength reduction.*/
+          switch((l_ref==ref)|(ul_ref==ref)<<1|
+           (u_ref==ref)<<2|(ur_ref==ref)<<3){
+            default:pred=pred_last[ref];break;
+            case  1:
+            case  3:pred=frags[fragi-1].dc;break;
+            case  2:pred=u_frags[fragi-1].dc;break;
+            case  4:
+            case  6:
+            case 12:pred=u_frags[fragi].dc;break;
+            case  5:pred=(frags[fragi-1].dc+u_frags[fragi].dc)/2;break;
+            case  8:pred=u_frags[fragi+1].dc;break;
+            case  9:
+            case 11:
+            case 13:{
+              pred=(75*frags[fragi-1].dc+53*u_frags[fragi+1].dc)/128;
+            }break;
+            case 10:pred=(u_frags[fragi-1].dc+u_frags[fragi+1].dc)/2;break;
+            case 14:{
+              pred=(3*(u_frags[fragi-1].dc+u_frags[fragi+1].dc)
+               +10*u_frags[fragi].dc)/16;
+            }break;
+            case  7:
+            case 15:{
+              int p0;
+              int p1;
+              int p2;
+              p0=frags[fragi-1].dc;
+              p1=u_frags[fragi-1].dc;
+              p2=u_frags[fragi].dc;
+              pred=(29*(p0+p2)-26*p1)/32;
+              if(abs(pred-p2)>128)pred=p2;
+              else if(abs(pred-p0)>128)pred=p0;
+              else if(abs(pred-p1)>128)pred=p1;
+            }break;
+          }
+          pred_last[ref]=frags[fragi].dc+=pred;
+          ncoded_fragis++;
+          l_ref=ref;
+        }
+        else l_ref=-1;
+        ul_ref=u_ref;
+        u_ref=ur_ref;
+      }
     }
   }
   _pipe->ncoded_fragis[_pli]=ncoded_fragis;
   /*Also save the number of uncoded fragments so we know how many to copy.*/
   _pipe->nuncoded_fragis[_pli]=
-   (fragy_end-fragy0)*fplane->nhfrags-ncoded_fragis;
+   (fragy_end-fragy0)*(ptrdiff_t)nhfrags-ncoded_fragis;
 }
 
 /*Reconstructs all coded fragments in a single MCU (one or two super block
    rows).
   This requires that each coded fragment have a proper macro block mode and
    motion vector (if not in INTRA mode), and have it's DC value decoded, with
    the DC prediction process reversed, and the number of coded and uncoded
    fragments in this plane of the MCU be counted.
   The token lists for each color plane and coefficient should also be filled
    in, along with initial token offsets, extra bits offsets, and EOB run
    counts.*/
 static void oc_dec_frags_recon_mcu_plane(oc_dec_ctx *_dec,
  oc_dec_pipeline_state *_pipe,int _pli){
-  /*Decode the AC coefficients.*/
-  int *ti;
-  int *ebi;
-  int *eob_runs;
-  int *coded_fragi;
-  int *coded_fragi_end;
+  unsigned char       *dct_tokens;
+  const unsigned char *dct_fzig_zag;
+  ogg_uint16_t         dc_quant[2];
+  const oc_fragment   *frags;
+  const ptrdiff_t     *coded_fragis;
+  ptrdiff_t            ncoded_fragis;
+  ptrdiff_t            fragii;
+  ptrdiff_t           *ti;
+  ptrdiff_t           *eob_runs;
+  int                  qti;
+  dct_tokens=_dec->dct_tokens;
+  dct_fzig_zag=_dec->state.opt_data.dct_fzig_zag;
+  frags=_dec->state.frags;
+  coded_fragis=_pipe->coded_fragis[_pli];
+  ncoded_fragis=_pipe->ncoded_fragis[_pli];
   ti=_pipe->ti[_pli];
-  ebi=_pipe->ebi[_pli];
   eob_runs=_pipe->eob_runs[_pli];
-  coded_fragi_end=coded_fragi=_pipe->coded_fragis[_pli];
-  coded_fragi_end+=_pipe->ncoded_fragis[_pli];
-  for(;coded_fragi<coded_fragi_end;coded_fragi++){
-    oc_fragment    *frag;
-    oc_quant_table *iquants;
-    /*This array is made one bigger than necessary so that an invalid zero
-       run cannot cause a buffer overflow.
-      The inverse zig-zag mapping sends all out of range indices to the last
-       entry of this array, where they are ignored.*/
-    ogg_int16_t    dct_coeffs[128];
-    int            fragi;
-    int            zzi;
-    int            last_zzi;
-    fragi=*coded_fragi;
-    frag=_dec->state.frags+fragi;
+  for(qti=0;qti<2;qti++)dc_quant[qti]=_pipe->dequant[_pli][0][qti][0];
+  for(fragii=0;fragii<ncoded_fragis;fragii++){
+    /*This array is made one element larger because the zig-zag index array
+       uses the final element as a dumping ground for out-of-range indices
+       to protect us from buffer overflow.*/
+    OC_ALIGN8(ogg_int16_t dct_coeffs[65]);
+    const ogg_uint16_t *ac_quant;
+    ptrdiff_t           fragi;
+    int                 last_zzi;
+    int                 zzi;
+    fragi=coded_fragis[fragii];
+    for(zzi=0;zzi<64;zzi++)dct_coeffs[zzi]=0;
+    qti=frags[fragi].mb_mode!=OC_MODE_INTRA;
+    ac_quant=_pipe->dequant[_pli][frags[fragi].qii][qti];
+    /*Decode the AC coefficients.*/
     for(zzi=0;zzi<64;){
       int token;
-      int eb;
       last_zzi=zzi;
       if(eob_runs[zzi]){
         eob_runs[zzi]--;
         break;
       }
       else{
-        int ebflag;
-        token=_dec->dct_tokens[zzi][ti[zzi]++];
-        ebflag=OC_DCT_TOKEN_EXTRA_BITS[token]!=0;
-        eb=_dec->extra_bits[zzi][ebi[zzi]]&-ebflag;
-        ebi[zzi]+=ebflag;
-        if(token<OC_NDCT_EOB_TOKEN_MAX){
-          eob_runs[zzi]=-oc_dct_token_skip(token,eb);
+        ptrdiff_t eob;
+        int       cw;
+        int       rlen;
+        int       coeff;
+        int       lti;
+        lti=ti[zzi];
+        token=dct_tokens[lti++];
+        cw=OC_DCT_CODE_WORD[token];
+        /*These parts could be done branchless, but the branches are fairly
+           predictable and the C code translates into more than a few
+           instructions, so it's worth it to avoid them.*/
+        if(OC_DCT_TOKEN_NEEDS_MORE(token)){
+          cw+=dct_tokens[lti++]<<OC_DCT_TOKEN_EB_POS(token);
         }
-        else oc_dct_token_expand(token,eb,dct_coeffs,&zzi);
+        eob=cw>>OC_DCT_CW_EOB_SHIFT&0xFFF;
+        if(token==OC_DCT_TOKEN_FAT_EOB){
+          eob+=dct_tokens[lti++]<<8;
+          if(eob==0)eob=OC_DCT_EOB_FINISH;
+        }
+        rlen=(unsigned char)(cw>>OC_DCT_CW_RLEN_SHIFT);
+        cw^=-(cw&1<<OC_DCT_CW_FLIP_BIT);
+        coeff=cw>>OC_DCT_CW_MAG_SHIFT;
+        eob_runs[zzi]=eob;
+        ti[zzi]=lti;
+        zzi+=rlen;
+        dct_coeffs[dct_fzig_zag[zzi]]=(ogg_int16_t)(coeff*(int)ac_quant[zzi]);
+        zzi+=!eob;
       }
     }
     /*TODO: zzi should be exactly 64 here.
       If it's not, we should report some kind of warning.*/
     zzi=OC_MINI(zzi,64);
-    dct_coeffs[0]=(ogg_int16_t)frag->dc;
-    iquants=_dec->state.dequant_tables[frag->mbmode!=OC_MODE_INTRA][_pli];
+    dct_coeffs[0]=(ogg_int16_t)frags[fragi].dc;
     /*last_zzi is always initialized.
       If your compiler thinks otherwise, it is dumb.*/
-    oc_state_frag_recon(&_dec->state,frag,_pli,dct_coeffs,last_zzi,zzi,
-     iquants[_dec->state.qis[0]][0],iquants[frag->qi]);
+    oc_state_frag_recon(&_dec->state,fragi,_pli,
+     dct_coeffs,last_zzi,dc_quant[qti]);
   }
-  _pipe->coded_fragis[_pli]=coded_fragi;
+  _pipe->coded_fragis[_pli]+=ncoded_fragis;
   /*Right now the reconstructed MCU has only the coded blocks in it.*/
   /*TODO: We make the decision here to always copy the uncoded blocks into it
      from the reference frame.
     We could also copy the coded blocks back over the reference frame, if we
      wait for an additional MCU to be decoded, which might be faster if only a
      small number of blocks are coded.
     However, this introduces more latency, creating a larger cache footprint.
     It's unknown which decision is better, but this one results in simpler
      code, and the hard case (high bitrate, high resolution) is handled
      correctly.*/
   /*Copy the uncoded blocks from the previous reference frame.*/
   _pipe->uncoded_fragis[_pli]-=_pipe->nuncoded_fragis[_pli];
-  oc_state_frag_copy(&_dec->state,_pipe->uncoded_fragis[_pli],
+  oc_state_frag_copy_list(&_dec->state,_pipe->uncoded_fragis[_pli],
    _pipe->nuncoded_fragis[_pli],OC_FRAME_SELF,OC_FRAME_PREV,_pli);
 }
 
 /*Filter a horizontal block edge.*/
 static void oc_filter_hedge(unsigned char *_dst,int _dst_ystride,
  const unsigned char *_src,int _src_ystride,int _qstep,int _flimit,
  int *_variance0,int *_variance1){
   unsigned char       *rdst;
@@ -1534,130 +1680,139 @@ static void oc_filter_vedge(unsigned cha
       *rdst++=(unsigned char)(r[0]*2+r[1]+r[2]*2+r[3]+r[4]+r[5]+4>>3);
       for(bx=0;bx<4;bx++){
         *rdst++=(unsigned char)(r[bx]+r[bx+1]+r[bx+2]+r[bx+3]*2+
          r[bx+4]+r[bx+5]+r[bx+6]+4>>3);
       }
       *rdst++=(unsigned char)(r[4]+r[5]+r[6]+r[7]*2+r[8]+r[9]*2+4>>3);
       *rdst=(unsigned char)(r[5]+r[6]+r[7]+r[8]*2+r[9]*3+4>>3);
     }
-    else for(bx=1;bx<=8;bx++)*rdst++=(unsigned char)r[bx];
     cdst+=_dst_ystride;
   }
 }
 
 static void oc_dec_deblock_frag_rows(oc_dec_ctx *_dec,
  th_img_plane *_dst,th_img_plane *_src,int _pli,int _fragy0,
  int _fragy_end){
   oc_fragment_plane   *fplane;
   int                 *variance;
   unsigned char       *dc_qi;
   unsigned char       *dst;
   const unsigned char *src;
+  ptrdiff_t            froffset;
+  int                  dst_ystride;
+  int                  src_ystride;
+  int                  nhfrags;
+  int                  width;
   int                  notstart;
   int                  notdone;
-  int                  froffset;
   int                  flimit;
   int                  qstep;
   int                  y_end;
   int                  y;
   int                  x;
   _dst+=_pli;
   _src+=_pli;
   fplane=_dec->state.fplanes+_pli;
-  froffset=fplane->froffset+_fragy0*fplane->nhfrags;
+  nhfrags=fplane->nhfrags;
+  froffset=fplane->froffset+_fragy0*(ptrdiff_t)nhfrags;
   variance=_dec->variances+froffset;
   dc_qi=_dec->dc_qis+froffset;
   notstart=_fragy0>0;
   notdone=_fragy_end<fplane->nvfrags;
   /*We want to clear an extra row of variances, except at the end.*/
-  memset(variance+(fplane->nhfrags&-notstart),0,
-   (_fragy_end+notdone-_fragy0-notstart)*fplane->nhfrags*sizeof(variance[0]));
+  memset(variance+(nhfrags&-notstart),0,
+   (_fragy_end+notdone-_fragy0-notstart)*(nhfrags*sizeof(variance[0])));
   /*Except for the first time, we want to point to the middle of the row.*/
   y=(_fragy0<<3)+(notstart<<2);
-  dst=_dst->data+y*_dst->stride;
-  src=_src->data+y*_src->stride;
+  dst_ystride=_dst->stride;
+  src_ystride=_src->stride;
+  dst=_dst->data+y*(ptrdiff_t)dst_ystride;
+  src=_src->data+y*(ptrdiff_t)src_ystride;
+  width=_dst->width;
   for(;y<4;y++){
-    memcpy(dst,src,_dst->width*sizeof(dst[0]));
-    dst+=_dst->stride;
-    src+=_src->stride;
+    memcpy(dst,src,width*sizeof(dst[0]));
+    dst+=dst_ystride;
+    src+=src_ystride;
   }
   /*We also want to skip the last row in the frame for this loop.*/
   y_end=_fragy_end-!notdone<<3;
   for(;y<y_end;y+=8){
     qstep=_dec->pp_dc_scale[*dc_qi];
     flimit=(qstep*3)>>2;
-    oc_filter_hedge(dst,_dst->stride,src-_src->stride,_src->stride,
-     qstep,flimit,variance,variance+fplane->nhfrags);
+    oc_filter_hedge(dst,dst_ystride,src-src_ystride,src_ystride,
+     qstep,flimit,variance,variance+nhfrags);
     variance++;
     dc_qi++;
-    for(x=8;x<_dst->width;x+=8){
+    for(x=8;x<width;x+=8){
       qstep=_dec->pp_dc_scale[*dc_qi];
       flimit=(qstep*3)>>2;
-      oc_filter_hedge(dst+x,_dst->stride,src+x-_src->stride,_src->stride,
-       qstep,flimit,variance,variance+fplane->nhfrags);
-      oc_filter_vedge(dst+x-(_dst->stride<<2)-4,_dst->stride,
+      oc_filter_hedge(dst+x,dst_ystride,src+x-src_ystride,src_ystride,
+       qstep,flimit,variance,variance+nhfrags);
+      oc_filter_vedge(dst+x-(dst_ystride<<2)-4,dst_ystride,
        qstep,flimit,variance-1);
       variance++;
       dc_qi++;
     }
-    dst+=_dst->stride<<3;
-    src+=_src->stride<<3;
+    dst+=dst_ystride<<3;
+    src+=src_ystride<<3;
   }
   /*And finally, handle the last row in the frame, if it's in the range.*/
   if(!notdone){
-    for(;y<_dst->height;y++){
-      memcpy(dst,src,_dst->width*sizeof(dst[0]));
-      dst+=_dst->stride;
-      src+=_src->stride;
+    int height;
+    height=_dst->height;
+    for(;y<height;y++){
+      memcpy(dst,src,width*sizeof(dst[0]));
+      dst+=dst_ystride;
+      src+=src_ystride;
     }
     /*Filter the last row of vertical block edges.*/
     dc_qi++;
-    for(x=8;x<_dst->width;x+=8){
+    for(x=8;x<width;x+=8){
       qstep=_dec->pp_dc_scale[*dc_qi++];
       flimit=(qstep*3)>>2;
-      oc_filter_vedge(dst+x-(_dst->stride<<3)-4,_dst->stride,
+      oc_filter_vedge(dst+x-(dst_ystride<<3)-4,dst_ystride,
        qstep,flimit,variance++);
     }
   }
 }
 
 static void oc_dering_block(unsigned char *_idata,int _ystride,int _b,
  int _dc_scale,int _sharp_mod,int _strong){
-  static const int     OCDB_MOD_MAX[2]={24,32};
-  static const int     OCDB_MOD_SHIFT[2]={1,0};
+  static const unsigned char OC_MOD_MAX[2]={24,32};
+  static const unsigned char OC_MOD_SHIFT[2]={1,0};
   const unsigned char *psrc;
   const unsigned char *src;
   const unsigned char *nsrc;
   unsigned char       *dst;
   int                  vmod[72];
   int                  hmod[72];
   int                  mod_hi;
   int                  by;
   int                  bx;
-  mod_hi=OC_MINI(3*_dc_scale,OCDB_MOD_MAX[_strong]);
+  mod_hi=OC_MINI(3*_dc_scale,OC_MOD_MAX[_strong]);
   dst=_idata;
   src=dst;
   psrc=src-(_ystride&-!(_b&4));
   for(by=0;by<9;by++){
     for(bx=0;bx<8;bx++){
       int mod;
-      mod=32+_dc_scale-(abs(src[bx]-psrc[bx])<<OCDB_MOD_SHIFT[_strong]);
+      mod=32+_dc_scale-(abs(src[bx]-psrc[bx])<<OC_MOD_SHIFT[_strong]);
       vmod[(by<<3)+bx]=mod<-64?_sharp_mod:OC_CLAMPI(0,mod,mod_hi);
     }
     psrc=src;
     src+=_ystride&-(!(_b&8)|by<7);
   }
   nsrc=dst;
   psrc=dst-!(_b&1);
   for(bx=0;bx<9;bx++){
     src=nsrc;
     for(by=0;by<8;by++){
       int mod;
-      mod=32+_dc_scale-(abs(*src-*psrc)<<OCDB_MOD_SHIFT[_strong]);
+      mod=32+_dc_scale-(abs(*src-*psrc)<<OC_MOD_SHIFT[_strong]);
       hmod[(bx<<3)+by]=mod<-64?_sharp_mod:OC_CLAMPI(0,mod,mod_hi);
       psrc+=_ystride;
       src+=_ystride;
     }
     psrc=nsrc;
     nsrc+=!(_b&2)|bx<7;
   }
   src=dst;
@@ -1667,20 +1822,20 @@ static void oc_dering_block(unsigned cha
     int a;
     int b;
     int w;
     a=128;
     b=64;
     w=hmod[by];
     a-=w;
     b+=w**(src-!(_b&1));
-    w=vmod[(by<<3)];
+    w=vmod[by<<3];
     a-=w;
     b+=w*psrc[0];
-    w=vmod[(by+1<<3)];
+    w=vmod[by+1<<3];
     a-=w;
     b+=w*nsrc[0];
     w=hmod[(1<<3)+by];
     a-=w;
     b+=w*src[1];
     dst[0]=OC_CLAMP255(a*src[0]+b>>7);
     for(bx=1;bx<7;bx++){
       a=128;
@@ -1728,76 +1883,83 @@ static void oc_dering_block(unsigned cha
 
 static void oc_dec_dering_frag_rows(oc_dec_ctx *_dec,th_img_plane *_img,
  int _pli,int _fragy0,int _fragy_end){
   th_img_plane      *iplane;
   oc_fragment_plane *fplane;
   oc_fragment       *frag;
   int               *variance;
   unsigned char     *idata;
+  ptrdiff_t          froffset;
+  int                ystride;
+  int                nhfrags;
   int                sthresh;
   int                strong;
-  int                froffset;
   int                y_end;
+  int                width;
+  int                height;
   int                y;
   int                x;
   iplane=_img+_pli;
   fplane=_dec->state.fplanes+_pli;
-  froffset=fplane->froffset+_fragy0*fplane->nhfrags;
+  nhfrags=fplane->nhfrags;
+  froffset=fplane->froffset+_fragy0*(ptrdiff_t)nhfrags;
   variance=_dec->variances+froffset;
   frag=_dec->state.frags+froffset;
   strong=_dec->pp_level>=(_pli?OC_PP_LEVEL_SDERINGC:OC_PP_LEVEL_SDERINGY);
   sthresh=_pli?OC_DERING_THRESH4:OC_DERING_THRESH3;
   y=_fragy0<<3;
-  idata=iplane->data+y*iplane->stride;
+  ystride=iplane->stride;
+  idata=iplane->data+y*(ptrdiff_t)ystride;
   y_end=_fragy_end<<3;
+  width=iplane->width;
+  height=iplane->height;
   for(;y<y_end;y+=8){
-    for(x=0;x<iplane->width;x+=8){
+    for(x=0;x<width;x+=8){
       int b;
       int qi;
       int var;
-      qi=frag->qi;
+      qi=_dec->state.qis[frag->qii];
       var=*variance;
-      b=(x<=0)|(x+8>=iplane->width)<<1|(y<=0)<<2|(y+8>=iplane->height)<<3;
+      b=(x<=0)|(x+8>=width)<<1|(y<=0)<<2|(y+8>=height)<<3;
       if(strong&&var>sthresh){
-        oc_dering_block(idata+x,iplane->stride,b,
+        oc_dering_block(idata+x,ystride,b,
          _dec->pp_dc_scale[qi],_dec->pp_sharp_mod[qi],1);
         if(_pli||!(b&1)&&*(variance-1)>OC_DERING_THRESH4||
          !(b&2)&&variance[1]>OC_DERING_THRESH4||
-         !(b&4)&&*(variance-fplane->nvfrags)>OC_DERING_THRESH4||
-         !(b&8)&&variance[fplane->nvfrags]>OC_DERING_THRESH4){
-          oc_dering_block(idata+x,iplane->stride,b,
+         !(b&4)&&*(variance-nhfrags)>OC_DERING_THRESH4||
+         !(b&8)&&variance[nhfrags]>OC_DERING_THRESH4){
+          oc_dering_block(idata+x,ystride,b,
            _dec->pp_dc_scale[qi],_dec->pp_sharp_mod[qi],1);
-          oc_dering_block(idata+x,iplane->stride,b,
+          oc_dering_block(idata+x,ystride,b,
            _dec->pp_dc_scale[qi],_dec->pp_sharp_mod[qi],1);
         }
       }
       else if(var>OC_DERING_THRESH2){
-        oc_dering_block(idata+x,iplane->stride,b,
+        oc_dering_block(idata+x,ystride,b,
          _dec->pp_dc_scale[qi],_dec->pp_sharp_mod[qi],1);
       }
       else if(var>OC_DERING_THRESH1){
-        oc_dering_block(idata+x,iplane->stride,b,
+        oc_dering_block(idata+x,ystride,b,
          _dec->pp_dc_scale[qi],_dec->pp_sharp_mod[qi],0);
       }
       frag++;
       variance++;
     }
-    idata+=iplane->stride<<3;
+    idata+=ystride<<3;
   }
 }
 
 
 
-th_dec_ctx *th_decode_alloc(const th_info *_info,
- const th_setup_info *_setup){
+th_dec_ctx *th_decode_alloc(const th_info *_info,const th_setup_info *_setup){
   oc_dec_ctx *dec;
   if(_info==NULL||_setup==NULL)return NULL;
   dec=_ogg_malloc(sizeof(*dec));
-  if(oc_dec_init(dec,_info,_setup)<0){
+  if(dec==NULL||oc_dec_init(dec,_info,_setup)<0){
     _ogg_free(dec);
     return NULL;
   }
   dec->state.curframe_num=0;
   return dec;
 }
 
 void th_decode_free(th_dec_ctx *_dec){
@@ -1805,79 +1967,109 @@ void th_decode_free(th_dec_ctx *_dec){
     oc_dec_clear(_dec);
     _ogg_free(_dec);
   }
 }
 
 int th_decode_ctl(th_dec_ctx *_dec,int _req,void *_buf,
  size_t _buf_sz){
   switch(_req){
-    case TH_DECCTL_GET_PPLEVEL_MAX:{
-      if(_dec==NULL||_buf==NULL)return TH_EFAULT;
-      if(_buf_sz!=sizeof(int))return TH_EINVAL;
-      (*(int *)_buf)=OC_PP_LEVEL_MAX;
-      return 0;
-    }break;
-    case TH_DECCTL_SET_PPLEVEL:{
-      int pp_level;
-      if(_dec==NULL||_buf==NULL)return TH_EFAULT;
-      if(_buf_sz!=sizeof(int))return TH_EINVAL;
-      pp_level=*(int *)_buf;
-      if(pp_level<0||pp_level>OC_PP_LEVEL_MAX)return TH_EINVAL;
-      _dec->pp_level=pp_level;
-      return 0;
-    }break;
-    case TH_DECCTL_SET_GRANPOS:{
-      ogg_int64_t granpos;
-      if(_dec==NULL||_buf==NULL)return TH_EFAULT;
-      if(_buf_sz!=sizeof(ogg_int64_t))return TH_EINVAL;
-      granpos=*(ogg_int64_t *)_buf;
-      if(granpos<0)return TH_EINVAL;
-      _dec->state.granpos=granpos;
-      _dec->state.keyframe_num=
-       granpos>>_dec->state.info.keyframe_granule_shift;
-      _dec->state.curframe_num=_dec->state.keyframe_num+
-       (granpos&(1<<_dec->state.info.keyframe_granule_shift)-1);
-      return 0;
-    }break;
-    case TH_DECCTL_SET_STRIPE_CB:{
-      th_stripe_callback *cb;
-      if(_dec==NULL||_buf==NULL)return TH_EFAULT;
-      if(_buf_sz!=sizeof(th_stripe_callback))return TH_EINVAL;
-      cb=(th_stripe_callback *)_buf;
-      _dec->stripe_cb.ctx=cb->ctx;
-      _dec->stripe_cb.stripe_decoded=cb->stripe_decoded;
-      return 0;
-    }break;
-    default:return TH_EIMPL;
+  case TH_DECCTL_GET_PPLEVEL_MAX:{
+    if(_dec==NULL||_buf==NULL)return TH_EFAULT;
+    if(_buf_sz!=sizeof(int))return TH_EINVAL;
+    (*(int *)_buf)=OC_PP_LEVEL_MAX;
+    return 0;
+  }break;
+  case TH_DECCTL_SET_PPLEVEL:{
+    int pp_level;
+    if(_dec==NULL||_buf==NULL)return TH_EFAULT;
+    if(_buf_sz!=sizeof(int))return TH_EINVAL;
+    pp_level=*(int *)_buf;
+    if(pp_level<0||pp_level>OC_PP_LEVEL_MAX)return TH_EINVAL;
+    _dec->pp_level=pp_level;
+    return 0;
+  }break;
+  case TH_DECCTL_SET_GRANPOS:{
+    ogg_int64_t granpos;
+    if(_dec==NULL||_buf==NULL)return TH_EFAULT;
+    if(_buf_sz!=sizeof(ogg_int64_t))return TH_EINVAL;
+    granpos=*(ogg_int64_t *)_buf;
+    if(granpos<0)return TH_EINVAL;
+    _dec->state.granpos=granpos;
+    _dec->state.keyframe_num=(granpos>>_dec->state.info.keyframe_granule_shift)
+     -_dec->state.granpos_bias;
+    _dec->state.curframe_num=_dec->state.keyframe_num
+     +(granpos&(1<<_dec->state.info.keyframe_granule_shift)-1);
+    return 0;
+  }break;
+  case TH_DECCTL_SET_STRIPE_CB:{
+    th_stripe_callback *cb;
+    if(_dec==NULL||_buf==NULL)return TH_EFAULT;
+    if(_buf_sz!=sizeof(th_stripe_callback))return TH_EINVAL;
+    cb=(th_stripe_callback *)_buf;
+    _dec->stripe_cb.ctx=cb->ctx;
+    _dec->stripe_cb.stripe_decoded=cb->stripe_decoded;
+    return 0;
+  }break;
+#ifdef HAVE_CAIRO
+  case TH_DECCTL_SET_TELEMETRY_MBMODE:{
+    if(_dec==NULL||_buf==NULL)return TH_EFAULT;
+    if(_buf_sz!=sizeof(int))return TH_EINVAL;
+    _dec->telemetry=1;
+    _dec->telemetry_mbmode=*(int *)_buf;
+    return 0;
+  }break;
+  case TH_DECCTL_SET_TELEMETRY_MV:{
+    if(_dec==NULL||_buf==NULL)return TH_EFAULT;
+    if(_buf_sz!=sizeof(int))return TH_EINVAL;
+    _dec->telemetry=1;
+    _dec->telemetry_mv=*(int *)_buf;
+    return 0;
+  }break;
+  case TH_DECCTL_SET_TELEMETRY_QI:{
+    if(_dec==NULL||_buf==NULL)return TH_EFAULT;
+    if(_buf_sz!=sizeof(int))return TH_EINVAL;
+    _dec->telemetry=1;
+    _dec->telemetry_qi=*(int *)_buf;
+    return 0;
+  }break;
+  case TH_DECCTL_SET_TELEMETRY_BITS:{
+    if(_dec==NULL||_buf==NULL)return TH_EFAULT;
+    if(_buf_sz!=sizeof(int))return TH_EINVAL;
+    _dec->telemetry=1;
+    _dec->telemetry_bits=*(int *)_buf;
+    return 0;
+  }break;
+#endif
+  default:return TH_EIMPL;
   }
 }
 
 /*We're decoding an INTER frame, but have no initialized reference
    buffers (i.e., decoding did not start on a key frame).
   We initialize them to a solid gray here.*/
 static void oc_dec_init_dummy_frame(th_dec_ctx *_dec){
   th_info *info;
   size_t   yplane_sz;
   size_t   cplane_sz;
   int      yhstride;
-  int      yvstride;
+  int      yheight;
   int      chstride;
-  int      cvstride;
+  int      cheight;
   _dec->state.ref_frame_idx[OC_FRAME_GOLD]=0;
   _dec->state.ref_frame_idx[OC_FRAME_PREV]=0;
   _dec->state.ref_frame_idx[OC_FRAME_SELF]=1;
   info=&_dec->state.info;
   yhstride=info->frame_width+2*OC_UMV_PADDING;
-  yvstride=info->frame_height+2*OC_UMV_PADDING;
+  yheight=info->frame_height+2*OC_UMV_PADDING;
   chstride=yhstride>>!(info->pixel_fmt&1);
-  cvstride=yvstride>>!(info->pixel_fmt&2);
-  yplane_sz=(size_t)yhstride*yvstride;
-  cplane_sz=(size_t)chstride*cvstride;
-  memset(_dec->state.ref_frame_data,0x80,yplane_sz+2*cplane_sz);
+  cheight=yheight>>!(info->pixel_fmt&2);
+  yplane_sz=yhstride*(size_t)yheight;
+  cplane_sz=chstride*(size_t)cheight;
+  memset(_dec->state.ref_frame_data[0],0x80,yplane_sz+2*cplane_sz);
 }
 
 int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op,
  ogg_int64_t *_granpos){
   int ret;
   if(_dec==NULL||_op==NULL)return TH_EFAULT;
   /*A completely empty packet indicates a dropped frame and is treated exactly
      like an inter frame with no coded blocks.
@@ -1885,17 +2077,20 @@ int th_decode_packetin(th_dec_ctx *_dec,
   if(_op->bytes!=0){
     oc_dec_pipeline_state pipe;
     th_ycbcr_buffer       stripe_buf;
     int                   stripe_fragy;
     int                   refi;
     int                   pli;
     int                   notstart;
     int                   notdone;
-    theorapackB_readinit(&_dec->opb,_op->packet,_op->bytes);
+    oc_pack_readinit(&_dec->opb,_op->packet,_op->bytes);
+#if defined(HAVE_CAIRO)
+    _dec->telemetry_frame_bytes=_op->bytes;
+#endif
     ret=oc_dec_frame_header_unpack(_dec);
     if(ret<0)return ret;
     /*Select a free buffer to use for the reconstructed version of this
        frame.*/
     if(_dec->state.frame_type!=OC_INTRA_FRAME&&
      (_dec->state.ref_frame_idx[OC_FRAME_GOLD]<0||
      _dec->state.ref_frame_idx[OC_FRAME_PREV]<0)){
       /*No reference frames yet!*/
@@ -1905,29 +2100,47 @@ int th_decode_packetin(th_dec_ctx *_dec,
     else{
       for(refi=0;refi==_dec->state.ref_frame_idx[OC_FRAME_GOLD]||
        refi==_dec->state.ref_frame_idx[OC_FRAME_PREV];refi++);
       _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi;
     }
     if(_dec->state.frame_type==OC_INTRA_FRAME){
       oc_dec_mark_all_intra(_dec);
       _dec->state.keyframe_num=_dec->state.curframe_num;
-    }else{
+#if defined(HAVE_CAIRO)
+      _dec->telemetry_coding_bytes=
+       _dec->telemetry_mode_bytes=
+       _dec->telemetry_mv_bytes=oc_pack_bytes_left(&_dec->opb);
+#endif
+    }
+    else{
       oc_dec_coded_flags_unpack(_dec);
+#if defined(HAVE_CAIRO)
+      _dec->telemetry_coding_bytes=oc_pack_bytes_left(&_dec->opb);
+#endif
       oc_dec_mb_modes_unpack(_dec);
+#if defined(HAVE_CAIRO)
+      _dec->telemetry_mode_bytes=oc_pack_bytes_left(&_dec->opb);
+#endif
       oc_dec_mv_unpack_and_frag_modes_fill(_dec);
+#if defined(HAVE_CAIRO)
+      _dec->telemetry_mv_bytes=oc_pack_bytes_left(&_dec->opb);
+#endif
     }
     oc_dec_block_qis_unpack(_dec);
+#if defined(HAVE_CAIRO)
+    _dec->telemetry_qi_bytes=oc_pack_bytes_left(&_dec->opb);
+#endif
     oc_dec_residual_tokens_unpack(_dec);
     /*Update granule position.
       This must be done before the striped decode callbacks so that the
        application knows what to do with the frame data.*/
-    _dec->state.granpos=
-     (_dec->state.keyframe_num<<_dec->state.info.keyframe_granule_shift)+
-     (_dec->state.curframe_num-_dec->state.keyframe_num);
+    _dec->state.granpos=(_dec->state.keyframe_num+_dec->state.granpos_bias<<
+     _dec->state.info.keyframe_granule_shift)
+     +(_dec->state.curframe_num-_dec->state.keyframe_num);
     _dec->state.curframe_num++;
     if(_granpos!=NULL)*_granpos=_dec->state.granpos;
     /*All of the rest of the operations -- DC prediction reversal,
        reconstructing coded fragments, copying uncoded fragments, loop
        filtering, extending borders, and out-of-loop post-processing -- should
        be pipelined.
       I.e., DC prediction reversal, reconstruction, and uncoded fragment
        copying are done for one or two super block rows, then loop filtering is
@@ -1946,17 +2159,17 @@ int th_decode_packetin(th_dec_ctx *_dec,
        cache, resulting in big performance improvements.
       An application callback allows further application processing (blitting
        to video memory, color conversion, etc.) to also use the data while it's
        in cache.*/
     oc_dec_pipeline_init(_dec,&pipe);
     oc_ycbcr_buffer_flip(stripe_buf,_dec->pp_frame_buf);
     notstart=0;
     notdone=1;
-    for(stripe_fragy=notstart=0;notdone;stripe_fragy+=pipe.mcu_nvfrags){
+    for(stripe_fragy=0;notdone;stripe_fragy+=pipe.mcu_nvfrags){
       int avail_fragy0;
       int avail_fragy_end;
       avail_fragy0=avail_fragy_end=_dec->state.fplanes[0].nvfrags;
       notdone=stripe_fragy+pipe.mcu_nvfrags<avail_fragy_end;
       for(pli=0;pli<3;pli++){
         oc_fragment_plane *fplane;
         int                frag_shift;
         int                pp_offset;
@@ -2013,16 +2226,21 @@ int th_decode_packetin(th_dec_ctx *_dec,
            doubled, but luma might have more post-processing filters enabled
            than chroma, so we don't know up front which one is the limiting
            factor.*/
         avail_fragy0=OC_MINI(avail_fragy0,pipe.fragy0[pli]-sdelay<<frag_shift);
         avail_fragy_end=OC_MINI(avail_fragy_end,
          pipe.fragy_end[pli]-edelay<<frag_shift);
       }
       if(_dec->stripe_cb.stripe_decoded!=NULL){
+        /*The callback might want to use the FPU, so let's make sure they can.
+          We violate all kinds of ABI restrictions by not doing this until
+           now, but none of them actually matter since we don't use floating
+           point ourselves.*/
+        oc_restore_fpu(&_dec->state);
         /*Make the callback, ensuring we flip the sense of the "start" and
            "end" of the available region upside down.*/
         (*_dec->stripe_cb.stripe_decoded)(_dec->stripe_cb.ctx,stripe_buf,
          _dec->state.fplanes[0].nvfrags-avail_fragy_end,
          _dec->state.fplanes[0].nvfrags-avail_fragy0);
       }
       notstart=1;
     }
@@ -2035,16 +2253,19 @@ int th_decode_packetin(th_dec_ctx *_dec,
        _dec->state.ref_frame_idx[OC_FRAME_PREV]=
        _dec->state.ref_frame_idx[OC_FRAME_SELF];
     }
     else{
       /*Otherwise, just replace the previous reference frame.*/
       _dec->state.ref_frame_idx[OC_FRAME_PREV]=
        _dec->state.ref_frame_idx[OC_FRAME_SELF];
     }
+    /*Restore the FPU before dump_frame, since that _does_ use the FPU (for PNG
+       gamma values, if nothing else).*/
+    oc_restore_fpu(&_dec->state);
 #if defined(OC_DUMP_IMAGES)
     /*Don't dump images for dropped frames.*/
     oc_state_dump_frame(&_dec->state,OC_FRAME_SELF,"dec");
 #endif
     return 0;
   }
   else{
     if(_dec->state.ref_frame_idx[OC_FRAME_GOLD]<0||
@@ -2053,21 +2274,670 @@ int th_decode_packetin(th_dec_ctx *_dec,
       /*No reference frames yet!*/
       oc_dec_init_dummy_frame(_dec);
       refi=_dec->state.ref_frame_idx[OC_FRAME_PREV];
       _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi;
       memcpy(_dec->pp_frame_buf,_dec->state.ref_frame_bufs[refi],
        sizeof(_dec->pp_frame_buf[0])*3);
     }
     /*Just update the granule position and return.*/
-    _dec->state.granpos=
-     (_dec->state.keyframe_num<<_dec->state.info.keyframe_granule_shift)+
-     (_dec->state.curframe_num-_dec->state.keyframe_num);
+    _dec->state.granpos=(_dec->state.keyframe_num+_dec->state.granpos_bias<<
+     _dec->state.info.keyframe_granule_shift)
+     +(_dec->state.curframe_num-_dec->state.keyframe_num);
     _dec->state.curframe_num++;
     if(_granpos!=NULL)*_granpos=_dec->state.granpos;
     return TH_DUPFRAME;
   }
 }
 
 int th_decode_ycbcr_out(th_dec_ctx *_dec,th_ycbcr_buffer _ycbcr){
+  if(_dec==NULL||_ycbcr==NULL)return TH_EFAULT;
   oc_ycbcr_buffer_flip(_ycbcr,_dec->pp_frame_buf);
+#if defined(HAVE_CAIRO)
+  /*If telemetry ioctls are active, we need to draw to the output buffer.
+    Stuff the plane into cairo.*/
+  if(_dec->telemetry){
+    cairo_surface_t *cs;
+    unsigned char   *data;
+    unsigned char   *y_row;
+    unsigned char   *u_row;
+    unsigned char   *v_row;
+    unsigned char   *rgb_row;
+    int              cstride;
+    int              w;
+    int              h;
+    int              x;
+    int              y;
+    int              hdec;
+    int              vdec;
+    w=_ycbcr[0].width;
+    h=_ycbcr[0].height;
+    hdec=!(_dec->state.info.pixel_fmt&1);
+    vdec=!(_dec->state.info.pixel_fmt&2);
+    /*Lazy data buffer init.
+      We could try to re-use the post-processing buffer, which would save
+       memory, but complicate the allocation logic there.
+      I don't think anyone cares about memory usage when using telemetry; it is
+       not meant for embedded devices.*/
+    if(_dec->telemetry_frame_data==NULL){
+      _dec->telemetry_frame_data=_ogg_malloc(
+       (w*h+2*(w>>hdec)*(h>>vdec))*sizeof(*_dec->telemetry_frame_data));
+      if(_dec->telemetry_frame_data==NULL)return 0;
+    }
+    cs=cairo_image_surface_create(CAIRO_FORMAT_RGB24,w,h);
+    /*Sadly, no YUV support in Cairo (yet); convert into the RGB buffer.*/
+    data=cairo_image_surface_get_data(cs);
+    if(data==NULL){
+      cairo_surface_destroy(cs);
+      return 0;
+    }
+    cstride=cairo_image_surface_get_stride(cs);
+    y_row=_ycbcr[0].data;
+    u_row=_ycbcr[1].data;
+    v_row=_ycbcr[2].data;
+    rgb_row=data;
+    for(y=0;y<h;y++){
+      for(x=0;x<w;x++){
+        int r;
+        int g;
+        int b;
+        r=(1904000*y_row[x]+2609823*v_row[x>>hdec]-363703744)/1635200;
+        g=(3827562*y_row[x]-1287801*u_row[x>>hdec]
+         -2672387*v_row[x>>hdec]+447306710)/3287200;
+        b=(952000*y_row[x]+1649289*u_row[x>>hdec]-225932192)/817600;
+        rgb_row[4*x+0]=OC_CLAMP255(b);
+        rgb_row[4*x+1]=OC_CLAMP255(g);
+        rgb_row[4*x+2]=OC_CLAMP255(r);
+      }
+      y_row+=_ycbcr[0].stride;
+      u_row+=_ycbcr[1].stride&-((y&1)|!vdec);
+      v_row+=_ycbcr[2].stride&-((y&1)|!vdec);
+      rgb_row+=cstride;
+    }
+    /*Draw coded identifier for each macroblock (stored in Hilbert order).*/
+    {
+      cairo_t           *c;
+      const oc_fragment *frags;
+      oc_mv             *frag_mvs;
+      const signed char *mb_modes;
+      oc_mb_map         *mb_maps;
+      size_t             nmbs;
+      size_t             mbi;
+      int                row2;
+      int                col2;
+      int                qim[3]={0,0,0};
+      if(_dec->state.nqis==2){
+        int bqi;
+        bqi=_dec->state.qis[0];
+        if(_dec->state.qis[1]>bqi)qim[1]=1;
+        if(_dec->state.qis[1]<bqi)qim[1]=-1;
+      }
+      if(_dec->state.nqis==3){
+        int bqi;
+        int cqi;
+        int dqi;
+        bqi=_dec->state.qis[0];
+        cqi=_dec->state.qis[1];
+        dqi=_dec->state.qis[2];
+        if(cqi>bqi&&dqi>bqi){
+          if(dqi>cqi){
+            qim[1]=1;
+            qim[2]=2;
+          }
+          else{
+            qim[1]=2;
+            qim[2]=1;
+          }
+        }
+        else if(cqi<bqi&&dqi<bqi){
+          if(dqi<cqi){
+            qim[1]=-1;
+            qim[2]=-2;
+          }
+          else{
+            qim[1]=-2;
+            qim[2]=-1;
+          }
+        }
+        else{
+          if(cqi<bqi)qim[1]=-1;
+          else qim[1]=1;
+          if(dqi<bqi)qim[2]=-1;
+          else qim[2]=1;
+        }
+      }
+      c=cairo_create(cs);
+      frags=_dec->state.frags;
+      frag_mvs=_dec->state.frag_mvs;
+      mb_modes=_dec->state.mb_modes;
+      mb_maps=_dec->state.mb_maps;
+      nmbs=_dec->state.nmbs;
+      row2=0;
+      col2=0;
+      for(mbi=0;mbi<nmbs;mbi++){
+        float x;
+        float y;
+        int   bi;
+        y=h-(row2+((col2+1>>1)&1))*16-16;
+        x=(col2>>1)*16;
+        cairo_set_line_width(c,1.);
+        /*Keyframe (all intra) red box.*/
+        if(_dec->state.frame_type==OC_INTRA_FRAME){
+          if(_dec->telemetry_mbmode&0x02){
+            cairo_set_source_rgba(c,1.,0,0,.5);
+            cairo_rectangle(c,x+2.5,y+2.5,11,11);
+            cairo_stroke_preserve(c);
+            cairo_set_source_rgba(c,1.,0,0,.25);
+            cairo_fill(c);
+          }
+        }
+        else{
+          const signed char *frag_mv;
+          ptrdiff_t          fragi;
+          for(bi=0;bi<4;bi++){
+            fragi=mb_maps[mbi][0][bi];
+            if(fragi>=0&&frags[fragi].coded){
+              frag_mv=frag_mvs[fragi];
+              break;
+            }
+          }
+          if(bi<4){
+            switch(mb_modes[mbi]){
+              case OC_MODE_INTRA:{
+                if(_dec->telemetry_mbmode&0x02){
+                  cairo_set_source_rgba(c,1.,0,0,.5);
+                  cairo_rectangle(c,x+2.5,y+2.5,11,11);
+                  cairo_stroke_preserve(c);
+                  cairo_set_source_rgba(c,1.,0,0,.25);
+                  cairo_fill(c);
+                }
+              }break;
+              case OC_MODE_INTER_NOMV:{
+                if(_dec->telemetry_mbmode&0x01){
+                  cairo_set_source_rgba(c,0,0,1.,.5);
+                  cairo_rectangle(c,x+2.5,y+2.5,11,11);
+                  cairo_stroke_preserve(c);
+                  cairo_set_source_rgba(c,0,0,1.,.25);
+                  cairo_fill(c);
+                }
+              }break;
+              case OC_MODE_INTER_MV:{
+                if(_dec->telemetry_mbmode&0x04){
+                  cairo_rectangle(c,x+2.5,y+2.5,11,11);
+                  cairo_set_source_rgba(c,0,1.,0,.5);
+                  cairo_stroke(c);
+                }
+                if(_dec->telemetry_mv&0x04){
+                  cairo_move_to(c,x+8+frag_mv[0],y+8-frag_mv[1]);
+                  cairo_set_source_rgba(c,1.,1.,1.,.9);
+                  cairo_set_line_width(c,3.);
+                  cairo_line_to(c,x+8+frag_mv[0]*.66,y+8-frag_mv[1]*.66);
+                  cairo_stroke_preserve(c);
+                  cairo_set_line_width(c,2.);
+                  cairo_line_to(c,x+8+frag_mv[0]*.33,y+8-frag_mv[1]*.33);
+                  cairo_stroke_preserve(c);
+                  cairo_set_line_width(c,1.);
+                  cairo_line_to(c,x+8,y+8);
+                  cairo_stroke(c);
+                }
+              }break;
+              case OC_MODE_INTER_MV_LAST:{
+                if(_dec->telemetry_mbmode&0x08){
+                  cairo_rectangle(c,x+2.5,y+2.5,11,11);
+                  cairo_set_source_rgba(c,0,1.,0,.5);
+                  cairo_move_to(c,x+13.5,y+2.5);
+                  cairo_line_to(c,x+2.5,y+8);
+                  cairo_line_to(c,x+13.5,y+13.5);
+                  cairo_stroke(c);
+                }
+                if(_dec->telemetry_mv&0x08){
+                  cairo_move_to(c,x+8+frag_mv[0],y+8-frag_mv[1]);
+                  cairo_set_source_rgba(c,1.,1.,1.,.9);
+                  cairo_set_line_width(c,3.);
+                  cairo_line_to(c,x+8+frag_mv[0]*.66,y+8-frag_mv[1]*.66);
+                  cairo_stroke_preserve(c);
+                  cairo_set_line_width(c,2.);
+                  cairo_line_to(c,x+8+frag_mv[0]*.33,y+8-frag_mv[1]*.33);
+                  cairo_stroke_preserve(c);
+                  cairo_set_line_width(c,1.);
+                  cairo_line_to(c,x+8,y+8);
+                  cairo_stroke(c);
+                }
+              }break;
+              case OC_MODE_INTER_MV_LAST2:{
+                if(_dec->telemetry_mbmode&0x10){
+                  cairo_rectangle(c,x+2.5,y+2.5,11,11);
+                  cairo_set_source_rgba(c,0,1.,0,.5);
+                  cairo_move_to(c,x+8,y+2.5);
+                  cairo_line_to(c,x+2.5,y+8);
+                  cairo_line_to(c,x+8,y+13.5);
+                  cairo_move_to(c,x+13.5,y+2.5);
+                  cairo_line_to(c,x+8,y+8);
+                  cairo_line_to(c,x+13.5,y+13.5);
+                  cairo_stroke(c);
+                }
+                if(_dec->telemetry_mv&0x10){
+                  cairo_move_to(c,x+8+frag_mv[0],y+8-frag_mv[1]);
+                  cairo_set_source_rgba(c,1.,1.,1.,.9);
+                  cairo_set_line_width(c,3.);
+                  cairo_line_to(c,x+8+frag_mv[0]*.66,y+8-frag_mv[1]*.66);
+                  cairo_stroke_preserve(c);
+                  cairo_set_line_width(c,2.);
+                  cairo_line_to(c,x+8+frag_mv[0]*.33,y+8-frag_mv[1]*.33);
+                  cairo_stroke_preserve(c);
+                  cairo_set_line_width(c,1.);
+                  cairo_line_to(c,x+8,y+8);
+                  cairo_stroke(c);
+                }
+              }break;
+              case OC_MODE_GOLDEN_NOMV:{
+                if(_dec->telemetry_mbmode&0x20){
+                  cairo_set_source_rgba(c,1.,1.,0,.5);
+                  cairo_rectangle(c,x+2.5,y+2.5,11,11);
+                  cairo_stroke_preserve(c);
+                  cairo_set_source_rgba(c,1.,1.,0,.25);
+                  cairo_fill(c);
+                }
+              }break;
+              case OC_MODE_GOLDEN_MV:{
+                if(_dec->telemetry_mbmode&0x40){
+                  cairo_rectangle(c,x+2.5,y+2.5,11,11);
+                  cairo_set_source_rgba(c,1.,1.,0,.5);
+                  cairo_stroke(c);
+                }
+                if(_dec->telemetry_mv&0x40){
+                  cairo_move_to(c,x+8+frag_mv[0],y+8-frag_mv[1]);
+                  cairo_set_source_rgba(c,1.,1.,1.,.9);
+                  cairo_set_line_width(c,3.);
+                  cairo_line_to(c,x+8+frag_mv[0]*.66,y+8-frag_mv[1]*.66);
+                  cairo_stroke_preserve(c);
+                  cairo_set_line_width(c,2.);
+                  cairo_line_to(c,x+8+frag_mv[0]*.33,y+8-frag_mv[1]*.33);
+                  cairo_stroke_preserve(c);
+                  cairo_set_line_width(c,1.);
+                  cairo_line_to(c,x+8,y+8);
+                  cairo_stroke(c);
+                }
+              }break;
+              case OC_MODE_INTER_MV_FOUR:{
+                if(_dec->telemetry_mbmode&0x80){
+                  cairo_rectangle(c,x+2.5,y+2.5,4,4);
+                  cairo_rectangle(c,x+9.5,y+2.5,4,4);
+                  cairo_rectangle(c,x+2.5,y+9.5,4,4);
+                  cairo_rectangle(c,x+9.5,y+9.5,4,4);
+                  cairo_set_source_rgba(c,0,1.,0,.5);
+                  cairo_stroke(c);
+                }
+                /*4mv is odd, coded in raster order.*/
+                fragi=mb_maps[mbi][0][0];
+                if(frags[fragi].coded&&_dec->telemetry_mv&0x80){
+                  frag_mv=frag_mvs[fragi];
+                  cairo_move_to(c,x+4+frag_mv[0],y+12-frag_mv[1]);
+                  cairo_set_source_rgba(c,1.,1.,1.,.9);
+                  cairo_set_line_width(c,3.);
+                  cairo_line_to(c,x+4+frag_mv[0]*.66,y+12-frag_mv[1]*.66);
+                  cairo_stroke_preserve(c);
+                  cairo_set_line_width(c,2.);
+                  cairo_line_to(c,x+4+frag_mv[0]*.33,y+12-frag_mv[1]*.33);
+                  cairo_stroke_preserve(c);
+                  cairo_set_line_width(c,1.);
+                  cairo_line_to(c,x+4,y+12);
+                  cairo_stroke(c);
+                }
+                fragi=mb_maps[mbi][0][1];
+                if(frags[fragi].coded&&_dec->telemetry_mv&0x80){
+                  frag_mv=frag_mvs[fragi];
+                  cairo_move_to(c,x+12+frag_mv[0],y+12-frag_mv[1]);
+                  cairo_set_source_rgba(c,1.,1.,1.,.9);
+                  cairo_set_line_width(c,3.);
+                  cairo_line_to(c,x+12+frag_mv[0]*.66,y+12-frag_mv[1]*.66);
+                  cairo_stroke_preserve(c);
+                  cairo_set_line_width(c,2.);
+                  cairo_line_to(c,x+12+frag_mv[0]*.33,y+12-frag_mv[1]*.33);
+                  cairo_stroke_preserve(c);
+                  cairo_set_line_width(c,1.);
+                  cairo_line_to(c,x+12,y+12);
+                  cairo_stroke(c);
+                }
+                fragi=mb_maps[mbi][0][2];
+                if(frags[fragi].coded&&_dec->telemetry_mv&0x80){
+                  frag_mv=frag_mvs[fragi];
+                  cairo_move_to(c,x+4+frag_mv[0],y+4-frag_mv[1]);
+                  cairo_set_source_rgba(c,1.,1.,1.,.9);
+                  cairo_set_line_width(c,3.);
+                  cairo_line_to(c,x+4+frag_mv[0]*.66,y+4-frag_mv[1]*.66);
+                  cairo_stroke_preserve(c);
+                  cairo_set_line_width(c,2.);
+                  cairo_line_to(c,x+4+frag_mv[0]*.33,y+4-frag_mv[1]*.33);
+                  cairo_stroke_preserve(c);
+                  cairo_set_line_width(c,1.);
+                  cairo_line_to(c,x+4,y+4);
+                  cairo_stroke(c);
+                }
+                fragi=mb_maps[mbi][0][3];
+                if(frags[fragi].coded&&_dec->telemetry_mv&0x80){
+                  frag_mv=frag_mvs[fragi];
+                  cairo_move_to(c,x+12+frag_mv[0],y+4-frag_mv[1]);
+                  cairo_set_source_rgba(c,1.,1.,1.,.9);
+                  cairo_set_line_width(c,3.);
+                  cairo_line_to(c,x+12+frag_mv[0]*.66,y+4-frag_mv[1]*.66);
+                  cairo_stroke_preserve(c);
+                  cairo_set_line_width(c,2.);
+                  cairo_line_to(c,x+12+frag_mv[0]*.33,y+4-frag_mv[1]*.33);
+                  cairo_stroke_preserve(c);
+                  cairo_set_line_width(c,1.);
+                  cairo_line_to(c,x+12,y+4);
+                  cairo_stroke(c);
+                }
+              }break;
+            }
+          }
+        }
+        /*qii illustration.*/
+        if(_dec->telemetry_qi&0x2){
+          cairo_set_line_cap(c,CAIRO_LINE_CAP_SQUARE);
+          for(bi=0;bi<4;bi++){
+            ptrdiff_t fragi;
+            int       qiv;
+            int       xp;
+            int       yp;
+            xp=x+(bi&1)*8;
+            yp=y+8-(bi&2)*4;
+            fragi=mb_maps[mbi][0][bi];
+            if(fragi>=0&&frags[fragi].coded){
+              qiv=qim[frags[fragi].qii];
+              cairo_set_line_width(c,3.);
+              cairo_set_source_rgba(c,0.,0.,0.,.5);
+              switch(qiv){
+                /*Double plus:*/
+                case 2:{
+                  if((bi&1)^((bi&2)>>1)){
+                    cairo_move_to(c,xp+2.5,yp+1.5);
+                    cairo_line_to(c,xp+2.5,yp+3.5);
+                    cairo_move_to(c,xp+1.5,yp+2.5);
+                    cairo_line_to(c,xp+3.5,yp+2.5);
+                    cairo_move_to(c,xp+5.5,yp+4.5);
+                    cairo_line_to(c,xp+5.5,yp+6.5);
+                    cairo_move_to(c,xp+4.5,yp+5.5);
+                    cairo_line_to(c,xp+6.5,yp+5.5);
+                    cairo_stroke_preserve(c);
+                    cairo_set_source_rgba(c,0.,1.,1.,1.);
+                  }
+                  else{
+                    cairo_move_to(c,xp+5.5,yp+1.5);
+                    cairo_line_to(c,xp+5.5,yp+3.5);
+                    cairo_move_to(c,xp+4.5,yp+2.5);
+                    cairo_line_to(c,xp+6.5,yp+2.5);
+                    cairo_move_to(c,xp+2.5,yp+4.5);
+                    cairo_line_to(c,xp+2.5,yp+6.5);
+                    cairo_move_to(c,xp+1.5,yp+5.5);
+                    cairo_line_to(c,xp+3.5,yp+5.5);
+                    cairo_stroke_preserve(c);
+                    cairo_set_source_rgba(c,0.,1.,1.,1.);
+                  }
+                }break;
+                /*Double minus:*/
+                case -2:{
+                  cairo_move_to(c,xp+2.5,yp+2.5);
+                  cairo_line_to(c,xp+5.5,yp+2.5);
+                  cairo_move_to(c,xp+2.5,yp+5.5);
+                  cairo_line_to(c,xp+5.5,yp+5.5);
+                  cairo_stroke_preserve(c);
+                  cairo_set_source_rgba(c,1.,1.,1.,1.);
+                }break;
+                /*Plus:*/
+                case 1:{
+                  if(bi&2==0)yp-=2;
+                  if(bi&1==0)xp-=2;
+                  cairo_move_to(c,xp+4.5,yp+2.5);
+                  cairo_line_to(c,xp+4.5,yp+6.5);
+                  cairo_move_to(c,xp+2.5,yp+4.5);
+                  cairo_line_to(c,xp+6.5,yp+4.5);
+                  cairo_stroke_preserve(c);
+                  cairo_set_source_rgba(c,.1,1.,.3,1.);
+                  break;
+                }
+                /*Fall through.*/
+                /*Minus:*/
+                case -1:{
+                  cairo_move_to(c,xp+2.5,yp+4.5);
+                  cairo_line_to(c,xp+6.5,yp+4.5);
+                  cairo_stroke_preserve(c);
+                  cairo_set_source_rgba(c,1.,.3,.1,1.);
+                }break;
+                default:continue;
+              }
+              cairo_set_line_width(c,1.);
+              cairo_stroke(c);
+            }
+          }
+        }
+        col2++;
+        if((col2>>1)>=_dec->state.nhmbs){
+          col2=0;
+          row2+=2;
+        }
+      }
+      /*Bit usage indicator[s]:*/
+      if(_dec->telemetry_bits){
+        int widths[6];
+        int fpsn;
+        int fpsd;
+        int mult;
+        int fullw;
+        int padw;
+        int i;
+        fpsn=_dec->state.info.fps_numerator;
+        fpsd=_dec->state.info.fps_denominator;
+        mult=(_dec->telemetry_bits>=0xFF?1:_dec->telemetry_bits);
+        fullw=250.f*h*fpsd*mult/fpsn;
+        padw=w-24;
+        /*Header and coded block bits.*/
+        if(_dec->telemetry_frame_bytes<0||
+         _dec->telemetry_frame_bytes==OC_LOTS_OF_BITS){
+          _dec->telemetry_frame_bytes=0;
+        }
+        if(_dec->telemetry_coding_bytes<0||
+         _dec->telemetry_coding_bytes>_dec->telemetry_frame_bytes){
+          _dec->telemetry_coding_bytes=0;
+        }
+        if(_dec->telemetry_mode_bytes<0||
+         _dec->telemetry_mode_bytes>_dec->telemetry_frame_bytes){
+          _dec->telemetry_mode_bytes=0;
+        }
+        if(_dec->telemetry_mv_bytes<0||
+         _dec->telemetry_mv_bytes>_dec->telemetry_frame_bytes){
+          _dec->telemetry_mv_bytes=0;
+        }
+        if(_dec->telemetry_qi_bytes<0||
+         _dec->telemetry_qi_bytes>_dec->telemetry_frame_bytes){
+          _dec->telemetry_qi_bytes=0;
+        }
+        if(_dec->telemetry_dc_bytes<0||
+         _dec->telemetry_dc_bytes>_dec->telemetry_frame_bytes){
+          _dec->telemetry_dc_bytes=0;
+        }
+        widths[0]=padw*(_dec->telemetry_frame_bytes-_dec->telemetry_coding_bytes)/fullw;
+        widths[1]=padw*(_dec->telemetry_coding_bytes-_dec->telemetry_mode_bytes)/fullw;
+        widths[2]=padw*(_dec->telemetry_mode_bytes-_dec->telemetry_mv_bytes)/fullw;
+        widths[3]=padw*(_dec->telemetry_mv_bytes-_dec->telemetry_qi_bytes)/fullw;
+        widths[4]=padw*(_dec->telemetry_qi_bytes-_dec->telemetry_dc_bytes)/fullw;
+        widths[5]=padw*(_dec->telemetry_dc_bytes)/fullw;
+        for(i=0;i<6;i++)if(widths[i]>w)widths[i]=w;
+        cairo_set_source_rgba(c,.0,.0,.0,.6);
+        cairo_rectangle(c,10,h-33,widths[0]+1,5);
+        cairo_rectangle(c,10,h-29,widths[1]+1,5);
+        cairo_rectangle(c,10,h-25,widths[2]+1,5);
+        cairo_rectangle(c,10,h-21,widths[3]+1,5);
+        cairo_rectangle(c,10,h-17,widths[4]+1,5);
+        cairo_rectangle(c,10,h-13,widths[5]+1,5);
+        cairo_fill(c);
+        cairo_set_source_rgb(c,1,0,0);
+        cairo_rectangle(c,10.5,h-32.5,widths[0],4);
+        cairo_fill(c);
+        cairo_set_source_rgb(c,0,1,0);
+        cairo_rectangle(c,10.5,h-28.5,widths[1],4);
+        cairo_fill(c);
+        cairo_set_source_rgb(c,0,0,1);
+        cairo_rectangle(c,10.5,h-24.5,widths[2],4);
+        cairo_fill(c);
+        cairo_set_source_rgb(c,.6,.4,.0);
+        cairo_rectangle(c,10.5,h-20.5,widths[3],4);
+        cairo_fill(c);
+        cairo_set_source_rgb(c,.3,.3,.3);
+        cairo_rectangle(c,10.5,h-16.5,widths[4],4);
+        cairo_fill(c);
+        cairo_set_source_rgb(c,.5,.5,.8);
+        cairo_rectangle(c,10.5,h-12.5,widths[5],4);
+        cairo_fill(c);
+      }
+      /*Master qi indicator[s]:*/
+      if(_dec->telemetry_qi&0x1){
+        cairo_text_extents_t extents;
+        char                 buffer[10];
+        int                  p;
+        int                  y;
+        p=0;
+        y=h-7.5;
+        if(_dec->state.qis[0]>=10)buffer[p++]=48+_dec->state.qis[0]/10;
+        buffer[p++]=48+_dec->state.qis[0]%10;
+        if(_dec->state.nqis>=2){
+          buffer[p++]=' ';
+          if(_dec->state.qis[1]>=10)buffer[p++]=48+_dec->state.qis[1]/10;
+          buffer[p++]=48+_dec->state.qis[1]%10;
+        }
+        if(_dec->state.nqis==3){
+          buffer[p++]=' ';
+          if(_dec->state.qis[2]>=10)buffer[p++]=48+_dec->state.qis[2]/10;
+          buffer[p++]=48+_dec->state.qis[2]%10;
+        }
+        buffer[p++]='\0';
+        cairo_select_font_face(c,"sans",
+         CAIRO_FONT_SLANT_NORMAL,CAIRO_FONT_WEIGHT_BOLD);
+        cairo_set_font_size(c,18);
+        cairo_text_extents(c,buffer,&extents);
+        cairo_set_source_rgb(c,1,1,1);
+        cairo_move_to(c,w-extents.x_advance-10,y);
+        cairo_show_text(c,buffer);
+        cairo_set_source_rgb(c,0,0,0);
+        cairo_move_to(c,w-extents.x_advance-10,y);
+        cairo_text_path(c,buffer);
+        cairo_set_line_width(c,.8);
+        cairo_set_line_join(c,CAIRO_LINE_JOIN_ROUND);
+        cairo_stroke(c);
+      }
+      cairo_destroy(c);
+    }
+    /*Out of the Cairo plane into the telemetry YUV buffer.*/
+    _ycbcr[0].data=_dec->telemetry_frame_data;
+    _ycbcr[0].stride=_ycbcr[0].width;
+    _ycbcr[1].data=_ycbcr[0].data+h*_ycbcr[0].stride;
+    _ycbcr[1].stride=_ycbcr[1].width;
+    _ycbcr[2].data=_ycbcr[1].data+(h>>vdec)*_ycbcr[1].stride;
+    _ycbcr[2].stride=_ycbcr[2].width;
+    y_row=_ycbcr[0].data;
+    u_row=_ycbcr[1].data;
+    v_row=_ycbcr[2].data;
+    rgb_row=data;
+    /*This is one of the few places it's worth handling chroma on a
+       case-by-case basis.*/
+    switch(_dec->state.info.pixel_fmt){
+      case TH_PF_420:{
+        for(y=0;y<h;y+=2){
+          unsigned char *y_row2;
+          unsigned char *rgb_row2;
+          y_row2=y_row+_ycbcr[0].stride;
+          rgb_row2=rgb_row+cstride;
+          for(x=0;x<w;x+=2){
+            int y;
+            int u;
+            int v;
+            y=(65481*rgb_row[4*x+2]+128553*rgb_row[4*x+1]
+             +24966*rgb_row[4*x+0]+4207500)/255000;
+            y_row[x]=OC_CLAMP255(y);
+            y=(65481*rgb_row[4*x+6]+128553*rgb_row[4*x+5]
+             +24966*rgb_row[4*x+4]+4207500)/255000;
+            y_row[x+1]=OC_CLAMP255(y);
+            y=(65481*rgb_row2[4*x+2]+128553*rgb_row2[4*x+1]
+             +24966*rgb_row2[4*x+0]+4207500)/255000;
+            y_row2[x]=OC_CLAMP255(y);
+            y=(65481*rgb_row2[4*x+6]+128553*rgb_row2[4*x+5]
+             +24966*rgb_row2[4*x+4]+4207500)/255000;
+            y_row2[x+1]=OC_CLAMP255(y);
+            u=(-8372*(rgb_row[4*x+2]+rgb_row[4*x+6]
+             +rgb_row2[4*x+2]+rgb_row2[4*x+6])
+             -16436*(rgb_row[4*x+1]+rgb_row[4*x+5]
+             +rgb_row2[4*x+1]+rgb_row2[4*x+5])
+             +24808*(rgb_row[4*x+0]+rgb_row[4*x+4]
+             +rgb_row2[4*x+0]+rgb_row2[4*x+4])+29032005)/225930;
+            v=(39256*(rgb_row[4*x+2]+rgb_row[4*x+6]
+             +rgb_row2[4*x+2]+rgb_row2[4*x+6])
+             -32872*(rgb_row[4*x+1]+rgb_row[4*x+5]
+              +rgb_row2[4*x+1]+rgb_row2[4*x+5])
+             -6384*(rgb_row[4*x+0]+rgb_row[4*x+4]
+              +rgb_row2[4*x+0]+rgb_row2[4*x+4])+45940035)/357510;
+            u_row[x>>1]=OC_CLAMP255(u);
+            v_row[x>>1]=OC_CLAMP255(v);
+          }
+          y_row+=_ycbcr[0].stride<<1;
+          u_row+=_ycbcr[1].stride;
+          v_row+=_ycbcr[2].stride;
+          rgb_row+=cstride<<1;
+        }
+      }break;
+      case TH_PF_422:{
+        for(y=0;y<h;y++){
+          for(x=0;x<w;x+=2){
+            int y;
+            int u;
+            int v;
+            y=(65481*rgb_row[4*x+2]+128553*rgb_row[4*x+1]
+             +24966*rgb_row[4*x+0]+4207500)/255000;
+            y_row[x]=OC_CLAMP255(y);
+            y=(65481*rgb_row[4*x+6]+128553*rgb_row[4*x+5]
+             +24966*rgb_row[4*x+4]+4207500)/255000;
+            y_row[x+1]=OC_CLAMP255(y);
+            u=(-16744*(rgb_row[4*x+2]+rgb_row[4*x+6])
+             -32872*(rgb_row[4*x+1]+rgb_row[4*x+5])
+             +49616*(rgb_row[4*x+0]+rgb_row[4*x+4])+29032005)/225930;
+            v=(78512*(rgb_row[4*x+2]+rgb_row[4*x+6])
+             -65744*(rgb_row[4*x+1]+rgb_row[4*x+5])
+             -12768*(rgb_row[4*x+0]+rgb_row[4*x+4])+45940035)/357510;
+            u_row[x>>1]=OC_CLAMP255(u);
+            v_row[x>>1]=OC_CLAMP255(v);
+          }
+          y_row+=_ycbcr[0].stride;
+          u_row+=_ycbcr[1].stride;
+          v_row+=_ycbcr[2].stride;
+          rgb_row+=cstride;
+        }
+      }break;
+      /*case TH_PF_444:*/
+      default:{
+        for(y=0;y<h;y++){
+          for(x=0;x<w;x++){
+            int y;
+            int u;
+            int v;
+            y=(65481*rgb_row[4*x+2]+128553*rgb_row[4*x+1]
+             +24966*rgb_row[4*x+0]+4207500)/255000;
+            u=(-33488*rgb_row[4*x+2]-65744*rgb_row[4*x+1]
+             +99232*rgb_row[4*x+0]+29032005)/225930;
+            v=(157024*rgb_row[4*x+2]-131488*rgb_row[4*x+1]
+             -25536*rgb_row[4*x+0]+45940035)/357510;
+            y_row[x]=OC_CLAMP255(y);
+            u_row[x]=OC_CLAMP255(u);
+            v_row[x]=OC_CLAMP255(v);
+          }
+          y_row+=_ycbcr[0].stride;
+          u_row+=_ycbcr[1].stride;
+          v_row+=_ycbcr[2].stride;
+          rgb_row+=cstride;
+        }
+      }break;
+    }
+    /*Finished.
+      Destroy the surface.*/
+    cairo_surface_destroy(cs);
+  }
+#endif
   return 0;
 }
rename from media/libtheora/lib/dec/dequant.c
rename to media/libtheora/lib/dequant.c
--- a/media/libtheora/lib/dec/dequant.c
+++ b/media/libtheora/lib/dequant.c
@@ -1,88 +1,88 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function:
-    last mod: $Id: dequant.c 15400 2008-10-15 12:10:58Z tterribe $
+    last mod: $Id: dequant.c 16503 2009-08-22 18:14:02Z giles $
 
  ********************************************************************/
 
 #include <stdlib.h>
 #include <string.h>
 #include <ogg/ogg.h>
 #include "dequant.h"
 #include "decint.h"
 
-int oc_quant_params_unpack(oggpack_buffer *_opb,
- th_quant_info *_qinfo){
+int oc_quant_params_unpack(oc_pack_buf *_opb,th_quant_info *_qinfo){
   th_quant_base *base_mats;
   long           val;
   int            nbase_mats;
   int            sizes[64];
   int            indices[64];
   int            nbits;
   int            bmi;
   int            ci;
   int            qti;
   int            pli;
   int            qri;
   int            qi;
   int            i;
-  theorapackB_read(_opb,3,&val);
+  val=oc_pack_read(_opb,3);
   nbits=(int)val;
   for(qi=0;qi<64;qi++){
-    theorapackB_read(_opb,nbits,&val);
+    val=oc_pack_read(_opb,nbits);
     _qinfo->loop_filter_limits[qi]=(unsigned char)val;
   }
-  theorapackB_read(_opb,4,&val);
+  val=oc_pack_read(_opb,4);
   nbits=(int)val+1;
   for(qi=0;qi<64;qi++){
-    theorapackB_read(_opb,nbits,&val);
+    val=oc_pack_read(_opb,nbits);
     _qinfo->ac_scale[qi]=(ogg_uint16_t)val;
   }
-  theorapackB_read(_opb,4,&val);
+  val=oc_pack_read(_opb,4);
   nbits=(int)val+1;
   for(qi=0;qi<64;qi++){
-    theorapackB_read(_opb,nbits,&val);
+    val=oc_pack_read(_opb,nbits);
     _qinfo->dc_scale[qi]=(ogg_uint16_t)val;
   }
-  theorapackB_read(_opb,9,&val);
+  val=oc_pack_read(_opb,9);
   nbase_mats=(int)val+1;
   base_mats=_ogg_malloc(nbase_mats*sizeof(base_mats[0]));
+  if(base_mats==NULL)return TH_EFAULT;
   for(bmi=0;bmi<nbase_mats;bmi++){
     for(ci=0;ci<64;ci++){
-      theorapackB_read(_opb,8,&val);
+      val=oc_pack_read(_opb,8);
       base_mats[bmi][ci]=(unsigned char)val;
     }
   }
   nbits=oc_ilog(nbase_mats-1);
   for(i=0;i<6;i++){
     th_quant_ranges *qranges;
     th_quant_base   *qrbms;
     int             *qrsizes;
     qti=i/3;
     pli=i%3;
     qranges=_qinfo->qi_ranges[qti]+pli;
     if(i>0){
-      theorapackB_read1(_opb,&val);
+      val=oc_pack_read1(_opb);
       if(!val){
         int qtj;
         int plj;
         if(qti>0){
-          theorapackB_read1(_opb,&val);
+          val=oc_pack_read1(_opb);
           if(val){
             qtj=qti-1;
             plj=pli;
           }
           else{
             qtj=(i-1)/3;
             plj=(i-1)%3;
           }
@@ -90,35 +90,47 @@ int oc_quant_params_unpack(oggpack_buffe
         else{
           qtj=(i-1)/3;
           plj=(i-1)%3;
         }
         *qranges=*(_qinfo->qi_ranges[qtj]+plj);
         continue;
       }
     }
-    theorapackB_read(_opb,nbits,&val);
+    val=oc_pack_read(_opb,nbits);
     indices[0]=(int)val;
     for(qi=qri=0;qi<63;){
-      theorapackB_read(_opb,oc_ilog(62-qi),&val);
+      val=oc_pack_read(_opb,oc_ilog(62-qi));
       sizes[qri]=(int)val+1;
       qi+=(int)val+1;
-      theorapackB_read(_opb,nbits,&val);
+      val=oc_pack_read(_opb,nbits);
       indices[++qri]=(int)val;
     }
     /*Note: The caller is responsible for cleaning up any partially
        constructed qinfo.*/
     if(qi>63){
       _ogg_free(base_mats);
       return TH_EBADHEADER;
     }
     qranges->nranges=qri;
     qranges->sizes=qrsizes=(int *)_ogg_malloc(qri*sizeof(qrsizes[0]));
+    if(qranges->sizes==NULL){
+      /*Note: The caller is responsible for cleaning up any partially
+         constructed qinfo.*/
+      _ogg_free(base_mats);
+      return TH_EFAULT;
+    }
     memcpy(qrsizes,sizes,qri*sizeof(qrsizes[0]));
     qrbms=(th_quant_base *)_ogg_malloc((qri+1)*sizeof(qrbms[0]));
+    if(qrbms==NULL){
+      /*Note: The caller is responsible for cleaning up any partially
+         constructed qinfo.*/
+      _ogg_free(base_mats);
+      return TH_EFAULT;
+    }
     qranges->base_matrices=(const th_quant_base *)qrbms;
     do{
       bmi=indices[qri];
       /*Note: The caller is responsible for cleaning up any partially
          constructed qinfo.*/
       if(bmi>=nbase_mats){
         _ogg_free(base_mats);
         return TH_EBADHEADER;
rename from media/libtheora/lib/dec/dequant.h
rename to media/libtheora/lib/dequant.h
--- a/media/libtheora/lib/dec/dequant.h
+++ b/media/libtheora/lib/dequant.h
@@ -1,26 +1,27 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function:
-    last mod: $Id: dequant.h 15400 2008-10-15 12:10:58Z tterribe $
+    last mod: $Id: dequant.h 16503 2009-08-22 18:14:02Z giles $
 
  ********************************************************************/
 
 #if !defined(_dequant_H)
 # define _dequant_H (1)
 # include "quant.h"
+# include "bitpack.h"
 
-int oc_quant_params_unpack(oggpack_buffer *_opb,
+int oc_quant_params_unpack(oc_pack_buf *_opb,
  th_quant_info *_qinfo);
 void oc_quant_params_clear(th_quant_info *_qinfo);
 
 #endif
new file mode 100644
--- /dev/null
+++ b/media/libtheora/lib/encint.h
@@ -0,0 +1,493 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * 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-2009                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+  last mod: $Id: encint.h 16503 2009-08-22 18:14:02Z giles $
+
+ ********************************************************************/
+#if !defined(_encint_H)
+# define _encint_H (1)
+# if defined(HAVE_CONFIG_H)
+#  include "config.h"
+# endif
+# include "theora/theoraenc.h"
+# include "internal.h"
+# include "ocintrin.h"
+# include "mathops.h"
+# include "enquant.h"
+# include "huffenc.h"
+/*# define OC_COLLECT_METRICS*/
+
+
+
+typedef oc_mv                         oc_mv2[2];
+
+typedef struct oc_enc_opt_vtable      oc_enc_opt_vtable;
+typedef struct oc_mb_enc_info         oc_mb_enc_info;
+typedef struct oc_mode_scheme_chooser oc_mode_scheme_chooser;
+typedef struct oc_iir_filter          oc_iir_filter;
+typedef struct oc_frame_metrics       oc_frame_metrics;
+typedef struct oc_rc_state            oc_rc_state;
+typedef struct th_enc_ctx             oc_enc_ctx;
+typedef struct oc_token_checkpoint    oc_token_checkpoint;
+
+
+
+/*Constants for the packet-out state machine specific to the encoder.*/
+
+/*Next packet to emit: Data packet, but none are ready yet.*/
+#define OC_PACKET_EMPTY (0)
+/*Next packet to emit: Data packet, and one is ready.*/
+#define OC_PACKET_READY (1)
+
+/*All features enabled.*/
+#define OC_SP_LEVEL_SLOW       (0)
+/*Enable early skip.*/
+#define OC_SP_LEVEL_EARLY_SKIP (1)
+/*Disable motion compensation.*/
+#define OC_SP_LEVEL_NOMC       (2)
+/*Maximum valid speed level.*/
+#define OC_SP_LEVEL_MAX        (2)
+
+
+/*The bits used for each of the MB mode codebooks.*/
+extern const unsigned char OC_MODE_BITS[2][OC_NMODES];
+
+/*The bits used for each of the MV codebooks.*/
+extern const unsigned char OC_MV_BITS[2][64];
+
+/*The minimum value that can be stored in a SB run for each codeword.
+  The last entry is the upper bound on the length of a single SB run.*/
+extern const ogg_uint16_t  OC_SB_RUN_VAL_MIN[8];
+/*The bits used for each SB run codeword.*/
+extern const unsigned char OC_SB_RUN_CODE_NBITS[7];
+
+/*The bits used for each block run length (starting with 1).*/
+extern const unsigned char OC_BLOCK_RUN_CODE_NBITS[30];
+
+
+
+/*Encoder specific functions with accelerated variants.*/
+struct oc_enc_opt_vtable{
+  unsigned (*frag_sad)(const unsigned char *_src,
+   const unsigned char *_ref,int _ystride);
+  unsigned (*frag_sad_thresh)(const unsigned char *_src,
+   const unsigned char *_ref,int _ystride,unsigned _thresh);
+  unsigned (*frag_sad2_thresh)(const unsigned char *_src,
+   const unsigned char *_ref1,const unsigned char *_ref2,int _ystride,
+   unsigned _thresh);
+  unsigned (*frag_satd_thresh)(const unsigned char *_src,
+   const unsigned char *_ref,int _ystride,unsigned _thresh);
+  unsigned (*frag_satd2_thresh)(const unsigned char *_src,
+   const unsigned char *_ref1,const unsigned char *_ref2,int _ystride,
+   unsigned _thresh);
+  unsigned (*frag_intra_satd)(const unsigned char *_src,int _ystride);
+  void     (*frag_sub)(ogg_int16_t _diff[64],const unsigned char *_src,
+   const unsigned char *_ref,int _ystride);
+  void     (*frag_sub_128)(ogg_int16_t _diff[64],
+   const unsigned char *_src,int _ystride);
+  void     (*frag_copy2)(unsigned char *_dst,
+   const unsigned char *_src1,const unsigned char *_src2,int _ystride);
+  void     (*frag_recon_intra)(unsigned char *_dst,int _ystride,
+   const ogg_int16_t _residue[64]);
+  void     (*frag_recon_inter)(unsigned char *_dst,
+   const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]);
+  void     (*fdct8x8)(ogg_int16_t _y[64],const ogg_int16_t _x[64]);
+};
+
+
+void oc_enc_vtable_init(oc_enc_ctx *_enc);
+
+
+
+/*Encoder-specific macroblock information.*/
+struct oc_mb_enc_info{
+  /*Neighboring macro blocks that have MVs available from the current frame.*/
+  unsigned      cneighbors[4];
+  /*Neighboring macro blocks to use for MVs from the previous frame.*/
+  unsigned      pneighbors[4];
+  /*The number of current-frame neighbors.*/
+  unsigned char ncneighbors;
+  /*The number of previous-frame neighbors.*/
+  unsigned char npneighbors;
+  /*Flags indicating which MB modes have been refined.*/
+  unsigned char refined;
+  /*Motion vectors for a macro block for the current frame and the
+     previous two frames.
+    Each is a set of 2 vectors against OC_FRAME_GOLD and OC_FRAME_PREV, which
+     can be used to estimate constant velocity and constant acceleration
+     predictors.
+    Uninitialized MVs are (0,0).*/
+  oc_mv2        analysis_mv[3];
+  /*Current unrefined analysis MVs.*/
+  oc_mv         unref_mv[2];
+  /*Unrefined block MVs.*/
+  oc_mv         block_mv[4];
+  /*Refined block MVs.*/
+  oc_mv         ref_mv[4];
+  /*Minimum motion estimation error from the analysis stage.*/
+  ogg_uint16_t  error[2];
+  /*MB error for half-pel refinement for each frame type.*/
+  unsigned      satd[2];
+  /*Block error for half-pel refinement.*/
+  unsigned      block_satd[4];
+};
+
+
+
+/*State machine to estimate the opportunity cost of coding a MB mode.*/
+struct oc_mode_scheme_chooser{
+  /*Pointers to the a list containing the index of each mode in the mode
+     alphabet used by each scheme.
+    The first entry points to the dynamic scheme0_ranks, while the remaining 7
+     point to the constant entries stored in OC_MODE_SCHEMES.*/
+  const unsigned char *mode_ranks[8];
+  /*The ranks for each mode when coded with scheme 0.
+    These are optimized so that the more frequent modes have lower ranks.*/
+  unsigned char        scheme0_ranks[OC_NMODES];
+  /*The list of modes, sorted in descending order of frequency, that
+    corresponds to the ranks above.*/
+  unsigned char        scheme0_list[OC_NMODES];
+  /*The number of times each mode has been chosen so far.*/
+  int                  mode_counts[OC_NMODES];
+  /*The list of mode coding schemes, sorted in ascending order of bit cost.*/
+  unsigned char        scheme_list[8];
+  /*The number of bits used by each mode coding scheme.*/
+  ptrdiff_t            scheme_bits[8];
+};
+
+
+void oc_mode_scheme_chooser_init(oc_mode_scheme_chooser *_chooser);
+
+
+
+/*A 2nd order low-pass Bessel follower.
+  We use this for rate control because it has fast reaction time, but is
+   critically damped.*/
+struct oc_iir_filter{
+  ogg_int32_t c[2];
+  ogg_int64_t g;
+  ogg_int32_t x[2];
+  ogg_int32_t y[2];
+};
+
+
+
+/*The 2-pass metrics associated with a single frame.*/
+struct oc_frame_metrics{
+  /*The log base 2 of the scale factor for this frame in Q24 format.*/
+  ogg_int32_t   log_scale;
+  /*The number of application-requested duplicates of this frame.*/
+  unsigned      dup_count:31;
+  /*The frame type from pass 1.*/
+  unsigned      frame_type:1;
+};
+
+
+
+/*Rate control state information.*/
+struct oc_rc_state{
+  /*The target average bits per frame.*/
+  ogg_int64_t        bits_per_frame;
+  /*The current buffer fullness (bits available to be used).*/
+  ogg_int64_t        fullness;
+  /*The target buffer fullness.
+    This is where we'd like to be by the last keyframe the appears in the next
+     buf_delay frames.*/
+  ogg_int64_t        target;
+  /*The maximum buffer fullness (total size of the buffer).*/
+  ogg_int64_t        max;
+  /*The log of the number of pixels in a frame in Q57 format.*/
+  ogg_int64_t        log_npixels;
+  /*The exponent used in the rate model in Q8 format.*/
+  unsigned           exp[2];
+  /*The number of frames to distribute the buffer usage over.*/
+  int                buf_delay;
+  /*The total drop count from the previous frame.
+    This includes duplicates explicitly requested via the
+     TH_ENCCTL_SET_DUP_COUNT API as well as frames we chose to drop ourselves.*/
+  ogg_uint32_t       prev_drop_count;
+  /*The log of an estimated scale factor used to obtain the real framerate, for
+     VFR sources or, e.g., 12 fps content doubled to 24 fps, etc.*/
+  ogg_int64_t        log_drop_scale;
+  /*The log of estimated scale factor for the rate model in Q57 format.*/
+  ogg_int64_t        log_scale[2];
+  /*The log of the target quantizer level in Q57 format.*/
+  ogg_int64_t        log_qtarget;
+  /*Will we drop frames to meet bitrate target?*/
+  unsigned char      drop_frames;
+  /*Do we respect the maximum buffer fullness?*/
+  unsigned char      cap_overflow;
+  /*Can the reservoir go negative?*/
+  unsigned char      cap_underflow;
+  /*Second-order lowpass filters to track scale and VFR.*/
+  oc_iir_filter      scalefilter[2];
+  int                inter_count;
+  int                inter_delay;
+  int                inter_delay_target;
+  oc_iir_filter      vfrfilter;
+  /*Two-pass mode state.
+    0 => 1-pass encoding.
+    1 => 1st pass of 2-pass encoding.
+    2 => 2nd pass of 2-pass encoding.*/
+  int                twopass;
+  /*Buffer for current frame metrics.*/
+  unsigned char      twopass_buffer[48];
+  /*The number of bytes in the frame metrics buffer.
+    When 2-pass encoding is enabled, this is set to 0 after each frame is
+     submitted, and must be non-zero before the next frame will be accepted.*/
+  int                twopass_buffer_bytes;
+  int                twopass_buffer_fill;
+  /*Whether or not to force the next frame to be a keyframe.*/
+  unsigned char      twopass_force_kf;
+  /*The metrics for the previous frame.*/
+  oc_frame_metrics   prev_metrics;
+  /*The metrics for the current frame.*/
+  oc_frame_metrics   cur_metrics;
+  /*The buffered metrics for future frames.*/
+  oc_frame_metrics  *frame_metrics;
+  int                nframe_metrics;
+  int                cframe_metrics;
+  /*The index of the current frame in the circular metric buffer.*/
+  int                frame_metrics_head;
+  /*The frame count of each type (keyframes, delta frames, and dup frames);
+     32 bits limits us to 2.268 years at 60 fps.*/
+  ogg_uint32_t       frames_total[3];
+  /*The number of frames of each type yet to be processed.*/
+  ogg_uint32_t       frames_left[3];
+  /*The sum of the scale values for each frame type.*/
+  ogg_int64_t        scale_sum[2];
+  /*The start of the window over which the current scale sums are taken.*/
+  int                scale_window0;
+  /*The end of the window over which the current scale sums are taken.*/
+  int                scale_window_end;
+  /*The frame count of each type in the current 2-pass window; this does not
+     include dup frames.*/
+  int                nframes[3];
+  /*The total accumulated estimation bias.*/
+  ogg_int64_t        rate_bias;
+};
+
+
+void oc_rc_state_init(oc_rc_state *_rc,oc_enc_ctx *_enc);
+void oc_rc_state_clear(oc_rc_state *_rc);
+
+void oc_enc_rc_resize(oc_enc_ctx *_enc);
+int oc_enc_select_qi(oc_enc_ctx *_enc,int _qti,int _clamp);
+void oc_enc_calc_lambda(oc_enc_ctx *_enc,int _frame_type);
+int oc_enc_update_rc_state(oc_enc_ctx *_enc,
+ long _bits,int _qti,int _qi,int _trial,int _droppable);
+int oc_enc_rc_2pass_out(oc_enc_ctx *_enc,unsigned char **_buf);
+int oc_enc_rc_2pass_in(oc_enc_ctx *_enc,unsigned char *_buf,size_t _bytes);
+
+
+
+/*The internal encoder state.*/
+struct th_enc_ctx{
+  /*Shared encoder/decoder state.*/
+  oc_theora_state          state;
+  /*Buffer in which to assemble packets.*/
+  oggpack_buffer           opb;
+  /*Encoder-specific macroblock information.*/
+  oc_mb_enc_info          *mb_info;
+  /*DC coefficients after prediction.*/
+  ogg_int16_t             *frag_dc;
+  /*The list of coded macro blocks, in coded order.*/
+  unsigned                *coded_mbis;
+  /*The number of coded macro blocks.*/
+  size_t                   ncoded_mbis;
+  /*Whether or not packets are ready to be emitted.
+    This takes on negative values while there are remaining header packets to
+     be emitted, reaches 0 when the codec is ready for input, and becomes
+     positive when a frame has been processed and data packets are ready.*/
+  int                      packet_state;
+  /*The maximum distance between keyframes.*/
+  ogg_uint32_t             keyframe_frequency_force;
+  /*The number of duplicates to produce for the next frame.*/
+  ogg_uint32_t             dup_count;
+  /*The number of duplicates remaining to be emitted for the current frame.*/
+  ogg_uint32_t             nqueued_dups;
+  /*The number of duplicates emitted for the last frame.*/
+  ogg_uint32_t             prev_dup_count;
+  /*The current speed level.*/
+  int                      sp_level;
+  /*Whether or not VP3 compatibility mode has been enabled.*/
+  unsigned char            vp3_compatible;
+  /*Whether or not any INTER frames have been coded.*/
+  unsigned char            coded_inter_frame;
+  /*Whether or not previous frame was dropped.*/
+  unsigned char            prevframe_dropped;
+  /*Stores most recently chosen Huffman tables for each frame type, DC and AC
+     coefficients, and luma and chroma tokens.
+    The actual Huffman table used for a given coefficient depends not only on
+     the choice made here, but also its index in the zig-zag ordering.*/
+  unsigned char            huff_idxs[2][2][2];
+  /*Current count of bits used by each MV coding mode.*/
+  size_t                   mv_bits[2];
+  /*The mode scheme chooser for estimating mode coding costs.*/
+  oc_mode_scheme_chooser   chooser;
+  /*The number of vertical super blocks in an MCU.*/
+  int                      mcu_nvsbs;
+  /*The SSD error for skipping each fragment in the current MCU.*/
+  unsigned                *mcu_skip_ssd;
+  /*The DCT token lists for each coefficient and each plane.*/
+  unsigned char          **dct_tokens[3];
+  /*The extra bits associated with each DCT token.*/
+  ogg_uint16_t           **extra_bits[3];
+  /*The number of DCT tokens for each coefficient for each plane.*/
+  ptrdiff_t                ndct_tokens[3][64];
+  /*Pending EOB runs for each coefficient for each plane.*/
+  ogg_uint16_t             eob_run[3][64];
+  /*The offset of the first DCT token for each coefficient for each plane.*/
+  unsigned char            dct_token_offs[3][64];
+  /*The last DC coefficient for each plane and reference frame.*/
+  int                      dc_pred_last[3][3];
+#if defined(OC_COLLECT_METRICS)
+  /*Fragment SATD statistics for MB mode estimation metrics.*/
+  unsigned                *frag_satd;
+  /*Fragment SSD statistics for MB mode estimation metrics.*/
+  unsigned                *frag_ssd;
+#endif
+  /*The R-D optimization parameter.*/
+  int                      lambda;
+  /*The huffman tables in use.*/
+  th_huff_code             huff_codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS];
+  /*The quantization parameters in use.*/
+  th_quant_info            qinfo;
+  oc_iquant               *enquant_tables[64][3][2];
+  oc_iquant_table          enquant_table_data[64][3][2];
+  /*An "average" quantizer for each quantizer type (INTRA or INTER) and qi
+     value.
+    This is used to paramterize the rate control decisions.
+    They are kept in the log domain to simplify later processing.
+    Keep in mind these are DCT domain quantizers, and so are scaled by an
+     additional factor of 4 from the pixel domain.*/
+  ogg_int64_t              log_qavg[2][64];
+  /*The buffer state used to drive rate control.*/
+  oc_rc_state              rc;
+  /*Table for encoder acceleration functions.*/
+  oc_enc_opt_vtable        opt_vtable;
+};
+
+
+void oc_enc_analyze_intra(oc_enc_ctx *_enc,int _recode);
+int oc_enc_analyze_inter(oc_enc_ctx *_enc,int _allow_keyframe,int _recode);
+#if defined(OC_COLLECT_METRICS)
+void oc_enc_mode_metrics_collect(oc_enc_ctx *_enc);
+void oc_enc_mode_metrics_dump(oc_enc_ctx *_enc);
+#endif
+
+
+
+/*Perform fullpel motion search for a single MB against both reference frames.*/
+void oc_mcenc_search(oc_enc_ctx *_enc,int _mbi);
+/*Refine a MB MV for one frame.*/
+void oc_mcenc_refine1mv(oc_enc_ctx *_enc,int _mbi,int _frame);
+/*Refine the block MVs.*/
+void oc_mcenc_refine4mv(oc_enc_ctx *_enc,int _mbi);
+
+
+
+/*Used to rollback a tokenlog transaction when we retroactively decide to skip
+   a fragment.
+  A checkpoint is taken right before each token is added.*/
+struct oc_token_checkpoint{
+  /*The color plane the token was added to.*/
+  unsigned char pli;
+  /*The zig-zag index the token was added to.*/
+  unsigned char zzi;
+  /*The outstanding EOB run count before the token was added.*/
+  ogg_uint16_t  eob_run;
+  /*The token count before the token was added.*/
+  ptrdiff_t     ndct_tokens;
+};
+
+
+
+void oc_enc_tokenize_start(oc_enc_ctx *_enc);
+int oc_enc_tokenize_ac(oc_enc_ctx *_enc,int _pli,ptrdiff_t _fragi,
+ ogg_int16_t *_qdct,const ogg_uint16_t *_dequant,const ogg_int16_t *_dct,
+ int _zzi,oc_token_checkpoint **_stack,int _acmin);
+void oc_enc_tokenlog_rollback(oc_enc_ctx *_enc,
+ const oc_token_checkpoint *_stack,int _n);
+void oc_enc_pred_dc_frag_rows(oc_enc_ctx *_enc,
+ int _pli,int _fragy0,int _frag_yend);
+void oc_enc_tokenize_dc_frag_list(oc_enc_ctx *_enc,int _pli,
+ const ptrdiff_t *_coded_fragis,ptrdiff_t _ncoded_fragis,
+ int _prev_ndct_tokens1,int _prev_eob_run1);
+void oc_enc_tokenize_finish(oc_enc_ctx *_enc);
+
+
+
+/*Utility routine to encode one of the header packets.*/
+int oc_state_flushheader(oc_theora_state *_state,int *_packet_state,
+ oggpack_buffer *_opb,const th_quant_info *_qinfo,
+ const th_huff_code _codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS],
+ const char *_vendor,th_comment *_tc,ogg_packet *_op);
+
+
+
+/*Encoder-specific accelerated functions.*/
+void oc_enc_frag_sub(const oc_enc_ctx *_enc,ogg_int16_t _diff[64],
+ const unsigned char *_src,const unsigned char *_ref,int _ystride);
+void oc_enc_frag_sub_128(const oc_enc_ctx *_enc,ogg_int16_t _diff[64],
+ const unsigned char *_src,int _ystride);
+unsigned oc_enc_frag_sad(const oc_enc_ctx *_enc,const unsigned char *_src,
+ const unsigned char *_ref,int _ystride);
+unsigned oc_enc_frag_sad_thresh(const oc_enc_ctx *_enc,
+ const unsigned char *_src,const unsigned char *_ref,int _ystride,
+ unsigned _thresh);
+unsigned oc_enc_frag_sad2_thresh(const oc_enc_ctx *_enc,
+ const unsigned char *_src,const unsigned char *_ref1,
+ const unsigned char *_ref2,int _ystride,unsigned _thresh);
+unsigned oc_enc_frag_satd_thresh(const oc_enc_ctx *_enc,
+ const unsigned char *_src,const unsigned char *_ref,int _ystride,
+ unsigned _thresh);
+unsigned oc_enc_frag_satd2_thresh(const oc_enc_ctx *_enc,
+ const unsigned char *_src,const unsigned char *_ref1,
+ const unsigned char *_ref2,int _ystride,unsigned _thresh);
+unsigned oc_enc_frag_intra_satd(const oc_enc_ctx *_enc,
+ const unsigned char *_src,int _ystride);
+void oc_enc_frag_copy2(const oc_enc_ctx *_enc,unsigned char *_dst,
+ const unsigned char *_src1,const unsigned char *_src2,int _ystride);
+void oc_enc_frag_recon_intra(const oc_enc_ctx *_enc,
+ unsigned char *_dst,int _ystride,const ogg_int16_t _residue[64]);
+void oc_enc_frag_recon_inter(const oc_enc_ctx *_enc,unsigned char *_dst,
+ const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]);
+void oc_enc_fdct8x8(const oc_enc_ctx *_enc,ogg_int16_t _y[64],
+ const ogg_int16_t _x[64]);
+
+/*Default pure-C implementations.*/
+void oc_enc_vtable_init_c(oc_enc_ctx *_enc);
+
+void oc_enc_frag_sub_c(ogg_int16_t _diff[64],
+ const unsigned char *_src,const unsigned char *_ref,int _ystride);
+void oc_enc_frag_sub_128_c(ogg_int16_t _diff[64],
+ const unsigned char *_src,int _ystride);
+void oc_enc_frag_copy2_c(unsigned char *_dst,
+ const unsigned char *_src1,const unsigned char *_src2,int _ystride);
+unsigned oc_enc_frag_sad_c(const unsigned char *_src,
+ const unsigned char *_ref,int _ystride);
+unsigned oc_enc_frag_sad_thresh_c(const unsigned char *_src,
+ const unsigned char *_ref,int _ystride,unsigned _thresh);
+unsigned oc_enc_frag_sad2_thresh_c(const unsigned char *_src,
+ const unsigned char *_ref1,const unsigned char *_ref2,int _ystride,
+ unsigned _thresh);
+unsigned oc_enc_frag_satd_thresh_c(const unsigned char *_src,
+ const unsigned char *_ref,int _ystride,unsigned _thresh);
+unsigned oc_enc_frag_satd2_thresh_c(const unsigned char *_src,
+ const unsigned char *_ref1,const unsigned char *_ref2,int _ystride,
+ unsigned _thresh);
+unsigned oc_enc_frag_intra_satd_c(const unsigned char *_src,int _ystride);
+void oc_enc_fdct8x8_c(ogg_int16_t _y[64],const ogg_int16_t _x[64]);
+
+#endif
new file mode 100644
--- /dev/null
+++ b/media/libtheora/lib/encoder_disabled.c
@@ -0,0 +1,67 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * 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-2009                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+  last mod: $Id: encoder_disabled.c 16503 2009-08-22 18:14:02Z giles $
+
+ ********************************************************************/
+#include "apiwrapper.h"
+#include "encint.h"
+
+th_enc_ctx *th_encode_alloc(const th_info *_info){
+  return NULL;
+}
+
+void th_encode_free(th_enc_ctx *_enc){}
+
+
+int th_encode_ctl(th_enc_ctx *_enc,int _req,void *_buf,size_t _buf_sz){
+  return OC_DISABLED;
+}
+
+int th_encode_flushheader(th_enc_ctx *_enc,th_comment *_tc,ogg_packet *_op){
+  return OC_DISABLED;
+}
+
+int th_encode_ycbcr_in(th_enc_ctx *_enc,th_ycbcr_buffer _img){
+  return OC_DISABLED;
+}
+
+int th_encode_packetout(th_enc_ctx *_enc,int _last_p,ogg_packet *_op){
+  return OC_DISABLED;
+}
+
+
+
+int theora_encode_init(theora_state *_te,theora_info *_ci){
+  return OC_DISABLED;
+}
+
+int theora_encode_YUVin(theora_state *_te,yuv_buffer *_yuv){
+  return OC_DISABLED;
+}
+
+int theora_encode_packetout(theora_state *_te,int _last_p,ogg_packet *_op){
+  return OC_DISABLED;
+}
+
+int theora_encode_header(theora_state *_te,ogg_packet *_op){
+  return OC_DISABLED;
+}
+
+int theora_encode_comment(theora_comment *_tc,ogg_packet *_op){
+  return OC_DISABLED;
+}
+
+int theora_encode_tables(theora_state *_te,ogg_packet *_op){
+  return OC_DISABLED;
+}
new file mode 100644
--- /dev/null
+++ b/media/libtheora/lib/enquant.h
@@ -0,0 +1,27 @@
+#if !defined(_enquant_H)
+# define _enquant_H (1)
+# include "quant.h"
+
+typedef struct oc_iquant oc_iquant;
+
+#define OC_QUANT_MAX_LOG (OC_Q57(OC_STATIC_ILOG_32(OC_QUANT_MAX)-1))
+
+/*Used to compute x/d via ((x*m>>16)+x>>l)+(x<0))
+   (i.e., one 16x16->16 mul, 2 shifts, and 2 adds).
+  This is not an approximation; for 16-bit x and d, it is exact.*/
+struct oc_iquant{
+  ogg_int16_t m;
+  ogg_int16_t l;
+};
+
+typedef oc_iquant        oc_iquant_table[64];
+
+
+
+void oc_quant_params_pack(oggpack_buffer *_opb,const th_quant_info *_qinfo);
+void oc_enquant_tables_init(ogg_uint16_t *_dequant[64][3][2],
+ oc_iquant *_enquant[64][3][2],const th_quant_info *_qinfo);
+void oc_enquant_qavg_init(ogg_int64_t _log_qavg[2][64],
+ ogg_uint16_t *_dequant[64][3][2],int _pixel_fmt);
+
+#endif
rename from media/libtheora/lib/dec/fragment.c
rename to media/libtheora/lib/fragment.c
--- a/media/libtheora/lib/dec/fragment.c
+++ b/media/libtheora/lib/fragment.c
@@ -1,199 +1,87 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function:
-    last mod: $Id: fragment.c 15469 2008-10-30 12:49:42Z tterribe $
+    last mod: $Id: fragment.c 16503 2009-08-22 18:14:02Z giles $
 
  ********************************************************************/
+#include <string.h>
+#include "internal.h"
 
-#include "../internal.h"
+void oc_frag_copy(const oc_theora_state *_state,unsigned char *_dst,
+ const unsigned char *_src,int _ystride){
+  (*_state->opt_vtable.frag_copy)(_dst,_src,_ystride);
+}
+
+void oc_frag_copy_c(unsigned char *_dst,const unsigned char *_src,int _ystride){
+  int i;
+  for(i=8;i-->0;){
+    memcpy(_dst,_src,8*sizeof(*_dst));
+    _dst+=_ystride;
+    _src+=_ystride;
+  }
+}
 
 void oc_frag_recon_intra(const oc_theora_state *_state,unsigned char *_dst,
- int _dst_ystride,const ogg_int16_t *_residue){
-  _state->opt_vtable.frag_recon_intra(_dst,_dst_ystride,_residue);
+ int _ystride,const ogg_int16_t _residue[64]){
+  _state->opt_vtable.frag_recon_intra(_dst,_ystride,_residue);
 }
 
-void oc_frag_recon_intra_c(unsigned char *_dst,int _dst_ystride,
- const ogg_int16_t *_residue){
+void oc_frag_recon_intra_c(unsigned char *_dst,int _ystride,
+ const ogg_int16_t _residue[64]){
   int i;
   for(i=0;i<8;i++){
     int j;
-    for(j=0;j<8;j++){
-      int res;
-      res=*_residue++;
-      _dst[j]=OC_CLAMP255(res+128);
-    }
-    _dst+=_dst_ystride;
+    for(j=0;j<8;j++)_dst[j]=OC_CLAMP255(_residue[i*8+j]+128);
+    _dst+=_ystride;
   }
 }
 
 void oc_frag_recon_inter(const oc_theora_state *_state,unsigned char *_dst,
- int _dst_ystride,const unsigned char *_src,int _src_ystride,
- const ogg_int16_t *_residue){
-  _state->opt_vtable.frag_recon_inter(_dst,_dst_ystride,_src,_src_ystride,
-   _residue);
+ const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]){
+  _state->opt_vtable.frag_recon_inter(_dst,_src,_ystride,_residue);
 }
 
-void oc_frag_recon_inter_c(unsigned char *_dst,int _dst_ystride,
- const unsigned char *_src,int _src_ystride,const ogg_int16_t *_residue){
+void oc_frag_recon_inter_c(unsigned char *_dst,
+ const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]){
   int i;
   for(i=0;i<8;i++){
     int j;
-    for(j=0;j<8;j++){
-      int res;
-      res=*_residue++;
-      _dst[j]=OC_CLAMP255(res+_src[j]);
-    }
-    _dst+=_dst_ystride;
-    _src+=_src_ystride;
+    for(j=0;j<8;j++)_dst[j]=OC_CLAMP255(_residue[i*8+j]+_src[j]);
+    _dst+=_ystride;
+    _src+=_ystride;
   }
 }
 
 void oc_frag_recon_inter2(const oc_theora_state *_state,unsigned char *_dst,
- int _dst_ystride,const unsigned char *_src1,int _src1_ystride,
- const unsigned char *_src2,int _src2_ystride,const ogg_int16_t *_residue){
-  _state->opt_vtable.frag_recon_inter2(_dst,_dst_ystride,_src1,_src1_ystride,
-   _src2,_src2_ystride,_residue);
+ const unsigned char *_src1,const unsigned char *_src2,int _ystride,
+ const ogg_int16_t _residue[64]){
+  _state->opt_vtable.frag_recon_inter2(_dst,_src1,_src2,_ystride,_residue);
 }
 
-void oc_frag_recon_inter2_c(unsigned char *_dst,int _dst_ystride,
- const unsigned char *_src1,int _src1_ystride,const unsigned char *_src2,
- int _src2_ystride,const ogg_int16_t *_residue){
+void oc_frag_recon_inter2_c(unsigned char *_dst,const unsigned char *_src1,
+ const unsigned char *_src2,int _ystride,const ogg_int16_t _residue[64]){
   int i;
   for(i=0;i<8;i++){
     int j;
-    for(j=0;j<8;j++){
-      int res;
-      res=*_residue++;
-      _dst[j]=OC_CLAMP255(res+((int)_src1[j]+_src2[j]>>1));
-    }
-    _dst+=_dst_ystride;
-    _src1+=_src1_ystride;
-    _src2+=_src2_ystride;
+    for(j=0;j<8;j++)_dst[j]=OC_CLAMP255(_residue[i*8+j]+(_src1[j]+_src2[j]>>1));
+    _dst+=_ystride;
+    _src1+=_ystride;
+    _src2+=_ystride;
   }
 }
 
-/*Computes the predicted DC value for the given fragment.
-  This requires that the fully decoded DC values be available for the left,
-   upper-left, upper, and upper-right fragments (if they exist).
-  _frag:      The fragment to predict the DC value for.
-  _fplane:    The fragment plane the fragment belongs to.
-  _x:         The x-coordinate of the fragment.
-  _y:         The y-coordinate of the fragment.
-  _pred_last: The last fully-decoded DC value for each predictor frame
-               (OC_FRAME_GOLD, OC_FRAME_PREV and OC_FRAME_SELF).
-              This should be initialized to 0's for the first fragment in each
-               color plane.
-  Return: The predicted DC value for this fragment.*/
-int oc_frag_pred_dc(const oc_fragment *_frag,
- const oc_fragment_plane *_fplane,int _x,int _y,int _pred_last[3]){
-  static const int PRED_SCALE[16][4]={
-    /*0*/
-    {0,0,0,0},
-    /*OC_PL*/
-    {1,0,0,0},
-    /*OC_PUL*/
-    {1,0,0,0},
-    /*OC_PL|OC_PUL*/
-    {1,0,0,0},
-    /*OC_PU*/
-    {1,0,0,0},
-    /*OC_PL|OC_PU*/
-    {1,1,0,0},
-    /*OC_PUL|OC_PU*/
-    {0,1,0,0},
-    /*OC_PL|OC_PUL|PC_PU*/
-    {29,-26,29,0},
-    /*OC_PUR*/
-    {1,0,0,0},
-    /*OC_PL|OC_PUR*/
-    {75,53,0,0},
-    /*OC_PUL|OC_PUR*/
-    {1,1,0,0},
-    /*OC_PL|OC_PUL|OC_PUR*/
-    {75,0,53,0},
-    /*OC_PU|OC_PUR*/
-    {1,0,0,0},
-    /*OC_PL|OC_PU|OC_PUR*/
-    {75,0,53,0},
-    /*OC_PUL|OC_PU|OC_PUR*/
-    {3,10,3,0},
-    /*OC_PL|OC_PUL|OC_PU|OC_PUR*/
-    {29,-26,29,0}
-  };
-  static const int PRED_SHIFT[16]={0,0,0,0,0,1,0,5,0,7,1,7,0,7,4,5};
-  static const int PRED_RMASK[16]={0,0,0,0,0,1,0,31,0,127,1,127,0,127,15,31};
-  static const int BC_MASK[8]={
-    /*No boundary condition.*/
-    OC_PL|OC_PUL|OC_PU|OC_PUR,
-    /*Left column.*/
-    OC_PU|OC_PUR,
-    /*Top row.*/
-    OC_PL,
-    /*Top row, left column.*/
-    0,
-    /*Right column.*/
-    OC_PL|OC_PUL|OC_PU,
-    /*Right and left column.*/
-    OC_PU,
-    /*Top row, right column.*/
-    OC_PL,
-    /*Top row, right and left column.*/
-    0
-  };
-  /*Predictor fragments, left, up-left, up, up-right.*/
-  const oc_fragment *predfr[4];
-  /*The frame used for prediction for this fragment.*/
-  int                pred_frame;
-  /*The boundary condition flags.*/
-  int                bc;
-  /*DC predictor values: left, up-left, up, up-right, missing values
-     skipped.*/
-  int                p[4];
-  /*Predictor count.*/
-  int                np;
-  /*Which predictor constants to use.*/
-  int                pflags;
-  /*The predicted DC value.*/
-  int                ret;
-  int                i;
-  pred_frame=OC_FRAME_FOR_MODE[_frag->mbmode];
-  bc=(_x==0)+((_y==0)<<1)+((_x+1==_fplane->nhfrags)<<2);
-  predfr[0]=_frag-1;
-  predfr[1]=_frag-_fplane->nhfrags-1;
-  predfr[2]=predfr[1]+1;
-  predfr[3]=predfr[2]+1;
-  np=0;
-  pflags=0;
-  for(i=0;i<4;i++){
-    int pflag;
-    pflag=1<<i;
-    if((BC_MASK[bc]&pflag)&&predfr[i]->coded&&
-     OC_FRAME_FOR_MODE[predfr[i]->mbmode]==pred_frame){
-      p[np++]=predfr[i]->dc;
-      pflags|=pflag;
-    }
-  }
-  if(pflags==0)return _pred_last[pred_frame];
-  else{
-    ret=PRED_SCALE[pflags][0]*p[0];
-    /*LOOP VECTORIZES.*/
-    for(i=1;i<np;i++)ret+=PRED_SCALE[pflags][i]*p[i];
-    ret=OC_DIV_POW2(ret,PRED_SHIFT[pflags],PRED_RMASK[pflags]);
-  }
-  if((pflags&(OC_PL|OC_PUL|OC_PU))==(OC_PL|OC_PUL|OC_PU)){
-    if(abs(ret-p[2])>128)ret=p[2];
-    else if(abs(ret-p[0])>128)ret=p[0];
-    else if(abs(ret-p[1])>128)ret=p[1];
-  }
-  return ret;
+void oc_restore_fpu(const oc_theora_state *_state){
+  _state->opt_vtable.restore_fpu();
 }
+
+void oc_restore_fpu_c(void){}
rename from media/libtheora/lib/dec/huffdec.c
rename to media/libtheora/lib/huffdec.c
--- a/media/libtheora/lib/dec/huffdec.c
+++ b/media/libtheora/lib/huffdec.c
@@ -1,78 +1,161 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function:
-    last mod: $Id: huffdec.c 15431 2008-10-21 05:04:02Z giles $
+    last mod: $Id: huffdec.c 16503 2009-08-22 18:14:02Z giles $
 
  ********************************************************************/
 
 #include <stdlib.h>
+#include <string.h>
 #include <ogg/ogg.h>
 #include "huffdec.h"
 #include "decint.h"
 
 
 /*The ANSI offsetof macro is broken on some platforms (e.g., older DECs).*/
 #define _ogg_offsetof(_type,_field)\
  ((size_t)((char *)&((_type *)0)->_field-(char *)0))
 
-/*These two functions are really part of the bitpack.c module, but
-  they are only used here. Declaring local static versions so they
-  can be inlined saves considerable function call overhead.*/
+/*The number of internal tokens associated with each of the spec tokens.*/
+static const unsigned char OC_DCT_TOKEN_MAP_ENTRIES[TH_NDCT_TOKENS]={
+  1,1,1,4,8,1,1,8,1,1,1,1,1,2,2,2,2,4,8,2,2,2,4,2,2,2,2,2,8,2,4,8
+};
 
-/*Read in bits without advancing the bitptr.
-  Here we assume 0<=_bits&&_bits<=32.*/
-static int theorapackB_look(oggpack_buffer *_b,int _bits,long *_ret){
-  long ret;
-  long m;
-  long d;
-  m=32-_bits;
-  _bits+=_b->endbit;
-  d=_b->storage-_b->endbyte;
-  if(d<=4){
-    /*Not the main path.*/
-    if(d<=0){
-      *_ret=0L;
-      return -(_bits>d*8);
-    }
-    /*If we have some bits left, but not enough, return the ones we have.*/
-    if(d*8<_bits)_bits=d*8;
+/*The map from external spec-defined tokens to internal tokens.
+  This is constructed so that any extra bits read with the original token value
+   can be masked off the least significant bits of its internal token index.
+  In addition, all of the tokens which require additional extra bits are placed
+   at the start of the list, and grouped by type.
+  OC_DCT_REPEAT_RUN3_TOKEN is placed first, as it is an extra-special case, so
+   giving it index 0 may simplify comparisons on some architectures.
+  These requirements require some substantial reordering.*/
+static const unsigned char OC_DCT_TOKEN_MAP[TH_NDCT_TOKENS]={
+  /*OC_DCT_EOB1_TOKEN (0 extra bits)*/
+  15,
+  /*OC_DCT_EOB2_TOKEN (0 extra bits)*/
+  16,
+  /*OC_DCT_EOB3_TOKEN (0 extra bits)*/
+  17,
+  /*OC_DCT_REPEAT_RUN0_TOKEN (2 extra bits)*/
+  88,
+  /*OC_DCT_REPEAT_RUN1_TOKEN (3 extra bits)*/
+  80,
+  /*OC_DCT_REPEAT_RUN2_TOKEN (4 extra bits)*/
+   1,
+  /*OC_DCT_REPEAT_RUN3_TOKEN (12 extra bits)*/
+   0,
+  /*OC_DCT_SHORT_ZRL_TOKEN (3 extra bits)*/
+  48,
+  /*OC_DCT_ZRL_TOKEN (6 extra bits)*/
+  14,
+  /*OC_ONE_TOKEN (0 extra bits)*/
+  56,
+  /*OC_MINUS_ONE_TOKEN (0 extra bits)*/
+  57,
+  /*OC_TWO_TOKEN (0 extra bits)*/
+  58,
+  /*OC_MINUS_TWO_TOKEN (0 extra bits)*/
+  59,
+  /*OC_DCT_VAL_CAT2 (1 extra bit)*/
+  60,
+  62,
+  64,
+  66,
+  /*OC_DCT_VAL_CAT3 (2 extra bits)*/
+  68,
+  /*OC_DCT_VAL_CAT4 (3 extra bits)*/
+  72,
+  /*OC_DCT_VAL_CAT5 (4 extra bits)*/
+   2,
+  /*OC_DCT_VAL_CAT6 (5 extra bits)*/
+   4,
+  /*OC_DCT_VAL_CAT7 (6 extra bits)*/
+   6,
+  /*OC_DCT_VAL_CAT8 (10 extra bits)*/
+   8,
+  /*OC_DCT_RUN_CAT1A (1 extra bit)*/
+  18,
+  20,
+  22,
+  24,
+  26,
+  /*OC_DCT_RUN_CAT1B (3 extra bits)*/
+  32,
+  /*OC_DCT_RUN_CAT1C (4 extra bits)*/
+  12,
+  /*OC_DCT_RUN_CAT2A (2 extra bits)*/
+  28,
+  /*OC_DCT_RUN_CAT2B (3 extra bits)*/
+  40
+};
+
+/*These three functions are really part of the bitpack.c module, but
+   they are only used here.
+  Declaring local static versions so they can be inlined saves considerable
+   function call overhead.*/
+
+static oc_pb_window oc_pack_refill(oc_pack_buf *_b,int _bits){
+  const unsigned char *ptr;
+  const unsigned char *stop;
+  oc_pb_window         window;
+  int                  available;
+  window=_b->window;
+  available=_b->bits;
+  ptr=_b->ptr;
+  stop=_b->stop;
+  /*This version of _refill() doesn't bother setting eof because we won't
+     check for it after we've started decoding DCT tokens.*/
+  if(ptr>=stop)available=OC_LOTS_OF_BITS;
+  while(available<=OC_PB_WINDOW_SIZE-8){
+    available+=8;
+    window|=(oc_pb_window)*ptr++<<OC_PB_WINDOW_SIZE-available;
+    if(ptr>=stop)available=OC_LOTS_OF_BITS;
   }
-  ret=_b->ptr[0]<<24+_b->endbit;
-  if(_bits>8){
-    ret|=_b->ptr[1]<<16+_b->endbit;
-    if(_bits>16){
-      ret|=_b->ptr[2]<<8+_b->endbit;
-      if(_bits>24){
-        ret|=_b->ptr[3]<<_b->endbit;
-        if(_bits>32)ret|=_b->ptr[4]>>8-_b->endbit;
-      }
-    }
-  }
-  *_ret=((ret&0xFFFFFFFF)>>(m>>1))>>(m+1>>1);
-  return 0;
+  _b->ptr=ptr;
+  if(_bits>available)window|=*ptr>>(available&7);
+  _b->bits=available;
+  return window;
 }
 
-/*advance the bitptr*/
-static void theorapackB_adv(oggpack_buffer *_b,int _bits){
-  _bits+=_b->endbit;
-  _b->ptr+=_bits>>3;
-  _b->endbyte+=_bits>>3;
-  _b->endbit=_bits&7;
+
+/*Read in bits without advancing the bit pointer.
+  Here we assume 0<=_bits&&_bits<=32.*/
+static long oc_pack_look(oc_pack_buf *_b,int _bits){
+  oc_pb_window window;
+  int          available;
+  long         result;
+  window=_b->window;
+  available=_b->bits;
+  if(_bits==0)return 0;
+  if(_bits>available)_b->window=window=oc_pack_refill(_b,_bits);
+  result=window>>OC_PB_WINDOW_SIZE-_bits;
+  return result;
+}
+
+/*Advance the bit pointer.*/
+static void oc_pack_adv(oc_pack_buf *_b,int _bits){
+  /*We ignore the special cases for _bits==0 and _bits==32 here, since they are
+     never used actually used.
+    OC_HUFF_SLUSH (defined below) would have to be at least 27 to actually read
+     32 bits in a single go, and would require a 32 GB lookup table (assuming
+     8 byte pointers, since 4 byte pointers couldn't fit such a table).*/
+  _b->window<<=_bits;
+  _b->bits-=_bits;
 }
 
 
 /*The log_2 of the size of a lookup table is allowed to grow to relative to
    the number of unique nodes it contains.
   E.g., if OC_HUFF_SLUSH is 2, then at most 75% of the space in the tree is
    wasted (each node will have an amortized cost of at most 20 bytes when using
    4-byte pointers).
@@ -85,91 +168,121 @@ static void theorapackB_adv(oggpack_buff
   11144969 read calls are required when OC_HUFF_SLUSH is 1 (34.6%).
   10538563 read calls are required when OC_HUFF_SLUSH is 2 (32.7%).
   10192578 read calls are required when OC_HUFF_SLUSH is 3 (31.6%).
   Since a value of 1 gets us the vast majority of the speed-up with only a
    small amount of wasted memory, this is what we use.*/
 #define OC_HUFF_SLUSH (1)
 
 
-/*Allocates a Huffman tree node that represents a subtree of depth _nbits.
+/*Determines the size in bytes of a Huffman tree node that represents a
+   subtree of depth _nbits.
   _nbits: The depth of the subtree.
           If this is 0, the node is a leaf node.
           Otherwise 1<<_nbits pointers are allocated for children.
-  Return: The newly allocated and fully initialized Huffman tree node.*/
-static oc_huff_node *oc_huff_node_alloc(int _nbits){
-  oc_huff_node *ret;
-  size_t        size;
+  Return: The number of bytes required to store the node.*/
+static size_t oc_huff_node_size(int _nbits){
+  size_t size;
   size=_ogg_offsetof(oc_huff_node,nodes);
   if(_nbits>0)size+=sizeof(oc_huff_node *)*(1<<_nbits);
-  ret=_ogg_calloc(1,size);
+  return size;
+}
+
+static oc_huff_node *oc_huff_node_init(char **_storage,size_t _size,int _nbits){
+  oc_huff_node *ret;
+  ret=(oc_huff_node *)*_storage;
   ret->nbits=(unsigned char)_nbits;
+  (*_storage)+=_size;
   return ret;
 }
 
-/*Frees a Huffman tree node allocated with oc_huf_node_alloc.
-  _node: The node to free.
-         This may be NULL.*/
-static void oc_huff_node_free(oc_huff_node *_node){
-  _ogg_free(_node);
-}
 
-/*Frees the memory used by a Huffman tree.
-  _node: The Huffman tree to free.
-         This may be NULL.*/
-static void oc_huff_tree_free(oc_huff_node *_node){
-  if(_node==NULL)return;
+/*Determines the size in bytes of a Huffman tree.
+  _nbits: The depth of the subtree.
+          If this is 0, the node is a leaf node.
+          Otherwise storage for 1<<_nbits pointers are added for children.
+  Return: The number of bytes required to store the tree.*/
+static size_t oc_huff_tree_size(const oc_huff_node *_node){
+  size_t size;
+  size=oc_huff_node_size(_node->nbits);
   if(_node->nbits){
     int nchildren;
     int i;
-    int inext;
     nchildren=1<<_node->nbits;
-    for(i=0;i<nchildren;i=inext){
-      inext=i+(_node->nodes[i]!=NULL?1<<_node->nbits-_node->nodes[i]->depth:1);
-      oc_huff_tree_free(_node->nodes[i]);
+    for(i=0;i<nchildren;i+=1<<_node->nbits-_node->nodes[i]->depth){
+      size+=oc_huff_tree_size(_node->nodes[i]);
     }
   }
-  oc_huff_node_free(_node);
+  return size;
 }
 
+
 /*Unpacks a sub-tree from the given buffer.
-  _opb:    The buffer to unpack from.
-  _binode: The location to store a pointer to the sub-tree in.
-  _depth:  The current depth of the tree.
-           This is used to prevent infinite recursion.
+  _opb:      The buffer to unpack from.
+  _binodes:  The nodes to store the sub-tree in.
+  _nbinodes: The number of nodes available for the sub-tree.
   Return: 0 on success, or a negative value on error.*/
-static int oc_huff_tree_unpack(oggpack_buffer *_opb,
- oc_huff_node **_binode,int _depth){
+static int oc_huff_tree_unpack(oc_pack_buf *_opb,
+ oc_huff_node *_binodes,int _nbinodes){
   oc_huff_node *binode;
   long          bits;
-  /*Prevent infinite recursion.*/
-  if(++_depth>32)return TH_EBADHEADER;
-  if(theorapackB_read1(_opb,&bits)<0)return TH_EBADHEADER;
+  int           nused;
+  if(_nbinodes<1)return TH_EBADHEADER;
+  binode=_binodes;
+  nused=0;
+  bits=oc_pack_read1(_opb);
+  if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
   /*Read an internal node:*/
   if(!bits){
     int ret;
-    binode=oc_huff_node_alloc(1);
-    binode->depth=(unsigned char)(_depth>1);
-    ret=oc_huff_tree_unpack(_opb,binode->nodes,_depth);
-    if(ret>=0)ret=oc_huff_tree_unpack(_opb,binode->nodes+1,_depth);
-    if(ret<0){
-      oc_huff_tree_free(binode);
-      *_binode=NULL;
-      return ret;
+    nused++;
+    binode->nbits=1;
+    binode->depth=1;
+    binode->nodes[0]=_binodes+nused;
+    ret=oc_huff_tree_unpack(_opb,_binodes+nused,_nbinodes-nused);
+    if(ret>=0){
+      nused+=ret;
+      binode->nodes[1]=_binodes+nused;
+      ret=oc_huff_tree_unpack(_opb,_binodes+nused,_nbinodes-nused);
     }
+    if(ret<0)return ret;
+    nused+=ret;
   }
   /*Read a leaf node:*/
   else{
-    if(theorapackB_read(_opb,OC_NDCT_TOKEN_BITS,&bits)<0)return TH_EBADHEADER;
-    binode=oc_huff_node_alloc(0);
-    binode->depth=(unsigned char)(_depth>1);
-    binode->token=(unsigned char)bits;
+    int ntokens;
+    int token;
+    int i;
+    bits=oc_pack_read(_opb,OC_NDCT_TOKEN_BITS);
+    if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
+    /*Find out how many internal tokens we translate this external token into.*/
+    ntokens=OC_DCT_TOKEN_MAP_ENTRIES[bits];
+    if(_nbinodes<2*ntokens-1)return TH_EBADHEADER;
+    /*Fill in a complete binary tree pointing to the internal tokens.*/
+    for(i=1;i<ntokens;i<<=1){
+      int j;
+      binode=_binodes+nused;
+      nused+=i;
+      for(j=0;j<i;j++){
+        binode[j].nbits=1;
+        binode[j].depth=1;
+        binode[j].nodes[0]=_binodes+nused+2*j;
+        binode[j].nodes[1]=_binodes+nused+2*j+1;
+      }
+    }
+    /*And now the leaf nodes with those tokens.*/
+    token=OC_DCT_TOKEN_MAP[bits];
+    for(i=0;i<ntokens;i++){
+      binode=_binodes+nused++;
+      binode->nbits=0;
+      binode->depth=1;
+      binode->token=token+i;
+    }
   }
-  *_binode=binode;
-  return 0;
+  return nused;
 }
 
 /*Finds the depth of shortest branch of the given sub-tree.
   The tree must be binary.
   _binode: The root of the given sub-tree.
            _binode->nbits must be 0 or 1.
   Return: The smallest depth of a leaf node in this sub-tree.
           0 indicates this sub-tree is a leaf node.*/
@@ -192,134 +305,185 @@ static int oc_huff_tree_mindepth(oc_huff
 static int oc_huff_tree_occupancy(oc_huff_node *_binode,int _depth){
   if(_binode->nbits==0||_depth<=0)return 1;
   else{
     return oc_huff_tree_occupancy(_binode->nodes[0],_depth-1)+
      oc_huff_tree_occupancy(_binode->nodes[1],_depth-1);
   }
 }
 
-static oc_huff_node *oc_huff_tree_collapse(oc_huff_node *_binode);
+/*Makes a copy of the given Huffman tree.
+  _node: The Huffman tree to copy.
+  Return: The copy of the Huffman tree.*/
+static oc_huff_node *oc_huff_tree_copy(const oc_huff_node *_node,
+ char **_storage){
+  oc_huff_node *ret;
+  ret=oc_huff_node_init(_storage,oc_huff_node_size(_node->nbits),_node->nbits);
+  ret->depth=_node->depth;
+  if(_node->nbits){
+    int nchildren;
+    int i;
+    int inext;
+    nchildren=1<<_node->nbits;
+    for(i=0;i<nchildren;){
+      ret->nodes[i]=oc_huff_tree_copy(_node->nodes[i],_storage);
+      inext=i+(1<<_node->nbits-ret->nodes[i]->depth);
+      while(++i<inext)ret->nodes[i]=ret->nodes[i-1];
+    }
+  }
+  else ret->token=_node->token;
+  return ret;
+}
+
+static size_t oc_huff_tree_collapse_size(oc_huff_node *_binode,int _depth){
+  size_t size;
+  int    mindepth;
+  int    depth;
+  int    loccupancy;
+  int    occupancy;
+  if(_binode->nbits!=0&&_depth>0){
+    return oc_huff_tree_collapse_size(_binode->nodes[0],_depth-1)+
+     oc_huff_tree_collapse_size(_binode->nodes[1],_depth-1);
+  }
+  depth=mindepth=oc_huff_tree_mindepth(_binode);
+  occupancy=1<<mindepth;
+  do{
+    loccupancy=occupancy;
+    occupancy=oc_huff_tree_occupancy(_binode,++depth);
+  }
+  while(occupancy>loccupancy&&occupancy>=1<<OC_MAXI(depth-OC_HUFF_SLUSH,0));
+  depth--;
+  size=oc_huff_node_size(depth);
+  if(depth>0){
+    size+=oc_huff_tree_collapse_size(_binode->nodes[0],depth-1);
+    size+=oc_huff_tree_collapse_size(_binode->nodes[1],depth-1);
+  }
+  return size;
+}
+
+static oc_huff_node *oc_huff_tree_collapse(oc_huff_node *_binode,
+ char **_storage);
 
 /*Fills the given nodes table with all the children in the sub-tree at the
    given depth.
   The nodes in the sub-tree with a depth less than that stored in the table
    are freed.
   The sub-tree must be binary and complete up until the given depth.
   _nodes:  The nodes table to fill.
   _binode: The root of the sub-tree to fill it with.
            _binode->nbits must be 0 or 1.
   _level:  The current level in the table.
            0 indicates that the current node should be stored, regardless of
             whether it is a leaf node or an internal node.
   _depth:  The depth of the nodes to fill the table with, relative to their
             parent.*/
 static void oc_huff_node_fill(oc_huff_node **_nodes,
- oc_huff_node *_binode,int _level,int _depth){
+ oc_huff_node *_binode,int _level,int _depth,char **_storage){
   if(_level<=0||_binode->nbits==0){
     int i;
     _binode->depth=(unsigned char)(_depth-_level);
-    _nodes[0]=oc_huff_tree_collapse(_binode);
+    _nodes[0]=oc_huff_tree_collapse(_binode,_storage);
     for(i=1;i<1<<_level;i++)_nodes[i]=_nodes[0];
   }
   else{
     _level--;
-    oc_huff_node_fill(_nodes,_binode->nodes[0],_level,_depth);
-    oc_huff_node_fill(_nodes+(1<<_level),_binode->nodes[1],_level,_depth);
-    oc_huff_node_free(_binode);
+    oc_huff_node_fill(_nodes,_binode->nodes[0],_level,_depth,_storage);
+    _nodes+=1<<_level;
+    oc_huff_node_fill(_nodes,_binode->nodes[1],_level,_depth,_storage);
   }
 }
 
 /*Finds the largest complete sub-tree rooted at the current node and collapses
    it into a single node.
   This procedure is then applied recursively to all the children of that node.
   _binode: The root of the sub-tree to collapse.
            _binode->nbits must be 0 or 1.
   Return: The new root of the collapsed sub-tree.*/
-static oc_huff_node *oc_huff_tree_collapse(oc_huff_node *_binode){
+static oc_huff_node *oc_huff_tree_collapse(oc_huff_node *_binode,
+ char **_storage){
   oc_huff_node *root;
+  size_t        size;
   int           mindepth;
   int           depth;
   int           loccupancy;
   int           occupancy;
   depth=mindepth=oc_huff_tree_mindepth(_binode);
   occupancy=1<<mindepth;
   do{
     loccupancy=occupancy;
     occupancy=oc_huff_tree_occupancy(_binode,++depth);
   }
   while(occupancy>loccupancy&&occupancy>=1<<OC_MAXI(depth-OC_HUFF_SLUSH,0));
   depth--;
-  if(depth<=1)return _binode;
-  root=oc_huff_node_alloc(depth);
+  if(depth<=1)return oc_huff_tree_copy(_binode,_storage);
+  size=oc_huff_node_size(depth);
+  root=oc_huff_node_init(_storage,size,depth);
   root->depth=_binode->depth;
-  oc_huff_node_fill(root->nodes,_binode,depth,depth);
+  oc_huff_node_fill(root->nodes,_binode,depth,depth,_storage);
   return root;
 }
 
-/*Makes a copy of the given Huffman tree.
-  _node: The Huffman tree to copy.
-  Return: The copy of the Huffman tree.*/
-static oc_huff_node *oc_huff_tree_copy(const oc_huff_node *_node){
-  oc_huff_node *ret;
-  ret=oc_huff_node_alloc(_node->nbits);
-  ret->depth=_node->depth;
-  if(_node->nbits){
-    int nchildren;
-    int i;
-    int inext;
-    nchildren=1<<_node->nbits;
-    for(i=0;i<nchildren;){
-      ret->nodes[i]=oc_huff_tree_copy(_node->nodes[i]);
-      inext=i+(1<<_node->nbits-ret->nodes[i]->depth);
-      while(++i<inext)ret->nodes[i]=ret->nodes[i-1];
-    }
-  }
-  else ret->token=_node->token;
-  return ret;
-}
-
 /*Unpacks a set of Huffman trees, and reduces them to a collapsed
    representation.
   _opb:   The buffer to unpack the trees from.
   _nodes: The table to fill with the Huffman trees.
   Return: 0 on success, or a negative value on error.*/
-int oc_huff_trees_unpack(oggpack_buffer *_opb,
+int oc_huff_trees_unpack(oc_pack_buf *_opb,
  oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]){
   int i;
   for(i=0;i<TH_NHUFFMAN_TABLES;i++){
-    int ret;
-    ret=oc_huff_tree_unpack(_opb,_nodes+i,0);
+    oc_huff_node  nodes[511];
+    char         *storage;
+    size_t        size;
+    int           ret;
+    /*Unpack the full tree into a temporary buffer.*/
+    ret=oc_huff_tree_unpack(_opb,nodes,sizeof(nodes)/sizeof(*nodes));
     if(ret<0)return ret;
-    _nodes[i]=oc_huff_tree_collapse(_nodes[i]);
+    /*Figure out how big the collapsed tree will be.*/
+    size=oc_huff_tree_collapse_size(nodes,0);
+    storage=(char *)_ogg_calloc(1,size);
+    if(storage==NULL)return TH_EFAULT;
+    /*And collapse it.*/
+    _nodes[i]=oc_huff_tree_collapse(nodes,&storage);
   }
   return 0;
 }
 
 /*Makes a copy of the given set of Huffman trees.
   _dst: The array to store the copy in.
   _src: The array of trees to copy.*/
-void oc_huff_trees_copy(oc_huff_node *_dst[TH_NHUFFMAN_TABLES],
+int oc_huff_trees_copy(oc_huff_node *_dst[TH_NHUFFMAN_TABLES],
  const oc_huff_node *const _src[TH_NHUFFMAN_TABLES]){
   int i;
-  for(i=0;i<TH_NHUFFMAN_TABLES;i++)_dst[i]=oc_huff_tree_copy(_src[i]);
+  for(i=0;i<TH_NHUFFMAN_TABLES;i++){
+    size_t  size;
+    char   *storage;
+    size=oc_huff_tree_size(_src[i]);
+    storage=(char *)_ogg_calloc(1,size);
+    if(storage==NULL){
+      while(i-->0)_ogg_free(_dst[i]);
+      return TH_EFAULT;
+    }
+    _dst[i]=oc_huff_tree_copy(_src[i],&storage);
+  }
+  return 0;
 }
 
 /*Frees the memory used by a set of Huffman trees.
   _nodes: The array of trees to free.*/
 void oc_huff_trees_clear(oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]){
   int i;
-  for(i=0;i<TH_NHUFFMAN_TABLES;i++)oc_huff_tree_free(_nodes[i]);
+  for(i=0;i<TH_NHUFFMAN_TABLES;i++)_ogg_free(_nodes[i]);
 }
 
 /*Unpacks a single token using the given Huffman tree.
   _opb:  The buffer to unpack the token from.
   _node: The tree to unpack the token with.
   Return: The token value.*/
-int oc_huff_token_decode(oggpack_buffer *_opb,const oc_huff_node *_node){
+int oc_huff_token_decode(oc_pack_buf *_opb,const oc_huff_node *_node){
   long bits;
   while(_node->nbits!=0){
-    theorapackB_look(_opb,_node->nbits,&bits);
+    bits=oc_pack_look(_opb,_node->nbits);
     _node=_node->nodes[bits];
-    theorapackB_adv(_opb,_node->depth);
+    oc_pack_adv(_opb,_node->depth);
   }
   return _node->token;
 }
rename from media/libtheora/lib/dec/huffdec.h
rename to media/libtheora/lib/huffdec.h
--- a/media/libtheora/lib/dec/huffdec.h
+++ b/media/libtheora/lib/huffdec.h
@@ -1,28 +1,29 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function:
-    last mod: $Id: huffdec.h 15400 2008-10-15 12:10:58Z tterribe $
+    last mod: $Id: huffdec.h 16503 2009-08-22 18:14:02Z giles $
 
  ********************************************************************/
 
 #if !defined(_huffdec_H)
 # define _huffdec_H (1)
 # include "huffman.h"
+# include "bitpack.h"
 
 
 
 typedef struct oc_huff_node oc_huff_node;
 
 /*A node in the Huffman tree.
   Instead of storing every branching in the tree, subtrees can be collapsed
    into one node, with a table of size 1<<nbits pointing directly to its
@@ -70,22 +71,22 @@ struct oc_huff_node{
     This can be less than its parent's nbits value, in which case there are
      1<<nbits-depth copies of this node in the table, and the bitstream should
      only be advanced depth bits after reaching this node.*/
   unsigned char  depth;
   /*The table of child nodes.
     The ACTUAL size of this array is 1<<nbits, despite what the declaration
      below claims.
     The exception is that for leaf nodes the size is 0.*/
-  oc_huff_node  *nodes[1];
+  oc_huff_node  *nodes[2];
 };
 
 
 
-int oc_huff_trees_unpack(oggpack_buffer *_opb,
+int oc_huff_trees_unpack(oc_pack_buf *_opb,
  oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]);
-void oc_huff_trees_copy(oc_huff_node *_dst[TH_NHUFFMAN_TABLES],
+int oc_huff_trees_copy(oc_huff_node *_dst[TH_NHUFFMAN_TABLES],
  const oc_huff_node *const _src[TH_NHUFFMAN_TABLES]);
 void oc_huff_trees_clear(oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]);
-int oc_huff_token_decode(oggpack_buffer *_opb,const oc_huff_node *_node);
+int oc_huff_token_decode(oc_pack_buf *_opb,const oc_huff_node *_node);
 
 
 #endif
new file mode 100644
--- /dev/null
+++ b/media/libtheora/lib/huffenc.h
@@ -0,0 +1,19 @@
+#if !defined(_huffenc_H)
+# define _huffenc_H (1)
+# include "huffman.h"
+
+
+
+typedef th_huff_code                  th_huff_table[TH_NDCT_TOKENS];
+
+
+
+extern const th_huff_code
+ TH_VP31_HUFF_CODES[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS];
+
+
+
+int oc_huff_codes_pack(oggpack_buffer *_opb,
+ const th_huff_code _codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]);
+
+#endif
rename from media/libtheora/lib/dec/huffman.h
rename to media/libtheora/lib/huffman.h
--- a/media/libtheora/lib/dec/huffman.h
+++ b/media/libtheora/lib/huffman.h
@@ -1,22 +1,22 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function:
-    last mod: $Id: huffman.h 15400 2008-10-15 12:10:58Z tterribe $
+    last mod: $Id: huffman.h 16503 2009-08-22 18:14:02Z giles $
 
  ********************************************************************/
 
 #if !defined(_huffman_H)
 # define _hufffman_H (1)
 # include "theora/codec.h"
 # include "ocintrin.h"
 
@@ -60,11 +60,11 @@
 #define OC_NDCT_ZRL_TOKEN_MAX    (9)
 #define OC_NDCT_VAL_MAX          (23)
 #define OC_NDCT_VAL_CAT1_MAX     (13)
 #define OC_NDCT_VAL_CAT2_MAX     (17)
 #define OC_NDCT_VAL_CAT2_SIZE    (OC_NDCT_VAL_CAT2_MAX-OC_DCT_VAL_CAT2)
 #define OC_NDCT_RUN_MAX          (32)
 #define OC_NDCT_RUN_CAT1A_MAX    (28)
 
-extern const int OC_DCT_TOKEN_EXTRA_BITS[TH_NDCT_TOKENS];
+extern const unsigned char OC_DCT_TOKEN_EXTRA_BITS[TH_NDCT_TOKENS];
 
 #endif
rename from media/libtheora/lib/dec/idct.c
rename to media/libtheora/lib/idct.c
--- a/media/libtheora/lib/dec/idct.c
+++ b/media/libtheora/lib/idct.c
@@ -1,29 +1,28 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function:
-    last mod: $Id: idct.c 15400 2008-10-15 12:10:58Z tterribe $
+    last mod: $Id: idct.c 16503 2009-08-22 18:14:02Z giles $
 
  ********************************************************************/
 
 #include <string.h>
-#include <ogg/ogg.h>
+#include "internal.h"
 #include "dct.h"
-#include "idct.h"
 
 /*Performs an inverse 8 point Type-II DCT transform.
   The output is scaled by a factor of 2 relative to the orthonormal version of
    the transform.
   _y: The buffer to store the result in.
       Data will be placed in every 8th entry (e.g., in a column of an 8x8
        block).
   _x: The input coefficients.
@@ -215,29 +214,39 @@ static void idct8_2(ogg_int16_t *_y,cons
 static void idct8_1(ogg_int16_t *_y,const ogg_int16_t _x[1]){
   _y[0<<3]=_y[1<<3]=_y[2<<3]=_y[3<<3]=
    _y[4<<3]=_y[5<<3]=_y[6<<3]=_y[7<<3]=(ogg_int16_t)(OC_C4S4*_x[0]>>16);
 }
 
 /*Performs an inverse 8x8 Type-II DCT transform.
   The input is assumed to be scaled by a factor of 4 relative to orthonormal
    version of the transform.
+  All coefficients but the first 3 in zig-zag scan order are assumed to be 0:
+   x  x  0  0  0  0  0  0
+   x  0  0  0  0  0  0  0
+   0  0  0  0  0  0  0  0
+   0  0  0  0  0  0  0  0
+   0  0  0  0  0  0  0  0
+   0  0  0  0  0  0  0  0
+   0  0  0  0  0  0  0  0
+   0  0  0  0  0  0  0  0
   _y: The buffer to store the result in.
       This may be the same as _x.
-  _x: The input coefficients. */
-void oc_idct8x8_c(ogg_int16_t _y[64],const ogg_int16_t _x[64]){
+  _x: The input coefficients.*/
+static void oc_idct8x8_3(ogg_int16_t _y[64],const ogg_int16_t _x[64]){
   const ogg_int16_t *in;
   ogg_int16_t       *end;
   ogg_int16_t       *out;
   ogg_int16_t        w[64];
   /*Transform rows of x into columns of w.*/
-  for(in=_x,out=w,end=out+8;out<end;in+=8,out++)idct8(out,in);
+  idct8_2(w,_x);
+  idct8_1(w+1,_x+8);
   /*Transform rows of w into columns of y.*/
-  for(in=w,out=_y,end=out+8;out<end;in+=8,out++)idct8(out,in);
-  /*Adjust for scale factor.*/
+  for(in=w,out=_y,end=out+8;out<end;in+=8,out++)idct8_2(out,in);
+  /*Adjust for the scale factor.*/
   for(out=_y,end=out+64;out<end;out++)*out=(ogg_int16_t)(*out+8>>4);
 }
 
 /*Performs an inverse 8x8 Type-II DCT transform.
   The input is assumed to be scaled by a factor of 4 relative to orthonormal
    version of the transform.
   All coefficients but the first 10 in zig-zag scan order are assumed to be 0:
    x  x  x  x  0  0  0  0
@@ -245,24 +254,82 @@ void oc_idct8x8_c(ogg_int16_t _y[64],con
    x  x  0  0  0  0  0  0
    x  0  0  0  0  0  0  0
    0  0  0  0  0  0  0  0
    0  0  0  0  0  0  0  0
    0  0  0  0  0  0  0  0
    0  0  0  0  0  0  0  0
   _y: The buffer to store the result in.
       This may be the same as _x.
-  _x: The input coefficients. */
-void oc_idct8x8_10_c(ogg_int16_t _y[64],const ogg_int16_t _x[64]){
+  _x: The input coefficients.*/
+static void oc_idct8x8_10(ogg_int16_t _y[64],const ogg_int16_t _x[64]){
   const ogg_int16_t *in;
   ogg_int16_t       *end;
   ogg_int16_t       *out;
   ogg_int16_t        w[64];
   /*Transform rows of x into columns of w.*/
   idct8_4(w,_x);
   idct8_3(w+1,_x+8);
   idct8_2(w+2,_x+16);
   idct8_1(w+3,_x+24);
   /*Transform rows of w into columns of y.*/
   for(in=w,out=_y,end=out+8;out<end;in+=8,out++)idct8_4(out,in);
-  /*Adjust for scale factor.*/
+  /*Adjust for the scale factor.*/
+  for(out=_y,end=out+64;out<end;out++)*out=(ogg_int16_t)(*out+8>>4);
+}
+
+/*Performs an inverse 8x8 Type-II DCT transform.
+  The input is assumed to be scaled by a factor of 4 relative to orthonormal
+   version of the transform.
+  _y: The buffer to store the result in.
+      This may be the same as _x.
+  _x: The input coefficients.*/
+static void oc_idct8x8_slow(ogg_int16_t _y[64],const ogg_int16_t _x[64]){
+  const ogg_int16_t *in;
+  ogg_int16_t       *end;
+  ogg_int16_t       *out;
+  ogg_int16_t        w[64];
+  /*Transform rows of x into columns of w.*/
+  for(in=_x,out=w,end=out+8;out<end;in+=8,out++)idct8(out,in);
+  /*Transform rows of w into columns of y.*/
+  for(in=w,out=_y,end=out+8;out<end;in+=8,out++)idct8(out,in);
+  /*Adjust for the scale factor.*/
   for(out=_y,end=out+64;out<end;out++)*out=(ogg_int16_t)(*out+8>>4);
 }
+
+void oc_idct8x8(const oc_theora_state *_state,ogg_int16_t _y[64],
+ int _last_zzi){
+  (*_state->opt_vtable.idct8x8)(_y,_last_zzi);
+}
+
+/*Performs an inverse 8x8 Type-II DCT transform.
+  The input is assumed to be scaled by a factor of 4 relative to orthonormal
+   version of the transform.*/
+void oc_idct8x8_c(ogg_int16_t _y[64],int _last_zzi){
+  /*_last_zzi is subtly different from an actual count of the number of
+     coefficients we decoded for this block.
+    It contains the value of zzi BEFORE the final token in the block was
+     decoded.
+    In most cases this is an EOB token (the continuation of an EOB run from a
+     previous block counts), and so this is the same as the coefficient count.
+    However, in the case that the last token was NOT an EOB token, but filled
+     the block up with exactly 64 coefficients, _last_zzi will be less than 64.
+    Provided the last token was not a pure zero run, the minimum value it can
+     be is 46, and so that doesn't affect any of the cases in this routine.
+    However, if the last token WAS a pure zero run of length 63, then _last_zzi
+     will be 1 while the number of coefficients decoded is 64.
+    Thus, we will trigger the following special case, where the real
+     coefficient count would not.
+    Note also that a zero run of length 64 will give _last_zzi a value of 0,
+     but we still process the DC coefficient, which might have a non-zero value
+     due to DC prediction.
+    Although convoluted, this is arguably the correct behavior: it allows us to
+     use a smaller transform when the block ends with a long zero run instead
+     of a normal EOB token.
+    It could be smarter... multiple separate zero runs at the end of a block
+     will fool it, but an encoder that generates these really deserves what it
+     gets.
+    Needless to say we inherited this approach from VP3.*/
+  /*Then perform the iDCT.*/
+  if(_last_zzi<3)oc_idct8x8_3(_y,_y);
+  else if(_last_zzi<10)oc_idct8x8_10(_y,_y);
+  else oc_idct8x8_slow(_y,_y);
+}
rename from media/libtheora/lib/dec/info.c
rename to media/libtheora/lib/info.c
--- a/media/libtheora/lib/dec/info.c
+++ b/media/libtheora/lib/info.c
@@ -1,29 +1,29 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function:
-    last mod: $Id: info.c 15400 2008-10-15 12:10:58Z tterribe $
+    last mod: $Id: info.c 16503 2009-08-22 18:14:02Z giles $
 
  ********************************************************************/
 
 #include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
-#include "../internal.h"
+#include "internal.h"
 
 
 
 /*This is more or less the same as strncasecmp, but that doesn't exist
    everywhere, and this is a fairly trivial function, so we include it.
   Note: We take advantage of the fact that we know _n is less than or equal to
    the length of at least one of the strings.*/
 static int oc_tagcompare(const char *_s1,const char *_s2,int _n){
@@ -50,37 +50,45 @@ void th_info_clear(th_info *_info){
 
 
 
 void th_comment_init(th_comment *_tc){
   memset(_tc,0,sizeof(*_tc));
 }
 
 void th_comment_add(th_comment *_tc,char *_comment){
-  int comment_len;
-  _tc->user_comments=_ogg_realloc(_tc->user_comments,
+  char **user_comments;
+  int   *comment_lengths;
+  int    comment_len;
+  user_comments=_ogg_realloc(_tc->user_comments,
    (_tc->comments+2)*sizeof(*_tc->user_comments));
-  _tc->comment_lengths=_ogg_realloc(_tc->comment_lengths,
+  if(user_comments==NULL)return;
+  _tc->user_comments=user_comments;
+  comment_lengths=_ogg_realloc(_tc->comment_lengths,
    (_tc->comments+2)*sizeof(*_tc->comment_lengths));
+  if(comment_lengths==NULL)return;
+  _tc->comment_lengths=comment_lengths;
   comment_len=strlen(_comment);
-  _tc->comment_lengths[_tc->comments]=comment_len;
-  _tc->user_comments[_tc->comments]=_ogg_malloc(comment_len+1);
+  comment_lengths[_tc->comments]=comment_len;
+  user_comments[_tc->comments]=_ogg_malloc(comment_len+1);
+  if(user_comments[_tc->comments]==NULL)return;
   memcpy(_tc->user_comments[_tc->comments],_comment,comment_len+1);
   _tc->comments++;
   _tc->user_comments[_tc->comments]=NULL;
 }
 
 void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val){
   char *comment;
   int   tag_len;
   int   val_len;
   tag_len=strlen(_tag);
   val_len=strlen(_val);
   /*+2 for '=' and '\0'.*/
   comment=_ogg_malloc(tag_len+val_len+2);
+  if(comment==NULL)return;
   memcpy(comment,_tag,tag_len);
   comment[tag_len]='=';
   memcpy(comment+tag_len+1,_val,val_len+1);
   th_comment_add(_tc,comment);
   _ogg_free(comment);
 }
 
 char *th_comment_query(th_comment *_tc,char *_tag,int _count){
rename from media/libtheora/lib/dec/internal.c
rename to media/libtheora/lib/internal.c
--- a/media/libtheora/lib/dec/internal.c
+++ b/media/libtheora/lib/internal.c
@@ -1,38 +1,37 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * 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-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
  *                                                                  *
  ********************************************************************
 
   function:
-    last mod: $Id: internal.c 15400 2008-10-15 12:10:58Z tterribe $
+    last mod: $Id: internal.c 16503 2009-08-22 18:14:02Z giles $
 
  ********************************************************************/
 
 #include <stdlib.h>
 #include <limits.h>
 #include <string.h>
-#include "../internal.h"
-#include "idct.h"
+#include "internal.h"
 
 
 
 /*A map from the index in the zig zag scan to the coefficient number in a
    block.
   All zig zag indices beyond 63 are sent to coefficient 64, so that zero runs
    past the end of a block in bogus streams get mapped to a known location.*/
-const int OC_FZIG_ZAG[128]={
+const unsigned char OC_FZIG_ZAG[128]={
    0, 1, 8,16, 9, 2, 3,10,
   17,24,32,25,18,11, 4, 5,
   12,19,26,33,40,48,41,34,
   27,20,13, 6, 7,14,21,28,
   35,42,49,56,57,50,43,36,
   29,22,15,23,30,37,44,51,
   58,59,52,45,38,31,39,46,
   53,60,61,54,47,55,62,63,
@@ -43,69 +42,49 @@ const int OC_FZIG_ZAG[128]={
   64,64,64,64,64,64,64,64,
   64,64,64,64,64,64,64,64,
   64,64,64,64,64,64,64,64,
   64,64,64,64,64,64,64,64
 };
 
 /*A map from the coefficient number in a block to its index in the zig zag
    scan.*/
-const int OC_IZIG_ZAG[64]={
+const unsigned char OC_IZIG_ZAG[64]={
    0, 1, 5, 6,14,15,27,28,
    2, 4, 7,13,16,26,29,42,
    3, 8,12,17,25,30,41,43,
    9,11,18,24,31,40,44,53,
   10,19,23,32,39,45,52,54,
   20,22,33,38,46,51,55,60,
   21,34,37,47,50,56,59,61,
   35,36,48,49,57,58,62,63
 };
 
-/*The predictor frame to use for each macro block mode.*/
-const int OC_FRAME_FOR_MODE[8]={
-  /*OC_MODE_INTER_NOMV*/
-  OC_FRAME_PREV,
-  /*OC_MODE_INTRA*/
-  OC_FRAME_SELF,
-  /*OC_MODE_INTER_MV*/
-  OC_FRAME_PREV,
-  /*OC_MODE_INTER_MV_LAST*/
-  OC_FRAME_PREV,
-  /*OC_MODE_INTER_MV_LAST2*/
-  OC_FRAME_PREV,
-  /*OC_MODE_GOLDEN*/
-  OC_FRAME_GOLD,
-  /*OC_MODE_GOLDEN_MV*/
-  OC_FRAME_GOLD,
-  /*OC_MODE_INTER_MV_FOUR*/
-  OC_FRAME_PREV,
-};
-
 /*A map from physical macro block ordering to bitstream macro block
    ordering within a super block.*/
-const int OC_MB_MAP[2][2]={{0,3},{1,2}};
+const unsigned char OC_MB_MAP[2][2]={{0,3},{1,2}};
 
 /*A list of the indices in the oc_mb.map array that can be valid for each of
    the various chroma decimation types.*/
-const int OC_MB_MAP_IDXS[TH_PF_NFORMATS][12]={
+const unsigned char OC_MB_MAP_IDXS[TH_PF_NFORMATS][12]={
   {0,1,2,3,4,8},
   {0,1,2,3,4,5,8,9},
   {0,1,2,3,4,6,8,10},
   {0,1,2,3,4,5,6,7,8,9,10,11}
 };
 
 /*The number of indices in the oc_mb.map array that can be valid for each of
    the various chroma decimation types.*/
-const int OC_MB_MAP_NIDXS[TH_PF_NFORMATS]={6,8,8,12};
+const unsigned char OC_MB_MAP_NIDXS[TH_PF_NFORMATS]={6,8,8,12};
 
 /*The number of extra bits that are coded with each of the DCT tokens.
   Each DCT token has some fixed number of additional bits (possibly 0) stored
    after the token itself, containing, for example, coefficient magnitude,
    sign bits, etc.*/
-const int OC_DCT_TOKEN_EXTRA_BITS[TH_NDCT_TOKENS]={
+const unsigned char OC_DCT_TOKEN_EXTRA_BITS[TH_NDCT_TOKENS]={
   0,0,0,2,3,4,12,3,6,
   0,0,0,0,
   1,1,1,1,2,3,4,5,6,10,
   1,1,1,1,1,3,4,
   2,3
 };
 
 
@@ -113,123 +92,20 @@ const int OC_DCT_TOKEN_EXTRA_BITS[TH_NDC
 int oc_ilog(unsigned _v){
   int ret;
   for(ret=0;_v;ret++)_v>>=1;
   return ret;
 }
 
 
 
-/*Determines the number of blocks or coefficients to be skipped for a given
-   token value.
-  _token:      The token value to skip.
-  _extra_bits: The extra bits attached to this token.
-  Return: A positive value indicates that number of coefficients are to be
-           skipped in the current block.
-          Otherwise, the negative of the return value indicates that number of
-           blocks are to be ended.*/
-typedef int (*oc_token_skip_func)(int _token,int _extra_bits);
-
-/*Handles the simple end of block tokens.*/
-static int oc_token_skip_eob(int _token,int _extra_bits){
-  static const int NBLOCKS_ADJUST[OC_NDCT_EOB_TOKEN_MAX]={1,2,3,4,8,16,0};
-  return -_extra_bits-NBLOCKS_ADJUST[_token];
-}
-
-/*The last EOB token has a special case, where an EOB run of size zero ends all
-   the remaining blocks in the frame.*/
-static int oc_token_skip_eob6(int _token,int _extra_bits){
-  if(!_extra_bits)return -INT_MAX;
-  return -_extra_bits;
-}
-
-/*Handles the pure zero run tokens.*/
-static int oc_token_skip_zrl(int _token,int _extra_bits){
-  return _extra_bits+1;
-}
-
-/*Handles a normal coefficient value token.*/
-static int oc_token_skip_val(void){
-  return 1;
-}
-
-/*Handles a category 1A zero run/coefficient value combo token.*/
-static int oc_token_skip_run_cat1a(int _token){
-  return _token-OC_DCT_RUN_CAT1A+2;
-}
-
-/*Handles category 1b and 2 zero run/coefficient value combo tokens.*/
-static int oc_token_skip_run(int _token,int _extra_bits){
-  static const int NCOEFFS_ADJUST[OC_NDCT_RUN_MAX-OC_DCT_RUN_CAT1B]={
-    7,11,2,3
-  };
-  static const int NCOEFFS_MASK[OC_NDCT_RUN_MAX-OC_DCT_RUN_CAT1B]={
-    3,7,0,1
-  };
-  _token-=OC_DCT_RUN_CAT1B;
-  return (_extra_bits&NCOEFFS_MASK[_token])+NCOEFFS_ADJUST[_token];
-}
-
-/*A jump table for computing the number of coefficients or blocks to skip for
-   a given token value.
-  This reduces all the conditional branches, etc., needed to parse these token
-   values down to one indirect jump.*/
-static const oc_token_skip_func OC_TOKEN_SKIP_TABLE[TH_NDCT_TOKENS]={
-  oc_token_skip_eob,
-  oc_token_skip_eob,
-  oc_token_skip_eob,
-  oc_token_skip_eob,
-  oc_token_skip_eob,
-  oc_token_skip_eob,
-  oc_token_skip_eob6,
-  oc_token_skip_zrl,
-  oc_token_skip_zrl,
-  (oc_token_skip_func)oc_token_skip_val,
-  (oc_token_skip_func)oc_token_skip_val,
-  (oc_token_skip_func)oc_token_skip_val,
-  (oc_token_skip_func)oc_token_skip_val,
-  (oc_token_skip_func)oc_token_skip_val,
-  (oc_token_skip_func)oc_token_skip_val,
-  (oc_token_skip_func)oc_token_skip_val,
-  (oc_token_skip_func)oc_token_skip_val,
-  (oc_token_skip_func)oc_token_skip_val,
-  (oc_token_skip_func)oc_token_skip_val,
-  (oc_token_skip_func)oc_token_skip_val,
-  (oc_token_skip_func)oc_token_skip_val,
-  (oc_token_skip_func)oc_token_skip_val,
-  (oc_token_skip_func)oc_token_skip_val,
-  (oc_token_skip_func)oc_token_skip_run_cat1a,
-  (oc_token_skip_func)oc_token_skip_run_cat1a,
-  (oc_token_skip_func)oc_token_skip_run_cat1a,
-  (oc_token_skip_func)oc_token_skip_run_cat1a,
-  (oc_token_skip_func)oc_token_skip_run_cat1a,
-  oc_token_skip_run,
-  oc_token_skip_run,
-  oc_token_skip_run,
-  oc_token_skip_run
-};
-
-/*Determines the number of blocks or coefficients to be skipped for a given
-   token value.
-  _token:      The token value to skip.
-  _extra_bits: The extra bits attached to this token.
-  Return: A positive value indicates that number of coefficients are to be
-           skipped in the current block.
-          Otherwise, the negative of the return value indicates that number of
-           blocks are to be ended.
-          0 will never be returned, so that at least one coefficient in one
-           block will always be decoded for every token.*/
-int oc_dct_token_skip(int _token,int _extra_bits){
-  return (*OC_TOKEN_SKIP_TABLE[_token])(_token,_extra_bits);
-}
-
-
 /*The function used to fill in the chroma plane motion vectors for a macro
    block when 4 different motion vectors are specified in the luma plane.
-  This version is for use with chroma decimated in the X and Y directions.
+  This version is for use with chroma decimated in the X and Y directions
+   (4:2:0).
   _cbmvs: The chroma block-level motion vectors to fill in.
   _lbmvs: The luma block-level motion vectors.*/
 static void oc_set_chroma_mvs00(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){
   int dx;
   int dy;
   dx=_lbmvs[0][0]+_lbmvs[1][0]+_lbmvs[2][0]+_lbmvs[3][0];
   dy=_lbmvs[0][1]+_lbmvs[1][1]+_lbmvs[2][1]+_lbmvs[3][1];
   _cbmvs[0][0]=(signed char)OC_DIV_ROUND_POW2(dx,2,2);
@@ -251,17 +127,17 @@ static void oc_set_chroma_mvs01(oc_mv _c
   dx=_lbmvs[1][0]+_lbmvs[3][0];
   dy=_lbmvs[1][1]+_lbmvs[3][1];
   _cbmvs[1][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1);
   _cbmvs[1][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1);
 }
 
 /*The function used to fill in the chroma plane motion vectors for a macro
    block when 4 different motion vectors are specified in the luma plane.
-  This version is for use with chroma decimated in the X direction.
+  This version is for use with chroma decimated in the X direction (4:2:2).
   _cbmvs: The chroma block-level motion vectors to fill in.
   _lbmvs: The luma block-level motion vectors.*/
 static void oc_set_chroma_mvs10(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){
   int dx;
   int dy;
   dx=_lbmvs[0][0]+_lbmvs[1][0];
   dy=_lbmvs[0][1]+_lbmvs[1][1];
   _cbmvs[0][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1);
@@ -269,17 +145,17 @@ static void oc_set_chroma_mvs10(oc_mv _c
   dx=_lbmvs[2][0]+_lbmvs[3][0];
   dy=_lbmvs[2][1]+_lbmvs[3][1];
   _cbmvs[2][0]=(signed char)OC_DIV_ROUND_POW2(dx,1,1);
   _cbmvs[2][1]=(signed char)OC_DIV_ROUND_POW2(dy,1,1);
 }
 
 /*The function used to fill in the chroma plane motion vectors for a macro
    block when 4 different motion vectors are specified in the luma plane.
-  This version is for use with no chroma decimation.
+  This version is for use with no chroma decimation (4:4:4).
   _cbmvs: The chroma block-level motion vectors to fill in.
   _lmbmv: The luma macro-block level motion vector to fill in for use in
            prediction.
   _lbmvs: The luma block-level motion vectors.*/
 static void oc_set_chroma_mvs11(oc_mv _cbmvs[4],const oc_mv _lbmvs[4]){
   memcpy(_cbmvs,_lbmvs,4*sizeof(_lbmvs[0]));
 }
 
@@ -300,16 +176,17 @@ void **oc_malloc_2d(size_t _height,size_
   size_t  colsz;
   size_t  datsz;
   char   *ret;
   colsz=_height*sizeof(void *);
   rowsz=_sz*_width;
   datsz=rowsz*_height;
   /*Alloc array and row pointers.*/
   ret=(char *)_ogg_malloc(datsz+colsz);
+  if(ret==NULL)return NULL;
   /*Initialize the array.*/
   if(ret!=NULL){
     size_t   i;
     void   **p;
     char    *datptr;
     p=(void **)ret;
     i=_height;
     for(datptr=ret+colsz;i-->0;p++,datptr+=rowsz)*p=(void *)datptr;
@@ -322,16 +199,17 @@ void **oc_calloc_2d(size_t _height,size_
   size_t  rowsz;
   size_t  datsz;
   char   *ret;
   colsz=_height*sizeof(void *);
   rowsz=_sz*_width;
   datsz=rowsz*_height;
   /*Alloc array and row pointers.*/
   ret=(char *)_ogg_calloc(datsz+colsz,1);
+  if(ret==NULL)return NULL;
   /*Initialize the array.*/
   if(ret!=NULL){
     size_t   i;
     void   **p;
     char    *datptr;
     p=(void **)ret;
     i=_height;
     for(datptr=ret+colsz;i-->0;p++,datptr+=rowsz)*p=(void *)datptr;
@@ -350,26 +228,27 @@ void oc_free_2d(void *_ptr){
   _src: The source buffer.*/
 void oc_ycbcr_buffer_flip(th_ycbcr_buffer _dst,
  const th_ycbcr_buffer _src){
   int pli;
   for(pli=0;pli<3;pli++){
     _dst[pli].width=_src[pli].width;
     _dst[pli].height=_src[pli].height;
     _dst[pli].stride=-_src[pli].stride;
-    _dst[pli].data=_src[pli].data+(1-_dst[pli].height)*_dst[pli].stride;
+    _dst[pli].data=_src[pli].data
+     +(1-_dst[pli].height)*(ptrdiff_t)_dst[pli].stride;
   }
 }
 
 const char *th_version_string(void){
   return OC_VENDOR_STRING;
 }
 
 ogg_uint32_t th_version_number(void){
-  return (TH_VERSION_MAJOR<<16)+(TH_VERSION_MINOR<<8)+(TH_VERSION_SUB);
+  return (TH_VERSI