📄 mcomp.c
字号:
/* Remember best match. */
MinError = Error;
BestBlockPtr = CandidateBlockPtr;
/* Where is it. */
x = MV->x + cpi->MVOffsetX[SearchSite];
y = MV->y + cpi->MVOffsetY[SearchSite];
}
/* Move to next search location. */
SearchSite += 1;
}
/* Move to best location this step. */
RefPtr = BestBlockPtr;
MV->x = x;
MV->y = y;
}
/* Factor vectors to 1/2 pixel resoultion. */
MV->x = (MV->x * 2);
MV->y = (MV->y * 2);
/* Now do the half pixel pass */
BestHalfOffset = 4; /* Default to the no offset case. */
BestHalfPixelError = MinError;
/* Get the half pixel error for each half pixel offset */
for ( i=0; i < 9; i++ ) {
HalfPixelError = 0;
if ( MBlockDispFrags[0] ) {
RefDataPtr1 = BestBlockPtr;
RefDataPtr2 = RefDataPtr1 + cpi->HalfPixelRef2Offset[i];
HalfPixelError =
GetHalfPixelSumAbsDiffs( SrcPtr[0], RefDataPtr1, RefDataPtr2,
PixelsPerLine, HalfPixelError, BestHalfPixelError );
}
if ( MBlockDispFrags[1] && (HalfPixelError < BestHalfPixelError) ) {
RefDataPtr1 = BestBlockPtr + 8;
RefDataPtr2 = RefDataPtr1 + cpi->HalfPixelRef2Offset[i];
HalfPixelError =
GetHalfPixelSumAbsDiffs( SrcPtr[1], RefDataPtr1, RefDataPtr2,
PixelsPerLine, HalfPixelError, BestHalfPixelError );
}
if ( MBlockDispFrags[2] && (HalfPixelError < BestHalfPixelError) ) {
RefDataPtr1 = BestBlockPtr + RefRow2Offset;
RefDataPtr2 = RefDataPtr1 + cpi->HalfPixelRef2Offset[i];
HalfPixelError =
GetHalfPixelSumAbsDiffs( SrcPtr[2], RefDataPtr1, RefDataPtr2,
PixelsPerLine, HalfPixelError, BestHalfPixelError );
}
if ( MBlockDispFrags[3] && (HalfPixelError < BestHalfPixelError) ) {
RefDataPtr1 = BestBlockPtr + RefRow2Offset + 8;
RefDataPtr2 = RefDataPtr1 + cpi->HalfPixelRef2Offset[i];
HalfPixelError =
GetHalfPixelSumAbsDiffs( SrcPtr[3], RefDataPtr1, RefDataPtr2,
PixelsPerLine, HalfPixelError, BestHalfPixelError );
}
if ( HalfPixelError < BestHalfPixelError ) {
BestHalfOffset = (unsigned char)i;
BestHalfPixelError = HalfPixelError;
}
}
/* Half pixel adjust the MV */
MV->x += cpi->HalfPixelXOffset[BestHalfOffset];
MV->y += cpi->HalfPixelYOffset[BestHalfOffset];
/* Get the error score for the chosen 1/2 pixel offset as a variance. */
InterMVError = GetMBInterError( cpi, cpi->ConvDestBuffer, RefFramePtr,
FragIndex, MV->x, MV->y, PixelsPerLine );
dsp_static_restore_fpu ();
/* Return score of best matching block. */
return InterMVError;
}
ogg_uint32_t GetMBMVExhaustiveSearch (CP_INSTANCE *cpi,
unsigned char * RefFramePtr,
ogg_uint32_t FragIndex,
ogg_uint32_t PixelsPerLine,
MOTION_VECTOR *MV ) {
ogg_uint32_t Error = 0;
ogg_uint32_t MinError = HUGE_ERROR;
ogg_uint32_t InterMVError = 0;
ogg_int32_t i, j;
ogg_int32_t x=0, y=0;
unsigned char *SrcPtr[4] = {NULL,NULL,NULL,NULL};
unsigned char *RefPtr;
unsigned char *CandidateBlockPtr=NULL;
unsigned char *BestBlockPtr=NULL;
ogg_uint32_t RefRow2Offset = cpi->pb.YStride * 8;
int MBlockDispFrags[4];
/* Half pixel variables */
ogg_int32_t HalfPixelError;
ogg_int32_t BestHalfPixelError;
unsigned char BestHalfOffset;
unsigned char * RefDataPtr1;
unsigned char * RefDataPtr2;
dsp_static_save_fpu ();
/* Note which of the four blocks in the macro block are to be
included in the search. */
MBlockDispFrags[0] = cpi->
pb.display_fragments[FragIndex];
MBlockDispFrags[1] = cpi->
pb.display_fragments[FragIndex + 1];
MBlockDispFrags[2] = cpi->
pb.display_fragments[FragIndex + cpi->pb.HFragments];
MBlockDispFrags[3] = cpi->
pb.display_fragments[FragIndex + cpi->pb.HFragments + 1];
/* Set up the source pointers for the four source blocks. */
SrcPtr[0] = &cpi->
ConvDestBuffer[cpi->pb.pixel_index_table[FragIndex]];
SrcPtr[1] = SrcPtr[0] + 8;
SrcPtr[2] = SrcPtr[0] + (PixelsPerLine * 8);
SrcPtr[3] = SrcPtr[2] + 8;
RefPtr = &RefFramePtr[cpi->pb.recon_pixel_index_table[FragIndex]];
RefPtr = RefPtr - ((MAX_MV_EXTENT/2) * cpi->
pb.YStride) - (MAX_MV_EXTENT/2);
/* Search each pixel alligned site */
for ( i = 0; i < (ogg_int32_t)MAX_MV_EXTENT; i ++ ) {
/* Starting position in row */
CandidateBlockPtr = RefPtr;
for ( j = 0; j < (ogg_int32_t)MAX_MV_EXTENT; j++ ) {
/* Reset error */
Error = 0;
/* Summ errors for each block. */
if ( MBlockDispFrags[0] ) {
Error += dsp_static_sad8x8 (SrcPtr[0], PixelsPerLine, CandidateBlockPtr,
PixelsPerLine + STRIDE_EXTRA);
}
if ( MBlockDispFrags[1] ){
Error += dsp_static_sad8x8 (SrcPtr[1], PixelsPerLine, CandidateBlockPtr + 8,
PixelsPerLine + STRIDE_EXTRA);
}
if ( MBlockDispFrags[2] ){
Error += dsp_static_sad8x8 (SrcPtr[2], PixelsPerLine, CandidateBlockPtr + RefRow2Offset,
PixelsPerLine + STRIDE_EXTRA);
}
if ( MBlockDispFrags[3] ){
Error += dsp_static_sad8x8 (SrcPtr[3], PixelsPerLine, CandidateBlockPtr + RefRow2Offset + 8,
PixelsPerLine + STRIDE_EXTRA);
}
/* Was this the best so far */
if ( Error < MinError ) {
MinError = Error;
BestBlockPtr = CandidateBlockPtr;
x = 16 + j - MAX_MV_EXTENT;
y = 16 + i - MAX_MV_EXTENT;
}
/* Move the the next site */
CandidateBlockPtr ++;
}
/* Move on to the next row. */
RefPtr += cpi->pb.YStride;
}
/* Factor vectors to 1/2 pixel resoultion. */
MV->x = (x * 2);
MV->y = (y * 2);
/* Now do the half pixel pass */
BestHalfOffset = 4; /* Default to the no offset case. */
BestHalfPixelError = MinError;
/* Get the half pixel error for each half pixel offset */
for ( i=0; i < 9; i++ ) {
HalfPixelError = 0;
if ( MBlockDispFrags[0] ) {
RefDataPtr1 = BestBlockPtr;
RefDataPtr2 = RefDataPtr1 + cpi->HalfPixelRef2Offset[i];
HalfPixelError =
GetHalfPixelSumAbsDiffs( SrcPtr[0], RefDataPtr1, RefDataPtr2,
PixelsPerLine, HalfPixelError, BestHalfPixelError );
}
if ( MBlockDispFrags[1] && (HalfPixelError < BestHalfPixelError) ) {
RefDataPtr1 = BestBlockPtr + 8;
RefDataPtr2 = RefDataPtr1 + cpi->HalfPixelRef2Offset[i];
HalfPixelError =
GetHalfPixelSumAbsDiffs( SrcPtr[1], RefDataPtr1, RefDataPtr2,
PixelsPerLine, HalfPixelError, BestHalfPixelError );
}
if ( MBlockDispFrags[2] && (HalfPixelError < BestHalfPixelError) ) {
RefDataPtr1 = BestBlockPtr + RefRow2Offset;
RefDataPtr2 = RefDataPtr1 + cpi->HalfPixelRef2Offset[i];
HalfPixelError =
GetHalfPixelSumAbsDiffs( SrcPtr[2], RefDataPtr1, RefDataPtr2,
PixelsPerLine, HalfPixelError, BestHalfPixelError );
}
if ( MBlockDispFrags[3] && (HalfPixelError < BestHalfPixelError) ) {
RefDataPtr1 = BestBlockPtr + RefRow2Offset + 8;
RefDataPtr2 = RefDataPtr1 + cpi->HalfPixelRef2Offset[i];
HalfPixelError =
GetHalfPixelSumAbsDiffs( SrcPtr[3], RefDataPtr1, RefDataPtr2,
PixelsPerLine, HalfPixelError, BestHalfPixelError );
}
if ( HalfPixelError < BestHalfPixelError ){
BestHalfOffset = (unsigned char)i;
BestHalfPixelError = HalfPixelError;
}
}
/* Half pixel adjust the MV */
MV->x += cpi->HalfPixelXOffset[BestHalfOffset];
MV->y += cpi->HalfPixelYOffset[BestHalfOffset];
/* Get the error score for the chosen 1/2 pixel offset as a variance. */
InterMVError = GetMBInterError( cpi, cpi->ConvDestBuffer, RefFramePtr,
FragIndex, MV->x, MV->y, PixelsPerLine );
dsp_static_restore_fpu ();
/* Return score of best matching block. */
return InterMVError;
}
static ogg_uint32_t GetBMVExhaustiveSearch (CP_INSTANCE *cpi,
unsigned char * RefFramePtr,
ogg_uint32_t FragIndex,
ogg_uint32_t PixelsPerLine,
MOTION_VECTOR *MV ) {
ogg_uint32_t Error = 0;
ogg_uint32_t MinError = HUGE_ERROR;
ogg_uint32_t InterMVError = 0;
ogg_int32_t i, j;
ogg_int32_t x=0, y=0;
unsigned char *SrcPtr = NULL;
unsigned char *RefPtr;
unsigned char *CandidateBlockPtr=NULL;
unsigned char *BestBlockPtr=NULL;
/* Half pixel variables */
ogg_int32_t HalfPixelError;
ogg_int32_t BestHalfPixelError;
unsigned char BestHalfOffset;
unsigned char * RefDataPtr2;
/* Set up the source pointer for the block. */
SrcPtr = &cpi->
ConvDestBuffer[cpi->pb.pixel_index_table[FragIndex]];
RefPtr = &RefFramePtr[cpi->pb.recon_pixel_index_table[FragIndex]];
RefPtr = RefPtr - ((MAX_MV_EXTENT/2) *
cpi->pb.YStride) - (MAX_MV_EXTENT/2);
/* Search each pixel alligned site */
for ( i = 0; i < (ogg_int32_t)MAX_MV_EXTENT; i ++ ) {
/* Starting position in row */
CandidateBlockPtr = RefPtr;
for ( j = 0; j < (ogg_int32_t)MAX_MV_EXTENT; j++ ){
/* Get the block error score. */
Error = dsp_static_sad8x8 (SrcPtr, PixelsPerLine, CandidateBlockPtr,
PixelsPerLine + STRIDE_EXTRA);
/* Was this the best so far */
if ( Error < MinError ) {
MinError = Error;
BestBlockPtr = CandidateBlockPtr;
x = 16 + j - MAX_MV_EXTENT;
y = 16 + i - MAX_MV_EXTENT;
}
/* Move the the next site */
CandidateBlockPtr ++;
}
/* Move on to the next row. */
RefPtr += cpi->pb.YStride;
}
/* Factor vectors to 1/2 pixel resoultion. */
MV->x = (x * 2);
MV->y = (y * 2);
/* Now do the half pixel pass */
BestHalfOffset = 4; /* Default to the no offset case. */
BestHalfPixelError = MinError;
/* Get the half pixel error for each half pixel offset */
for ( i=0; i < 9; i++ ) {
RefDataPtr2 = BestBlockPtr + cpi->HalfPixelRef2Offset[i];
HalfPixelError =
GetHalfPixelSumAbsDiffs( SrcPtr, BestBlockPtr, RefDataPtr2,
PixelsPerLine, 0, BestHalfPixelError );
if ( HalfPixelError < BestHalfPixelError ){
BestHalfOffset = (unsigned char)i;
BestHalfPixelError = HalfPixelError;
}
}
/* Half pixel adjust the MV */
MV->x += cpi->HalfPixelXOffset[BestHalfOffset];
MV->y += cpi->HalfPixelYOffset[BestHalfOffset];
/* Get the variance score at the chosen offset */
RefDataPtr2 = BestBlockPtr + cpi->HalfPixelRef2Offset[BestHalfOffset];
InterMVError =
GetInterErr( SrcPtr, BestBlockPtr, RefDataPtr2, PixelsPerLine );
/* Return score of best matching block. */
return InterMVError;
}
ogg_uint32_t GetFOURMVExhaustiveSearch (CP_INSTANCE *cpi,
unsigned char * RefFramePtr,
ogg_uint32_t FragIndex,
ogg_uint32_t PixelsPerLine,
MOTION_VECTOR *MV ) {
ogg_uint32_t InterMVError;
dsp_static_save_fpu ();
/* For the moment the 4MV mode is only deemed to be valid
if all four Y blocks are to be updated */
/* This may be adapted later. */
if ( cpi->pb.display_fragments[FragIndex] &&
cpi->pb.display_fragments[FragIndex + 1] &&
cpi->pb.display_fragments[FragIndex + cpi->pb.HFragments] &&
cpi->pb.display_fragments[FragIndex + cpi->pb.HFragments + 1] ) {
/* Reset the error score. */
InterMVError = 0;
/* Get the error component from each coded block */
InterMVError +=
GetBMVExhaustiveSearch(cpi, RefFramePtr, FragIndex,
PixelsPerLine, &(MV[0]) );
InterMVError +=
GetBMVExhaustiveSearch(cpi, RefFramePtr, (FragIndex + 1),
PixelsPerLine, &(MV[1]) );
InterMVError +=
GetBMVExhaustiveSearch(cpi, RefFramePtr,
(FragIndex + cpi->pb.HFragments),
PixelsPerLine, &(MV[2]) );
InterMVError +=
GetBMVExhaustiveSearch(cpi, RefFramePtr,
(FragIndex + cpi->pb.HFragments + 1),
PixelsPerLine, &(MV[3]) );
}else{
InterMVError = HUGE_ERROR;
}
dsp_static_restore_fpu ();
/* Return score of best matching block. */
return InterMVError;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -