[tbb-commits] [tor-browser] 41/76: Bug 1741873 - Update libtheora to latest; r=bryce, a=RyanVM

gitolite role git at cupani.torproject.org
Wed Mar 30 20:40:09 UTC 2022


This is an automated email from the git hooks/post-receive script.

richard pushed a commit to branch tor-browser-91.8.0esr-11.0-1
in repository tor-browser.

commit cea85e0f3a5ad8a3cb90e178604be68d930185f8
Author: june wilde <jewilde at mozilla.com>
AuthorDate: Mon Feb 14 21:08:35 2022 +0000

    Bug 1741873 - Update libtheora to latest; r=bryce, a=RyanVM
    
    Differential Revision: https://phabricator.services.mozilla.com/D131500
---
 media/libtheora/AUTHORS                    |   14 +-
 media/libtheora/LICENSE                    |    8 +-
 media/libtheora/{README => README.md}      |  110 ++-
 media/libtheora/bug468275-r18219.patch     |   22 -
 media/libtheora/bug625773-r17780.patch     |   23 -
 media/libtheora/bug752139-r18031.patch     |   53 --
 media/libtheora/bug752668-r18268.patch     |   28 -
 media/libtheora/bug920992.patch            |  103 ---
 media/libtheora/include/theora/codec.h     |   77 +-
 media/libtheora/include/theora/theora.h    |  112 +--
 media/libtheora/include/theora/theoradec.h |   19 +-
 media/libtheora/include/theora/theoraenc.h |  540 -----------
 media/libtheora/lib/arm/arm2gnu.pl         |   55 +-
 media/libtheora/lib/arm/armbits.s          |    8 +-
 media/libtheora/lib/arm/armcpu.c           |   40 +-
 media/libtheora/lib/arm/armfrag.s          |   11 +-
 media/libtheora/lib/arm/armidct.s          |  177 ++--
 media/libtheora/lib/arm/armloop.s          |    8 +-
 media/libtheora/lib/bitpack.c              |    2 +-
 media/libtheora/lib/config.h               |   35 +-
 media/libtheora/lib/dct.h                  |    2 +-
 media/libtheora/lib/decinfo.c              |   36 +-
 media/libtheora/lib/decint.h               |    3 +-
 media/libtheora/lib/decode.c               | 1349 ++++++++++++++--------------
 media/libtheora/lib/dequant.c              |    2 +-
 media/libtheora/lib/dequant.h              |    2 +-
 media/libtheora/lib/fragment.c             |    2 +-
 media/libtheora/lib/huffdec.c              |    2 +-
 media/libtheora/lib/huffdec.h              |    2 +-
 media/libtheora/lib/huffman.h              |    4 +-
 media/libtheora/lib/idct.c                 |   13 +-
 media/libtheora/lib/info.c                 |   10 +-
 media/libtheora/lib/internal.c             |    4 +-
 media/libtheora/lib/internal.h             |    2 +-
 media/libtheora/lib/ocintrin.h             |    2 +-
 media/libtheora/lib/quant.c                |    2 +-
 media/libtheora/lib/quant.h                |    2 +-
 media/libtheora/lib/state.c                |   19 +-
 media/libtheora/lib/x86/mmxfrag.c          |    4 +-
 media/libtheora/lib/x86/mmxidct.c          |   42 +-
 media/libtheora/lib/x86/mmxstate.c         |    2 +-
 media/libtheora/lib/x86/sse2idct.c         |   44 +-
 media/libtheora/lib/x86/x86cpu.c           |    2 +-
 media/libtheora/lib/x86/x86cpu.h           |    2 +-
 media/libtheora/lib/x86/x86int.h           |    2 +-
 media/libtheora/lib/x86/x86state.c         |    4 +-
 media/libtheora/lib/x86_vc/mmxfrag.c       |    2 +-
 media/libtheora/lib/x86_vc/mmxidct.c       |   45 +-
 media/libtheora/lib/x86_vc/mmxstate.c      |    2 +-
 media/libtheora/lib/x86_vc/x86cpu.c        |    2 +-
 media/libtheora/lib/x86_vc/x86cpu.h        |    2 +-
 media/libtheora/lib/x86_vc/x86int.h        |    2 +-
 media/libtheora/lib/x86_vc/x86state.c      |    2 +-
 media/libtheora/moz.build                  |    1 -
 media/libtheora/moz.yaml                   |    4 +-
 55 files changed, 1174 insertions(+), 1893 deletions(-)

diff --git a/media/libtheora/AUTHORS b/media/libtheora/AUTHORS
index 077d4e588c7dd..8a4e529b5acce 100644
--- a/media/libtheora/AUTHORS
+++ b/media/libtheora/AUTHORS
@@ -1,24 +1,25 @@
 Monty <monty at xiph.org>
 	- Original VP3 port
 
-Ralph Giles
 Timothy B. Terriberry
+Gregory Maxwell
+Ralph Giles
 Monty
 	- Ongoing development
-	
+
 Dan B. Miller
 	- Pre alpha3 development
-	
+
 Rudolf Marek
 Wim Tayman
 Dan Lenski
 Nils Pipenbrinck
 Monty
 	- MMX optimized functions
-	
+
 David Schleef
 	- C64x port
-	
+
 Aaron Colwell
 Thomas Vander Stichele
 Jan Gerber
@@ -26,8 +27,9 @@ Conrad Parker
 Cristian Adam
 Sebastian Pippin
 Simon Hosie
+Brad Smith
 	- Bug fixes, enhancements, build systems.
-	
+
 Mauricio Piacentini
 	- Original win32 projects and example ports
 	- VP3->Theora transcoder
diff --git a/media/libtheora/LICENSE b/media/libtheora/LICENSE
index 5e5ec08469b05..97e84317906b8 100644
--- a/media/libtheora/LICENSE
+++ b/media/libtheora/LICENSE
@@ -4,13 +4,13 @@ In addition to and irrespective of the copyright license associated
 with this software, On2 Technologies, Inc. makes the following statement
 regarding technology used in this software:
 
-  On2 represents and warrants that it shall not assert any rights 
+  On2 represents and warrants that it shall not assert any rights
   relating to infringement of On2's registered patents, nor initiate
   any litigation asserting such rights, against any person who, or
-  entity which utilizes the On2 VP3 Codec Software, including any 
-  use, distribution, and sale of said Software; which make changes, 
+  entity which utilizes the On2 VP3 Codec Software, including any
+  use, distribution, and sale of said Software; which make changes,
   modifications, and improvements in said Software; and to use,
-  distribute, and sell said changes as well as applications for other 
+  distribute, and sell said changes as well as applications for other
   fields of use.
 
 This reference implementation is originally derived from the On2 VP3
diff --git a/media/libtheora/README b/media/libtheora/README.md
similarity index 56%
rename from media/libtheora/README
rename to media/libtheora/README.md
index 7663f9ff8c8b4..b136f7114cea0 100644
--- a/media/libtheora/README
+++ b/media/libtheora/README.md
@@ -1,13 +1,11 @@
--------------------------------------------------------------------------
-             The Xiph.org Foundation's libtheora 1.2
--------------------------------------------------------------------------
+# Xiph.org Foundation's libtheora
 
-*** What is Theora?
+### What is Theora?
 
-Theora is Xiph.Org's first publicly released video codec, intended
+Theora was 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, adds new features
-while allow it a longer useful lifetime as an competitive codec.
+while allowing it a longer useful lifetime.
 
 The 1.0 release decoder supported all the new features, but the
 encoder is nearly identical to the VP3 code.
@@ -20,46 +18,43 @@ The 1.2 release features significant additional improvements in
 compression and performance. Files produced by newer encoders can
 be decoded by earlier releases.
 
-*** Where is Theora?
+### 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.
+Theora's main site is https://www.theora.org. Releases of Theora
+and related libraries can be found on the
+[download page](https://www.theora.org/downloads/) or the
+[main Xiph.Org site](https://xiph.org/downloads/).
 
--------------------------------------------------------------------------
-Getting started with the code
--------------------------------------------------------------------------
+Development source is kept at https://gitlab.xiph.org/xiph/theora.
 
-*** What do I need to build the source?
+## Getting started with the code
 
-Requirements summary:
-
-  For libtheora:
-
-      libogg 1.1 or newer.
+### What do I need to build the source?
 
-  For example encoder:
+Requirements summary:
 
-      as above,
+For libtheora:
 
-      libvorbis and libvorbisenc 1.0.1 or newer.
-      (libvorbis 1.3.1 or newer for 5.1 audio)
+*   libogg 1.1 or newer.
 
-  For creating a source distribution package:
+For example encoder:
 
-      as above,
+*   as above,
+*   libvorbis and libvorbisenc 1.0.1 or newer.
+    (libvorbis 1.3.1 or newer for 5.1 audio)
 
-      Doxygen to build the API documentation,
-      pdflatex and fig2dev to build the format specification
-        (transfig package in Ubuntu).
+For creating a source distribution package:
 
-  For the player only:
+*   as above,
+*   Doxygen to build the API documentation,
+*   pdflatex and fig2dev to build the format specification
+    (transfig package in Ubuntu).
 
-      as above,
+For the player only:
 
-      SDL (Simple Direct media Layer) libraries and headers,
-      OSS audio driver and development headers.
+*   as above,
+*   SDL (Simple Direct media Layer) libraries and headers,
+*   OSS audio driver and development headers.
 
 The provided build system is the GNU automake/autoconf system, and
 the main library, libtheora, should already build smoothly on any
@@ -72,11 +67,11 @@ Project files for Apple XCode are included in the macosx directory.
 
 There is also a more limited scons build.
 
-*** How do I use the sample encoder?
+### 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 
+if any, in a separate wave WAV file. Try 'encoder_example -h' for a
 complete list of options.
 
 An easy way to get raw video and audio files is to use MPlayer as an
@@ -85,7 +80,7 @@ wav file named audiodump.wav and a YUV video file in the correct
 format for encoder_example as stream.yuv.  Be careful when exporting
 video alone; MPlayer may drop frames to 'keep up' with the audio
 timer.  The example encoder can't properly synchronize input audio and
-video file that aren't in sync to begin with.  
+video file that aren't in sync to begin with.
 
 The encoder will also take video or audio on stdin if '-' is specified
 as the input file name.
@@ -93,64 +88,61 @@ as the input file name.
 There is also a 'png2theora' example which accepts a set of image
 files in that format.
 
-*** How do I use the sample player?
+### How do I use the sample player?
 
 The sample player takes an Ogg file on standard in; the file may be
 audio alone, video alone or video with audio.
 
-*** What other tools are available?
+### What other tools are available?
 
-The programs in the examples directory are intended as tutorial source 
-for developers using the library. As such they sacrifice features and 
-robustness in the interests of comprehension and should not be 
+The programs in the examples directory are intended as tutorial source
+for developers using the library. As such they sacrifice features and
+robustness in the interests of comprehension and should not be
 considered serious applications.
 
 If you're wanting to just use theora, consider the programs linked
-from http://www.theora.org/. There is playback support in a number
+from https://www.theora.org/. There is playback support in a number
 of common free players, and plugins for major media frameworks.
 Jan Gerber's ffmpeg2theora is an excellent encoding front end.
 
--------------------------------------------------------------------------
-Troubleshooting the build process
--------------------------------------------------------------------------
+## Troubleshooting the build process
 
-*** Compile error, such as:
+### Compile error, such as:
 
-encoder_internal.h:664: parse error before `ogg_uint16_t'
+encoder_internal.h:664: parse error before `ogg_uint16_t`
 
-This means you have version of libogg prior to 1.1. A *complete* new Ogg 
+This means you have version of libogg prior to 1.1. A *complete* new Ogg
 install, libs and headers is needed.
 
 Also be sure that there aren't multiple copies of Ogg installed in
 /usr and /usr/local; an older one might be first on the search path
 for libs and headers.
 
-*** Link error, such as:
+### Link error, such as:
 
-undefined reference to `oggpackB_stream'
+undefined reference to `oggpackB_stream`
 
 See above; you need libogg 1.1 or later.
 
-*** Link error, such as:
+### Link error, such as:
 
-undefined reference to `vorbis_granule_time'
+undefined reference to `vorbis_granule_time`
 
 You need libvorbis and libvorbisenc from the 1.0.1 release or later.
 
-*** Link error, such as:
+### Link error, such as:
 
-/usr/lib/libSDL.a(SDL_esdaudio.lo): In function `ESD_OpenAudio':
-SDL_esdaudio.lo(.text+0x25d): undefined reference to `esd_play_stream'
+/usr/lib/libSDL.a(SDL_esdaudio.lo): In function `ESD_OpenAudio`:
+SDL_esdaudio.lo(.text+0x25d): undefined reference to `esd_play_stream`
 
 Be sure to use an SDL that's built to work with OSS.  If you use an
 SDL that is also built with ESD and/or ALSA support, it will try to
 suck in all those extra libraries at link time too.  That will only
 work if the extra libraries are also installed.
 
-*** Link warning, such as:
+### Link warning, such as:
 
-libtool: link: warning: library `/usr/lib/libogg.la' was moved.
-libtool: link: warning: library `/usr/lib/libogg.la' was moved.
+libtool: link: warning: library `/usr/lib/libogg.la` was moved.
+libtool: link: warning: library `/usr/lib/libogg.la` was moved.
 
 Re-run theora/autogen.sh after an Ogg or Vorbis rebuild/reinstall
-
diff --git a/media/libtheora/bug468275-r18219.patch b/media/libtheora/bug468275-r18219.patch
deleted file mode 100644
index 7b64b4195a2c4..0000000000000
--- a/media/libtheora/bug468275-r18219.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-diff --git a/media/libtheora/lib/state.c b/media/libtheora/lib/state.c
---- a/media/libtheora/lib/state.c
-+++ b/media/libtheora/lib/state.c
-@@ -583,17 +583,17 @@ static int oc_state_ref_bufs_init(oc_the
-    ref_frame_sz<yplane_sz||ref_frame_data_sz/_nrefs!=ref_frame_sz){
-     return TH_EIMPL;
-   }
-   ref_frame_data=oc_aligned_malloc(ref_frame_data_sz,16);
-   frag_buf_offs=_state->frag_buf_offs=
-    _ogg_malloc(_state->nfrags*sizeof(*frag_buf_offs));
-   if(ref_frame_data==NULL||frag_buf_offs==NULL){
-     _ogg_free(frag_buf_offs);
--    _ogg_free(ref_frame_data);
-+    oc_aligned_free(ref_frame_data);
-     return TH_EFAULT;
-   }
-   /*Set up the width, height and stride for the image buffers.*/
-   _state->ref_frame_bufs[0][0].width=info->frame_width;
-   _state->ref_frame_bufs[0][0].height=info->frame_height;
-   _state->ref_frame_bufs[0][0].stride=yhstride;
-   _state->ref_frame_bufs[0][1].width=_state->ref_frame_bufs[0][2].width=
-    info->frame_width>>hdec;
diff --git a/media/libtheora/bug625773-r17780.patch b/media/libtheora/bug625773-r17780.patch
deleted file mode 100644
index af112560b08b5..0000000000000
--- a/media/libtheora/bug625773-r17780.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-diff --git a/media/libtheora/lib/decode.c b/media/libtheora/lib/decode.c
---- a/media/libtheora/lib/decode.c
-+++ b/media/libtheora/lib/decode.c
-@@ -2072,18 +2072,17 @@ static void oc_dec_init_dummy_frame(th_d
-    sizeof(_dec->pp_frame_buf[0])*3);
-   info=&_dec->state.info;
-   yhstride=abs(_dec->state.ref_ystride[0]);
-   yheight=info->frame_height+2*OC_UMV_PADDING;
-   chstride=abs(_dec->state.ref_ystride[1]);
-   cheight=yheight>>!(info->pixel_fmt&2);
-   yplane_sz=yhstride*(size_t)yheight+16;
-   cplane_sz=chstride*(size_t)cheight;
--  yoffset=_dec->state.ref_ystride[0]*(yheight-1)-
--   (OC_UMV_PADDING+OC_UMV_PADDING*(ptrdiff_t)yhstride);
-+  yoffset=yhstride*(ptrdiff_t)(yheight-OC_UMV_PADDING-1)+OC_UMV_PADDING;
-   memset(_dec->state.ref_frame_data[0]-yoffset,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
diff --git a/media/libtheora/bug752139-r18031.patch b/media/libtheora/bug752139-r18031.patch
deleted file mode 100644
index 62ea87632b1fe..0000000000000
--- a/media/libtheora/bug752139-r18031.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-diff --git a/media/libtheora/lib/arm/arm2gnu.pl b/media/libtheora/lib/arm/arm2gnu.pl
---- a/media/libtheora/lib/arm/arm2gnu.pl
-+++ b/media/libtheora/lib/arm/arm2gnu.pl
-@@ -1,11 +1,14 @@
- #!/usr/bin/perl
- 
- my $bigend;  # little/big endian
-+my $nxstack;
-+
-+$nxstack = 0;
- 
- eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}'
-     if $running_under_some_shell;
- 
- while ($ARGV[0] =~ /^-/) {
-     $_ = shift;
-   last if /^--/;
-     if (/^-n/) {
-@@ -77,16 +80,19 @@ while (<>) {
-     if ( /\bMEND\b/ ) {
-       s/\bMEND\b/.endm/;
-       $n=0;
-     }
- 
-     # ".rdata" doesn't work in 'as' version 2.13.2, as it is ".rodata" there.
-     #
-     if ( /\bAREA\b/ ) {
-+        if ( /CODE/ ) {
-+            $nxstack = 1;
-+        }
-         s/^(.+)CODE(.+)READONLY(.*)/    .text/;
-         s/^(.+)DATA(.+)READONLY(.*)/    .section .rdata\n    .align 2/;
-         s/^(.+)\|\|\.data\|\|(.+)/    .data\n    .align 2/;
-         s/^(.+)\|\|\.bss\|\|(.+)/    .bss/;
-     }
- 
-     s/\|\|\.constdata\$(\d+)\|\|/.L_CONST$1/;       # ||.constdata$3||
-     s/\|\|\.bss\$(\d+)\|\|/.L_BSS$1/;               # ||.bss$2||
-@@ -263,9 +269,13 @@ while (<>) {
- } continue {
-     printf ("%s", $_) if $printit;
-     if ($addPadding != 0)
-     {
-         printf ("   mov r0,r0\n");
-         $addPadding = 0;
-     }
- }
--
-+#If we had a code section, mark that this object doesn't need an executable
-+# stack.
-+if ($nxstack) {
-+    printf ("    .section\t.note.GNU-stack,\"\",\%\%progbits\n");
-+}
diff --git a/media/libtheora/bug752668-r18268.patch b/media/libtheora/bug752668-r18268.patch
deleted file mode 100644
index 6931e07fafecf..0000000000000
--- a/media/libtheora/bug752668-r18268.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-diff -r 1092c1a3ac50 media/libtheora/lib/decode.c
---- a/media/libtheora/lib/decode.c	Tue May 08 08:53:50 2012 +0200
-+++ b/media/libtheora/lib/decode.c	Tue May 08 01:00:59 2012 -0700
-@@ -395,20 +395,20 @@ static int oc_dec_init(oc_dec_ctx *_dec,
-      _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][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);
-+      qsum+=_dec->state.dequant_tables[qi][pli][qti][12]+
-+       _dec->state.dequant_tables[qi][pli][qti][17]+
-+       _dec->state.dequant_tables[qi][pli][qti][18]+
-+       _dec->state.dequant_tables[qi][pli][qti][24]<<(pli==0);
-     }
-     _dec->pp_sharp_mod[qi]=-(qsum>>11);
-   }
-   memcpy(_dec->state.loop_filter_limits,_setup->qinfo.loop_filter_limits,
-    sizeof(_dec->state.loop_filter_limits));
-   oc_dec_accel_init(_dec);
-   _dec->pp_level=OC_PP_LEVEL_DISABLED;
-   _dec->dc_qis=NULL;
diff --git a/media/libtheora/bug920992.patch b/media/libtheora/bug920992.patch
deleted file mode 100644
index 4fa4691475c9b..0000000000000
--- a/media/libtheora/bug920992.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-diff --git a/media/libtheora/lib/arm/armbits.s b/media/libtheora/lib/arm/armbits.s
---- a/media/libtheora/lib/arm/armbits.s
-+++ b/media/libtheora/lib/arm/armbits.s
-@@ -12,16 +12,22 @@
- ;
- ; function:
- ;   last mod: $Id$
- ;
- ;********************************************************************
- 
- 	AREA	|.text|, CODE, READONLY
- 
-+	; Explicitly specifying alignment here because some versions of
-+	; gas don't align code correctly. See
-+	; http://lists.gnu.org/archive/html/bug-binutils/2011-06/msg00199.html
-+	; https://bugzilla.mozilla.org/show_bug.cgi?id=920992
-+	ALIGN
-+
- 	EXPORT oc_pack_read_arm
- 	EXPORT oc_pack_read1_arm
- 	EXPORT oc_huff_token_decode_arm
- 
- oc_pack_read1_arm PROC
- 	; r0 = oc_pack_buf *_b
- 	ADD r12,r0,#8
- 	LDMIA r12,{r2,r3}      ; r2 = window
-diff --git a/media/libtheora/lib/arm/armfrag.s b/media/libtheora/lib/arm/armfrag.s
---- a/media/libtheora/lib/arm/armfrag.s
-+++ b/media/libtheora/lib/arm/armfrag.s
-@@ -11,16 +11,22 @@
- ;********************************************************************
- ; Original implementation:
- ;  Copyright (C) 2009 Robin Watts for Pinknoise Productions Ltd
- ; last mod: $Id$
- ;********************************************************************
- 
- 	AREA	|.text|, CODE, READONLY
- 
-+	; Explicitly specifying alignment here because some versions of
-+	; gas don't align code correctly. See
-+	; http://lists.gnu.org/archive/html/bug-binutils/2011-06/msg00199.html
-+	; https://bugzilla.mozilla.org/show_bug.cgi?id=920992
-+	ALIGN
-+
- 	GET	armopts.s
- 
- ; Vanilla ARM v4 versions
- 	EXPORT	oc_frag_copy_list_arm
- 	EXPORT	oc_frag_recon_intra_arm
- 	EXPORT	oc_frag_recon_inter_arm
- 	EXPORT	oc_frag_recon_inter2_arm
- 
-diff --git a/media/libtheora/lib/arm/armidct.s b/media/libtheora/lib/arm/armidct.s
---- a/media/libtheora/lib/arm/armidct.s
-+++ b/media/libtheora/lib/arm/armidct.s
-@@ -11,16 +11,22 @@
- ;********************************************************************
- ; Original implementation:
- ;  Copyright (C) 2009 Robin Watts for Pinknoise Productions Ltd
- ; last mod: $Id$
- ;********************************************************************
- 
- 	AREA	|.text|, CODE, READONLY
- 
-+	; Explicitly specifying alignment here because some versions of
-+	; gas don't align code correctly. See
-+	; http://lists.gnu.org/archive/html/bug-binutils/2011-06/msg00199.html
-+	; https://bugzilla.mozilla.org/show_bug.cgi?id=920992
-+	ALIGN
-+
- 	GET	armopts.s
- 
- 	EXPORT	oc_idct8x8_1_arm
- 	EXPORT	oc_idct8x8_arm
- 
- oc_idct8x8_1_arm PROC
- 	; r0 = ogg_int16_t  *_y
- 	; r1 = ogg_uint16_t  _dc
-diff --git a/media/libtheora/lib/arm/armloop.s b/media/libtheora/lib/arm/armloop.s
---- a/media/libtheora/lib/arm/armloop.s
-+++ b/media/libtheora/lib/arm/armloop.s
-@@ -11,16 +11,22 @@
- ;********************************************************************
- ; Original implementation:
- ;  Copyright (C) 2009 Robin Watts for Pinknoise Productions Ltd
- ; last mod: $Id$
- ;********************************************************************
- 
- 	AREA	|.text|, CODE, READONLY
- 
-+	; Explicitly specifying alignment here because some versions of
-+	; gas don't align code correctly. See
-+	; http://lists.gnu.org/archive/html/bug-binutils/2011-06/msg00199.html
-+	; https://bugzilla.mozilla.org/show_bug.cgi?id=920992
-+	ALIGN
-+
- 	GET	armopts.s
- 
- 	EXPORT	oc_loop_filter_frag_rows_arm
- 
- ; Which bit this is depends on the order of packing within a bitfield.
- ; Hopefully that doesn't change among any of the relevant compilers.
- OC_FRAG_CODED_FLAG	*	1
diff --git a/media/libtheora/include/theora/codec.h b/media/libtheora/include/theora/codec.h
index 5c2669630c1d6..29b860232544a 100644
--- a/media/libtheora/include/theora/codec.h
+++ b/media/libtheora/include/theora/codec.h
@@ -16,11 +16,12 @@
  ********************************************************************/
 
 /**\mainpage
- * 
+ *
  * \section intro Introduction
  *
- * This is the documentation for <tt>libtheora</tt> C API.
- * The current reference
+ * This is the documentation for the <tt>libtheora</tt> C API.
+ *
+ * The \c libtheora package is 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
@@ -30,29 +31,31 @@
  * <a href="http://www.theora.org/doc/Theora.pdf">the Theora
  *  specification</a>.
  *
- * \subsection Organization
+ * \section Organization
  *
- * The functions documented here are actually subdivided into three 
+ * The functions documented here are divided between two
  * separate libraries:
- * - <tt>libtheoraenc</tt> contains the encoder interface,
+ * - \c libtheoraenc contains the encoder interface,
  *   described in \ref encfuncs.
- * - <tt>libtheoradec</tt> contains the decoder interface and
- *   routines shared with the encoder.
- *   You must also link to this if you link to <tt>libtheoraenc</tt>.
- *   The routines in this library are described in \ref decfuncs and 
- *   \ref basefuncs.
- * - <tt>libtheora</tt> contains the \ref oldfuncs.
+ * - \c libtheoradec contains the decoder interface,
+ *   described in \ref decfuncs, \n
+ *   and additional \ref basefuncs.
+ *
+ * New code should link to \c libtheoradec. If using encoder
+ * features, it must also link to \c libtheoraenc.
  *
- * New code should link to <tt>libtheoradec</tt> and, if using encoder
- * features, <tt>libtheoraenc</tt>. Together these two export both
- * the standard and the legacy API, so this is all that is needed by
- * any code. The older <tt>libtheora</tt> library is provided just for
- * compatibility with older build configurations.
+ * During initial development, prior to the 1.0 release,
+ * \c libtheora exported a different \ref oldfuncs which
+ * combined both encode and decode functions.
+ * In general, legacy API symbols can be indentified
+ * by their \c theora_ or \c OC_ namespace prefixes.
+ * The current API uses \c th_ or \c TH_ instead.
  *
- * In general the recommended 1.x API symbols can be distinguished
- * by their <tt>th_</tt> or <tt>TH_</tt> namespace prefix.
- * The older, legacy API uses <tt>theora_</tt> or <tt>OC_</tt>
- * prefixes instead.
+ * While deprecated, \c libtheoraenc and \c libtheoradec
+ * together export the legacy api as well at the one documented above.
+ * Likewise, the legacy \c libtheora included with this package
+ * exports the new 1.x API. Older code and build scripts can therefore
+ * but updated independently to the current scheme.
  */
 
 /**\file
@@ -168,7 +171,7 @@ typedef struct{
 typedef th_img_plane th_ycbcr_buffer[3];
 
 /**Theora bitstream information.
- * This contains the basic playback parameters for a stream, and corresponds to 
+ * 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
  *  passes it to th_encode_alloc().
@@ -317,7 +320,7 @@ typedef struct{
  * 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
+ *  possibly containing null characters, so the length array should be
  *  treated as their authoritative length.
  */
 typedef struct th_comment{
@@ -448,7 +451,13 @@ typedef struct{
 
 /**\defgroup basefuncs Functions Shared by Encode and Decode*/
 /*@{*/
-/**\name Basic shared functions*/
+/**\name Basic shared functions
+ * These functions return information about the library itself,
+ * or provide high-level information about codec state
+ * and packet type.
+ *
+ * You must link to \c libtheoradec if you use any of the
+ * functions in this section.*/
 /*@{*/
 /**Retrieves a human-readable string to identify the library vendor and
  *  version.
@@ -510,7 +519,12 @@ extern int th_packet_iskeyframe(ogg_packet *_op);
 /*@}*/
 
 
-/**\name Functions for manipulating header data*/
+/**\name Functions for manipulating header data
+ * These functions manipulate the #th_info and #th_comment structures
+ * which describe video parameters and key-value metadata, respectively.
+ *
+ * You must link to \c libtheoradec if you use any of the
+ * functions in this section.*/
 /*@{*/
 /**Initializes a th_info structure.
  * This should be called on a freshly allocated #th_info structure before
@@ -537,7 +551,7 @@ extern void th_comment_init(th_comment *_tc);
  * \param _tc      The #th_comment struct to add the comment to.
  * \param _comment Must be a null-terminated UTF-8 string containing the
  *                  comment in "TAG=the value" form.*/
-extern void th_comment_add(th_comment *_tc, char *_comment);
+extern void th_comment_add(th_comment *_tc,const char *_comment);
 /**Add a comment to an initialized #th_comment structure.
  * \note Neither th_comment_add() nor th_comment_add_tag() support
  *  comments containing null values, although the bitstream format does
@@ -545,10 +559,11 @@ extern void th_comment_add(th_comment *_tc, char *_comment);
  * To add such comments you will need to manipulate the #th_comment
  *  structure directly.
  * \param _tc  The #th_comment struct to add the comment to.
- * \param _tag A null-terminated string containing the tag  associated with
+ * \param _tag A null-terminated string containing the tag associated with
  *              the comment.
  * \param _val The corresponding value as a null-terminated string.*/
-extern void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val);
+extern void th_comment_add_tag(th_comment *_tc,const char *_tag,
+ const char *_val);
 /**Look up a comment value by its tag.
  * \param _tc    An initialized #th_comment structure.
  * \param _tag   The tag to look up.
@@ -564,15 +579,15 @@ extern void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val);
  *         It should not be modified or freed by the application, and
  *          modifications to the structure may invalidate the pointer.
  * \retval NULL If no matching tag is found.*/
-extern char *th_comment_query(th_comment *_tc,char *_tag,int _count);
+extern char *th_comment_query(th_comment *_tc,const char *_tag,int _count);
 /**Look up the number of instances of a tag.
  * Call this first when querying for a specific tag and then iterate over the
  *  number of instances with separate calls to th_comment_query() to
  *  retrieve all the values for that tag in order.
  * \param _tc    An initialized #th_comment structure.
  * \param _tag   The tag to look up.
- * \return The number on instances of this particular tag.*/
-extern int th_comment_query_count(th_comment *_tc,char *_tag);
+ * \return The number of instances of this particular tag.*/
+extern int th_comment_query_count(th_comment *_tc,const char *_tag);
 /**Clears a #th_comment structure.
  * This should be called on a #th_comment structure after it is no longer
  *  needed.
diff --git a/media/libtheora/include/theora/theora.h b/media/libtheora/include/theora/theora.h
index 575a889b71269..a729a76890dd2 100644
--- a/media/libtheora/include/theora/theora.h
+++ b/media/libtheora/include/theora/theora.h
@@ -34,41 +34,41 @@ extern "C"
  *
  * \section intro Introduction
  *
- * This is the documentation for the libtheora legacy C API, declared in 
+ * 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 
+ * 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 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 
+ * 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 
+ * need to be embedded in an Ogg stream.  Use
+ * <a href="http://xiph.org/ogg/">libogg</a> or
  * <a href="http://www.annodex.net/software/liboggz/index.html">liboggz</a>
  * to extract/package these packets.
  *
  * \section decoding Decoding Process
  *
  * Decoding can be separated into the following steps:
- * -# initialise theora_info and theora_comment structures using 
+ * -# initialise theora_info and theora_comment structures using
  *    theora_info_init() and theora_comment_init():
  \verbatim
  theora_info     info;
  theora_comment  comment;
-   
+
  theora_info_init(&info);
  theora_comment_init(&comment);
  \endverbatim
- * -# retrieve header packets from Ogg stream (there should be 3) and decode 
- *    into theora_info and theora_comment structures using 
- *    theora_decode_header().  See \ref identification for more information on 
+ * -# retrieve header packets from Ogg stream (there should be 3) and decode
+ *    into theora_info and theora_comment structures using
+ *    theora_decode_header().  See \ref identification for more information on
  *    identifying which packets are theora packets.
  \verbatim
  int i;
@@ -79,14 +79,14 @@ extern "C"
  }
  \endverbatim
  * -# initialise the decoder based on the information retrieved into the
- *    theora_info struct by theora_decode_header().  You will need a 
+ *    theora_info struct by theora_decode_header().  You will need a
  *    theora_state struct.
  \verbatim
  theora_state state;
- 
+
  theora_decode_init(&state, &info);
  \endverbatim
- * -# pass in packets and retrieve decoded frames!  See the yuv_buffer 
+ * -# pass in packets and retrieve decoded frames!  See the yuv_buffer
  *    documentation for information on how to retrieve raw YUV data.
  \verbatim
  yuf_buffer buffer;
@@ -96,20 +96,20 @@ extern "C"
    theora_decode_YUVout(&state, &buffer);
  }
  \endverbatim
- *  
+ *
  *
  * \subsection identification Identifying Theora Packets
  *
- * All streams inside an Ogg file have a unique serial_no attached to the 
- * stream.  Typically, you will want to 
- *  - retrieve the serial_no for each b_o_s (beginning of stream) page 
- *    encountered within the Ogg file; 
- *  - test the first (only) packet on that page to determine if it is a theora 
+ * All streams inside an Ogg file have a unique serial_no attached to the
+ * stream.  Typically, you will want to
+ *  - retrieve the serial_no for each b_o_s (beginning of stream) page
+ *    encountered within the Ogg file;
+ *  - test the first (only) packet on that page to determine if it is a theora
  *    packet;
- *  - once you have found a theora b_o_s page then use the retrieved serial_no 
+ *  - 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 
+ *
+ * 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
@@ -124,9 +124,9 @@ extern "C"
  * 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 
+ * 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 
+ * must be a multiple of 16. The actual meaningful picture size and
  * offset are stored in the theora_info structure; frames returned by
  * the decoder may need to be cropped for display.
  *
@@ -135,8 +135,8 @@ extern "C"
  * are ordered from left to right.
  *
  * During decode, the yuv_buffer struct is allocated by the user, but all
- * fields (including luma and chroma pointers) are filled by the library.  
- * These pointers address library-internal memory and their contents should 
+ * fields (including luma and chroma pointers) are filled by the library.
+ * These pointers address library-internal memory and their contents should
  * not be modified.
  *
  * Conversely, during encode the user allocates the struct and fills out all
@@ -186,7 +186,7 @@ typedef enum {
  * Theora bitstream info.
  * Contains the basic playback parameters for a stream,
  * corresponding to the initial 'info' header packet.
- * 
+ *
  * Encoded theora frames must be a multiple of 16 in width and height.
  * To handle other frame sizes, a crop rectangle is specified in
  * frame_height and frame_width, offset_x and * offset_y. The offset
@@ -198,10 +198,10 @@ typedef enum {
  * fraction. Aspect ratio is also stored as a rational fraction, and
  * refers to the aspect ratio of the frame pixels, not of the
  * overall frame itself.
- * 
+ *
  * See <a href="http://svn.xiph.org/trunk/theora/examples/encoder_example.c">
  * examples/encoder_example.c</a> for usage examples of the
- * other paramters and good default settings for the encoder parameters.
+ * other parameters and good default settings for the encoder parameters.
  */
 typedef struct {
   ogg_uint32_t  width;		/**< encoded frame width  */
@@ -253,14 +253,14 @@ typedef struct{
 
 } theora_state;
 
-/** 
+/**
  * Comment header metadata.
  *
  * This structure holds the in-stream metadata corresponding to
  * the 'comment' header packet.
  *
  * Meta data is stored as a series of (tag, value) pairs, in
- * length-encoded string vectors. The first occurence of the 
+ * length-encoded string vectors. The first occurence of the
  * '=' character delimits the tag and value. A particular tag
  * may occur more than once. The character set encoding for
  * the strings is always UTF-8, but the tag names are limited
@@ -285,7 +285,7 @@ typedef struct theora_comment{
 /* \anchor decctlcodes_old
  * These are the available request codes for theora_control()
  * when called with a decoder instance.
- * By convention decoder control codes are odd, to distinguish 
+ * By convention decoder control codes are odd, to distinguish
  * them from \ref encctlcodes_old "encoder control codes" which
  * are even.
  *
@@ -306,7 +306,7 @@ typedef struct theora_comment{
 #define TH_DECCTL_GET_PPLEVEL_MAX (1)
 
 /**Set the post-processing level.
- * Sets the level of post-processing to use when decoding the 
+ * 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.
  */
@@ -345,9 +345,9 @@ typedef struct theora_comment{
  * \param[in] buf #th_quant_info
  * \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 
+ *                    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)
@@ -424,7 +424,7 @@ typedef struct theora_comment{
 #define OC_NEWPACKET   -25      /**< Packet is an (ignorable) unhandled extension */
 #define OC_DUPFRAME    1        /**< Packet is a dropped frame */
 
-/** 
+/**
  * Retrieve a human-readable string to identify the encoder vendor and version.
  * \returns A version string.
  */
@@ -462,7 +462,7 @@ extern int theora_encode_init(theora_state *th, theora_info *ti);
 extern int theora_encode_YUVin(theora_state *t, yuv_buffer *yuv);
 
 /**
- * Request the next packet of encoded video. 
+ * Request the next packet of encoded video.
  * The encoded data is placed in a user-provided ogg_packet structure.
  * \param t A theora_state handle previously initialized for encoding.
  * \param last_p whether this is the last packet the encoder should produce.
@@ -496,7 +496,11 @@ extern int theora_encode_header(theora_state *t, ogg_packet *op);
  * \param op An ogg_packet structure to fill. libtheora will set all
  *           elements of this structure, including a pointer to the encoded
  *           comment data. The memory for the comment data is owned by
- *           libtheora.
+ *           the application, and must be freed by it using _ogg_free().
+ *           On some systems (such as Windows when using dynamic linking), this
+ *           may mean the free is executed in a different module from the
+ *           malloc, which will crash; there is no way to free this memory on
+ *           such systems.
  * \retval 0 Success
  */
 extern int theora_encode_comment(theora_comment *tc, ogg_packet *op);
@@ -581,8 +585,8 @@ extern int theora_decode_packetin(theora_state *th,ogg_packet *op);
  * \param th A theora_state handle previously initialized for decoding.
  * \param yuv A yuv_buffer in which libtheora should place the decoded data.
  *            Note that the buffer struct itself is allocated by the user, but
- *            that the luma and chroma pointers will be filled in by the 
- *            library.  Also note that these luma and chroma regions should be 
+ *            that the luma and chroma pointers will be filled in by the
+ *            library.  Also note that these luma and chroma regions should be
  *            considered read-only by the user.
  * \retval 0 Success
  */
@@ -617,22 +621,22 @@ extern int theora_packet_iskeyframe(ogg_packet *op);
 /**
  * Report the granulepos shift radix
  *
- * When embedded in Ogg, Theora uses a two-part granulepos, 
+ * When embedded in Ogg, Theora uses a two-part granulepos,
  * splitting the 64-bit field into two pieces. The more-significant
  * section represents the frame count at the last keyframe,
  * and the less-significant section represents the count of
  * frames since the last keyframe. In this way the overall
  * field is still non-decreasing with time, but usefully encodes
  * a pointer to the last keyframe, which is necessary for
- * correctly restarting decode after a seek. 
+ * correctly restarting decode after a seek.
  *
  * This function reports the number of bits used to represent
  * the distance to the last keyframe, and thus how the granulepos
  * field must be shifted or masked to obtain the two parts.
- * 
+ *
  * Since libtheora returns compressed data in an ogg_packet
  * structure, this may be generally useful even if the Theora
- * packets are not being used in an Ogg container. 
+ * packets are not being used in an Ogg container.
  *
  * \param ti A previously initialized theora_info struct
  * \returns The bit shift dividing the two granulepos fields
@@ -644,7 +648,7 @@ int theora_granule_shift(theora_info *ti);
 /**
  * Convert a granulepos to an absolute frame index, starting at 0.
  * The granulepos is interpreted in the context of a given theora_state handle.
- * 
+ *
  * Note that while the granulepos encodes the frame count (i.e. starting
  * from 1) this call returns the frame index, starting from zero. Thus
  * One can calculate the presentation time by multiplying the index by
@@ -670,9 +674,7 @@ extern ogg_int64_t theora_granule_frame(theora_state *th,ogg_int64_t granulepos)
  *          This is the "end time" for the frame, or the latest time it should
  *           be displayed.
  *          It is not the presentation time.
- * \retval -1. The given granulepos is undefined (i.e. negative), or
- * \retval -1. The function has been disabled because floating 
- *              point support is not available.
+ * \retval -1. The given granulepos is undefined (i.e. negative).
  */
 extern double theora_granule_time(theora_state *th,ogg_int64_t granulepos);
 
@@ -699,7 +701,7 @@ extern void theora_clear(theora_state *t);
 
 /**
  * Initialize an allocated theora_comment structure
- * \param tc An allocated theora_comment structure 
+ * \param tc An allocated theora_comment structure
  **/
 extern void theora_comment_init(theora_comment *tc);
 
@@ -720,7 +722,7 @@ extern void theora_comment_add(theora_comment *tc, char *comment);
 /**
  * Add a comment to an initialized theora_comment structure.
  * \param tc A previously initialized theora comment structure
- * \param tag A null-terminated string containing the tag 
+ * \param tag A null-terminated string containing the tag
  *            associated with the comment.
  * \param value The corresponding value as a null-terminated string
  *
@@ -752,9 +754,9 @@ extern char *theora_comment_query(theora_comment *tc, char *tag, int count);
  *  \param tc An initialized theora_comment structure
  *  \param tag The tag to look up
  *  \returns The number on instances of a particular tag.
- * 
+ *
  *  Call this first when querying for a specific tag and then interate
- *  over the number of instances with separate calls to 
+ *  over the number of instances with separate calls to
  *  theora_comment_query() to retrieve all instances in order.
  **/
 extern int   theora_comment_query_count(theora_comment *tc, char *tag);
@@ -769,7 +771,7 @@ extern void  theora_comment_clear(theora_comment *tc);
  * 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_old "the list of available 
+ *                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.*/
diff --git a/media/libtheora/include/theora/theoradec.h b/media/libtheora/include/theora/theoradec.h
index 6177af3216bf3..77bef81909c40 100644
--- a/media/libtheora/include/theora/theoradec.h
+++ b/media/libtheora/include/theora/theoradec.h
@@ -92,13 +92,17 @@ extern "C" {
  *                     <tt>sizeof(th_stripe_callback)</tt>.*/
 #define TH_DECCTL_SET_STRIPE_CB (7)
 
-/**Enables telemetry and sets the macroblock display mode */
+/**Sets the macroblock display mode. Set to 0 to disable displaying
+ * macroblocks.*/
 #define TH_DECCTL_SET_TELEMETRY_MBMODE (9)
-/**Enables telemetry and sets the motion vector display mode */
+/**Sets the motion vector display mode. Set to 0 to disable displaying motion
+ * vectors.*/
 #define TH_DECCTL_SET_TELEMETRY_MV (11)
-/**Enables telemetry and sets the adaptive quantization display mode */
+/**Sets the adaptive quantization display mode. Set to 0 to disable displaying
+ * adaptive quantization. */
 #define TH_DECCTL_SET_TELEMETRY_QI (13)
-/**Enables telemetry and sets the bitstream breakdown visualization mode */
+/**Sets the bitstream breakdown visualization mode. Set to 0 to disable
+ * displaying bitstream breakdown.*/
 #define TH_DECCTL_SET_TELEMETRY_BITS (15)
 /*@}*/
 
@@ -171,7 +175,7 @@ typedef struct th_setup_info th_setup_info;
 /**\defgroup decfuncs Functions for Decoding*/
 /*@{*/
 /**\name Functions for decoding
- * You must link to <tt>libtheoradec</tt> if you use any of the 
+ * You must link to <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 decode.
@@ -267,7 +271,10 @@ extern void th_setup_free(th_setup_info *_setup);
  *                See \ref decctlcodes "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.*/
+ * \param _buf_sz The size of the parameter buffer.
+ * \return Possible return values depend on the control code used.
+ *          See \ref decctlcodes "the list of control codes" for
+ *          specific values. Generally 0 indicates success.*/
 extern int th_decode_ctl(th_dec_ctx *_dec,int _req,void *_buf,
  size_t _buf_sz);
 /**Submits a packet containing encoded video data to the decoder.
diff --git a/media/libtheora/include/theora/theoraenc.h b/media/libtheora/include/theora/theoraenc.h
deleted file mode 100644
index 721ea89b9d45d..0000000000000
--- a/media/libtheora/include/theora/theoraenc.h
+++ /dev/null
@@ -1,540 +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-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 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 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 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 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 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 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 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 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 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 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 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 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 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 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)
-/**Sets the configuration to be compatible with that from the given setup
- *  header.
- * This sets the Huffman codebooks and quantization parameters to match those
- *  found in the given setup header.
- * This guarantees that packets encoded by this encoder will be decodable using
- *  a decoder configured with the passed-in setup header.
- * It does <em>not</em> guarantee that th_encode_flushheader() will produce a
- *  bit-identical setup header, only that they will be compatible.
- * If you need a bit-identical setup header, then use the one you passed into
- *  this command, and not the one returned by th_encode_flushheader().
- *
- * This also does <em>not</em> enable or disable VP3 compatibility; that is not
- *  signaled in the setup header (or anywhere else in the encoded stream), and
- *  is controlled independently by the #TH_ENCCTL_SET_VP3_COMPATIBLE function.
- * If you wish to enable VP3 compatibility mode <em>and</em> want the codebooks
- *  and quantization parameters to match the given setup header, you should
- *  enable VP3 compatibility before invoking this command, otherwise the
- *  codebooks and quantization parameters will be reset to the VP3 defaults.
- *
- * The current encoder does not support Huffman codebooks which do not contain
- *  codewords for all 32 tokens.
- * Such codebooks are legal, according to the specification, but cannot be
- *  configured with this function.
- *
- * \param[in] _buf <tt>unsigned char[]</tt>: The encoded setup header to copy
- *                                            the configuration from.
- *                                           This should be the original,
- *                                            undecoded setup header packet,
- *                                            and <em>not</em> a #th_setup_info
- *                                            structure filled in by
- *                                            th_decode_headerin().
- * \retval TH_EFAULT     \a _enc or \a _buf is <tt>NULL</tt>.
- * \retval TH_EINVAL     Encoding has already begun, so the codebooks and
- *                        quantization parameters cannot be changed, or the
- *                        data in the setup header was not supported by this
- *                        encoder.
- * \retval TH_EBADHEADER \a _buf did not contain a valid setup header packet.
- * \retval TH_ENOTFORMAT \a _buf did not contain a Theora header at all.
- * \retval TH_EIMPL   Not supported by this implementation.*/
-#define TH_ENCCTL_SET_COMPAT_CONFIG (32)
-
-/*@}*/
-
-
-/**\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.
- *               If the width and height of the buffer matches the frame size
- *                the encoder was initialized with, the encoder will only
- *                reference the portion inside the picture region.
- *               Any data outside this region will be ignored, and need not map
- *                to a valid address.
- *               Alternatively, you can pass a buffer equal to the size of the
- *                picture region, if this is less than the full frame size.
- *               When using subsampled chroma planes, odd picture sizes or odd
- *                picture offsets may require an unexpected chroma plane size,
- *                and their use is generally discouraged, as they will not be
- *                well-supported by players and other media frameworks.
- *               See Section 4.4 of 
- *                <a href="http://www.theora.org/doc/Theora.pdf">the Theora
- *                specification</a> for details if you wish to use them anyway.
- * \retval 0         Success.
- * \retval TH_EFAULT \a _enc or \a _ycbcr is <tt>NULL</tt>.
- * \retval TH_EINVAL The buffer size matches neither the frame size nor the
- *                    picture 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
diff --git a/media/libtheora/lib/arm/arm2gnu.pl b/media/libtheora/lib/arm/arm2gnu.pl
old mode 100644
new mode 100755
index 5831bd81e26a6..8cb68e4a9faeb
--- a/media/libtheora/lib/arm/arm2gnu.pl
+++ b/media/libtheora/lib/arm/arm2gnu.pl
@@ -23,6 +23,7 @@ $\ = "\n";      # automatically add newline on print
 $n=0;
 
 $thumb = 0;     # ARM mode by default, not Thumb.
+ at proc_stack = ();
 
 LINE:
 while (<>) {
@@ -85,13 +86,19 @@ while (<>) {
     # ".rdata" doesn't work in 'as' version 2.13.2, as it is ".rodata" there.
     #
     if ( /\bAREA\b/ ) {
+        my $align;
+        $align = "2";
+        if ( /ALIGN=(\d+)/ ) {
+            $align = $1;
+        }
         if ( /CODE/ ) {
             $nxstack = 1;
         }
         s/^(.+)CODE(.+)READONLY(.*)/    .text/;
-        s/^(.+)DATA(.+)READONLY(.*)/    .section .rdata\n    .align 2/;
-        s/^(.+)\|\|\.data\|\|(.+)/    .data\n    .align 2/;
+        s/^(.+)DATA(.+)READONLY(.*)/    .section .rdata/;
+        s/^(.+)\|\|\.data\|\|(.+)/    .data/;
         s/^(.+)\|\|\.bss\|\|(.+)/    .bss/;
+        s/$/;   .p2align $align/;
     }
 
     s/\|\|\.constdata\$(\d+)\|\|/.L_CONST$1/;       # ||.constdata$3||
@@ -105,12 +112,30 @@ while (<>) {
     s/\bCODE16\b/.code 16/ && do {$thumb = 1};
     if (/\bPROC\b/)
     {
-        print "    .thumb_func" if ($thumb);
+        my $prefix;
+        my $proc;
+        /^([A-Za-z_\.]\w+)\b/;
+        $proc = $1;
+        $prefix = "";
+        if ($proc)
+        {
+            $prefix = $prefix.sprintf("\t.type\t%s, %%function; ",$proc);
+            push(@proc_stack, $proc);
+            s/^[A-Za-z_\.]\w+/$&:/;
+        }
+        $prefix = $prefix."\t.thumb_func; " if ($thumb);
         s/\bPROC\b/@ $&/;
+        $_ = $prefix.$_;
     }
     s/^(\s*)(S|Q|SH|U|UQ|UH)ASX\b/$1$2ADDSUBX/;
     s/^(\s*)(S|Q|SH|U|UQ|UH)SAX\b/$1$2SUBADDX/;
-    s/\bENDP\b/@ $&/;
+    if (/\bENDP\b/)
+    {
+        my $proc;
+        s/\bENDP\b/@ $&/;
+        $proc = pop(@proc_stack);
+        $_ = "\t.size $proc, .-$proc".$_ if ($proc);
+    }
     s/\bSUBT\b/@ $&/;
     s/\bDATA\b/@ $&/;   # DATA directive is deprecated -- Asm guide, p.7-25
     s/\bKEEP\b/@ $&/;
@@ -223,6 +248,7 @@ while (<>) {
     {
         my $cmd=$_;
         my $value;
+        my $prefix;
         my $w1;
         my $w2;
         my $w3;
@@ -241,25 +267,22 @@ while (<>) {
         if( $bigend ne "")
         {
             # big endian
-
-            print "        .byte      0x".$w1;
-            print "        .byte      0x".$w2;
-            print "        .byte      0x".$w3;
-            print "        .byte      0x".$w4;
+            $prefix = "\t.byte\t0x".$w1.";".
+                      "\t.byte\t0x".$w2.";".
+                      "\t.byte\t0x".$w3.";".
+                      "\t.byte\t0x".$w4."; ";
         }
         else
         {
             # little endian
-
-            print "        .byte      0x".$w4;
-            print "        .byte      0x".$w3;
-            print "        .byte      0x".$w2;
-            print "        .byte      0x".$w1;
+            $prefix = "\t.byte\t0x".$w4.";".
+                      "\t.byte\t0x".$w3.";".
+                      "\t.byte\t0x".$w2.";".
+                      "\t.byte\t0x".$w1."; ";
         }
-
+        $_=$prefix.$_;
     }
 
-
     if ( /\badrl\b/i )
     {
         s/\badrl\s+(\w+)\s*,\s*(\w+)/ldr $1,=$2/i;
diff --git a/media/libtheora/lib/arm/armbits.s b/media/libtheora/lib/arm/armbits.s
index 0fdb6fdd37441..94007225435f5 100644
--- a/media/libtheora/lib/arm/armbits.s
+++ b/media/libtheora/lib/arm/armbits.s
@@ -11,18 +11,12 @@
 ;********************************************************************
 ;
 ; function:
-;   last mod: $Id: armbits.s 17481 2010-10-03 22:49:42Z tterribe $
+;   last mod: $Id$
 ;
 ;********************************************************************
 
 	AREA	|.text|, CODE, READONLY
 
-	; Explicitly specifying alignment here because some versions of
-	; gas don't align code correctly. See
-	; http://lists.gnu.org/archive/html/bug-binutils/2011-06/msg00199.html
-	; https://bugzilla.mozilla.org/show_bug.cgi?id=920992
-	ALIGN
-
 	EXPORT oc_pack_read_arm
 	EXPORT oc_pack_read1_arm
 	EXPORT oc_huff_token_decode_arm
diff --git a/media/libtheora/lib/arm/armcpu.c b/media/libtheora/lib/arm/armcpu.c
index 8b0f9a857465f..f1941bdc15577 100644
--- a/media/libtheora/lib/arm/armcpu.c
+++ b/media/libtheora/lib/arm/armcpu.c
@@ -20,7 +20,7 @@
 #include "armcpu.h"
 
 #if !defined(OC_ARM_ASM)|| \
- !defined(OC_ARM_ASM_EDSP)&&!defined(OC_ARM_ASM_ARMV6)&& \
+ !defined(OC_ARM_ASM_EDSP)&&!defined(OC_ARM_ASM_MEDIA)&& \
  !defined(OC_ARM_ASM_NEON)
 ogg_uint32_t oc_cpu_flags_get(void){
   return 0;
@@ -107,6 +107,44 @@ ogg_uint32_t oc_cpu_flags_get(void){
   return flags;
 }
 
+#elif defined(__riscos__)
+#include <kernel.h>
+#include <swis.h>
+
+ogg_uint32_t oc_cpu_flags_get(void) {
+  ogg_uint32_t flags = 0;
+
+#if defined(OC_ARM_ASM_EDSP) || defined(OC_ARM_ASM_MEDIA)
+
+  if (_swi(OS_Byte,_IN(0)|_IN(2)|_RETURN(1), 129, 0xFF) <= 0xA9)
+     _swix(OS_Module, _INR(0,1), 1, "System:Modules.CallASWI");
+
+  ogg_uint32_t features;
+  _kernel_oserror* test = _swix(OS_PlatformFeatures, _IN(0)|_OUT(0), 0, &features);
+  if (test == NULL) {
+#if defined(OC_ARM_ASM_EDSP)
+    if((features>>10 & 1) == 1)flags|=OC_CPU_ARM_EDSP;
+#endif
+
+#if defined(OC_ARM_ASM_MEDIA)
+    if ((features>>31 & 1) == 1) {
+      ogg_uint32_t shadd = 0;
+      test =_swix(OS_PlatformFeatures, _INR(0,1)|_OUT(0), 34, 29, &shadd);
+      if (test==NULL && shadd==1)flags|=OC_CPU_ARM_MEDIA;
+    }
+#endif
+  }
+#endif
+
+#if defined(OC_ARM_ASM_NEON)
+  ogg_uint32_t mvfr1;
+  test = _swix(VFPSupport_Features, _IN(0)|_OUT(2), 0, &mvfr1);
+  if (test==NULL && (mvfr1 & 0xFFF00)==0x11100)flags|=OC_CPU_ARM_NEON;
+#endif
+
+  return flags;
+}
+
 #else
 /*The feature registers which can tell us what the processor supports are
    accessible in priveleged modes only, so we can't have a general user-space
diff --git a/media/libtheora/lib/arm/armfrag.s b/media/libtheora/lib/arm/armfrag.s
index e20579eee4b07..38627ed669ba3 100644
--- a/media/libtheora/lib/arm/armfrag.s
+++ b/media/libtheora/lib/arm/armfrag.s
@@ -11,17 +11,11 @@
 ;********************************************************************
 ; Original implementation:
 ;  Copyright (C) 2009 Robin Watts for Pinknoise Productions Ltd
-; last mod: $Id: armfrag.s 17481 2010-10-03 22:49:42Z tterribe $
+; last mod: $Id$
 ;********************************************************************
 
 	AREA	|.text|, CODE, READONLY
 
-	; Explicitly specifying alignment here because some versions of
-	; gas don't align code correctly. See
-	; http://lists.gnu.org/archive/html/bug-binutils/2011-06/msg00199.html
-	; https://bugzilla.mozilla.org/show_bug.cgi?id=920992
-	ALIGN
-
 	GET	armopts.s
 
 ; Vanilla ARM v4 versions
@@ -516,8 +510,7 @@ oc_frag_recon_intra_neon PROC
 	; r0 =       unsigned char *_dst
 	; r1 =       int            _ystride
 	; r2 = const ogg_int16_t    _residue[64]
-	MOV	r3, #128
-	VDUP.S16	Q0, r3
+	VMOV.I16	Q0, #128
 	VLDMIA	r2,  {D16-D31}	; D16= 3333222211110000 etc	; 9(8) cycles
 	VQADD.S16	Q8, Q8, Q0
 	VQADD.S16	Q9, Q9, Q0
diff --git a/media/libtheora/lib/arm/armidct.s b/media/libtheora/lib/arm/armidct.s
index babd846ecd30e..68530c7140184 100644
--- a/media/libtheora/lib/arm/armidct.s
+++ b/media/libtheora/lib/arm/armidct.s
@@ -11,17 +11,11 @@
 ;********************************************************************
 ; Original implementation:
 ;  Copyright (C) 2009 Robin Watts for Pinknoise Productions Ltd
-; last mod: $Id: armidct.s 17481 2010-10-03 22:49:42Z tterribe $
+; last mod: $Id$
 ;********************************************************************
 
 	AREA	|.text|, CODE, READONLY
 
-	; Explicitly specifying alignment here because some versions of
-	; gas don't align code correctly. See
-	; http://lists.gnu.org/archive/html/bug-binutils/2011-06/msg00199.html
-	; https://bugzilla.mozilla.org/show_bug.cgi?id=920992
-	ALIGN
-
 	GET	armopts.s
 
 	EXPORT	oc_idct8x8_1_arm
@@ -70,11 +64,8 @@ oc_idct8x8_slow_arm
 	BL	idct8core_arm
 	BL	idct8core_arm
 	LDR	r0, [r13], #4	; Write to the final destination.
-	; Clear input data for next block (decoder only).
 	SUB	r2, r1, #8*16
-	CMP	r0, r2
-	MOV	r1, r13		; And read from temp storage.
-	BEQ	oc_idct8x8_slow_arm_cols
+	; Clear input data for next block.
 	MOV	r4, #0
 	MOV	r5, #0
 	MOV	r6, #0
@@ -87,7 +78,7 @@ oc_idct8x8_slow_arm
 	STMIA	r2!,{r4,r5,r6,r7}
 	STMIA	r2!,{r4,r5,r6,r7}
 	STMIA	r2!,{r4,r5,r6,r7}
-oc_idct8x8_slow_arm_cols
+	MOV	r1, r13		; And read from temp storage.
 ; Column transforms
 	BL	idct8core_down_arm
 	BL	idct8core_down_arm
@@ -111,18 +102,15 @@ oc_idct8x8_10_arm PROC
 	BL	idct3core_arm
 	BL	idct2core_arm
 	BL	idct1core_arm
-	; Clear input data for next block (decoder only).
-	SUB	r0, r1, #4*16
-	CMP	r0, r2
-	MOV	r1, r13		; Read from temp storage.
-	BEQ	oc_idct8x8_10_arm_cols
+	; Clear input data for next block.
 	MOV	r4, #0
-	STR	r4, [r0]
-	STR	r4, [r0,#4]
-	STR	r4, [r0,#16]
-	STR	r4, [r0,#20]
-	STR	r4, [r0,#32]
-	STR	r4, [r0,#48]
+	STR	r4, [r1,#-4*16]!
+	STR	r4, [r1,#4]
+	STR	r4, [r1,#16]
+	STR	r4, [r1,#20]
+	STR	r4, [r1,#32]
+	STR	r4, [r1,#48]
+	MOV	r1, r13		; Read from temp storage.
 	MOV	r0, r2		; Write to the final destination
 oc_idct8x8_10_arm_cols
 ; Column transforms
@@ -147,18 +135,14 @@ oc_idct8x8_6_arm PROC
 	BL	idct3core_arm
 	BL	idct2core_arm
 	BL	idct1core_arm
-	; Clear input data for next block (decoder only).
-	SUB	r0, r1, #3*16
-	CMP	r0, r2
-	MOV	r1, r13		; Read from temp storage.
-	BEQ	oc_idct8x8_6_arm_cols
+	; Clear input data for next block.
 	MOV	r4, #0
-	STR	r4, [r0]
-	STR	r4, [r0,#4]
-	STR	r4, [r0,#16]
-	STR	r4, [r0,#32]
+	STR	r4, [r1,#-3*16]!
+	STR	r4, [r1,#4]
+	STR	r4, [r1,#16]
+	STR	r4, [r1,#32]
+	MOV	r1, r13		; Read from temp storage.
 	MOV	r0, r2		; Write to the final destination
-oc_idct8x8_6_arm_cols
 ; Column transforms
 	BL	idct3core_down_arm
 	BL	idct3core_down_arm
@@ -180,14 +164,12 @@ oc_idct8x8_3_arm PROC
 	MOV	r0, r13		; Write to temp storage.
 	BL	idct2core_arm
 	BL	idct1core_arm
-	; Clear input data for next block (decoder only).
-	SUB	r0, r1, #2*16
-	CMP	r0, r2
+	; Clear input data for next block.
+	MOV	r4, #0
+	STR	r4, [r1,#-2*16]!
+	STR	r4, [r1,#16]
 	MOV	r1, r13		; Read from temp storage.
-	MOVNE	r4, #0
-	STRNE	r4, [r0]
-	STRNE	r4, [r0,#16]
-	MOVNE	r0, r2		; Write to the final destination
+	MOV	r0, r2		; Write to the final destination
 ; Column transforms
 	BL	idct2core_down_arm
 	BL	idct2core_down_arm
@@ -805,30 +787,26 @@ oc_idct8x8_slow_v6
 	BL	idct8_8core_v6
 	BL	idct8_8core_v6
 	LDR	r0, [r13], #4	; Write to the final destination.
-	; Clear input data for next block (decoder only).
-	SUB	r2, r1, #8*16
-	CMP	r0, r2
-	MOV	r1, r13		; And read from temp storage.
-	BEQ	oc_idct8x8_slow_v6_cols
+	; Clear input data for next block.
 	MOV	r4, #0
 	MOV	r5, #0
-	STRD	r4, [r2], #8
-	STRD	r4, [r2], #8
-	STRD	r4, [r2], #8
-	STRD	r4, [r2], #8
-	STRD	r4, [r2], #8
-	STRD	r4, [r2], #8
-	STRD	r4, [r2], #8
-	STRD	r4, [r2], #8
-	STRD	r4, [r2], #8
-	STRD	r4, [r2], #8
-	STRD	r4, [r2], #8
-	STRD	r4, [r2], #8
-	STRD	r4, [r2], #8
-	STRD	r4, [r2], #8
-	STRD	r4, [r2], #8
-	STRD	r4, [r2], #8
-oc_idct8x8_slow_v6_cols
+	STRD	r4, [r1,#-8*16]!
+	STRD	r4, [r1,#8]
+	STRD	r4, [r1,#16]
+	STRD	r4, [r1,#24]
+	STRD	r4, [r1,#32]
+	STRD	r4, [r1,#40]
+	STRD	r4, [r1,#48]
+	STRD	r4, [r1,#56]
+	STRD	r4, [r1,#64]
+	STRD	r4, [r1,#72]
+	STRD	r4, [r1,#80]
+	STRD	r4, [r1,#88]
+	STRD	r4, [r1,#96]
+	STRD	r4, [r1,#104]
+	STRD	r4, [r1,#112]
+	STRD	r4, [r1,#120]
+	MOV	r1, r13		; And read from temp storage.
 ; Column transforms
 	BL	idct8_8core_down_v6
 	BL	idct8_8core_down_v6
@@ -849,20 +827,16 @@ oc_idct8x8_10_v6 PROC
 	BL	idct4_3core_v6
 	BL	idct2_1core_v6
 	LDR	r0, [r13], #4	; Write to the final destination.
-	; Clear input data for next block (decoder only).
-	SUB	r2, r1, #4*16
-	CMP	r0, r2
-	AND	r1, r13,#4	; Align the stack.
-	BEQ	oc_idct8x8_10_v6_cols
+	; Clear input data for next block.
 	MOV	r4, #0
 	MOV	r5, #0
-	STRD	r4, [r2]
-	STRD	r4, [r2,#16]
-	STR	r4, [r2,#32]
-	STR	r4, [r2,#48]
-oc_idct8x8_10_v6_cols
-; Column transforms
+	STRD	r4, [r1,#-4*16]!
+	STRD	r4, [r1,#16]
+	STR	r4, [r1,#32]
+	STR	r4, [r1,#48]
+	AND	r1, r13,#4	; Align the stack.
 	ADD	r1, r1, r13	; And read from temp storage.
+; Column transforms
 	BL	idct4_4core_down_v6
 	BL	idct4_4core_down_v6
 	BL	idct4_4core_down_v6
@@ -878,14 +852,12 @@ oc_idct8x8_3_v6 PROC
 	MOV	r8, r0
 	MOV	r0, r13		; Write to temp storage.
 	BL	idct2_1core_v6
-	; Clear input data for next block (decoder only).
-	SUB	r0, r1, #2*16
-	CMP	r0, r8
+	; Clear input data for next block.
+	MOV	r4, #0
+	STR	r4, [r1,#-2*16]!
+	STR	r4, [r1,#16]
 	MOV	r1, r13		; Read from temp storage.
-	MOVNE	r4, #0
-	STRNE	r4, [r0]
-	STRNE	r4, [r0,#16]
-	MOVNE	r0, r8		; Write to the final destination.
+	MOV	r0, r8		; Write to the final destination.
 ; Column transforms
 	BL	idct2_2core_down_v6
 	BL	idct2_2core_down_v6
@@ -1041,20 +1013,16 @@ oc_idct8x8_6_v6 PROC
 	ADD	r0, r0, r13	; Write to temp storage.
 	BL	idct3_2core_v6
 	BL	idct1core_v6
-	; Clear input data for next block (decoder only).
-	SUB	r0, r1, #3*16
-	CMP	r0, r8
-	AND	r1, r13,#4	; Align the stack.
-	BEQ	oc_idct8x8_6_v6_cols
+	; Clear input data for next block.
 	MOV	r4, #0
 	MOV	r5, #0
-	STRD	r4, [r0]
-	STR	r4, [r0,#16]
-	STR	r4, [r0,#32]
+	STRD	r4, [r1,#-3*16]!
+	STR	r4, [r1,#16]
+	STR	r4, [r1,#32]
+	AND	r1, r13,#4	; Align the stack.
 	MOV	r0, r8		; Write to the final destination.
-oc_idct8x8_6_v6_cols
-; Column transforms
 	ADD	r1, r1, r13	; And read from temp storage.
+; Column transforms
 	BL	idct3_3core_down_v6
 	BL	idct3_3core_down_v6
 	BL	idct3_3core_down_v6
@@ -1596,7 +1564,6 @@ oc_idct8x8_slow_neon
 	VSWP		D23,D30
 	; Column transforms
 	BL	oc_idct8x8_stage123_neon
-	CMP	r0,r1
 	; We have to put the return address back in the LR, or the branch
 	;  predictor will not recognize the function return and mis-predict the
 	;  entire call stack.
@@ -1610,7 +1577,6 @@ oc_idct8x8_slow_neon
 	VADD.S16	Q10,Q10,Q5	; Q10 = y[2]=t[2]'+t[5]''
 	VSUB.S16	Q12,Q11,Q4	; Q12 = y[4]=t[3]'-t[4]'
 	VADD.S16	Q11,Q11,Q4	; Q11 = y[3]=t[3]'+t[4]'
-	BEQ		oc_idct8x8_slow_neon_noclear
 	VMOV.I8		Q2,#0
 	VPOP		{D8-D15}
 	VMOV.I8		Q3,#0
@@ -1628,19 +1594,6 @@ oc_idct8x8_slow_neon
 	VRSHR.S16	Q15,Q15,#4	; Q15 = y[7]+8>>4
 	VSTMIA		r0, {D16-D31}
 	MOV	PC, r14
-
-oc_idct8x8_slow_neon_noclear
-	VPOP		{D8-D15}
-	VRSHR.S16	Q8, Q8, #4	; Q8  = y[0]+8>>4
-	VRSHR.S16	Q9, Q9, #4	; Q9  = y[1]+8>>4
-	VRSHR.S16	Q10,Q10,#4	; Q10 = y[2]+8>>4
-	VRSHR.S16	Q11,Q11,#4	; Q11 = y[3]+8>>4
-	VRSHR.S16	Q12,Q12,#4	; Q12 = y[4]+8>>4
-	VRSHR.S16	Q13,Q13,#4	; Q13 = y[5]+8>>4
-	VRSHR.S16	Q14,Q14,#4	; Q14 = y[6]+8>>4
-	VRSHR.S16	Q15,Q15,#4	; Q15 = y[7]+8>>4
-	VSTMIA		r0, {D16-D31}
-	MOV	PC, r14
 	ENDP
 
 oc_idct8x8_stage123_neon PROC
@@ -1871,7 +1824,6 @@ oc_idct8x8_10_neon PROC
 	VADD.S16	Q10,Q1, Q2	; Q10= t[1]'=t[0]+t[2]
 	VSUB.S16	Q2, Q1, Q2	; Q2 = t[2]'=t[0]-t[2]
 ; Stage 4
-	CMP	r0, r1
 	VADD.S16	Q8, Q11,Q15	; Q8  = y[0]=t[0]'+t[7]'
 	VADD.S16	Q9, Q10,Q14	; Q9  = y[1]=t[1]'+t[6]''
 	VSUB.S16	Q15,Q11,Q15	; Q15 = y[7]=t[0]'-t[7]'
@@ -1880,7 +1832,6 @@ oc_idct8x8_10_neon PROC
 	VADD.S16	Q11,Q3, Q12	; Q11 = y[3]=t[3]'+t[4]'
 	VSUB.S16	Q12,Q3, Q12	; Q12 = y[4]=t[3]'-t[4]'
 	VSUB.S16	Q13,Q2, Q13	; Q13 = y[5]=t[2]'-t[5]''
-	BEQ	oc_idct8x8_10_neon_noclear
 	VMOV.I8		D2, #0
 	VRSHR.S16	Q8, Q8, #4	; Q8  = y[0]+8>>4
 	VST1.64		{D2}, [r1 at 64], r12
@@ -1896,18 +1847,6 @@ oc_idct8x8_10_neon PROC
 	VRSHR.S16	Q15,Q15,#4	; Q15 = y[7]+8>>4
 	VSTMIA		r0, {D16-D31}
 	MOV	PC, r14
-
-oc_idct8x8_10_neon_noclear
-	VRSHR.S16	Q8, Q8, #4	; Q8  = y[0]+8>>4
-	VRSHR.S16	Q9, Q9, #4	; Q9  = y[1]+8>>4
-	VRSHR.S16	Q10,Q10,#4	; Q10 = y[2]+8>>4
-	VRSHR.S16	Q11,Q11,#4	; Q11 = y[3]+8>>4
-	VRSHR.S16	Q12,Q12,#4	; Q12 = y[4]+8>>4
-	VRSHR.S16	Q13,Q13,#4	; Q13 = y[5]+8>>4
-	VRSHR.S16	Q14,Q14,#4	; Q14 = y[6]+8>>4
-	VRSHR.S16	Q15,Q15,#4	; Q15 = y[7]+8>>4
-	VSTMIA		r0, {D16-D31}
-	MOV	PC, r14
 	ENDP
  ]
 
diff --git a/media/libtheora/lib/arm/armloop.s b/media/libtheora/lib/arm/armloop.s
index 0a1d4705e7403..bbd4d630edec1 100644
--- a/media/libtheora/lib/arm/armloop.s
+++ b/media/libtheora/lib/arm/armloop.s
@@ -11,17 +11,11 @@
 ;********************************************************************
 ; Original implementation:
 ;  Copyright (C) 2009 Robin Watts for Pinknoise Productions Ltd
-; last mod: $Id: armloop.s 17481 2010-10-03 22:49:42Z tterribe $
+; last mod: $Id$
 ;********************************************************************
 
 	AREA	|.text|, CODE, READONLY
 
-	; Explicitly specifying alignment here because some versions of
-	; gas don't align code correctly. See
-	; http://lists.gnu.org/archive/html/bug-binutils/2011-06/msg00199.html
-	; https://bugzilla.mozilla.org/show_bug.cgi?id=920992
-	ALIGN
-
 	GET	armopts.s
 
 	EXPORT	oc_loop_filter_frag_rows_arm
diff --git a/media/libtheora/lib/bitpack.c b/media/libtheora/lib/bitpack.c
index 8bfce4c3d0506..5125dde6b075c 100644
--- a/media/libtheora/lib/bitpack.c
+++ b/media/libtheora/lib/bitpack.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function: packing variable sized words into an octet stream
-  last mod: $Id: bitpack.c 17410 2010-09-21 21:53:48Z tterribe $
+  last mod: $Id$
 
  ********************************************************************/
 #include <string.h>
diff --git a/media/libtheora/lib/config.h b/media/libtheora/lib/config.h
index 49772ac7f3b13..e331b9977f217 100644
--- a/media/libtheora/lib/config.h
+++ b/media/libtheora/lib/config.h
@@ -13,8 +13,8 @@
 /* Define to 1 if you have the <machine/soundcard.h> header file. */
 /* #undef HAVE_MACHINE_SOUNDCARD_H */
 
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
+/* Abort if size exceeds 16384x16384 (for fuzzing only) */
+/* #undef HAVE_MEMORY_CONSTRAINT */
 
 /* Define to 1 if you have the <soundcard.h> header file. */
 /* #undef HAVE_SOUNDCARD_H */
@@ -22,6 +22,9 @@
 /* Define to 1 if you have the <stdint.h> header file. */
 #define HAVE_STDINT_H 1
 
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
 /* Define to 1 if you have the <stdlib.h> header file. */
 #define HAVE_STDLIB_H 1
 
@@ -43,20 +46,20 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #define HAVE_UNISTD_H 1
 
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-/* #undef NO_MINUS_C_MINUS_O */
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+/* #undef LT_OBJDIR */
 
 /* make use of arm asm optimization */
- 
+/* #undef OC_ARM_ASM */
 
 /* Define if assembler supports EDSP instructions */
-
+/* #undef OC_ARM_ASM_EDSP */
 
 /* Define if assembler supports ARMv6 media instructions */
-
+/* #undef OC_ARM_ASM_MEDIA */
 
 /* Define if compiler supports NEON instructions */
-
+/* #undef OC_ARM_ASM_NEON */
 
 /* make use of c64x+ asm optimization */
 /* #undef OC_C64X_ASM */
@@ -77,22 +80,24 @@
 #define PACKAGE_NAME "libtheora"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "libtheora 1.2.0alpha1+svn"
+#define PACKAGE_STRING "libtheora 1.2.0alpha1+git"
 
 /* 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.2.0alpha1+svn"
+#define PACKAGE_VERSION "1.2.0alpha1+git"
 
-/* Define to 1 if you have the ANSI C header files. */
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+   required in a freestanding environment). This macro is provided for
+   backward compatibility; new code need not use it. */
 #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 */
-
 /* Version number of package */
-#define VERSION "1.2.0alpha1+svn"
+#define VERSION "1.2.0alpha1+git"
diff --git a/media/libtheora/lib/dct.h b/media/libtheora/lib/dct.h
index 24ba6f111aacd..8052ea6bc1d46 100644
--- a/media/libtheora/lib/dct.h
+++ b/media/libtheora/lib/dct.h
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-  last mod: $Id: dct.h 16503 2009-08-22 18:14:02Z giles $
+  last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/decinfo.c b/media/libtheora/lib/decinfo.c
index 603b1f93e46a6..a91e740b15309 100644
--- a/media/libtheora/lib/decinfo.c
+++ b/media/libtheora/lib/decinfo.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: decinfo.c 17276 2010-06-05 05:57:05Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
@@ -20,6 +20,11 @@
 #include <limits.h>
 #include "decint.h"
 
+/*Only used for fuzzing.*/
+#if defined(HAVE_MEMORY_CONSTRAINT)
+static const int MAX_FUZZING_WIDTH = 16384;
+static const int MAX_FUZZING_HEIGHT = 16384;
+#endif
 
 
 /*Unpacks a series of octets from a given byte array into the pack buffer.
@@ -55,8 +60,8 @@ static int oc_info_unpack(oc_pack_buf *_opb,th_info *_info){
   /*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){
+   (_info->version_major==TH_VERSION_MAJOR&&
+   _info->version_minor>TH_VERSION_MINOR)){
     return TH_EVERSION;
   }
   /*Read the encoded frame description.*/
@@ -82,6 +87,11 @@ static int oc_info_unpack(oc_pack_buf *_opb,th_info *_info){
    _info->fps_numerator==0||_info->fps_denominator==0){
     return TH_EBADHEADER;
   }
+#if defined(HAVE_MEMORY_CONSTRAINT)
+  if(_info->frame_width>=MAX_FUZZING_WIDTH&&_info->frame_height>=MAX_FUZZING_HEIGHT){
+    return TH_EBADHEADER;
+  }
+#endif
   /*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
@@ -172,9 +182,23 @@ static int oc_dec_headerin(oc_pack_buf *_opb,th_info *_info,
   int  ret;
   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){
+  /*If we're at a data packet...*/
+  if(!(packtype&0x80)){
+    /*Check to make sure we received all three headers...
+      If we haven't seen any valid headers, assume this is not actually
+       Theora.*/
+    if(_info->frame_width<=0)return TH_ENOTFORMAT;
+    /*Follow our documentation, which says we'll return TH_EFAULT if this
+       are NULL (_info was checked by our caller).*/
+    if(_tc==NULL)return TH_EFAULT;
+    /*And if any other headers were missing, declare this packet "out of
+       sequence" instead.*/
+    if(_tc->vendor==NULL)return TH_EBADHEADER;
+    /*Don't check this until it's needed, since we allow passing NULL for the
+       arguments that we're not expecting the next header to fill in yet.*/
+    if(_setup==NULL)return TH_EFAULT;
+    if(*_setup==NULL)return TH_EBADHEADER;
+    /*If we got everything, we're done.*/
     return 0;
   }
   /*Check the codec string.*/
diff --git a/media/libtheora/lib/decint.h b/media/libtheora/lib/decint.h
index bd65222732a50..3cea6b1439fa5 100644
--- a/media/libtheora/lib/decint.h
+++ b/media/libtheora/lib/decint.h
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: decint.h 17457 2010-09-24 02:05:49Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
@@ -162,7 +162,6 @@ struct th_dec_ctx{
 # endif
 # if defined(HAVE_CAIRO)
   /*Output metrics for debugging.*/
-  int                    telemetry;
   int                    telemetry_mbmode;
   int                    telemetry_mv;
   int                    telemetry_qi;
diff --git a/media/libtheora/lib/decode.c b/media/libtheora/lib/decode.c
index 563782b7a25a6..fad26e092789d 100644
--- a/media/libtheora/lib/decode.c
+++ b/media/libtheora/lib/decode.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: decode.c 17576 2010-10-29 01:07:51Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
@@ -417,7 +417,6 @@ static int oc_dec_init(oc_dec_ctx *_dec,const th_info *_info,
   _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;
@@ -1203,6 +1202,9 @@ static void oc_dec_residual_tokens_unpack(oc_dec_ctx *_dec){
 
 
 static int oc_dec_postprocess_init(oc_dec_ctx *_dec){
+  /*musl libc malloc()/realloc() calls might use floating point, so make sure
+     we've cleared the MMX state for them.*/
+  oc_restore_fpu(&_dec->state);
   /*pp_level 0: disabled; free any memory used and return*/
   if(_dec->pp_level<=OC_PP_LEVEL_DISABLED){
     if(_dec->dc_qis!=NULL){
@@ -2019,28 +2021,24 @@ int th_decode_ctl(th_dec_ctx *_dec,int _req,void *_buf,
   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;
@@ -2081,6 +2079,664 @@ static void oc_dec_init_dummy_frame(th_dec_ctx *_dec){
   memset(_dec->state.ref_frame_data[0]-yoffset,0x80,yplane_sz+2*cplane_sz);
 }
 
+#if defined(HAVE_CAIRO)
+static void oc_render_telemetry(th_dec_ctx *_dec,th_ycbcr_buffer _ycbcr,
+ int _telemetry){
+  /*Stuff the plane into cairo.*/
+  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;
+  }
+  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;
+  }
+  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{
+        ptrdiff_t fragi;
+        int       frag_mvx;
+        int       frag_mvy;
+        for(bi=0;bi<4;bi++){
+          fragi=mb_maps[mbi][0][bi];
+          if(fragi>=0&&frags[fragi].coded){
+            frag_mvx=OC_MV_X(frag_mvs[fragi]);
+            frag_mvy=OC_MV_Y(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_mvx,y+8-frag_mvy);
+                cairo_set_source_rgba(c,1.,1.,1.,.9);
+                cairo_set_line_width(c,3.);
+                cairo_line_to(c,x+8+frag_mvx*.66,y+8-frag_mvy*.66);
+                cairo_stroke_preserve(c);
+                cairo_set_line_width(c,2.);
+                cairo_line_to(c,x+8+frag_mvx*.33,y+8-frag_mvy*.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_mvx,y+8-frag_mvy);
+                cairo_set_source_rgba(c,1.,1.,1.,.9);
+                cairo_set_line_width(c,3.);
+                cairo_line_to(c,x+8+frag_mvx*.66,y+8-frag_mvy*.66);
+                cairo_stroke_preserve(c);
+                cairo_set_line_width(c,2.);
+                cairo_line_to(c,x+8+frag_mvx*.33,y+8-frag_mvy*.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_mvx,y+8-frag_mvy);
+                cairo_set_source_rgba(c,1.,1.,1.,.9);
+                cairo_set_line_width(c,3.);
+                cairo_line_to(c,x+8+frag_mvx*.66,y+8-frag_mvy*.66);
+                cairo_stroke_preserve(c);
+                cairo_set_line_width(c,2.);
+                cairo_line_to(c,x+8+frag_mvx*.33,y+8-frag_mvy*.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_mvx,y+8-frag_mvy);
+                cairo_set_source_rgba(c,1.,1.,1.,.9);
+                cairo_set_line_width(c,3.);
+                cairo_line_to(c,x+8+frag_mvx*.66,y+8-frag_mvy*.66);
+                cairo_stroke_preserve(c);
+                cairo_set_line_width(c,2.);
+                cairo_line_to(c,x+8+frag_mvx*.33,y+8-frag_mvy*.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_mvx=OC_MV_X(frag_mvs[fragi]);
+                frag_mvx=OC_MV_Y(frag_mvs[fragi]);
+                cairo_move_to(c,x+4+frag_mvx,y+12-frag_mvy);
+                cairo_set_source_rgba(c,1.,1.,1.,.9);
+                cairo_set_line_width(c,3.);
+                cairo_line_to(c,x+4+frag_mvx*.66,y+12-frag_mvy*.66);
+                cairo_stroke_preserve(c);
+                cairo_set_line_width(c,2.);
+                cairo_line_to(c,x+4+frag_mvx*.33,y+12-frag_mvy*.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_mvx=OC_MV_X(frag_mvs[fragi]);
+                frag_mvx=OC_MV_Y(frag_mvs[fragi]);
+                cairo_move_to(c,x+12+frag_mvx,y+12-frag_mvy);
+                cairo_set_source_rgba(c,1.,1.,1.,.9);
+                cairo_set_line_width(c,3.);
+                cairo_line_to(c,x+12+frag_mvx*.66,y+12-frag_mvy*.66);
+                cairo_stroke_preserve(c);
+                cairo_set_line_width(c,2.);
+                cairo_line_to(c,x+12+frag_mvx*.33,y+12-frag_mvy*.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_mvx=OC_MV_X(frag_mvs[fragi]);
+                frag_mvx=OC_MV_Y(frag_mvs[fragi]);
+                cairo_move_to(c,x+4+frag_mvx,y+4-frag_mvy);
+                cairo_set_source_rgba(c,1.,1.,1.,.9);
+                cairo_set_line_width(c,3.);
+                cairo_line_to(c,x+4+frag_mvx*.66,y+4-frag_mvy*.66);
+                cairo_stroke_preserve(c);
+                cairo_set_line_width(c,2.);
+                cairo_line_to(c,x+4+frag_mvx*.33,y+4-frag_mvy*.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_mvx=OC_MV_X(frag_mvs[fragi]);
+                frag_mvx=OC_MV_Y(frag_mvs[fragi]);
+                cairo_move_to(c,x+12+frag_mvx,y+4-frag_mvy);
+                cairo_set_source_rgba(c,1.,1.,1.,.9);
+                cairo_set_line_width(c,3.);
+                cairo_line_to(c,x+12+frag_mvx*.66,y+4-frag_mvy*.66);
+                cairo_stroke_preserve(c);
+                cairo_set_line_width(c,2.);
+                cairo_line_to(c,x+12+frag_mvx*.33,y+4-frag_mvy*.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
+
 int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op,
  ogg_int64_t *_granpos){
   int ret;
@@ -2121,6 +2777,15 @@ int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op,
     int             pli;
     int             notstart;
     int             notdone;
+#ifdef HAVE_CAIRO
+    int             telemetry;
+    /*Save the current telemetry state.
+      This prevents it from being modified in the middle of decoding this
+       frame, which could cause us to skip calls to the striped decoding
+       callback.*/
+    telemetry=_dec->telemetry_mbmode||_dec->telemetry_mv||
+     _dec->telemetry_qi||_dec->telemetry_bits;
+#endif
     /*Select a free buffer to use for the reconstructed version of this frame.*/
     for(refi=0;refi==_dec->state.ref_frame_idx[OC_FRAME_GOLD]||
      refi==_dec->state.ref_frame_idx[OC_FRAME_PREV];refi++);
@@ -2258,7 +2923,11 @@ int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op,
         avail_fragy_end=OC_MINI(avail_fragy_end,
          _dec->pipe.fragy_end[pli]-edelay<<frag_shift);
       }
+#ifdef HAVE_CAIRO
+      if(_dec->stripe_cb.stripe_decoded!=NULL&&!telemetry){
+#else
       if(_dec->stripe_cb.stripe_decoded!=NULL){
+#endif
         /*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
@@ -2294,6 +2963,20 @@ int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op,
     /*Restore the FPU before dump_frame, since that _does_ use the FPU (for PNG
        gamma values, if nothing else).*/
     oc_restore_fpu(&_dec->state);
+#ifdef HAVE_CAIRO
+    /*If telemetry ioctls are active, we need to draw to the output buffer.*/
+    if(telemetry){
+      oc_render_telemetry(_dec,stripe_buf,telemetry);
+      oc_ycbcr_buffer_flip(_dec->pp_frame_buf,stripe_buf);
+      /*If we had a striped decoding callback, we skipped calling it above
+         (because the telemetry wasn't rendered yet).
+        Call it now with the whole frame.*/
+      if(_dec->stripe_cb.stripe_decoded!=NULL){
+        (*_dec->stripe_cb.stripe_decoded)(_dec->stripe_cb.ctx,
+         stripe_buf,0,_dec->state.fplanes[0].nvfrags);
+      }
+    }
+#endif
 #if defined(OC_DUMP_IMAGES)
     /*We only dump images if there were some coded blocks.*/
     oc_state_dump_frame(&_dec->state,OC_FRAME_SELF,"dec");
@@ -2305,659 +2988,5 @@ int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op,
 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{
-          ptrdiff_t fragi;
-          int       frag_mvx;
-          int       frag_mvy;
-          for(bi=0;bi<4;bi++){
-            fragi=mb_maps[mbi][0][bi];
-            if(fragi>=0&&frags[fragi].coded){
-              frag_mvx=OC_MV_X(frag_mvs[fragi]);
-              frag_mvy=OC_MV_Y(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_mvx,y+8-frag_mvy);
-                  cairo_set_source_rgba(c,1.,1.,1.,.9);
-                  cairo_set_line_width(c,3.);
-                  cairo_line_to(c,x+8+frag_mvx*.66,y+8-frag_mvy*.66);
-                  cairo_stroke_preserve(c);
-                  cairo_set_line_width(c,2.);
-                  cairo_line_to(c,x+8+frag_mvx*.33,y+8-frag_mvy*.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_mvx,y+8-frag_mvy);
-                  cairo_set_source_rgba(c,1.,1.,1.,.9);
-                  cairo_set_line_width(c,3.);
-                  cairo_line_to(c,x+8+frag_mvx*.66,y+8-frag_mvy*.66);
-                  cairo_stroke_preserve(c);
-                  cairo_set_line_width(c,2.);
-                  cairo_line_to(c,x+8+frag_mvx*.33,y+8-frag_mvy*.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_mvx,y+8-frag_mvy);
-                  cairo_set_source_rgba(c,1.,1.,1.,.9);
-                  cairo_set_line_width(c,3.);
-                  cairo_line_to(c,x+8+frag_mvx*.66,y+8-frag_mvy*.66);
-                  cairo_stroke_preserve(c);
-                  cairo_set_line_width(c,2.);
-                  cairo_line_to(c,x+8+frag_mvx*.33,y+8-frag_mvy*.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_mvx,y+8-frag_mvy);
-                  cairo_set_source_rgba(c,1.,1.,1.,.9);
-                  cairo_set_line_width(c,3.);
-                  cairo_line_to(c,x+8+frag_mvx*.66,y+8-frag_mvy*.66);
-                  cairo_stroke_preserve(c);
-                  cairo_set_line_width(c,2.);
-                  cairo_line_to(c,x+8+frag_mvx*.33,y+8-frag_mvy*.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_mvx=OC_MV_X(frag_mvs[fragi]);
-                  frag_mvx=OC_MV_Y(frag_mvs[fragi]);
-                  cairo_move_to(c,x+4+frag_mvx,y+12-frag_mvy);
-                  cairo_set_source_rgba(c,1.,1.,1.,.9);
-                  cairo_set_line_width(c,3.);
-                  cairo_line_to(c,x+4+frag_mvx*.66,y+12-frag_mvy*.66);
-                  cairo_stroke_preserve(c);
-                  cairo_set_line_width(c,2.);
-                  cairo_line_to(c,x+4+frag_mvx*.33,y+12-frag_mvy*.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_mvx=OC_MV_X(frag_mvs[fragi]);
-                  frag_mvx=OC_MV_Y(frag_mvs[fragi]);
-                  cairo_move_to(c,x+12+frag_mvx,y+12-frag_mvy);
-                  cairo_set_source_rgba(c,1.,1.,1.,.9);
-                  cairo_set_line_width(c,3.);
-                  cairo_line_to(c,x+12+frag_mvx*.66,y+12-frag_mvy*.66);
-                  cairo_stroke_preserve(c);
-                  cairo_set_line_width(c,2.);
-                  cairo_line_to(c,x+12+frag_mvx*.33,y+12-frag_mvy*.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_mvx=OC_MV_X(frag_mvs[fragi]);
-                  frag_mvx=OC_MV_Y(frag_mvs[fragi]);
-                  cairo_move_to(c,x+4+frag_mvx,y+4-frag_mvy);
-                  cairo_set_source_rgba(c,1.,1.,1.,.9);
-                  cairo_set_line_width(c,3.);
-                  cairo_line_to(c,x+4+frag_mvx*.66,y+4-frag_mvy*.66);
-                  cairo_stroke_preserve(c);
-                  cairo_set_line_width(c,2.);
-                  cairo_line_to(c,x+4+frag_mvx*.33,y+4-frag_mvy*.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_mvx=OC_MV_X(frag_mvs[fragi]);
-                  frag_mvx=OC_MV_Y(frag_mvs[fragi]);
-                  cairo_move_to(c,x+12+frag_mvx,y+4-frag_mvy);
-                  cairo_set_source_rgba(c,1.,1.,1.,.9);
-                  cairo_set_line_width(c,3.);
-                  cairo_line_to(c,x+12+frag_mvx*.66,y+4-frag_mvy*.66);
-                  cairo_stroke_preserve(c);
-                  cairo_set_line_width(c,2.);
-                  cairo_line_to(c,x+12+frag_mvx*.33,y+4-frag_mvy*.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;
 }
diff --git a/media/libtheora/lib/dequant.c b/media/libtheora/lib/dequant.c
index e554872d4eec9..860536f72db29 100644
--- a/media/libtheora/lib/dequant.c
+++ b/media/libtheora/lib/dequant.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: dequant.c 16503 2009-08-22 18:14:02Z giles $
+    last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/dequant.h b/media/libtheora/lib/dequant.h
index ef25838e354c2..9d6cd6be5671b 100644
--- a/media/libtheora/lib/dequant.h
+++ b/media/libtheora/lib/dequant.h
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: dequant.h 16503 2009-08-22 18:14:02Z giles $
+    last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/fragment.c b/media/libtheora/lib/fragment.c
index 4ba6af1b714b7..14c38be5076e5 100644
--- a/media/libtheora/lib/fragment.c
+++ b/media/libtheora/lib/fragment.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: fragment.c 17410 2010-09-21 21:53:48Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 #include <string.h>
diff --git a/media/libtheora/lib/huffdec.c b/media/libtheora/lib/huffdec.c
index c592542ebd889..5a83c5f150480 100644
--- a/media/libtheora/lib/huffdec.c
+++ b/media/libtheora/lib/huffdec.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: huffdec.c 17577 2010-10-29 04:00:07Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/huffdec.h b/media/libtheora/lib/huffdec.h
index 2fd112a90bd97..03d25dcd1e147 100644
--- a/media/libtheora/lib/huffdec.h
+++ b/media/libtheora/lib/huffdec.h
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: huffdec.h 17410 2010-09-21 21:53:48Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/huffman.h b/media/libtheora/lib/huffman.h
index 36cf7572e5383..eb805866b9d9b 100644
--- a/media/libtheora/lib/huffman.h
+++ b/media/libtheora/lib/huffman.h
@@ -11,12 +11,12 @@
  ********************************************************************
 
   function:
-    last mod: $Id: huffman.h 16503 2009-08-22 18:14:02Z giles $
+    last mod: $Id$
 
  ********************************************************************/
 
 #if !defined(_huffman_H)
-# define _hufffman_H (1)
+# define _huffman_H (1)
 # include "theora/codec.h"
 # include "ocintrin.h"
 
diff --git a/media/libtheora/lib/idct.c b/media/libtheora/lib/idct.c
index c56eb94c5c6dc..838e3ad8caf0f 100644
--- a/media/libtheora/lib/idct.c
+++ b/media/libtheora/lib/idct.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: idct.c 17410 2010-09-21 21:53:48Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
@@ -241,8 +241,8 @@ static void oc_idct8x8_3(ogg_int16_t _y[64],ogg_int16_t _x[64]){
   for(i=0;i<8;i++)idct8_2(_y+i,w+i*8);
   /*Adjust for the scale factor.*/
   for(i=0;i<64;i++)_y[i]=(ogg_int16_t)(_y[i]+8>>4);
-  /*Clear input data for next block (decoder only).*/
-  if(_x!=_y)_x[0]=_x[1]=_x[8]=0;
+  /*Clear input data for next block.*/
+  _x[0]=_x[1]=_x[8]=0;
 }
 
 /*Performs an inverse 8x8 Type-II DCT transform.
@@ -272,8 +272,8 @@ static void oc_idct8x8_10(ogg_int16_t _y[64],ogg_int16_t _x[64]){
   for(i=0;i<8;i++)idct8_4(_y+i,w+i*8);
   /*Adjust for the scale factor.*/
   for(i=0;i<64;i++)_y[i]=(ogg_int16_t)(_y[i]+8>>4);
-  /*Clear input data for next block (decoder only).*/
-  if(_x!=_y)_x[0]=_x[1]=_x[2]=_x[3]=_x[8]=_x[9]=_x[10]=_x[16]=_x[17]=_x[24]=0;
+  /*Clear input data for next block.*/
+  _x[0]=_x[1]=_x[2]=_x[3]=_x[8]=_x[9]=_x[10]=_x[16]=_x[17]=_x[24]=0;
 }
 
 /*Performs an inverse 8x8 Type-II DCT transform.
@@ -291,7 +291,8 @@ static void oc_idct8x8_slow(ogg_int16_t _y[64],ogg_int16_t _x[64]){
   for(i=0;i<8;i++)idct8(_y+i,w+i*8);
   /*Adjust for the scale factor.*/
   for(i=0;i<64;i++)_y[i]=(ogg_int16_t)(_y[i]+8>>4);
-  if(_x!=_y)for(i=0;i<64;i++)_x[i]=0;
+  /*Clear input data for next block.*/
+  for(i=0;i<64;i++)_x[i]=0;
 }
 
 /*Performs an inverse 8x8 Type-II DCT transform.
diff --git a/media/libtheora/lib/info.c b/media/libtheora/lib/info.c
index 6b9762978ba9d..e5cecd2de5b88 100644
--- a/media/libtheora/lib/info.c
+++ b/media/libtheora/lib/info.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: info.c 16503 2009-08-22 18:14:02Z giles $
+    last mod: $Id$
 
  ********************************************************************/
 
@@ -54,7 +54,7 @@ void th_comment_init(th_comment *_tc){
   memset(_tc,0,sizeof(*_tc));
 }
 
-void th_comment_add(th_comment *_tc,char *_comment){
+void th_comment_add(th_comment *_tc,const char *_comment){
   char **user_comments;
   int   *comment_lengths;
   int    comment_len;
@@ -75,7 +75,7 @@ void th_comment_add(th_comment *_tc,char *_comment){
   _tc->user_comments[_tc->comments]=NULL;
 }
 
-void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val){
+void th_comment_add_tag(th_comment *_tc,const char *_tag,const char *_val){
   char *comment;
   int   tag_len;
   int   val_len;
@@ -91,7 +91,7 @@ void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val){
   _ogg_free(comment);
 }
 
-char *th_comment_query(th_comment *_tc,char *_tag,int _count){
+char *th_comment_query(th_comment *_tc,const char *_tag,int _count){
   long i;
   int  found;
   int  tag_len;
@@ -107,7 +107,7 @@ char *th_comment_query(th_comment *_tc,char *_tag,int _count){
   return NULL;
 }
 
-int th_comment_query_count(th_comment *_tc,char *_tag){
+int th_comment_query_count(th_comment *_tc,const char *_tag){
   long i;
   int  tag_len;
   int  count;
diff --git a/media/libtheora/lib/internal.c b/media/libtheora/lib/internal.c
index 1b2611da15ddb..afbb6efae7511 100644
--- a/media/libtheora/lib/internal.c
+++ b/media/libtheora/lib/internal.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: internal.c 17506 2010-10-13 02:52:41Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
@@ -131,7 +131,6 @@ void **oc_malloc_2d(size_t _height,size_t _width,size_t _sz){
   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;
@@ -154,7 +153,6 @@ void **oc_calloc_2d(size_t _height,size_t _width,size_t _sz){
   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;
diff --git a/media/libtheora/lib/internal.h b/media/libtheora/lib/internal.h
index 24e1b5125234e..53c77b88beb01 100644
--- a/media/libtheora/lib/internal.h
+++ b/media/libtheora/lib/internal.h
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: internal.h 17578 2010-10-29 04:21:26Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 #if !defined(_internal_H)
diff --git a/media/libtheora/lib/ocintrin.h b/media/libtheora/lib/ocintrin.h
index d49ebb21595bb..b200ceafce753 100644
--- a/media/libtheora/lib/ocintrin.h
+++ b/media/libtheora/lib/ocintrin.h
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: ocintrin.h 16503 2009-08-22 18:14:02Z giles $
+    last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/quant.c b/media/libtheora/lib/quant.c
index c3f3f477135d6..e206202844b72 100644
--- a/media/libtheora/lib/quant.c
+++ b/media/libtheora/lib/quant.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: quant.c 17307 2010-06-27 06:02:15Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/quant.h b/media/libtheora/lib/quant.h
index 49ce13a65c3af..247210eaaec5b 100644
--- a/media/libtheora/lib/quant.h
+++ b/media/libtheora/lib/quant.h
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: quant.h 16503 2009-08-22 18:14:02Z giles $
+    last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/state.c b/media/libtheora/lib/state.c
index 5e7b0ae651852..f4c6240387af9 100644
--- a/media/libtheora/lib/state.c
+++ b/media/libtheora/lib/state.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: state.c 17576 2010-10-29 01:07:51Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
@@ -21,6 +21,7 @@
 #if defined(OC_DUMP_IMAGES)
 # include <stdio.h>
 # include "png.h"
+# include "zlib.h"
 #endif
 
 /*The function used to fill in the chroma plane motion vectors for a macro
@@ -253,10 +254,14 @@ static void oc_mb_fill_cmapping10(oc_mb_map_plane _mb_map[3],
   This version is for use with no chroma decimation (4:4:4).
   This uses the already filled-in luma plane values.
   _mb_map:  The macro block map to fill.
-  _fplanes: The descriptions of the fragment planes.*/
+  _fplanes: The descriptions of the fragment planes.
+  _xfrag0:  The X location of the upper-left hand fragment in the luma plane.
+  _yfrag0:  The Y location of the upper-left hand fragment in the luma plane.*/
 static void oc_mb_fill_cmapping11(oc_mb_map_plane _mb_map[3],
- const oc_fragment_plane _fplanes[3]){
+ const oc_fragment_plane _fplanes[3],int _xfrag0,int _yfrag0){
   int k;
+  (void)_xfrag0;
+  (void)_yfrag0;
   for(k=0;k<4;k++){
     _mb_map[1][k]=_mb_map[0][k]+_fplanes[1].froffset;
     _mb_map[2][k]=_mb_map[0][k]+_fplanes[2].froffset;
@@ -278,7 +283,7 @@ static const oc_mb_fill_cmapping_func OC_MB_FILL_CMAPPING_TABLE[4]={
   oc_mb_fill_cmapping00,
   oc_mb_fill_cmapping01,
   oc_mb_fill_cmapping10,
-  (oc_mb_fill_cmapping_func)oc_mb_fill_cmapping11
+  oc_mb_fill_cmapping11
 };
 
 /*Fills in the mapping from macro blocks to their corresponding fragment
@@ -702,7 +707,8 @@ int oc_state_init(oc_theora_state *_state,const th_info *_info,int _nrefs){
      how it is specified in the bitstream, because the Y axis is flipped in
      the bitstream.
     The displayable frame must fit inside the encoded frame.
-    The color space must be one known by the encoder.*/
+    The color space must be one known by the encoder.
+    The framerate ratio must not contain a zero value.*/
   if((_info->frame_width&0xF)||(_info->frame_height&0xF)||
    _info->frame_width<=0||_info->frame_width>=0x100000||
    _info->frame_height<=0||_info->frame_height>=0x100000||
@@ -715,7 +721,8 @@ int oc_state_init(oc_theora_state *_state,const th_info *_info,int _nrefs){
       but there are a number of compilers which will mis-optimize this.
      It's better to live with the spurious warnings.*/
    _info->colorspace<0||_info->colorspace>=TH_CS_NSPACES||
-   _info->pixel_fmt<0||_info->pixel_fmt>=TH_PF_NFORMATS){
+   _info->pixel_fmt<0||_info->pixel_fmt>=TH_PF_NFORMATS||
+   _info->fps_numerator<1||_info->fps_denominator<1){
     return TH_EINVAL;
   }
   memset(_state,0,sizeof(*_state));
diff --git a/media/libtheora/lib/x86/mmxfrag.c b/media/libtheora/lib/x86/mmxfrag.c
index b7df1c1ec9edb..b3ec50895668a 100644
--- a/media/libtheora/lib/x86/mmxfrag.c
+++ b/media/libtheora/lib/x86/mmxfrag.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: mmxfrag.c 17410 2010-09-21 21:53:48Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
@@ -355,7 +355,7 @@ void oc_frag_recon_inter2_mmx(unsigned char *_dst,const unsigned char *_src1,
       /*Advance dest ptr.*/
       "lea (%[dst],%[ystride],2),%[dst]\n\t"
      :[dst]"+r"(_dst),[residue]"+r"(_residue),
-      [src1]"+%r"(_src1),[src2]"+r"(_src2)
+      [src1]"+r"(_src1),[src2]"+r"(_src2)
      :[ystride]"r"((ptrdiff_t)_ystride)
      :"memory"
     );
diff --git a/media/libtheora/lib/x86/mmxidct.c b/media/libtheora/lib/x86/mmxidct.c
index 8d61bdfb162e5..b8e30770661b3 100644
--- a/media/libtheora/lib/x86/mmxidct.c
+++ b/media/libtheora/lib/x86/mmxidct.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: mmxidct.c 17446 2010-09-23 20:06:20Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
@@ -284,6 +284,7 @@
   "#end OC_COLUMN_IDCT\n\t" \
 
 static void oc_idct8x8_slow_mmx(ogg_int16_t _y[64],ogg_int16_t _x[64]){
+  int i;
   /*This routine accepts an 8x8 matrix, but in partially transposed form.
     Every 4x4 block is transposed.*/
   __asm__ __volatile__(
@@ -313,18 +314,15 @@ static void oc_idct8x8_slow_mmx(ogg_int16_t _y[64],ogg_int16_t _x[64]){
     :[x]"m"OC_CONST_ARRAY_OPERAND(ogg_int16_t,_x,64),
      [c]"m"OC_CONST_ARRAY_OPERAND(ogg_int16_t,OC_IDCT_CONSTS,128)
   );
-  if(_x!=_y){
-    int i;
-    __asm__ __volatile__("pxor %%mm0,%%mm0\n\t"::);
-    for(i=0;i<4;i++){
-      __asm__ __volatile__(
-        "movq %%mm0,"OC_MEM_OFFS(0x00,x)"\n\t"
-        "movq %%mm0,"OC_MEM_OFFS(0x08,x)"\n\t"
-        "movq %%mm0,"OC_MEM_OFFS(0x10,x)"\n\t"
-        "movq %%mm0,"OC_MEM_OFFS(0x18,x)"\n\t"
-        :[x]"=m"OC_ARRAY_OPERAND(ogg_int16_t,_x+16*i,16)
-      );
-    }
+  __asm__ __volatile__("pxor %%mm0,%%mm0\n\t"::);
+  for(i=0;i<4;i++){
+    __asm__ __volatile__(
+      "movq %%mm0,"OC_MEM_OFFS(0x00,x)"\n\t"
+      "movq %%mm0,"OC_MEM_OFFS(0x08,x)"\n\t"
+      "movq %%mm0,"OC_MEM_OFFS(0x10,x)"\n\t"
+      "movq %%mm0,"OC_MEM_OFFS(0x18,x)"\n\t"
+      :[x]"=m"OC_ARRAY_OPERAND(ogg_int16_t,_x+16*i,16)
+    );
   }
 }
 
@@ -514,16 +512,14 @@ static void oc_idct8x8_10_mmx(ogg_int16_t _y[64],ogg_int16_t _x[64]){
     :[x]"m"OC_CONST_ARRAY_OPERAND(ogg_int16_t,_x,64),
      [c]"m"OC_CONST_ARRAY_OPERAND(ogg_int16_t,OC_IDCT_CONSTS,128)
   );
-  if(_x!=_y){
-    __asm__ __volatile__(
-      "pxor %%mm0,%%mm0\n\t"
-      "movq %%mm0,"OC_MEM_OFFS(0x00,x)"\n\t"
-      "movq %%mm0,"OC_MEM_OFFS(0x10,x)"\n\t"
-      "movq %%mm0,"OC_MEM_OFFS(0x20,x)"\n\t"
-      "movq %%mm0,"OC_MEM_OFFS(0x30,x)"\n\t"
-      :[x]"+m"OC_ARRAY_OPERAND(ogg_int16_t,_x,28)
-    );
-  }
+  __asm__ __volatile__(
+    "pxor %%mm0,%%mm0\n\t"
+    "movq %%mm0,"OC_MEM_OFFS(0x00,x)"\n\t"
+    "movq %%mm0,"OC_MEM_OFFS(0x10,x)"\n\t"
+    "movq %%mm0,"OC_MEM_OFFS(0x20,x)"\n\t"
+    "movq %%mm0,"OC_MEM_OFFS(0x30,x)"\n\t"
+    :[x]"+m"OC_ARRAY_OPERAND(ogg_int16_t,_x,28)
+  );
 }
 
 /*Performs an inverse 8x8 Type-II DCT transform.
diff --git a/media/libtheora/lib/x86/mmxstate.c b/media/libtheora/lib/x86/mmxstate.c
index 0b9586f943eea..eebea14fbaa97 100644
--- a/media/libtheora/lib/x86/mmxstate.c
+++ b/media/libtheora/lib/x86/mmxstate.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: mmxstate.c 17563 2010-10-25 17:40:54Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/x86/sse2idct.c b/media/libtheora/lib/x86/sse2idct.c
index 5f8523fa5f730..4597ab074f93a 100644
--- a/media/libtheora/lib/x86/sse2idct.c
+++ b/media/libtheora/lib/x86/sse2idct.c
@@ -208,6 +208,7 @@ const unsigned short __attribute__((aligned(16),used)) OC_IDCT_CONSTS[64]={
 
 static void oc_idct8x8_slow_sse2(ogg_int16_t _y[64],ogg_int16_t _x[64]){
   OC_ALIGN16(ogg_int16_t buf[16]);
+  int i;
   /*This routine accepts an 8x8 matrix pre-transposed.*/
   __asm__ __volatile__(
     /*Load rows 2, 3, 5, and 6 for the first stage of the iDCT.*/
@@ -230,19 +231,16 @@ static void oc_idct8x8_slow_sse2(ogg_int16_t _y[64],ogg_int16_t _x[64]){
     :[x]"m"(OC_CONST_ARRAY_OPERAND(ogg_int16_t,_x,64)),
      [c]"m"(OC_CONST_ARRAY_OPERAND(ogg_int16_t,OC_IDCT_CONSTS,128))
   );
-  if(_x!=_y){
-    int i;
-    __asm__ __volatile__("pxor %%xmm0,%%xmm0\n\t"::);
-    /*Clear input data for next block (decoder only).*/
-    for(i=0;i<2;i++){
-      __asm__ __volatile__(
-        "movdqa %%xmm0,"OC_MEM_OFFS(0x00,x)"\n\t"
-        "movdqa %%xmm0,"OC_MEM_OFFS(0x10,x)"\n\t"
-        "movdqa %%xmm0,"OC_MEM_OFFS(0x20,x)"\n\t"
-        "movdqa %%xmm0,"OC_MEM_OFFS(0x30,x)"\n\t"
-        :[x]"=m"(OC_ARRAY_OPERAND(ogg_int16_t,_x+i*32,32))
-      );
-    }
+  __asm__ __volatile__("pxor %%xmm0,%%xmm0\n\t"::);
+  /*Clear input data for next block (decoder only).*/
+  for(i=0;i<2;i++){
+    __asm__ __volatile__(
+      "movdqa %%xmm0,"OC_MEM_OFFS(0x00,x)"\n\t"
+      "movdqa %%xmm0,"OC_MEM_OFFS(0x10,x)"\n\t"
+      "movdqa %%xmm0,"OC_MEM_OFFS(0x20,x)"\n\t"
+      "movdqa %%xmm0,"OC_MEM_OFFS(0x30,x)"\n\t"
+      :[x]"=m"(OC_ARRAY_OPERAND(ogg_int16_t,_x+i*32,32))
+    );
   }
 }
 
@@ -411,17 +409,15 @@ static void oc_idct8x8_10_sse2(ogg_int16_t _y[64],ogg_int16_t _x[64]){
     :[x]"m"OC_CONST_ARRAY_OPERAND(ogg_int16_t,_x,64),
      [c]"m"(OC_CONST_ARRAY_OPERAND(ogg_int16_t,OC_IDCT_CONSTS,128))
   );
-  if(_x!=_y){
-    /*Clear input data for next block (decoder only).*/
-    __asm__ __volatile__(
-      "pxor %%mm0,%%mm0\n\t"
-      "movq %%mm0,"OC_MEM_OFFS(0x00,x)"\n\t"
-      "movq %%mm0,"OC_MEM_OFFS(0x10,x)"\n\t"
-      "movq %%mm0,"OC_MEM_OFFS(0x20,x)"\n\t"
-      "movq %%mm0,"OC_MEM_OFFS(0x30,x)"\n\t"
-      :[x]"+m"(OC_ARRAY_OPERAND(ogg_int16_t,_x,28))
-    );
-  }
+  /*Clear input data for next block (decoder only).*/
+  __asm__ __volatile__(
+    "pxor %%mm0,%%mm0\n\t"
+    "movq %%mm0,"OC_MEM_OFFS(0x00,x)"\n\t"
+    "movq %%mm0,"OC_MEM_OFFS(0x10,x)"\n\t"
+    "movq %%mm0,"OC_MEM_OFFS(0x20,x)"\n\t"
+    "movq %%mm0,"OC_MEM_OFFS(0x30,x)"\n\t"
+    :[x]"+m"(OC_ARRAY_OPERAND(ogg_int16_t,_x,28))
+  );
 }
 
 /*Performs an inverse 8x8 Type-II DCT transform.
diff --git a/media/libtheora/lib/x86/x86cpu.c b/media/libtheora/lib/x86/x86cpu.c
index c3a20b319c1c2..49fd76d0ac635 100644
--- a/media/libtheora/lib/x86/x86cpu.c
+++ b/media/libtheora/lib/x86/x86cpu.c
@@ -14,7 +14,7 @@
   Originally written by Rudolf Marek.
 
  function:
-  last mod: $Id: x86cpu.c 17410 2010-09-21 21:53:48Z tterribe $
+  last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/x86/x86cpu.h b/media/libtheora/lib/x86/x86cpu.h
index 153a48d892881..e0192d52e290f 100644
--- a/media/libtheora/lib/x86/x86cpu.h
+++ b/media/libtheora/lib/x86/x86cpu.h
@@ -10,7 +10,7 @@
  *                                                                  *
  ********************************************************************
  function:
-    last mod: $Id: x86cpu.h 17410 2010-09-21 21:53:48Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/x86/x86int.h b/media/libtheora/lib/x86/x86int.h
index 35bfb0a02b69e..ceb2dbb0ec11d 100644
--- a/media/libtheora/lib/x86/x86int.h
+++ b/media/libtheora/lib/x86/x86int.h
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: x86int.h 17578 2010-10-29 04:21:26Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/x86/x86state.c b/media/libtheora/lib/x86/x86state.c
index a3d37267f61e7..9f8bceb534887 100644
--- a/media/libtheora/lib/x86/x86state.c
+++ b/media/libtheora/lib/x86/x86state.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: x86state.c 17421 2010-09-22 16:46:18Z giles $
+    last mod: $Id$
 
  ********************************************************************/
 
@@ -19,6 +19,7 @@
 
 #if defined(OC_X86_ASM)
 
+#if defined(OC_STATE_USE_VTABLE)
 /*This table has been modified from OC_FZIG_ZAG by baking a 4x4 transpose into
    each quadrant of the destination.*/
 static const unsigned char OC_FZIG_ZAG_MMX[128]={
@@ -39,6 +40,7 @@ static const unsigned char OC_FZIG_ZAG_MMX[128]={
   64,64,64,64,64,64,64,64,
   64,64,64,64,64,64,64,64
 };
+#endif
 
 /*This table has been modified from OC_FZIG_ZAG by baking an 8x8 transpose into
    the destination.*/
diff --git a/media/libtheora/lib/x86_vc/mmxfrag.c b/media/libtheora/lib/x86_vc/mmxfrag.c
index c16b026ffc6fd..248312ff9049b 100644
--- a/media/libtheora/lib/x86_vc/mmxfrag.c
+++ b/media/libtheora/lib/x86_vc/mmxfrag.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: mmxfrag.c 17446 2010-09-23 20:06:20Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/x86_vc/mmxidct.c b/media/libtheora/lib/x86_vc/mmxidct.c
index 53a9ac7f38ca4..55e00aedcfd45 100644
--- a/media/libtheora/lib/x86_vc/mmxidct.c
+++ b/media/libtheora/lib/x86_vc/mmxidct.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: mmxidct.c 17446 2010-09-23 20:06:20Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
@@ -339,22 +339,19 @@ static void oc_idct8x8_slow(ogg_int16_t _y[64],ogg_int16_t _x[64]){
 #undef  Y
 #undef  X
   }
-  if(_x!=_y){
-    int i;
-    __asm pxor mm0,mm0;
-    for(i=0;i<4;i++){
-      ogg_int16_t *x;
-      x=_x+16*i;
+  __asm pxor mm0,mm0;
+  for(i=0;i<4;i++){
+    ogg_int16_t *x;
+    x=_x+16*i;
 #define X ecx
-      __asm{
-        mov X,x
-        movq [X+0x00],mm0
-        movq [X+0x08],mm0
-        movq [X+0x10],mm0
-        movq [X+0x18],mm0
-      }
-#undef  X
+    __asm{
+      mov X,x
+      movq [X+0x00],mm0
+      movq [X+0x08],mm0
+      movq [X+0x10],mm0
+      movq [X+0x18],mm0
     }
+#undef  X
   }
 }
 
@@ -547,18 +544,16 @@ static void oc_idct8x8_10(ogg_int16_t _y[64],ogg_int16_t _x[64]){
 #undef  Y
 #undef  X
   }
-  if(_x!=_y){
 #define X ecx
-    __asm{
-      pxor mm0,mm0;
-      mov X,_x
-      movq [X+0x00],mm0
-      movq [X+0x10],mm0
-      movq [X+0x20],mm0
-      movq [X+0x30],mm0
-    }
-#undef  X
+  __asm{
+    pxor mm0,mm0;
+    mov X,_x
+    movq [X+0x00],mm0
+    movq [X+0x10],mm0
+    movq [X+0x20],mm0
+    movq [X+0x30],mm0
   }
+#undef  X
 }
 
 /*Performs an inverse 8x8 Type-II DCT transform.
diff --git a/media/libtheora/lib/x86_vc/mmxstate.c b/media/libtheora/lib/x86_vc/mmxstate.c
index d3d468d5f2c63..f532ee1b6f5ab 100644
--- a/media/libtheora/lib/x86_vc/mmxstate.c
+++ b/media/libtheora/lib/x86_vc/mmxstate.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: mmxstate.c 17563 2010-10-25 17:40:54Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/x86_vc/x86cpu.c b/media/libtheora/lib/x86_vc/x86cpu.c
index 41f4bcba9ddd8..6a1d8d850cb3d 100644
--- a/media/libtheora/lib/x86_vc/x86cpu.c
+++ b/media/libtheora/lib/x86_vc/x86cpu.c
@@ -14,7 +14,7 @@
   Originally written by Rudolf Marek.
 
  function:
-  last mod: $Id: x86cpu.c 17410 2010-09-21 21:53:48Z tterribe $
+  last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/x86_vc/x86cpu.h b/media/libtheora/lib/x86_vc/x86cpu.h
index 327d9324679c4..eea261d4489e1 100644
--- a/media/libtheora/lib/x86_vc/x86cpu.h
+++ b/media/libtheora/lib/x86_vc/x86cpu.h
@@ -10,7 +10,7 @@
  *                                                                  *
  ********************************************************************
  function:
-    last mod: $Id: x86cpu.h 17410 2010-09-21 21:53:48Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/x86_vc/x86int.h b/media/libtheora/lib/x86_vc/x86int.h
index bc4c54a2f6ff6..318a09dca00f6 100644
--- a/media/libtheora/lib/x86_vc/x86int.h
+++ b/media/libtheora/lib/x86_vc/x86int.h
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: x86int.h 17410 2010-09-21 21:53:48Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/lib/x86_vc/x86state.c b/media/libtheora/lib/x86_vc/x86state.c
index 7aa73deae4c41..fa3a0d42fcc48 100644
--- a/media/libtheora/lib/x86_vc/x86state.c
+++ b/media/libtheora/lib/x86_vc/x86state.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function:
-    last mod: $Id: x86state.c 17410 2010-09-21 21:53:48Z tterribe $
+    last mod: $Id$
 
  ********************************************************************/
 
diff --git a/media/libtheora/moz.build b/media/libtheora/moz.build
index 7c4d242ba030e..cba454726ff35 100644
--- a/media/libtheora/moz.build
+++ b/media/libtheora/moz.build
@@ -10,7 +10,6 @@ with Files('*'):
 EXPORTS.theora += [
     'include/theora/codec.h',
     'include/theora/theoradec.h',
-    'include/theora/theoraenc.h',
 ]
 
 # We allow warnings for third-party code that can be updated from upstream.
diff --git a/media/libtheora/moz.yaml b/media/libtheora/moz.yaml
index 5f2ca1a43cf67..c075c5fecef09 100644
--- a/media/libtheora/moz.yaml
+++ b/media/libtheora/moz.yaml
@@ -17,5 +17,5 @@ origin:
   url: "https://www.theora.org/"
   license: "BSD-3-Clause-Clear"
 
-  # update.sh will update this value
-  release: "74b57560775804bf248e3e5b4e57964112ccd7af (2010-10-29 04:21:26 +0000)"
+  release: commit 7180717276af1ebc7da15c83162d6c5d6203aabf (2020-10-27T09:17:42.000-07:00).
+  revision: 7180717276af1ebc7da15c83162d6c5d6203aabf

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tbb-commits mailing list