www.pudn.com > wm2.5.zip > interprediction.c
/* *********************************************************************** * COPYRIGHT AND WARRANTY INFORMATION * * Copyright 2004, Advanced Audio Video Coding Standard, Part II * * DISCLAIMER OF WARRANTY * * These software programs are available to the users without any * license fee or royalty on an "as is" basis. The AVS disclaims * any and all warranties, whether express, implied, or statutory, * including any implied warranties of merchantability or of fitness * for a particular purpose. In no event shall the contributors or * the AVS be liable for any incidental, punitive, or consequential * damages of any kind whatsoever arising from the use of this program. * * This disclaimer of warranty extends to the user of this program * and user's customers, employees, agents, transferees, successors, * and assigns. * * The AVS does not represent or warrant that the program furnished * hereunder are free of infringement of any third-party patents. * Commercial implementations of AVS, including shareware, may be * subject to royalty fees to patent holders. Information regarding * the AVS patent policy is available from the AVS Web site at * http://www.avs.org.cn * * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. ************************************************************************ */ #include#include "global.h" /*! ************************************************************************ * \brief * Set motion vector predictor ************************************************************************ */ void SetMotionVectorPredictor(int *pmv_x, int *pmv_y, int ref_frame, int block_x, int block_y, int blockshape_x, int blockshape_y, int ref) { int mb_x = 4*block_x; int mb_y = 4*block_y; int pic_block_x = pgImage->block4_x + block_x; int pic_block_y = pgImage->block4_y + block_y; int mb_width = pgImage->width/16; //WJP FOR SLICE int mb_available_up = (pgImage->mb_y == 0) ? 0 : (pgcurrMB->slice_nr == mb_data[pgImage->current_mb_nr-mb_width].slice_nr); int mb_available_left = (pgImage->mb_x == 0) ? 0 : (pgcurrMB->slice_nr == mb_data[pgImage->current_mb_nr-1].slice_nr); int mb_available_upleft = (pgImage->mb_x == 0 || pgImage->mb_y == 0) ? 0 : (pgcurrMB->slice_nr == mb_data[pgImage->current_mb_nr-mb_width-1].slice_nr); int mb_available_upright = (pgImage->mb_x >= mb_width-1 || pgImage->mb_y == 0) ? 0 : (pgcurrMB->slice_nr == mb_data[pgImage->current_mb_nr-mb_width+1].slice_nr); //WJP END int block_available_up, block_available_left, block_available_upright, block_available_upleft; int mv_a, mv_b, mv_c, mv_d, pred_vec[2]; int mvPredType, rFrameL, rFrameU, rFrameUR; int hv; int ***tmp_mv = pgImage->mv; int a_c, b_c, a_b;//qhg int ABC;//qhg int a[2],b[2],c[2];//qhg /* D B C */ /* A X */ /* 1 A, B, D are set to 0 if unavailable */ /* 2 If C is not available it is replaced by D */ block_available_up = mb_available_up || (mb_y > 0); block_available_left = mb_available_left || (mb_x > 0); if (mb_y > 0) { if (mb_x < 8) // first column of 8x8 blocks { if (mb_y==8) { if (blockshape_x == 16) block_available_upright = 0; else block_available_upright = 1; } else { if (mb_x+blockshape_x != 8) block_available_upright = 1; else block_available_upright = 0; } } else { if (mb_x+blockshape_x != 16) block_available_upright = 1; else block_available_upright = 0; } } else if (mb_x+blockshape_x != MB_BLOCK_SIZE) { block_available_upright = block_available_up; } else { block_available_upright = mb_available_upright; } if (mb_x > 0) { block_available_upleft = (mb_y > 0 ? 1 : mb_available_up); } else if (mb_y > 0) { block_available_upleft = mb_available_left; } else { block_available_upleft = mb_available_upleft; } mvPredType = MVPRED_MEDIAN; // rFrameL = block_available_left ? refFrArr[pic_block_y] [pic_block_x-1 ] : -1; rFrameL = block_available_left ? refFrArr[pic_block_y+blockshape_y/4 -1] [pic_block_x-1] : -1; //JX 05-4-1 rFrameU = block_available_up ? refFrArr[pic_block_y-1][pic_block_x] : -1; //added by MZ if(block_available_upright) block_available_upright = block_available_upright && (refFrArr[pic_block_y-1][pic_block_x+blockshape_x/4]!=-1); if(block_available_upleft) block_available_upleft = block_available_upleft && (refFrArr[pic_block_y-1][pic_block_x-1 ]!=-1); rFrameUR = block_available_upright ? refFrArr[pic_block_y-1][pic_block_x+blockshape_x/4] : block_available_upleft ? refFrArr[pic_block_y-1][pic_block_x-1] : -1; /* Prediction if only one of the neighbors uses the reference frame * we are checking */ if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame) mvPredType = MVPRED_L; else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame) mvPredType = MVPRED_U; else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame) mvPredType = MVPRED_UR; // Directional predictions else if(blockshape_x == 8 && blockshape_y == 16) { if(mb_x == 0) { if(rFrameL == ref_frame) mvPredType = MVPRED_L; } else { if(rFrameUR == ref_frame) mvPredType = MVPRED_UR; } } else if(blockshape_x == 16 && blockshape_y == 8) { if(mb_y == 0) { if(rFrameU == ref_frame) mvPredType = MVPRED_U; } else { if(rFrameL == ref_frame) mvPredType = MVPRED_L; } } //#define MIN(a,b,c) (ab?a>c?a:c:b>c?b:c)//WJP FOR MV prediction 050320 a_b=a_c=b_c=0; //printf("%d \n" , pgImage->current_mb_nr); for (hv=0; hv < 2; hv++) { //mv_a = block_available_left ? tmp_mv[4+pic_block_x-1 ][pic_block_y ][hv] : 0; mv_a = block_available_left ? tmp_mv[4+pic_block_x-1][pic_block_y + (blockshape_y/4) -1 ][hv]: 0; mv_b = block_available_up ? tmp_mv[4+pic_block_x ][pic_block_y-1][hv] : 0; mv_d = block_available_upleft ? tmp_mv[4+pic_block_x-1 ][pic_block_y-1][hv] : 0; mv_c = block_available_upright ? tmp_mv[4+pic_block_x+blockshape_x/4][pic_block_y-1][hv] : mv_d; //qhg a[hv] = mv_a; b[hv] = mv_b; c[hv] = mv_c; a_b+= abs(mv_a-mv_b); a_c+= abs(mv_a-mv_c); b_c+= abs(mv_b-mv_c); switch (mvPredType) { case MVPRED_MEDIAN: /*WJP FOR MV prediction 050320 if(!(block_available_upleft || block_available_up || block_available_upright)) pred_vec[hv] = mv_a; else if(hv==1) { ABC = MIN(a_b,a_c,b_c); if(ABC==a_b) { if(ABC==a_c) { pred_vec[0] = a[0]; pred_vec[1] = a[1]; } else if(ABC==b_c) { pred_vec[0] = b[0]; pred_vec[1] = b[1]; } else { pred_vec[0] = (a[0]+b[0]+1)>>1; pred_vec[1] = (a[1]+b[1]+1)>>1; } } else if(ABC==a_c) { if(ABC==b_c) { pred_vec[0] = c[0]; pred_vec[1] = c[1]; } else { pred_vec[0] = (a[0]+c[0]+1)>>1; pred_vec[1] = (a[1]+c[1]+1)>>1; } } else { pred_vec[0] = (b[0]+c[0]+1)>>1; pred_vec[1] = (b[1]+c[1]+1)>>1; } } */ if(hv == 1) { ABC = MAX(a_b,a_c,b_c); if(ABC == a_b) { pred_vec[0] = c[0]; pred_vec[1] = c[1]; } else if(ABC == b_c) { pred_vec[0] = a[0]; pred_vec[1] = a[1]; } else { pred_vec[0] = b[0]; pred_vec[1] = b[1]; } } //WJP END break; case MVPRED_L: pred_vec[hv] = mv_a; break; case MVPRED_U: pred_vec[hv] = mv_b; break; case MVPRED_UR: pred_vec[hv] = mv_c; break; default: break; } } if ( pgImage->half_pixel_mv_flag == 0) { *pmv_x = pred_vec[0]; *pmv_y = pred_vec[1]; } else { *pmv_x = pred_vec[0] << 1; *pmv_y = pred_vec[1] << 1; } } /* ************************************************************************* * Function: * Input: * Output: * Return: * Attention: ************************************************************************* */ void FindSkipMVandRef() { int i, j, iii, jjj, pmv[2]; int ***tmp_mv = pgImage->mv; int mb_available_up = (pgImage->mb_y == 0) ? 0 : (pgcurrMB->slice_nr == mb_data[pgImage->current_mb_nr-pgImage->width/16].slice_nr); int mb_available_left = (pgImage->mb_x == 0) ? 0 : (pgcurrMB->slice_nr == mb_data[pgImage->current_mb_nr-1].slice_nr); int zeroMotionAbove = !mb_available_up ? 1 : refFrArr[pgImage->block4_y-1][pgImage->block4_x] == 0 && tmp_mv[4+pgImage->block4_x ][pgImage->block4_y-1][0] == 0 && tmp_mv[4+pgImage->block4_x ][pgImage->block4_y-1][1] == 0 ? 1 : 0; //int zeroMotionLeft = !mb_available_left? 1 : refFrArr[pgImage->block4_y][pgImage->block4_x-1] == 0 && tmp_mv[4+pgImage->block4_x-1][pgImage->block4_y][0] == 0 && tmp_mv[4+pgImage->block4_x-1][pgImage->block4_y][1] == 0 ? 1 : 0; //MZ 050403 int zeroMotionLeft = !mb_available_left? 1 : refFrArr[pgImage->block4_y+4-1][pgImage->block4_x-1] == 0 && tmp_mv[4+pgImage->block4_x-1][pgImage->block4_y+4-1][0] == 0 && tmp_mv[4+pgImage->block4_x-1][pgImage->block4_y+4-1][1] == 0 ? 1 : 0; int img_block_y; pgcurrMB->cbp = 0; for (i=0;i cof[i][j][iii][jjj]=0; } for (j=4;j<6;j++) { // reset chroma coeffs for (i=0;i<4;i++) for (iii=0;iii<4;iii++) for (jjj=0;jjj<4;jjj++) pgImage->cof[i][j][iii][jjj]=0; } img_block_y = pgImage->block4_y; if (zeroMotionAbove || zeroMotionLeft) { for(i=0;i<4;i++) for(j=0;j<4;j++) { pgImage->mv[pgImage->block4_x+i+BLOCK_SIZE][pgImage->block4_y+j][0] = 0; pgImage->mv[pgImage->block4_x+i+BLOCK_SIZE][pgImage->block4_y+j][1] = 0; } } else { SetMotionVectorPredictor (pmv, pmv+1, 0, 0, 0, 16, 16, 0);//Lou 1016 for(i=0;i<4;i++) for(j=0;j<4;j++) { pgImage->mv[pgImage->block4_x+i+BLOCK_SIZE][img_block_y+j][0] = pmv[0]; pgImage->mv[pgImage->block4_x+i+BLOCK_SIZE][img_block_y+j][1] = pmv[1]; } } for (j=0; j<4;j++) for (i=0; i<4;i++) { refFrArr[pgImage->block4_y+j][pgImage->block4_x+i] = 0; } }