📄 dct_decode.c
字号:
// calculate values vl = pbi->QFragData[l][0]; // fragment valid for prediction if coded and it comes from same frame as the one we are predicting fl = pbi->display_fragments[l] && (Mode2Frame[pbi->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 default: // Johns: to avoid uninitialized warnings // calculate values left, up, up-right and up-left l = i-1; u = i - FragsAcross; ul = i - FragsAcross - 1; // calculate values vl = pbi->QFragData[l][0]; vu = pbi->QFragData[u][0]; vul = pbi->QFragData[ul][0]; // fragment valid for prediction if coded and it comes from same frame as the one we are predicting fl = pbi->display_fragments[l] && (Mode2Frame[pbi->FragCodingMethod[l]] == WhichFrame); fu = pbi->display_fragments[u] && (Mode2Frame[pbi->FragCodingMethod[u]] == WhichFrame); ful = pbi->display_fragments[ul] && (Mode2Frame[pbi->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(pbi->display_fragments[FragIndex] && (Mode2Frame[pbi->FragCodingMethod[FragIndex]] == WhichFrame)) { pbi->QFragData[i][0] += pbi->QFragData[FragIndex][0]; FragIndex = 0; break; } } } // if none matched fall back to the last one ever if(FragIndex) { pbi->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; } pbi->QFragData[i][0] += PredictedDC; } // Save the last fragment coded for whatever frame we are predicting from Last[WhichFrame] = pbi->QFragData[i][0]; // Inverse DCT and reconstitute buffer in thisframe ExpandBlockA( pbi, i ); } // if display fragments } // for n = 0 to columns across } // for m = 0 to rows down } // for j = 0 to 2 (y,u,v) // Copy the current reconstruction back to the last frame recon buffer.//printf("%d\n",pbi->CodedBlockIndex); if(pbi->CodedBlockIndex > (INT32) (pbi->UnitFragments >> 1)) { SwapReconBuffersTemp = pbi->ThisFrameRecon; pbi->ThisFrameRecon = pbi->LastFrameRecon; pbi->LastFrameRecon = SwapReconBuffersTemp; CopyNotRecon( pbi, pbi->LastFrameRecon, pbi->ThisFrameRecon ); } else { CopyRecon( pbi, pbi->LastFrameRecon, pbi->ThisFrameRecon ); } // We may need to update the UMV border //UpdateUMVBorder(pbi, pbi->LastFrameRecon ); // Apply a loop filter to edge pixels of updated blocks if( pbi->Vp3VersionNo == 0 ) ApplyReconLoopFilter(pbi); else LoopFilter(pbi); // Reconstruct the golden frame if necessary. // For VFW codec only on key frames if ( GetFrameType(pbi) == BASE_FRAME ) { CopyRecon( pbi, pbi->GoldenFrame, pbi->LastFrameRecon ); } // If appropriate clear the MMX state. pbi->ClearSysState();}/**************************************************************************** * * ROUTINE : ExpandKFBlock * * INPUTS : INT32 FragIndex * * OUTPUTS : None * * RETURNS : None. * * FUNCTION : Reverses quantisation and dc and reconstructs pixel * data for an "Intra" frame block. * * SPECIAL NOTES : * * ERRORS : None. * ****************************************************************************/void ExpandKFBlock ( PB_INSTANCE *pbi, INT32 FragmentNumber ){ UINT32 ReconPixelsPerLine; // Pixels per line INT32 ReconPixelIndex; // Offset for block into a reconstruction buffer //INT32 i; // Select the appropriate inverse Q matrix and line stride if ( FragmentNumber<(INT32)pbi->YPlaneFragments ) { ReconPixelsPerLine = pbi->Configuration.YStride; select_Y_dequantiser(pbi); } else { ReconPixelsPerLine = pbi->Configuration.UVStride; select_UV_dequantiser(pbi); } // Set up pointer into the quantisation buffer. pbi->quantized_list = (Q_LIST_ENTRY *)(&pbi->QFragData[FragmentNumber][0]); // Invert quantisation and DCT to get pixel data. pbi->idct[pbi->FragCoefEOB[FragmentNumber]]( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer ); // Convert fragment number to a pixel offset in a reconstruction buffer. ReconPixelIndex = ReconGetFragIndex ( pbi->recon_pixel_index_table, FragmentNumber ); // Get the pixel index for the first pixel in the fragment. pbi->ReconIntra( pbi, (UINT8 *)(&pbi->ThisFrameRecon[ReconPixelIndex]), (UINT16 *)pbi->ReconDataBuffer, ReconPixelsPerLine );}/**************************************************************************** * * ROUTINE : ExpandBlock * * INPUTS : INT32 FragIndex * * OUTPUTS : None * * RETURNS : None. * * FUNCTION : Reverses quantisation and dc and reconstructs pixel data. * * SPECIAL NOTES : * * ERRORS : None. * ****************************************************************************/void ExpandBlock ( PB_INSTANCE *pbi, INT32 FragmentNumber ){ UINT8 *LastFrameRecPtr; // Pointer into previous frame reconstruction. UINT8 *LastFrameRecPtr2; // Pointer into previous frame reconstruction for 1/2 pixel MC. UINT32 ReconPixelsPerLine; // Pixels per line INT32 ReconPixelIndex; // Offset for block into a reconstruction buffer INT32 ReconPtr2Offset; // Offset for second reconstruction in half pixel MC INT32 MVOffset; // Baseline motion vector offset INT32 MvShift ; // Shift to correct to 1/2 or 1/4 pixel INT32 MvModMask; // Mask to determine whether 1/2 pixel is used // TEST //INT32 mmask; //INT32 ReconPtr2OffsetB; // Offset for second reconstruction in half pixel MC //INT32 MVOffsetB; // Get coding mode for this block if ( GetFrameType(pbi) == BASE_FRAME ) { pbi->CodingMode = CODE_INTRA; } else { // Get Motion vector and mode for this block. pbi->CodingMode = pbi->FragCodingMethod[FragmentNumber]; } // Select the appropriate inverse Q matrix and line stride if ( FragmentNumber<(INT32)pbi->YPlaneFragments ) { ReconPixelsPerLine = pbi->Configuration.YStride; MvShift = 1; MvModMask = 0x00000001; //mmask = 1; // Select appropriate dequantiser matrix. if ( pbi->CodingMode == CODE_INTRA ) select_Y_dequantiser(pbi); else select_Inter_dequantiser(pbi); } else { ReconPixelsPerLine = pbi->Configuration.UVStride; MvShift = 2; MvModMask = 0x00000003; //mmask = 3; // Select appropriate dequantiser matrix. if ( pbi->CodingMode == CODE_INTRA ) select_UV_dequantiser(pbi); else select_Inter_dequantiser(pbi); } // Set up pointer into the quantisation buffer. pbi->quantized_list = (Q_LIST_ENTRY *)(&pbi->QFragData[FragmentNumber][0]); // Invert quantisation and DCT to get pixel data. pbi->idct[pbi->FragCoefEOB[FragmentNumber]]( pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer ); // Convert fragment number to a pixel offset in a reconstruction buffer. ReconPixelIndex = ReconGetFragIndex ( pbi->recon_pixel_index_table, FragmentNumber ); // Action depends on decode mode. if ( pbi->CodingMode == CODE_INTER_NO_MV ) // Inter with no motion vector { // Reconstruct the pixel data using the last frame reconstruction and change data // when the motion vector is (0,0), the recon is based on the lastframe without // loop filtering---- for testing pbi->ReconInter( pbi, (UINT8 *)&pbi->ThisFrameRecon[ReconPixelIndex], (UINT8 *)&pbi->LastFrameRecon[ReconPixelIndex], pbi->ReconDataBuffer, ReconPixelsPerLine ); } else if ( ModeUsesMC[pbi->CodingMode] ) // The mode uses a motion vector. { { // Get vector from list pbi->MVector.x = pbi->FragMVect[FragmentNumber].x; pbi->MVector.y = pbi->FragMVect[FragmentNumber].y; // Work out the base motion vector offset and the 1/2 pixel offset if any. // For the U and V planes the MV specifies 1/4 pixel accuracy. This is adjusted to // 1/2 pixel as follows ( 0->0, 1/4->1/2, 1/2->1/2, 3/4->1/2 ). MVOffset = 0; ReconPtr2Offset = 0; if ( pbi->MVector.x > 0 ) { MVOffset = pbi->MVector.x >> MvShift; if ( pbi->MVector.x & MvModMask ) ReconPtr2Offset += 1; } else if ( pbi->MVector.x < 0 ) { MVOffset -= (-pbi->MVector.x) >> MvShift; if ( (-pbi->MVector.x) & MvModMask ) ReconPtr2Offset -= 1; } if ( pbi->MVector.y > 0 ) { MVOffset += (pbi->MVector.y >> MvShift) * ReconPixelsPerLine; if ( pbi->MVector.y & MvModMask ) ReconPtr2Offset += ReconPixelsPerLine; } else if ( pbi->MVector.y < 0 ) { MVOffset -= ((-pbi->MVector.y) >> MvShift) * ReconPixelsPerLine; if ( (-pbi->MVector.y) & MvModMask ) ReconPtr2Offset -= ReconPixelsPerLine; } // Set up the first of the two reconstruction buffer pointers. if ( pbi->CodingMode==CODE_GOLDEN_MV ) { LastFrameRecPtr = (UINT8 * )( &pbi->GoldenFrame[ReconPixelIndex] + MVOffset); } else { LastFrameRecPtr = (UINT8 * )( &pbi->LastFrameRecon[ReconPixelIndex] + MVOffset); } // Set up the second of the two reconstruction pointers. LastFrameRecPtr2 = LastFrameRecPtr + ReconPtr2Offset; // Select the appropriate reconstruction function if ( (int)(LastFrameRecPtr - LastFrameRecPtr2) == 0 ) { // Reconstruct the pixel dats from the reference frame and change data // (no half pixel in this case as the two references were the same. pbi->ReconInter( pbi, (UINT8 *)&pbi->ThisFrameRecon[ReconPixelIndex], LastFrameRecPtr, pbi->ReconDataBuffer, ReconPixelsPerLine ); } // Fractional pixel reconstruction. // Note that we only use two pixels per reconstruction even for the diagonal. else { pbi->ReconInterHalfPixel2( pbi, (UINT8 *)&pbi->ThisFrameRecon[ReconPixelIndex], LastFrameRecPtr, LastFrameRecPtr2, pbi->ReconDataBuffer, ReconPixelsPerLine ); } } } else if ( pbi->CodingMode == CODE_USING_GOLDEN ) // Golden frame with motion vector { // Reconstruct the pixel data using the golden frame reconstruction and change data pbi->ReconInter( pbi, (UINT8 *)&pbi->ThisFrameRecon[ReconPixelIndex], (UINT8 *)&pbi->GoldenFrame[ ReconPixelIndex ], pbi->ReconDataBuffer, ReconPixelsPerLine ); } else // Simple Intra coding { // Get the pixel index for the first pixel in the fragment. pbi->ReconIntra( pbi, (UINT8 *)&pbi->ThisFrameRecon[ReconPixelIndex], (UINT16 *)pbi->ReconDataBuffer, ReconPixelsPerLine ); }}/**************************************************************************** * * ROUTINE : ExpandToken * * INPUTS : Q_LIST_ENTRY * ExpandedBlock * Pointer to block structure into which the token * should be expanded. * * INT32 * CoeffIndex
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -