📄 dct_decode.c
字号:
if ( !pbi->display_fragments[ i + 1 ] ){
dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
pbi->recon_pixel_index_table[i]+6,
LineLength, BoundingValuePtr);
}
/* Bottom done if next row set */
if( !pbi->display_fragments[ i + LineFragments] ){
dsp_funcs.FilterVert(pbi->LastFrameRecon+
pbi->recon_pixel_index_table[i + LineFragments],
LineLength, BoundingValuePtr);
}
}
}
/***************************************************************/
/* Last Column */
if( pbi->display_fragments[i]){
/* Filter Left edge always */
dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
pbi->recon_pixel_index_table[i] - 2 ,
LineLength, BoundingValuePtr);
/* Bottom done if next row set */
if( !pbi->display_fragments[ i + LineFragments] ){
dsp_funcs.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 */
dsp_funcs.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 ] ){
dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
pbi->recon_pixel_index_table[i] + 6,
LineLength, BoundingValuePtr);
}
/* Bottom done if next row set */
if( !pbi->display_fragments[ i + LineFragments] ){
dsp_funcs.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 */
dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
pbi->recon_pixel_index_table[i] - 2,
LineLength, BoundingValuePtr);
/* TopRow is always done */
dsp_funcs.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 ] ){
dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
pbi->recon_pixel_index_table[i] + 6,
LineLength, BoundingValuePtr);
}
/* Bottom done if next row set */
if( !pbi->display_fragments[ i + LineFragments] ){
dsp_funcs.FilterVert(pbi->LastFrameRecon+
pbi->recon_pixel_index_table[i + LineFragments],
LineLength, BoundingValuePtr);
}
}
}
/******************************************************************/
/* Last Column */
if( pbi->display_fragments[i]){
/* Filter Left edge always*/
dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
pbi->recon_pixel_index_table[i] - 2,
LineLength, BoundingValuePtr);
/* TopRow is always done */
dsp_funcs.FilterVert(pbi->LastFrameRecon+
pbi->recon_pixel_index_table[i],
LineLength, BoundingValuePtr);
/* Bottom done if next row set */
if( !pbi->display_fragments[ i + LineFragments] ){
dsp_funcs.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 */
dsp_funcs.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 ] ){
dsp_funcs.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 */
dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
pbi->recon_pixel_index_table[i] - 2,
LineLength, BoundingValuePtr);
/* TopRow is always done */
dsp_funcs.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 ] ){
dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
pbi->recon_pixel_index_table[i] + 6,
LineLength, BoundingValuePtr);
}
}
}
/******************************************************************/
/* Last Column */
if( pbi->display_fragments[i]){
/* Filter Left edge always */
dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
pbi->recon_pixel_index_table[i] - 2,
LineLength, BoundingValuePtr);
/* TopRow is always done */
dsp_funcs.FilterVert(pbi->LastFrameRecon+
pbi->recon_pixel_index_table[i],
LineLength, BoundingValuePtr);
}
i++;
}
_mm_empty();
}
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 );
}
}
}
}
_mm_empty();
/* 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 + -