[xiph-commits] r13256 - in trunk/theora: include/theora lib/enc

maikmerten at svn.xiph.org maikmerten at svn.xiph.org
Fri Jul 13 12:55:15 PDT 2007


Author: maikmerten
Date: 2007-07-13 12:55:15 -0700 (Fri, 13 Jul 2007)
New Revision: 13256

Modified:
   trunk/theora/include/theora/theora.h
   trunk/theora/lib/enc/codec_internal.h
   trunk/theora/lib/enc/dct_decode.c
   trunk/theora/lib/enc/encoder_quant.c
   trunk/theora/lib/enc/encoder_toplevel.c
Log:
first iteration of theora_control() support. Apps now can provide their own
th_quant_info data or ask the encoder to switch to VP3 profile (that's currently
the default anyway).

Cleaned up some underscore-prefixed variable names that were inherited from theora-exp

Got rid of PROFILE_FULL and PROFILE_VP3 - those weren't exposed in the API. Now apps
can use theora_control() to get something equivalent to PROFILE_VP3. If the apps want
"PROFILE_FULL" (that was a 6 quant table thingie) they can just provide the necessary
data.

Modified: trunk/theora/include/theora/theora.h
===================================================================
--- trunk/theora/include/theora/theora.h	2007-07-13 15:35:29 UTC (rev 13255)
+++ trunk/theora/include/theora/theora.h	2007-07-13 19:55:15 UTC (rev 13256)
@@ -286,6 +286,153 @@
 
 } theora_comment;
 
+
+/**\name theora_control() codes
+ * \anchor encctlcodes
+ * These are the available request codes for theora_control().
+ * 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_FAULT  \a theora_state 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_IMPL   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.
+ * For the current encoder, <tt>scale[ci!=0][qi]</tt> must be no greater than
+ *  <tt>scale[ci!=0][qi-1]</tt> and <tt>base[qti][pli][qi][ci]</tt> must be no
+ *  greater than <tt>base[qti][pli][qi-1][ci]</tt>.
+ * These two conditions ensure that the actual quantizer for a given \a qti,
+ *  \a pli, and \a ci does not increase as \a qi increases.
+ *
+ * \param[in] buf #th_quant_info
+ * \retval TH_FAULT  \a theora_state is <tt>NULL</tt>.
+ * \retval TH_EINVAL Encoding has already begun, the quantization parameters
+ *                    do not meet one of the above stated conditions, \a buf
+ *                    is <tt>NULL</tt> and \a buf_sz is not zero, or \a buf
+ *                    is non-<tt>NULL</tt> and \a buf_sz is not
+ *                    <tt>sizeof(#th_quant_info)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#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_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(ogg_uint32_t)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#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-level QI values and not using 4MV mode
+ *  when any of the luma blocks in a macro block are not coded.
+ * It also includes using the VP3 quantization tables and Huffman codes; if you
+ *  set them explicitly after calling this function, the resulting stream will
+ *  not be VP3-compatible.
+ * If you enable VP3-compatibility when encoding 4:2:2 or 4:4:4 source
+ *  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_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_VP3_COMPATIBLE (10)
+/**Gets the maximum speed level.
+ * Higher speed levels favor quicker encoding over better quality per bit.
+ * Depending on the encoding mode, and the internal algorithms used, quality
+ *  may actually improve, but in this case bitrate will also likely increase.
+ * In any case, overall rate/distortion performance will probably decrease.
+ * The maximum value, and the meaning of each value, may change depending on
+ *  the current encoding mode (VBR vs. CQI, etc.).
+ *
+ * \param[out] buf int: The maximum encoding speed level.
+ * \retval TH_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_GET_SPLEVEL_MAX (12)
+/**Sets the speed level.
+ * By default, the slowest speed (0) is used.
+ *
+ * \param[in] buf int: The new encoding speed level.
+ *                      0 is slowest, larger values use less CPU.
+ * \retval TH_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>, or the
+ *                    encoding speed level is out of bounds.
+ *                   The maximum encoding speed level may be
+ *                    implementation- and encoding mode-specific, and can be
+ *                    obtained via #TH_ENCCTL_GET_SPLEVEL_MAX.
+ * \retval TH_IMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_SET_SPLEVEL (14)
+/**Puts the encoder in VBR mode.
+ * This can be done at any time during the encoding process, with different
+ *  configuration parameters, to encode different regions of the video segment
+ *  with different qualities.
+ * See the #th_info struct documentation for details on how the default
+ *  encoding mode is chosen.
+ *
+ * \param[in] buf <tt>#th_vbr_cfg</tt>: the configuration parameters.
+ *                 This may be <tt>NULL</tt>, in which case the current VBR
+ *                  configuration is unchanged.
+ *                 The default is to use the QI setting passed in via the
+ *                  #th_info struct when the encoder was initialized, with a
+ *                  full range of admissible quantizers.
+ * \retval OC_EFAULT \a theora_state is <tt>NULL</tt>.
+ * \retval TH_EINVAL The configuration parameters do not meet one of their
+ *                    stated requirements, \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_vbr_cfg)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SETUP_VBR (16)
+/**Puts the encoder in CQI mode.
+ * This can be done at any time during the encoding process, with different QI
+ *  values.
+ * See the #th_info struct documentation for details on how the default
+ *  encoding mode is chosen.
+ *
+ * \param[in] buf <tt>#th_cqi_cfg</tt>: the configuration parameters.
+ *                 This may be <tt>NULL</tt>, in which case the current CQI
+ *                  configuration is unchanged.
+ *                 The default is to use the QI setting passed in via the
+ *                  #th_info struct when the encoder was initialized.
+ * \retval OC_EFAULT \a theora_state is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(#th_cqi_cfg)</tt>.
+ * \retval TH_IMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SETUP_CQI (18)
+/*@}*/
+
 #define OC_FAULT       -1       /**< General failure */
 #define OC_EINVAL      -10      /**< Library encountered invalid internal data */
 #define OC_DISABLED    -11      /**< Requested action is disabled */
@@ -628,6 +775,16 @@
  **/
 extern void  theora_comment_clear(theora_comment *tc);
 
+/**Encoder control function.
+ * This is used to provide advanced control the encoding process.
+ * \param th     A #theora_state handle.
+ * \param req    The control code to process.
+ *                See \ref encctlcodes "the list of available control codes"
+ *                 for details.
+ * \param buf    The parameters for this control code.
+ * \param buf_sz The size of the parameter buffer.*/
+extern int theora_control(theora_state *th,int req,void *buf,size_t buf_sz);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: trunk/theora/lib/enc/codec_internal.h
===================================================================
--- trunk/theora/lib/enc/codec_internal.h	2007-07-13 15:35:29 UTC (rev 13255)
+++ trunk/theora/lib/enc/codec_internal.h	2007-07-13 19:55:15 UTC (rev 13256)
@@ -57,12 +57,6 @@
   BLOCK_INTER_V
 };
 
-/* Encoding profiles */
-enum EncodingProfiles {
-  PROFILE_VP3,
-  PROFILE_FULL
-};
-
 /* Baseline dct block size */
 #define BLOCK_SIZE              (BLOCK_HEIGHT_WIDTH * BLOCK_HEIGHT_WIDTH)
 
@@ -303,6 +297,10 @@
 typedef struct PB_INSTANCE {
   oggpack_buffer *opb;
   theora_info     info;
+  
+  /* flag to indicate if the headers already have been written */
+  int            HeadersWritten;
+  
   /* how far do we shift the granulepos to seperate out P frame counts? */
   int             keyframe_granule_shift;
 
@@ -470,9 +468,6 @@
   /* Loop filter bounding values */
   ogg_int16_t    FiltBoundingValue[256];
 
-  /* encoder profiles differ by their quantization table usage */
-  int            encoder_profile;
-
   /* Naming convention for all quant matrices and related data structures:
    * Fields containing "Inter" in their name are for Inter frames, the
    * rest is Intra. */
@@ -497,7 +492,7 @@
   unsigned char *HuffCodeLengthArray_VP3x[NUM_HUFF_TABLES];
   const unsigned char *ExtraBitLengths_VP3x;
 
-  th_quant_info  *quant_info;
+  th_quant_info  quant_info;
   ogg_uint16_t   quant_tables[2][3][64][64];
 
   /* Quantiser and rounding tables */
@@ -786,7 +781,7 @@
 extern void InitFrameDetails(PB_INSTANCE *pbi);
 extern void WriteQTables(PB_INSTANCE *pbi,oggpack_buffer *opb);
 extern void InitQTables( PB_INSTANCE *pbi );
-extern void quant_tables_init( PB_INSTANCE *pbi, const th_quant_info *_qinfo);
+extern void quant_tables_init( PB_INSTANCE *pbi, const th_quant_info *qinfo);
 extern void InitHuffmanSet( PB_INSTANCE *pbi );
 extern void ClearHuffmanSet( PB_INSTANCE *pbi );
 extern int  ReadHuffmanTrees(codec_setup_info *ci, oggpack_buffer *opb);

Modified: trunk/theora/lib/enc/dct_decode.c
===================================================================
--- trunk/theora/lib/enc/dct_decode.c	2007-07-13 15:35:29 UTC (rev 13255)
+++ trunk/theora/lib/enc/dct_decode.c	2007-07-13 19:55:15 UTC (rev 13256)
@@ -66,7 +66,7 @@
 void SetupLoopFilter(PB_INSTANCE *pbi){
   ogg_int32_t FLimit;
 
-  FLimit = pbi->quant_info->loop_filter_limits[pbi->FrameQIndex];
+  FLimit = pbi->quant_info.loop_filter_limits[pbi->FrameQIndex];
   SetupBoundingValueArray_Generic(pbi, FLimit);
 }
 
@@ -701,12 +701,12 @@
   QIndex = Q_TABLE_SIZE - 1;
   while ( QIndex >= 0 ) {
     if ( (QIndex == 0) ||
-         ( pbi->quant_info->ac_scale[QIndex] >= pbi->ThisFrameQualityValue) )
+         ( pbi->quant_info.ac_scale[QIndex] >= pbi->ThisFrameQualityValue) )
       break;
     QIndex --;
   }
 
-  FLimit = pbi->quant_info->loop_filter_limits[QIndex];
+  FLimit = pbi->quant_info.loop_filter_limits[QIndex];
   if ( FLimit == 0 ) return;
   SetupBoundingValueArray_Generic(pbi, FLimit);
 

Modified: trunk/theora/lib/enc/encoder_quant.c
===================================================================
--- trunk/theora/lib/enc/encoder_quant.c	2007-07-13 15:35:29 UTC (rev 13255)
+++ trunk/theora/lib/enc/encoder_quant.c	2007-07-13 19:55:15 UTC (rev 13256)
@@ -20,127 +20,10 @@
 #include "codec_internal.h"
 #include "quant_lookup.h"
 
-/*
- * th_quant_info for VP3 
- */
- 
-/*The default quantization parameters used by VP3.1.*/
-static const int OC_VP31_RANGE_SIZES[1]={63};
-static const th_quant_base OC_VP31_BASES_INTRA_Y[2]={
-  {
-     16, 11, 10, 16, 24,  40, 51, 61,
-     12, 12, 14, 19, 26,  58, 60, 55,
-     14, 13, 16, 24, 40,  57, 69, 56,
-     14, 17, 22, 29, 51,  87, 80, 62,
-     18, 22, 37, 58, 68, 109,103, 77,
-     24, 35, 55, 64, 81, 104,113, 92,
-     49, 64, 78, 87,103, 121,120,101,
-     72, 92, 95, 98,112, 100,103, 99
-  },
-  {
-     16, 11, 10, 16, 24,  40, 51, 61,
-     12, 12, 14, 19, 26,  58, 60, 55,
-     14, 13, 16, 24, 40,  57, 69, 56,
-     14, 17, 22, 29, 51,  87, 80, 62,
-     18, 22, 37, 58, 68, 109,103, 77,
-     24, 35, 55, 64, 81, 104,113, 92,
-     49, 64, 78, 87,103, 121,120,101,
-     72, 92, 95, 98,112, 100,103, 99
-  }
-};
-static const th_quant_base OC_VP31_BASES_INTRA_C[2]={
-  {
-     17, 18, 24, 47, 99, 99, 99, 99,
-     18, 21, 26, 66, 99, 99, 99, 99,
-     24, 26, 56, 99, 99, 99, 99, 99,
-     47, 66, 99, 99, 99, 99, 99, 99,
-     99, 99, 99, 99, 99, 99, 99, 99,
-     99, 99, 99, 99, 99, 99, 99, 99,
-     99, 99, 99, 99, 99, 99, 99, 99,
-     99, 99, 99, 99, 99, 99, 99, 99
-  },
-  {
-     17, 18, 24, 47, 99, 99, 99, 99,
-     18, 21, 26, 66, 99, 99, 99, 99,
-     24, 26, 56, 99, 99, 99, 99, 99,
-     47, 66, 99, 99, 99, 99, 99, 99,
-     99, 99, 99, 99, 99, 99, 99, 99,
-     99, 99, 99, 99, 99, 99, 99, 99,
-     99, 99, 99, 99, 99, 99, 99, 99,
-     99, 99, 99, 99, 99, 99, 99, 99
-  }
-};
-static const th_quant_base OC_VP31_BASES_INTER[2]={
-  {
-     16, 16, 16, 20, 24, 28, 32, 40,
-     16, 16, 20, 24, 28, 32, 40, 48,
-     16, 20, 24, 28, 32, 40, 48, 64,
-     20, 24, 28, 32, 40, 48, 64, 64,
-     24, 28, 32, 40, 48, 64, 64, 64,
-     28, 32, 40, 48, 64, 64, 64, 96,
-     32, 40, 48, 64, 64, 64, 96,128,
-     40, 48, 64, 64, 64, 96,128,128
-  },
-  {
-     16, 16, 16, 20, 24, 28, 32, 40,
-     16, 16, 20, 24, 28, 32, 40, 48,
-     16, 20, 24, 28, 32, 40, 48, 64,
-     20, 24, 28, 32, 40, 48, 64, 64,
-     24, 28, 32, 40, 48, 64, 64, 64,
-     28, 32, 40, 48, 64, 64, 64, 96,
-     32, 40, 48, 64, 64, 64, 96,128,
-     40, 48, 64, 64, 64, 96,128,128
-  }
-};
 
-const th_quant_info TH_VP31_QUANT_INFO={
-  {
-    220,200,190,180,170,170,160,160,
-    150,150,140,140,130,130,120,120,
-    110,110,100,100, 90, 90, 90, 80,
-     80, 80, 70, 70, 70, 60, 60, 60,
-     60, 50, 50, 50, 50, 40, 40, 40,
-     40, 40, 30, 30, 30, 30, 30, 30,
-     30, 20, 20, 20, 20, 20, 20, 20,
-     20, 10, 10, 10, 10, 10, 10, 10
-  },
-  {
-    500,450,400,370,340,310,285,265,
-    245,225,210,195,185,180,170,160,
-    150,145,135,130,125,115,110,107,
-    100, 96, 93, 89, 85, 82, 75, 74,
-     70, 68, 64, 60, 57, 56, 52, 50,
-     49, 45, 44, 43, 40, 38, 37, 35,
-     33, 32, 30, 29, 28, 25, 24, 22,
-     21, 19, 18, 17, 15, 13, 12, 10
-  },
-  {
-    30,25,20,20,15,15,14,14,
-    13,13,12,12,11,11,10,10,
-     9, 9, 8, 8, 7, 7, 7, 7,
-     6, 6, 6, 6, 5, 5, 5, 5,
-     4, 4, 4, 4, 3, 3, 3, 3,
-     2, 2, 2, 2, 2, 2, 2, 2,
-     0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 0
-  },
-  {
-    {
-      {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTRA_Y},
-      {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTRA_C},
-      {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTRA_C}
-    },
-    {
-      {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTER},
-      {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTER},
-      {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTER}
-    }
-  }
-};
-
 void WriteQTables(PB_INSTANCE *pbi,oggpack_buffer* _opb) {
   
-  th_quant_info *_qinfo = pbi->quant_info; 
+  th_quant_info *_qinfo = &pbi->quant_info; 
   
   const th_quant_ranges *qranges;
   const th_quant_base   *base_mats[2*3*64];
@@ -245,22 +128,9 @@
     better. */
 void InitQTables( PB_INSTANCE *pbi ){
     
-  switch(pbi->encoder_profile) {
-  	case PROFILE_FULL:
-  	
-  	  pbi->quant_info = (th_quant_info *) &TH_VP31_QUANT_INFO;
-      
-      break;
-    default: /* VP3 */
-      
-      pbi->quant_info = (th_quant_info *) &TH_VP31_QUANT_INFO;
-      
-      break;
-  }
-    
-  pbi->QThreshTable = pbi->quant_info->ac_scale;
+  pbi->QThreshTable = pbi->quant_info.ac_scale;
   
-  quant_tables_init(pbi, pbi->quant_info);
+  quant_tables_init(pbi, &pbi->quant_info);
 }
 
 static void BuildZigZagIndex(PB_INSTANCE *pbi){
@@ -274,7 +144,7 @@
 }
 
 /* this is a butchered version of derf's theora-exp code */
-void quant_tables_init(PB_INSTANCE *pbi, const th_quant_info *_qinfo){
+void quant_tables_init(PB_INSTANCE *pbi, const th_quant_info *qinfo){
   int          qti;
   int          pli;
   for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){
@@ -291,7 +161,7 @@
       pbi->quant_tables[qti][pli]=pbi->quant_tables[qti-1][pli];
       continue;
     }*/
-    for(qi=qri=0;qri<=_qinfo->qi_ranges[qti][pli].nranges;qri++){
+    for(qi=qri=0;qri<=qinfo->qi_ranges[qti][pli].nranges;qri++){
       int i;
       ogg_uint16_t  base[64];
       int           qi_start;
@@ -299,11 +169,11 @@
       int           ci;
 
       for(i = 0; i < 64; i++)
-        base[i] = _qinfo->qi_ranges[qti][pli].base_matrices[qri][i];
+        base[i] = qinfo->qi_ranges[qti][pli].base_matrices[qri][i];
 
       qi_start=qi;
-      if(qri==_qinfo->qi_ranges[qti][pli].nranges)qi_end=qi+1;
-      else qi_end=qi+_qinfo->qi_ranges[qti][pli].sizes[qri];
+      if(qri==qinfo->qi_ranges[qti][pli].nranges)qi_end=qi+1;
+      else qi_end=qi+qinfo->qi_ranges[qti][pli].sizes[qri];
       for(;;){
                
         memcpy(pbi->quant_tables[qti][pli][qi], base, sizeof(base));
@@ -312,10 +182,10 @@
         /*Interpolate the next base matrix.*/
         for(ci=0;ci<64;ci++){
           base[ci]=(unsigned char)(
-           (2*((qi_end-qi)*_qinfo->qi_ranges[qti][pli].base_matrices[qri][ci]+
-           (qi-qi_start)*_qinfo->qi_ranges[qti][pli].base_matrices[qri+1][ci])
-           +_qinfo->qi_ranges[qti][pli].sizes[qri])/
-           (2*_qinfo->qi_ranges[qti][pli].sizes[qri]));
+           (2*((qi_end-qi)*qinfo->qi_ranges[qti][pli].base_matrices[qri][ci]+
+           (qi-qi_start)*qinfo->qi_ranges[qti][pli].base_matrices[qri+1][ci])
+           +qinfo->qi_ranges[qti][pli].sizes[qri])/
+           (2*qinfo->qi_ranges[qti][pli].sizes[qri]));
         }
       }
     }
@@ -355,7 +225,7 @@
     temp_Inter_Y_coeffs = pbi->quant_tables[1][0][QIndex];
     temp_Inter_U_coeffs = pbi->quant_tables[1][1][QIndex];
     temp_Inter_V_coeffs = pbi->quant_tables[1][2][QIndex];
-    temp_DcScaleFactorTable = pbi->quant_info->dc_scale;
+    temp_DcScaleFactorTable = pbi->quant_info.dc_scale;
     
     ZBinFactor = 0.9;
 
@@ -676,7 +546,7 @@
   InterY_coeffs = pbi->quant_tables[1][0][QIndex];
   InterU_coeffs = pbi->quant_tables[1][1][QIndex];
   InterV_coeffs = pbi->quant_tables[1][2][QIndex];
-  DcScaleFactorTable = pbi->quant_info->dc_scale;
+  DcScaleFactorTable = pbi->quant_info.dc_scale;
 
   /* invert the dequant index into the quant index
      the dxer has a different order than the cxer. */
@@ -809,7 +679,7 @@
 
   pbi->FrameQIndex = NewQIndex;
   
-  qscale = pbi->quant_info->ac_scale[NewQIndex];
+  qscale = pbi->quant_info.ac_scale[NewQIndex];
   pbi->ThisFrameQualityValue = qscale;
 
   /* Re-initialise the Q tables for forward and reverse transforms. */
@@ -822,16 +692,16 @@
 
   /* Do bounds checking and convert to a float.  */
   qscale = NewQ;
-  if ( qscale < pbi->quant_info->ac_scale[Q_TABLE_SIZE-1] )
-    qscale = pbi->quant_info->ac_scale[Q_TABLE_SIZE-1];
-  else if ( qscale > pbi->quant_info->ac_scale[0] )
-    qscale = pbi->quant_info->ac_scale[0];
+  if ( qscale < pbi->quant_info.ac_scale[Q_TABLE_SIZE-1] )
+    qscale = pbi->quant_info.ac_scale[Q_TABLE_SIZE-1];
+  else if ( qscale > pbi->quant_info.ac_scale[0] )
+    qscale = pbi->quant_info.ac_scale[0];
 
   /* Set the inter/intra descision control variables. */
   pbi->FrameQIndex = Q_TABLE_SIZE - 1;
   while ((ogg_int32_t) pbi->FrameQIndex >= 0 ) {
     if ( (pbi->FrameQIndex == 0) ||
-         ( pbi->quant_info->ac_scale[pbi->FrameQIndex] >= NewQ) )
+         ( pbi->quant_info.ac_scale[pbi->FrameQIndex] >= NewQ) )
       break;
     pbi->FrameQIndex --;
   }

Modified: trunk/theora/lib/enc/encoder_toplevel.c
===================================================================
--- trunk/theora/lib/enc/encoder_toplevel.c	2007-07-13 15:35:29 UTC (rev 13255)
+++ trunk/theora/lib/enc/encoder_toplevel.c	2007-07-13 19:55:15 UTC (rev 13256)
@@ -29,7 +29,125 @@
 #define A_TABLE_SIZE        29
 #define DF_CANDIDATE_WINDOW 5
 
+/*
+ * th_quant_info for VP3 
+ */
+ 
+/*The default quantization parameters used by VP3.1.*/
+static const int OC_VP31_RANGE_SIZES[1]={63};
+static const th_quant_base OC_VP31_BASES_INTRA_Y[2]={
+  {
+     16, 11, 10, 16, 24,  40, 51, 61,
+     12, 12, 14, 19, 26,  58, 60, 55,
+     14, 13, 16, 24, 40,  57, 69, 56,
+     14, 17, 22, 29, 51,  87, 80, 62,
+     18, 22, 37, 58, 68, 109,103, 77,
+     24, 35, 55, 64, 81, 104,113, 92,
+     49, 64, 78, 87,103, 121,120,101,
+     72, 92, 95, 98,112, 100,103, 99
+  },
+  {
+     16, 11, 10, 16, 24,  40, 51, 61,
+     12, 12, 14, 19, 26,  58, 60, 55,
+     14, 13, 16, 24, 40,  57, 69, 56,
+     14, 17, 22, 29, 51,  87, 80, 62,
+     18, 22, 37, 58, 68, 109,103, 77,
+     24, 35, 55, 64, 81, 104,113, 92,
+     49, 64, 78, 87,103, 121,120,101,
+     72, 92, 95, 98,112, 100,103, 99
+  }
+};
+static const th_quant_base OC_VP31_BASES_INTRA_C[2]={
+  {
+     17, 18, 24, 47, 99, 99, 99, 99,
+     18, 21, 26, 66, 99, 99, 99, 99,
+     24, 26, 56, 99, 99, 99, 99, 99,
+     47, 66, 99, 99, 99, 99, 99, 99,
+     99, 99, 99, 99, 99, 99, 99, 99,
+     99, 99, 99, 99, 99, 99, 99, 99,
+     99, 99, 99, 99, 99, 99, 99, 99,
+     99, 99, 99, 99, 99, 99, 99, 99
+  },
+  {
+     17, 18, 24, 47, 99, 99, 99, 99,
+     18, 21, 26, 66, 99, 99, 99, 99,
+     24, 26, 56, 99, 99, 99, 99, 99,
+     47, 66, 99, 99, 99, 99, 99, 99,
+     99, 99, 99, 99, 99, 99, 99, 99,
+     99, 99, 99, 99, 99, 99, 99, 99,
+     99, 99, 99, 99, 99, 99, 99, 99,
+     99, 99, 99, 99, 99, 99, 99, 99
+  }
+};
+static const th_quant_base OC_VP31_BASES_INTER[2]={
+  {
+     16, 16, 16, 20, 24, 28, 32, 40,
+     16, 16, 20, 24, 28, 32, 40, 48,
+     16, 20, 24, 28, 32, 40, 48, 64,
+     20, 24, 28, 32, 40, 48, 64, 64,
+     24, 28, 32, 40, 48, 64, 64, 64,
+     28, 32, 40, 48, 64, 64, 64, 96,
+     32, 40, 48, 64, 64, 64, 96,128,
+     40, 48, 64, 64, 64, 96,128,128
+  },
+  {
+     16, 16, 16, 20, 24, 28, 32, 40,
+     16, 16, 20, 24, 28, 32, 40, 48,
+     16, 20, 24, 28, 32, 40, 48, 64,
+     20, 24, 28, 32, 40, 48, 64, 64,
+     24, 28, 32, 40, 48, 64, 64, 64,
+     28, 32, 40, 48, 64, 64, 64, 96,
+     32, 40, 48, 64, 64, 64, 96,128,
+     40, 48, 64, 64, 64, 96,128,128
+  }
+};
 
+const th_quant_info TH_VP31_QUANT_INFO={
+  {
+    220,200,190,180,170,170,160,160,
+    150,150,140,140,130,130,120,120,
+    110,110,100,100, 90, 90, 90, 80,
+     80, 80, 70, 70, 70, 60, 60, 60,
+     60, 50, 50, 50, 50, 40, 40, 40,
+     40, 40, 30, 30, 30, 30, 30, 30,
+     30, 20, 20, 20, 20, 20, 20, 20,
+     20, 10, 10, 10, 10, 10, 10, 10
+  },
+  {
+    500,450,400,370,340,310,285,265,
+    245,225,210,195,185,180,170,160,
+    150,145,135,130,125,115,110,107,
+    100, 96, 93, 89, 85, 82, 75, 74,
+     70, 68, 64, 60, 57, 56, 52, 50,
+     49, 45, 44, 43, 40, 38, 37, 35,
+     33, 32, 30, 29, 28, 25, 24, 22,
+     21, 19, 18, 17, 15, 13, 12, 10
+  },
+  {
+    30,25,20,20,15,15,14,14,
+    13,13,12,12,11,11,10,10,
+     9, 9, 8, 8, 7, 7, 7, 7,
+     6, 6, 6, 6, 5, 5, 5, 5,
+     4, 4, 4, 4, 3, 3, 3, 3,
+     2, 2, 2, 2, 2, 2, 2, 2,
+     0, 0, 0, 0, 0, 0, 0, 0,
+     0, 0, 0, 0, 0, 0, 0, 0
+  },
+  {
+    {
+      {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTRA_Y},
+      {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTRA_C},
+      {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTRA_C}
+    },
+    {
+      {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTER},
+      {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTER},
+      {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTER}
+    }
+  }
+};
+
+
 static void EClearFragmentInfo(CP_INSTANCE * cpi){
   if(cpi->extra_fragments)
     _ogg_free(cpi->extra_fragments);
@@ -915,13 +1033,15 @@
   InitHuffmanSet(&cpi->pb);
 
   /* This makes sure encoder version specific tables are initialised */
-  cpi->pb.encoder_profile = PROFILE_VP3;
+  memcpy(&cpi->pb.quant_info, &TH_VP31_QUANT_INFO, sizeof(th_quant_info));
   InitQTables(&cpi->pb);
 
   /* Indicate that the next frame to be compressed is the first in the
      current clip. */
   cpi->ThisIsFirstFrame = 1;
   cpi->readyflag = 1;
+  
+  cpi->pb.HeadersWritten = 0;
 
   return 0;
 }
@@ -1200,6 +1320,8 @@
   op->granulepos=0;
   cpi->packetflag=0;
 
+  cpi->pb.HeadersWritten = 1;
+
   return(0);
 }
 
@@ -1258,3 +1380,37 @@
 
   return(-1);
 }
+
+
+int theora_control(theora_state *th,int req,void *buf,size_t buf_sz) {
+
+  if(th == NULL)
+    return TH_EFAULT;
+
+  CP_INSTANCE *cpi = th->internal_encode;
+  PB_INSTANCE *pbi = &cpi->pb;
+  
+  switch(req) {
+    case TH_ENCCTL_SET_QUANT_PARAMS:
+      if( ( buf==NULL&&buf_sz!=0 )
+  	   || ( buf!=NULL&&buf_sz!=sizeof(th_quant_info) )
+  	   || cpi->pb.HeadersWritten ){
+        return TH_EINVAL;
+      }
+      
+      memcpy(&pbi->quant_info, buf, sizeof(th_quant_info));
+      InitQTables(pbi);
+      
+      return 0;
+    case TH_ENCCTL_SET_VP3_COMPATIBLE:
+      if(cpi->pb.HeadersWritten)
+        return TH_EINVAL;
+      
+      memcpy(&pbi->quant_info, &TH_VP31_QUANT_INFO, sizeof(th_quant_info));
+      InitQTables(pbi);
+      
+      return 0;  
+    default:
+      return TH_EIMPL;
+  }
+}



More information about the commits mailing list