📄 scan.c
字号:
ogg_uint32_t LocalGrpLowSadThresh = ppi->ModifiedGrpLowSadThresh;
ogg_uint32_t LocalGrpHighSadThresh = ppi->ModifiedGrpHighSadThresh;
signed char *LocalDispFragPtr;
unsigned char *LocalYuvPtr1;
unsigned char *LocalYuvPtr2;
int InterestingBlocksInRow = 0;
/* For each row of pixels in the row of blocks */
for ( j = 0; j < VFRAGPIXELS; j++ ){
/* Set local block map pointer. */
LocalDispFragPtr = DispFragPtr;
/* Set the local pixel data pointers for this row.*/
LocalYuvPtr1 = YuvPtr1;
LocalYuvPtr2 = YuvPtr2;
/* Scan along the row of pixels If the block to which a group of
pixels belongs is already marked for update then do nothing. */
for ( i = 0; i < ppi->PlaneHFragments; i ++ ){
if ( *LocalDispFragPtr <= BLOCK_NOT_CODED ){
/* Calculate the SAD score for the block row */
GrpSad = dsp_static_row_sad8(LocalYuvPtr1,LocalYuvPtr2);
/* Now test the group SAD score */
if ( GrpSad > LocalGrpLowSadThresh ){
/* If SAD very high we must update else we have candidate block */
if ( GrpSad > LocalGrpHighSadThresh ){
/* Force update */
*LocalDispFragPtr = BLOCK_CODED;
}else{
/* Possible Update required */
*LocalDispFragPtr = CANDIDATE_BLOCK;
}
InterestingBlocksInRow = 1;
}
}
LocalDispFragPtr++;
LocalYuvPtr1 += 8;
LocalYuvPtr2 += 8;
}
/* Increment the base data pointers to the start of the next line. */
YuvPtr1 += ppi->PlaneStride;
YuvPtr2 += ppi->PlaneStride;
}
return InterestingBlocksInRow;
}
static int ColSadScan( PP_INSTANCE *ppi,
unsigned char * YuvPtr1,
unsigned char * YuvPtr2,
signed char * DispFragPtr ){
ogg_int32_t i;
ogg_uint32_t MaxSad;
ogg_uint32_t LocalGrpLowSadThresh = ppi->ModifiedGrpLowSadThresh;
ogg_uint32_t LocalGrpHighSadThresh = ppi->ModifiedGrpHighSadThresh;
signed char * LocalDispFragPtr;
unsigned char * LocalYuvPtr1;
unsigned char * LocalYuvPtr2;
int InterestingBlocksInRow = 0;
/* Set the local pixel data pointers for this row. */
LocalYuvPtr1 = YuvPtr1;
LocalYuvPtr2 = YuvPtr2;
/* Set local block map pointer. */
LocalDispFragPtr = DispFragPtr;
/* Scan along the row of blocks */
for ( i = 0; i < ppi->PlaneHFragments; i ++ ){
/* Skip if block already marked to be coded. */
if ( *LocalDispFragPtr <= BLOCK_NOT_CODED ){
/* Calculate the SAD score for the block column */
MaxSad = dsp_static_col_sad8x8(LocalYuvPtr1, LocalYuvPtr2, ppi->PlaneStride );
/* Now test the group SAD score */
if ( MaxSad > LocalGrpLowSadThresh ){
/* If SAD very high we must update else we have candidate block */
if ( MaxSad > LocalGrpHighSadThresh ){
/* Force update */
*LocalDispFragPtr = BLOCK_CODED;
}else{
/* Possible Update required */
*LocalDispFragPtr = CANDIDATE_BLOCK;
}
InterestingBlocksInRow = 1;
}
}
/* Increment the block map pointer. */
LocalDispFragPtr++;
/* Step data pointers on ready for next block */
LocalYuvPtr1 += HFRAGPIXELS;
LocalYuvPtr2 += HFRAGPIXELS;
}
return InterestingBlocksInRow;
}
static void SadPass2( PP_INSTANCE *ppi,
ogg_int32_t RowNumber,
signed char * DispFragPtr ){
ogg_int32_t i;
/* First row */
if ( RowNumber == 0 ) {
/* First block in row. */
if ( DispFragPtr[0] == CANDIDATE_BLOCK ){
if ( (DispFragPtr[1] == BLOCK_CODED) ||
(DispFragPtr[ppi->PlaneHFragments] == BLOCK_CODED) ||
(DispFragPtr[ppi->PlaneHFragments+1] == BLOCK_CODED) ){
ppi->TmpCodedMap[0] = BLOCK_CODED_LOW;
}else{
ppi->TmpCodedMap[0] = DispFragPtr[0];
}
}else{
ppi->TmpCodedMap[0] = DispFragPtr[0];
}
/* All but first and last in row */
for ( i = 1; (i < ppi->PlaneHFragments-1); i++ ){
if ( DispFragPtr[i] == CANDIDATE_BLOCK ){
if ( (DispFragPtr[i-1] == BLOCK_CODED) ||
(DispFragPtr[i+1] == BLOCK_CODED) ||
(DispFragPtr[i+ppi->PlaneHFragments] == BLOCK_CODED) ||
(DispFragPtr[i+ppi->PlaneHFragments-1] == BLOCK_CODED) ||
(DispFragPtr[i+ppi->PlaneHFragments+1] == BLOCK_CODED) ){
ppi->TmpCodedMap[i] = BLOCK_CODED_LOW;
}else{
ppi->TmpCodedMap[i] = DispFragPtr[i];
}
}else{
ppi->TmpCodedMap[i] = DispFragPtr[i];
}
}
/* Last block in row. */
i = ppi->PlaneHFragments-1;
if ( DispFragPtr[i] == CANDIDATE_BLOCK ){
if ( (DispFragPtr[i-1] == BLOCK_CODED) ||
(DispFragPtr[i+ppi->PlaneHFragments] == BLOCK_CODED) ||
(DispFragPtr[i+ppi->PlaneHFragments-1] == BLOCK_CODED) ){
ppi->TmpCodedMap[i] = BLOCK_CODED_LOW;
}else{
ppi->TmpCodedMap[i] = DispFragPtr[i];
}
}else{
ppi->TmpCodedMap[i] = DispFragPtr[i];
}
}else if ( RowNumber < (ppi->PlaneVFragments - 1) ){
/* General case */
/* First block in row. */
if ( DispFragPtr[0] == CANDIDATE_BLOCK ){
if ( (DispFragPtr[1] == BLOCK_CODED) ||
(DispFragPtr[(-ppi->PlaneHFragments)] == BLOCK_CODED) ||
(DispFragPtr[(-ppi->PlaneHFragments)+1] == BLOCK_CODED) ||
(DispFragPtr[ppi->PlaneHFragments] == BLOCK_CODED) ||
(DispFragPtr[ppi->PlaneHFragments+1] == BLOCK_CODED) ){
ppi->TmpCodedMap[0] = BLOCK_CODED_LOW;
}else{
ppi->TmpCodedMap[0] = DispFragPtr[0];
}
}else{
ppi->TmpCodedMap[0] = DispFragPtr[0];
}
/* All but first and last in row */
for ( i = 1; (i < ppi->PlaneHFragments-1); i++ ){
if ( DispFragPtr[i] == CANDIDATE_BLOCK ){
if ( (DispFragPtr[i-1] == BLOCK_CODED) ||
(DispFragPtr[i+1] == BLOCK_CODED) ||
(DispFragPtr[i-ppi->PlaneHFragments] == BLOCK_CODED) ||
(DispFragPtr[i-ppi->PlaneHFragments-1] == BLOCK_CODED) ||
(DispFragPtr[i-ppi->PlaneHFragments+1] == BLOCK_CODED) ||
(DispFragPtr[i+ppi->PlaneHFragments] == BLOCK_CODED) ||
(DispFragPtr[i+ppi->PlaneHFragments-1] == BLOCK_CODED) ||
(DispFragPtr[i+ppi->PlaneHFragments+1] == BLOCK_CODED) ){
ppi->TmpCodedMap[i] = BLOCK_CODED_LOW;
}else{
ppi->TmpCodedMap[i] = DispFragPtr[i];
}
}else{
ppi->TmpCodedMap[i] = DispFragPtr[i];
}
}
/* Last block in row. */
i = ppi->PlaneHFragments-1;
if ( DispFragPtr[i] == CANDIDATE_BLOCK ){
if ( (DispFragPtr[i-1] == BLOCK_CODED) ||
(DispFragPtr[i-ppi->PlaneHFragments] == BLOCK_CODED) ||
(DispFragPtr[i-ppi->PlaneHFragments-1] == BLOCK_CODED) ||
(DispFragPtr[i+ppi->PlaneHFragments] == BLOCK_CODED) ||
(DispFragPtr[i+ppi->PlaneHFragments-1] == BLOCK_CODED) ){
ppi->TmpCodedMap[i] = BLOCK_CODED_LOW;
}else{
ppi->TmpCodedMap[i] = DispFragPtr[i];
}
}else{
ppi->TmpCodedMap[i] = DispFragPtr[i];
}
}else{
/* Last row */
/* First block in row. */
if ( DispFragPtr[0] == CANDIDATE_BLOCK ){
if ( (DispFragPtr[1] == BLOCK_CODED) ||
(DispFragPtr[(-ppi->PlaneHFragments)] == BLOCK_CODED) ||
(DispFragPtr[(-ppi->PlaneHFragments)+1] == BLOCK_CODED)){
ppi->TmpCodedMap[0] = BLOCK_CODED_LOW;
}else{
ppi->TmpCodedMap[0] = DispFragPtr[0];
}
}else{
ppi->TmpCodedMap[0] = DispFragPtr[0];
}
/* All but first and last in row */
for ( i = 1; (i < ppi->PlaneHFragments-1); i++ ){
if ( DispFragPtr[i] == CANDIDATE_BLOCK ){
if ( (DispFragPtr[i-1] == BLOCK_CODED) ||
(DispFragPtr[i+1] == BLOCK_CODED) ||
(DispFragPtr[i-ppi->PlaneHFragments] == BLOCK_CODED) ||
(DispFragPtr[i-ppi->PlaneHFragments-1] == BLOCK_CODED) ||
(DispFragPtr[i-ppi->PlaneHFragments+1] == BLOCK_CODED) ){
ppi->TmpCodedMap[i] = BLOCK_CODED_LOW;
}else{
ppi->TmpCodedMap[i] = DispFragPtr[i];
}
}else{
ppi->TmpCodedMap[i] = DispFragPtr[i];
}
}
/* Last block in row. */
i = ppi->PlaneHFragments-1;
if ( DispFragPtr[i] == CANDIDATE_BLOCK ){
if ( (DispFragPtr[i-1] == BLOCK_CODED) ||
(DispFragPtr[i-ppi->PlaneHFragments] == BLOCK_CODED) ||
(DispFragPtr[i-ppi->PlaneHFragments-1] == BLOCK_CODED) ){
ppi->TmpCodedMap[i] = BLOCK_CODED_LOW;
}else{
ppi->TmpCodedMap[i] = DispFragPtr[i];
}
}else{
ppi->TmpCodedMap[i] = DispFragPtr[i];
}
}
/* Now copy back the modified Fragment data */
memcpy( &DispFragPtr[0], &ppi->TmpCodedMap[0], (ppi->PlaneHFragments) );
}
static unsigned char ApplyPakLowPass( PP_INSTANCE *ppi,
unsigned char * SrcPtr ){
unsigned char * SrcPtr1 = SrcPtr - 1;
unsigned char * SrcPtr0 = SrcPtr1 - ppi->PlaneStride; /* Note the
use of
stride not
width. */
unsigned char * SrcPtr2 = SrcPtr1 + ppi->PlaneStride;
return (unsigned char)( ( (ogg_uint32_t)SrcPtr0[0] +
(ogg_uint32_t)SrcPtr0[1] +
(ogg_uint32_t)SrcPtr0[2] +
(ogg_uint32_t)SrcPtr1[0] +
(ogg_uint32_t)SrcPtr1[2] +
(ogg_uint32_t)SrcPtr2[0] +
(ogg_uint32_t)SrcPtr2[1] +
(ogg_uint32_t)SrcPtr2[2] ) >> 3 );
}
static void RowDiffScan( PP_INSTANCE *ppi,
unsigned char * YuvPtr1,
unsigned char * YuvPtr2,
ogg_int16_t * YUVDiffsPtr,
unsigned char * bits_map_ptr,
signed char * SgcPtr,
signed char * DispFragPtr,
unsigned char * FDiffPixels,
ogg_int32_t * RowDiffsPtr,
unsigned char * ChLocalsPtr, int EdgeRow ){
ogg_int32_t i,j;
ogg_int32_t FragChangedPixels;
ogg_int16_t Diff; /* Temp local workspace. */
/* Cannot use kernel if at edge or if PAK disabled */
if ( (!ppi->PAKEnabled) || EdgeRow ){
for ( i = 0; i < ppi->PlaneWidth; i += HFRAGPIXELS ){
/* Reset count of pixels changed for the current fragment. */
FragChangedPixels = 0;
/* Test for break out conditions to save time. */
if (*DispFragPtr == CANDIDATE_BLOCK){
/* Clear down entries in changed locals array */
SET8_0(ChLocalsPtr);
for ( j = 0; j < HFRAGPIXELS; j++ ){
/* Take a local copy of the measured difference. */
Diff = (int)YuvPtr1[j] - (int)YuvPtr2[j];
/* Store the actual difference value */
YUVDiffsPtr[j] = Diff;
/* Test against the Level thresholds and record the results */
SgcPtr[0] += ppi->SgcThreshTable[Diff+255];
/* Test against the SRF thresholds */
bits_map_ptr[j] = ppi->SrfThreshTable[Diff+255];
FragChangedPixels += ppi->SrfThreshTable[Diff+255];
}
}else{
/* If we are breaking out here mark all pixels as changed. */
if ( *DispFragPtr > BLOCK_NOT_CODED ){
SET8_1(bits_map_ptr);
SET8_8(ChLocalsPtr);
}else{
SET8_0(ChLocalsPtr);
}
}
*RowDiffsPtr += FragChangedPixels;
*FDiffPixels += (unsigned char)FragChangedPixels;
YuvPtr1 += HFRAGPIXELS;
YuvPtr2 += HFRAGPIXELS;
bits_map_ptr += HFRAGPIXELS;
ChLocalsPtr += HFRAGPIXELS;
YUVDiffsPtr += HFRAGPIXELS;
SgcPtr ++;
FDiffPixels ++;
/* If we have a lot of changed pixels for this fragment on this
row then the fragment is almost sure to be picked (e.g. through
the line search) so we can mark it as selected and then ignore
it. */
if (FragChangedPixels >= 7){
*DispFragPtr = BLOCK_CODED_LOW;
}
DispFragPtr++;
}
}else{
/*************************************************************/
/* First fragment of row !! */
i = 0;
/* Reset count of pixels changed for the current fragment. */
FragChangedPixels = 0;
/* Test for break out conditions to save time. */
if (*DispFragPtr == CANDIDATE_BLOCK){
/* Clear down entries in changed locals array */
SET8_0(ChLocalsPtr);
for ( j = 0; j < HFRAGPIXELS; j++ ){
/* Take a local copy of the measured difference. */
Diff = (int)YuvPtr1[j] - (int)YuvPtr2[j];
/* Store the actual difference value */
YUVDiffsPtr[j] = Diff;
/* Test against the Level thresholds and record the results */
SgcPtr[0] += ppi->SgcThreshTable[Diff+255];
if (j>0 && ppi->SrfPakThreshTable[Diff+255] )
Diff = (int)ApplyPakLowPass( ppi, &YuvPtr1[j] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[j] );
/* Test against the SRF thresholds */
bits_map_ptr[j] = ppi->SrfThreshTable[Diff+255];
FragChangedPixels += ppi->SrfThreshTable[Diff+255];
}
}else{
/* If we are breaking out here mark all pixels as changed. */
if ( *DispFragPtr > BLOCK_NOT_CODED ){
SET8_1(bits_map_ptr);
SET8_8(ChLocalsPtr);
}else{
SET8_0(ChLocalsPtr);
}
}
*RowDiffsPtr += FragChangedPixels;
*FDiffPixels += (unsigned char)FragChangedPixels;
YuvPtr1 += HFRAGPIXELS;
YuvPtr2 += HFRAGPIXELS;
bits_map_ptr += HFRAGPIXELS;
ChLocalsPtr += HFRAGPIXELS;
YUVDiffsPtr += HFRAGPIXELS;
SgcPtr ++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -