[xiph-cvs] cvs commit: theora/lib huffman.c huffman.h hufftables.h idct.c pp.c dct_encode.c encode.c encoder_internal.h encoder_lookup.h frarray.c mcomp.c misc_common.c toplevel.c
Monty
xiphmont at xiph.org
Wed Sep 18 01:56:58 PDT 2002
xiphmont 02/09/18 04:56:57
Modified: lib dct_encode.c encode.c encoder_internal.h
encoder_lookup.h frarray.c mcomp.c misc_common.c
toplevel.c
Added: lib huffman.c huffman.h hufftables.h idct.c pp.c
Log:
Avoid losing work
Revision Changes Path
1.2 +109 -106 theora/lib/dct_encode.c
Index: dct_encode.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/dct_encode.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- dct_encode.c 16 Sep 2002 07:10:02 -0000 1.1
+++ dct_encode.c 18 Sep 2002 08:56:56 -0000 1.2
@@ -11,10 +11,14 @@
********************************************************************
function:
- last mod: $Id: dct_encode.c,v 1.1 2002/09/16 07:10:02 xiphmont Exp $
+ last mod: $Id: dct_encode.c,v 1.2 2002/09/18 08:56:56 xiphmont Exp $
********************************************************************/
+#include "encoder_internal.h"
+
+int ModeUsesMC[MAX_MODES] = { 0, 0, 1, 1, 1, 0, 1, 1 };
+
void SUB8 (unsigned char *FiltPtr, unsigned char *ReconPtr,
ogg_int16_t *DctInputPtr, unsigned char *old_ptr1,
unsigned char *new_ptr1, ogg_uint32_t PixelsPerLine,
@@ -115,110 +119,7 @@
}
}
-ogg_uint32_t DPCMTokenizeBlock (CP_INSTANCE *cpi, ogg_int32_t FragIndex,
- ogg_uint32_t PixelsPerLine ) {
- ogg_uint32_t token_count;
- Q_LIST_ENTRY TempLastDC = 0;
-
-
- if ( GetFrameType(&cpi->pb) == BASE_FRAME ){
- /* Key frame so code block in INTRA mode. */
- cpi->pb.CodingMode = CODE_INTRA;
- }else{
- /* Get Motion vector and mode for this block. */
- cpi->pb.CodingMode = cpi->pb.FragCodingMethod[FragIndex];
- }
-
- /* Tokenise the dct data. */
- token_count = TokenizeDctBlock( cpi->pb.QFragData[FragIndex],
- cpi->pb.TokenList[FragIndex] );
-
- cpi->FragTokenCounts[FragIndex] = token_count;
- cpi->TotTokenCount += token_count;
-
- /* Return number of pixels coded (i.e. 8x8). */
- return BLOCK_SIZE;
-}
-
-int AllZeroDctData( Q_LIST_ENTRY * QuantList ){
- ogg_uint32_t i;
-
- for ( i = 0; i < 64; i ++ )
- if ( QuantList[i] != 0 )
- return 0;
-
- return 1;
-}
-
-unsigned char TokenizeDctBlock (ogg_int16_t * RawData,
- ogg_uint32_t * TokenListPtr ) {
- ogg_uint32_t i;
- unsigned char run_count;
- unsigned char token_count = 0; /* Number of tokens crated. */
- ogg_uint32_t AbsData;
-
-
- /* Tokenize the block */
- for( i = 0; i < BLOCK_SIZE; i++ ){
- run_count = 0;
-
- /* Look for a zero run. */
- /* NOTE the use of & instead of && which is faster (and
- equivalent) in this instance. */
- while( (i < BLOCK_SIZE) & (!RawData[i]) ){
- run_count++;
- i++;
- }
-
- /* If we have reached the end of the block then code EOB */
- if ( i == BLOCK_SIZE ){
- TokenListPtr[token_count] = DCT_EOB_TOKEN;
- token_count++;
- }else{
- /* If we have a short zero run followed by a low data value code
- the two as a composite token. */
- if ( run_count ){
- AbsData = abs(RawData[i]);
-
- if ( ((AbsData == 1) && (run_count <= 17)) ||
- ((AbsData <= 3) && (run_count <= 3)) ) {
- /* Tokenise the run and subsequent value combination value */
- token_count += TokenizeDctRunValue( run_count,
- RawData[i],
- &TokenListPtr[token_count] );
- }else{
-
- /* Else if we have a long non-EOB run or a run followed by a
- value token > MAX_RUN_VAL then code the run and token
- seperately */
- if ( run_count <= 8 )
- TokenListPtr[token_count] = DCT_SHORT_ZRL_TOKEN;
- else
- TokenListPtr[token_count] = DCT_ZRL_TOKEN;
-
- token_count++;
- TokenListPtr[token_count] = run_count - 1;
- token_count++;
-
- /* Now tokenize the value */
- token_count += TokenizeDctValue( RawData[i],
- &TokenListPtr[token_count] );
- }
- }else{
- /* Else there was NO zero run. */
- /* Tokenise the value */
- token_count += TokenizeDctValue( RawData[i],
- &TokenListPtr[token_count] );
- }
- }
- }
-
- /* Return the total number of tokens (including additional bits
- tokens) used. */
- return token_count;
-}
-
-unsigned char TokenizeDctValue (ogg_int16_t DataValue,
+unsigned char TokenizeDctValue (ogg_int16_t DataValue,
ogg_uint32_t * TokenListPtr ){
unsigned char tokens_added = 0;
ogg_uint32_t AbsDataVal = abs( (ogg_int32_t)DataValue );
@@ -376,6 +277,109 @@
return tokens_added;
}
+unsigned char TokenizeDctBlock (ogg_int16_t * RawData,
+ ogg_uint32_t * TokenListPtr ) {
+ ogg_uint32_t i;
+ unsigned char run_count;
+ unsigned char token_count = 0; /* Number of tokens crated. */
+ ogg_uint32_t AbsData;
+
+
+ /* Tokenize the block */
+ for( i = 0; i < BLOCK_SIZE; i++ ){
+ run_count = 0;
+
+ /* Look for a zero run. */
+ /* NOTE the use of & instead of && which is faster (and
+ equivalent) in this instance. */
+ while( (i < BLOCK_SIZE) & (!RawData[i]) ){
+ run_count++;
+ i++;
+ }
+
+ /* If we have reached the end of the block then code EOB */
+ if ( i == BLOCK_SIZE ){
+ TokenListPtr[token_count] = DCT_EOB_TOKEN;
+ token_count++;
+ }else{
+ /* If we have a short zero run followed by a low data value code
+ the two as a composite token. */
+ if ( run_count ){
+ AbsData = abs(RawData[i]);
+
+ if ( ((AbsData == 1) && (run_count <= 17)) ||
+ ((AbsData <= 3) && (run_count <= 3)) ) {
+ /* Tokenise the run and subsequent value combination value */
+ token_count += TokenizeDctRunValue( run_count,
+ RawData[i],
+ &TokenListPtr[token_count] );
+ }else{
+
+ /* Else if we have a long non-EOB run or a run followed by a
+ value token > MAX_RUN_VAL then code the run and token
+ seperately */
+ if ( run_count <= 8 )
+ TokenListPtr[token_count] = DCT_SHORT_ZRL_TOKEN;
+ else
+ TokenListPtr[token_count] = DCT_ZRL_TOKEN;
+
+ token_count++;
+ TokenListPtr[token_count] = run_count - 1;
+ token_count++;
+
+ /* Now tokenize the value */
+ token_count += TokenizeDctValue( RawData[i],
+ &TokenListPtr[token_count] );
+ }
+ }else{
+ /* Else there was NO zero run. */
+ /* Tokenise the value */
+ token_count += TokenizeDctValue( RawData[i],
+ &TokenListPtr[token_count] );
+ }
+ }
+ }
+
+ /* Return the total number of tokens (including additional bits
+ tokens) used. */
+ return token_count;
+}
+
+ogg_uint32_t DPCMTokenizeBlock (CP_INSTANCE *cpi, ogg_int32_t FragIndex,
+ ogg_uint32_t PixelsPerLine ) {
+ ogg_uint32_t token_count;
+ Q_LIST_ENTRY TempLastDC = 0;
+
+
+ if ( GetFrameType(&cpi->pb) == BASE_FRAME ){
+ /* Key frame so code block in INTRA mode. */
+ cpi->pb.CodingMode = CODE_INTRA;
+ }else{
+ /* Get Motion vector and mode for this block. */
+ cpi->pb.CodingMode = cpi->pb.FragCodingMethod[FragIndex];
+ }
+
+ /* Tokenise the dct data. */
+ token_count = TokenizeDctBlock( cpi->pb.QFragData[FragIndex],
+ cpi->pb.TokenList[FragIndex] );
+
+ cpi->FragTokenCounts[FragIndex] = token_count;
+ cpi->TotTokenCount += token_count;
+
+ /* Return number of pixels coded (i.e. 8x8). */
+ return BLOCK_SIZE;
+}
+
+int AllZeroDctData( Q_LIST_ENTRY * QuantList ){
+ ogg_uint32_t i;
+
+ for ( i = 0; i < 64; i ++ )
+ if ( QuantList[i] != 0 )
+ return 0;
+
+ return 1;
+}
+
void MotionBlockDifference (CP_INSTANCE * cpi, unsigned char * FiltPtr,
ogg_int16_t *DctInputPtr, ogg_int32_t MvDevisor,
unsigned char* old_ptr1, unsigned char* new_ptr1,
@@ -570,4 +574,3 @@
}
}
-
<p><p>1.3 +1000 -999 theora/lib/encode.c
Index: encode.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/encode.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- encode.c 17 Sep 2002 07:01:33 -0000 1.2
+++ encode.c 18 Sep 2002 08:56:56 -0000 1.3
@@ -11,32 +11,14 @@
********************************************************************
function:
- last mod: $Id: encode.c,v 1.2 2002/09/17 07:01:33 xiphmont Exp $
+ last mod: $Id: encode.c,v 1.3 2002/09/18 08:56:56 xiphmont Exp $
********************************************************************/
#include "ogg/ogg.h"
-#include "encoder_lookup.h"
#include "encoder_internal.h"
-
-ogg_uint32_t EncodeData(CP_INSTANCE *cpi){
- ogg_uint32_t coded_pixels = 0;
-
- /* Zero the count of tokens so far this frame. */
- cpi->TotTokenCount = 0;
-
- /* Zero the mode and MV list indices. */
- cpi->ModeListCount = 0;
-
- /* Zero Decoder EOB run count */
- cpi->pb.EOB_Run = 0;
-
- /* Encode any fragments coded using DCT. */
- coded_pixels += QuadCodeDisplayFragments (cpi);
-
- return coded_pixels;
-
-}
+#include "encoder_lookup.h"
+#include "hufftables.h"
#define PUL 8
#define PU 4
@@ -44,89 +26,6 @@
#define PL 1
#define HIGHBITDUPPED(X) (((ogg_int16_t) X) >> 15)
-ogg_int32_t CalculateMotionErrorforFragments(CP_INSTANCE *cpi,
- ogg_int32_t CountUsingMV,
- ogg_int32_t *FragsUsing,
- MOTION_VECTOR MVect,
- ogg_int32_t PixelsPerLine){
- int i;
- ogg_int32_t NewError = 0;
-
- /* for now 4 motion vector is to hard to recalculate so return huge
- error!! */
- if( cpi->pb.FragCodingMethod[0] == CODE_INTER_FOURMV)
- return HUGE_ERROR;
-
- for(i = 0 ; i < CountUsingMV ; i++) {
- ogg_int32_t FragIndex = FragsUsing[i];
- ogg_int32_t ThisError = GetMBInterError( cpi,
- cpi->ConvDestBuffer,
- cpi->pb.LastFrameRecon,
- FragIndex, MVect.x,
- MVect.y, PixelsPerLine );
-
- NewError += ThisError;
-
- }
-
- return NewError;
-
-}
-
-ogg_uint32_t PickIntra( CP_INSTANCE *cpi, ogg_uint32_t SBRows,
- ogg_uint32_t SBCols, ogg_uint32_t HExtra,
- ogg_uint32_t VExtra, ogg_uint32_t PixelsPerLine){
-
- ogg_int32_t FragIndex; /* Fragment number */
- ogg_uint32_t MB, B; /* Macro-Block, Block indices */
- ogg_uint32_t SBrow; /* Super-Block row number */
- ogg_uint32_t SBcol; /* Super-Block row number */
- ogg_uint32_t SB=0; /* Super-Block index, initialised to first of
- this component */
-
- ogg_uint32_t UVRow;
- ogg_uint32_t UVColumn;
- ogg_uint32_t UVFragOffset;
-
- /* decide what block type and motion vectors to use on all of the frames */
- for ( SBrow=0; SBrow<SBRows; SBrow++ ) {
- for ( SBcol=0; SBcol<SBCols; SBcol++ ) {
- /* Check its four Macro-Blocks */
- for ( MB=0; MB<4; MB++ ) {
- /* There may be MB's lying out of frame which must be
- ignored. For these MB's Top left block will have a negative
- Fragment Index. */
- if ( QuadMapToMBTopLeft(cpi->pb.BlockMap,SB,MB) >= 0 ) {
-
- cpi->MBCodingMode = CODE_INTRA;
-
- /* Now actually code the blocks. */
- for ( B=0; B<4; B++ ) {
- FragIndex = QuadMapToIndex1( cpi->pb.BlockMap, SB, MB, B );
- cpi->pb.FragCodingMethod[FragIndex] = cpi->MBCodingMode;
- }
-
- /* Matching fragments in the U and V planes */
- UVRow = (FragIndex / (cpi->pb.HFragments * 2));
- UVColumn = (FragIndex % cpi->pb.HFragments) / 2;
- UVFragOffset = (UVRow * (cpi->pb.HFragments / 2)) + UVColumn;
-
- cpi->pb.FragCodingMethod[cpi->pb.YPlaneFragments + UVFragOffset] =
- cpi->MBCodingMode;
- cpi->pb.FragCodingMethod[cpi->pb.YPlaneFragments +
- cpi->pb.UVPlaneFragments + UVFragOffset] =
- cpi->MBCodingMode;
-
- }
- }
-
- /* Next Super-Block */
- SB++;
- }
- }
- return 0;
-}
-
ogg_uint32_t QuadCodeComponent ( CP_INSTANCE *cpi,
ogg_uint32_t FirstSB,
ogg_uint32_t SBRows,
@@ -201,114 +100,12 @@
}
/* system state should be cleared here.... */
- cpi->pb.ClearSysState();
+ ClearSysState();
/* Return number of pixels coded */
return coded_pixels;
}
-void PackCodedVideo (CP_INSTANCE *cpi) {
- ogg_int32_t i;
- ogg_int32_t EncodedCoeffs = 1;
- ogg_int32_t TotalTokens = cpi->TotTokenCount;
- ogg_int32_t FragIndex;
- ogg_uint32_t HuffIndex; /* Index to group of tables used to code a token */
-
- cpi->pb.ClearSysState();
-
- /* Reset the count of second order optimised tokens */
- cpi->OptimisedTokenCount = 0;
-
- cpi->TokensToBeCoded = cpi->TotTokenCount;
- cpi->TokensCoded = 0;
-
- /* Calculate the bit rate at which this frame should be capped. */
- cpi->MaxBitTarget = (ogg_uint32_t)((double)(cpi->ThisFrameTargetBytes * 8) *
- cpi->BitRateCapFactor);
-
- /* Blank the various fragment data structures before we start. */
- memset(cpi->pb.FragCoeffs, 0, cpi->pb.UnitFragments);
- memset(cpi->FragTokens, 0, cpi->pb.UnitFragments);
-
- /* Clear down the QFragData structure for all coded blocks. */
- cpi->pb.ClearDownQFrag(&cpi->pb);
-
- /* The tree is not needed (implicit) for key frames */
- if ( GetFrameType(&cpi->pb) != BASE_FRAME ){
- /* Pack the quad tree fragment mapping. */
- PackAndWriteDFArray( cpi );
- }
-
- /* Note the number of bits used to code the tree itself. */
- cpi->FrameBitCount = oggpackB_bytes(&cpi->opb) << 3;
-
- /* Mode and MV data not needed for key frames. */
- if ( GetFrameType(&cpi->pb) != BASE_FRAME ){
- /* Pack and code the mode list. */
- PackModes(cpi);
- /* Pack the motion vectors */
- PackMotionVectors (cpi);
- }
-
- cpi->FrameBitCount = oggpackB_bytes(&cpi->opb) << 3;
-
- /* Optimise the DC tokens */
- for ( i = 0; i < cpi->pb.CodedBlockIndex; i++ ) {
- /* Get the linear index for the current fragment. */
- FragIndex = cpi->pb.CodedBlockList[i];
-
- cpi->pb.FragCoefEOB[FragIndex]=EncodedCoeffs;
- PackToken(cpi, FragIndex, DC_HUFF_OFFSET );
-
- }
-
- /* Pack any outstanding EOB tokens */
- PackEOBRun(cpi);
-
- /* Now output the optimised DC token list using the appropriate
- entropy tables. */
- EncodeDcTokenList(cpi);
-
- /* Work out the number of DC bits coded */
-
- /* Optimise the AC tokens */
- while ( EncodedCoeffs < 64 ) {
- /* Huffman table adjustment based upon coefficient number. */
- if ( EncodedCoeffs <= AC_TABLE_2_THRESH )
- HuffIndex = AC_HUFF_OFFSET;
- else if ( EncodedCoeffs <= AC_TABLE_3_THRESH )
- HuffIndex = AC_HUFF_OFFSET + AC_HUFF_CHOICES;
- else if ( EncodedCoeffs <= AC_TABLE_4_THRESH )
- HuffIndex = AC_HUFF_OFFSET + (AC_HUFF_CHOICES * 2);
- else
- HuffIndex = AC_HUFF_OFFSET + (AC_HUFF_CHOICES * 3);
-
- /* Repeatedly scan through the list of blocks. */
- for ( i = 0; i < cpi->pb.CodedBlockIndex; i++ ) {
- /* Get the linear index for the current fragment. */
- FragIndex = cpi->pb.CodedBlockList[i];
-
- /* Should we code a token for this block on this pass. */
- if ( cpi->FragTokens[FragIndex] < cpi->FragTokenCounts[FragIndex]
- && cpi->pb.FragCoeffs[FragIndex] <= EncodedCoeffs ) {
- /* Bit pack and a token for this block */
- cpi->pb.FragCoefEOB[FragIndex]=EncodedCoeffs;
- PackToken( cpi, FragIndex, HuffIndex );
- }
- }
-
- EncodedCoeffs ++;
- }
-
- /* Pack any outstanding EOB tokens */
- PackEOBRun(cpi);
-
- /* Now output the optimised AC token list using the appropriate
- entropy tables. */
- EncodeAcTokenList(cpi);
-
-}
-
void EncodeDcTokenList (CP_INSTANCE *cpi) {
ogg_int32_t i,j;
ogg_uint32_t Token;
@@ -319,7 +116,7 @@
ogg_uint32_t DcHuffChoice[2];
ogg_uint32_t EntropyTableBits[2][DC_HUFF_CHOICES];
- oggpack_buffer *opb=cpi.oggbuffer;
+ oggpack_buffer *opb=&cpi->oggbuffer;
/* Clear table data structure */
memset ( EntropyTableBits, 0, sizeof(ogg_uint32_t)*DC_HUFF_CHOICES*2 );
@@ -402,7 +199,7 @@
ogg_uint32_t AcHuffChoice[2];
ogg_uint32_t EntropyTableBits[2][AC_HUFF_CHOICES];
- oggpack_buffer *opb=cpi.oggbuffer;
+ oggpack_buffer *opb=&cpi->oggbuffer;
memset ( EntropyTableBits, 0, sizeof(ogg_uint32_t)*AC_HUFF_CHOICES*2 );
@@ -474,17 +271,17 @@
void PackModes (CP_INSTANCE *cpi) {
ogg_uint32_t i,j;
- ogg_uint16_t ModeIndex;
+ unsigned char ModeIndex;
ogg_int32_t ModeCount[MAX_MODES];
ogg_int32_t TmpFreq;
ogg_int32_t TmpIndex;
- ogg_uint16_t BestScheme;
+ unsigned char BestScheme;
ogg_uint32_t BestSchemeScore;
ogg_uint32_t SchemeScore;
- oggpack_buffer *opb=cpi.oggbuffer;
+ oggpack_buffer *opb=&cpi->oggbuffer;
/* Build a frequency map for the modes in this frame */
memset( ModeCount, 0, MAX_MODES*sizeof(ogg_int32_t) );
@@ -547,7 +344,7 @@
for ( i = 0; i < cpi->ModeListCount; i++ ) {
/* Add the appropriate mode entropy token. */
ModeIndex = ModeSchemes[BestScheme][cpi->ModeList[i]];
- oggpackB_write( cpi, ModeBitPatterns[ModeIndex],
+ oggpackB_write( opb, ModeBitPatterns[ModeIndex],
(ogg_uint32_t)ModeBitLengths[ModeIndex] );
}
}else{
@@ -567,7 +364,7 @@
ogg_int32_t LastXMVComponent = 0;
ogg_int32_t LastYMVComponent = 0;
- oggpack_buffer *opb=cpi.oggbuffer;
+ oggpack_buffer *opb=&cpi->oggbuffer;
/* Choose the coding method */
MvBitsPtr = &MvBits[MAX_MV_EXTENT];
@@ -591,9 +388,9 @@
/* Pack and encode the motion vectors */
for ( i = 0; i < (ogg_int32_t)cpi->MvListCount; i++ ) {
- oggpackB_write( cpi, MvPatternPtr[cpi->MVList[i].x],
+ oggpackB_write( opb, MvPatternPtr[cpi->MVList[i].x],
(ogg_uint32_t)MvBitsPtr[cpi->MVList[i].x] );
- oggpackB_write( cpi, MvPatternPtr[cpi->MVList[i].y],
+ oggpackB_write( opb, MvPatternPtr[cpi->MVList[i].y],
(ogg_uint32_t)MvBitsPtr[cpi->MVList[i].y] );
}
}
@@ -612,7 +409,7 @@
/* Note the huffman index to be used */
cpi->OptimisedTokenListHi[cpi->OptimisedTokenCount] =
- (ogg_uint16_t)cpi->RunHuffIndex;
+ cpi->RunHuffIndex;
if ( cpi->RunLength <= 3 ) {
if ( cpi->RunLength == 1 ) {
@@ -663,47 +460,6 @@
cpi->RunLength = 0;
}
-ogg_uint32_t GetBlockReconErrorSlow( CP_INSTANCE *cpi,
- ogg_int32_t BlockIndex ) {
- ogg_uint32_t i;
- ogg_uint32_t ErrorVal = 0;
-
- ogg_uint16_t * SrcDataPtr =
- &cpi->ConvDestBuffer[GetFragIndex(cpi->pb.pixel_index_table,
- BlockIndex)];
- ogg_uint16_t * RecDataPtr =
- &cpi->pb.LastFrameRecon[GetFragIndex(cpi->pb.recon_pixel_index_table,
- BlockIndex)];
- ogg_int32_t SrcStride;
- ogg_int32_t RecStride;
-
- /* Is the block a Y block or a UV block. */
- if ( BlockIndex < (ogg_int32_t)cpi->pb.YPlaneFragments ) {
- SrcStride = cpi->pb.Configuration.VideoFrameWidth;
- RecStride = cpi->pb.Configuration.YStride;
- }else{
- SrcStride = cpi->pb.Configuration.VideoFrameWidth >> 1;
- RecStride = cpi->pb.Configuration.UVStride;
- }
-
-
- /* Decide on standard or MMX implementation */
- for ( i=0; i < BLOCK_HEIGHT_WIDTH; i++ ) {
- ErrorVal += AbsX_LUT[ ((int)SrcDataPtr[0]) - ((int)RecDataPtr[0]) ];
- ErrorVal += AbsX_LUT[ ((int)SrcDataPtr[1]) - ((int)RecDataPtr[1]) ];
- ErrorVal += AbsX_LUT[ ((int)SrcDataPtr[2]) - ((int)RecDataPtr[2]) ];
- ErrorVal += AbsX_LUT[ ((int)SrcDataPtr[3]) - ((int)RecDataPtr[3]) ];
- ErrorVal += AbsX_LUT[ ((int)SrcDataPtr[4]) - ((int)RecDataPtr[4]) ];
- ErrorVal += AbsX_LUT[ ((int)SrcDataPtr[5]) - ((int)RecDataPtr[5]) ];
- ErrorVal += AbsX_LUT[ ((int)SrcDataPtr[6]) - ((int)RecDataPtr[6]) ];
- ErrorVal += AbsX_LUT[ ((int)SrcDataPtr[7]) - ((int)RecDataPtr[7]) ];
- /* Step to next row of block. */
- SrcDataPtr += SrcStride;
- RecDataPtr += RecStride;
- }
- return ErrorVal;
-}
-
void PackToken ( CP_INSTANCE *cpi, ogg_int32_t FragmentNumber,
ogg_uint32_t HuffIndex ) {
ogg_uint32_t Token =
@@ -755,840 +511,1085 @@
/* Note the token, extra bits and hufman table in the optimised
token list */
cpi->OptimisedTokenList[cpi->OptimisedTokenCount] =
- (ogg_uint16_t)Token;
+ Token;
cpi->OptimisedTokenListEb[cpi->OptimisedTokenCount] =
ExtraBitsToken;
cpi->OptimisedTokenListHi[cpi->OptimisedTokenCount] =
- (ogg_uint16_t)HuffIndex;
+ HuffIndex;
cpi->OptimisedTokenCount++;
}
}
-void AddMotionVector(CP_INSTANCE *cpi,
- MOTION_VECTOR *ThisMotionVector) {
- cpi->MVList[cpi->MvListCount].x = ThisMotionVector->x;
- cpi->MVList[cpi->MvListCount].y = ThisMotionVector->y;
- cpi->MvListCount++;
-}
-
-void SetFragMotionVectorAndMode(CP_INSTANCE *cpi,
- ogg_int32_t FragIndex,
- MOTION_VECTOR *ThisMotionVector){
- /* Note the coding mode and vector for each block */
- cpi->pb.FragMVect[FragIndex].x = ThisMotionVector->x;
- cpi->pb.FragMVect[FragIndex].y = ThisMotionVector->y;
- cpi->pb.FragCodingMethod[FragIndex] = cpi->MBCodingMode;
-}
-
-void SetMBMotionVectorsAndMode(CP_INSTANCE *cpi,
- ogg_int32_t YFragIndex,
- ogg_int32_t UFragIndex,
- ogg_int32_t VFragIndex,
- MOTION_VECTOR *ThisMotionVector){
- SetFragMotionVectorAndMode(cpi, YFragIndex, ThisMotionVector);
- SetFragMotionVectorAndMode(cpi, YFragIndex + 1, ThisMotionVector);
- SetFragMotionVectorAndMode(cpi, YFragIndex + cpi->pb.HFragments,
- ThisMotionVector);
- SetFragMotionVectorAndMode(cpi, YFragIndex + cpi->pb.HFragments + 1,
- ThisMotionVector);
- SetFragMotionVectorAndMode(cpi, UFragIndex, ThisMotionVector);
- SetFragMotionVectorAndMode(cpi, VFragIndex, ThisMotionVector);
+ogg_uint32_t GetBlockReconErrorSlow( CP_INSTANCE *cpi,
+ ogg_int32_t BlockIndex ) {
+ ogg_uint32_t i;
+ ogg_uint32_t ErrorVal = 0;
+
+ unsigned char * SrcDataPtr =
+ &cpi->ConvDestBuffer[GetFragIndex(cpi->pb.pixel_index_table,
+ BlockIndex)];
+ unsigned char * RecDataPtr =
+ &cpi->pb.LastFrameRecon[GetFragIndex(cpi->pb.recon_pixel_index_table,
+ BlockIndex)];
+ ogg_int32_t SrcStride;
+ ogg_int32_t RecStride;
+
+ /* Is the block a Y block or a UV block. */
+ if ( BlockIndex < (ogg_int32_t)cpi->pb.YPlaneFragments ) {
+ SrcStride = cpi->pb.Configuration.VideoFrameWidth;
+ RecStride = cpi->pb.Configuration.YStride;
+ }else{
+ SrcStride = cpi->pb.Configuration.VideoFrameWidth >> 1;
+ RecStride = cpi->pb.Configuration.UVStride;
+ }
+
+
+ /* Decide on standard or MMX implementation */
+ for ( i=0; i < BLOCK_HEIGHT_WIDTH; i++ ) {
+ ErrorVal += abs( ((int)SrcDataPtr[0]) - ((int)RecDataPtr[0]) );
+ ErrorVal += abs( ((int)SrcDataPtr[1]) - ((int)RecDataPtr[1]) );
+ ErrorVal += abs( ((int)SrcDataPtr[2]) - ((int)RecDataPtr[2]) );
+ ErrorVal += abs( ((int)SrcDataPtr[3]) - ((int)RecDataPtr[3]) );
+ ErrorVal += abs( ((int)SrcDataPtr[4]) - ((int)RecDataPtr[4]) );
+ ErrorVal += abs( ((int)SrcDataPtr[5]) - ((int)RecDataPtr[5]) );
+ ErrorVal += abs( ((int)SrcDataPtr[6]) - ((int)RecDataPtr[6]) );
+ ErrorVal += abs( ((int)SrcDataPtr[7]) - ((int)RecDataPtr[7]) );
+ /* Step to next row of block. */
+ SrcDataPtr += SrcStride;
+ RecDataPtr += RecStride;
+ }
+ return ErrorVal;
}
-ogg_uint32_t PickModes(CP_INSTANCE *cpi,
- ogg_uint32_t SBRows, ogg_uint32_t SBCols,
- ogg_uint32_t HExtra, ogg_uint32_t VExtra,
- ogg_uint32_t PixelsPerLine,
- ogg_uint32_t *InterError, ogg_uint32_t *IntraError) {
- ogg_int32_t YFragIndex;
- ogg_int32_t UFragIndex;
- ogg_int32_t VFragIndex;
- ogg_uint32_t MB, B; /* Macro-Block, Block indices */
- ogg_uint32_t SBrow; /* Super-Block row number */
- ogg_uint32_t SBcol; /* Super-Block row number */
- ogg_uint32_t SB=0; /* Super-Block index, initialised to first
- of this component */
+void PackCodedVideo (CP_INSTANCE *cpi) {
+ ogg_int32_t i;
+ ogg_int32_t EncodedCoeffs = 1;
+ ogg_int32_t TotalTokens = cpi->TotTokenCount;
+ ogg_int32_t FragIndex;
+ ogg_uint32_t HuffIndex; /* Index to group of tables used to code a token */
- ogg_uint32_t MBIntraError; /* Intra error for macro block */
- ogg_uint32_t MBGFError; /* Golden frame macro block error */
- ogg_uint32_t MBGF_MVError; /* Golden frame plus MV error */
- ogg_uint32_t LastMBGF_MVError; /* Golden frame error with
- last used GF motion
- vector. */
- ogg_uint32_t MBInterError; /* Inter no MV macro block error */
- ogg_uint32_t MBLastInterError; /* Inter with last used MV */
- ogg_uint32_t MBPriorLastInterError; /* Inter with prior last MV */
- ogg_uint32_t MBInterMVError; /* Inter MV macro block error */
- ogg_uint32_t MBInterMVExError; /* Inter MV (exhaustive
- search) macro block error */
- ogg_uint32_t MBInterFOURMVError; /* Inter MV error when using 4
- motion vectors per macro
- block */
- ogg_uint32_t BestError; /* Best error so far. */
-
- MOTION_VECTOR FourMVect[6]; /* storage for last used vectors (one
- entry for each block in MB) */
- MOTION_VECTOR LastInterMVect; /* storage for last used Inter frame
- MB motion vector */
- MOTION_VECTOR PriorLastInterMVect; /* storage for prior last used
- Inter frame MB motion vector */
- MOTION_VECTOR TmpMVect; /* Temporary MV storage */
- MOTION_VECTOR LastGFMVect; /* storage for last used Golden
- Frame MB motion vector */
- MOTION_VECTOR InterMVect; /* storage for motion vector */
- MOTION_VECTOR InterMVectEx; /* storage for motion vector result
- from exhaustive search */
- MOTION_VECTOR GFMVect; /* storage for motion vector */
- MOTION_VECTOR ZeroVect;
+ ClearSysState();
+
+ /* Reset the count of second order optimised tokens */
+ cpi->OptimisedTokenCount = 0;
- ogg_uint32_t UVRow;
- ogg_uint32_t UVColumn;
- ogg_uint32_t UVFragOffset;
+ cpi->TokensToBeCoded = cpi->TotTokenCount;
+ cpi->TokensCoded = 0;
- int MBCodedFlag;
- ogg_uint16_t QIndex;
+ /* Calculate the bit rate at which this frame should be capped. */
+ cpi->MaxBitTarget = (ogg_uint32_t)((double)(cpi->ThisFrameTargetBytes * 8) *
+ cpi->BitRateCapFactor);
- /* initialize error scores */
- *InterError = 0;
- *IntraError = 0;
+ /* Blank the various fragment data structures before we start. */
+ memset(cpi->pb.FragCoeffs, 0, cpi->pb.UnitFragments);
+ memset(cpi->FragTokens, 0, cpi->pb.UnitFragments);
+
+ /* Clear down the QFragData structure for all coded blocks. */
+ ClearDownQFragData(&cpi->pb);
+
+ /* The tree is not needed (implicit) for key frames */
+ if ( GetFrameType(&cpi->pb) != BASE_FRAME ){
+ /* Pack the quad tree fragment mapping. */
+ PackAndWriteDFArray( cpi );
+ }
- /* clear down the default motion vector. */
- cpi->MvListCount = 0;
- FourMVect[0].x = 0;
- FourMVect[0].y = 0;
- FourMVect[1].x = 0;
- FourMVect[1].y = 0;
- FourMVect[2].x = 0;
- FourMVect[2].y = 0;
- FourMVect[3].x = 0;
- FourMVect[3].y = 0;
- FourMVect[4].x = 0;
- FourMVect[4].y = 0;
- FourMVect[5].x = 0;
- FourMVect[5].y = 0;
- LastInterMVect.x = 0;
- LastInterMVect.y = 0;
- PriorLastInterMVect.x = 0;
- PriorLastInterMVect.y = 0;
- LastGFMVect.x = 0;
- LastGFMVect.y = 0;
- InterMVect.x = 0;
- InterMVect.y = 0;
- GFMVect.x = 0;
- GFMVect.y = 0;
+ /* Note the number of bits used to code the tree itself. */
+ cpi->FrameBitCount = oggpackB_bytes(&cpi->oggbuffer) << 3;
+
+ /* Mode and MV data not needed for key frames. */
+ if ( GetFrameType(&cpi->pb) != BASE_FRAME ){
+ /* Pack and code the mode list. */
+ PackModes(cpi);
+ /* Pack the motion vectors */
+ PackMotionVectors (cpi);
+ }
- ZeroVect.x = 0;
- ZeroVect.y = 0;
+ cpi->FrameBitCount = oggpackB_bytes(&cpi->oggbuffer) << 3;
- QIndex = cpi->pb.FrameQIndex;
-
+ /* Optimise the DC tokens */
+ for ( i = 0; i < cpi->pb.CodedBlockIndex; i++ ) {
+ /* Get the linear index for the current fragment. */
+ FragIndex = cpi->pb.CodedBlockList[i];
+
+ cpi->pb.FragCoefEOB[FragIndex]=EncodedCoeffs;
+ PackToken(cpi, FragIndex, DC_HUFF_OFFSET );
+
+ }
+ /* Pack any outstanding EOB tokens */
+ PackEOBRun(cpi);
+
+ /* Now output the optimised DC token list using the appropriate
+ entropy tables. */
+ EncodeDcTokenList(cpi);
- /* change the quatization matrix to the one at best Q to compute the
- new error score */
- cpi->MinImprovementForNewMV = (MvThreshTable[QIndex] << 12);
- cpi->InterTripOutThresh = (5000<<12);
- cpi->MVChangeFactor = MVChangeFactorTable[QIndex]; /* 0.9 */
+ /* Work out the number of DC bits coded */
- if ( cpi->QuickCompress ) {
- cpi->ExhaustiveSearchThresh = (1000<<12);
- cpi->FourMVThreshold = (2500<<12);
- } else {
- cpi->ExhaustiveSearchThresh = (250<<12);
- cpi->FourMVThreshold = (500<<12);
+ /* Optimise the AC tokens */
+ while ( EncodedCoeffs < 64 ) {
+ /* Huffman table adjustment based upon coefficient number. */
+ if ( EncodedCoeffs <= AC_TABLE_2_THRESH )
+ HuffIndex = AC_HUFF_OFFSET;
+ else if ( EncodedCoeffs <= AC_TABLE_3_THRESH )
+ HuffIndex = AC_HUFF_OFFSET + AC_HUFF_CHOICES;
+ else if ( EncodedCoeffs <= AC_TABLE_4_THRESH )
+ HuffIndex = AC_HUFF_OFFSET + (AC_HUFF_CHOICES * 2);
+ else
+ HuffIndex = AC_HUFF_OFFSET + (AC_HUFF_CHOICES * 3);
+
+ /* Repeatedly scan through the list of blocks. */
+ for ( i = 0; i < cpi->pb.CodedBlockIndex; i++ ) {
+ /* Get the linear index for the current fragment. */
+ FragIndex = cpi->pb.CodedBlockList[i];
+
+ /* Should we code a token for this block on this pass. */
+ if ( cpi->FragTokens[FragIndex] < cpi->FragTokenCounts[FragIndex]
+ && cpi->pb.FragCoeffs[FragIndex] <= EncodedCoeffs ) {
+ /* Bit pack and a token for this block */
+ cpi->pb.FragCoefEOB[FragIndex]=EncodedCoeffs;
+ PackToken( cpi, FragIndex, HuffIndex );
+ }
+ }
+
+ EncodedCoeffs ++;
}
- cpi->MinImprovementForFourMV = cpi->MinImprovementForNewMV * 4;
- if(cpi->MinImprovementForFourMV < (40<<12))
- cpi->MinImprovementForFourMV = (40<<12);
+ /* Pack any outstanding EOB tokens */
+ PackEOBRun(cpi);
- cpi->FourMvChangeFactor = 8; /* cpi->MVChangeFactor - 0.05; */
+ /* Now output the optimised AC token list using the appropriate
+ entropy tables. */
+ EncodeAcTokenList(cpi);
- /* decide what block type and motion vectors to use on all of the frames */
- for ( SBrow=0; SBrow<SBRows; SBrow++ ) {
- for ( SBcol=0; SBcol<SBCols; SBcol++ ) {
- /* Check its four Macro-Blocks */
- for ( MB=0; MB<4; MB++ ) {
- /* There may be MB's lying out of frame which must be
- ignored. For these MB's Top left block will have a negative
- Fragment Index. */
- if ( QuadMapToMBTopLeft(cpi->pb.BlockMap,SB,MB) < 0 ) continue;
-
- /* Is the current macro block coded (in part or in whole) */
- MBCodedFlag = 0;
- for ( B=0; B<4; B++ ) {
- YFragIndex = QuadMapToIndex1( cpi->pb.BlockMap, SB, MB, B );
-
- /* Does Block lie in frame: */
- if ( YFragIndex >= 0 ) {
- /* In Frame: Is it coded: */
- if ( cpi->pb.display_fragments[YFragIndex] ) {
- MBCodedFlag = 1;
- break;
- }
- } else
- MBCodedFlag = 0;
- }
-
- /* This one isn't coded go to the next one */
- if(!MBCodedFlag) continue;
+}
- /* Calculate U and V FragIndex from YFragIndex */
- YFragIndex = QuadMapToMBTopLeft(cpi->pb.BlockMap, SB,MB);
- UVRow = (YFragIndex / (cpi->pb.HFragments * 2));
- UVColumn = (YFragIndex % cpi->pb.HFragments) / 2;
- UVFragOffset = (UVRow * (cpi->pb.HFragments / 2)) + UVColumn;
- UFragIndex = cpi->pb.YPlaneFragments + UVFragOffset;
- VFragIndex = cpi->pb.YPlaneFragments + cpi->pb.UVPlaneFragments +
- UVFragOffset;
-
-
- /**************************************************************
- Find the block choice with the lowest error
+ogg_uint32_t QuadCodeDisplayFragments (CP_INSTANCE *cpi) {
+ ogg_int32_t i,j;
+ ogg_uint32_t coded_pixels=0;
+ int QIndex;
+ int k,m,n;
- NOTE THAT if U or V is coded but no Y from a macro block then
- the mode will be CODE_INTER_NO_MV as this is the default
- state to which the mode data structure is initialised in
- encoder and decoder at the start of each frame. */
+ /* predictor multiplier up-left, up, up-right,left, shift */
+ ogg_int16_t pc[16][6]={
+ {0,0,0,0,0,0},
+ {0,0,0,1,0,0}, /* PL */
+ {0,0,1,0,0,0}, /* PUR */
+ {0,0,53,75,7,127}, /* PUR|PL */
+ {0,1,0,0,0,0}, /* PU */
+ {0,1,0,1,1,1}, /* PU|PL */
+ {0,1,0,0,0,0}, /* PU|PUR */
+ {0,0,53,75,7,127}, /* PU|PUR|PL */
+ {1,0,0,0,0,0}, /* PUL| */
+ {0,0,0,1,0,0}, /* PUL|PL */
+ {1,0,1,0,1,1}, /* PUL|PUR */
+ {0,0,53,75,7,127}, /* PUL|PUR|PL */
+ {0,1,0,0,0,0}, /* PUL|PU */
+ {-26,29,0,29,5,31}, /* PUL|PU|PL */
+ {3,10,3,0,4,15}, /* PUL|PU|PUR */
+ {-26,29,0,29,5,31} /* PUL|PU|PUR|PL */
+ };
- BestError = HUGE_ERROR;
-
+ struct SearchPoints {
+ int RowOffset;
+ int ColOffset;
+ } DCSearchPoints[]= {
+ {0,-2},{-2,0},{-1,-2},{-2,-1},{-2,1},{-1,2},{-2,-2},{-2,2},{0,-3},
+ {-3,0},{-1,-3},{-3,-1},{-3,1},{-1,3},{-2,-3},{-3,-2},{-3,2},{-2,3},
+ {0,-4},{-4,0},{-1,-4},{-4,-1},{-4,1},{-1,4},{-3,-3},{-3,3}
+ };
- /* Look at the intra coding error. */
- MBIntraError = GetMBIntraError( cpi, YFragIndex, PixelsPerLine );
- BestError = (BestError > MBIntraError) ? MBIntraError : BestError;
-
- /* Get the golden frame error */
- MBGFError = GetMBInterError( cpi, cpi->ConvDestBuffer,
- cpi->pb.GoldenFrame, YFragIndex,
- 0, 0, PixelsPerLine );
- BestError = (BestError > MBGFError) ? MBGFError : BestError;
-
- /* Calculate the 0,0 case. */
- MBInterError = GetMBInterError( cpi, cpi->ConvDestBuffer,
- cpi->pb.LastFrameRecon,
- YFragIndex, 0, 0, PixelsPerLine );
- BestError = (BestError > MBInterError) ? MBInterError : BestError;
-
- /* Measure error for last MV */
- MBLastInterError = GetMBInterError( cpi, cpi->ConvDestBuffer,
- cpi->pb.LastFrameRecon,
- YFragIndex, LastInterMVect.x,
- LastInterMVect.y, PixelsPerLine );
- BestError = (BestError > MBLastInterError) ?
- MBLastInterError : BestError;
-
- /* Measure error for prior last MV */
- MBPriorLastInterError = GetMBInterError( cpi, cpi->ConvDestBuffer,
- cpi->pb.LastFrameRecon,
- YFragIndex,
- PriorLastInterMVect.x,
- PriorLastInterMVect.y,
- PixelsPerLine );
- BestError = (BestError > MBPriorLastInterError) ?
- MBPriorLastInterError : BestError;
+ int DCSearchPointCount = 0;
+
+ /* fragment left fragment up-left, fragment up, fragment up-right */
+ int fl,ful,fu,fur;
+
+ /* value left value up-left, value up, value up-right */
+ int vl,vul,vu,vur;
+
+ /* fragment number left, up-left, up, up-right */
+ int l,ul,u,ur;
+
+ /*which predictor constants to use */
+ ogg_int16_t wpc;
+
+ /* last used inter predictor (Raster Order) */
+ ogg_int16_t Last[3]; /* last value used for given frame */
+ ogg_int16_t TempInter = 0;
+
+ int FragsAcross=cpi->pb.HFragments;
+ int FragsDown = cpi->pb.VFragments;
+ int FromFragment,ToFragment;
+ ogg_int32_t FragIndex;
+ int WhichFrame;
+ int WhichCase;
+
+ ogg_int16_t Mode2Frame[] = {
+ 1, /* CODE_INTER_NO_MV 0 => Encoded diff from same MB last frame */
+ 0, /* CODE_INTRA 1 => DCT Encoded Block */
+ 1, /* CODE_INTER_PLUS_MV 2 => Encoded diff from included MV MB last frame */
+ 1, /* CODE_INTER_LAST_MV 3 => Encoded diff from MRU MV MB last frame */
+ 1, /* CODE_INTER_PRIOR_MV 4 => Encoded diff from included 4 separate MV blocks */
+ 2, /* CODE_USING_GOLDEN 5 => Encoded diff from same MB golden frame */
+ 2, /* CODE_GOLDEN_MV 6 => Encoded diff from included MV MB golden frame */
+ 1 /* CODE_INTER_FOUR_MV 7 => Encoded diff from included 4 separate MV blocks */
+ };
- /* Temporarily force usage of no motionvector blocks */
- MBInterMVError = HUGE_ERROR;
- InterMVect.x = 0; /* Set 0,0 motion vector */
- InterMVect.y = 0;
-
- /* If the best error is above the required threshold search
- for a new inter MV */
- if ( BestError > cpi->MinImprovementForNewMV ) {
- /* Use a mix of heirachical and exhaustive searches for
- quick mode. */
- if ( cpi->QuickCompress ) {
- MBInterMVError = GetMBMVInterError( cpi, cpi->pb.LastFrameRecon,
- YFragIndex, PixelsPerLine,
- cpi->MVPixelOffsetY,
- &InterMVect );
-
- /* If we still do not have a good match try an exhaustive
- MBMV search */
- if ( (MBInterMVError > cpi->ExhaustiveSearchThresh) &&
- (BestError > cpi->ExhaustiveSearchThresh) ) {
+ ogg_int16_t PredictedDC;
- MBInterMVExError =
- GetMBMVExhaustiveSearch( cpi, cpi->pb.LastFrameRecon,
- YFragIndex, PixelsPerLine,
- &InterMVectEx );
-
- /* Is the Variance measure for the EX search
- better... If so then use it. */
- if ( MBInterMVExError < MBInterMVError ) {
- MBInterMVError = MBInterMVExError;
- InterMVect.x = InterMVectEx.x;
- InterMVect.y = InterMVectEx.y;
- }
- }
- }else{
- /* Use an exhaustive search */
- MBInterMVError =
- GetMBMVExhaustiveSearch( cpi, cpi->pb.LastFrameRecon,
- YFragIndex, PixelsPerLine,
- &InterMVect );
- }
-
-
- /* Is the improvement, if any, good enough to justify a new MV */
- if ( (16 * MBInterMVError < (BestError * cpi->MVChangeFactor)) &&
- ((MBInterMVError + cpi->MinImprovementForNewMV) < BestError) ){
- BestError = MBInterMVError;
- }
-
- }
-
- /* If the best error is still above the required threshold
- search for a golden frame MV */
- MBGF_MVError = HUGE_ERROR;
- GFMVect.x = 0; /* Set 0,0 motion vector */
- GFMVect.y = 0;
- if ( BestError > cpi->MinImprovementForNewMV ) {
- /* Do an MV search in the golden reference frame */
- MBGF_MVError = GetMBMVInterError( cpi, cpi->pb.GoldenFrame,
- YFragIndex, PixelsPerLine,
- cpi->MVPixelOffsetY, &GFMVect );
-
- /* Measure error for last GFMV */
- LastMBGF_MVError = GetMBInterError( cpi, cpi->ConvDestBuffer,
- cpi->pb.GoldenFrame,
- YFragIndex, LastGFMVect.x,
- LastGFMVect.y, PixelsPerLine );
-
- /* Check against last GF motion vector and reset if the
- search has thrown a worse result. */
- if ( LastMBGF_MVError < MBGF_MVError ) {
- GFMVect.x = LastGFMVect.x;
- GFMVect.y = LastGFMVect.y;
- MBGF_MVError = LastMBGF_MVError;
- }else{
- LastGFMVect.x = GFMVect.x;
- LastGFMVect.y = GFMVect.y;
- }
-
- /* Is the improvement, if any, good enough to justify a new MV */
- if ( (16 * MBGF_MVError < (BestError * cpi->MVChangeFactor)) &&
- ((MBGF_MVError + cpi->MinImprovementForNewMV) < BestError) ) {
- BestError = MBGF_MVError;
- }
- }
+ /* Initialise the coded block indices variables. These allow
+ subsequent linear access to the quad tree ordered list of coded
+ blocks */
+ cpi->pb.CodedBlockIndex = 0;
+
+ /* Set the inter/intra descision control variables. */
+ QIndex = Q_TABLE_SIZE - 1;
+ while ( QIndex >= 0 ) {
+ if ( (QIndex == 0) ||
+ ( cpi->pb.QThreshTable[QIndex] >= cpi->pb.ThisFrameQualityValue) )
+ break;
+ QIndex --;
+ }
+
- /* Finally... If the best error is still to high then consider
- the 4MV mode */
- MBInterFOURMVError = HUGE_ERROR;
- if ( BestError > cpi->FourMVThreshold ) {
- /* Get the 4MV error. */
- MBInterFOURMVError =
- GetFOURMVExhaustiveSearch( cpi, cpi->pb.LastFrameRecon,
- YFragIndex, PixelsPerLine, FourMVect );
-
- /* If the improvement is great enough then use the four MV mode */
- if ( ((MBInterFOURMVError + cpi->MinImprovementForFourMV) <
- BestError) && (16 * MBInterFOURMVError <
- (BestError * cpi->FourMvChangeFactor))) {
- BestError = MBInterFOURMVError;
- }
- }
-
- /********************************************************
- end finding the best error
- *******************************************************
-
- Figure out what to do with the block we chose
-
- Over-ride and force intra if error high and Intra error similar
- Now choose a mode based on lowest error (with bias towards no MV) */
+ /* Encode and tokenise the Y, U and V components */
+ coded_pixels = QuadCodeComponent(cpi, 0, cpi->pb.YSBRows, cpi->pb.YSBCols,
+ cpi->pb.HFragments%4,
+ cpi->pb.VFragments%4,
+ cpi->pb.Configuration.VideoFrameWidth );
+ coded_pixels += QuadCodeComponent(cpi, cpi->pb.YSuperBlocks,
+ cpi->pb.UVSBRows,
+ cpi->pb.UVSBCols,
+ (cpi->pb.HFragments/2)%4,
+ (cpi->pb.VFragments/2)%4,
+ cpi->pb.Configuration.VideoFrameWidth>>1 );
+ coded_pixels += QuadCodeComponent(cpi,
+ cpi->pb.YSuperBlocks+cpi->pb.UVSuperBlocks,
+ cpi->pb.UVSBRows, cpi->pb.UVSBCols,
+ (cpi->pb.HFragments/2)%4,
+ (cpi->pb.VFragments/2)%4,
+ cpi->pb.Configuration.VideoFrameWidth>>1 );
+
+ /* for y,u,v */
+ for ( j = 0; j < 3 ; j++) {
+ /* pick which fragments based on Y, U, V */
+ switch(j){
+ case 0: /* y */
+ FromFragment = 0;
+ ToFragment = cpi->pb.YPlaneFragments;
+ FragsAcross = cpi->pb.HFragments;
+ FragsDown = cpi->pb.VFragments;
+ break;
+ case 1: /* u */
+ FromFragment = cpi->pb.YPlaneFragments;
+ ToFragment = cpi->pb.YPlaneFragments + cpi->pb.UVPlaneFragments ;
+ FragsAcross = cpi->pb.HFragments >> 1;
+ FragsDown = cpi->pb.VFragments >> 1;
+ break;
+ case 2: /* v */
+ FromFragment = cpi->pb.YPlaneFragments + cpi->pb.UVPlaneFragments;
+ ToFragment = cpi->pb.YPlaneFragments + (2 * cpi->pb.UVPlaneFragments) ;
+ FragsAcross = cpi->pb.HFragments >> 1;
+ FragsDown = cpi->pb.VFragments >> 1;
+ break;
+ }
- if ( (BestError > cpi->InterTripOutThresh) &&
- (10 * BestError > MBIntraError * 7 ) ) {
- cpi->MBCodingMode = CODE_INTRA;
- SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
- VFragIndex,&ZeroVect);
- } else if ( BestError == MBInterError ) {
- cpi->MBCodingMode = CODE_INTER_NO_MV;
- SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
- VFragIndex,&ZeroVect);
- } else if ( BestError == MBGFError ) {
- cpi->MBCodingMode = CODE_USING_GOLDEN;
- SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
- VFragIndex,&ZeroVect);
- } else if ( BestError == MBLastInterError ) {
- cpi->MBCodingMode = CODE_INTER_LAST_MV;
- SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
- VFragIndex,&LastInterMVect);
- } else if ( BestError == MBPriorLastInterError ) {
- cpi->MBCodingMode = CODE_INTER_PRIOR_LAST;
- SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
- VFragIndex,&PriorLastInterMVect);
+ /* initialize our array of last used DC Components */
+ for(k=0;k<3;k++)Last[k]=0;
+ i=FromFragment;
+
+ /* do prediction on all of Y, U or V */
+ for ( m = 0 ; m < FragsDown ; m++) {
+ for ( n = 0 ; n < FragsAcross ; n++, i++) {
+ cpi->OriginalDC[i] = cpi->pb.QFragData[i][0];
+
+ /* only do 2 prediction if fragment coded and on non intra or
+ if all fragments are intra */
+ if( cpi->pb.display_fragments[i] ||
+ (GetFrameType(&cpi->pb) == BASE_FRAME) ) {
+ /* Type of Fragment */
+ WhichFrame = Mode2Frame[cpi->pb.FragCodingMethod[i]];
+
+ /* Check Borderline Cases */
+ WhichCase = (n==0) + ((m==0) << 1) + ((n+1 == FragsAcross) << 2);
- /* Swap the prior and last MV cases over */
- TmpMVect.x = PriorLastInterMVect.x;
- TmpMVect.y = PriorLastInterMVect.y;
- PriorLastInterMVect.x = LastInterMVect.x;
- PriorLastInterMVect.y = LastInterMVect.y;
- LastInterMVect.x = TmpMVect.x;
- LastInterMVect.y = TmpMVect.y;
+ switch(WhichCase) {
+ case 0: /* normal case no border condition */
+
+ /* calculate values left, up, up-right and up-left */
+ l = i-1;
+ u = i - FragsAcross;
+ ur = i - FragsAcross + 1;
+ ul = i - FragsAcross - 1;
- } else if ( BestError == MBInterMVError ) {
+ /* calculate values */
+ vl = cpi->OriginalDC[l];
+ vu = cpi->OriginalDC[u];
+ vur = cpi->OriginalDC[ur];
+ vul = cpi->OriginalDC[ul];
+
+ /* fragment valid for prediction use if coded and it comes
+ from same frame as the one we are predicting */
+ fl = cpi->pb.display_fragments[l] &&
+ (Mode2Frame[cpi->pb.FragCodingMethod[l]] == WhichFrame);
+ fu = cpi->pb.display_fragments[u] &&
+ (Mode2Frame[cpi->pb.FragCodingMethod[u]] == WhichFrame);
+ fur = cpi->pb.display_fragments[ur] &&
+ (Mode2Frame[cpi->pb.FragCodingMethod[ur]] == WhichFrame);
+ ful = cpi->pb.display_fragments[ul] &&
+ (Mode2Frame[cpi->pb.FragCodingMethod[ul]] == WhichFrame);
+
+ /* calculate which predictor to use */
+ wpc = (fl*PL) | (fu*PU) | (ful*PUL) | (fur*PUR);
+
+ break;
+
+ case 1: /* n == 0 Left Column */
+
+ /* calculate values left, up, up-right and up-left */
+ u = i - FragsAcross;
+ ur = i - FragsAcross + 1;
+
+ /* calculate values */
+ vu = cpi->OriginalDC[u];
+ vur = cpi->OriginalDC[ur];
+
+ /* fragment valid for prediction if coded and it comes
+ from same frame as the one we are predicting */
+ fu = cpi->pb.display_fragments[u] &&
+ (Mode2Frame[cpi->pb.FragCodingMethod[u]] == WhichFrame);
+ fur = cpi->pb.display_fragments[ur] &&
+ (Mode2Frame[cpi->pb.FragCodingMethod[ur]] == WhichFrame);
+
+ /* calculate which predictor to use */
+ wpc = (fu*PU) | (fur*PUR);
+
+ break;
+
+ case 2: /* m == 0 Top Row */
+ case 6: /* m == 0 and n+1 == FragsAcross or Top Row Right Column */
+
+ /* calculate values left, up, up-right and up-left */
+ l = i-1;
+
+ /* calculate values */
+ vl = cpi->OriginalDC[l];
+
+ /* fragment valid for prediction if coded and it comes
+ from same frame as the one we are predicting */
+ fl = cpi->pb.display_fragments[l] &&
+ (Mode2Frame[cpi->pb.FragCodingMethod[l]] == WhichFrame);
+
+ /* calculate which predictor to use */
+ wpc = (fl*PL) ;
+
+ break;
+
+ case 3: /* n == 0 & m == 0 Top Row Left Column */
+
+ wpc = 0;
+ break;
+
+ case 4: /* n+1 == FragsAcross : Right Column */
+
+ /* calculate values left, up, up-right and up-left */
+ l = i-1;
+ u = i - FragsAcross;
+ ul = i - FragsAcross - 1;
+
+ /* calculate values */
+ vl = cpi->OriginalDC[l];
+ vu = cpi->OriginalDC[u];
+ vul = cpi->OriginalDC[ul];
+
+ /* fragment valid for prediction if coded and it comes
+ from same frame as the one we are predicting */
+ fl = cpi->pb.display_fragments[l] &&
+ (Mode2Frame[cpi->pb.FragCodingMethod[l]] == WhichFrame);
+ fu = cpi->pb.display_fragments[u] &&
+ (Mode2Frame[cpi->pb.FragCodingMethod[u]] == WhichFrame);
+ ful = cpi->pb.display_fragments[ul] &&
+ (Mode2Frame[cpi->pb.FragCodingMethod[ul]] == WhichFrame);
+
+ /* calculate which predictor to use */
+ wpc = (fl*PL) | (fu*PU) | (ful*PUL) ;
+ break;
- cpi->MBCodingMode = CODE_INTER_PLUS_MV;
- SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
- VFragIndex,&InterMVect);
-
- /* Update Prior last mv with last mv */
- PriorLastInterMVect.x = LastInterMVect.x;
- PriorLastInterMVect.y = LastInterMVect.y;
-
- /* Note last inter MV for future use */
- LastInterMVect.x = InterMVect.x;
- LastInterMVect.y = InterMVect.y;
+ }
- AddMotionVector( cpi, &InterMVect);
+ if(wpc==0) {
+ FragIndex = 1;
+
+ /* find the nearest one that is coded */
+ for( k = 0; k < DCSearchPointCount ; k++) {
+ FragIndex = i + DCSearchPoints[k].RowOffset *
+ FragsAcross + DCSearchPoints[k].ColOffset;
+
+ if( FragIndex - FromFragment > 0 ) {
+ if(cpi->pb.display_fragments[FragIndex] &&
+ (Mode2Frame[cpi->pb.FragCodingMethod[FragIndex]] ==
+ WhichFrame)) {
+ cpi->pb.QFragData[i][0] -= cpi->OriginalDC[FragIndex];
+ FragIndex = 0;
+ break;
+ }
+ }
+ }
+
+ /* if none matched fall back to the last one ever */
+ if(FragIndex) cpi->pb.QFragData[i][0] -= Last[WhichFrame];
+
+ } else {
+
+ /* don't do divide if divisor is 1 or 0 */
+ PredictedDC = (pc[wpc][0]*vul + pc[wpc][1] * vu +
+ pc[wpc][2] * vur + pc[wpc][3] * vl );
+
+ /* if we need to do a shift */
+ if(pc[wpc][4] != 0 ) {
- } else if ( BestError == MBGF_MVError ) {
+ /* If negative add in the negative correction factor */
+ PredictedDC += (HIGHBITDUPPED(PredictedDC) & pc[wpc][5]);
+ /* Shift in lieu of a divide */
+ PredictedDC >>= pc[wpc][4];
- cpi->MBCodingMode = CODE_GOLDEN_MV;
- SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
- VFragIndex,&GFMVect);
-
- /* Note last inter GF MV for future use */
- LastGFMVect.x = GFMVect.x;
- LastGFMVect.y = GFMVect.y;
-
- AddMotionVector( cpi, &GFMVect);
- } else if ( BestError == MBInterFOURMVError ) {
- cpi->MBCodingMode = CODE_INTER_FOURMV;
-
- /* Calculate the UV vectors as the average of the Y plane ones. */
- /* First .x component */
- FourMVect[4].x = FourMVect[0].x + FourMVect[1].x +
- FourMVect[2].x + FourMVect[3].x;
- if ( FourMVect[4].x >= 0 )
- FourMVect[4].x = (FourMVect[4].x + 2) / 4;
- else
- FourMVect[4].x = (FourMVect[4].x - 2) / 4;
- FourMVect[5].x = FourMVect[4].x;
-
- /* Then .y component */
- FourMVect[4].y = FourMVect[0].y + FourMVect[1].y +
- FourMVect[2].y + FourMVect[3].y;
- if ( FourMVect[4].y >= 0 )
- FourMVect[4].y = (FourMVect[4].y + 2) / 4;
- else
- FourMVect[4].y = (FourMVect[4].y - 2) / 4;
- FourMVect[5].y = FourMVect[4].y;
-
- SetFragMotionVectorAndMode(cpi, YFragIndex, &FourMVect[0]);
- SetFragMotionVectorAndMode(cpi, YFragIndex + 1, &FourMVect[1]);
- SetFragMotionVectorAndMode(cpi, YFragIndex + cpi->pb.HFragments,
- &FourMVect[2]);
- SetFragMotionVectorAndMode(cpi, YFragIndex + cpi->pb.HFragments + 1,
- &FourMVect[3]);
- SetFragMotionVectorAndMode(cpi, UFragIndex, &FourMVect[4]);
- SetFragMotionVectorAndMode(cpi, VFragIndex, &FourMVect[5]);
-
- /* Note the four MVs values for current macro-block. */
- AddMotionVector( cpi, &FourMVect[0]);
- AddMotionVector( cpi, &FourMVect[1]);
- AddMotionVector( cpi, &FourMVect[2]);
- AddMotionVector( cpi, &FourMVect[3]);
+ }
+
+ /* check for outranging on the two predictors that can outrange */
+ switch(wpc) {
+ case 13: /* pul pu pl */
+ case 15: /* pul pu pur pl */
+ if( abs(PredictedDC - vu) > 128)
+ PredictedDC = vu;
+ else if( abs(PredictedDC - vl) > 128)
+ PredictedDC = vl;
+ else if( abs(PredictedDC - vul) > 128)
+ PredictedDC = vul;
+ break;
+ }
+
+ cpi->pb.QFragData[i][0] -= PredictedDC;
+ }
- /* Update Prior last mv with last mv */
- PriorLastInterMVect.x = LastInterMVect.x;
- PriorLastInterMVect.y = LastInterMVect.y;
+ /* Save the last fragment coded for whatever frame we are
+ predicting from */
- /* Note last inter MV for future use */
- LastInterMVect.x = FourMVect[3].x;
- LastInterMVect.y = FourMVect[3].y;
+ Last[WhichFrame] = cpi->OriginalDC[i];
- } else {
-
- cpi->MBCodingMode = CODE_INTRA;
- SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
- VFragIndex,&ZeroVect);
}
-
+ }
+ }
+ }
- /* setting up mode specific block types
- *******************************************************/
-
- *InterError += (BestError>>8);
- *IntraError += (MBIntraError>>8);
-
-
- }
- SB++;
-
- }
+ /* Pack DC tokens and adjust the ones we couldn't predict 2d */
+ for ( i = 0; i < cpi->pb.CodedBlockIndex; i++ ) {
+ /* Get the linear index for the current coded fragment. */
+ FragIndex = cpi->pb.CodedBlockList[i];
+ coded_pixels += DPCMTokenizeBlock ( cpi, FragIndex,
+ cpi->pb.Configuration.VideoFrameWidth);
+
}
- cpi->pb.ClearSysState();
-
- /* Return number of pixels coded */
- return 0;
-}
-ogg_uint32_t QuadCodeDisplayFragments (CP_INSTANCE *cpi) {
- ogg_int32_t i,j;
- ogg_uint32_t coded_pixels=0;
- ogg_uint16_t QIndex;
- int k,m,n;
+ /* Bit pack the video data data */
+ PackCodedVideo(cpi);
- /* predictor multiplier up-left, up, up-right,left, shift */
- ogg_int16_t pc[16][6]={
- {0,0,0,0,0,0},
- {0,0,0,1,0,0}, /* PL */
- {0,0,1,0,0,0}, /* PUR */
- {0,0,53,75,7,127}, /* PUR|PL */
- {0,1,0,0,0,0}, /* PU */
- {0,1,0,1,1,1}, /* PU|PL */
- {0,1,0,0,0,0}, /* PU|PUR */
- {0,0,53,75,7,127}, /* PU|PUR|PL */
- {1,0,0,0,0,0}, /* PUL| */
- {0,0,0,1,0,0}, /* PUL|PL */
- {1,0,1,0,1,1}, /* PUL|PUR */
- {0,0,53,75,7,127}, /* PUL|PUR|PL */
- {0,1,0,0,0,0}, /* PUL|PU */
- {-26,29,0,29,5,31}, /* PUL|PU|PL */
- {3,10,3,0,4,15}, /* PUL|PU|PUR */
- {-26,29,0,29,5,31} /* PUL|PU|PUR|PL */
- };
+ /* End the bit packing run. */
+ /* EndAddBitsToBuffer(cpi); */
- struct SearchPoints {
- int RowOffset;
- int ColOffset;
- } DCSearchPoints[]= {
- {0,-2},{-2,0},{-1,-2},{-2,-1},{-2,1},{-1,2},{-2,-2},{-2,2},{0,-3},
- {-3,0},{-1,-3},{-3,-1},{-3,1},{-1,3},{-2,-3},{-3,-2},{-3,2},{-2,3},
- {0,-4},{-4,0},{-1,-4},{-4,-1},{-4,1},{-1,4},{-3,-3},{-3,3}
- };
+ /* Reconstruct the reference frames */
+ ReconRefFrames(&cpi->pb);
- int DCSearchPointCount = 0;
-
- /* fragment left fragment up-left, fragment up, fragment up-right */
- int fl,ful,fu,fur;
-
- /* value left value up-left, value up, value up-right */
- int vl,vul,vu,vur;
-
- /* fragment number left, up-left, up, up-right */
- int l,ul,u,ur;
-
- /*which predictor constants to use */
- ogg_int16_t wpc;
-
- /* last used inter predictor (Raster Order) */
- ogg_int16_t Last[3]; /* last value used for given frame */
- ogg_int16_t TempInter = 0;
-
- int FragsAcross=cpi->pb.HFragments;
- int FragsDown = cpi->pb.VFragments;
- int FromFragment,ToFragment;
- ogg_int32_t FragIndex;
- int WhichFrame;
- int WhichCase;
+ UpdateFragQIndex(&cpi->pb);
- ogg_int16_t Mode2Frame[] = {
- 1, /* CODE_INTER_NO_MV 0 => Encoded diff from same MB last frame */
- 0, /* CODE_INTRA 1 => DCT Encoded Block */
- 1, /* CODE_INTER_PLUS_MV 2 => Encoded diff from included MV MB last frame */
- 1, /* CODE_INTER_LAST_MV 3 => Encoded diff from MRU MV MB last frame */
- 1, /* CODE_INTER_PRIOR_MV 4 => Encoded diff from included 4 separate MV blocks */
- 2, /* CODE_USING_GOLDEN 5 => Encoded diff from same MB golden frame */
- 2, /* CODE_GOLDEN_MV 6 => Encoded diff from included MV MB golden frame */
- 1 /* CODE_INTER_FOUR_MV 7 => Encoded diff from included 4 separate MV blocks */
- };
+ /* Measure the inter reconstruction error for all the blocks that
+ were coded */
+ // for use as part of the recovery monitoring process in subsequent frames.
+ for ( i = 0; i < cpi->pb.CodedBlockIndex; i++ ) {
+ cpi->LastCodedErrorScore[ cpi->pb.CodedBlockList[i] ] =
+ GetBlockReconErrorSlow( cpi, cpi->pb.CodedBlockList[i] );
+
+ }
+
+ ClearSysState();
+
+ /* Return total number of coded pixels */
+ return coded_pixels;
+}
+
+ogg_uint32_t EncodeData(CP_INSTANCE *cpi){
+ ogg_uint32_t coded_pixels = 0;
- ogg_int16_t PredictedDC;
+ /* Zero the count of tokens so far this frame. */
+ cpi->TotTokenCount = 0;
- /* Initialise the coded block indices variables. These allow
- subsequent linear access to the quad tree ordered list of coded
- blocks */
- cpi->pb.CodedBlockIndex = 0;
+ /* Zero the mode and MV list indices. */
+ cpi->ModeListCount = 0;
+
+ /* Zero Decoder EOB run count */
+ cpi->pb.EOB_Run = 0;
+
+ /* Encode any fragments coded using DCT. */
+ coded_pixels += QuadCodeDisplayFragments (cpi);
+
+ return coded_pixels;
+
+}
+
+ogg_int32_t CalculateMotionErrorforFragments(CP_INSTANCE *cpi,
+ ogg_int32_t CountUsingMV,
+ ogg_int32_t *FragsUsing,
+ MOTION_VECTOR MVect,
+ ogg_int32_t PixelsPerLine){
+ int i;
+ ogg_int32_t NewError = 0;
- /* Set the inter/intra descision control variables. */
- QIndex = Q_TABLE_SIZE - 1;
- while ( (ogg_int32_t) QIndex >= 0 ) {
- if ( (QIndex == 0) ||
- ( cpi->pb.QThreshTable[QIndex] >= cpi->pb.ThisFrameQualityValue) )
- break;
- QIndex --;
- }
+ /* for now 4 motion vector is to hard to recalculate so return huge
+ error!! */
+ if( cpi->pb.FragCodingMethod[0] == CODE_INTER_FOURMV)
+ return HUGE_ERROR;
-
- /* Encode and tokenise the Y, U and V components */
- coded_pixels = QuadCodeComponent(cpi, 0, cpi->pb.YSBRows, cpi->pb.YSBCols,
- cpi->pb.HFragments%4,
- cpi->pb.VFragments%4,
- cpi->pb.Configuration.VideoFrameWidth );
- coded_pixels += QuadCodeComponent(cpi, cpi->pb.YSuperBlocks,
- cpi->pb.UVSBRows,
- cpi->pb.UVSBCols,
- (cpi->pb.HFragments/2)%4,
- (cpi->pb.VFragments/2)%4,
- cpi->pb.Configuration.VideoFrameWidth>>1 );
- coded_pixels += QuadCodeComponent(cpi,
- cpi->pb.YSuperBlocks+cpi->pb.UVSuperBlocks,
- cpi->pb.UVSBRows, cpi->pb.UVSBCols,
- (cpi->pb.HFragments/2)%4,
- (cpi->pb.VFragments/2)%4,
- cpi->pb.Configuration.VideoFrameWidth>>1 );
+ for(i = 0 ; i < CountUsingMV ; i++) {
+ ogg_int32_t FragIndex = FragsUsing[i];
+ ogg_int32_t ThisError = GetMBInterError( cpi,
+ cpi->ConvDestBuffer,
+ cpi->pb.LastFrameRecon,
+ FragIndex, MVect.x,
+ MVect.y, PixelsPerLine );
+
+ NewError += ThisError;
- /* for y,u,v */
- for ( j = 0; j < 3 ; j++) {
- /* pick which fragments based on Y, U, V */
- switch(j){
- case 0: /* y */
- FromFragment = 0;
- ToFragment = cpi->pb.YPlaneFragments;
- FragsAcross = cpi->pb.HFragments;
- FragsDown = cpi->pb.VFragments;
- break;
- case 1: /* u */
- FromFragment = cpi->pb.YPlaneFragments;
- ToFragment = cpi->pb.YPlaneFragments + cpi->pb.UVPlaneFragments ;
- FragsAcross = cpi->pb.HFragments >> 1;
- FragsDown = cpi->pb.VFragments >> 1;
- break;
- case 2: /* v */
- FromFragment = cpi->pb.YPlaneFragments + cpi->pb.UVPlaneFragments;
- ToFragment = cpi->pb.YPlaneFragments + (2 * cpi->pb.UVPlaneFragments) ;
- FragsAcross = cpi->pb.HFragments >> 1;
- FragsDown = cpi->pb.VFragments >> 1;
- break;
- }
+ }
- /* initialize our array of last used DC Components */
- for(k=0;k<3;k++)Last[k]=0;
- i=FromFragment;
+ return NewError;
- /* do prediction on all of Y, U or V */
- for ( m = 0 ; m < FragsDown ; m++) {
- for ( n = 0 ; n < FragsAcross ; n++, i++) {
- cpi->OriginalDC[i] = cpi->pb.QFragData[i][0];
+}
- /* only do 2 prediction if fragment coded and on non intra or
- if all fragments are intra */
- if( cpi->pb.display_fragments[i] ||
- (GetFrameType(&cpi->pb) == BASE_FRAME) ) {
- /* Type of Fragment */
- WhichFrame = Mode2Frame[cpi->pb.FragCodingMethod[i]];
+ogg_uint32_t PickIntra( CP_INSTANCE *cpi, ogg_uint32_t SBRows,
+ ogg_uint32_t SBCols, ogg_uint32_t HExtra,
+ ogg_uint32_t VExtra, ogg_uint32_t PixelsPerLine){
- /* Check Borderline Cases */
- WhichCase = (n==0) + ((m==0) << 1) + ((n+1 == FragsAcross) << 2);
+ ogg_int32_t FragIndex; /* Fragment number */
+ ogg_uint32_t MB, B; /* Macro-Block, Block indices */
+ ogg_uint32_t SBrow; /* Super-Block row number */
+ ogg_uint32_t SBcol; /* Super-Block row number */
+ ogg_uint32_t SB=0; /* Super-Block index, initialised to first of
+ this component */
+
+ ogg_uint32_t UVRow;
+ ogg_uint32_t UVColumn;
+ ogg_uint32_t UVFragOffset;
+
+ /* decide what block type and motion vectors to use on all of the frames */
+ for ( SBrow=0; SBrow<SBRows; SBrow++ ) {
+ for ( SBcol=0; SBcol<SBCols; SBcol++ ) {
+ /* Check its four Macro-Blocks */
+ for ( MB=0; MB<4; MB++ ) {
+ /* There may be MB's lying out of frame which must be
+ ignored. For these MB's Top left block will have a negative
+ Fragment Index. */
+ if ( QuadMapToMBTopLeft(cpi->pb.BlockMap,SB,MB) >= 0 ) {
+
+ cpi->MBCodingMode = CODE_INTRA;
- switch(WhichCase) {
- case 0: /* normal case no border condition */
-
- /* calculate values left, up, up-right and up-left */
- l = i-1;
- u = i - FragsAcross;
- ur = i - FragsAcross + 1;
- ul = i - FragsAcross - 1;
+ /* Now actually code the blocks. */
+ for ( B=0; B<4; B++ ) {
+ FragIndex = QuadMapToIndex1( cpi->pb.BlockMap, SB, MB, B );
+ cpi->pb.FragCodingMethod[FragIndex] = cpi->MBCodingMode;
+ }
+
+ /* Matching fragments in the U and V planes */
+ UVRow = (FragIndex / (cpi->pb.HFragments * 2));
+ UVColumn = (FragIndex % cpi->pb.HFragments) / 2;
+ UVFragOffset = (UVRow * (cpi->pb.HFragments / 2)) + UVColumn;
+
+ cpi->pb.FragCodingMethod[cpi->pb.YPlaneFragments + UVFragOffset] =
+ cpi->MBCodingMode;
+ cpi->pb.FragCodingMethod[cpi->pb.YPlaneFragments +
+ cpi->pb.UVPlaneFragments + UVFragOffset] =
+ cpi->MBCodingMode;
+
+ }
+ }
+
+ /* Next Super-Block */
+ SB++;
+ }
+ }
+ return 0;
+}
- /* calculate values */
- vl = cpi->OriginalDC[l];
- vu = cpi->OriginalDC[u];
- vur = cpi->OriginalDC[ur];
- vul = cpi->OriginalDC[ul];
-
- /* fragment valid for prediction use if coded and it comes
- from same frame as the one we are predicting */
- fl = cpi->pb.display_fragments[l] &&
- (Mode2Frame[cpi->pb.FragCodingMethod[l]] == WhichFrame);
- fu = cpi->pb.display_fragments[u] &&
- (Mode2Frame[cpi->pb.FragCodingMethod[u]] == WhichFrame);
- fur = cpi->pb.display_fragments[ur] &&
- (Mode2Frame[cpi->pb.FragCodingMethod[ur]] == WhichFrame);
- ful = cpi->pb.display_fragments[ul] &&
- (Mode2Frame[cpi->pb.FragCodingMethod[ul]] == WhichFrame);
-
- /* calculate which predictor to use */
- wpc = (fl*PL) | (fu*PU) | (ful*PUL) | (fur*PUR);
+void AddMotionVector(CP_INSTANCE *cpi,
+ MOTION_VECTOR *ThisMotionVector) {
+ cpi->MVList[cpi->MvListCount].x = ThisMotionVector->x;
+ cpi->MVList[cpi->MvListCount].y = ThisMotionVector->y;
+ cpi->MvListCount++;
+}
- break;
+void SetFragMotionVectorAndMode(CP_INSTANCE *cpi,
+ ogg_int32_t FragIndex,
+ MOTION_VECTOR *ThisMotionVector){
+ /* Note the coding mode and vector for each block */
+ cpi->pb.FragMVect[FragIndex].x = ThisMotionVector->x;
+ cpi->pb.FragMVect[FragIndex].y = ThisMotionVector->y;
+ cpi->pb.FragCodingMethod[FragIndex] = cpi->MBCodingMode;
+}
- case 1: /* n == 0 Left Column */
-
- /* calculate values left, up, up-right and up-left */
- u = i - FragsAcross;
- ur = i - FragsAcross + 1;
-
- /* calculate values */
- vu = cpi->OriginalDC[u];
- vur = cpi->OriginalDC[ur];
-
- /* fragment valid for prediction if coded and it comes
- from same frame as the one we are predicting */
- fu = cpi->pb.display_fragments[u] &&
- (Mode2Frame[cpi->pb.FragCodingMethod[u]] == WhichFrame);
- fur = cpi->pb.display_fragments[ur] &&
- (Mode2Frame[cpi->pb.FragCodingMethod[ur]] == WhichFrame);
+void SetMBMotionVectorsAndMode(CP_INSTANCE *cpi,
+ ogg_int32_t YFragIndex,
+ ogg_int32_t UFragIndex,
+ ogg_int32_t VFragIndex,
+ MOTION_VECTOR *ThisMotionVector){
+ SetFragMotionVectorAndMode(cpi, YFragIndex, ThisMotionVector);
+ SetFragMotionVectorAndMode(cpi, YFragIndex + 1, ThisMotionVector);
+ SetFragMotionVectorAndMode(cpi, YFragIndex + cpi->pb.HFragments,
+ ThisMotionVector);
+ SetFragMotionVectorAndMode(cpi, YFragIndex + cpi->pb.HFragments + 1,
+ ThisMotionVector);
+ SetFragMotionVectorAndMode(cpi, UFragIndex, ThisMotionVector);
+ SetFragMotionVectorAndMode(cpi, VFragIndex, ThisMotionVector);
+}
+
+ogg_uint32_t PickModes(CP_INSTANCE *cpi,
+ ogg_uint32_t SBRows, ogg_uint32_t SBCols,
+ ogg_uint32_t HExtra, ogg_uint32_t VExtra,
+ ogg_uint32_t PixelsPerLine,
+ ogg_uint32_t *InterError, ogg_uint32_t *IntraError) {
+ ogg_int32_t YFragIndex;
+ ogg_int32_t UFragIndex;
+ ogg_int32_t VFragIndex;
+ ogg_uint32_t MB, B; /* Macro-Block, Block indices */
+ ogg_uint32_t SBrow; /* Super-Block row number */
+ ogg_uint32_t SBcol; /* Super-Block row number */
+ ogg_uint32_t SB=0; /* Super-Block index, initialised to first
+ of this component */
+
+ ogg_uint32_t MBIntraError; /* Intra error for macro block */
+ ogg_uint32_t MBGFError; /* Golden frame macro block error */
+ ogg_uint32_t MBGF_MVError; /* Golden frame plus MV error */
+ ogg_uint32_t LastMBGF_MVError; /* Golden frame error with
+ last used GF motion
+ vector. */
+ ogg_uint32_t MBInterError; /* Inter no MV macro block error */
+ ogg_uint32_t MBLastInterError; /* Inter with last used MV */
+ ogg_uint32_t MBPriorLastInterError; /* Inter with prior last MV */
+ ogg_uint32_t MBInterMVError; /* Inter MV macro block error */
+ ogg_uint32_t MBInterMVExError; /* Inter MV (exhaustive
+ search) macro block error */
+ ogg_uint32_t MBInterFOURMVError; /* Inter MV error when using 4
+ motion vectors per macro
+ block */
+ ogg_uint32_t BestError; /* Best error so far. */
+
+ MOTION_VECTOR FourMVect[6]; /* storage for last used vectors (one
+ entry for each block in MB) */
+ MOTION_VECTOR LastInterMVect; /* storage for last used Inter frame
+ MB motion vector */
+ MOTION_VECTOR PriorLastInterMVect; /* storage for prior last used
+ Inter frame MB motion vector */
+ MOTION_VECTOR TmpMVect; /* Temporary MV storage */
+ MOTION_VECTOR LastGFMVect; /* storage for last used Golden
+ Frame MB motion vector */
+ MOTION_VECTOR InterMVect; /* storage for motion vector */
+ MOTION_VECTOR InterMVectEx; /* storage for motion vector result
+ from exhaustive search */
+ MOTION_VECTOR GFMVect; /* storage for motion vector */
+ MOTION_VECTOR ZeroVect;
+
+ ogg_uint32_t UVRow;
+ ogg_uint32_t UVColumn;
+ ogg_uint32_t UVFragOffset;
+
+ int MBCodedFlag;
+ unsigned char QIndex;
+
+ /* initialize error scores */
+ *InterError = 0;
+ *IntraError = 0;
+
+ /* clear down the default motion vector. */
+ cpi->MvListCount = 0;
+ FourMVect[0].x = 0;
+ FourMVect[0].y = 0;
+ FourMVect[1].x = 0;
+ FourMVect[1].y = 0;
+ FourMVect[2].x = 0;
+ FourMVect[2].y = 0;
+ FourMVect[3].x = 0;
+ FourMVect[3].y = 0;
+ FourMVect[4].x = 0;
+ FourMVect[4].y = 0;
+ FourMVect[5].x = 0;
+ FourMVect[5].y = 0;
+ LastInterMVect.x = 0;
+ LastInterMVect.y = 0;
+ PriorLastInterMVect.x = 0;
+ PriorLastInterMVect.y = 0;
+ LastGFMVect.x = 0;
+ LastGFMVect.y = 0;
+ InterMVect.x = 0;
+ InterMVect.y = 0;
+ GFMVect.x = 0;
+ GFMVect.y = 0;
+
+ ZeroVect.x = 0;
+ ZeroVect.y = 0;
+
+ QIndex = cpi->pb.FrameQIndex;
- /* calculate which predictor to use */
- wpc = (fu*PU) | (fur*PUR);
-
- break;
- case 2: /* m == 0 Top Row */
- case 6: /* m == 0 and n+1 == FragsAcross or Top Row Right Column */
- /* calculate values left, up, up-right and up-left */
- l = i-1;
-
- /* calculate values */
- vl = cpi->OriginalDC[l];
-
- /* fragment valid for prediction if coded and it comes
- from same frame as the one we are predicting */
- fl = cpi->pb.display_fragments[l] &&
- (Mode2Frame[cpi->pb.FragCodingMethod[l]] == WhichFrame);
-
- /* calculate which predictor to use */
- wpc = (fl*PL) ;
-
- break;
-
- case 3: /* n == 0 & m == 0 Top Row Left Column */
+ /* change the quatization matrix to the one at best Q to compute the
+ new error score */
+ cpi->MinImprovementForNewMV = (MvThreshTable[QIndex] << 12);
+ cpi->InterTripOutThresh = (5000<<12);
+ cpi->MVChangeFactor = MVChangeFactorTable[QIndex]; /* 0.9 */
+
+ if ( cpi->QuickCompress ) {
+ cpi->ExhaustiveSearchThresh = (1000<<12);
+ cpi->FourMVThreshold = (2500<<12);
+ } else {
+ cpi->ExhaustiveSearchThresh = (250<<12);
+ cpi->FourMVThreshold = (500<<12);
+ }
+ cpi->MinImprovementForFourMV = cpi->MinImprovementForNewMV * 4;
+
+ if(cpi->MinImprovementForFourMV < (40<<12))
+ cpi->MinImprovementForFourMV = (40<<12);
+
+ cpi->FourMvChangeFactor = 8; /* cpi->MVChangeFactor - 0.05; */
+
+ /* decide what block type and motion vectors to use on all of the frames */
+ for ( SBrow=0; SBrow<SBRows; SBrow++ ) {
+ for ( SBcol=0; SBcol<SBCols; SBcol++ ) {
+ /* Check its four Macro-Blocks */
+ for ( MB=0; MB<4; MB++ ) {
+ /* There may be MB's lying out of frame which must be
+ ignored. For these MB's Top left block will have a negative
+ Fragment Index. */
+ if ( QuadMapToMBTopLeft(cpi->pb.BlockMap,SB,MB) < 0 ) continue;
+
+ /* Is the current macro block coded (in part or in whole) */
+ MBCodedFlag = 0;
+ for ( B=0; B<4; B++ ) {
+ YFragIndex = QuadMapToIndex1( cpi->pb.BlockMap, SB, MB, B );
+
+ /* Does Block lie in frame: */
+ if ( YFragIndex >= 0 ) {
+ /* In Frame: Is it coded: */
+ if ( cpi->pb.display_fragments[YFragIndex] ) {
+ MBCodedFlag = 1;
+ break;
+ }
+ } else
+ MBCodedFlag = 0;
+ }
+
+ /* This one isn't coded go to the next one */
+ if(!MBCodedFlag) continue;
- wpc = 0;
- break;
+ /* Calculate U and V FragIndex from YFragIndex */
+ YFragIndex = QuadMapToMBTopLeft(cpi->pb.BlockMap, SB,MB);
+ UVRow = (YFragIndex / (cpi->pb.HFragments * 2));
+ UVColumn = (YFragIndex % cpi->pb.HFragments) / 2;
+ UVFragOffset = (UVRow * (cpi->pb.HFragments / 2)) + UVColumn;
+ UFragIndex = cpi->pb.YPlaneFragments + UVFragOffset;
+ VFragIndex = cpi->pb.YPlaneFragments + cpi->pb.UVPlaneFragments +
+ UVFragOffset;
+
+
+ /**************************************************************
+ Find the block choice with the lowest error
- case 4: /* n+1 == FragsAcross : Right Column */
+ NOTE THAT if U or V is coded but no Y from a macro block then
+ the mode will be CODE_INTER_NO_MV as this is the default
+ state to which the mode data structure is initialised in
+ encoder and decoder at the start of each frame. */
- /* calculate values left, up, up-right and up-left */
- l = i-1;
- u = i - FragsAcross;
- ul = i - FragsAcross - 1;
-
- /* calculate values */
- vl = cpi->OriginalDC[l];
- vu = cpi->OriginalDC[u];
- vul = cpi->OriginalDC[ul];
-
- /* fragment valid for prediction if coded and it comes
- from same frame as the one we are predicting */
- fl = cpi->pb.display_fragments[l] &&
- (Mode2Frame[cpi->pb.FragCodingMethod[l]] == WhichFrame);
- fu = cpi->pb.display_fragments[u] &&
- (Mode2Frame[cpi->pb.FragCodingMethod[u]] == WhichFrame);
- ful = cpi->pb.display_fragments[ul] &&
- (Mode2Frame[cpi->pb.FragCodingMethod[ul]] == WhichFrame);
-
- /* calculate which predictor to use */
- wpc = (fl*PL) | (fu*PU) | (ful*PUL) ;
- break;
+ BestError = HUGE_ERROR;
+
- }
-
- if(wpc==0) {
- FragIndex = 1;
-
- /* find the nearest one that is coded */
- for( k = 0; k < DCSearchPointCount ; k++) {
- FragIndex = i + DCSearchPoints[k].RowOffset *
- FragsAcross + DCSearchPoints[k].ColOffset;
-
- if( FragIndex - FromFragment > 0 ) {
- if(cpi->pb.display_fragments[FragIndex] &&
- (Mode2Frame[cpi->pb.FragCodingMethod[FragIndex]] ==
- WhichFrame)) {
- cpi->pb.QFragData[i][0] -= cpi->OriginalDC[FragIndex];
- FragIndex = 0;
- break;
- }
- }
- }
-
- /* if none matched fall back to the last one ever */
- if(FragIndex) cpi->pb.QFragData[i][0] -= Last[WhichFrame];
-
- } else {
-
- /* don't do divide if divisor is 1 or 0 */
- PredictedDC = (pc[wpc][0]*vul + pc[wpc][1] * vu +
- pc[wpc][2] * vur + pc[wpc][3] * vl );
-
- /* if we need to do a shift */
- if(pc[wpc][4] != 0 ) {
+ /* Look at the intra coding error. */
+ MBIntraError = GetMBIntraError( cpi, YFragIndex, PixelsPerLine );
+ BestError = (BestError > MBIntraError) ? MBIntraError : BestError;
+
+ /* Get the golden frame error */
+ MBGFError = GetMBInterError( cpi, cpi->ConvDestBuffer,
+ cpi->pb.GoldenFrame, YFragIndex,
+ 0, 0, PixelsPerLine );
+ BestError = (BestError > MBGFError) ? MBGFError : BestError;
+
+ /* Calculate the 0,0 case. */
+ MBInterError = GetMBInterError( cpi, cpi->ConvDestBuffer,
+ cpi->pb.LastFrameRecon,
+ YFragIndex, 0, 0, PixelsPerLine );
+ BestError = (BestError > MBInterError) ? MBInterError : BestError;
+
+ /* Measure error for last MV */
+ MBLastInterError = GetMBInterError( cpi, cpi->ConvDestBuffer,
+ cpi->pb.LastFrameRecon,
+ YFragIndex, LastInterMVect.x,
+ LastInterMVect.y, PixelsPerLine );
+ BestError = (BestError > MBLastInterError) ?
+ MBLastInterError : BestError;
+
+ /* Measure error for prior last MV */
+ MBPriorLastInterError = GetMBInterError( cpi, cpi->ConvDestBuffer,
+ cpi->pb.LastFrameRecon,
+ YFragIndex,
+ PriorLastInterMVect.x,
+ PriorLastInterMVect.y,
+ PixelsPerLine );
+ BestError = (BestError > MBPriorLastInterError) ?
+ MBPriorLastInterError : BestError;
- /* If negative add in the negative correction factor */
- PredictedDC += (HIGHBITDUPPED(PredictedDC) & pc[wpc][5]);
- /* Shift in lieu of a divide */
- PredictedDC >>= pc[wpc][4];
+ /* Temporarily force usage of no motionvector blocks */
+ MBInterMVError = HUGE_ERROR;
+ InterMVect.x = 0; /* Set 0,0 motion vector */
+ InterMVect.y = 0;
+
+ /* If the best error is above the required threshold search
+ for a new inter MV */
+ if ( BestError > cpi->MinImprovementForNewMV ) {
+ /* Use a mix of heirachical and exhaustive searches for
+ quick mode. */
+ if ( cpi->QuickCompress ) {
+ MBInterMVError = GetMBMVInterError( cpi, cpi->pb.LastFrameRecon,
+ YFragIndex, PixelsPerLine,
+ cpi->MVPixelOffsetY,
+ &InterMVect );
+
+ /* If we still do not have a good match try an exhaustive
+ MBMV search */
+ if ( (MBInterMVError > cpi->ExhaustiveSearchThresh) &&
+ (BestError > cpi->ExhaustiveSearchThresh) ) {
+ MBInterMVExError =
+ GetMBMVExhaustiveSearch( cpi, cpi->pb.LastFrameRecon,
+ YFragIndex, PixelsPerLine,
+ &InterMVectEx );
+
+ /* Is the Variance measure for the EX search
+ better... If so then use it. */
+ if ( MBInterMVExError < MBInterMVError ) {
+ MBInterMVError = MBInterMVExError;
+ InterMVect.x = InterMVectEx.x;
+ InterMVect.y = InterMVectEx.y;
+ }
}
-
- /* check for outranging on the two predictors that can outrange */
- switch(wpc) {
- case 13: /* pul pu pl */
- case 15: /* pul pu pur pl */
- if( abs(PredictedDC - vu) > 128)
- PredictedDC = vu;
- else if( abs(PredictedDC - vl) > 128)
- PredictedDC = vl;
- else if( abs(PredictedDC - vul) > 128)
- PredictedDC = vul;
- break;
- }
-
- cpi->pb.QFragData[i][0] -= PredictedDC;
+ }else{
+ /* Use an exhaustive search */
+ MBInterMVError =
+ GetMBMVExhaustiveSearch( cpi, cpi->pb.LastFrameRecon,
+ YFragIndex, PixelsPerLine,
+ &InterMVect );
}
+
- /* Save the last fragment coded for whatever frame we are
- predicting from */
+ /* Is the improvement, if any, good enough to justify a new MV */
+ if ( (16 * MBInterMVError < (BestError * cpi->MVChangeFactor)) &&
+ ((MBInterMVError + cpi->MinImprovementForNewMV) < BestError) ){
+ BestError = MBInterMVError;
+ }
- Last[WhichFrame] = cpi->OriginalDC[i];
+ }
+
+ /* If the best error is still above the required threshold
+ search for a golden frame MV */
+ MBGF_MVError = HUGE_ERROR;
+ GFMVect.x = 0; /* Set 0,0 motion vector */
+ GFMVect.y = 0;
+ if ( BestError > cpi->MinImprovementForNewMV ) {
+ /* Do an MV search in the golden reference frame */
+ MBGF_MVError = GetMBMVInterError( cpi, cpi->pb.GoldenFrame,
+ YFragIndex, PixelsPerLine,
+ cpi->MVPixelOffsetY, &GFMVect );
+
+ /* Measure error for last GFMV */
+ LastMBGF_MVError = GetMBInterError( cpi, cpi->ConvDestBuffer,
+ cpi->pb.GoldenFrame,
+ YFragIndex, LastGFMVect.x,
+ LastGFMVect.y, PixelsPerLine );
+
+ /* Check against last GF motion vector and reset if the
+ search has thrown a worse result. */
+ if ( LastMBGF_MVError < MBGF_MVError ) {
+ GFMVect.x = LastGFMVect.x;
+ GFMVect.y = LastGFMVect.y;
+ MBGF_MVError = LastMBGF_MVError;
+ }else{
+ LastGFMVect.x = GFMVect.x;
+ LastGFMVect.y = GFMVect.y;
+ }
+ /* Is the improvement, if any, good enough to justify a new MV */
+ if ( (16 * MBGF_MVError < (BestError * cpi->MVChangeFactor)) &&
+ ((MBGF_MVError + cpi->MinImprovementForNewMV) < BestError) ) {
+ BestError = MBGF_MVError;
+ }
}
- }
- }
- }
- /* Pack DC tokens and adjust the ones we couldn't predict 2d */
- for ( i = 0; i < cpi->pb.CodedBlockIndex; i++ ) {
- /* Get the linear index for the current coded fragment. */
- FragIndex = cpi->pb.CodedBlockList[i];
- coded_pixels += DPCMTokenizeBlock ( cpi, FragIndex,
- cpi->pb.Configuration.VideoFrameWidth);
-
- }
+ /* Finally... If the best error is still to high then consider
+ the 4MV mode */
+ MBInterFOURMVError = HUGE_ERROR;
+ if ( BestError > cpi->FourMVThreshold ) {
+ /* Get the 4MV error. */
+ MBInterFOURMVError =
+ GetFOURMVExhaustiveSearch( cpi, cpi->pb.LastFrameRecon,
+ YFragIndex, PixelsPerLine, FourMVect );
+
+ /* If the improvement is great enough then use the four MV mode */
+ if ( ((MBInterFOURMVError + cpi->MinImprovementForFourMV) <
+ BestError) && (16 * MBInterFOURMVError <
+ (BestError * cpi->FourMvChangeFactor))) {
+ BestError = MBInterFOURMVError;
+ }
+ }
+
+ /********************************************************
+ end finding the best error
+ *******************************************************
+
+ Figure out what to do with the block we chose
+
+ Over-ride and force intra if error high and Intra error similar
+ Now choose a mode based on lowest error (with bias towards no MV) */
+
+ if ( (BestError > cpi->InterTripOutThresh) &&
+ (10 * BestError > MBIntraError * 7 ) ) {
+ cpi->MBCodingMode = CODE_INTRA;
+ SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
+ VFragIndex,&ZeroVect);
+ } else if ( BestError == MBInterError ) {
+ cpi->MBCodingMode = CODE_INTER_NO_MV;
+ SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
+ VFragIndex,&ZeroVect);
+ } else if ( BestError == MBGFError ) {
+ cpi->MBCodingMode = CODE_USING_GOLDEN;
+ SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
+ VFragIndex,&ZeroVect);
+ } else if ( BestError == MBLastInterError ) {
+ cpi->MBCodingMode = CODE_INTER_LAST_MV;
+ SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
+ VFragIndex,&LastInterMVect);
+ } else if ( BestError == MBPriorLastInterError ) {
+ cpi->MBCodingMode = CODE_INTER_PRIOR_LAST;
+ SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
+ VFragIndex,&PriorLastInterMVect);
+
+ /* Swap the prior and last MV cases over */
+ TmpMVect.x = PriorLastInterMVect.x;
+ TmpMVect.y = PriorLastInterMVect.y;
+ PriorLastInterMVect.x = LastInterMVect.x;
+ PriorLastInterMVect.y = LastInterMVect.y;
+ LastInterMVect.x = TmpMVect.x;
+ LastInterMVect.y = TmpMVect.y;
+ } else if ( BestError == MBInterMVError ) {
- /* Bit pack the video data data */
- PackCodedVideo(cpi);
+ cpi->MBCodingMode = CODE_INTER_PLUS_MV;
+ SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
+ VFragIndex,&InterMVect);
+
+ /* Update Prior last mv with last mv */
+ PriorLastInterMVect.x = LastInterMVect.x;
+ PriorLastInterMVect.y = LastInterMVect.y;
+
+ /* Note last inter MV for future use */
+ LastInterMVect.x = InterMVect.x;
+ LastInterMVect.y = InterMVect.y;
+
+ AddMotionVector( cpi, &InterMVect);
- /* End the bit packing run. */
- /* EndAddBitsToBuffer(cpi); */
+ } else if ( BestError == MBGF_MVError ) {
- /* Reconstruct the reference frames */
- ReconRefFrames(&cpi->pb);
+ cpi->MBCodingMode = CODE_GOLDEN_MV;
+ SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
+ VFragIndex,&GFMVect);
+
+ /* Note last inter GF MV for future use */
+ LastGFMVect.x = GFMVect.x;
+ LastGFMVect.y = GFMVect.y;
+
+ AddMotionVector( cpi, &GFMVect);
+ } else if ( BestError == MBInterFOURMVError ) {
+ cpi->MBCodingMode = CODE_INTER_FOURMV;
+
+ /* Calculate the UV vectors as the average of the Y plane ones. */
+ /* First .x component */
+ FourMVect[4].x = FourMVect[0].x + FourMVect[1].x +
+ FourMVect[2].x + FourMVect[3].x;
+ if ( FourMVect[4].x >= 0 )
+ FourMVect[4].x = (FourMVect[4].x + 2) / 4;
+ else
+ FourMVect[4].x = (FourMVect[4].x - 2) / 4;
+ FourMVect[5].x = FourMVect[4].x;
+
+ /* Then .y component */
+ FourMVect[4].y = FourMVect[0].y + FourMVect[1].y +
+ FourMVect[2].y + FourMVect[3].y;
+ if ( FourMVect[4].y >= 0 )
+ FourMVect[4].y = (FourMVect[4].y + 2) / 4;
+ else
+ FourMVect[4].y = (FourMVect[4].y - 2) / 4;
+ FourMVect[5].y = FourMVect[4].y;
+
+ SetFragMotionVectorAndMode(cpi, YFragIndex, &FourMVect[0]);
+ SetFragMotionVectorAndMode(cpi, YFragIndex + 1, &FourMVect[1]);
+ SetFragMotionVectorAndMode(cpi, YFragIndex + cpi->pb.HFragments,
+ &FourMVect[2]);
+ SetFragMotionVectorAndMode(cpi, YFragIndex + cpi->pb.HFragments + 1,
+ &FourMVect[3]);
+ SetFragMotionVectorAndMode(cpi, UFragIndex, &FourMVect[4]);
+ SetFragMotionVectorAndMode(cpi, VFragIndex, &FourMVect[5]);
+
+ /* Note the four MVs values for current macro-block. */
+ AddMotionVector( cpi, &FourMVect[0]);
+ AddMotionVector( cpi, &FourMVect[1]);
+ AddMotionVector( cpi, &FourMVect[2]);
+ AddMotionVector( cpi, &FourMVect[3]);
+
+ /* Update Prior last mv with last mv */
+ PriorLastInterMVect.x = LastInterMVect.x;
+ PriorLastInterMVect.y = LastInterMVect.y;
+
+ /* Note last inter MV for future use */
+ LastInterMVect.x = FourMVect[3].x;
+ LastInterMVect.y = FourMVect[3].y;
+
+ } else {
- UpdateFragQIndex(&cpi->pb);
-
- /* Measure the inter reconstruction error for all the blocks that
- were coded */
- // for use as part of the recovery monitoring process in subsequent frames.
- for ( i = 0; i < cpi->pb.CodedBlockIndex; i++ ) {
- cpi->LastCodedErrorScore[ cpi->pb.CodedBlockList[i] ] =
- cpi->GetBlockReconError( cpi, cpi->pb.CodedBlockList[i] );
-
- }
+ cpi->MBCodingMode = CODE_INTRA;
+ SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
+ VFragIndex,&ZeroVect);
+ }
- cpi->pb.ClearSysState();
- /* Return total number of coded pixels */
- return coded_pixels;
+ /* setting up mode specific block types
+ *******************************************************/
+
+ *InterError += (BestError>>8);
+ *IntraError += (MBIntraError>>8);
+
+
+ }
+ SB++;
+
+ }
+ }
+
+ ClearSysState();
+
+ /* Return number of pixels coded */
+ return 0;
}
void WriteFrameHeader( CP_INSTANCE *cpi) {
ogg_uint32_t i;
- oggpack_buffer *opb=cpi.oggbuffer;
+ oggpack_buffer *opb=&cpi->oggbuffer;
/* Output the frame type (base/key frame or inter frame) */
- oggpackB_write( opb, (UINT32)cpi->pb.FrameType, 1 );
+ oggpackB_write( opb, cpi->pb.FrameType, 1 );
/* usused set to 0 allways */
oggpackB_write( opb, 0, 1 );
@@ -1609,14 +1610,14 @@
/* If the frame was a base frame then write out the frame dimensions. */
if ( cpi->pb.FrameType == BASE_FRAME ) {
- oggpackB_write( opb, (UINT32)0, 8 );
- oggpackB_write( opb, (UINT32)cpi->pb.Vp3VersionNo, 5 );
+ oggpackB_write( opb, 0, 8 );
+ oggpackB_write( opb, cpi->pb.Vp3VersionNo, 5 );
/* Key frame type / method */
- oggpackB_write( opb, (UINT32)cpi->pb.KeyFrameType, 1 );
+ oggpackB_write( opb, cpi->pb.KeyFrameType, 1 );
/* Spare configuration bits */
- oggpackB_write( opb, (UINT32)0, 2 );
+ oggpackB_write( opb, 0, 2 );
}
}
<p><p>1.3 +336 -21 theora/lib/encoder_internal.h
Index: encoder_internal.h
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/encoder_internal.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- encoder_internal.h 17 Sep 2002 07:01:33 -0000 1.2
+++ encoder_internal.h 18 Sep 2002 08:56:56 -0000 1.3
@@ -11,11 +11,66 @@
********************************************************************
function:
- last mod: $Id: encoder_internal.h,v 1.2 2002/09/17 07:01:33 xiphmont Exp $
+ last mod: $Id: encoder_internal.h,v 1.3 2002/09/18 08:56:56 xiphmont Exp $
********************************************************************/
#include <ogg/ogg.h>
+#include "huffman.h"
+
+#define CURRENT_ENCODE_VERSION 1
+#define HUGE_ERROR (1<<28) /* Out of range test value */
+
+/* Baseline dct height and width. */
+#define BLOCK_HEIGHT_WIDTH 8
+
+/* Baseline dct block size */
+#define BLOCK_SIZE (BLOCK_HEIGHT_WIDTH * BLOCK_HEIGHT_WIDTH)
+
+/* Border is for unrestricted mv's */
+#define UMV_BORDER 16
+#define STRIDE_EXTRA (UMV_BORDER * 2)
+#define Q_TABLE_SIZE 64
+
+#define BASE_FRAME 0
+#define NORMAL_FRAME 1
+
+#define MAX_MODES 8
+#define MODE_BITS 3
+#define MODE_METHODS 8
+#define MODE_METHOD_BITS 3
+
+/* Different key frame types/methods */
+#define DCT_KEY_FRAME 0
+
+#define KEY_FRAME_CONTEXT 5
+
+/* Preprocessor defines */
+#define MAX_PREV_FRAMES 16
+
+/* Number of search sites for a 4-step search (at pixel accuracy) */
+#define MAX_SEARCH_SITES 33
+
+#define VERY_BEST_Q 10
+#define MIN_BPB_FACTOR 0.3
+#define MAX_BPB_FACTOR 3.0
+
+typedef enum{
+ SCP_CONFIGURE_PP
+} SCP_SETTINGS;
+
+typedef struct CONFIG_TYPE{
+ /* The size of the surface we want to draw to */
+ ogg_uint32_t VideoFrameWidth;
+ ogg_uint32_t VideoFrameHeight;
+
+ ogg_uint32_t YStride;
+ ogg_uint32_t UVStride;
+
+ /* The number of horizontal and vertical blocks encoded */
+ ogg_uint32_t HFragPixels;
+ ogg_uint32_t VFragPixels;
+} CONFIG_TYPE;
typedef struct CONFIG_TYPE2{
ogg_uint32_t TargetBandwidth;
@@ -30,6 +85,11 @@
} CONFIG_TYPE2;
+typedef struct coeffNode{
+ int i;
+ struct coeffNode *next;
+} COEFFNODE;
+
typedef struct{
unsigned char * Yuv0ptr;
unsigned char * Yuv1ptr;
@@ -52,29 +112,13 @@
ogg_int32_t y;
} MOTION_VECTOR;
+typedef MOTION_VECTOR COORDINATE;
+
typedef ogg_int16_t Q_LIST_ENTRY;
typedef Q_LIST_ENTRY Q_LIST[64];
typedef struct PP_INSTANCE {
ogg_uint32_t PrevFrameLimit;
- ogg_uint32_t *ScanPixelIndexTableAlloc;
- signed char *ScanDisplayFragmentsAlloc;
-
- signed char *PrevFragmentsAlloc[MAX_PREV_FRAMES];
-
- ogg_uint32_t *FragScoresAlloc; /* The individual frame difference ratings. */
- signed char *SameGreyDirPixelsAlloc;
- signed char *BarBlockMapAlloc;
-
- /* Number of pixels changed by diff threshold in row of a fragment. */
- unsigned char *FragDiffPixelsAlloc;
-
- unsigned char *PixelScoresAlloc;
- unsigned char *PixelChangedMapAlloc;
- unsigned char *ChLocalsAlloc;
- ogg_int16_t *yuv_differencesAlloc;
- ogg_int32_t *RowChangedPixelsAlloc;
- signed char *TmpCodedMapAlloc;
ogg_uint32_t *ScanPixelIndexTable;
signed char *ScanDisplayFragments;
@@ -188,6 +232,259 @@
} PP_INSTANCE;
+
+typedef struct {
+ int bitsinremainder; /* # of bits still used in remainder */
+ ogg_uint32_t remainder; /* remaining bits from original long */
+ unsigned char *position;/* character pointer position within data */
+ unsigned char *origin; /* starting point of original data */
+} BITREADER;
+
+typedef enum{
+ CODE_INTER_NO_MV = 0x0, /* INTER prediction, (0,0) motion
+ vector implied. */
+ CODE_INTRA = 0x1, /* INTRA i.e. no prediction. */
+ CODE_INTER_PLUS_MV = 0x2, /* INTER prediction, non zero motion
+ vector. */
+ CODE_INTER_LAST_MV = 0x3, /* Use Last Motion vector */
+ CODE_INTER_PRIOR_LAST = 0x4, /* Prior last motion vector */
+ CODE_USING_GOLDEN = 0x5, /* 'Golden frame' prediction (no MV). */
+ CODE_GOLDEN_MV = 0x6, /* 'Golden frame' prediction plus MV. */
+ CODE_INTER_FOURMV = 0x7 /* Inter prediction 4MV per macro block. */
+} CODING_MODE;
+
+typedef struct HUFF_ENTRY {
+ struct HUFF_ENTRY *ZeroChild;
+ struct HUFF_ENTRY *OneChild;
+ struct HUFF_ENTRY *Previous;
+ struct HUFF_ENTRY *Next;
+ ogg_int32_t Value;
+ ogg_uint32_t Frequency;
+
+} HUFF_ENTRY;
+
+typedef struct PB_INSTANCE {
+ /***********************************************************************
+ Bitstream input and Output Pointers
+ ************************************************************************/
+
+ /* Current access points for input and output buffers */
+ BITREADER br;
+
+ /***********************************************************************/
+ /* Decoder and Frame Type Information */
+ unsigned char Vp3VersionNo;
+
+ int DecoderErrorCode;
+ int FramesHaveBeenSkipped;
+ int SkipYUVtoRGB; /* Skip conversion */
+ int OutputRGB; /* Output To RGB */
+
+ int PostProcessEnabled;
+
+ ogg_uint32_t PostProcessingLevel; /* Perform post processing */
+ ogg_uint32_t ProcessorFrequency; /* CPU frequency */
+ ogg_uint32_t CPUFree;
+
+
+ /* Frame Info */
+ CODING_MODE CodingMode;
+ unsigned char FrameType;
+ unsigned char KeyFrameType;
+ ogg_uint32_t QualitySetting;
+ ogg_uint32_t FrameQIndex; /* Quality specified as a
+ table index */
+ ogg_uint32_t ThisFrameQualityValue; /* Quality value for this frame */
+ ogg_uint32_t LastFrameQualityValue; /* Last Frame's Quality */
+ ogg_int32_t CodedBlockIndex; /* Number of Coded Blocks */
+ ogg_uint32_t CodedBlocksThisFrame; /* Index into coded blocks */
+ ogg_uint32_t FrameSize; /* The number of bytes in the frame. */
+
+ /**********************************************************************/
+ /* Frame Size & Index Information */
+ CONFIG_TYPE Configuration; /* frame configuration */
+
+ ogg_uint32_t YPlaneSize;
+ ogg_uint32_t UVPlaneSize;
+ ogg_uint32_t VFragments;
+ ogg_uint32_t HFragments;
+ ogg_uint32_t UnitFragments;
+ ogg_uint32_t YPlaneFragments;
+ ogg_uint32_t UVPlaneFragments;
+
+ ogg_uint32_t ReconYPlaneSize;
+ ogg_uint32_t ReconUVPlaneSize;
+
+ ogg_uint32_t YDataOffset;
+ ogg_uint32_t UDataOffset;
+ ogg_uint32_t VDataOffset;
+ ogg_uint32_t ReconYDataOffset;
+ ogg_uint32_t ReconUDataOffset;
+ ogg_uint32_t ReconVDataOffset;
+ ogg_uint32_t YSuperBlocks; /* Number of SuperBlocks in a Y frame */
+ ogg_uint32_t UVSuperBlocks; /* Number of SuperBlocks in a U or V frame */
+ ogg_uint32_t SuperBlocks; /* Total number of SuperBlocks in a
+ Y,U,V frame */
+
+ ogg_uint32_t YSBRows; /* Number of rows of SuperBlocks in a
+ Y frame */
+ ogg_uint32_t YSBCols; /* Number of cols of SuperBlocks in a
+ Y frame */
+ ogg_uint32_t UVSBRows; /* Number of rows of SuperBlocks in a
+ U or V frame */
+ ogg_uint32_t UVSBCols; /* Number of cols of SuperBlocks in a
+ U or V frame */
+
+ ogg_uint32_t YMacroBlocks; /* Number of Macro-Blocks in Y component */
+ ogg_uint32_t UVMacroBlocks; /* Number of Macro-Blocks in U/V component */
+ ogg_uint32_t MacroBlocks; /* Total number of Macro-Blocks */
+
+ /**********************************************************************/
+ /* Frames */
+ YUV_BUFFER_ENTRY *ThisFrameRecon;
+ YUV_BUFFER_ENTRY *GoldenFrame;
+ YUV_BUFFER_ENTRY *LastFrameRecon;
+ YUV_BUFFER_ENTRY *PostProcessBuffer;
+ YUV_BUFFER_ENTRY *ScaleBuffer; /* new buffer for testing new loop fi
+ ltering scheme */
+
+ unsigned char *bmp_dptr0;
+
+ ogg_int32_t *BoundingValuePtr;
+
+ /**********************************************************************/
+ /* Fragment Information */
+ ogg_uint32_t *pixel_index_table; /* start address of first
+ pixel of fragment in
+ source */
+ ogg_uint32_t *recon_pixel_index_table; /* start address of first
+ pixel in recon buffer */
+
+ unsigned char *display_fragments; /* Fragment update map */
+ unsigned char *skipped_display_fragments;/* whether fragment YUV
+ Conversion and update is to be
+ skipped */
+ ogg_int32_t *CodedBlockList; /* A list of fragment indices for
+ coded blocks. */
+ MOTION_VECTOR *FragMVect; /* fragment motion vectors */
+
+ ogg_uint32_t *FragTokenCounts; /* Number of tokens per fragment */
+ ogg_uint32_t (*TokenList)[128]; /* Fragment Token Pointers */
+
+ ogg_int32_t *FragmentVariances;
+ ogg_uint32_t *FragQIndex; /* Fragment Quality used in
+ PostProcess */
+ Q_LIST_ENTRY (*PPCoefBuffer)[64]; /* PostProcess Buffer for
+ coefficients data */
+
+ unsigned char *FragCoeffs; /* # of coeffs decoded so far for
+ fragment */
+ unsigned char *FragCoefEOB; /* Position of last non 0 coef
+ within QFragData */
+ Q_LIST_ENTRY (*QFragData)[64]; /* Fragment Coefficients
+ Array Pointers */
+ CODING_MODE *FragCodingMethod; /* coding method for the
+ fragment */
+
+ //**********************************************************************/
+ /* pointers to addresses used for allocation and deallocation the
+ others are rounded up to the nearest 32 bytes */
+
+ COEFFNODE *_Nodes;
+ ogg_uint32_t *transIndex; /* ptr to table of
+ transposed indexes */
+
+ /**********************************************************************/
+ ogg_int32_t bumpLast;
+
+ /* Macro Block and SuperBlock Information */
+ ogg_int32_t (*BlockMap)[4][4]; /* super block + sub macro
+ block + sub frag ->
+ FragIndex */
+
+ /* Coded flag arrays and counters for them */
+ unsigned char *SBCodedFlags;
+ unsigned char *SBFullyFlags;
+ unsigned char *MBCodedFlags;
+ unsigned char *MBFullyFlags;
+
+ /**********************************************************************/
+ ogg_uint32_t EOB_Run;
+
+ COORDINATE *FragCoordinates;
+ MOTION_VECTOR MVector;
+ ogg_int32_t ReconPtr2Offset; /* Offset for second reconstruction
+ in half pixel MC */
+ Q_LIST_ENTRY *quantized_list;
+ ogg_int16_t *ReconDataBuffer;
+ Q_LIST_ENTRY InvLastIntraDC;
+ Q_LIST_ENTRY InvLastInterDC;
+ Q_LIST_ENTRY LastIntraDC;
+ Q_LIST_ENTRY LastInterDC;
+
+ ogg_uint32_t BlocksToDecode; /* Blocks to be decoded this frame */
+ ogg_uint32_t DcHuffChoice; /* Huffman table selection variables */
+ unsigned char ACHuffChoice;
+ ogg_uint32_t QuadMBListIndex;
+
+ ogg_int32_t ByteCount;
+
+ ogg_uint32_t bit_pattern;
+ unsigned char bits_so_far;
+ unsigned char NextBit;
+ ogg_int32_t BitsLeft;
+
+ ogg_int16_t *DequantBuffer;
+
+ ogg_int32_t fp_quant_InterUV_coeffs[64];
+ ogg_int32_t fp_quant_InterUV_round[64];
+ ogg_int32_t fp_ZeroBinSize_InterUV[64];
+
+ ogg_int16_t *TmpReconBuffer;
+ ogg_int16_t *TmpDataBuffer;
+
+ /* Loop filter bounding values */
+ ogg_int32_t FiltBoundingValue[512];
+
+ /* Dequantiser and rounding tables */
+ ogg_uint32_t QThreshTable[Q_TABLE_SIZE];
+ Q_LIST_ENTRY *dequant_InterUV_coeffs;
+ unsigned int quant_index[64];
+ ogg_int32_t quant_Y_coeffs[64];
+ ogg_int32_t quant_UV_coeffs[64];
+ ogg_int32_t fp_quant_Y_coeffs[64]; /* used in reiniting quantizers */
+
+ HUFF_ENTRY **HuffRoot_VP3x;
+ ogg_uint32_t **HuffCodeArray_VP3x;
+ unsigned char **HuffCodeLengthArray_VP3x;
+
+ /* Quantiser and rounding tables */
+ ogg_int32_t fp_quant_UV_coeffs[64];
+ ogg_int32_t fp_quant_Inter_coeffs[64];
+ ogg_int32_t fp_quant_Y_round[64];
+ ogg_int32_t fp_quant_UV_round[64];
+ ogg_int32_t fp_quant_Inter_round[64];
+ ogg_int32_t fp_ZeroBinSize_Y[64];
+ ogg_int32_t fp_ZeroBinSize_UV[64];
+ ogg_int32_t fp_ZeroBinSize_Inter[64];
+ ogg_int32_t *fquant_coeffs;
+ ogg_int32_t *fquant_round;
+ ogg_int32_t *fquant_ZbSize;
+ Q_LIST_ENTRY *dequant_Y_coeffs;
+ Q_LIST_ENTRY *dequant_UV_coeffs;
+ Q_LIST_ENTRY *dequant_Inter_coeffs;
+ Q_LIST_ENTRY *dequant_coeffs;
+
+ /* Predictor used in choosing entropy table for decoding block patterns. */
+ unsigned char BlockPatternPredictor;
+
+ short Modifier[4][512];
+ short *ModifierPointer[4];
+
+ unsigned char *DataOutputInPtr;
+
+} PB_INSTANCE;
+
typedef struct CP_INSTANCE {
/* Compressor Configuration */
@@ -357,7 +654,6 @@
ogg_uint32_t lastrun ;
Q_LIST_ENTRY *quantized_list;
- Q_LIST_ENTRY *quantized_listAlloc;
MOTION_VECTOR MVector;
ogg_uint32_t TempBitCount;
@@ -371,7 +667,7 @@
double QTargetModifier[Q_TABLE_SIZE];
/* instances (used for reconstructing buffers and to hold tokens etc.) */
- PP_INSTANCE *pp; /* preprocessor */
+ PP_INSTANCE pp; /* preprocessor */
PB_INSTANCE pb; /* playback */
/* ogg bitpacker for use in packet coding, other API state */
@@ -384,3 +680,22 @@
int keyframe_granule_shift;
} CP_INSTANCE;
+
+typedef struct{
+ int YWidth;
+ int YHeight;
+ int YStride;
+
+ int UVWidth;
+ int UVHeight;
+ int UVStride;
+
+ char * YBuffer;
+ char * UBuffer;
+ char * VBuffer;
+
+} YUV_INPUT_BUFFER_CONFIG;
+
+
+extern void ClearPPInstance(PP_INSTANCE *ppi);
+extern void InitPPInstance(PP_INSTANCE *ppi);
<p><p>1.2 +14 -1 theora/lib/encoder_lookup.h
Index: encoder_lookup.h
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/encoder_lookup.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- encoder_lookup.h 16 Sep 2002 07:10:02 -0000 1.1
+++ encoder_lookup.h 18 Sep 2002 08:56:57 -0000 1.2
@@ -11,10 +11,12 @@
********************************************************************
function: simple static lookups for VP3 frame encoder
- last mod: $Id: encoder_lookup.h,v 1.1 2002/09/16 07:10:02 xiphmont Exp $
+ last mod: $Id: encoder_lookup.h,v 1.2 2002/09/18 08:56:57 xiphmont Exp $
********************************************************************/
+#define MAX_MV_EXTENT 31 /* Max search distance in half pixel increments */
+
ogg_uint32_t MvPattern[(MAX_MV_EXTENT * 2) + 1] = {
0x000000ff, 0x000000fd, 0x000000fb, 0x000000f9,
0x000000f7, 0x000000f5, 0x000000f3, 0x000000f1,
@@ -143,3 +145,14 @@
2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2 };
+/* Quantization zigzag pattern */
+ogg_uint32_t dequant_index[64] = {
+ 0, 1, 8, 16, 9, 2, 3, 10,
+ 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34,
+ 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36,
+ 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63
+};
<p><p>1.2 +87 -87 theora/lib/frarray.c
Index: frarray.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/frarray.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- frarray.c 16 Sep 2002 07:10:02 -0000 1.1
+++ frarray.c 18 Sep 2002 08:56:57 -0000 1.2
@@ -11,13 +11,98 @@
********************************************************************
function:
- last mod: $Id: frarray.c,v 1.1 2002/09/16 07:10:02 xiphmont Exp $
+ last mod: $Id: frarray.c,v 1.2 2002/09/18 08:56:57 xiphmont Exp $
********************************************************************/
-#include "ogg/ogg.h"
+#include <ogg/ogg.h>
#include "encoder_internal.h"
+ogg_uint32_t FrArrayCodeSBRun( CP_INSTANCE *cpi, ogg_uint32_t value ){
+ ogg_uint32_t CodedVal = 0;
+ ogg_uint32_t CodedBits = 0;
+
+ // Coding scheme:
+ // Codeword RunLength
+ // 0 1
+ // 10x 2-3
+ // 110x 4-5
+ // 1110xx 6-9
+ // 11110xxx 10-17
+ // 111110xxxx 18-33
+ // 111111xxxxxxxxxxxx 34-4129
+
+ if ( value == 1 ){
+ CodedVal = 0;
+ CodedBits = 1;
+ } else if ( value <= 3 ) {
+ CodedVal = 0x0004 + (value - 2);
+ CodedBits = 3;
+ } else if ( value <= 5 ) {
+ CodedVal = 0x000C + (value - 4);
+ CodedBits = 4;
+ } else if ( value <= 9 ) {
+ CodedVal = 0x0038 + (value - 6);
+ CodedBits = 6;
+ } else if ( value <= 17 ) {
+ CodedVal = 0x00F0 + (value - 10);
+ CodedBits = 8;
+ } else if ( value <= 33 ) {
+ CodedVal = 0x03E0 + (value - 18);
+ CodedBits = 10;
+ } else {
+ CodedVal = 0x3F000 + (value - 34);
+ CodedBits = 18;
+ }
+
+ /* Add the bits to the encode holding buffer. */
+ AddBitsToBuffer( cpi, CodedVal, (ogg_uint32_t)CodedBits );
+
+ return CodedBits;
+}
+
+ogg_uint32_t FrArrayCodeBlockRun( CP_INSTANCE *cpi, ogg_uint32_t value ) {
+ ogg_uint32_t CodedVal = 0;
+ ogg_uint32_t CodedBits = 0;
+
+ // Coding scheme:
+ // Codeword RunLength
+ // 0x 1-2
+ // 10x 3-4
+ // 110x 5-6
+ // 1110xx 7-10
+ // 11110xx 11-14
+ // 11111xxxx 15-30
+
+ if ( value <= 2 ) {
+ CodedVal = value - 1;
+ CodedBits = 2;
+ } else if ( value <= 4 ) {
+ CodedVal = 0x0004 + (value - 3);
+ CodedBits = 3;
+
+ } else if ( value <= 6 ) {
+ CodedVal = 0x000C + (value - 5);
+ CodedBits = 4;
+
+ } else if ( value <= 10 ) {
+ CodedVal = 0x0038 + (value - 7);
+ CodedBits = 6;
+
+ } else if ( value <= 14 ) {
+ CodedVal = 0x0078 + (value - 11);
+ CodedBits = 7;
+ } else {
+ CodedVal = 0x01F0 + (value - 15);
+ CodedBits = 9;
+ }
+
+ /* Add the bits to the encode holding buffer. */
+ AddBitsToBuffer( cpi, CodedVal, (ogg_uint32_t)CodedBits );
+
+ return CodedBits;
+}
+
void PackAndWriteDFArray( CP_INSTANCE *cpi ){
ogg_uint32_t i;
unsigned char val;
@@ -134,90 +219,5 @@
}
}
-}
-
-ogg_uint32_t FrArrayCodeSBRun( CP_INSTANCE *cpi, ogg_uint32_t value ){
- ogg_uint32_t CodedVal = 0;
- ogg_uint32_t CodedBits = 0;
-
- // Coding scheme:
- // Codeword RunLength
- // 0 1
- // 10x 2-3
- // 110x 4-5
- // 1110xx 6-9
- // 11110xxx 10-17
- // 111110xxxx 18-33
- // 111111xxxxxxxxxxxx 34-4129
-
- if ( value == 1 ){
- CodedVal = 0;
- CodedBits = 1;
- } else if ( value <= 3 ) {
- CodedVal = 0x0004 + (value - 2);
- CodedBits = 3;
- } else if ( value <= 5 ) {
- CodedVal = 0x000C + (value - 4);
- CodedBits = 4;
- } else if ( value <= 9 ) {
- CodedVal = 0x0038 + (value - 6);
- CodedBits = 6;
- } else if ( value <= 17 ) {
- CodedVal = 0x00F0 + (value - 10);
- CodedBits = 8;
- } else if ( value <= 33 ) {
- CodedVal = 0x03E0 + (value - 18);
- CodedBits = 10;
- } else {
- CodedVal = 0x3F000 + (value - 34);
- CodedBits = 18;
- }
-
- /* Add the bits to the encode holding buffer. */
- AddBitsToBuffer( cpi, CodedVal, (ogg_uint32_t)CodedBits );
-
- return CodedBits;
-}
-
-ogg_uint32_t FrArrayCodeBlockRun( CP_INSTANCE *cpi, ogg_uint32_t value ) {
- ogg_uint32_t CodedVal = 0;
- ogg_uint32_t CodedBits = 0;
-
- // Coding scheme:
- // Codeword RunLength
- // 0x 1-2
- // 10x 3-4
- // 110x 5-6
- // 1110xx 7-10
- // 11110xx 11-14
- // 11111xxxx 15-30
-
- if ( value <= 2 ) {
- CodedVal = value - 1;
- CodedBits = 2;
- } else if ( value <= 4 ) {
- CodedVal = 0x0004 + (value - 3);
- CodedBits = 3;
-
- } else if ( value <= 6 ) {
- CodedVal = 0x000C + (value - 5);
- CodedBits = 4;
-
- } else if ( value <= 10 ) {
- CodedVal = 0x0038 + (value - 7);
- CodedBits = 6;
-
- } else if ( value <= 14 ) {
- CodedVal = 0x0078 + (value - 11);
- CodedBits = 7;
- } else {
- CodedVal = 0x01F0 + (value - 15);
- CodedBits = 9;
- }
-
- /* Add the bits to the encode holding buffer. */
- AddBitsToBuffer( cpi, CodedVal, (ogg_uint32_t)CodedBits );
-
- return CodedBits;
}
<p><p>1.2 +145 -141 theora/lib/mcomp.c
Index: mcomp.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/mcomp.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- mcomp.c 16 Sep 2002 07:10:02 -0000 1.1
+++ mcomp.c 18 Sep 2002 08:56:57 -0000 1.2
@@ -11,12 +11,16 @@
********************************************************************
function:
- last mod: $Id: mcomp.c,v 1.1 2002/09/16 07:10:02 xiphmont Exp $
+ last mod: $Id: mcomp.c,v 1.2 2002/09/18 08:56:57 xiphmont Exp $
********************************************************************/
+#include <stdio.h>
+#include <ogg/ogg.h>
+#include "encoder_internal.h"
+#include "encoder_lookup.h"
+
//#define NEW_ERROR_METRIC
-#include "mcomp.h"
/* Initialises motion compentsation. */
void InitMotionCompensation ( CP_INSTANCE *cpi ){
@@ -25,7 +29,7 @@
int Len;
int LineStepY = (ogg_int32_t)cpi->pb.Configuration.YStride;
- Len=((MvMaxExtent/2)+1)/2;
+ Len=((MAX_MV_EXTENT/2)+1)/2;
/* How many search stages are there. */
@@ -113,35 +117,35 @@
XSum += DiffVal;
/* negative array indexes are strictly forbidden by ANSI C and C99 */
- XXSum += XX_LUT[DiffVal+255];
+ XXSum += DiffVal*DiffVal;
DiffVal = ((int)NewDataPtr[1]) - (int)RefDataPtr1[1];
XSum += DiffVal;
- XXSum += XX_LUT[DiffVal+255];
+ XXSum += DiffVal*DiffVal;
DiffVal = ((int)NewDataPtr[2]) - (int)RefDataPtr1[2];
XSum += DiffVal;
- XXSum += XX_LUT[DiffVal+255];
+ XXSum += DiffVal*DiffVal;
DiffVal = ((int)NewDataPtr[3]) - (int)RefDataPtr1[3];
XSum += DiffVal;
- XXSum += XX_LUT[DiffVal+255];
+ XXSum += DiffVal*DiffVal;
DiffVal = ((int)NewDataPtr[4]) - (int)RefDataPtr1[4];
XSum += DiffVal;
- XXSum += XX_LUT[DiffVal+255];
+ XXSum += DiffVal*DiffVal;
DiffVal = ((int)NewDataPtr[5]) - (int)RefDataPtr1[5];
XSum += DiffVal;
- XXSum += XX_LUT[DiffVal+255];
+ XXSum += DiffVal*DiffVal;
DiffVal = ((int)NewDataPtr[6]) - (int)RefDataPtr1[6];
XSum += DiffVal;
- XXSum += XX_LUT[DiffVal+255];
+ XXSum += DiffVal*DiffVal;
DiffVal = ((int)NewDataPtr[7]) - (int)RefDataPtr1[7];
XSum += DiffVal;
- XXSum += XX_LUT[DiffVal+255];
+ XXSum += DiffVal*DiffVal;
/* Step to next row of block. */
NewDataPtr += PixelsPerLine;
@@ -155,42 +159,42 @@
DiffVal = ((int)NewDataPtr[0]) -
(((int)RefDataPtr1[0] + (int)RefDataPtr2[0]) / 2);
XSum += DiffVal;
- XXSum += XX_LUT[DiffVal+255];
+ XXSum += DiffVal*DiffVal;
DiffVal = ((int)NewDataPtr[1]) -
(((int)RefDataPtr1[1] + (int)RefDataPtr2[1]) / 2);
XSum += DiffVal;
- XXSum += XX_LUT[DiffVal+255];
+ XXSum += DiffVal*DiffVal;
DiffVal = ((int)NewDataPtr[2]) -
(((int)RefDataPtr1[2] + (int)RefDataPtr2[2]) / 2);
XSum += DiffVal;
- XXSum += XX_LUT[DiffVal+255];
+ XXSum += DiffVal*DiffVal;
DiffVal = ((int)NewDataPtr[3]) -
(((int)RefDataPtr1[3] + (int)RefDataPtr2[3]) / 2);
XSum += DiffVal;
- XXSum += XX_LUT[DiffVal+255];
+ XXSum += DiffVal*DiffVal;
DiffVal = ((int)NewDataPtr[4]) -
(((int)RefDataPtr1[4] + (int)RefDataPtr2[4]) / 2);
XSum += DiffVal;
- XXSum += XX_LUT[DiffVal+255];
+ XXSum += DiffVal*DiffVal;
DiffVal = ((int)NewDataPtr[5]) -
(((int)RefDataPtr1[5] + (int)RefDataPtr2[5]) / 2);
XSum += DiffVal;
- XXSum += XX_LUT[DiffVal+255];
+ XXSum += DiffVal*DiffVal;
DiffVal = ((int)NewDataPtr[6]) -
(((int)RefDataPtr1[6] + (int)RefDataPtr2[6]) / 2);
XSum += DiffVal;
- XXSum += XX_LUT[DiffVal+255];
+ XXSum += DiffVal*DiffVal;
DiffVal = ((int)NewDataPtr[7]) -
(((int)RefDataPtr1[7] + (int)RefDataPtr2[7]) / 2);
XSum += DiffVal;
- XXSum += XX_LUT[DiffVal+255];
+ XXSum += DiffVal*DiffVal;
/* Step to next row of block. */
NewDataPtr += PixelsPerLine;
@@ -319,21 +323,21 @@
/* Examine alternate pixel locations. */
XSum += DiffPtr[0];
- XXSum += XX_LUT[DiffPtr[0]+255];
+ XXSum += DiffPtr[0]*DiffPtr[0];
XSum += DiffPtr[1];
- XXSum += XX_LUT[DiffPtr[1]+255];
+ XXSum += DiffPtr[1]*DiffPtr[1];
XSum += DiffPtr[2];
- XXSum += XX_LUT[DiffPtr[2]+255];
+ XXSum += DiffPtr[2]*DiffPtr[2];
XSum += DiffPtr[3];
- XXSum += XX_LUT[DiffPtr[3]+255];
+ XXSum += DiffPtr[3]*DiffPtr[3];
XSum += DiffPtr[4];
- XXSum += XX_LUT[DiffPtr[4]+255];
+ XXSum += DiffPtr[4]*DiffPtr[4];
XSum += DiffPtr[5];
- XXSum += XX_LUT[DiffPtr[5]+255];
+ XXSum += DiffPtr[5]*DiffPtr[5];
XSum += DiffPtr[6];
- XXSum += XX_LUT[DiffPtr[6]+255];
+ XXSum += DiffPtr[6]*DiffPtr[6];
XSum += DiffPtr[7];
- XXSum += XX_LUT[DiffPtr[7]+277];
+ XXSum += DiffPtr[7]*DiffPtr[7];
/* Step to next row of block. */
DiffPtr += PixelsPerLine;
@@ -353,37 +357,37 @@
that are coded (Y only) */
if ( cpi->pb.display_fragments[LocalFragIndex] )
IntraError +=
- cpi->GetIntraError(&cpi->
- ConvDestBuffer[GetFragIndex(cpi->
- pb.pixel_index_table,
- LocalFragIndex)],
- PixelsPerLine );
-
+ GetIntraError(&cpi->
+ ConvDestBuffer[GetFragIndex(cpi->
+ pb.pixel_index_table,
+ LocalFragIndex)],
+ PixelsPerLine );
+
LocalFragIndex++;
if ( cpi->pb.display_fragments[LocalFragIndex] )
IntraError +=
- cpi->GetIntraError(&cpi->
- ConvDestBuffer[GetFragIndex(cpi->pb.pixel_index_table,
- LocalFragIndex)],
- PixelsPerLine );
-
+ GetIntraError(&cpi->
+ ConvDestBuffer[GetFragIndex(cpi->pb.pixel_index_table,
+ LocalFragIndex)],
+ PixelsPerLine );
+
LocalFragIndex = FragIndex + cpi->pb.HFragments;
if ( cpi->pb.display_fragments[LocalFragIndex] )
IntraError +=
- cpi->GetIntraError(&cpi->
- ConvDestBuffer[GetFragIndex(cpi->pb.pixel_index_table,
- LocalFragIndex)],
- PixelsPerLine );
+ cGetIntraError(&cpi->
+ ConvDestBuffer[GetFragIndex(cpi->pb.pixel_index_table,
+ LocalFragIndex)],
+ PixelsPerLine );
LocalFragIndex++;
if ( cpi->pb.display_fragments[LocalFragIndex] )
IntraError +=
- cpi->GetIntraError(&cpi->
- ConvDestBuffer[GetFragIndex(cpi->pb.pixel_index_table,
- LocalFragIndex)],
- PixelsPerLine );
-
+ GetIntraError(&cpi->
+ ConvDestBuffer[GetFragIndex(cpi->pb.pixel_index_table,
+ LocalFragIndex)],
+ PixelsPerLine );
+
return IntraError;
}
@@ -432,8 +436,8 @@
if ( cpi->pb.display_fragments[LocalFragIndex] ) {
SrcPtr1 = &SrcPtr[PixelIndex];
RefPtr1 = &RefPtr[RefPixelIndex + RefPixelOffset];
- InterError += cpi->GetInterError( SrcPtr1, RefPtr1,
- &RefPtr1[RefPtr2Offset], PixelsPerLine );
+ InterError += GetInterError( SrcPtr1, RefPtr1,
+ &RefPtr1[RefPtr2Offset], PixelsPerLine );
}
LocalFragIndex++;
@@ -443,8 +447,8 @@
LocalFragIndex);
SrcPtr1 = &SrcPtr[PixelIndex];
RefPtr1 = &RefPtr[RefPixelIndex + RefPixelOffset];
- InterError += cpi->GetInterError( SrcPtr1, RefPtr1,
- &RefPtr1[RefPtr2Offset], PixelsPerLine );
+ InterError += GetInterError( SrcPtr1, RefPtr1,
+ &RefPtr1[RefPtr2Offset], PixelsPerLine );
}
@@ -455,8 +459,8 @@
LocalFragIndex);
SrcPtr1 = &SrcPtr[PixelIndex];
RefPtr1 = &RefPtr[RefPixelIndex + RefPixelOffset];
- InterError += cpi->GetInterError( SrcPtr1, RefPtr1,
- &RefPtr1[RefPtr2Offset], PixelsPerLine );
+ InterError += GetInterError( SrcPtr1, RefPtr1,
+ &RefPtr1[RefPtr2Offset], PixelsPerLine );
}
LocalFragIndex++;
@@ -466,10 +470,10 @@
LocalFragIndex);
SrcPtr1 = &SrcPtr[PixelIndex];
RefPtr1 = &RefPtr[RefPixelIndex + RefPixelOffset];
- InterError += cpi->GetInterError( SrcPtr1, RefPtr1,
- &RefPtr1[RefPtr2Offset], PixelsPerLine );
+ InterError += GetInterError( SrcPtr1, RefPtr1,
+ &RefPtr1[RefPtr2Offset], PixelsPerLine );
}
- return InterError;
+ return InterError;
}
ogg_uint32_t GetMBMVInterError (CP_INSTANCE *cpi,
@@ -527,19 +531,19 @@
/* Check the 0,0 candidate. */
if ( MBlockDispFrags[0] ) {
- Error = cpi->GetSAD( SrcPtr[0], RefPtr,
+ Error = GetSumAbsDiffs( SrcPtr[0], RefPtr,
PixelsPerLine, Error, HUGE_ERROR );
}
if ( MBlockDispFrags[1] ) {
- Error = cpi->GetSAD( SrcPtr[1], RefPtr + 8,
+ Error = GetSumAbsDiffs( SrcPtr[1], RefPtr + 8,
PixelsPerLine, Error, HUGE_ERROR );
}
if ( MBlockDispFrags[2] ) {
- Error = cpi->GetSAD( SrcPtr[2], RefPtr + RefRow2Offset,
+ Error = GetSumAbsDiffs( SrcPtr[2], RefPtr + RefRow2Offset,
PixelsPerLine, Error, HUGE_ERROR );
}
if ( MBlockDispFrags[3] ) {
- Error = cpi->GetSAD( SrcPtr[3], RefPtr + RefRow2Offset + 8,
+ Error = GetSumAbsDiffs( SrcPtr[3], RefPtr + RefRow2Offset + 8,
PixelsPerLine, Error, HUGE_ERROR );
}
@@ -563,22 +567,22 @@
/* Get the score for the current offset */
if ( MBlockDispFrags[0] ) {
- Error = cpi->GetSAD( SrcPtr[0], CandidateBlockPtr,
+ Error = GetSumAbsDiffs( SrcPtr[0], CandidateBlockPtr,
PixelsPerLine, Error, MinError );
}
if ( MBlockDispFrags[1] && (Error < MinError) ) {
- Error = cpi->GetNextSAD( SrcPtr[1], CandidateBlockPtr + 8,
+ Error = GetNextSumAbsDiffs( SrcPtr[1], CandidateBlockPtr + 8,
PixelsPerLine, Error, MinError );
}
if ( MBlockDispFrags[2] && (Error < MinError) ) {
- Error = cpi->GetNextSAD( SrcPtr[2], CandidateBlockPtr + RefRow2Offset,
+ Error = GetNextSumAbsDiffs( SrcPtr[2], CandidateBlockPtr + RefRow2Offset,
PixelsPerLine, Error, MinError );
}
if ( MBlockDispFrags[3] && (Error < MinError) ) {
- Error = cpi->GetNextSAD( SrcPtr[3],
+ Error = GetNextSumAbsDiffs( SrcPtr[3],
CandidateBlockPtr + RefRow2Offset + 8,
PixelsPerLine, Error, MinError );
}
@@ -618,32 +622,32 @@
if ( MBlockDispFrags[0] ) {
RefDataPtr1 = BestBlockPtr;
RefDataPtr2 = RefDataPtr1 + cpi->HalfPixelRef2Offset[i];
- HalfPixelError = cpi->
- GetSadHalfPixel( SrcPtr[0], RefDataPtr1, RefDataPtr2,
+ HalfPixelError =
+ GetHalfPixelSumAbsDiffs( SrcPtr[0], RefDataPtr1, RefDataPtr2,
PixelsPerLine, HalfPixelError, BestHalfPixelError );
}
if ( MBlockDispFrags[1] && (HalfPixelError < BestHalfPixelError) ) {
RefDataPtr1 = BestBlockPtr + 8;
RefDataPtr2 = RefDataPtr1 + cpi->HalfPixelRef2Offset[i];
- HalfPixelError = cpi->
- GetSadHalfPixel( SrcPtr[1], RefDataPtr1, RefDataPtr2,
+ HalfPixelError =
+ GetHalfPixelSumAbsDiffs( SrcPtr[1], RefDataPtr1, RefDataPtr2,
PixelsPerLine, HalfPixelError, BestHalfPixelError );
}
if ( MBlockDispFrags[2] && (HalfPixelError < BestHalfPixelError) ) {
RefDataPtr1 = BestBlockPtr + RefRow2Offset;
RefDataPtr2 = RefDataPtr1 + cpi->HalfPixelRef2Offset[i];
- HalfPixelError = cpi->
- GetSadHalfPixel( SrcPtr[2], RefDataPtr1, RefDataPtr2,
+ HalfPixelError =
+ GetHalfPixelSumAbsDiffs( SrcPtr[2], RefDataPtr1, RefDataPtr2,
PixelsPerLine, HalfPixelError, BestHalfPixelError );
}
if ( MBlockDispFrags[3] && (HalfPixelError < BestHalfPixelError) ) {
RefDataPtr1 = BestBlockPtr + RefRow2Offset + 8;
RefDataPtr2 = RefDataPtr1 + cpi->HalfPixelRef2Offset[i];
- HalfPixelError = cpi->
- GetSadHalfPixel( SrcPtr[3], RefDataPtr1, RefDataPtr2,
+ HalfPixelError =
+ GetHalfPixelSumAbsDiffs( SrcPtr[3], RefDataPtr1, RefDataPtr2,
PixelsPerLine, HalfPixelError, BestHalfPixelError );
}
@@ -657,7 +661,7 @@
MV->x += cpi->HalfPixelXOffset[BestHalfOffset];
MV->y += cpi->HalfPixelYOffset[BestHalfOffset];
- cpi->pb.ClearSysState();
+ ClearSysState();
/* Get the error score for the chosen 1/2 pixel offset as a variance. */
InterMVError = GetMBInterError( cpi, cpi->ConvDestBuffer, RefFramePtr,
@@ -715,33 +719,33 @@
RefPtr = &RefFramePtr[GetFragIndex(cpi->
pb.recon_pixel_index_table,FragIndex)];
- RefPtr = RefPtr - ((MvMaxExtent/2) * cpi->
- pb.Configuration.YStride) - (MvMaxExtent/2);
+ RefPtr = RefPtr - ((MAX_MV_EXTENT/2) * cpi->
+ pb.Configuration.YStride) - (MAX_MV_EXTENT/2);
/* Search each pixel alligned site */
- for ( i = 0; i < (ogg_int32_t)MvMaxExtent; i ++ ) {
+ for ( i = 0; i < (ogg_int32_t)MAX_MV_EXTENT; i ++ ) {
/* Starting position in row */
CandidateBlockPtr = RefPtr;
- for ( j = 0; j < (ogg_int32_t)MvMaxExtent; j++ ) {
+ for ( j = 0; j < (ogg_int32_t)MAX_MV_EXTENT; j++ ) {
/* Reset error */
Error = 0;
/* Summ errors for each block. */
if ( MBlockDispFrags[0] ) {
- Error = cpi->GetSAD( SrcPtr[0], CandidateBlockPtr,
+ Error = GetSumAbsDiffs( SrcPtr[0], CandidateBlockPtr,
PixelsPerLine, Error, HUGE_ERROR );
}
if ( MBlockDispFrags[1] ){
- Error = cpi->GetSAD( SrcPtr[1], CandidateBlockPtr + 8,
+ Error = GetSumAbsDiffs( SrcPtr[1], CandidateBlockPtr + 8,
PixelsPerLine, Error, HUGE_ERROR );
}
if ( MBlockDispFrags[2] ){
- Error = cpi->GetSAD( SrcPtr[2], CandidateBlockPtr + RefRow2Offset,
+ Error = GetSumAbsDiffs( SrcPtr[2], CandidateBlockPtr + RefRow2Offset,
PixelsPerLine, Error, HUGE_ERROR );
}
if ( MBlockDispFrags[3] ){
- Error = cpi->GetSAD( SrcPtr[3], CandidateBlockPtr + RefRow2Offset + 8,
+ Error = GetSumAbsDiffs( SrcPtr[3], CandidateBlockPtr + RefRow2Offset + 8,
PixelsPerLine, Error, HUGE_ERROR );
}
@@ -749,8 +753,8 @@
if ( Error < MinError ) {
MinError = Error;
BestBlockPtr = CandidateBlockPtr;
- x = 16 + j - MvMaxExtent;
- y = 16 + i - MvMaxExtent;
+ x = 16 + j - MAX_MV_EXTENT;
+ y = 16 + i - MAX_MV_EXTENT;
}
/* Move the the next site */
@@ -777,32 +781,32 @@
if ( MBlockDispFrags[0] ) {
RefDataPtr1 = BestBlockPtr;
RefDataPtr2 = RefDataPtr1 + cpi->HalfPixelRef2Offset[i];
- HalfPixelError = cpi->
- GetSadHalfPixel( SrcPtr[0], RefDataPtr1, RefDataPtr2,
+ HalfPixelError =
+ GetHalfPixelSumAbsDiffs( SrcPtr[0], RefDataPtr1, RefDataPtr2,
PixelsPerLine, HalfPixelError, BestHalfPixelError );
}
if ( MBlockDispFrags[1] && (HalfPixelError < BestHalfPixelError) ) {
RefDataPtr1 = BestBlockPtr + 8;
RefDataPtr2 = RefDataPtr1 + cpi->HalfPixelRef2Offset[i];
- HalfPixelError = cpi->
- GetSadHalfPixel( SrcPtr[1], RefDataPtr1, RefDataPtr2,
+ HalfPixelError =
+ GetHalfPixelSumAbsDiffs( SrcPtr[1], RefDataPtr1, RefDataPtr2,
PixelsPerLine, HalfPixelError, BestHalfPixelError );
}
if ( MBlockDispFrags[2] && (HalfPixelError < BestHalfPixelError) ) {
RefDataPtr1 = BestBlockPtr + RefRow2Offset;
RefDataPtr2 = RefDataPtr1 + cpi->HalfPixelRef2Offset[i];
- HalfPixelError = cpi->
- GetSadHalfPixel( SrcPtr[2], RefDataPtr1, RefDataPtr2,
+ HalfPixelError =
+ GetHalfPixelSumAbsDiffs( SrcPtr[2], RefDataPtr1, RefDataPtr2,
PixelsPerLine, HalfPixelError, BestHalfPixelError );
}
if ( MBlockDispFrags[3] && (HalfPixelError < BestHalfPixelError) ) {
RefDataPtr1 = BestBlockPtr + RefRow2Offset + 8;
RefDataPtr2 = RefDataPtr1 + cpi->HalfPixelRef2Offset[i];
- HalfPixelError = cpi->
- GetSadHalfPixel( SrcPtr[3], RefDataPtr1, RefDataPtr2,
+ HalfPixelError =
+ GetHalfPixelSumAbsDiffs( SrcPtr[3], RefDataPtr1, RefDataPtr2,
PixelsPerLine, HalfPixelError, BestHalfPixelError );
}
@@ -824,47 +828,6 @@
return InterMVError;
}
-ogg_uint32_t GetFOURMVExhaustiveSearch (CP_INSTANCE *cpi,
- unsigned char * RefFramePtr,
- ogg_uint32_t FragIndex,
- ogg_uint32_t PixelsPerLine,
- MOTION_VECTOR *MV ) {
- ogg_uint32_t InterMVError;
-
- /* For the moment the 4MV mode is only deemd to be valid if all four
- Y blocks are to be updated */
- /* This May be adapted later. */
- if ( cpi->pb.display_fragments[FragIndex] &&
- cpi->pb.display_fragments[FragIndex + 1] &&
- cpi->pb.display_fragments[FragIndex + cpi->pb.HFragments] &&
- cpi->pb.display_fragments[FragIndex + cpi->pb.HFragments + 1] ) {
-
- /* Reset the error score. */
- InterMVError = 0;
-
- /* Get the error component from each coded block */
- InterMVError +=
- GetBMVExhaustiveSearch(cpi, RefFramePtr, FragIndex,
- PixelsPerLine, &(MV[0]) );
- InterMVError +=
- GetBMVExhaustiveSearch(cpi, RefFramePtr, (FragIndex + 1),
- PixelsPerLine, &(MV[1]) );
- InterMVError +=
- GetBMVExhaustiveSearch(cpi, RefFramePtr,
- (FragIndex + cpi->pb.HFragments),
- PixelsPerLine, &(MV[2]) );
- InterMVError +=
- GetBMVExhaustiveSearch(cpi, RefFramePtr,
- (FragIndex + cpi->pb.HFragments + 1),
- PixelsPerLine, &(MV[3]) );
- }else{
- InterMVError = HUGE_ERROR;
- }
-
- /* Return score of best matching block. */
- return InterMVError;
-}
-
ogg_uint32_t GetBMVExhaustiveSearch (CP_INSTANCE *cpi,
unsigned char * RefFramePtr,
ogg_uint32_t FragIndex,
@@ -894,25 +857,25 @@
RefPtr = &RefFramePtr[GetFragIndex(cpi->
pb.recon_pixel_index_table,FragIndex)];
- RefPtr = RefPtr - ((MvMaxExtent/2) *
- cpi->pb.Configuration.YStride) - (MvMaxExtent/2);
+ RefPtr = RefPtr - ((MAX_MV_EXTENT/2) *
+ cpi->pb.Configuration.YStride) - (MAX_MV_EXTENT/2);
/* Search each pixel alligned site */
- for ( i = 0; i < (ogg_int32_t)MvMaxExtent; i ++ ) {
+ for ( i = 0; i < (ogg_int32_t)MAX_MV_EXTENT; i ++ ) {
/* Starting position in row */
CandidateBlockPtr = RefPtr;
- for ( j = 0; j < (ogg_int32_t)MvMaxExtent; j++ ){
+ for ( j = 0; j < (ogg_int32_t)MAX_MV_EXTENT; j++ ){
/* Get the block error score. */
- Error = cpi->GetSAD( SrcPtr, CandidateBlockPtr,
+ Error = GetSumAbsDiffs( SrcPtr, CandidateBlockPtr,
PixelsPerLine, 0, HUGE_ERROR );
/* Was this the best so far */
if ( Error < MinError ) {
MinError = Error;
BestBlockPtr = CandidateBlockPtr;
- x = 16 + j - MvMaxExtent;
- y = 16 + i - MvMaxExtent;
+ x = 16 + j - MAX_MV_EXTENT;
+ y = 16 + i - MAX_MV_EXTENT;
}
/* Move the the next site */
@@ -935,7 +898,7 @@
for ( i=0; i < 9; i++ ) {
RefDataPtr2 = BestBlockPtr + cpi->HalfPixelRef2Offset[i];
HalfPixelError =
- cpi->GetSadHalfPixel( SrcPtr, BestBlockPtr, RefDataPtr2,
+ GetHalfPixelSumAbsDiffs( SrcPtr, BestBlockPtr, RefDataPtr2,
PixelsPerLine, 0, BestHalfPixelError );
if ( HalfPixelError < BestHalfPixelError ){
@@ -953,11 +916,52 @@
#ifndef NEW_ERROR_METRIC
InterMVError =
- cpi->GetInterError( SrcPtr, BestBlockPtr, RefDataPtr2, PixelsPerLine );
+ GetInterError( SrcPtr, BestBlockPtr, RefDataPtr2, PixelsPerLine );
#else
InterMVError =
GetInterDCTErr(cpi, SrcPtr, BestBlockPtr, RefDataPtr2, PixelsPerLine );
#endif
+
+ /* Return score of best matching block. */
+ return InterMVError;
+}
+
+ogg_uint32_t GetFOURMVExhaustiveSearch (CP_INSTANCE *cpi,
+ unsigned char * RefFramePtr,
+ ogg_uint32_t FragIndex,
+ ogg_uint32_t PixelsPerLine,
+ MOTION_VECTOR *MV ) {
+ ogg_uint32_t InterMVError;
+
+ /* For the moment the 4MV mode is only deemd to be valid if all four
+ Y blocks are to be updated */
+ /* This May be adapted later. */
+ if ( cpi->pb.display_fragments[FragIndex] &&
+ cpi->pb.display_fragments[FragIndex + 1] &&
+ cpi->pb.display_fragments[FragIndex + cpi->pb.HFragments] &&
+ cpi->pb.display_fragments[FragIndex + cpi->pb.HFragments + 1] ) {
+
+ /* Reset the error score. */
+ InterMVError = 0;
+
+ /* Get the error component from each coded block */
+ InterMVError +=
+ GetBMVExhaustiveSearch(cpi, RefFramePtr, FragIndex,
+ PixelsPerLine, &(MV[0]) );
+ InterMVError +=
+ GetBMVExhaustiveSearch(cpi, RefFramePtr, (FragIndex + 1),
+ PixelsPerLine, &(MV[1]) );
+ InterMVError +=
+ GetBMVExhaustiveSearch(cpi, RefFramePtr,
+ (FragIndex + cpi->pb.HFragments),
+ PixelsPerLine, &(MV[2]) );
+ InterMVError +=
+ GetBMVExhaustiveSearch(cpi, RefFramePtr,
+ (FragIndex + cpi->pb.HFragments + 1),
+ PixelsPerLine, &(MV[3]) );
+ }else{
+ InterMVError = HUGE_ERROR;
+ }
/* Return score of best matching block. */
return InterMVError;
<p><p>1.3 +27 -1 theora/lib/misc_common.c
Index: misc_common.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/misc_common.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- misc_common.c 17 Sep 2002 07:01:33 -0000 1.2
+++ misc_common.c 18 Sep 2002 08:56:57 -0000 1.3
@@ -11,12 +11,38 @@
********************************************************************
function:
- last mod: $Id: misc_common.c,v 1.2 2002/09/17 07:01:33 xiphmont Exp $
+ last mod: $Id: misc_common.c,v 1.3 2002/09/18 08:56:57 xiphmont Exp $
********************************************************************/
+#include <ogg/ogg.h>
+#include "encoder_internal.h"
+
#define FIXED_Q 150
#define MAX_UP_REG_LOOPS 2
+
+/* Gives the initial bytes per block estimate for each Q value */
+double BpbTable[Q_TABLE_SIZE] = {
+ 0.42, 0.45, 0.46, 0.49, 0.51, 0.53, 0.56, 0.58,
+ 0.61, 0.64, 0.68, 0.71, 0.74, 0.77, 0.80, 0.84,
+ 0.89, 0.92, 0.98, 1.01, 1.04, 1.13, 1.17, 1.23,
+ 1.28, 1.34, 1.41, 1.45, 1.51, 1.59, 1.69, 1.80,
+ 1.84, 1.94, 2.02, 2.15, 2.23, 2.34, 2.44, 2.50,
+ 2.69, 2.80, 2.87, 3.04, 3.16, 3.29, 3.59, 3.66,
+ 3.86, 3.94, 4.22, 4.50, 4.64, 4.70, 5.24, 5.34,
+ 5.61, 5.87, 6.11, 6.41, 6.71, 6.99, 7.36, 7.69
+};
+
+double KfBpbTable[Q_TABLE_SIZE] = {
+ 0.74, 0.81, 0.88, 0.94, 1.00, 1.06, 1.14, 1.19,
+ 1.27, 1.34, 1.42, 1.49, 1.54, 1.59, 1.66, 1.73,
+ 1.80, 1.87, 1.97, 2.01, 2.08, 2.21, 2.25, 2.36,
+ 2.39, 2.50, 2.55, 2.65, 2.71, 2.82, 2.95, 3.01,
+ 3.11, 3.19, 3.31, 3.42, 3.58, 3.66, 3.78, 3.89,
+ 4.11, 4.26, 4.36, 4.39, 4.63, 4.76, 4.85, 5.04,
+ 5.26, 5.29, 5.47, 5.64, 5.76, 6.05, 6.35, 6.67,
+ 6.91, 7.17, 7.40, 7.56, 8.02, 8.45, 8.86, 9.38
+};
double GetEstimatedBpb( CP_INSTANCE *cpi, ogg_uint32_t TargetQ ){
ogg_uint32_t i;
<p><p>1.3 +184 -190 theora/lib/toplevel.c
Index: toplevel.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/toplevel.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- toplevel.c 17 Sep 2002 07:01:33 -0000 1.2
+++ toplevel.c 18 Sep 2002 08:56:57 -0000 1.3
@@ -11,19 +11,25 @@
********************************************************************
function:
- last mod: $Id: toplevel.c,v 1.2 2002/09/17 07:01:33 xiphmont Exp $
+ last mod: $Id: toplevel.c,v 1.3 2002/09/18 08:56:57 xiphmont Exp $
********************************************************************/
+#include <stdlib.h>
+#include <ogg/ogg.h>
+#include <theora/theora.h>
+#include "encoder_internal.h"
+#include "encoder_lookup.h"
+
#define A_TABLE_SIZE 29
#define DF_CANDIDATE_WINDOW 5
-#define VERSION_MAJOR 0
-#define VERSION_MINOR 0
+#define VERSION_MAJOR 3
+#define VERSION_MINOR 1
#define VERSION_SUB 0
#define CommentString "Xiph.Org libTheora I 20020916 0 0 0"
-static void EDeleteFragmentInfo(CP_INSTANCE * cpi){
+static void EClearFragmentInfo(CP_INSTANCE * cpi){
if(cpi->extra_fragments)
_ogg_free(cpi->extra_fragments);
if(cpi->FragmentLastQ)
@@ -151,7 +157,7 @@
}
-void EDeleteFrameInfo(CP_INSTANCE * cpi) {
+void EClearFrameInfo(CP_INSTANCE * cpi) {
if(cpi->ConvDestBuffer )
_ogg_free(cpi->ConvDestBuffer );
cpi->ConvDestBuffer = 0;
@@ -238,7 +244,7 @@
ogg_int32_t MinFrameTargetRate;
/* Update the frame carry over. */
- cpi->TotKeyFrameBytes += oggpackB_bytes(&cpi->opb);
+ cpi->TotKeyFrameBytes += oggpackB_bytes(&cpi->oggbuffer);
/* reset keyframe context and calculate weighted average of last
KEY_FRAME_CONTEXT keyframes */
@@ -248,7 +254,7 @@
cpi->PriorKeyFrameDistance[i] = cpi->PriorKeyFrameDistance[i+1];
} else {
cpi->PriorKeyFrameSize[KEY_FRAME_CONTEXT - 1] =
- oggpackB_bytes(&cpi->opb);
+ oggpackB_bytes(&cpi->oggbuffer);
cpi->PriorKeyFrameDistance[KEY_FRAME_CONTEXT - 1] =
cpi->LastKeyFrame;
}
@@ -287,12 +293,121 @@
}
cpi->LastKeyFrame = 1;
- cpi->LastKeyFrameSize=oggpackB_bytes(&cpi->opb);
+ cpi->LastKeyFrameSize=oggpackB_bytes(&cpi->oggbuffer);
}
+void UpdateFrame(CP_INSTANCE *cpi){
+ ogg_int32_t AvKeyFrameFrequency =
+ (ogg_int32_t) (cpi->CurrentFrame / cpi->KeyFrameCount);
+ ogg_int32_t AvKeyFrameBytes =
+ (ogg_int32_t) (cpi->TotKeyFrameBytes / cpi->KeyFrameCount);
+ ogg_int32_t TotalWeight = 0;
+
+ double CorrectionFactor;
+ ogg_uint32_t fragment_count = 0;
+
+ ogg_uint32_t diff_tokens = 0;
+ ogg_uint32_t bits_per_token = 0;
+
+ /* Reset the DC predictors. */
+ cpi->pb.LastIntraDC = 0;
+ cpi->pb.InvLastIntraDC = 0;
+ cpi->pb.LastInterDC = 0;
+ cpi->pb.InvLastInterDC = 0;
+
+ /* Initialise bit packing mechanism. */
+ oggpackB_reset(&cpi->oggbuffer);
+
+ /* Write out the frame header information including size. */
+ WriteFrameHeader(cpi);
+
+ /* Copy back any extra frags that are to be updated by the codec
+ as part of the background cleanup task */
+ CopyBackExtraFrags(cpi);
+
+ /* Encode the data. */
+ EncodeData(cpi);
+
+ /* Adjust drop frame trigger. */
+ if ( GetFrameType(&cpi->pb) != BASE_FRAME ) {
+ /* Apply decay factor then add in the last frame size. */
+ cpi->DropFrameTriggerBytes =
+ ((cpi->DropFrameTriggerBytes * (DF_CANDIDATE_WINDOW-1)) /
+ DF_CANDIDATE_WINDOW) + oggpackB_bytes(&cpi->oggbuffer);
+ }else{
+ /* Increase cpi->DropFrameTriggerBytes a little. Just after a key
+ frame may actually be a good time to drop a frame. */
+ cpi->DropFrameTriggerBytes =
+ (cpi->DropFrameTriggerBytes * DF_CANDIDATE_WINDOW) /
+ (DF_CANDIDATE_WINDOW-1);
+ }
+
+ /* Test for overshoot which may require a dropped frame next time
+ around. If we are already in a drop frame condition but the
+ previous frame was not dropped then the threshold for continuing
+ to allow dropped frames is reduced. */
+ if ( cpi->DropFrameCandidate ) {
+ if ( cpi->DropFrameTriggerBytes >
+ (cpi->frame_target_rate * (DF_CANDIDATE_WINDOW+1)) )
+ cpi->DropFrameCandidate = 1;
+ else
+ cpi->DropFrameCandidate = 0;
+ } else {
+ if ( cpi->DropFrameTriggerBytes >
+ (cpi->frame_target_rate * ((DF_CANDIDATE_WINDOW*2)-2)) )
+ cpi->DropFrameCandidate = 1;
+ else
+ cpi->DropFrameCandidate = 0;
+ }
+
+ /* Update the BpbCorrectionFactor variable according to whether or
+ not we were close enough with our selection of DCT quantiser. */
+ if ( GetFrameType(&cpi->pb) != BASE_FRAME ) {
+ /* Work out a size correction factor. */
+ CorrectionFactor = (double)oggpackB_bytes(&cpi->oggbuffer) /
+ (double)cpi->ThisFrameTargetBytes;
+
+ if ( (CorrectionFactor > 1.05) &&
+ (cpi->pb.ThisFrameQualityValue <
+ cpi->pb.QThreshTable[cpi->Configuration.ActiveMaxQ]) ) {
+ CorrectionFactor = 1.0 + ((CorrectionFactor - 1.0)/2);
+ if ( CorrectionFactor > 1.5 )
+ cpi->BpbCorrectionFactor *= 1.5;
+ else
+ cpi->BpbCorrectionFactor *= CorrectionFactor;
+
+ /* Keep BpbCorrectionFactor within limits */
+ if ( cpi->BpbCorrectionFactor > MAX_BPB_FACTOR )
+ cpi->BpbCorrectionFactor = MAX_BPB_FACTOR;
+ } else if ( (CorrectionFactor < 0.95) &&
+ (cpi->pb.ThisFrameQualityValue > VERY_BEST_Q) ){
+ CorrectionFactor = 1.0 - ((1.0 - CorrectionFactor)/2);
+ if ( CorrectionFactor < 0.75 )
+ cpi->BpbCorrectionFactor *= 0.75;
+ else
+ cpi->BpbCorrectionFactor *= CorrectionFactor;
+
+ /* Keep BpbCorrectionFactor within limits */
+ if ( cpi->BpbCorrectionFactor < MIN_BPB_FACTOR )
+ cpi->BpbCorrectionFactor = MIN_BPB_FACTOR;
+ }
+ }
+
+ /* Adjust carry over and or key frame context. */
+ if ( GetFrameType(&cpi->pb) == BASE_FRAME ) {
+ /* Adjust the key frame context unless the key frame was very small */
+ AdjustKeyFrameContext(cpi);
+ } else {
+ /* Update the frame carry over */
+ cpi->CarryOver += ((ogg_int32_t)cpi->frame_target_rate -
+ (ogg_int32_t)oggpackB_bytes(&cpi->oggbuffer));
+ }
+ cpi->TotalByteCount += oggpackB_bytes(&cpi->oggbuffer);
+}
+
static void CompressFirstFrame(CP_INSTANCE *cpi) {
- ogg_uint32_t register i;
+ ogg_uint32_t i;
/* if not AutoKeyframing cpi->ForceKeyFrameEvery = is frequency */
if(!cpi->AutoKeyFrameEnabled)
@@ -545,10 +660,10 @@
/* Set Baseline filter level. */
- SetScanParam( cpi->pp, SCP_CONFIGURE_PP, cpi->PreProcFilterLevel );
+ SetScanParam( &cpi->pp, SCP_CONFIGURE_PP, cpi->PreProcFilterLevel );
/* Score / analyses the fragments. */
- cpi->MotionScore = YUVAnalyseFrame(cpi->pp, &KFIndicator );
+ cpi->MotionScore = YUVAnalyseFrame(&cpi->pp, &KFIndicator );
/* Get the baseline Q value */
RegulateQ( cpi, cpi->MotionScore );
@@ -658,115 +773,6 @@
}
}
-void UpdateFrame(CP_INSTANCE *cpi){
- ogg_int32_t AvKeyFrameFrequency =
- (ogg_int32_t) (cpi->CurrentFrame / cpi->KeyFrameCount);
- ogg_int32_t AvKeyFrameBytes =
- (ogg_int32_t) (cpi->TotKeyFrameBytes / cpi->KeyFrameCount);
- ogg_int32_t TotalWeight = 0;
-
- double CorrectionFactor;
- ogg_uint32_t fragment_count = 0;
-
- ogg_uint32_t diff_tokens = 0;
- ogg_uint32_t bits_per_token = 0;
-
- /* Reset the DC predictors. */
- cpi->pb.LastIntraDC = 0;
- cpi->pb.InvLastIntraDC = 0;
- cpi->pb.LastInterDC = 0;
- cpi->pb.InvLastInterDC = 0;
-
- /* Initialise bit packing mechanism. */
- oggpackB_reset(&cpi->opb);
-
- /* Write out the frame header information including size. */
- WriteFrameHeader(cpi);
-
- /* Copy back any extra frags that are to be updated by the codec
- as part of the background cleanup task */
- CopyBackExtraFrags(cpi);
-
- /* Encode the data. */
- EncodeData(cpi);
-
- /* Adjust drop frame trigger. */
- if ( GetFrameType(&cpi->pb) != BASE_FRAME ) {
- /* Apply decay factor then add in the last frame size. */
- cpi->DropFrameTriggerBytes =
- ((cpi->DropFrameTriggerBytes * (DF_CANDIDATE_WINDOW-1)) /
- DF_CANDIDATE_WINDOW) + oggpackB_bytes(&cpi->opb);
- }else{
- /* Increase cpi->DropFrameTriggerBytes a little. Just after a key
- frame may actually be a good time to drop a frame. */
- cpi->DropFrameTriggerBytes =
- (cpi->DropFrameTriggerBytes * DF_CANDIDATE_WINDOW) /
- (DF_CANDIDATE_WINDOW-1);
- }
-
- /* Test for overshoot which may require a dropped frame next time
- around. If we are already in a drop frame condition but the
- previous frame was not dropped then the threshold for continuing
- to allow dropped frames is reduced. */
- if ( cpi->DropFrameCandidate ) {
- if ( cpi->DropFrameTriggerBytes >
- (cpi->frame_target_rate * (DF_CANDIDATE_WINDOW+1)) )
- cpi->DropFrameCandidate = 1;
- else
- cpi->DropFrameCandidate = 0;
- } else {
- if ( cpi->DropFrameTriggerBytes >
- (cpi->frame_target_rate * ((DF_CANDIDATE_WINDOW*2)-2)) )
- cpi->DropFrameCandidate = 1;
- else
- cpi->DropFrameCandidate = 0;
- }
-
- /* Update the BpbCorrectionFactor variable according to whether or
- not we were close enough with our selection of DCT quantiser. */
- if ( GetFrameType(&cpi->pb) != BASE_FRAME ) {
- /* Work out a size correction factor. */
- CorrectionFactor = (double)oggpackB_bytes(&cpi->opb) /
- (double)cpi->ThisFrameTargetBytes;
-
- if ( (CorrectionFactor > 1.05) &&
- (cpi->pb.ThisFrameQualityValue <
- cpi->pb.QThreshTable[cpi->Configuration.ActiveMaxQ]) ) {
- CorrectionFactor = 1.0 + ((CorrectionFactor - 1.0)/2);
- if ( CorrectionFactor > 1.5 )
- cpi->BpbCorrectionFactor *= 1.5;
- else
- cpi->BpbCorrectionFactor *= CorrectionFactor;
-
- /* Keep BpbCorrectionFactor within limits */
- if ( cpi->BpbCorrectionFactor > MAX_BPB_FACTOR )
- cpi->BpbCorrectionFactor = MAX_BPB_FACTOR;
- } else if ( (CorrectionFactor < 0.95) &&
- (cpi->pb.ThisFrameQualityValue > VERY_BEST_Q) ){
- CorrectionFactor = 1.0 - ((1.0 - CorrectionFactor)/2);
- if ( CorrectionFactor < 0.75 )
- cpi->BpbCorrectionFactor *= 0.75;
- else
- cpi->BpbCorrectionFactor *= CorrectionFactor;
-
- /* Keep BpbCorrectionFactor within limits */
- if ( cpi->BpbCorrectionFactor < MIN_BPB_FACTOR )
- cpi->BpbCorrectionFactor = MIN_BPB_FACTOR;
- }
- }
-
- /* Adjust carry over and or key frame context. */
- if ( GetFrameType(&cpi->pb) == BASE_FRAME ) {
- /* Adjust the key frame context unless the key frame was very small */
- AdjustKeyFrameContext(cpi);
- } else {
- /* Update the frame carry over */
- cpi->CarryOver += ((ogg_int32_t)cpi->frame_target_rate -
- (ogg_int32_t)oggpackB_bytes(&cpi->opb));
- }
- cpi->TotalByteCount += oggpackB_bytes(&cpi->opb);
-}
-
/********************** The toplevel ***********************/
const char *theora_encode_version(void){
@@ -782,7 +788,7 @@
return(ret);
}
-int theora_encode_init(theora_state *th, theora_encode_config *c){
+int theora_encode_init(theora_state *th, theora_info *c){
int i;
CP_INSTANCE *cpi;
@@ -795,7 +801,7 @@
c->version_subminor=VERSION_SUB;
AllocateTmpBuffers(&cpi->pb);
- cpi->pp = CreatePPInstance();
+ CreatePPInstance(&cpi->pp);
/* Initialise Configuration structure to legal values */
cpi->Configuration.BaseQ = 32;
@@ -829,13 +835,8 @@
cpi->QTargetModifier[Q_TABLE_SIZE] = 1.0;
/* Set up an encode buffer */
- oggpackB_writeinit(&cpi->opb);
+ oggpackB_writeinit(&cpi->oggbuffer);
- for(i=0;i<=64;i++) {
- if(i<=1)cpi->pb.idct[i]=IDct1;
- else if(i<=10)cpi->pb.idct[i]=IDct10;
- else cpi->pb.idct[i]=IDctSlow;
- }
cpi->pb.Configuration.HFragPixels = 8;
cpi->pb.Configuration.VFragPixels = 8;
@@ -880,21 +881,9 @@
cpi->Configuration.OutputFrameRate;
/* Initialise image format details */
- if(!InitFrameDetails(&cpi->pb)){
- return -1;
- }
- if(!EAllocateFragmentInfo(cpi)){
- DeleteFragmentInfo(&cpi->pb);
- DeleteFrameInfo(&cpi->pb);
- return -1;
- }
-
- if(!EAllocateFrameInfo(cpi)){
- DeleteFragmentInfo(&cpi->pb);
- DeleteFrameInfo(&cpi->pb);
- EDeleteFragmentInfo(cpi);
- return -1;
- }
+ InitFrameDetails(&cpi->pb);
+ EAllocateFragmentInfo(cpi);
+ EAllocateFrameInfo(cpi);
/* Set up pre-processor config pointers. */
cpi->ScanConfig.Yuv0ptr = cpi->yuv0ptr;
@@ -908,13 +897,7 @@
(unsigned char)cpi->pb.Configuration.VFragPixels;
/* Initialise the pre-processor module. */
- if(!ScanYUVInit(cpi->pp, &(cpi->ScanConfig))) {
- DeleteFragmentInfo(&cpi->pb);
- DeleteFrameInfo(&cpi->pb);
- EDeleteFragmentInfo(cpi);
- EDeleteFrameInfo(cpi);
- return -1;
- }
+ ScanYUVInit(&cpi->pp, &(cpi->ScanConfig));
/* Set encoder flags. */
cpi->DropFramesAllowed = c->droppedframes_p;
@@ -928,13 +911,14 @@
/* don't go too nuts on keyframe spacing; impose a high limit to
make certain the granulepos encoding strategy works */
- if(c->ForceKeyFrameEvery>32768)c->ForceKeyFrameEvery=32768;
- if(c->MinimumDistanceToKeyFrame>32768)c->MinimumDistanceToKeyFrame=32768;
+ if(cpi->ForceKeyFrameEvery>32768)cpi->ForceKeyFrameEvery=32768;
+ if(cpi->MinimumDistanceToKeyFrame>32768)cpi->MinimumDistanceToKeyFrame=32768;
{
- long maxPframes=c->ForceKeyFrameEvery > c->MinimumDistanceToKeyFrame ?
- c->ForceKeyFrameEvery ; c->MinimumDistanceToKeyFrame ;
- c->keyframe_granule_shift=_ilog(maxPframes-1);
+ long maxPframes=(int)cpi->ForceKeyFrameEvery >
+ (int)cpi->MinimumDistanceToKeyFrame ?
+ cpi->ForceKeyFrameEvery : cpi->MinimumDistanceToKeyFrame ;
+ cpi->keyframe_granule_shift=_ilog(maxPframes-1);
}
/* Initialise Motion compensation */
@@ -965,13 +949,13 @@
/* Indicate that the next frame to be compressed is the first in the
current clip. */
cpi->ThisIsFirstFrame = 1;
- int readyflag = 1;
+ cpi->readyflag = 1;
return 0;
}
int theora_encode_YUVin( CP_INSTANCE *cpi,
- YUV_INPUT_BUFFER_CONFIG *YuvInputData){
+ YUV_INPUT_BUFFER_CONFIG *YuvInputData){
ogg_int32_t i;
unsigned char *LocalDataPtr;
unsigned char *InputDataPtr;
@@ -980,8 +964,8 @@
if(cpi->doneflag)return -1;
/* If frame size has changed, abort out for now */
- if (YuvInputData->YHeight != (INT32)cpi->pb.Configuration.VideoFrameHeight ||
- YuvInputData->YWidth != (INT32)cpi->pb.Configuration.VideoFrameWidth )
+ if (YuvInputData->YHeight != (int)cpi->pb.Configuration.VideoFrameHeight ||
+ YuvInputData->YWidth != (int)cpi->pb.Configuration.VideoFrameWidth )
return(-1);
@@ -1015,7 +999,7 @@
}
/* Mark this as a video frame */
- oggpackB_write(&cpi->opb,0,1);
+ oggpackB_write(&cpi->oggbuffer,0,1);
/* Special case for first frame */
if ( cpi->ThisIsFirstFrame ){
@@ -1031,7 +1015,7 @@
}
/* Update stats variables. */
- cpi->LastFrameSize = oggpackB_bytes(&cpi->opb);
+ cpi->LastFrameSize = oggpackB_bytes(&cpi->oggbuffer);
cpi->CurrentFrame++;
cpi->packetflag=1;
@@ -1039,20 +1023,19 @@
}
int theora_encode_packetout( CP_INSTANCE *cpi, int last_p, ogg_packet *op){
- long bytes=oggpackB_bytes(&cpi->opb);
-
+ long bytes=oggpackB_bytes(&cpi->oggbuffer);
+
if(!bytes)return(0);
if(!cpi->packetflag)return(0);
if(cpi->doneflag)return(-1);
- op->packet=oggpackB_buffer(&cpi->opb);
+ op->packet=oggpackB_get_buffer(&cpi->oggbuffer);
op->bytes=bytes;
op->b_o_s=0;
op->e_o_s=last_p;
op->packetno=cpi->CurrentFrame;
-
op->granulepos=
((cpi->CurrentFrame-cpi->LastKeyFrame+1)<<cpi->keyframe_granule_shift)+
cpi->LastKeyFrame-1;
@@ -1066,38 +1049,49 @@
int theora_encode_header(CP_INSTANCE *cpi, ogg_packet *op){
/* width, height, fps, granule_shift, version */
- oggpackB_reset(&cpi->opb);
- oggpackB_write(&cpi->opb,0x80,8);
- oggpackB_write(&cpi->opb,'t',8);
- oggpackB_write(&cpi->opb,'h',8);
- oggpackB_write(&cpi->opb,'e',8);
- oggpackB_write(&cpi->opb,'o',8);
- oggpackB_write(&cpi->opb,'r',8);
- oggpackB_write(&cpi->opb,'a',8);
-
- oggpackB_write(&cpi->opb,cpi->ScanConfig.VideoFrameWidth,16);
- oggpackB_write(&cpi->opb,cpi->ScanConfig.VideoFrameHeight,16);
- oggpackB_write(&cpi->opb,cpi->Configuration.OutputFrameN,32);
- oggpackB_write(&cpi->opb,cpi->Configuration.OutputFrameD,32);
-
- oggpackB_write(&cpi->opb,cpi->keyframe_granule_shift,5);
-
- oggpackB_write(&cpi->opb,cpi->version_major,8);
- oggpackB_write(&cpi->opb,cpi->version_minor,8);
- oggpackB_write(&cpi->opb,cpi->version_subminor,8);
+ oggpackB_reset(&cpi->oggbuffer);
+ oggpackB_write(&cpi->oggbuffer,0x80,8);
+ oggpackB_write(&cpi->oggbuffer,'t',8);
+ oggpackB_write(&cpi->oggbuffer,'h',8);
+ oggpackB_write(&cpi->oggbuffer,'e',8);
+ oggpackB_write(&cpi->oggbuffer,'o',8);
+ oggpackB_write(&cpi->oggbuffer,'r',8);
+ oggpackB_write(&cpi->oggbuffer,'a',8);
+
+ oggpackB_write(&cpi->oggbuffer,cpi->ScanConfig.VideoFrameWidth,16);
+ oggpackB_write(&cpi->oggbuffer,cpi->ScanConfig.VideoFrameHeight,16);
+ oggpackB_write(&cpi->oggbuffer,cpi->Configuration.OutputFrameRateN,32);
+ oggpackB_write(&cpi->oggbuffer,cpi->Configuration.OutputFrameRateD,32);
+
+ oggpackB_write(&cpi->oggbuffer,cpi->keyframe_granule_shift,5);
+
+ oggpackB_write(&cpi->oggbuffer,VERSION_MAJOR,8);
+ oggpackB_write(&cpi->oggbuffer,VERSION_MINOR,8);
+ oggpackB_write(&cpi->oggbuffer,VERSION_SUB,8);
+
+ op->packet=oggpackB_get_buffer(&cpi->oggbuffer);
+ op->bytes=oggpackB_bytes(&cpi->oggbuffer);
+
+ op->b_o_s=1;
+ op->e_o_s=0;
+ op->packetno=0;
+
+ op->granulepos=0;
+ cpi->packetflag=0;
+
return(0);
}
void theora_encode_clear(CP_INSTANCE *cpi){
if(cpi){
- DeleteFragmentInfo(&cpi->pb);
- DeleteFrameInfo(&cpi->pb);
- EDeleteFragmentInfo(cpi);
- EDeleteFrameInfo(cpi);
- DeleteTmpBuffers(cpi->pb);
- DeletePPInstance(cpi->pp);
+ ClearFragmentInfo(&cpi->pb);
+ ClearFrameInfo(&cpi->pb);
+ EClearFragmentInfo(cpi);
+ ECleadFrameInfo(cpi);
+ ClearTmpBuffers(&cpi->pb);
+ ClearPPInstance(&cpi->pp);
}
}
<p><p>1.1 theora/lib/huffman.c
Index: huffman.c
===================================================================
/********************************************************************
* *
* 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 OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function:
last mod: $Id: huffman.c,v 1.1 2002/09/18 08:56:57 xiphmont Exp $
********************************************************************/
#include <stdlib.h>
#include <ogg/ogg.h>
#include "encoder_internal.h"
#include "hufftables.h"
void CreateHuffmanList(HUFF_ENTRY ** HuffRoot,
ogg_uint32_t HIndex, ogg_uint32_t *FreqList ) {
int i;
HUFF_ENTRY *entry_ptr;
HUFF_ENTRY *search_ptr;
/* Create a HUFF entry for token zero. */
HuffRoot[HIndex] = (HUFF_ENTRY *)_ogg_calloc(1,sizeof(*HuffRoot[HIndex]));
HuffRoot[HIndex]->Previous = NULL;
HuffRoot[HIndex]->Next = NULL;
HuffRoot[HIndex]->ZeroChild = NULL;
HuffRoot[HIndex]->OneChild = NULL;
HuffRoot[HIndex]->Value = 0;
HuffRoot[HIndex]->Frequency = FreqList[0];
if ( HuffRoot[HIndex]->Frequency == 0 )
HuffRoot[HIndex]->Frequency = 1;
/* Now add entries for all the other possible tokens. */
for ( i = 1; i < MAX_ENTROPY_TOKENS; i++ ) {
entry_ptr = (HUFF_ENTRY *)_ogg_calloc(1,sizeof(*entry_ptr));
entry_ptr->Value = i;
entry_ptr->Frequency = FreqList[i];
entry_ptr->ZeroChild = NULL;
entry_ptr->OneChild = NULL;
/* Force min value of 1. This prevents the tree getting too deep. */
if ( entry_ptr->Frequency == 0 )
entry_ptr->Frequency = 1;
if ( entry_ptr->Frequency <= HuffRoot[HIndex]->Frequency ){
entry_ptr->Next = HuffRoot[HIndex];
HuffRoot[HIndex]->Previous = entry_ptr;
entry_ptr->Previous = NULL;
HuffRoot[HIndex] = entry_ptr;
}else{
search_ptr = HuffRoot[HIndex];
while ( (search_ptr->Next != NULL) &&
(search_ptr->Frequency < entry_ptr->Frequency) ){
search_ptr = (HUFF_ENTRY *)search_ptr->Next;
}
if ( search_ptr->Frequency < entry_ptr->Frequency ){
entry_ptr->Next = NULL;
entry_ptr->Previous = search_ptr;
search_ptr->Next = entry_ptr;
}else{
entry_ptr->Next = search_ptr;
entry_ptr->Previous = search_ptr->Previous;
search_ptr->Previous->Next = entry_ptr;
search_ptr->Previous = entry_ptr;
}
}
}
}
void CreateCodeArray( HUFF_ENTRY * HuffRoot,
ogg_uint32_t *HuffCodeArray,
unsigned char *HuffCodeLengthArray,
ogg_uint32_t CodeValue,
unsigned char CodeLength ) {
/* If we are at a leaf then fill in a code array entry. */
if ( ( HuffRoot->ZeroChild == NULL ) && ( HuffRoot->OneChild == NULL ) ){
HuffCodeArray[HuffRoot->Value] = CodeValue;
HuffCodeLengthArray[HuffRoot->Value] = CodeLength;
}else{
/* Recursive calls to scan down the tree. */
CreateCodeArray(HuffRoot->ZeroChild, HuffCodeArray, HuffCodeLengthArray,
((CodeValue << 1) + 0), CodeLength + 1);
CreateCodeArray(HuffRoot->OneChild, HuffCodeArray, HuffCodeLengthArray,
((CodeValue << 1) + 1), CodeLength + 1);
}
}
void BuildHuffmanTree( HUFF_ENTRY **HuffRoot,
ogg_uint32_t *HuffCodeArray,
unsigned char *HuffCodeLengthArray,
ogg_uint32_t HIndex,
ogg_uint32_t *FreqList ){
HUFF_ENTRY *entry_ptr;
HUFF_ENTRY *search_ptr;
/* First create a sorted linked list representing the frequencies of
each token. */
CreateHuffmanList( HuffRoot, HIndex, FreqList );
/* Now build the tree from the list. */
/* While there are at least two items left in the list. */
while ( HuffRoot[HIndex]->Next != NULL ){
/* Create the new node as the parent of the first two in the list. */
entry_ptr = (HUFF_ENTRY *)_ogg_calloc(1,sizeof(*entry_ptr));
entry_ptr->Value = -1;
entry_ptr->Frequency = HuffRoot[HIndex]->Frequency +
HuffRoot[HIndex]->Next->Frequency ;
entry_ptr->ZeroChild = HuffRoot[HIndex];
entry_ptr->OneChild = HuffRoot[HIndex]->Next;
/* If there are still more items in the list then insert the new
node into the list. */
if (entry_ptr->OneChild->Next != NULL ){
/* Set up the provisional 'new root' */
HuffRoot[HIndex] = entry_ptr->OneChild->Next;
HuffRoot[HIndex]->Previous = NULL;
/* Now scan through the remaining list to insert the new entry
at the appropriate point. */
if ( entry_ptr->Frequency <= HuffRoot[HIndex]->Frequency ){
entry_ptr->Next = HuffRoot[HIndex];
HuffRoot[HIndex]->Previous = entry_ptr;
entry_ptr->Previous = NULL;
HuffRoot[HIndex] = entry_ptr;
}else{
search_ptr = HuffRoot[HIndex];
while ( (search_ptr->Next != NULL) &&
(search_ptr->Frequency < entry_ptr->Frequency) ){
search_ptr = search_ptr->Next;
}
if ( search_ptr->Frequency < entry_ptr->Frequency ){
entry_ptr->Next = NULL;
entry_ptr->Previous = search_ptr;
search_ptr->Next = entry_ptr;
}else{
entry_ptr->Next = search_ptr;
entry_ptr->Previous = search_ptr->Previous;
search_ptr->Previous->Next = entry_ptr;
search_ptr->Previous = entry_ptr;
}
}
}else{
/* Build has finished. */
entry_ptr->Next = NULL;
entry_ptr->Previous = NULL;
HuffRoot[HIndex] = entry_ptr;
}
/* Delete the Next/Previous properties of the children (PROB NOT NEC). */
entry_ptr->ZeroChild->Next = NULL;
entry_ptr->ZeroChild->Previous = NULL;
entry_ptr->OneChild->Next = NULL;
entry_ptr->OneChild->Previous = NULL;
}
/* Now build a code array from the tree. */
CreateCodeArray( HuffRoot[HIndex], HuffCodeArray,
HuffCodeLengthArray, 0, 0);
}
void DestroyHuffTree(HUFF_ENTRY *root_ptr){
if (root_ptr){
if ( root_ptr->ZeroChild )
DestroyHuffTree(root_ptr->ZeroChild);
if ( root_ptr->OneChild )
DestroyHuffTree(root_ptr->OneChild);
_ogg_free(root_ptr);
}
}
void InitHuffmanSet( PB_INSTANCE *pbi ){
int i;
pbi->HuffRoot_VP3x =
_ogg_calloc(NUM_HUFF_TABLES,sizeof(*pbi->HuffRoot_VP3x));
pbi->HuffCodeArray_VP3x =
_ogg_calloc(NUM_HUFF_TABLES,sizeof(*pbi->HuffCodeArray_VP3x));
pbi->HuffCodeLengthArray_VP3x =
_ogg_calloc(NUM_HUFF_TABLES,sizeof(*pbi->HuffCodeLengthArray_VP3x));
for ( i = 0; i < NUM_HUFF_TABLES; i++ ){
pbi->HuffCodeArray_VP3x[i] =
_ogg_calloc(MAX_ENTROPY_TOKENS,
sizeof(*pbi->HuffCodeArray_VP3x[i]));
pbi->HuffCodeLengthArray_VP3x[i] =
_ogg_calloc(MAX_ENTROPY_TOKENS,
sizeof(*pbi->HuffCodeLengthArray_VP3x[i]));
BuildHuffmanTree( pbi->HuffRoot_VP3x,
pbi->HuffCodeArray_VP3x[i],
pbi->HuffCodeLengthArray_VP3x[i],
i, FrequencyCounts_VP31[i]);
}
}
void DestroyHuffmanSet( PB_INSTANCE *pbi ){
int i;
HUFF_ENTRY **HuffRoot = pbi->HuffRoot_VP3x ;
for ( i = 0; i < NUM_HUFF_TABLES; i++ ){
if (pbi->HuffRoot_VP3x[i]) DestroyHuffTree(pbi->HuffRoot_VP3x[i]);
if (pbi->HuffCodeArray_VP3x[i])
_ogg_free (pbi->HuffCodeArray_VP3x[i]);
if (pbi->HuffCodeLengthArray_VP3x[i])
_ogg_free (pbi->HuffCodeLengthArray_VP3x[i]);
}
if(pbi->HuffRoot_VP3x)_ogg_free(pbi->HuffRoot_VP3x);
if (pbi->HuffCodeArray_VP3x)
_ogg_free (pbi->HuffCodeArray_VP3x);
if (pbi->HuffCodeLengthArray_VP3x)
_ogg_free (pbi->HuffCodeLengthArray_VP3x);
pbi->HuffRoot_VP3x=NULL;
pbi->HuffCodeArray_VP3x=NULL;
pbi->HuffCodeLengthArray_VP3x=NULL;
}
<p><p><p>1.1 theora/lib/huffman.h
Index: huffman.h
===================================================================
/********************************************************************
* *
* 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 OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function:
last mod: $Id: huffman.h,v 1.1 2002/09/18 08:56:57 xiphmont Exp $
********************************************************************/
/********************************************************************
* Constants
********************************************************************/
#define NUM_HUFF_TABLES 80
#define DC_HUFF_OFFSET 0
#define AC_HUFF_OFFSET 16
#define AC_TABLE_2_THRESH 5
#define AC_TABLE_3_THRESH 14
#define AC_TABLE_4_THRESH 27
#define DC_HUFF_CHOICES 16
#define DC_HUFF_CHOICE_BITS 4
#define AC_HUFF_CHOICES 16
#define AC_HUFF_CHOICE_BITS 4
/* Constants assosciated with entropy tokenisation. */
#define MAX_SINGLE_TOKEN_VALUE 6
#define DCT_VAL_CAT2_MIN 3
#define DCT_VAL_CAT3_MIN 7
#define DCT_VAL_CAT4_MIN 9
#define DCT_VAL_CAT5_MIN 13
#define DCT_VAL_CAT6_MIN 21
#define DCT_VAL_CAT7_MIN 37
#define DCT_VAL_CAT8_MIN 69
#define DCT_EOB_TOKEN 0
#define DCT_EOB_PAIR_TOKEN 1
#define DCT_EOB_TRIPLE_TOKEN 2
#define DCT_REPEAT_RUN_TOKEN 3
#define DCT_REPEAT_RUN2_TOKEN 4
#define DCT_REPEAT_RUN3_TOKEN 5
#define DCT_REPEAT_RUN4_TOKEN 6
#define DCT_SHORT_ZRL_TOKEN 7
#define DCT_ZRL_TOKEN 8
#define ONE_TOKEN 9 /* Special tokens for -1,1,-2,2 */
#define MINUS_ONE_TOKEN 10
#define TWO_TOKEN 11
#define MINUS_TWO_TOKEN 12
#define LOW_VAL_TOKENS (MINUS_TWO_TOKEN + 1)
#define DCT_VAL_CATEGORY3 (LOW_VAL_TOKENS + 4)
#define DCT_VAL_CATEGORY4 (DCT_VAL_CATEGORY3 + 1)
#define DCT_VAL_CATEGORY5 (DCT_VAL_CATEGORY4 + 1)
#define DCT_VAL_CATEGORY6 (DCT_VAL_CATEGORY5 + 1)
#define DCT_VAL_CATEGORY7 (DCT_VAL_CATEGORY6 + 1)
#define DCT_VAL_CATEGORY8 (DCT_VAL_CATEGORY7 + 1)
#define DCT_RUN_CATEGORY1 (DCT_VAL_CATEGORY8 + 1)
#define DCT_RUN_CATEGORY1B (DCT_RUN_CATEGORY1 + 5)
#define DCT_RUN_CATEGORY1C (DCT_RUN_CATEGORY1B + 1)
#define DCT_RUN_CATEGORY2 (DCT_RUN_CATEGORY1C + 1)
/* 35 */
#define MAX_ENTROPY_TOKENS (DCT_RUN_CATEGORY2 + 2)
<p><p><p>1.1 theora/lib/hufftables.h
Index: hufftables.h
===================================================================
/********************************************************************
* *
* 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 OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function:
last mod: $Id: hufftables.h,v 1.1 2002/09/18 08:56:57 xiphmont Exp $
********************************************************************/
#include "huffman.h"
unsigned char ExtraBitLengths_VP31[MAX_ENTROPY_TOKENS] = {
0, 0, 0, 2, 3, 4, 12,3, 6, // EOB and Zero-run tokens.
0, 0, 0, 0, // Very low value tokens.
1, 1, 1, 1, 2, 3, 4, 5, 6, 10, // Other value tokens
1, 1, 1, 1, 1, 3, 4, // Category 1 runs.
2, 3, // Category 2 runs.
};
/* Frequency tables for encoder version < 2 */
ogg_uint32_t FrequencyCounts_VP31[NUM_HUFF_TABLES][MAX_ENTROPY_TOKENS] = {
/* DC Intra bias */
{ 198, 62, 22, 31, 14, 6, 6, 205, 3,
843, 843, 415, 516,
660, 509, 412, 347, 560, 779, 941, 930, 661, 377,
170, 155, 39, 2, 9, 15, 11,
128, 86,
},
{ 299, 92, 34, 39, 15, 6, 6, 132, 1,
851, 851, 484, 485,
666, 514, 416, 351, 567, 788, 953, 943, 670, 383,
117, 119, 26, 4, 17, 7, 1,
93, 56,
},
{ 367, 115, 42, 47, 16, 6, 6, 105, 1,
896, 896, 492, 493,
667, 510, 408, 342, 547, 760, 932, 927, 656, 379,
114, 103, 10, 3, 6, 2, 1,
88, 49,
},
{ 462, 158, 63, 76, 28, 9, 8, 145, 1,
1140, 1140, 573, 574,
754, 562, 435, 357, 555, 742, 793, 588, 274, 81,
154, 117, 13, 6, 12, 2, 1,
104, 62,
},
{ 558, 196, 81, 99, 36, 11, 9, 135, 1,
1300, 1301, 606, 607,
779, 560, 429, 349, 536, 680, 644, 405, 153, 30,
171, 120, 12, 5, 14, 3, 1,
104, 53,
},
{ 635, 233, 100, 122, 46, 14, 12, 113, 1,
1414, 1415, 631, 631,
785, 555, 432, 335, 513, 611, 521, 284, 89, 13,
170, 113, 10, 5, 14, 3, 1,
102, 62,
},
{ 720, 276, 119, 154, 62, 20, 16, 101, 1,
1583, 1583, 661, 661,
794, 556, 407, 318, 447, 472, 343, 153, 35, 1,
172, 115, 11, 7, 14, 3, 1,
112, 70,
},
{ 853, 326, 144, 184, 80, 27, 19, 52, 1,
1739, 1740, 684, 685,
800, 540, 381, 277, 364, 352, 218, 78, 13, 1,
139, 109, 9, 6, 20, 2, 1,
94, 50,
},
/* DC Inter Bias */
{ 490, 154, 57, 53, 10, 2, 1, 238, 160,
1391, 1390, 579, 578,
491, 273, 172, 118, 152, 156, 127, 79, 41, 39,
712, 547, 316, 125, 183, 306, 237,
451, 358,
},
{ 566, 184, 70, 65, 11, 2, 1, 235, 51,
1414, 1414, 599, 598,
510, 285, 180, 124, 157, 161, 131, 82, 42, 40,
738, 551, 322, 138, 195, 188, 93,
473, 365,
},
{ 711, 261, 111, 126, 27, 4, 1, 137, 52,
1506, 1505, 645, 645,
567, 316, 199, 136, 172, 175, 142, 88, 45, 48,
548, 449, 255, 145, 184, 174, 121,
260, 227,
},
{ 823, 319, 144, 175, 43, 7, 1, 53, 42,
1648, 1648, 653, 652,
583, 329, 205, 139, 175, 176, 139, 84, 44, 34,
467, 389, 211, 137, 181, 186, 107,
106, 85,
},
{ 948, 411, 201, 276, 85, 16, 2, 39, 33,
1778, 1777, 584, 583,
489, 265, 162, 111, 140, 140, 108, 64, 38, 23,
428, 356, 201, 139, 186, 165, 94,
78, 63,
},
{ 1002, 470, 248, 386, 153, 39, 6, 23, 23,
1866, 1866, 573, 573,
467, 249, 155, 103, 130, 128, 94, 60, 38, 14,
323, 263, 159, 111, 156, 153, 74,
46, 34,
},
{ 1020, 518, 291, 504, 242, 78, 18, 14, 14,
1980, 1979, 527, 526,
408, 219, 132, 87, 110, 104, 79, 55, 31, 7,
265, 213, 129, 91, 131, 111, 50,
31, 20,
},
{ 1018, 544, 320, 591, 338, 139, 47, 5, 2,
2123, 2123, 548, 547,
414, 212, 126, 83, 101, 96, 79, 60, 23, 1,
120, 97, 55, 39, 60, 38, 15,
11, 8,
},
/* AC INTRA Tables */
/* AC Intra bias group 1 tables */
{ 242, 62, 22, 20, 4, 1, 1, 438, 1,
593, 593, 489, 490,
657, 580, 471, 374, 599, 783, 869, 770, 491, 279,
358, 144, 82, 54, 49, 70, 5,
289, 107,
},
{ 317, 95, 38, 41, 8, 1, 1, 479, 1,
653, 654, 500, 501,
682, 611, 473, 376, 582, 762, 806, 656, 358, 155,
419, 162, 86, 58, 36, 34, 1,
315, 126,
},
{ 382, 121, 49, 59, 15, 3, 1, 496, 1,
674, 674, 553, 554,
755, 636, 487, 391, 576, 718, 701, 488, 221, 72,
448, 161, 107, 56, 37, 29, 1,
362, 156,
},
{ 415, 138, 57, 73, 21, 5, 1, 528, 1,
742, 741, 562, 563,
753, 669, 492, 388, 563, 664, 589, 340, 129, 26,
496, 184, 139, 71, 48, 33, 2,
387, 166,
},
{ 496, 170, 73, 94, 31, 8, 2, 513, 1,
855, 855, 604, 604,
769, 662, 477, 356, 486, 526, 381, 183, 51, 5,
590, 214, 160, 85, 60, 39, 3,
427, 203,
},
{ 589, 207, 89, 116, 40, 13, 3, 491, 1,
919, 919, 631, 631,
769, 633, 432, 308, 408, 378, 247, 94, 17, 1,
659, 247, 201, 105, 73, 51, 3,
466, 242,
},
{ 727, 266, 115, 151, 49, 17, 6, 439, 1,
977, 977, 642, 642,
718, 572, 379, 243, 285, 251, 133, 40, 1, 1,
756, 287, 253, 126, 94, 66, 4,
492, 280,
},
{ 940, 392, 180, 247, 82, 30, 14, 343, 1,
1064, 1064, 615, 616,
596, 414, 235, 146, 149, 108, 41, 1, 1, 1,
882, 314, 346, 172, 125, 83, 6,
489, 291,
},
/* AC Inter bias group 1 tables */
{ 440, 102, 33, 23, 2, 1, 1, 465, 85,
852, 852, 744, 743,
701, 496, 297, 193, 225, 200, 129, 58, 18, 2,
798, 450, 269, 202, 145, 308, 154,
646, 389,
},
{ 592, 151, 53, 43, 6, 1, 1, 409, 34,
875, 875, 748, 747,
723, 510, 305, 196, 229, 201, 130, 59, 18, 2,
800, 436, 253, 185, 115, 194, 88,
642, 368,
},
{ 759, 222, 86, 85, 17, 2, 1, 376, 46,
888, 888, 689, 688,
578, 408, 228, 143, 165, 141, 84, 35, 7, 1,
878, 488, 321, 244, 147, 266, 124,
612, 367,
},
{ 912, 298, 122, 133, 34, 7, 1, 261, 44,
1092, 1091, 496, 496,
409, 269, 150, 95, 106, 87, 49, 16, 1, 1,
1102, 602, 428, 335, 193, 323, 157,
423, 253,
},
{ 1072, 400, 180, 210, 60, 16, 3, 210, 40,
1063, 1063, 451, 451,
345, 221, 121, 73, 79, 64, 31, 6, 1, 1,
1105, 608, 462, 358, 202, 330, 155,
377, 228,
},
{ 1164, 503, 254, 330, 109, 34, 9, 167, 35,
1038, 1037, 390, 390,
278, 170, 89, 54, 56, 40, 13, 1, 1, 1,
1110, 607, 492, 401, 218, 343, 141,
323, 192,
},
{ 1173, 583, 321, 486, 196, 68, 23, 124, 23,
1037, 1037, 347, 346,
232, 139, 69, 40, 37, 20, 2, 1, 1, 1,
1128, 584, 506, 410, 199, 301, 113,
283, 159,
},
{ 1023, 591, 366, 699, 441, 228, 113, 79, 5,
1056, 1056, 291, 291,
173, 96, 38, 19, 8, 1, 1, 1, 1, 1,
1187, 527, 498, 409, 147, 210, 56,
263, 117,
},
/* AC Intra bias group 2 tables */
{ 311, 74, 27, 27, 5, 1, 1, 470, 24,
665, 667, 637, 638,
806, 687, 524, 402, 585, 679, 609, 364, 127, 20,
448, 210, 131, 76, 52, 111, 19,
393, 195,
},
{ 416, 104, 39, 38, 8, 1, 1, 545, 33,
730, 731, 692, 692,
866, 705, 501, 365, 495, 512, 387, 168, 39, 2,
517, 240, 154, 86, 64, 127, 19,
461, 247,
},
{ 474, 117, 43, 42, 9, 1, 1, 560, 40,
783, 783, 759, 760,
883, 698, 466, 318, 404, 377, 215, 66, 7, 1,
559, 259, 176, 110, 87, 170, 22,
520, 278,
},
{ 582, 149, 53, 53, 12, 2, 1, 473, 39,
992, 993, 712, 713,
792, 593, 373, 257, 299, 237, 114, 25, 1, 1,
710, 329, 221, 143, 116, 226, 26,
490, 259,
},
{ 744, 210, 78, 77, 16, 2, 1, 417, 37,
1034, 1035, 728, 728,
718, 509, 296, 175, 184, 122, 42, 3, 1, 1,
791, 363, 255, 168, 145, 311, 35,
492, 272,
},
{ 913, 291, 121, 128, 28, 4, 1, 334, 40,
1083, 1084, 711, 712,
624, 378, 191, 107, 95, 50, 7, 1, 1, 1,
876, 414, 288, 180, 164, 382, 39,
469, 275,
},
{ 1065, 405, 184, 216, 53, 8, 1, 236, 36,
1134, 1134, 685, 686,
465, 253, 113, 48, 41, 9, 1, 1, 1, 1,
965, 451, 309, 179, 166, 429, 53,
414, 249,
},
{ 1148, 548, 301, 438, 160, 42, 6, 84, 17,
1222, 1223, 574, 575,
272, 111, 23, 6, 2, 1, 1, 1, 1, 1,
1060, 502, 328, 159, 144, 501, 54,
302, 183,
},
/* AC Inter bias group 2 tables */
{ 403, 80, 24, 17, 1, 1, 1, 480, 90,
899, 899, 820, 819,
667, 413, 228, 133, 139, 98, 42, 10, 1, 1,
865, 470, 316, 222, 171, 419, 213,
645, 400,
},
{ 698, 169, 59, 49, 6, 1, 1, 414, 101,
894, 893, 761, 761,
561, 338, 171, 96, 97, 64, 26, 6, 1, 1,
896, 494, 343, 239, 192, 493, 215,
583, 366,
},
{ 914, 255, 94, 80, 10, 1, 1, 345, 128,
935, 935, 670, 671,
415, 222, 105, 55, 51, 30, 10, 1, 1, 1,
954, 530, 377, 274, 232, 641, 295,
456, 298,
},
{ 1103, 359, 146, 135, 20, 1, 1, 235, 119,
1042, 1042, 508, 507,
293, 146, 65, 33, 30, 16, 4, 1, 1, 1,
1031, 561, 407, 296, 265, 813, 317,
301, 192,
},
{ 1255, 504, 238, 265, 51, 5, 1, 185, 113,
1013, 1013, 437, 438,
212, 92, 41, 18, 15, 6, 1, 1, 1, 1,
976, 530, 386, 276, 260, 927, 357,
224, 148,
},
{ 1292, 610, 332, 460, 127, 16, 1, 136, 99,
1014, 1015, 384, 384,
153, 65, 25, 11, 6, 1, 1, 1, 1, 1,
942, 487, 343, 241, 238, 970, 358,
174, 103,
},
{ 1219, 655, 407, 700, 280, 55, 2, 100, 60,
1029, 1029, 337, 336,
119, 43, 11, 3, 2, 1, 1, 1, 1, 1,
894, 448, 305, 199, 213, 1005, 320,
136, 77,
},
{ 1099, 675, 435, 971, 581, 168, 12, 37, 16,
1181, 1081, 319, 318,
66, 11, 6, 1, 1, 1, 1, 1, 1, 1,
914, 370, 235, 138, 145, 949, 128,
94, 41,
},
/* AC Intra bias group 3 tables */
{ 486, 112, 39, 34, 6, 1, 1, 541, 67,
819, 818, 762, 763,
813, 643, 403, 280, 332, 295, 164, 53, 6, 1,
632, 294, 180, 131, 105, 208, 109,
594, 295,
},
{ 723, 191, 69, 65, 12, 1, 1, 445, 79,
865, 865, 816, 816,
750, 515, 290, 172, 184, 122, 46, 5, 1, 1,
740, 340, 213, 165, 129, 270, 168,
603, 326,
},
{ 884, 264, 102, 103, 21, 3, 1, 382, 68,
897, 897, 836, 836,
684, 427, 227, 119, 119, 70, 16, 1, 1, 1,
771, 367, 234, 184, 143, 272, 178,
555, 326,
},
{ 1028, 347, 153, 161, 36, 8, 1, 251, 44,
1083, 1084, 735, 735,
541, 289, 144, 77, 57, 23, 3, 1, 1, 1,
926, 422, 270, 215, 176, 301, 183,
443, 248,
},
{ 1155, 465, 224, 264, 71, 14, 3, 174, 27,
1110, 1111, 730, 731,
429, 206, 79, 30, 19, 4, 1, 1, 1, 1,
929, 443, 279, 225, 194, 298, 196,
354, 223,
},
{ 1191, 576, 296, 415, 144, 36, 8, 114, 16,
1162, 1162, 749, 749,
338, 108, 29, 8, 5, 1, 1, 1, 1, 1,
947, 458, 273, 207, 194, 248, 145,
258, 152,
},
{ 1169, 619, 366, 603, 247, 92, 23, 46, 1,
1236, 1236, 774, 775,
191, 35, 14, 1, 1, 1, 1, 1, 1, 1,
913, 449, 260, 214, 194, 180, 82,
174, 98,
},
{ 1006, 537, 381, 897, 504, 266, 101, 39, 1,
1307, 1307, 668, 667,
116, 3, 1, 1, 1, 1, 1, 1, 1, 1,
1175, 261, 295, 70, 164, 107, 31,
10, 76,
},
/* AC Inter bias group 3 tables */
{ 652, 156, 53, 43, 5, 1, 1, 368, 128,
983, 984, 825, 825,
583, 331, 163, 88, 84, 48, 15, 1, 1, 1,
870, 480, 316, 228, 179, 421, 244,
562, 349,
},
{ 988, 280, 104, 87, 12, 1, 1, 282, 194,
980, 981, 738, 739,
395, 189, 80, 37, 31, 12, 2, 1, 1, 1,
862, 489, 333, 262, 214, 600, 446,
390, 260,
},
{ 1176, 399, 165, 154, 24, 2, 1, 218, 224,
1017, 1018, 651, 651,
280, 111, 42, 16, 9, 3, 1, 1, 1, 1,
787, 469, 324, 269, 229, 686, 603,
267, 194,
},
{ 1319, 530, 255, 268, 47, 4, 1, 113, 183,
1149, 1150, 461, 461,
173, 58, 17, 5, 3, 1, 1, 1, 1, 1,
768, 450, 305, 261, 221, 716, 835,
136, 97,
},
{ 1362, 669, 355, 465, 104, 9, 1, 76, 153,
1253, 1253, 398, 397,
102, 21, 5, 1, 1, 1, 1, 1, 1, 1,
596, 371, 238, 228, 196, 660, 954,
68, 53,
},
{ 1354, 741, 446, 702, 174, 15, 1, 38, 87,
1498, 1498, 294, 294,
43, 7, 1, 1, 1, 1, 1, 1, 1, 1,
381, 283, 165, 181, 155, 544, 1039,
25, 21,
},
{ 1262, 885, 546, 947, 263, 18, 1, 18, 27,
1908, 1908, 163, 162,
14, 1, 1, 1, 1, 1, 1, 1, 1, 1,
195, 152, 83, 125, 109, 361, 827,
7, 5,
},
{ 2539, 951, 369, 554, 212, 18, 1, 1, 1,
2290, 2289, 64, 64,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
18, 18, 9, 55, 36, 184, 323,
1, 1,
},
/* AC Intra bias group 4 tables */
{ 921, 264, 101, 100, 19, 2, 1, 331, 98,
1015, 1016, 799, 799,
512, 269, 119, 60, 50, 17, 1, 1, 1, 1,
841, 442, 307, 222, 182, 493, 256,
438, 310,
},
{ 1147, 412, 184, 206, 50, 6, 1, 242, 141,
977, 976, 808, 807,
377, 135, 40, 10, 7, 1, 1, 1, 1, 1,
788, 402, 308, 223, 205, 584, 406,
316, 227,
},
{ 1243, 504, 238, 310, 79, 11, 1, 184, 150,
983, 984, 814, 813,
285, 56, 10, 1, 1, 1, 1, 1, 1, 1,
713, 377, 287, 217, 180, 615, 558,
208, 164,
},
{ 1266, 606, 329, 484, 161, 27, 1, 79, 92,
1187, 1188, 589, 588,
103, 10, 1, 1, 1, 1, 1, 1, 1, 1,
680, 371, 278, 221, 244, 614, 728,
80, 62,
},
{ 1126, 828, 435, 705, 443, 90, 8, 10, 55,
1220, 1219, 350, 350,
28, 1, 1, 1, 1, 1, 1, 1, 1, 1,
602, 330, 222, 168, 158, 612, 919,
104, 5,
},
{ 1210, 506, 1014, 926, 474, 240, 4, 1, 44,
1801, 1801, 171, 171,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
900, 132, 36, 11, 47, 191, 316,
2, 1,
},
{ 1210, 506, 1014, 926, 474, 240, 4, 1, 44,
1801, 1801, 171, 171,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
900, 132, 36, 11, 47, 191, 316,
2, 1,
},
{ 1210, 506, 1014, 926, 474, 240, 4, 1, 44,
1801, 1801, 171, 171,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
900, 132, 36, 11, 47, 191, 316,
2, 1,
},
/* AC Inter bias group 4 tables */
{ 1064, 325, 129, 117, 20, 2, 1, 266, 121,
1000, 1000, 706, 706,
348, 162, 67, 32, 25, 11, 1, 1, 1, 1,
876, 513, 363, 274, 225, 627, 384,
370, 251,
},
{ 1311, 517, 238, 254, 45, 3, 1, 188, 160,
1070, 1070, 635, 635,
239, 85, 30, 11, 6, 1, 1, 1, 1, 1,
744, 420, 313, 239, 206, 649, 541,
221, 155,
},
{ 1394, 632, 322, 385, 78, 7, 1, 134, 152,
1163, 1164, 607, 607,
185, 51, 12, 3, 1, 1, 1, 1, 1, 1,
631, 331, 275, 203, 182, 604, 620,
146, 98,
},
{ 1410, 727, 407, 546, 146, 19, 1, 67, 88,
1485, 1486, 419, 418,
103, 18, 3, 1, 1, 1, 1, 1, 1, 1,
555, 261, 234, 164, 148, 522, 654,
67, 39,
},
{ 1423, 822, 492, 719, 216, 22, 1, 28, 59,
1793, 1793, 323, 324,
37, 2, 1, 1, 1, 1, 1, 1, 1, 1,
376, 138, 158, 102, 119, 400, 604,
28, 9,
},
{ 1585, 923, 563, 918, 207, 25, 1, 5, 20,
2229, 2230, 172, 172,
7, 1, 1, 1, 1, 1, 1, 1, 1, 1,
191, 40, 56, 22, 65, 243, 312,
2, 1,
},
{ 2225, 1100, 408, 608, 133, 8, 1, 1, 1,
2658, 2658, 25, 24,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
8, 1, 1, 1, 1, 125, 16,
1, 1,
},
{ 2539, 951, 369, 554, 212, 18, 1, 1, 1,
2290, 2289, 64, 64,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
18, 18, 9, 55, 36, 184, 323,
1, 1,
},
};
/* New baseline frequency tables for encoder version >= 2 */
ogg_uint32_t FrequencyCounts_VP33[NUM_HUFF_TABLES][MAX_ENTROPY_TOKENS] = {
/* DC Intra bias */
{ 272, 84, 31, 36, 10, 2, 1, 92, 1,
701, 872, 410, 478,
630, 502, 417, 356, 582, 824, 985, 965, 697, 606,
125, 119, 40, 3, 9, 15, 10,
73, 37,
},
{ 311, 107, 41, 51, 18, 4, 2, 120, 1,
824, 1037, 468, 541,
714, 555, 451, 374, 595, 819, 929, 817, 474, 220,
172, 142, 27, 4, 9, 10, 2,
98, 48,
},
{ 353, 125, 49, 66, 24, 6, 2, 124, 1,
926, 1172, 512, 594,
766, 581, 458, 379, 590, 789, 849, 665, 306, 80,
204, 147, 25, 5, 12, 9, 2,
108, 54,
},
{ 392, 141, 57, 75, 31, 7, 4, 138, 1,
1050, 1321, 559, 649,
806, 594, 460, 372, 568, 727, 710, 475, 155, 19,
251, 174, 27, 7, 16, 8, 2,
126, 62,
},
{ 455, 168, 66, 87, 39, 10, 6, 124, 2,
1143, 1455, 592, 692,
824, 596, 453, 361, 542, 657, 592, 329, 78, 5,
269, 184, 27, 9, 19, 7, 2,
127, 66,
},
{ 544, 201, 80, 102, 45, 11, 6, 99, 1,
1236, 1587, 610, 720,
833, 590, 444, 348, 506, 588, 487, 226, 39, 2,
253, 178, 27, 10, 20, 7, 2,
118, 65,
},
{ 649, 241, 98, 121, 54, 14, 8, 84, 1,
1349, 1719, 634, 763,
847, 583, 428, 323, 456, 492, 349, 120, 13, 1,
231, 170, 24, 8, 19, 7, 1,
109, 67,
},
{ 824, 304, 129, 158, 66, 19, 10, 44, 2,
1476, 1925, 644, 794,
838, 559, 396, 289, 392, 384, 223, 53, 3, 1,
159, 121, 17, 6, 16, 6, 2,
69, 53,
},
/* DC Inter Bias */
{ 534, 174, 71, 68, 10, 1, 1, 68, 119,
1674, 1526, 560, 536,
539, 331, 229, 168, 233, 262, 231, 149, 71, 51,
629, 530, 284, 126, 182, 208, 184,
148, 87,
},
{ 594, 195, 77, 71, 9, 1, 1, 47, 89,
1723, 1592, 595, 570,
574, 351, 241, 176, 243, 271, 234, 144, 65, 37,
534, 449, 240, 117, 167, 277, 153,
96, 54,
},
{ 642, 213, 88, 83, 12, 1, 1, 40, 80,
1751, 1630, 621, 600,
598, 367, 250, 183, 251, 276, 235, 143, 62, 28,
485, 397, 212, 110, 161, 193, 141,
84, 48,
},
{ 693, 258, 114, 131, 27, 3, 1, 44, 79,
1794, 1644, 550, 533,
518, 314, 213, 154, 209, 223, 174, 97, 40, 14,
584, 463, 236, 138, 196, 249, 143,
94, 54,
},
{ 758, 303, 144, 189, 53, 8, 1, 37, 69,
1842, 1732, 513, 504,
478, 287, 191, 137, 182, 186, 137, 72, 31, 6,
589, 469, 199, 128, 177, 264, 161,
89, 49,
},
{ 817, 344, 170, 243, 84, 18, 2, 30, 65,
1836, 1733, 518, 511,
477, 281, 185, 130, 169, 166, 117, 59, 25, 3,
572, 450, 185, 121, 173, 232, 146,
80, 43,
},
{ 865, 389, 204, 322, 139, 42, 9, 26, 51,
1848, 1766, 531, 522,
477, 275, 177, 122, 153, 144, 97, 50, 16, 1,
485, 378, 167, 115, 164, 203, 128,
74, 42,
},
{ 961, 447, 243, 407, 196, 74, 26, 12, 34,
2003, 1942, 571, 565,
494, 278, 173, 116, 141, 129, 85, 44, 8, 1,
285, 223, 101, 66, 104, 120, 74,
35, 22,
},
/* AC INTRA Tables */
/* AC Intra bias group 1 tables */
{ 245, 68, 25, 28, 5, 1, 1, 359, 4,
910, 904, 570, 571,
766, 620, 478, 375, 554, 684, 652, 441, 182, 30,
535, 206, 118, 77, 69, 90, 16,
299, 100,
},
{ 302, 86, 32, 36, 8, 1, 1, 362, 3,
974, 968, 599, 599,
774, 635, 469, 365, 528, 628, 557, 337, 118, 14,
577, 219, 136, 82, 69, 65, 13,
317, 112,
},
{ 348, 102, 39, 44, 9, 2, 1, 363, 3,
1062, 1055, 607, 609,
787, 626, 457, 348, 494, 550, 452, 233, 60, 2,
636, 244, 159, 92, 74, 68, 12,
327, 119,
},
{ 400, 121, 47, 51, 11, 2, 1, 366, 3,
1109, 1102, 620, 622,
786, 624, 450, 331, 459, 490, 366, 163, 29, 1,
673, 257, 175, 98, 77, 63, 14,
344, 131,
},
{ 470, 151, 59, 67, 15, 3, 1, 354, 4,
1198, 1189, 640, 643,
769, 603, 410, 294, 386, 381, 240, 78, 5, 1,
746, 282, 205, 113, 87, 64, 15,
368, 145,
},
{ 553, 189, 77, 94, 24, 6, 1, 347, 4,
1244, 1232, 650, 653,
739, 551, 360, 249, 303, 261, 129, 24, 1, 1,
828, 313, 245, 135, 108, 77, 17,
403, 169,
},
{ 701, 253, 109, 140, 42, 12, 2, 350, 6,
1210, 1197, 652, 647,
673, 495, 299, 189, 211, 151, 50, 2, 1, 1,
892, 336, 284, 162, 134, 101, 25,
455, 205,
},
{ 924, 390, 180, 248, 85, 31, 13, 286, 14,
1242, 1206, 601, 577,
519, 342, 175, 100, 85, 36, 1, 1, 1, 1,
1031, 348, 346, 204, 166, 131, 34,
473, 197,
},
/* AC Inter bias group 1 tables */
{ 459, 128, 50, 48, 8, 1, 1, 224, 69,
1285, 1227, 587, 565,
573, 406, 261, 180, 228, 213, 130, 47, 11, 3,
1069, 540, 309, 231, 147, 279, 157,
383, 165,
},
{ 524, 155, 62, 64, 14, 2, 1, 209, 63,
1345, 1288, 523, 507,
515, 358, 225, 153, 183, 160, 87, 29, 7, 2,
1151, 591, 365, 282, 179, 308, 133,
344, 157,
},
{ 588, 181, 75, 81, 19, 3, 1, 204, 68,
1344, 1288, 517, 503,
505, 346, 216, 141, 169, 139, 71, 21, 5, 1,
1146, 584, 366, 286, 170, 298, 153,
342, 157,
},
{ 634, 196, 82, 89, 22, 4, 1, 194, 60,
1356, 1312, 515, 502,
489, 331, 199, 127, 145, 111, 51, 14, 3, 1,
1156, 589, 393, 300, 182, 285, 144,
340, 159,
},
{ 715, 231, 98, 113, 31, 7, 1, 181, 57,
1345, 1303, 498, 490,
448, 291, 166, 101, 106, 75, 30, 9, 1, 1,
1175, 584, 416, 321, 209, 333, 164,
330, 159,
},
{ 825, 283, 125, 149, 44, 11, 2, 160, 59,
1343, 1308, 476, 469,
405, 247, 131, 75, 76, 47, 18, 5, 1, 1,
1192, 579, 432, 332, 217, 327, 176,
320, 154,
},
{ 961, 361, 170, 215, 70, 20, 5, 161, 55,
1250, 1218, 463, 460,
354, 204, 101, 52, 48, 28, 11, 1, 1, 1,
1172, 570, 449, 350, 222, 332, 169,
338, 174,
},
{ 1139, 506, 266, 387, 156, 57, 26, 114, 48,
1192, 1170, 366, 366,
226, 113, 47, 22, 22, 12, 1, 1, 1, 1,
1222, 551, 462, 391, 220, 322, 156,
290, 136,
},
/* AC Intra bias group 2 tables */
{ 245, 49, 15, 11, 1, 1, 1, 332, 38,
1163, 1162, 685, 683,
813, 623, 437, 318, 421, 424, 288, 109, 14, 1,
729, 303, 179, 112, 87, 199, 46,
364, 135,
},
{ 305, 67, 22, 17, 2, 1, 1, 329, 39,
1250, 1245, 706, 705,
801, 584, 385, 267, 330, 296, 165, 40, 3, 1,
798, 340, 206, 131, 108, 258, 52,
382, 154,
},
{ 356, 82, 28, 23, 3, 1, 1, 312, 42,
1340, 1334, 701, 703,
770, 545, 346, 227, 269, 223, 100, 17, 1, 1,
846, 359, 222, 142, 120, 284, 55,
379, 157,
},
{ 402, 95, 33, 30, 4, 1, 1, 300, 43,
1379, 1371, 710, 714,
724, 486, 289, 182, 202, 144, 47, 5, 1, 1,
908, 394, 250, 161, 141, 350, 60,
391, 171,
},
{ 499, 122, 44, 42, 7, 1, 1, 267, 45,
1439, 1436, 690, 694,
628, 385, 213, 122, 117, 62, 14, 1, 1, 1,
992, 441, 288, 187, 167, 446, 82,
378, 176,
},
{ 641, 168, 62, 60, 12, 1, 1, 247, 49,
1435, 1436, 662, 669,
527, 298, 142, 71, 55, 22, 3, 1, 1, 1,
1036, 470, 319, 208, 193, 548, 106,
362, 184,
},
{ 860, 274, 111, 113, 23, 4, 1, 229, 59,
1331, 1323, 629, 645,
419, 192, 72, 30, 19, 6, 1, 1, 1, 1,
1022, 478, 339, 225, 213, 690, 142,
342, 198,
},
{ 1059, 437, 218, 285, 84, 17, 2, 152, 44,
1284, 1313, 530, 561,
212, 66, 17, 6, 3, 1, 1, 1, 1, 1,
1034, 485, 346, 226, 207, 819, 185,
248, 145,
},
/* AC Inter bias group 2 tables */
{ 407, 93, 31, 24, 2, 1, 1, 232, 108,
1365, 1349, 581, 578,
498, 305, 170, 100, 103, 67, 24, 5, 1, 1,
1175, 604, 393, 268, 209, 506, 217,
379, 193,
},
{ 521, 129, 46, 39, 4, 1, 1, 199, 116,
1419, 1403, 543, 540,
446, 263, 138, 78, 75, 44, 13, 2, 1, 1,
1201, 605, 392, 267, 214, 533, 252,
334, 167,
},
{ 575, 144, 52, 46, 6, 1, 1, 193, 124,
1394, 1384, 528, 528,
406, 227, 112, 59, 54, 28, 7, 1, 1, 1,
1210, 621, 412, 284, 235, 604, 265,
320, 167,
},
{ 673, 174, 64, 59, 9, 1, 1, 177, 128,
1392, 1385, 499, 499,
352, 183, 85, 42, 35, 16, 3, 1, 1, 1,
1210, 626, 418, 289, 246, 675, 297,
292, 158,
},
{ 804, 225, 85, 77, 12, 1, 1, 150, 129,
1387, 1384, 455, 455,
277, 129, 53, 23, 17, 7, 1, 1, 1, 1,
1212, 635, 433, 306, 268, 760, 313,
249, 137,
},
{ 975, 305, 123, 117, 20, 2, 1, 135, 140,
1312, 1310, 401, 399,
201, 80, 28, 11, 8, 2, 1, 1, 1, 1,
1162, 623, 439, 314, 283, 906, 368,
203, 121,
},
{ 1205, 452, 208, 231, 50, 6, 1, 123, 149,
1161, 1164, 370, 370,
137, 45, 14, 4, 2, 1, 1, 1, 1, 1,
1047, 562, 413, 300, 277, 1020, 404,
168, 105,
},
{ 1297, 662, 389, 574, 200, 39, 4, 55, 120,
1069, 1076, 273, 265,
66, 14, 2, 1, 1, 1, 1, 1, 1, 1,
930, 475, 345, 249, 236, 1124, 376,
91, 56,
},
/* AC Intra bias group 3 tables */
{ 278, 55, 17, 12, 1, 1, 1, 288, 71,
1315, 1304, 725, 724,
733, 506, 307, 195, 225, 175, 77, 12, 1, 1,
904, 414, 246, 170, 126, 290, 205,
423, 185,
},
{ 382, 80, 26, 21, 2, 1, 1, 239, 64,
1442, 1429, 706, 701,
664, 420, 239, 146, 152, 105, 34, 2, 1, 1,
975, 440, 263, 185, 140, 332, 229,
397, 169,
},
{ 451, 97, 32, 27, 4, 1, 1, 223, 75,
1462, 1454, 682, 680,
574, 343, 179, 101, 98, 54, 9, 1, 1, 1,
1031, 482, 293, 210, 163, 400, 297,
384, 181,
},
{ 551, 128, 43, 37, 5, 1, 1, 201, 78,
1497, 1487, 642, 651,
493, 269, 133, 70, 60, 24, 2, 1, 1, 1,
1065, 504, 312, 228, 178, 451, 352,
351, 174,
},
{ 693, 179, 63, 54, 8, 1, 1, 169, 78,
1502, 1497, 580, 591,
375, 186, 77, 35, 21, 4, 1, 1, 1, 1,
1099, 533, 341, 253, 206, 542, 432,
306, 164,
},
{ 867, 263, 105, 96, 16, 2, 1, 152, 81,
1435, 1439, 521, 525,
270, 107, 32, 8, 3, 1, 1, 1, 1, 1,
1085, 537, 361, 277, 223, 616, 549,
258, 156,
},
{ 1022, 385, 182, 207, 46, 7, 1, 158, 88,
1290, 1318, 501, 502,
184, 38, 6, 1, 1, 1, 1, 1, 1, 1,
1023, 480, 345, 301, 232, 665, 661,
210, 133,
},
{ 1184, 555, 307, 457, 185, 44, 6, 115, 41,
1236, 1253, 329, 340,
32, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1017, 385, 316, 370, 246, 672, 788,
85, 23,
},
/* AC Inter bias group 3 tables */
{ 502, 106, 33, 22, 1, 1, 1, 151, 132,
1446, 1451, 502, 499,
343, 181, 84, 42, 36, 16, 3, 1, 1, 1,
1211, 661, 429, 312, 242, 637, 498,
288, 156,
},
{ 651, 147, 48, 35, 3, 1, 1, 145, 140,
1419, 1420, 469, 466,
281, 132, 56, 25, 18, 6, 1, 1, 1, 1,
1175, 656, 435, 328, 260, 715, 556,
252, 147,
},
{ 749, 179, 59, 43, 4, 1, 1, 123, 135,
1423, 1431, 413, 409,
221, 95, 36, 15, 9, 2, 1, 1, 1, 1,
1159, 658, 444, 340, 272, 782, 656,
205, 124,
},
{ 902, 243, 86, 67, 7, 1, 1, 114, 141,
1385, 1385, 387, 383,
178, 67, 22, 7, 4, 1, 1, 1, 1, 1,
1096, 632, 434, 339, 277, 813, 735,
171, 109,
},
{ 1081, 337, 133, 112, 15, 1, 1, 92, 137,
1350, 1349, 311, 309,
115, 34, 8, 2, 1, 1, 1, 1, 1, 1,
1016, 595, 418, 342, 283, 870, 883,
114, 78,
},
{ 1253, 467, 210, 205, 34, 3, 1, 80, 130,
1318, 1313, 258, 260,
68, 12, 2, 1, 1, 1, 1, 1, 1, 1,
874, 516, 378, 330, 273, 877, 1000,
72, 53,
},
{ 1362, 626, 333, 423, 100, 10, 1, 73, 106,
1311, 1313, 241, 231,
31, 3, 1, 1, 1, 1, 1, 1, 1, 1,
620, 368, 286, 302, 245, 814, 1127,
34, 28,
},
{ 1203, 743, 460, 774, 284, 36, 1, 13, 25,
1956, 1961, 103, 106,
3, 1, 1, 1, 1, 1, 1, 1, 1, 1,
248, 131, 149, 272, 165, 535, 813,
3, 3,
},
/* AC Intra bias group 4 tables */
{ 599, 150, 55, 50, 9, 1, 1, 181, 19,
1487, 1487, 625, 625,
473, 271, 138, 74, 71, 42, 11, 1, 1, 1,
1187, 591, 356, 239, 170, 351, 137,
395, 194,
},
{ 758, 209, 79, 74, 15, 2, 1, 147, 25,
1514, 1514, 521, 520,
334, 165, 74, 36, 30, 11, 1, 1, 1, 1,
1252, 644, 409, 279, 211, 472, 203,
318, 171,
},
{ 852, 252, 100, 98, 20, 3, 1, 130, 26,
1493, 1498, 481, 473,
268, 123, 51, 23, 15, 3, 1, 1, 1, 1,
1256, 652, 426, 294, 231, 543, 242,
278, 156,
},
{ 971, 309, 130, 136, 30, 5, 1, 113, 28,
1458, 1467, 443, 435,
215, 90, 31, 12, 5, 1, 1, 1, 1, 1,
1232, 643, 426, 303, 243, 590, 300,
235, 136,
},
{ 1100, 399, 180, 206, 53, 9, 1, 101, 29,
1419, 1425, 375, 374,
158, 47, 10, 1, 1, 1, 1, 1, 1, 1,
1193, 609, 426, 319, 256, 643, 383,
166, 103,
},
{ 1195, 505, 249, 326, 98, 20, 3, 102, 25,
1370, 1356, 355, 347,
104, 11, 1, 1, 1, 1, 1, 1, 1, 1,
1100, 568, 381, 330, 261, 642, 466,
105, 69,
},
{ 1176, 608, 345, 559, 244, 57, 6, 110, 9,
1370, 1332, 372, 367,
29, 1, 1, 1, 1, 1, 1, 1, 1, 1,
859, 427, 269, 359, 375, 608, 451,
35, 20,
},
{ 1140, 613, 391, 797, 458, 180, 37, 2, 1,
2037, 1697, 95, 31,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
360, 49, 23, 198, 1001, 719, 160,
1, 1,
},
/* AC Inter bias group 4 tables */
{ 931, 272, 105, 96, 16, 1, 1, 91, 52,
1481, 1489, 347, 349,
174, 74, 28, 12, 8, 3, 1, 1, 1, 1,
1247, 719, 490, 356, 279, 706, 363,
187, 110,
},
{ 1095, 358, 148, 143, 25, 3, 1, 74, 61,
1439, 1457, 304, 302,
127, 46, 15, 5, 3, 1, 1, 1, 1, 1,
1138, 664, 469, 347, 282, 768, 487,
139, 87,
},
{ 1192, 423, 188, 189, 36, 4, 1, 64, 61,
1457, 1475, 284, 282,
106, 35, 10, 3, 1, 1, 1, 1, 1, 1,
1078, 624, 440, 329, 264, 744, 507,
117, 73,
},
{ 1275, 496, 231, 258, 52, 6, 1, 53, 55,
1458, 1470, 248, 245,
77, 20, 5, 1, 1, 1, 1, 1, 1, 1,
984, 576, 414, 323, 260, 771, 569,
84, 54,
},
{ 1377, 603, 302, 367, 87, 11, 1, 37, 52,
1522, 1532, 207, 204,
47, 8, 1, 1, 1, 1, 1, 1, 1, 1,
840, 493, 366, 291, 231, 690, 636,
52, 32,
},
{ 1409, 708, 385, 529, 148, 24, 1, 23, 37,
1672, 1670, 163, 162,
22, 2, 1, 1, 1, 1, 1, 1, 1, 1,
647, 364, 291, 262, 210, 574, 643,
26, 14,
},
{ 1348, 778, 481, 755, 245, 53, 4, 13, 19,
2114, 2089, 141, 139,
7, 1, 1, 1, 1, 1, 1, 1, 1, 1,
302, 183, 162, 181, 182, 344, 437,
8, 3,
},
{ 1560, 769, 410, 664, 243, 58, 1, 1, 1,
3017, 2788, 17, 24,
3, 1, 1, 1, 1, 1, 1, 1, 1, 1,
34, 16, 8, 55, 134, 105, 86,
1, 1,
},
};
<p><p>1.1 theora/lib/idct.c
Index: idct.c
===================================================================
/********************************************************************
* *
* 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 OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function:
last mod: $Id: idct.c,v 1.1 2002/09/18 08:56:57 xiphmont Exp $
********************************************************************/
#include <ogg/ogg.h>
#include "encoder_internal.h"
#include "encoder_lookup.h"
#define IdctAdjustBeforeShift 8
#define xC1S7 64277
#define xC2S6 60547
#define xC3S5 54491
#define xC4S4 46341
#define xC5S3 36410
#define xC6S2 25080
#define xC7S1 12785
void dequant_slow( ogg_int16_t * dequant_coeffs,
ogg_int16_t * quantized_list,
ogg_int32_t * DCT_block) {
int i;
for(i=0;i<64;i++)
DCT_block[dequant_index[i]] = quantized_list[i] * dequant_coeffs[i];
}
void IDctSlow( Q_LIST_ENTRY * InputData,
ogg_int16_t *QuantMatrix,
ogg_int16_t * OutputData ) {
ogg_int32_t IntermediateData[64];
ogg_int32_t * ip = IntermediateData;
ogg_int16_t * op = OutputData;
ogg_int32_t _A, _B, _C, _D, _Ad, _Bd, _Cd, _Dd, _E, _F, _G, _H;
ogg_int32_t _Ed, _Gd, _Add, _Bdd, _Fd, _Hd;
ogg_int32_t t1, t2;
int loop;
dequant_slow( QuantMatrix, InputData, IntermediateData);
/* Inverse DCT on the rows now */
for ( loop = 0; loop < 8; loop++){
/* Check for non-zero values */
if ( ip[0] | ip[1] | ip[2] | ip[3] | ip[4] | ip[5] | ip[6] | ip[7] ) {
t1 = (xC1S7 * ip[1]);
t2 = (xC7S1 * ip[7]);
t1 >>= 16;
t2 >>= 16;
_A = t1 + t2;
t1 = (xC7S1 * ip[1]);
t2 = (xC1S7 * ip[7]);
t1 >>= 16;
t2 >>= 16;
_B = t1 - t2;
t1 = (xC3S5 * ip[3]);
t2 = (xC5S3 * ip[5]);
t1 >>= 16;
t2 >>= 16;
_C = t1 + t2;
t1 = (xC3S5 * ip[5]);
t2 = (xC5S3 * ip[3]);
t1 >>= 16;
t2 >>= 16;
_D = t1 - t2;
t1 = (xC4S4 * (_A - _C));
t1 >>= 16;
_Ad = t1;
t1 = (xC4S4 * (_B - _D));
t1 >>= 16;
_Bd = t1;
_Cd = _A + _C;
_Dd = _B + _D;
t1 = (xC4S4 * (ip[0] + ip[4]));
t1 >>= 16;
_E = t1;
t1 = (xC4S4 * (ip[0] - ip[4]));
t1 >>= 16;
_F = t1;
t1 = (xC2S6 * ip[2]);
t2 = (xC6S2 * ip[6]);
t1 >>= 16;
t2 >>= 16;
_G = t1 + t2;
t1 = (xC6S2 * ip[2]);
t2 = (xC2S6 * ip[6]);
t1 >>= 16;
t2 >>= 16;
_H = t1 - t2;
_Ed = _E - _G;
_Gd = _E + _G;
_Add = _F + _Ad;
_Bdd = _Bd - _H;
_Fd = _F - _Ad;
_Hd = _Bd + _H;
/* Final sequence of operations over-write original inputs. */
ip[0] = (ogg_int16_t)((_Gd + _Cd ) >> 0);
ip[7] = (ogg_int16_t)((_Gd - _Cd ) >> 0);
ip[1] = (ogg_int16_t)((_Add + _Hd ) >> 0);
ip[2] = (ogg_int16_t)((_Add - _Hd ) >> 0);
ip[3] = (ogg_int16_t)((_Ed + _Dd ) >> 0);
ip[4] = (ogg_int16_t)((_Ed - _Dd ) >> 0);
ip[5] = (ogg_int16_t)((_Fd + _Bdd ) >> 0);
ip[6] = (ogg_int16_t)((_Fd - _Bdd ) >> 0);
}
ip += 8; /* next row */
}
ip = IntermediateData;
for ( loop = 0; loop < 8; loop++){
/* Check for non-zero values (bitwise or faster than ||) */
if ( ip[0 * 8] | ip[1 * 8] | ip[2 * 8] | ip[3 * 8] |
ip[4 * 8] | ip[5 * 8] | ip[6 * 8] | ip[7 * 8] ) {
t1 = (xC1S7 * ip[1*8]);
t2 = (xC7S1 * ip[7*8]);
t1 >>= 16;
t2 >>= 16;
_A = t1 + t2;
t1 = (xC7S1 * ip[1*8]);
t2 = (xC1S7 * ip[7*8]);
t1 >>= 16;
t2 >>= 16;
_B = t1 - t2;
t1 = (xC3S5 * ip[3*8]);
t2 = (xC5S3 * ip[5*8]);
t1 >>= 16;
t2 >>= 16;
_C = t1 + t2;
t1 = (xC3S5 * ip[5*8]);
t2 = (xC5S3 * ip[3*8]);
t1 >>= 16;
t2 >>= 16;
_D = t1 - t2;
t1 = (xC4S4 * (_A - _C));
t1 >>= 16;
_Ad = t1;
t1 = (xC4S4 * (_B - _D));
t1 >>= 16;
_Bd = t1;
_Cd = _A + _C;
_Dd = _B + _D;
t1 = (xC4S4 * (ip[0*8] + ip[4*8]));
t1 >>= 16;
_E = t1;
t1 = (xC4S4 * (ip[0*8] - ip[4*8]));
t1 >>= 16;
_F = t1;
t1 = (xC2S6 * ip[2*8]);
t2 = (xC6S2 * ip[6*8]);
t1 >>= 16;
t2 >>= 16;
_G = t1 + t2;
t1 = (xC6S2 * ip[2*8]);
t2 = (xC2S6 * ip[6*8]);
t1 >>= 16;
t2 >>= 16;
_H = t1 - t2;
_Ed = _E - _G;
_Gd = _E + _G;
_Add = _F + _Ad;
_Bdd = _Bd - _H;
_Fd = _F - _Ad;
_Hd = _Bd + _H;
_Gd += IdctAdjustBeforeShift;
_Add += IdctAdjustBeforeShift;
_Ed += IdctAdjustBeforeShift;
_Fd += IdctAdjustBeforeShift;
/* Final sequence of operations over-write original inputs. */
op[0*8] = (ogg_int16_t)((_Gd + _Cd ) >> 4);
op[7*8] = (ogg_int16_t)((_Gd - _Cd ) >> 4);
op[1*8] = (ogg_int16_t)((_Add + _Hd ) >> 4);
op[2*8] = (ogg_int16_t)((_Add - _Hd ) >> 4);
op[3*8] = (ogg_int16_t)((_Ed + _Dd ) >> 4);
op[4*8] = (ogg_int16_t)((_Ed - _Dd ) >> 4);
op[5*8] = (ogg_int16_t)((_Fd + _Bdd ) >> 4);
op[6*8] = (ogg_int16_t)((_Fd - _Bdd ) >> 4);
}else{
op[0*8] = 0;
op[7*8] = 0;
op[1*8] = 0;
op[2*8] = 0;
op[3*8] = 0;
op[4*8] = 0;
op[5*8] = 0;
op[6*8] = 0;
}
ip++; /* next column */
op++;
}
}
/*////////////////////////
// x x x x 0 0 0 0
// x x x 0 0 0 0 0
// x x 0 0 0 0 0 0
// x 0 0 0 0 0 0 0
// 0 0 0 0 0 0 0 0
// 0 0 0 0 0 0 0 0
// 0 0 0 0 0 0 0 0
// 0 0 0 0 0 0 0 0
////////////////////////*/
void dequant_slow10( ogg_int16_t * dequant_coeffs,
ogg_int16_t * quantized_list,
ogg_int32_t * DCT_block){
int i;
memset(DCT_block,0, 128);
for(i=0;i<10;i++)
DCT_block[dequant_index[i]] = quantized_list[i] * dequant_coeffs[i];
}
void IDct10( Q_LIST_ENTRY * InputData,
ogg_int16_t *QuantMatrix,
ogg_int16_t * OutputData ){
ogg_int32_t IntermediateData[64];
ogg_int32_t * ip = IntermediateData;
ogg_int16_t * op = OutputData;
ogg_int32_t _A, _B, _C, _D, _Ad, _Bd, _Cd, _Dd, _E, _F, _G, _H;
ogg_int32_t _Ed, _Gd, _Add, _Bdd, _Fd, _Hd;
ogg_int32_t t1, t2;
int loop;
dequant_slow10( QuantMatrix, InputData, IntermediateData);
/* Inverse DCT on the rows now */
for ( loop = 0; loop < 4; loop++){
/* Check for non-zero values */
if ( ip[0] | ip[1] | ip[2] | ip[3] ){
t1 = (xC1S7 * ip[1]);
t1 >>= 16;
_A = t1;
t1 = (xC7S1 * ip[1]);
t1 >>= 16;
_B = t1 ;
t1 = (xC3S5 * ip[3]);
t1 >>= 16;
_C = t1;
t2 = (xC5S3 * ip[3]);
t2 >>= 16;
_D = -t2;
t1 = (xC4S4 * (_A - _C));
t1 >>= 16;
_Ad = t1;
t1 = (xC4S4 * (_B - _D));
t1 >>= 16;
_Bd = t1;
_Cd = _A + _C;
_Dd = _B + _D;
t1 = (xC4S4 * ip[0] );
t1 >>= 16;
_E = t1;
_F = t1;
t1 = (xC2S6 * ip[2]);
t1 >>= 16;
_G = t1;
t1 = (xC6S2 * ip[2]);
t1 >>= 16;
_H = t1 ;
_Ed = _E - _G;
_Gd = _E + _G;
_Add = _F + _Ad;
_Bdd = _Bd - _H;
_Fd = _F - _Ad;
_Hd = _Bd + _H;
/* Final sequence of operations over-write original inputs. */
ip[0] = (ogg_int16_t)((_Gd + _Cd ) >> 0);
ip[7] = (ogg_int16_t)((_Gd - _Cd ) >> 0);
ip[1] = (ogg_int16_t)((_Add + _Hd ) >> 0);
ip[2] = (ogg_int16_t)((_Add - _Hd ) >> 0);
ip[3] = (ogg_int16_t)((_Ed + _Dd ) >> 0);
ip[4] = (ogg_int16_t)((_Ed - _Dd ) >> 0);
ip[5] = (ogg_int16_t)((_Fd + _Bdd ) >> 0);
ip[6] = (ogg_int16_t)((_Fd - _Bdd ) >> 0);
}
ip += 8; /* next row */
}
ip = IntermediateData;
for ( loop = 0; loop < 8; loop++) {
/* Check for non-zero values (bitwise or faster than ||) */
if ( ip[0 * 8] | ip[1 * 8] | ip[2 * 8] | ip[3 * 8] ) {
t1 = (xC1S7 * ip[1*8]);
t1 >>= 16;
_A = t1 ;
t1 = (xC7S1 * ip[1*8]);
t1 >>= 16;
_B = t1 ;
t1 = (xC3S5 * ip[3*8]);
t1 >>= 16;
_C = t1 ;
t2 = (xC5S3 * ip[3*8]);
t2 >>= 16;
_D = - t2;
t1 = (xC4S4 * (_A - _C));
t1 >>= 16;
_Ad = t1;
t1 = (xC4S4 * (_B - _D));
t1 >>= 16;
_Bd = t1;
_Cd = _A + _C;
_Dd = _B + _D;
t1 = (xC4S4 * ip[0*8]);
t1 >>= 16;
_E = t1;
_F = t1;
t1 = (xC2S6 * ip[2*8]);
t1 >>= 16;
_G = t1;
t1 = (xC6S2 * ip[2*8]);
t1 >>= 16;
_H = t1;
_Ed = _E - _G;
_Gd = _E + _G;
_Add = _F + _Ad;
_Bdd = _Bd - _H;
_Fd = _F - _Ad;
_Hd = _Bd + _H;
_Gd += IdctAdjustBeforeShift;
_Add += IdctAdjustBeforeShift;
_Ed += IdctAdjustBeforeShift;
_Fd += IdctAdjustBeforeShift;
/* Final sequence of operations over-write original inputs. */
op[0*8] = (ogg_int16_t)((_Gd + _Cd ) >> 4);
op[7*8] = (ogg_int16_t)((_Gd - _Cd ) >> 4);
op[1*8] = (ogg_int16_t)((_Add + _Hd ) >> 4);
op[2*8] = (ogg_int16_t)((_Add - _Hd ) >> 4);
op[3*8] = (ogg_int16_t)((_Ed + _Dd ) >> 4);
op[4*8] = (ogg_int16_t)((_Ed - _Dd ) >> 4);
op[5*8] = (ogg_int16_t)((_Fd + _Bdd ) >> 4);
op[6*8] = (ogg_int16_t)((_Fd - _Bdd ) >> 4);
}else{
op[0*8] = 0;
op[7*8] = 0;
op[1*8] = 0;
op[2*8] = 0;
op[3*8] = 0;
op[4*8] = 0;
op[5*8] = 0;
op[6*8] = 0;
}
ip++; /* next column */
op++;
}
}
/*//////////////////////////
// x 0 0 0 0 0 0 0
// 0 0 0 0 0 0 0 0
// 0 0 0 0 0 0 0 0
// 0 0 0 0 0 0 0 0
// 0 0 0 0 0 0 0 0
// 0 0 0 0 0 0 0 0
// 0 0 0 0 0 0 0 0
// 0 0 0 0 0 0 0 0
/////////////////////////*/
void IDct1( Q_LIST_ENTRY * InputData,
ogg_int16_t *QuantMatrix,
ogg_int16_t * OutputData ){
int loop;
ogg_int16_t OutD;
OutD=(ogg_int16_t) ((ogg_int32_t)(InputData[0]*QuantMatrix[0]+15)>>5);
for(loop=0;loop<64;loop++)
OutputData[loop]=OutD;
}
<p><p>1.1 theora/lib/pp.c
Index: pp.c
===================================================================
/********************************************************************
* *
* 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 OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function:
last mod: $Id: pp.c,v 1.1 2002/09/18 08:56:57 xiphmont Exp $
********************************************************************/
#include <stdlib.h>
#include <ogg/ogg.h>
#include "encoder_internal.h"
void PClearFrameInfo(PP_INSTANCE * ppi){
int i;
if(ppi->ScanPixelIndexTable) _ogg_free(ppi->ScanPixelIndexTable);
ppi->ScanPixelIndexTable=0;
if(ppi->ScanDisplayFragments) _ogg_free(ppi->ScanDisplayFragments);
ppi->ScanDisplayFragments=0;
for(i = 0 ; i < MAX_PREV_FRAMES ; i ++)
if(ppi->PrevFragments[i]){
_ogg_free(ppi->PrevFragments[i]);
ppi->PrevFragments[i]=0;
}
if(ppi->FragScores) _ogg_free(ppi->FragScores);
ppi->FragScores=0;
if(ppi->SameGreyDirPixels) _ogg_free(ppi->SameGreyDirPixels);
ppi->SameGreyDirPixels=0;
if(ppi->FragDiffPixels) _ogg_free(ppi->FragDiffPixels);
ppi->FragDiffPixels=0;
if(ppi->BarBlockMap) _ogg_free(ppi->BarBlockMap);
ppi->BarBlockMap=0;
if(ppi->TmpCodedMap) _ogg_free(ppi->TmpCodedMap);
ppi->TmpCodedMap=0;
if(ppi->RowChangedPixels) _ogg_free(ppi->RowChangedPixels);
ppi->RowChangedPixels=0;
if(ppi->PixelScores) _ogg_free(ppi->PixelScores);
ppi->PixelScores=0;
if(ppi->PixelChangedMap) _ogg_free(ppi->PixelChangedMap);
ppi->PixelChangedMap=0;
if(ppi->ChLocals) _ogg_free(ppi->ChLocals);
ppi->ChLocals=0;
if(ppi->yuv_differences) _ogg_free(ppi->yuv_differences);
ppi->yuv_differences=0;
}
void PAllocateFrameInfo(PP_INSTANCE * ppi){
int i;
PClearFrameInfo(ppi);
ppi->ScanPixelIndexTable =
_ogg_malloc(ppi->ScanFrameFragments*sizeof(*ppi->ScanPixelIndexTable));
ppi->ScanDisplayFragments =
_ogg_malloc(ppi->ScanFrameFragments*sizeof(*ppi->ScanDisplayFragments));
for(i = 0 ; i < MAX_PREV_FRAMES ; i ++)
ppi->PrevFragments[i] =
_ogg_malloc(ppi->ScanFrameFragments*sizeof(*ppi->PrevFragments));
ppi->FragScores =
_ogg_malloc(ppi->ScanFrameFragments*sizeof(*ppi->FragScores));
ppi->SameGreyDirPixels =
_ogg_malloc(ppi->ScanFrameFragments*sizeof(*ppi->SameGreyDirPixels));
ppi->FragDiffPixels =
_ogg_malloc(ppi->ScanFrameFragments*sizeof(*ppi->FragScores));
ppi->BarBlockMap=
_ogg_malloc(3 * ppi->ScanHFragments*sizeof(*ppi->BarBlockMap));
ppi->TmpCodedMap =
_ogg_malloc(ppi->ScanHFragments*sizeof(*ppi->TmpCodedMap));
ppi->RowChangedPixels =
_ogg_malloc(3 * ppi->ScanConfig.VideoFrameHeight*
sizeof(*ppi->RowChangedPixels));
ppi->PixelScores =
_ogg_malloc(ppi->ScanConfig.VideoFrameWidth*
sizeof(*ppi->PixelScores) * PSCORE_CB_ROWS);
ppi->PixelChangedMap =
_ogg_malloc(ppi->ScanConfig.VideoFrameWidth*
sizeof(*ppi->PixelChangedMap) * PMAP_CB_ROWS);
ppi->ChLocals =
_ogg_malloc(ppi->ScanConfig.VideoFrameWidth*
sizeof(*ppi->ChLocals) * CHLOCALS_CB_ROWS);
ppi->yuv_differences =
_ogg_malloc(ppi->ScanConfig.VideoFrameWidth*
sizeof(*ppi->yuv_differences) * YDIFF_CB_ROWS);
}
void ClearPPInstance(PP_INSTANCE *ppi){
PClearFrameInfo(ppi);
}
<p>void InitPPInstance(PP_INSTANCE *ppi){
memset(ppi,0,sizeof(*ppi));
/* Initializations */
ppi->PrevFrameLimit = 3; /* Must not exceed MAX_PREV_FRAMES (Note
that this number includes the current
frame so "1 = no effect") */
/* Scan control variables. */
ppi->HFragPixels = 8;
ppi->VFragPixels = 8;
ppi->SRFGreyThresh = 4;
ppi->SRFColThresh = 5;
ppi->NoiseSupLevel = 3;
ppi->SgcLevelThresh = 3;
ppi->SuvcLevelThresh = 4;
/* Variables controlling S.A.D. breakouts. */
ppi->GrpLowSadThresh = 10;
ppi->GrpHighSadThresh = 64;
ppi->PrimaryBlockThreshold = 5;
ppi->SgcThresh = 16; /* (Default values for 8x8 blocks). */
ppi->UVBlockThreshCorrection = 1.25;
ppi->UVSgcCorrection = 1.5;
ppi->MaxLineSearchLen = MAX_SEARCH_LINE_LEN;
}
<p><p>--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list