📄 dct_decode.c
字号:
UINT8 *SrcPtr1; // Pointer into destination buffer UINT8 *SrcPtr2; // Pointer into destination buffer UINT8 *DestPtr1; // Pointer into destination buffer UINT8 *DestPtr2; // Pointer into destination buffer // Work out various plane specific values if ( PlaneFragOffset == 0 ) { // Y Plane BlockVStep = (pbi->Configuration.YStride * (pbi->Configuration.VFragPixels - 1)); PlaneStride = pbi->Configuration.YStride; PlaneBorderWidth = UMV_BORDER; PlaneFragments = pbi->YPlaneFragments; LineFragments = pbi->HFragments; } else { // U or V plane. BlockVStep = (pbi->Configuration.UVStride * (pbi->Configuration.VFragPixels - 1)); PlaneStride = pbi->Configuration.UVStride; PlaneBorderWidth = UMV_BORDER / 2; PlaneFragments = pbi->UVPlaneFragments; LineFragments = pbi->HFragments / 2; } // Setup the source and destination pointers for the top and bottom borders PixelIndex = ReconGetFragIndex ( pbi->recon_pixel_index_table, PlaneFragOffset ); SrcPtr1 = &DestReconPtr[ PixelIndex - PlaneBorderWidth ]; DestPtr1 = SrcPtr1 - (PlaneBorderWidth * PlaneStride); PixelIndex = ReconGetFragIndex ( pbi->recon_pixel_index_table, PlaneFragOffset + PlaneFragments - LineFragments ) + BlockVStep; SrcPtr2 = &DestReconPtr[ PixelIndex - PlaneBorderWidth]; DestPtr2 = SrcPtr2 + PlaneStride; // Now copy the top and bottom source lines into each line of the respective borders for ( i = 0; i < PlaneBorderWidth; i++ ) { memcpy( DestPtr1, SrcPtr1, PlaneStride ); memcpy( DestPtr2, SrcPtr2, PlaneStride ); DestPtr1 += PlaneStride; DestPtr2 += PlaneStride; }}/**************************************************************************** * * ROUTINE : UpdateUMV_VBorders * * INPUTS : UINT8 * DestReconPtr * UINT32 PlaneFragOffset * * OUTPUTS : None * * RETURNS : None * * FUNCTION : Fills in the vertical UMV borders for the given * reconstruction buffer. * * SPECIAL NOTES : * * * ERRORS : None. * ****************************************************************************/void UpdateUMV_VBorders( PB_INSTANCE *pbi, UINT8 * DestReconPtr, UINT32 PlaneFragOffset ){ UINT32 i; UINT32 PixelIndex; UINT32 PlaneStride; UINT32 LineFragments; UINT32 PlaneBorderWidth; UINT32 PlaneHeight; UINT8 *SrcPtr1; // Pointer into destination buffer UINT8 *SrcPtr2; // Pointer into destination buffer UINT8 *DestPtr1; // Pointer into destination buffer UINT8 *DestPtr2; // Pointer into destination buffer // Work out various plane specific values if ( PlaneFragOffset == 0 ) { // Y Plane PlaneStride = pbi->Configuration.YStride; PlaneBorderWidth = UMV_BORDER; LineFragments = pbi->HFragments; PlaneHeight = pbi->Configuration.VideoFrameHeight; } else { // U or V plane. PlaneStride = pbi->Configuration.UVStride; PlaneBorderWidth = UMV_BORDER / 2; LineFragments = pbi->HFragments / 2; PlaneHeight = pbi->Configuration.VideoFrameHeight / 2; } // Setup the source data values and destination pointers for the left and right edge borders PixelIndex = ReconGetFragIndex ( pbi->recon_pixel_index_table, PlaneFragOffset ); SrcPtr1 = &DestReconPtr[ PixelIndex ]; DestPtr1 = &DestReconPtr[ PixelIndex - PlaneBorderWidth ]; PixelIndex = ReconGetFragIndex ( pbi->recon_pixel_index_table, PlaneFragOffset + LineFragments - 1 ) + (pbi->Configuration.HFragPixels - 1); SrcPtr2 = &DestReconPtr[ PixelIndex ]; DestPtr2 = &DestReconPtr[ PixelIndex + 1 ]; // Now copy the top and bottom source lines into each line of the respective borders for ( i = 0; i < PlaneHeight; i++ ) { memset( DestPtr1, SrcPtr1[0], PlaneBorderWidth ); memset( DestPtr2, SrcPtr2[0], PlaneBorderWidth ); SrcPtr1 += PlaneStride; SrcPtr2 += PlaneStride; DestPtr1 += PlaneStride; DestPtr2 += PlaneStride; }}/**************************************************************************** * * ROUTINE : ClearDownQFragData * * INPUTS : None. * * OUTPUTS : None. * * RETURNS : None. * * FUNCTION : Clears down the data structure that is used * to store quantised dct coefficients for each block. * * SPECIAL NOTES : None. * * * ERRORS : None. * ****************************************************************************/void ClearDownQFragData(PB_INSTANCE *pbi){ INT32 i,j; UINT16 * QFragPtr; for ( i = 0; i < pbi->CodedBlockIndex; i++ ) { // Get the linear index for the current fragment. QFragPtr = (UINT16*)(&pbi->QFragData[pbi->CodedBlockList[i]]); for ( j = 0; j < 8; j++ ) { QFragPtr[0] = 0; QFragPtr[1] = 0; QFragPtr[2] = 0; QFragPtr[3] = 0; QFragPtr[4] = 0; QFragPtr[5] = 0; QFragPtr[6] = 0; QFragPtr[7] = 0; QFragPtr += 8; } }}/**************************************************************************** * * ROUTINE : FilterHoriz_Generic * * INPUTS : None * * OUTPUTS : None * * RETURNS : None * * FUNCTION : Applies a loop filter to the vertical edge horizontally * * SPECIAL NOTES : * * * ERRORS : None. * ****************************************************************************/void FilterHoriz_Generic(PB_INSTANCE *pbi __attribute__((unused)), UINT8 * PixelPtr, INT32 LineLength, INT32 *BoundingValuePtr){ INT32 j; INT32 FiltVal; UINT8 * LimitTable = &LimitVal_VP31[VAL_RANGE]; for ( j = 0; j < 8; j++ ) { FiltVal = ( PixelPtr[0] ) - ( PixelPtr[1] * 3 ) + ( PixelPtr[2] * 3 ) - ( PixelPtr[3] ); FiltVal = BoundingValuePtr[(FiltVal + 4) >> 3]; PixelPtr[1] = LimitTable[(INT32)PixelPtr[1] + FiltVal]; PixelPtr[2] = LimitTable[(INT32)PixelPtr[2] - FiltVal]; PixelPtr += LineLength; }}/**************************************************************************** * * ROUTINE : FilterVert_Generic * * INPUTS : None * * OUTPUTS : None * * RETURNS : None * * FUNCTION : Applies a loop filter to a horizontal edge vertically * * SPECIAL NOTES : * * * ERRORS : None. * ****************************************************************************/void FilterVert_Generic(PB_INSTANCE *pbi __attribute__((unused)), UINT8 * PixelPtr, INT32 LineLength, INT32 *BoundingValuePtr){ INT32 j; INT32 FiltVal; UINT8 * LimitTable = &LimitVal_VP31[VAL_RANGE]; for ( j = 0; j < 8; j++ ) { FiltVal = ( (INT32)PixelPtr[- (2 * LineLength)] ) - ( (INT32)PixelPtr[- LineLength] * 3 ) + ( (INT32)PixelPtr[0] * 3 ) - ( (INT32)PixelPtr[LineLength] ); FiltVal = BoundingValuePtr[(FiltVal + 4) >> 3]; PixelPtr[- LineLength] = LimitTable[(INT32)PixelPtr[- LineLength] + FiltVal]; PixelPtr[0] = LimitTable[(INT32)PixelPtr[0] - FiltVal]; PixelPtr ++; }}/**************************************************************************** * * ROUTINE : SetupBoundingValueArray * * INPUTS : None * * OUTPUTS : None * * RETURNS : None * * FUNCTION : Set up the bounding value array. * * SPECIAL NOTES : * * * ERRORS : None. * ****************************************************************************/INT32 *SetupBoundingValueArray_Generic(PB_INSTANCE *pbi, INT32 FLimit){ INT32 * BoundingValuePtr; INT32 i; BoundingValuePtr = &pbi->FiltBoundingValue[256]; // Set up the bounding value array. memset ( pbi->FiltBoundingValue, 0, (512*sizeof(*pbi->FiltBoundingValue)) ); for ( i = 0; i < FLimit; i++ ) { BoundingValuePtr[-i-FLimit] = (-FLimit+i); BoundingValuePtr[-i] = -i; BoundingValuePtr[i] = i; BoundingValuePtr[i+FLimit] = FLimit-i; } return BoundingValuePtr;}/**************************************************************************** * * ROUTINE : ApplyReconLoopFilter * * INPUTS : None * * OUTPUTS : None * * RETURNS : None * * FUNCTION : Applies a loop filter to the edge pixels of coded blocks. * * SPECIAL NOTES : * * * ERRORS : None. * ****************************************************************************/void ApplyReconLoopFilter(PB_INSTANCE *pbi){ INT32 i; INT32 * BoundingValuePtr; //UINT8 * LimitTable = &LimitVal_VP31[VAL_RANGE]; int FragsAcross=pbi->HFragments; int FromFragment,ToFragment; int FragsDown = pbi->VFragments; INT32 LineFragments; INT32 LineLength; //UINT8 BlockHeight = (UINT8)pbi->Configuration.VFragPixels; //UINT8 BlockWidth = (UINT8)pbi->Configuration.HFragPixels; INT32 FLimit; INT32 QIndex; int j,m,n; // Set the limit value for the loop filter based upon the current quantizer. QIndex = Q_TABLE_SIZE - 1; while ( QIndex >= 0 ) { if ( (QIndex == 0) || ( pbi->QThreshTable[QIndex] >= pbi->ThisFrameQualityValue) ) break; QIndex --; } FLimit = LoopFilterLimitValuesV1[QIndex]; if ( FLimit == 0 ) return; BoundingValuePtr = pbi->SetupBoundingValueArray(pbi, FLimit); for ( j = 0; j < 3 ; j++) { switch(j) { case 0: // y FromFragment = 0; ToFragment = pbi->YPlaneFragments; FragsAcross = pbi->HFragments; FragsDown = pbi->VFragments; LineLength = pbi->Configuration.YStride; LineFragments = pbi->HFragments; break; case 1: // u FromFragment = pbi->YPlaneFragments; ToFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments ; FragsAcross = pbi->HFragments >> 1; FragsDown = pbi->VFragments >> 1; LineLength = pbi->Configuration.UVStride; LineFragments = pbi->HFragments / 2; break; case 2: // v default: // Johns: to avoid uninitialized warnings FromFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments; ToFragment = pbi->YPlaneFragments + (2 * pbi->UVPlaneFragments) ; FragsAcross = pbi->HFragments >> 1; FragsDown = pbi->VFragments >> 1; LineLength = pbi->Configuration.UVStride; LineFragments = pbi->HFragments / 2; break; } i=FromFragment; //**************************************************************************************************************** // First Row //**************************************************************************************************************** //****************************************************************** // first column conditions // only do 2 prediction if fragment coded and on non intra or if all fragments are intra if( pbi->display_fragments[i]) { // Filter right hand border only if the block to the right is not coded if ( !pbi->display_fragments[ i + 1 ] ) { pbi->FilterHoriz(pbi, &pbi->LastFrameRecon[ ReconGetFragIndex(pbi->recon_pixel_index_table, i) + 6 ], LineLength, BoundingValuePtr); } // Bottom done if next row set if( !pbi->display_fragments[ i + LineFragments] ) { pbi->FilterVert(pbi, &pbi->LastFrameRecon[ ReconGetFragIndex(pbi->recon_pixel_index_table, i + LineFragments) ], LineLength, BoundingValuePtr); } } // if( pbi->display_fragments[i]) i++; // next i //****************************************************************** // middle columns for ( n = 1 ; n < FragsAcross - 1 ; n++, i++) { if( pbi->display_fragments[i]) { // Filter Left edge always pbi->FilterHoriz(pbi, &pbi->LastFrameRecon[ ReconGetFragIndex(pbi->recon_pixel_index_table, i) - 2 ], LineLength, BoundingValuePtr); // Filter right hand border only if the block to the right is not coded if ( !pbi->display_fragments[ i + 1 ] )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -