[xiph-cvs] cvs commit: theora/lib encode.c encoder_lookup.h
Timothy Terriberry
tterribe at xiph.org
Tue Jun 10 19:24:30 PDT 2003
tterribe 03/06/10 22:24:29
Modified: examples splayer.c
lib encode.c encoder_lookup.h
Log:
More cleanups. These should actually not generate broken bitstreams.
Revision Changes Path
1.3 +107 -110 theora/examples/splayer.c
Index: splayer.c
===================================================================
RCS file: /usr/local/cvsroot/theora/examples/splayer.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- splayer.c 10 Jun 2003 11:42:46 -0000 1.2
+++ splayer.c 11 Jun 2003 02:24:29 -0000 1.3
@@ -290,7 +290,7 @@
PASTREAMIO_Stream *data = (PASTREAMIO_Stream*)userData;
long numBytes = data->bytesPerFrame * framesPerBuffer;
(void) outTime;
- (void) inputBuffer;
+ (void) inputBuffer;
if( outputBuffer != NULL )
{
@@ -563,22 +563,22 @@
static void usage(void){
printf("Usage: splayer ogg_file\n\n"
- "or drag and drop an ogg file over the .exe\n\n");
+ "or drag and drop an ogg file over the .exe\n\n");
exit(1);
}
static int open_audio(){
- /* this will open one circular audio stream*/
- /*build on top of portaudio routines*/
- /*implementation on fille pastreamio.c*/
+ /* this will open one circular audio stream*/
+ /*build on top of portaudio routines*/
+ /*implementation on fille pastreamio.c*/
- int numSamples;
+ int numSamples;
int numBytes;
- int minNumBuffers;
- int numFrames;
+ int minNumBuffers;
+ int numFrames;
- minNumBuffers = 2 * Pa_GetMinNumBuffers( FRAMES_PER_BUFFER, vi.rate );
+ minNumBuffers = 2 * Pa_GetMinNumBuffers( FRAMES_PER_BUFFER, vi.rate );
numFrames = minNumBuffers * FRAMES_PER_BUFFER;
numFrames = RoundUpToNextPowerOf2( numFrames );
@@ -587,30 +587,30 @@
samples = (SAMPLE *) malloc( numBytes );
- /*store our latency calculation here*/
- latency_sec = (double) numFrames / vi.rate / vi.channels;
- printf( "Latency: %.04f\n", latency_sec );
+ /*store our latency calculation here*/
+ latency_sec = (double) numFrames / vi.rate / vi.channels;
+ printf( "Latency: %.04f\n", latency_sec );
- err = OpenAudioStream( &aOutStream, vi.rate, PA_SAMPLE_TYPE,
+ err = OpenAudioStream( &aOutStream, vi.rate, PA_SAMPLE_TYPE,
(PASTREAMIO_WRITE | PASTREAMIO_STEREO) );
if( err != paNoError ) goto error;
return err;
error:
- CloseAudioStream( aOutStream );
+ CloseAudioStream( aOutStream );
printf( "An error occured while opening the portaudio stream\n" );
printf( "Error number: %d\n", err );
printf( "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
-
+
}
static int start_audio(){
- err = StartAudioStream(aOutStream);
+ err = StartAudioStream(aOutStream);
if( err != paNoError ) goto error;
-
+
return err;
error:
- CloseAudioStream( aOutStream );
+ CloseAudioStream( aOutStream );
printf( "An error occured while opening the portaudio stream\n" );
printf( "Error number: %d\n", err );
printf( "Error message: %s\n", Pa_GetErrorText( err ) );
@@ -618,10 +618,10 @@
}
static int audio_close(void){
- err = CloseAudioStream( aOutStream );
- if( err != paNoError ) goto error;
-
- free(samples);
+ err = CloseAudioStream( aOutStream );
+ if( err != paNoError ) goto error;
+
+ free(samples);
return err;
error:
@@ -644,7 +644,7 @@
static void open_video(void){
- /*taken from player_sample.c test file for theora alpha*/
+ /*taken from player_sample.c test file for theora alpha*/
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
printf("Unable to init SDL: %s\n", SDL_GetError());
@@ -654,7 +654,7 @@
screen = SDL_SetVideoMode(ti.frame_width, ti.frame_height, 0, SDL_SWSURFACE);
if ( screen == NULL ) {
printf("Unable to set %dx%d video: %s\n",
- ti.frame_width,ti.frame_height,SDL_GetError());
+ ti.frame_width,ti.frame_height,SDL_GetError());
exit(1);
}
@@ -663,7 +663,7 @@
screen);
if ( yuv_overlay == NULL ) {
printf("SDL: Couldn't create SDL_yuv_overlay: %s\n",
- SDL_GetError());
+ SDL_GetError());
exit(1);
}
rect.x = 0;
@@ -675,7 +675,7 @@
}
static void video_write(void){
- /*taken from player_sample.c test file for theora alpha*/
+ /*taken from player_sample.c test file for theora alpha*/
int i;
yuv_buffer yuv;
int crop_offset;
@@ -774,8 +774,8 @@
void parseHeaders(){
- /*extracted from player_sample.c test file for theora alpha*/
- ogg_packet op;
+ /*extracted from player_sample.c test file for theora alpha*/
+ ogg_packet op;
/* Parse the headers */
/* Only interested in Vorbis/Theora streams */
while(!stateflag){
@@ -812,11 +812,11 @@
}
}
}
-
+
/* we're expecting more header packets. */
while((theora_p && theora_p<3) || (vorbis_p && vorbis_p<3)){
int ret;
-
+
/* look for further theora headers */
while(theora_p && (theora_p<3) && (ret=ogg_stream_packetout(&to,&op))){
if(ret<0){
@@ -844,7 +844,7 @@
vorbis_p++;
if(vorbis_p==3)break;
}
-
+
/* The header pages/packets will arrive before anything else we
care about, or the stream is not obeying spec */
@@ -862,7 +862,7 @@
}
int main( int argc, char* argv[] ){
-
+
int i,j;
ogg_packet op;
SDL_Event event;
@@ -877,8 +877,8 @@
if( argc != 2 )
{
- usage();
- exit(0);
+ usage();
+ exit(0);
}
infile = fopen( argv[1], "rb" );
@@ -901,8 +901,8 @@
theora_decode_init(&td,&ti);
printf("Ogg logical stream %x is Theora %dx%d %.02f fps video\n"
" Frame content is %dx%d with offset (%d,%d).\n",
- to.serialno,ti.width,ti.height, (double)ti.fps_numerator/ti.fps_denominator,
- ti.frame_width, ti.frame_height, ti.offset_x, ti.offset_y);
+ to.serialno,ti.width,ti.height, (double)ti.fps_numerator/ti.fps_denominator,
+ ti.frame_width, ti.frame_height, ti.offset_x, ti.offset_y);
report_colorspace(&ti);
dump_comments(&tc);
}else{
@@ -914,7 +914,7 @@
vorbis_synthesis_init(&vd,&vi);
vorbis_block_init(&vd,&vb);
printf("Ogg logical stream %x is Vorbis %d channel %d Hz audio.\n",
- vo.serialno,vi.channels,vi.rate);
+ vo.serialno,vi.channels,vi.rate);
}else{
/* tear down the partial vorbis setup */
vorbis_info_clear(&vi);
@@ -929,64 +929,64 @@
/*our main loop*/
while(1){
- SDL_Delay(5);
+ SDL_Delay(5);
- if (playbackdone == 1 ) break;
+ if (playbackdone == 1 ) break;
- /*break out on SDL quit event*/
+ /*break out on SDL quit event*/
if ( SDL_PollEvent ( &event ) )
{
if ( event.type == SDL_QUIT ) break ;
-
+
}
- /*get some audio data*/
+ /*get some audio data*/
while(vorbis_p){
int ret;
float **pcm;
- int count = 0;
- int maxBytesToWrite;
+ int count = 0;
+ int maxBytesToWrite;
- /* is there pending audio? does it fit our circular buffer without blocking?*/
- ret=vorbis_synthesis_pcmout(&vd,&pcm);
- maxBytesToWrite = GetAudioStreamWriteable(aOutStream);
-
- if (maxBytesToWrite<=FRAMES_PER_BUFFER)
- {
- /*break out until there is a significant amount of
- data to avoid a series of small write operations*/
- break;
+ /* is there pending audio? does it fit our circular buffer without blocking?*/
+ ret=vorbis_synthesis_pcmout(&vd,&pcm);
+ maxBytesToWrite = GetAudioStreamWriteable(aOutStream);
+
+ if (maxBytesToWrite<=FRAMES_PER_BUFFER)
+ {
+ /*break out until there is a significant amount of
+ data to avoid a series of small write operations*/
+ break;
}
/* if there's pending, decoded audio, grab it */
if((ret>0)&&(maxBytesToWrite>0)){
-
- for(i=0;i<ret && i<(maxBytesToWrite/vi.channels);i++)
- for(j=0;j<vi.channels;j++){
- int val=(int)(pcm[j][i]*32767.f);
+
+ for(i=0;i<ret && i<(maxBytesToWrite/vi.channels);i++)
+ for(j=0;j<vi.channels;j++){
+ int val=(int)(pcm[j][i]*32767.f);
if(val>32767)val=32767;
if(val<-32768)val=-32768;
- samples[count]=val;
- count++;
- }
- WriteAudioStream( aOutStream, samples, i );
- vorbis_synthesis_read(&vd,i);
-
- if(vd.granulepos>=0)
- audiobuf_granulepos=vd.granulepos-ret+i;
- else
- audiobuf_granulepos+=i;
+ samples[count]=val;
+ count++;
+ }
+ WriteAudioStream( aOutStream, samples, i );
+ vorbis_synthesis_read(&vd,i);
+
+ if(vd.granulepos>=0)
+ audiobuf_granulepos=vd.granulepos-ret+i;
+ else
+ audiobuf_granulepos+=i;
}else{
- /* no pending audio; is there a pending packet to decode? */
- if(ogg_stream_packetout(&vo,&op)>0){
- if(vorbis_synthesis(&vb,&op)==0) /* test for success! */
- vorbis_synthesis_blockin(&vd,&vb);
- }else /* we need more data; break out to suck in another page */
- break;
+ /* no pending audio; is there a pending packet to decode? */
+ if(ogg_stream_packetout(&vo,&op)>0){
+ if(vorbis_synthesis(&vb,&op)==0) /* test for success! */
+ vorbis_synthesis_blockin(&vd,&vb);
+ }else /* we need more data; break out to suck in another page */
+ break;
}
}/*end audio cycle*/
-
+
while(theora_p && !videobuf_ready){
/* get one video packet... */
if(ogg_stream_packetout(&to,&op)>0){
@@ -1008,47 +1008,46 @@
videobuf_ready=1;
}else
- /*already have a good frame in the buffer*/
- {
- if (isPlaying == 1)
- {
- printf("end\n");
- /*endticks = GetTickCount();*/
- isPlaying = 0;
- playbackdone = 1;
- }
+ /*already have a good frame in the buffer*/
+ {
+ if (isPlaying == 1)
+ {
+ printf("end\n");
+ /*endticks = GetTickCount();*/
+ isPlaying = 0;
+ playbackdone = 1;
+ }
break;
- }
+ }
}
if(stateflag && videobuf_ready && (videobuf_time<= get_time())){
- /*time to write our cached frame*/
- video_write();
- videobuf_ready=0;
-
- /*if audio has not started (first frame) then start it*/
- if ((!isPlaying)&&(vorbis_p)){
- start_audio();
- isPlaying = 1;
- }
- }
-
- /*buffer compressed data every loop */
- //buffer_data(&oy);
- if (hasdatatobuffer)
- {
- hasdatatobuffer=buffer_data(&oy);
+ /*time to write our cached frame*/
+ video_write();
+ videobuf_ready=0;
+
+ /*if audio has not started (first frame) then start it*/
+ if ((!isPlaying)&&(vorbis_p)){
+ start_audio();
+ isPlaying = 1;
+ }
+ }
+
+ /*buffer compressed data every loop */
+ if (hasdatatobuffer)
+ {
+ hasdatatobuffer=buffer_data(&oy);
if(hasdatatobuffer==0){
- printf("Ogg buffering stopped, end of file reached.\n");
+ printf("Ogg buffering stopped, end of file reached.\n");
}
- }
+ }
- if (ogg_sync_pageout(&oy,&og)>0){
- if(theora_p)ogg_stream_pagein(&to,&og);
- if(vorbis_p)ogg_stream_pagein(&vo,&og);
- }
+ if (ogg_sync_pageout(&oy,&og)>0){
+ if(theora_p)ogg_stream_pagein(&to,&og);
+ if(vorbis_p)ogg_stream_pagein(&vo,&og);
+ }
}
@@ -1063,7 +1062,7 @@
SDL_Quit();
if(vorbis_p){
- audio_close();
+ audio_close();
ogg_stream_clear(&vo);
vorbis_block_clear(&vb);
@@ -1080,9 +1079,7 @@
ogg_sync_clear(&oy);
printf("\r "
- "\nDone.\n");
+ "\nDone.\n");
return(0);
}
-
-
<p><p>1.12 +812 -799 theora/lib/encode.c
Index: encode.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/encode.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- encode.c 10 Jun 2003 13:50:52 -0000 1.11
+++ encode.c 11 Jun 2003 02:24:29 -0000 1.12
@@ -10,12 +10,14 @@
* *
********************************************************************
- function:
- last mod: $Id: encode.c,v 1.11 2003/06/10 13:50:52 mauricio Exp $
+ function:
+ last mod: $Id: encode.c,v 1.12 2003/06/11 02:24:29 tterribe Exp $
********************************************************************/
-#include "ogg/ogg.h"
+#include <stdlib.h>
+#include <string.h>
+#include <ogg/ogg.h>
#include "encoder_internal.h"
#include "encoder_lookup.h"
#include "block_inline.h"
@@ -26,19 +28,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
@@ -49,52 +51,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 */
@@ -106,11 +108,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 */
@@ -121,11 +123,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;
@@ -138,7 +140,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;
@@ -148,7 +150,7 @@
DcHuffChoice[1] = j;
}
}
-
+
/* Add the DC huffman table choice to the bitstream */
oggpackB_write( opb, DcHuffChoice[1], DC_HUFF_CHOICE_BITS );
@@ -158,28 +160,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;
}
@@ -189,7 +191,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];
@@ -197,15 +199,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];
}
}
@@ -221,7 +223,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;
@@ -231,56 +233,58 @@
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;
+ ogg_uint32_t i,j;
unsigned char ModeIndex;
-
- ogg_int32_t ModeCount[MAX_MODES];
- ogg_int32_t TmpFreq;
- ogg_int32_t TmpIndex;
-
- unsigned char BestScheme;
- ogg_uint32_t BestSchemeScore;
- ogg_uint32_t SchemeScore;
+ unsigned char *SchemeList;
+
+ unsigned char BestModeSchemes[MAX_MODES];
+ ogg_int32_t ModeCount[MAX_MODES];
+ ogg_int32_t TmpFreq;
+ ogg_int32_t TmpIndex;
+
+ ogg_uint32_t BestScheme;
+ ogg_uint32_t BestSchemeScore;
+ ogg_uint32_t SchemeScore;
oggpack_buffer *opb=&cpi->oggbuffer;
/* 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
@@ -291,12 +295,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;
- ModeSchemes[0][TmpIndex] = j;
+ BestModeSchemes[TmpIndex] = (unsigned char)j;
}
/* Default/ fallback scheme uses MODE_BITS bits per mode entry */
@@ -304,16 +308,20 @@
BestSchemeScore = cpi->ModeListCount * 3;
/* Get a bit score for the available schemes. */
for ( j = 0; j < (MODE_METHODS - 1); j++ ) {
+
/* Reset the scheme score */
- if ( j == 0 )
- SchemeScore = 24; /* Scheme 0 additional cost of sending
- frequency order */
- else
+ if ( j == 0 ){
+ /* Scheme 0 additional cost of sending frequency order */
+ SchemeScore = 24;
+ SchemeList = BestModeSchemes;
+ } 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[ModeSchemes[j][cpi->ModeList[i]]];
+ for ( i = 0; i < cpi->ModeListCount; i++ )
+ SchemeScore += ModeBitLengths[SchemeList[cpi->ModeList[i]]];
/* Is this the best scheme so far ??? */
if ( SchemeScore < BestSchemeScore ) {
@@ -330,7 +338,11 @@
if ( BestScheme == 0 ) {
for ( j = 0; j < MAX_MODES; j++ )
/* Note that the last two entries are implicit */
- oggpackB_write( opb, ModeSchemes[0][j], (ogg_uint32_t)MODE_BITS );
+ oggpackB_write( opb, BestModeSchemes[j], (ogg_uint32_t)MODE_BITS );
+ SchemeList = BestModeSchemes;
+ }
+ else {
+ SchemeList = ModeSchemes[BestScheme-1];
}
/* Are we using one of the alphabet based schemes or the fallback scheme */
@@ -338,9 +350,9 @@
/* Pack and encode the Mode list */
for ( i = 0; i < cpi->ModeListCount; i++ ) {
/* Add the appropriate mode entropy token. */
- ModeIndex = ModeSchemes[BestScheme][cpi->ModeList[i]];
- oggpackB_write( opb, ModeBitPatterns[ModeIndex],
- (ogg_uint32_t)ModeBitLengths[ModeIndex] );
+ ModeIndex = SchemeList[cpi->ModeList[i]];
+ oggpackB_write( opb, ModeBitPatterns[ModeIndex],
+ (ogg_uint32_t)ModeBitLengths[ModeIndex] );
}
}else{
/* Fall back to MODE_BITS per entry */
@@ -353,16 +365,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 */
@@ -381,10 +393,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] );
}
}
@@ -397,13 +409,13 @@
the first token in the run */
/* Mark out which plane the block belonged to */
- cpi->OptimisedTokenListPl[cpi->OptimisedTokenCount] =
- cpi->RunPlaneIndex;
-
+ cpi->OptimisedTokenListPl[cpi->OptimisedTokenCount] =
+ (unsigned char)cpi->RunPlaneIndex;
+
/* Note the huffman index to be used */
- cpi->OptimisedTokenListHi[cpi->OptimisedTokenCount] =
- cpi->RunHuffIndex;
-
+ cpi->OptimisedTokenListHi[cpi->OptimisedTokenCount] =
+ (unsigned char)cpi->RunHuffIndex;
+
if ( cpi->RunLength <= 3 ) {
if ( cpi->RunLength == 1 ) {
cpi->OptimisedTokenList[cpi->OptimisedTokenCount] = DCT_EOB_TOKEN;
@@ -412,50 +424,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;
@@ -466,65 +478,66 @@
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] += OneOrTwo;
-
+ cpi->FragTokens[FragmentNumber] += (unsigned char)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] = 1 - OneOrZero;
-
+ cpi->OptimisedTokenListPl[cpi->OptimisedTokenCount] =
+ (unsigned char)(1 - OneOrZero);
+
/* Note the token, extra bits and hufman table in the optimised
token list */
- cpi->OptimisedTokenList[cpi->OptimisedTokenCount] =
- Token;
- cpi->OptimisedTokenListEb[cpi->OptimisedTokenCount] =
+ cpi->OptimisedTokenList[cpi->OptimisedTokenCount] =
+ (unsigned char)Token;
+ cpi->OptimisedTokenListEb[cpi->OptimisedTokenCount] =
ExtraBitsToken;
- cpi->OptimisedTokenListHi[cpi->OptimisedTokenCount] =
- HuffIndex;
-
+ cpi->OptimisedTokenListHi[cpi->OptimisedTokenCount] =
+ (unsigned char)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;
@@ -533,8 +546,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]) );
@@ -560,27 +573,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;
@@ -591,28 +604,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]=EncodedCoeffs;
+
+ cpi->pb.FragCoefEOB[FragIndex]=(unsigned char)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. */
@@ -624,57 +637,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]=EncodedCoeffs;
- PackToken( cpi, FragIndex, HuffIndex );
+ && cpi->pb.FragCoeffs[FragIndex] <= EncodedCoeffs ) {
+ /* Bit pack and a token for this block */
+ cpi->pb.FragCoefEOB[FragIndex]=(unsigned char)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 {
@@ -687,38 +700,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;
@@ -727,29 +740,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 */
@@ -781,184 +794,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 */
@@ -966,7 +979,7 @@
/* Get the linear index for the current coded fragment. */
FragIndex = cpi->pb.CodedBlockList[i];
coded_pixels += DPCMTokenizeBlock ( cpi, FragIndex);
-
+
}
@@ -980,16 +993,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;
}
@@ -1007,22 +1020,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;
@@ -1033,33 +1046,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++;
}
@@ -1067,48 +1080,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 */
@@ -1127,9 +1140,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
@@ -1142,18 +1155,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;
@@ -1178,20 +1191,20 @@
InterMVect.y = 0;
GFMVect.x = 0;
GFMVect.y = 0;
-
+
ZeroVect.x = 0;
ZeroVect.y = 0;
-
- QIndex = cpi->pb.FrameQIndex;
+
+ QIndex = (unsigned char)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);
@@ -1199,329 +1212,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) ) {
+ if ( (MBInterMVError > cpi->ExhaustiveSearchThresh) &&
+ (BestError > cpi->ExhaustiveSearchThresh) ) {
+
+ MBInterMVExError =
+ GetMBMVExhaustiveSearch( cpi, cpi->pb.LastFrameRecon,
+ YFragIndex, PixelsPerLine,
+ &InterMVectEx );
- MBInterMVExError =
- GetMBMVExhaustiveSearch( cpi, cpi->pb.LastFrameRecon,
- YFragIndex, PixelsPerLine,
- &InterMVectEx );
-
- /* Is the Variance measure for the EX search
+ /* 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);
- }
-
- /* setting up mode specific block types
+ 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
*******************************************************/
-
- *InterError += (BestError>>8);
- *IntraError += (MBIntraError>>8);
-
-
+
+ *InterError += (BestError>>8);
+ *IntraError += (MBIntraError>>8);
+
+
}
SB++;
-
+
}
}
@@ -1535,7 +1548,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] ) {
@@ -1543,20 +1556,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.7 +1 -4 theora/lib/encoder_lookup.h
Index: encoder_lookup.h
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/encoder_lookup.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- encoder_lookup.h 10 Jun 2003 13:50:52 -0000 1.6
+++ encoder_lookup.h 11 Jun 2003 02:24:29 -0000 1.7
@@ -11,7 +11,7 @@
********************************************************************
function: simple static lookups for VP3 frame encoder
- last mod: $Id: encoder_lookup.h,v 1.6 2003/06/10 13:50:52 mauricio Exp $
+ last mod: $Id: encoder_lookup.h,v 1.7 2003/06/11 02:24:29 tterribe Exp $
********************************************************************/
@@ -81,10 +81,7 @@
ogg_int32_t ModeBitLengths[MAX_MODES] = {
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 },
-
+unsigned char ModeSchemes[MODE_METHODS-2][MAX_MODES] = {
/* 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