[xiph-cvs] cvs commit: theora/lib encode.c encoder_lookup.h
Mauricio Piacentini
mauricio at xiph.org
Tue Jun 10 06:50:53 PDT 2003
mauricio 03/06/10 09:50:52
Modified: lib encode.c encoder_lookup.h
Log:
Backed up derf's changes in encoder.c and encoder_lookup.h, to correct the breakage.
Revision Changes Path
1.11 +795 -804 theora/lib/encode.c
Index: encode.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/encode.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- encode.c 10 Jun 2003 01:31:33 -0000 1.10
+++ encode.c 10 Jun 2003 13:50:52 -0000 1.11
@@ -10,14 +10,12 @@
* *
********************************************************************
- function:
- last mod: $Id: encode.c,v 1.10 2003/06/10 01:31:33 tterribe Exp $
+ function:
+ last mod: $Id: encode.c,v 1.11 2003/06/10 13:50:52 mauricio Exp $
********************************************************************/
-#include <stdlib.h>
-#include <string.h>
-#include <ogg/ogg.h>
+#include "ogg/ogg.h"
#include "encoder_internal.h"
#include "encoder_lookup.h"
#include "block_inline.h"
@@ -28,19 +26,19 @@
#define PL 1
#define HIGHBITDUPPED(X) (((ogg_int16_t) X) >> 15)
-static ogg_uint32_t QuadCodeComponent ( CP_INSTANCE *cpi,
- ogg_uint32_t FirstSB,
- ogg_uint32_t SBRows,
- ogg_uint32_t SBCols,
- 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=FirstSB; /* Super-Block index, initialised to first
- of this component */
- ogg_uint32_t coded_pixels=0; /* Number of pixels coded */
+static ogg_uint32_t QuadCodeComponent ( CP_INSTANCE *cpi,
+ ogg_uint32_t FirstSB,
+ ogg_uint32_t SBRows,
+ ogg_uint32_t SBCols,
+ 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=FirstSB; /* Super-Block index, initialised to first
+ of this component */
+ ogg_uint32_t coded_pixels=0; /* Number of pixels coded */
int MBCodedFlag;
/* actually transform and quantize the image now that we've decided
@@ -51,52 +49,52 @@
for ( SBcol=0; SBcol<SBCols; SBcol++ ) {
/* Check its four Macro-Blocks */
for ( MB=0; MB<4; MB++ ) {
-
- if ( QuadMapToMBTopLeft(cpi->pb.BlockMap,SB,MB) >= 0 ) {
-
- MBCodedFlag = 0;
-
- /* Now actually code the blocks */
- for ( B=0; B<4; B++ ) {
- FragIndex = QuadMapToIndex1( cpi->pb.BlockMap, SB, MB, B );
-
- /* Does Block lie in frame: */
- if ( FragIndex >= 0 ) {
- /* In Frame: Is it coded: */
- if ( cpi->pb.display_fragments[FragIndex] ) {
+
+ if ( QuadMapToMBTopLeft(cpi->pb.BlockMap,SB,MB) >= 0 ) {
+
+ MBCodedFlag = 0;
+
+ /* Now actually code the blocks */
+ for ( B=0; B<4; B++ ) {
+ FragIndex = QuadMapToIndex1( cpi->pb.BlockMap, SB, MB, B );
+
+ /* Does Block lie in frame: */
+ if ( FragIndex >= 0 ) {
+ /* In Frame: Is it coded: */
+ if ( cpi->pb.display_fragments[FragIndex] ) {
/* transform and quantize block */
- TransformQuantizeBlock( cpi, FragIndex, PixelsPerLine );
-
+ TransformQuantizeBlock( cpi, FragIndex, PixelsPerLine );
+
/* Has the block got struck off (no MV and no data
- generated after DCT) If not then mark it and the
- assosciated MB as coded. */
- if ( cpi->pb.display_fragments[FragIndex] ) {
- /* Create linear list of coded block indices */
- cpi->pb.CodedBlockList[cpi->pb.CodedBlockIndex] = FragIndex;
- cpi->pb.CodedBlockIndex++;
-
- /* MB is still coded */
- MBCodedFlag = 1;
- cpi->MBCodingMode = cpi->pb.FragCodingMethod[FragIndex];
-
- }
- }
- }
- }
- /* If the MB is marked as coded and we are in the Y plane then */
+ generated after DCT) If not then mark it and the
+ assosciated MB as coded. */
+ if ( cpi->pb.display_fragments[FragIndex] ) {
+ /* Create linear list of coded block indices */
+ cpi->pb.CodedBlockList[cpi->pb.CodedBlockIndex] = FragIndex;
+ cpi->pb.CodedBlockIndex++;
+
+ /* MB is still coded */
+ MBCodedFlag = 1;
+ cpi->MBCodingMode = cpi->pb.FragCodingMethod[FragIndex];
+
+ }
+ }
+ }
+ }
+ /* If the MB is marked as coded and we are in the Y plane then */
/* the mode list needs to be updated. */
- if ( MBCodedFlag && (FirstSB == 0) ){
- /* Make a note of the selected mode in the mode list */
- cpi->ModeList[cpi->ModeListCount] = cpi->MBCodingMode;
- cpi->ModeListCount++;
- }
- }
+ if ( MBCodedFlag && (FirstSB == 0) ){
+ /* Make a note of the selected mode in the mode list */
+ cpi->ModeList[cpi->ModeListCount] = cpi->MBCodingMode;
+ cpi->ModeListCount++;
+ }
+ }
}
SB++;
- }
+ }
}
/* Return number of pixels coded */
@@ -108,11 +106,11 @@
ogg_uint32_t Token;
ogg_uint32_t ExtraBitsToken;
ogg_uint32_t HuffIndex;
-
+
ogg_uint32_t BestDcBits;
ogg_uint32_t DcHuffChoice[2];
ogg_uint32_t EntropyTableBits[2][DC_HUFF_CHOICES];
-
+
oggpack_buffer *opb=&cpi->oggbuffer;
/* Clear table data structure */
@@ -123,11 +121,11 @@
/* Count number of bits for each table option */
Token = (ogg_uint32_t)cpi->OptimisedTokenList[i];
for ( j = 0; j < DC_HUFF_CHOICES; j++ ){
- EntropyTableBits[cpi->OptimisedTokenListPl[i]][j] +=
- cpi->pb.HuffCodeLengthArray_VP3x[DC_HUFF_OFFSET + j][Token];
+ EntropyTableBits[cpi->OptimisedTokenListPl[i]][j] +=
+ cpi->pb.HuffCodeLengthArray_VP3x[DC_HUFF_OFFSET + j][Token];
}
}
-
+
/* Work out which table option is best for Y */
BestDcBits = EntropyTableBits[0][0];
DcHuffChoice[0] = 0;
@@ -140,7 +138,7 @@
/* Add the DC huffman table choice to the bitstream */
oggpackB_write( opb, DcHuffChoice[0], DC_HUFF_CHOICE_BITS );
-
+
/* Work out which table option is best for UV */
BestDcBits = EntropyTableBits[1][0];
DcHuffChoice[1] = 0;
@@ -150,7 +148,7 @@
DcHuffChoice[1] = j;
}
}
-
+
/* Add the DC huffman table choice to the bitstream */
oggpackB_write( opb, DcHuffChoice[1], DC_HUFF_CHOICE_BITS );
@@ -160,28 +158,28 @@
/* Get the token and extra bits */
Token = (ogg_uint32_t)cpi->OptimisedTokenList[i];
ExtraBitsToken = (ogg_uint32_t)cpi->OptimisedTokenListEb[i];
-
+
/* Select the huffman table */
if ( cpi->OptimisedTokenListPl[i] == 0)
HuffIndex = (ogg_uint32_t)DC_HUFF_OFFSET + (ogg_uint32_t)DcHuffChoice[0];
else
HuffIndex = (ogg_uint32_t)DC_HUFF_OFFSET + (ogg_uint32_t)DcHuffChoice[1];
-
+
/* Add the bits to the encode holding buffer. */
cpi->FrameBitCount += cpi->pb.HuffCodeLengthArray_VP3x[HuffIndex][Token];
- oggpackB_write( opb, cpi->pb.HuffCodeArray_VP3x[HuffIndex][Token],
- (ogg_uint32_t)cpi->
- pb.HuffCodeLengthArray_VP3x[HuffIndex][Token] );
+ oggpackB_write( opb, cpi->pb.HuffCodeArray_VP3x[HuffIndex][Token],
+ (ogg_uint32_t)cpi->
+ pb.HuffCodeLengthArray_VP3x[HuffIndex][Token] );
/* If the token is followed by an extra bits token then code it */
if ( cpi->pb.ExtraBitLengths_VP3x[Token] > 0 ) {
/* Add the bits to the encode holding buffer. */
cpi->FrameBitCount += cpi->pb.ExtraBitLengths_VP3x[Token];
- oggpackB_write( opb, ExtraBitsToken,
- (ogg_uint32_t)cpi->pb.ExtraBitLengths_VP3x[Token] );
+ oggpackB_write( opb, ExtraBitsToken,
+ (ogg_uint32_t)cpi->pb.ExtraBitLengths_VP3x[Token] );
}
}
-
+
/* Reset the count of second order optimised tokens */
cpi->OptimisedTokenCount = 0;
}
@@ -191,7 +189,7 @@
ogg_uint32_t Token;
ogg_uint32_t ExtraBitsToken;
ogg_uint32_t HuffIndex;
-
+
ogg_uint32_t BestAcBits;
ogg_uint32_t AcHuffChoice[2];
ogg_uint32_t EntropyTableBits[2][AC_HUFF_CHOICES];
@@ -199,15 +197,15 @@
oggpack_buffer *opb=&cpi->oggbuffer;
memset ( EntropyTableBits, 0, sizeof(ogg_uint32_t)*AC_HUFF_CHOICES*2 );
-
+
/* Analyse token list to see which is the best entropy table to use */
for ( i = 0; i < cpi->OptimisedTokenCount; i++ ) {
/* Count number of bits for each table option */
Token = (ogg_uint32_t)cpi->OptimisedTokenList[i];
HuffIndex = cpi->OptimisedTokenListHi[i];
for ( j = 0; j < AC_HUFF_CHOICES; j++ ) {
- EntropyTableBits[cpi->OptimisedTokenListPl[i]][j] +=
- cpi->pb.HuffCodeLengthArray_VP3x[HuffIndex + j][Token];
+ EntropyTableBits[cpi->OptimisedTokenListPl[i]][j] +=
+ cpi->pb.HuffCodeLengthArray_VP3x[HuffIndex + j][Token];
}
}
@@ -223,7 +221,7 @@
/* Add the AC-Y huffman table choice to the bitstream */
oggpackB_write( opb, AcHuffChoice[0], AC_HUFF_CHOICE_BITS );
-
+
/* Select the best set of AC tables for UV */
BestAcBits = EntropyTableBits[1][0];
AcHuffChoice[1] = 0;
@@ -233,49 +231,48 @@
AcHuffChoice[1] = j;
}
}
-
+
/* Add the AC-UV huffman table choice to the bitstream */
oggpackB_write( opb, AcHuffChoice[1], AC_HUFF_CHOICE_BITS );
-
+
/* Encode the token list */
for ( i = 0; i < cpi->OptimisedTokenCount; i++ ) {
/* Get the token and extra bits */
Token = (ogg_uint32_t)cpi->OptimisedTokenList[i];
ExtraBitsToken = (ogg_uint32_t)cpi->OptimisedTokenListEb[i];
-
+
/* Select the huffman table */
- HuffIndex = (ogg_uint32_t)cpi->OptimisedTokenListHi[i] +
+ HuffIndex = (ogg_uint32_t)cpi->OptimisedTokenListHi[i] +
AcHuffChoice[cpi->OptimisedTokenListPl[i]];
/* Add the bits to the encode holding buffer. */
cpi->FrameBitCount += cpi->pb.HuffCodeLengthArray_VP3x[HuffIndex][Token];
- oggpackB_write( opb, cpi->pb.HuffCodeArray_VP3x[HuffIndex][Token],
- (ogg_uint32_t)cpi->
- pb.HuffCodeLengthArray_VP3x[HuffIndex][Token] );
+ oggpackB_write( opb, cpi->pb.HuffCodeArray_VP3x[HuffIndex][Token],
+ (ogg_uint32_t)cpi->
+ pb.HuffCodeLengthArray_VP3x[HuffIndex][Token] );
/* If the token is followed by an extra bits token then code it */
if ( cpi->pb.ExtraBitLengths_VP3x[Token] > 0 ) {
/* Add the bits to the encode holding buffer. */
cpi->FrameBitCount += cpi->pb.ExtraBitLengths_VP3x[Token];
- oggpackB_write( opb, ExtraBitsToken,
- (ogg_uint32_t)cpi->pb.ExtraBitLengths_VP3x[Token] );
+ oggpackB_write( opb, ExtraBitsToken,
+ (ogg_uint32_t)cpi->pb.ExtraBitLengths_VP3x[Token] );
}
}
-
+
/* Reset the count of second order optimised tokens */
cpi->OptimisedTokenCount = 0;
}
static void PackModes (CP_INSTANCE *cpi) {
ogg_uint32_t i,j;
- unsigned char ModeIndex;
-
- unsigned char BestModeSchemes[MAX_MODES];
+ unsigned char ModeIndex;
+
ogg_int32_t ModeCount[MAX_MODES];
ogg_int32_t TmpFreq;
ogg_int32_t TmpIndex;
-
- ogg_uint32_t BestScheme;
+
+ unsigned char BestScheme;
ogg_uint32_t BestSchemeScore;
ogg_uint32_t SchemeScore;
@@ -283,7 +280,7 @@
/* Build a frequency map for the modes in this frame */
memset( ModeCount, 0, MAX_MODES*sizeof(ogg_int32_t) );
- for ( i = 0; i < cpi->ModeListCount; i++ )
+ for ( i = 0; i < cpi->ModeListCount; i++ )
ModeCount[cpi->ModeList[i]] ++;
/* Order the modes from most to least frequent. Store result as
@@ -294,12 +291,12 @@
for ( i = 0; i < MAX_MODES; i++ ) {
/* Is this the best scheme so far ??? */
if ( ModeCount[i] > TmpFreq ) {
- TmpFreq = ModeCount[i];
- TmpIndex = i;
+ TmpFreq = ModeCount[i];
+ TmpIndex = i;
}
}
ModeCount[TmpIndex] = -1;
- BestModeSchemes[TmpIndex] = (unsigned char)j;
+ ModeSchemes[0][TmpIndex] = j;
}
/* Default/ fallback scheme uses MODE_BITS bits per mode entry */
@@ -307,21 +304,16 @@
BestSchemeScore = cpi->ModeListCount * 3;
/* Get a bit score for the available schemes. */
for ( j = 0; j < (MODE_METHODS - 1); j++ ) {
- unsigned char *SchemeList;
-
/* Reset the scheme score */
- if ( j == 0 ){
- /* Scheme 0 additional cost of sending frequency order */
- SchemeScore = 24;
- SchemeList = BestModeSchemes;
- } else {
+ if ( j == 0 )
+ SchemeScore = 24; /* Scheme 0 additional cost of sending
+ frequency order */
+ else
SchemeScore = 0;
- SchemeList = ModeSchemes[j-1];
- }
-
+
/* Find the total bits to code using each avaialable scheme */
- for ( i = 0; i < cpi->ModeListCount; i++ )
- SchemeScore += ModeBitLengths[SchemeList[cpi->ModeList[i]]];
+ for ( i = 0; i < cpi->ModeListCount; i++ )
+ SchemeScore += ModeBitLengths[ModeSchemes[j][cpi->ModeList[i]]];
/* Is this the best scheme so far ??? */
if ( SchemeScore < BestSchemeScore ) {
@@ -338,7 +330,7 @@
if ( BestScheme == 0 ) {
for ( j = 0; j < MAX_MODES; j++ )
/* Note that the last two entries are implicit */
- oggpackB_write( opb, BestModeSchemes[j], (ogg_uint32_t)MODE_BITS );
+ oggpackB_write( opb, ModeSchemes[0][j], (ogg_uint32_t)MODE_BITS );
}
/* Are we using one of the alphabet based schemes or the fallback scheme */
@@ -346,9 +338,9 @@
/* Pack and encode the Mode list */
for ( i = 0; i < cpi->ModeListCount; i++ ) {
/* Add the appropriate mode entropy token. */
- ModeIndex = ModeSchemes[BestScheme-1][cpi->ModeList[i]];
- oggpackB_write( opb, ModeBitPatterns[ModeIndex],
- (ogg_uint32_t)ModeBitLengths[ModeIndex] );
+ ModeIndex = ModeSchemes[BestScheme][cpi->ModeList[i]];
+ oggpackB_write( opb, ModeBitPatterns[ModeIndex],
+ (ogg_uint32_t)ModeBitLengths[ModeIndex] );
}
}else{
/* Fall back to MODE_BITS per entry */
@@ -361,16 +353,16 @@
static void PackMotionVectors (CP_INSTANCE *cpi) {
ogg_int32_t i;
- ogg_uint32_t MethodBits[2] = {0,0};
+ ogg_uint32_t MethodBits[2] = {0,0};
ogg_uint32_t * MvBitsPtr;
- ogg_uint32_t * MvPatternPtr;
+ ogg_uint32_t * MvPatternPtr;
oggpack_buffer *opb=&cpi->oggbuffer;
/* Choose the coding method */
MvBitsPtr = &MvBits[MAX_MV_EXTENT];
for ( i = 0; i < (ogg_int32_t)cpi->MvListCount; i++ ) {
- MethodBits[0] += MvBitsPtr[cpi->MVList[i].x];
+ MethodBits[0] += MvBitsPtr[cpi->MVList[i].x];
MethodBits[0] += MvBitsPtr[cpi->MVList[i].y];
MethodBits[1] += 12; /* Simple six bits per mv component fallback
mechanism */
@@ -389,10 +381,10 @@
/* Pack and encode the motion vectors */
for ( i = 0; i < (ogg_int32_t)cpi->MvListCount; i++ ) {
- oggpackB_write( opb, MvPatternPtr[cpi->MVList[i].x],
- (ogg_uint32_t)MvBitsPtr[cpi->MVList[i].x] );
- oggpackB_write( opb, MvPatternPtr[cpi->MVList[i].y],
- (ogg_uint32_t)MvBitsPtr[cpi->MVList[i].y] );
+ oggpackB_write( opb, MvPatternPtr[cpi->MVList[i].x],
+ (ogg_uint32_t)MvBitsPtr[cpi->MVList[i].x] );
+ oggpackB_write( opb, MvPatternPtr[cpi->MVList[i].y],
+ (ogg_uint32_t)MvBitsPtr[cpi->MVList[i].y] );
}
}
@@ -405,13 +397,13 @@
the first token in the run */
/* Mark out which plane the block belonged to */
- cpi->OptimisedTokenListPl[cpi->OptimisedTokenCount] =
- (unsigned char)cpi->RunPlaneIndex;
-
+ cpi->OptimisedTokenListPl[cpi->OptimisedTokenCount] =
+ cpi->RunPlaneIndex;
+
/* Note the huffman index to be used */
- cpi->OptimisedTokenListHi[cpi->OptimisedTokenCount] =
- (unsigned char)cpi->RunHuffIndex;
-
+ cpi->OptimisedTokenListHi[cpi->OptimisedTokenCount] =
+ cpi->RunHuffIndex;
+
if ( cpi->RunLength <= 3 ) {
if ( cpi->RunLength == 1 ) {
cpi->OptimisedTokenList[cpi->OptimisedTokenCount] = DCT_EOB_TOKEN;
@@ -420,50 +412,50 @@
} else {
cpi->OptimisedTokenList[cpi->OptimisedTokenCount] = DCT_EOB_TRIPLE_TOKEN;
}
-
+
cpi->RunLength = 0;
} else {
/* Choose a token appropriate to the run length. */
if ( cpi->RunLength < 8 ) {
- cpi->OptimisedTokenList[cpi->OptimisedTokenCount] =
- DCT_REPEAT_RUN_TOKEN;
- cpi->OptimisedTokenListEb[cpi->OptimisedTokenCount] =
- cpi->RunLength - 4;
+ cpi->OptimisedTokenList[cpi->OptimisedTokenCount] =
+ DCT_REPEAT_RUN_TOKEN;
+ cpi->OptimisedTokenListEb[cpi->OptimisedTokenCount] =
+ cpi->RunLength - 4;
cpi->RunLength = 0;
} else if ( cpi->RunLength < 16 ) {
- cpi->OptimisedTokenList[cpi->OptimisedTokenCount] =
- DCT_REPEAT_RUN2_TOKEN;
- cpi->OptimisedTokenListEb[cpi->OptimisedTokenCount] =
- cpi->RunLength - 8;
+ cpi->OptimisedTokenList[cpi->OptimisedTokenCount] =
+ DCT_REPEAT_RUN2_TOKEN;
+ cpi->OptimisedTokenListEb[cpi->OptimisedTokenCount] =
+ cpi->RunLength - 8;
cpi->RunLength = 0;
} else if ( cpi->RunLength < 32 ) {
- cpi->OptimisedTokenList[cpi->OptimisedTokenCount] =
- DCT_REPEAT_RUN3_TOKEN;
- cpi->OptimisedTokenListEb[cpi->OptimisedTokenCount] =
- cpi->RunLength - 16;
+ cpi->OptimisedTokenList[cpi->OptimisedTokenCount] =
+ DCT_REPEAT_RUN3_TOKEN;
+ cpi->OptimisedTokenListEb[cpi->OptimisedTokenCount] =
+ cpi->RunLength - 16;
cpi->RunLength = 0;
} else if ( cpi->RunLength < 4096) {
- cpi->OptimisedTokenList[cpi->OptimisedTokenCount] =
- DCT_REPEAT_RUN4_TOKEN;
- cpi->OptimisedTokenListEb[cpi->OptimisedTokenCount] =
- cpi->RunLength;
+ cpi->OptimisedTokenList[cpi->OptimisedTokenCount] =
+ DCT_REPEAT_RUN4_TOKEN;
+ cpi->OptimisedTokenListEb[cpi->OptimisedTokenCount] =
+ cpi->RunLength;
cpi->RunLength = 0;
- }
-
+ }
+
}
-
+
cpi->OptimisedTokenCount++;
/* Reset run EOB length */
cpi->RunLength = 0;
}
-static void PackToken ( CP_INSTANCE *cpi, ogg_int32_t FragmentNumber,
- ogg_uint32_t HuffIndex ) {
- ogg_uint32_t Token =
+static void PackToken ( CP_INSTANCE *cpi, ogg_int32_t FragmentNumber,
+ ogg_uint32_t HuffIndex ) {
+ ogg_uint32_t Token =
cpi->pb.TokenList[FragmentNumber][cpi->FragTokens[FragmentNumber]];
- ogg_uint32_t ExtraBitsToken =
+ ogg_uint32_t ExtraBitsToken =
cpi->pb.TokenList[FragmentNumber][cpi->FragTokens[FragmentNumber] + 1];
ogg_uint32_t OneOrTwo;
ogg_uint32_t OneOrZero;
@@ -474,66 +466,65 @@
if ( Token == DCT_EOB_TOKEN )
cpi->pb.FragCoeffs[FragmentNumber] = BLOCK_SIZE;
else
- ExpandToken( cpi->pb.QFragData[FragmentNumber],
- &cpi->pb.FragCoeffs[FragmentNumber],
- Token, ExtraBitsToken );
-
+ ExpandToken( cpi->pb.QFragData[FragmentNumber],
+ &cpi->pb.FragCoeffs[FragmentNumber],
+ Token, ExtraBitsToken );
+
/* Update record of tokens coded and where we are in this fragment. */
/* Is there an extra bits token */
- OneOrTwo= 1 + ( cpi->pb.ExtraBitLengths_VP3x[Token] > 0 );
+ OneOrTwo= 1 + ( cpi->pb.ExtraBitLengths_VP3x[Token] > 0 );
/* Advance to the next real token. */
- cpi->FragTokens[FragmentNumber] += (unsigned char)OneOrTwo;
-
+ cpi->FragTokens[FragmentNumber] += OneOrTwo;
+
/* Update the counts of tokens coded */
cpi->TokensCoded += OneOrTwo;
cpi->TokensToBeCoded -= OneOrTwo;
-
+
OneOrZero = ( FragmentNumber < (ogg_int32_t)cpi->pb.YPlaneFragments );
-
+
if ( Token == DCT_EOB_TOKEN ) {
if ( cpi->RunLength == 0 ) {
cpi->RunHuffIndex = HuffIndex;
cpi->RunPlaneIndex = 1 - OneOrZero;
}
cpi->RunLength++;
-
+
/* we have exceeded our longest run length xmit an eob run token; */
if ( cpi->RunLength == 4095 ) PackEOBRun(cpi);
-
+
}else{
/* If we have an EOB run then code it up first */
if ( cpi->RunLength > 0 ) PackEOBRun( cpi);
/* Mark out which plane the block belonged to */
- cpi->OptimisedTokenListPl[cpi->OptimisedTokenCount] =
- (unsigned char)(1 - OneOrZero);
-
+ cpi->OptimisedTokenListPl[cpi->OptimisedTokenCount] = 1 - OneOrZero;
+
/* Note the token, extra bits and hufman table in the optimised
token list */
- cpi->OptimisedTokenList[cpi->OptimisedTokenCount] =
- (unsigned char)Token;
- cpi->OptimisedTokenListEb[cpi->OptimisedTokenCount] =
+ cpi->OptimisedTokenList[cpi->OptimisedTokenCount] =
+ Token;
+ cpi->OptimisedTokenListEb[cpi->OptimisedTokenCount] =
ExtraBitsToken;
- cpi->OptimisedTokenListHi[cpi->OptimisedTokenCount] =
- (unsigned char)HuffIndex;
-
+ cpi->OptimisedTokenListHi[cpi->OptimisedTokenCount] =
+ HuffIndex;
+
cpi->OptimisedTokenCount++;
}
}
-static ogg_uint32_t GetBlockReconErrorSlow( CP_INSTANCE *cpi,
- ogg_int32_t BlockIndex ) {
- ogg_uint32_t i;
- ogg_uint32_t ErrorVal = 0;
-
- unsigned char * SrcDataPtr =
+static 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[cpi->pb.pixel_index_table[BlockIndex]];
- unsigned char * RecDataPtr =
+ unsigned char * RecDataPtr =
&cpi->pb.LastFrameRecon[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.info.width;
@@ -542,8 +533,8 @@
SrcStride = cpi->pb.info.width >> 1;
RecStride = cpi->pb.UVStride;
}
-
-
+
+
/* Decide on standard or MMX implementation */
for ( i=0; i < BLOCK_HEIGHT_WIDTH; i++ ) {
ErrorVal += abs( ((int)SrcDataPtr[0]) - ((int)RecDataPtr[0]) );
@@ -569,27 +560,27 @@
/* 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);
-
+ 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. */
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 );
}
-
+
/* Note the number of bits used to code the tree itself. */
cpi->FrameBitCount = oggpackB_bytes(&cpi->oggbuffer) << 3;
@@ -600,28 +591,28 @@
/* Pack the motion vectors */
PackMotionVectors (cpi);
}
-
+
cpi->FrameBitCount = oggpackB_bytes(&cpi->oggbuffer) << 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]=(unsigned char)EncodedCoeffs;
+
+ 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. */
@@ -633,57 +624,57 @@
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]=(unsigned char)EncodedCoeffs;
- PackToken( cpi, FragIndex, HuffIndex );
+ && 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);
-
+
}
static ogg_uint32_t QuadCodeDisplayFragments (CP_INSTANCE *cpi) {
ogg_int32_t i,j;
- ogg_uint32_t coded_pixels=0;
+ ogg_uint32_t coded_pixels=0;
int QIndex;
int k,m,n;
/* 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 */
+ {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 */
+ {3,10,3,0,4,15}, /* PUL|PU|PUR */
+ {-26,29,0,29,5,31} /* PUL|PU|PUR|PL */
};
struct SearchPoints {
@@ -696,38 +687,38 @@
};
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 */
-
- int FragsAcross=cpi->pb.HFragments;
+ ogg_int16_t Last[3]; /* last value used for given frame */
+
+ int FragsAcross=cpi->pb.HFragments;
int FragsDown = cpi->pb.VFragments;
int FromFragment,ToFragment;
- ogg_int32_t FragIndex;
+ 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 */
+ 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 */
};
ogg_int16_t PredictedDC;
@@ -736,29 +727,29 @@
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) )
+ if ( (QIndex == 0) ||
+ ( cpi->pb.QThreshTable[QIndex] >= cpi->pb.ThisFrameQualityValue) )
break;
QIndex --;
}
-
+
/* Encode and tokenise the Y, U and V components */
- coded_pixels = QuadCodeComponent(cpi, 0, cpi->pb.YSBRows, cpi->pb.YSBCols,
- cpi->pb.info.width );
- coded_pixels += QuadCodeComponent(cpi, cpi->pb.YSuperBlocks,
- cpi->pb.UVSBRows,
- cpi->pb.UVSBCols,
- cpi->pb.info.width>>1 );
- coded_pixels += QuadCodeComponent(cpi,
- cpi->pb.YSuperBlocks+cpi->pb.UVSuperBlocks,
- cpi->pb.UVSBRows, cpi->pb.UVSBCols,
- cpi->pb.info.width>>1 );
-
+ coded_pixels = QuadCodeComponent(cpi, 0, cpi->pb.YSBRows, cpi->pb.YSBCols,
+ cpi->pb.info.width );
+ coded_pixels += QuadCodeComponent(cpi, cpi->pb.YSuperBlocks,
+ cpi->pb.UVSBRows,
+ cpi->pb.UVSBCols,
+ cpi->pb.info.width>>1 );
+ coded_pixels += QuadCodeComponent(cpi,
+ cpi->pb.YSuperBlocks+cpi->pb.UVSuperBlocks,
+ cpi->pb.UVSBRows, cpi->pb.UVSBCols,
+ cpi->pb.info.width>>1 );
+
/* for y,u,v */
for ( j = 0; j < 3 ; j++) {
/* pick which fragments based on Y, U, V */
@@ -790,184 +781,184 @@
/* 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];
+ cpi->OriginalDC[i] = cpi->pb.QFragData[i][0];
- /* only do 2 prediction if fragment coded and on non intra or
+ /* 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);
-
- 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;
-
- /* 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
+ 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);
+
+ 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;
+
+ /* 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
+ 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
+ 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
+ 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;
-
- }
-
- 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 ) {
-
- /* If negative add in the negative correction factor */
- PredictedDC += (HIGHBITDUPPED(PredictedDC) & pc[wpc][5]);
- /* Shift in lieu of a divide */
- PredictedDC >>= pc[wpc][4];
-
- }
-
- /* 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;
- }
-
- /* Save the last fragment coded for whatever frame we are
+ 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;
+
+ }
+
+ 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 ) {
+
+ /* If negative add in the negative correction factor */
+ PredictedDC += (HIGHBITDUPPED(PredictedDC) & pc[wpc][5]);
+ /* Shift in lieu of a divide */
+ PredictedDC >>= pc[wpc][4];
+
+ }
+
+ /* 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;
+ }
+
+ /* Save the last fragment coded for whatever frame we are
predicting from */
-
- Last[WhichFrame] = cpi->OriginalDC[i];
-
- }
- }
- }
+
+ Last[WhichFrame] = cpi->OriginalDC[i];
+
+ }
+ }
+ }
}
/* Pack DC tokens and adjust the ones we couldn't predict 2d */
@@ -975,7 +966,7 @@
/* Get the linear index for the current coded fragment. */
FragIndex = cpi->pb.CodedBlockList[i];
coded_pixels += DPCMTokenizeBlock ( cpi, FragIndex);
-
+
}
@@ -989,16 +980,16 @@
ReconRefFrames(&cpi->pb);
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->LastCodedErrorScore[ cpi->pb.CodedBlockList[i] ] =
GetBlockReconErrorSlow( cpi, cpi->pb.CodedBlockList[i] );
-
+
}
-
+
/* Return total number of coded pixels */
return coded_pixels;
}
@@ -1016,22 +1007,22 @@
cpi->pb.EOB_Run = 0;
/* Encode any fragments coded using DCT. */
- coded_pixels += QuadCodeDisplayFragments (cpi);
+ coded_pixels += QuadCodeDisplayFragments (cpi);
return coded_pixels;
}
-ogg_uint32_t PickIntra( CP_INSTANCE *cpi,
- ogg_uint32_t SBRows,
- ogg_uint32_t SBCols){
-
- 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 PickIntra( CP_INSTANCE *cpi,
+ ogg_uint32_t SBRows,
+ ogg_uint32_t SBCols){
+
+ 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;
@@ -1042,33 +1033,33 @@
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;
-
- }
+ /* 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++;
}
@@ -1076,48 +1067,48 @@
return 0;
}
-static void AddMotionVector(CP_INSTANCE *cpi,
- MOTION_VECTOR *ThisMotionVector) {
+static void AddMotionVector(CP_INSTANCE *cpi,
+ MOTION_VECTOR *ThisMotionVector) {
cpi->MVList[cpi->MvListCount].x = ThisMotionVector->x;
cpi->MVList[cpi->MvListCount].y = ThisMotionVector->y;
cpi->MvListCount++;
}
-static void SetFragMotionVectorAndMode(CP_INSTANCE *cpi,
- ogg_int32_t FragIndex,
- MOTION_VECTOR *ThisMotionVector){
+static 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;
+ cpi->pb.FragCodingMethod[FragIndex] = cpi->MBCodingMode;
}
-static void SetMBMotionVectorsAndMode(CP_INSTANCE *cpi,
- ogg_int32_t YFragIndex,
- ogg_int32_t UFragIndex,
- ogg_int32_t VFragIndex,
- MOTION_VECTOR *ThisMotionVector){
+static 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);
+ 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 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
+ogg_uint32_t PickModes(CP_INSTANCE *cpi,
+ ogg_uint32_t SBRows, ogg_uint32_t SBCols,
+ 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 */
@@ -1136,9 +1127,9 @@
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) */
+ 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
@@ -1151,18 +1142,18 @@
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;
@@ -1187,20 +1178,20 @@
InterMVect.y = 0;
GFMVect.x = 0;
GFMVect.y = 0;
-
+
ZeroVect.x = 0;
ZeroVect.y = 0;
-
- QIndex = (unsigned char)cpi->pb.FrameQIndex;
+
+ QIndex = cpi->pb.FrameQIndex;
/* change the quatization matrix to the one at best Q to compute the
new error score */
- cpi->MinImprovementForNewMV = (MvThreshTable[QIndex] << 12);
+ cpi->MinImprovementForNewMV = (MvThreshTable[QIndex] << 12);
cpi->InterTripOutThresh = (5000<<12);
cpi->MVChangeFactor = MVChangeFactorTable[QIndex]; /* 0.9 */
-
+
if ( cpi->pb.info.quick_p ) {
cpi->ExhaustiveSearchThresh = (1000<<12);
cpi->FourMVThreshold = (2500<<12);
@@ -1208,329 +1199,329 @@
cpi->ExhaustiveSearchThresh = (250<<12);
cpi->FourMVThreshold = (500<<12);
}
- cpi->MinImprovementForFourMV = cpi->MinImprovementForNewMV * 4;
-
+ 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;
-
- /* 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
-
- 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. */
-
- BestError = HUGE_ERROR;
-
-
- /* 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;
-
- /* 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
+ /* 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
+
+ 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. */
+
+ BestError = HUGE_ERROR;
+
+
+ /* 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;
+
+ /* 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
+ if ( BestError > cpi->MinImprovementForNewMV ) {
+ /* Use a mix of heirachical and exhaustive searches for
quick mode. */
- if ( cpi->pb.info.quick_p ) {
- MBInterMVError = GetMBMVInterError( cpi, cpi->pb.LastFrameRecon,
- YFragIndex, PixelsPerLine,
- cpi->MVPixelOffsetY,
- &InterMVect );
-
- /* If we still do not have a good match try an exhaustive
+ if ( cpi->pb.info.quick_p ) {
+ 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 );
+ if ( (MBInterMVError > cpi->ExhaustiveSearchThresh) &&
+ (BestError > cpi->ExhaustiveSearchThresh) ) {
- /* Is the Variance measure for the EX search
+ 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
+ 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
+ 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;
- }
- }
+ 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;
+ }
+ }
- /* Finally... If the best error is still to high then consider
+ /* 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;
- }
- }
-
+ 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
- *******************************************************
-
+ 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 ) {
+
+ 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);
+
+ } else if ( BestError == MBGF_MVError ) {
+
+ 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 {
+
+ cpi->MBCodingMode = CODE_INTRA;
+ SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
+ VFragIndex,&ZeroVect);
+ }
+
- 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 ) {
-
- 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);
-
- } else if ( BestError == MBGF_MVError ) {
-
- 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 {
-
- cpi->MBCodingMode = CODE_INTRA;
- SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
- VFragIndex,&ZeroVect);
- }
-
-
- /* setting up mode specific block types
+ /* setting up mode specific block types
*******************************************************/
-
- *InterError += (BestError>>8);
- *IntraError += (MBIntraError>>8);
-
-
+
+ *InterError += (BestError>>8);
+ *IntraError += (MBIntraError>>8);
+
+
}
SB++;
-
+
}
}
@@ -1544,7 +1535,7 @@
/* Output the frame type (base/key frame or inter frame) */
oggpackB_write( opb, cpi->pb.FrameType, 1 );
-
+
/* Write out details of the current value of Q... variable resolution. */
for ( i = 0; i < Q_TABLE_SIZE; i++ ) {
if ( cpi->pb.ThisFrameQualityValue == cpi->pb.QThreshTable[i] ) {
@@ -1552,20 +1543,20 @@
break;
}
}
-
+
if ( i == Q_TABLE_SIZE ) {
/* An invalid DCT value was specified. */
/*IssueWarning( "Invalid Q Multiplier" );*/
oggpackB_write( opb, 31, 6 );
}
-
+
/* If the frame was a base frame then write out the frame dimensions. */
if ( cpi->pb.FrameType == BASE_FRAME ) {
/* Key frame type / method */
oggpackB_write( opb, cpi->pb.KeyFrameType, 1 );
-
+
/* Spare configuration bits */
- oggpackB_write( opb, 0, 2 );
+ oggpackB_write( opb, 0, 2 );
}
}
<p><p>1.6 +4 -1 theora/lib/encoder_lookup.h
Index: encoder_lookup.h
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/encoder_lookup.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- encoder_lookup.h 10 Jun 2003 01:31:33 -0000 1.5
+++ encoder_lookup.h 10 Jun 2003 13:50:52 -0000 1.6
@@ -11,7 +11,7 @@
********************************************************************
function: simple static lookups for VP3 frame encoder
- last mod: $Id: encoder_lookup.h,v 1.5 2003/06/10 01:31:33 tterribe Exp $
+ last mod: $Id: encoder_lookup.h,v 1.6 2003/06/10 13:50:52 mauricio Exp $
********************************************************************/
@@ -82,6 +82,9 @@
1, 2, 3, 4, 5, 6, 7, 7 };
unsigned char ModeSchemes[MODE_METHODS-1][MAX_MODES] = {
+ /* Reserved for optimal */
+ { 0, 0, 0, 0, 0, 0, 0, 0 },
+
/* Last Mv dominates */
{ 3, 4, 2, 0, 1, 5, 6, 7 }, /* L P M N I G GM 4 */
{ 2, 4, 3, 0, 1, 5, 6, 7 }, /* L P N M I G GM 4 */
<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