[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