📄 dct_decode.c
字号:
FilterHoriz(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i]+6, LineLength, BoundingValuePtr); } /* Bottom done if next row set */ if( !pbi->display_fragments[ i + LineFragments] ){ FilterVert(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i + LineFragments], LineLength, BoundingValuePtr); } } } /***************************************************************/ /* Last Column */ if( pbi->display_fragments[i]){ /* Filter Left edge always */ FilterHoriz(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i] - 2 , LineLength, BoundingValuePtr); /* Bottom done if next row set */ if( !pbi->display_fragments[ i + LineFragments] ){ FilterVert(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i + LineFragments], LineLength, BoundingValuePtr); } } i++; /***************************************************************/ /* Middle Rows */ /***************************************************************/ for ( m = 1 ; m < FragsDown-1 ; m++) { /*****************************************************************/ /* 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]){ /* TopRow is always done */ FilterVert(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i], LineLength, BoundingValuePtr); /* Filter right hand border only if the block to the right is not coded */ if ( !pbi->display_fragments[ i + 1 ] ){ FilterHoriz(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i] + 6, LineLength, BoundingValuePtr); } /* Bottom done if next row set */ if( !pbi->display_fragments[ i + LineFragments] ){ FilterVert(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i + LineFragments], LineLength, BoundingValuePtr); } } i++; /*****************************************************************/ /* middle columns */ for ( n = 1 ; n < FragsAcross - 1 ; n++, i++){ if( pbi->display_fragments[i]){ /* Filter Left edge always */ FilterHoriz(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i] - 2, LineLength, BoundingValuePtr); /* TopRow is always done */ FilterVert(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i], LineLength, BoundingValuePtr); /* Filter right hand border only if the block to the right is not coded */ if ( !pbi->display_fragments[ i + 1 ] ){ FilterHoriz(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i] + 6, LineLength, BoundingValuePtr); } /* Bottom done if next row set */ if( !pbi->display_fragments[ i + LineFragments] ){ FilterVert(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i + LineFragments], LineLength, BoundingValuePtr); } } } /******************************************************************/ /* Last Column */ if( pbi->display_fragments[i]){ /* Filter Left edge always*/ FilterHoriz(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i] - 2, LineLength, BoundingValuePtr); /* TopRow is always done */ FilterVert(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i], LineLength, BoundingValuePtr); /* Bottom done if next row set */ if( !pbi->display_fragments[ i + LineFragments] ){ FilterVert(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i + LineFragments], LineLength, BoundingValuePtr); } } i++; } /*******************************************************************/ /* Last 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]){ /* TopRow is always done */ FilterVert(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i], LineLength, BoundingValuePtr); /* Filter right hand border only if the block to the right is not coded */ if ( !pbi->display_fragments[ i + 1 ] ){ FilterHoriz(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i] + 6, LineLength, BoundingValuePtr); } } i++; /******************************************************************/ /* middle columns */ for ( n = 1 ; n < FragsAcross - 1 ; n++, i++){ if( pbi->display_fragments[i]){ /* Filter Left edge always */ FilterHoriz(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i] - 2, LineLength, BoundingValuePtr); /* TopRow is always done */ FilterVert(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i], LineLength, BoundingValuePtr); /* Filter right hand border only if the block to the right is not coded */ if ( !pbi->display_fragments[ i + 1 ] ){ FilterHoriz(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i] + 6, LineLength, BoundingValuePtr); } } } /******************************************************************/ /* Last Column */ if( pbi->display_fragments[i]){ /* Filter Left edge always */ FilterHoriz(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i] - 2, LineLength, BoundingValuePtr); /* TopRow is always done */ FilterVert(pbi->LastFrameRecon+ pbi->recon_pixel_index_table[i], LineLength, BoundingValuePtr); } i++; }}void ReconRefFrames (PB_INSTANCE *pbi){ ogg_int32_t i; unsigned char *SwapReconBuffersTemp; /* predictor multiplier up-left, up, up-right,left, shift Entries are packed in the order L, UL, U, UR, with missing entries moved to the end (before the shift parameters). */ static const ogg_int16_t pc[16][6]={ {0,0,0,0,0,0}, {1,0,0,0,0,0}, /* PL */ {1,0,0,0,0,0}, /* PUL */ {1,0,0,0,0,0}, /* PUL|PL */ {1,0,0,0,0,0}, /* PU */ {1,1,0,0,1,1}, /* PU|PL */ {0,1,0,0,0,0}, /* PU|PUL */ {29,-26,29,0,5,31}, /* PU|PUL|PL */ {1,0,0,0,0,0}, /* PUR */ {75,53,0,0,7,127}, /* PUR|PL */ {1,1,0,0,1,1}, /* PUR|PUL */ {75,0,53,0,7,127}, /* PUR|PUL|PL */ {1,0,0,0,0,0}, /* PUR|PU */ {75,0,53,0,7,127}, /* PUR|PU|PL */ {3,10,3,0,4,15}, /* PUR|PU|PUL */ {29,-26,29,0,5,31} /* PUR|PU|PUL|PL */ }; /* boundary case bit masks. */ static const int bc_mask[8]={ /* normal case no boundary condition */ PUR|PU|PUL|PL, /* left column */ PUR|PU, /* top row */ PL, /* top row, left column */ 0, /* right column */ PU|PUL|PL, /* right and left column */ PU, /* top row, right column */ PL, /* top row, right and left column */ 0 }; /* value left value up-left, value up, value up-right, missing values skipped. */ int v[4]; /* fragment number left, up-left, up, up-right */ int fn[4]; /* predictor count. */ int pcount; short wpc; static const short 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 */ }; short Last[3]; short PredictedDC; int FragsAcross=pbi->HFragments; int FromFragment,ToFragment; int FragsDown = pbi->VFragments; int WhichFrame; int WhichCase; int j,k,m,n; void (*ExpandBlockA) ( PB_INSTANCE *pbi, ogg_int32_t FragmentNumber ); if ( GetFrameType(pbi) == KEY_FRAME ) ExpandBlockA=ExpandKFBlock; else ExpandBlockA=ExpandBlock; SetupLoopFilter(pbi); /* for y,u,v */ for ( j = 0; j < 3 ; j++) { /* pick which fragments based on Y, U, V */ switch(j){ case 0: /* y */ FromFragment = 0; ToFragment = pbi->YPlaneFragments; FragsAcross = pbi->HFragments; FragsDown = pbi->VFragments; break; case 1: /* u */ FromFragment = pbi->YPlaneFragments; ToFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments ; FragsAcross = pbi->HFragments >> 1; FragsDown = pbi->VFragments >> 1; break; /*case 2: v */ default: FromFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments; ToFragment = pbi->YPlaneFragments + (2 * pbi->UVPlaneFragments) ; FragsAcross = pbi->HFragments >> 1; FragsDown = pbi->VFragments >> 1; break; } /* initialize our array of last used DC Components */ for(k=0;k<3;k++) Last[k]=0; i=FromFragment; /* do prediction on all of Y, U or V */ for ( m = 0 ; m < FragsDown ; m++) { for ( n = 0 ; n < FragsAcross ; n++, i++){ /* only do 2 prediction if fragment coded and on non intra or if all fragments are intra */ if( pbi->display_fragments[i] || (GetFrameType(pbi) == KEY_FRAME) ){ /* Type of Fragment */ WhichFrame = Mode2Frame[pbi->FragCodingMethod[i]]; /* Check Borderline Cases */ WhichCase = (n==0) + ((m==0) << 1) + ((n+1 == FragsAcross) << 2); fn[0]=i-1; fn[1]=i-FragsAcross-1; fn[2]=i-FragsAcross; fn[3]=i-FragsAcross+1; /* fragment valid for prediction use if coded and it comes from same frame as the one we are predicting */ for(k=pcount=wpc=0; k<4; k++) { int pflag; pflag=1<<k; if((bc_mask[WhichCase]&pflag) && pbi->display_fragments[fn[k]] && (Mode2Frame[pbi->FragCodingMethod[fn[k]]] == WhichFrame)){ v[pcount]=pbi->QFragData[fn[k]][0]; wpc|=pflag; pcount++; } } if(wpc==0){ /* fall back to the last coded fragment */ pbi->QFragData[i][0] += Last[WhichFrame]; }else{ /* don't do divide if divisor is 1 or 0 */ PredictedDC = pc[wpc][0]*v[0]; for(k=1; k<pcount; k++){ PredictedDC += pc[wpc][k]*v[k]; } /* 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 */ if((wpc&(PU|PUL|PL)) == (PU|PUL|PL)){ if( abs(PredictedDC - v[2]) > 128) { PredictedDC = v[2]; } else if( abs(PredictedDC - v[0]) > 128) { PredictedDC = v[0]; } else if( abs(PredictedDC - v[1]) > 128) { PredictedDC = v[1]; } } 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 ); } } } } /* Copy the current reconstruction back to the last frame recon buffer. */ if(pbi->CodedBlockIndex > (ogg_int32_t) (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 ); } /* Apply a loop filter to edge pixels of updated blocks */ LoopFilter(pbi); /* We may need to update the UMV border */ UpdateUMVBorder(pbi, pbi->LastFrameRecon); /* Reconstruct the golden frame if necessary. For VFW codec only on key frames */ if ( GetFrameType(pbi) == KEY_FRAME ){ CopyRecon( pbi, pbi->GoldenFrame, pbi->LastFrameRecon ); /* We may need to update the UMV border */ UpdateUMVBorder(pbi, pbi->GoldenFrame); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -