⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pred.c

📁 基于H.263的图像压缩编解码的C源码
💻 C
📖 第 1 页 / 共 3 页
字号:
  yvec = (bdy == 0 ? (TRB-TRD) *  mvy / TRD : TRB * mvy / TRD + bdy - mvy);

  /* Luma */

  FindBiDirLimits(xvec,&xstart,&xstop,nh);
  FindBiDirLimits(yvec,&ystart,&ystop,nv);

  BiDirPredBlock(xstart,xstop,ystart,ystop,xvec,yvec, recon_P,pred,16);

  return;
}

/**********************************************************************
 *
 *	Name:	       FindBiDirChrPredPB
 *	Description:   Finds the bi-dir. chroma prediction in PB-frame 
 *                     prediction
 *	
 *	Input:	       pointer to future recon. data, current positon,
 *                     MV structure and pred. structure to fill
 *
 ***********************************************************************/

void FindBiDirChrPredPB(MB_Structure *recon_P, int dx, int dy, 
        MB_Structure *pred)
{
  int xstart,xstop,ystart,ystop;

  FindBiDirChromaLimits(dx,&xstart,&xstop);
  FindBiDirChromaLimits(dy,&ystart,&ystop);

  BiDirPredBlock(xstart,xstop,ystart,ystop,dx,dy,
         &recon_P->Cb[0][0], &pred->Cb[0][0],8);
  BiDirPredBlock(xstart,xstop,ystart,ystop,dx,dy,
         &recon_P->Cr[0][0], &pred->Cr[0][0],8);

  return;
}

void FindBiDirLimits(int vec, int *start, int *stop, int nhv)
{

  /* limits taken from C loop in section G5 in H.263 */
  *start = mmax(0,(-vec+1)/2 - nhv*8);
  *stop = mmin(7,15-(vec+1)/2 - nhv*8);

  return;

}
  
void FindBiDirChromaLimits(int vec, int *start, int *stop)
{

  /* limits taken from C loop in section G5 in H.263 */
  *start = mmax(0,(-vec+1)/2);
  *stop = mmin(7,7-(vec+1)/2);

  return;
}


void BiDirPredBlock(int xstart, int xstop, int ystart, int ystop,
            int xvec, int yvec, int *recon, int *pred, int bl)
{
  int i,j,pel;
  int xint, yint;
  int xh, yh;

  xint = xvec>>1;
  xh = xvec - 2*xint;
  yint = yvec>>1;
  yh = yvec - 2*yint;

  if (!xh && !yh) {
    for (j = ystart; j <= ystop; j++) {
      for (i = xstart; i <= xstop; i++) {
        pel = *(recon +(j+yint)*bl + i+xint);
        *(pred + j*bl + i) = (mmin(255,mmax(0,pel)) + *(pred + j*bl + i))>>1;
      }
    }
  }
  else if (!xh && yh) {
    for (j = ystart; j <= ystop; j++) {
      for (i = xstart; i <= xstop; i++) {
        pel = (*(recon +(j+yint)*bl + i+xint)       + 
               *(recon +(j+yint+yh)*bl + i+xint) + 1)>>1;
        *(pred + j*bl + i) = (pel + *(pred + j*bl + i))>>1;
      }
    }
  }
  else if (xh && !yh) {
    for (j = ystart; j <= ystop; j++) {
      for (i = xstart; i <= xstop; i++) {
        pel = (*(recon +(j+yint)*bl + i+xint)       + 
               *(recon +(j+yint)*bl + i+xint+xh) + 1)>>1;
        *(pred + j*bl + i) = (pel + *(pred + j*bl + i))>>1;
      }
    }
  }
  else { /* xh && yh */
    for (j = ystart; j <= ystop; j++) {
      for (i = xstart; i <= xstop; i++) {
        pel = (*(recon +(j+yint)*bl + i+xint)       + 
               *(recon +(j+yint+yh)*bl + i+xint) + 
               *(recon +(j+yint)*bl + i+xint+xh) + 
               *(recon +(j+yint+yh)*bl + i+xint+xh)+2)>>2;
        *(pred + j*bl + i) = (pel + *(pred + j*bl + i))>>1;
      }
    }
  }
  return;
}

/**********************************************************************
 *
 *      Name:           DoPredChrom_P
 *	Description:	Does the chrominance prediction for P-frames
 *	
 *      Input:          motionvectors for each field,
 *                      current position in image,
 *                      pointers to current and previos image,
 *                      pointer to pred_error array,
 *                      (int) field: 1 if field coding
 *        
 *	Side effects:	fills chrom-array in pred_error structure
 *
 ***********************************************************************/

void DoPredChrom_P(int x_curr, int y_curr, int dx, int dy,
           PictImage *curr, PictImage *prev, 
           MB_Structure *pred_error)
{
  int m,n;

  int x, y, ofx, ofy, pel, lx;
  int xint, yint;
  int xh, yh;

  lx = (mv_outside_frame ? pels/2 + (long_vectors?32:16) : pels/2);

  x = x_curr>>1;
  y = y_curr>>1;

  xint = dx>>1;
  xh = dx & 1;
  yint = dy>>1;
  yh = dy & 1;

  if (!xh && !yh) {
    for (n = 0; n < 8; n++) {
      for (m = 0; m < 8; m++) {

        ofx = x + xint + m;
        ofy = y + yint + n;
        pel=*(prev->Cr+ofx    + (ofy   )*lx);
        pred_error->Cr[n][m] = (int)(*(curr->Cr + x+m + (y+n)*cpels) - pel);

        pel=*(prev->Cb+ofx    + (ofy   )*lx);
        pred_error->Cb[n][m] = (int)(*(curr->Cb + x+m + (y+n)*cpels) - pel);
      }
    }
  }
  else if (!xh && yh) {
    for (n = 0; n < 8; n++) {
      for (m = 0; m < 8; m++) {

        ofx = x + xint + m;
        ofy = y + yint + n;
        pel=(*(prev->Cr+ofx    + (ofy   )*lx)+
             *(prev->Cr+ofx    + (ofy+yh)*lx) + 1)>>1;

        pred_error->Cr[n][m] = 
          (int)(*(curr->Cr + x+m + (y+n)*cpels) - pel);

        pel=(*(prev->Cb+ofx    + (ofy   )*lx)+
             *(prev->Cb+ofx    + (ofy+yh)*lx) + 1)>>1;

        pred_error->Cb[n][m] = 
          (int)(*(curr->Cb + x+m + (y+n)*cpels) - pel);
      
      }
    }
  }
  else if (xh && !yh) {
    for (n = 0; n < 8; n++) {
      for (m = 0; m < 8; m++) {

        ofx = x + xint + m;
        ofy = y + yint + n;
        pel=(*(prev->Cr+ofx    + (ofy   )*lx)+
             *(prev->Cr+ofx+xh + (ofy   )*lx) + 1)>>1;

        pred_error->Cr[n][m] = 
          (int)(*(curr->Cr + x+m + (y+n)*cpels) - pel);

        pel=(*(prev->Cb+ofx    + (ofy   )*lx)+
             *(prev->Cb+ofx+xh + (ofy   )*lx) + 1)>>1;

        pred_error->Cb[n][m] = 
          (int)(*(curr->Cb + x+m + (y+n)*cpels) - pel);
      
      }
    }
  }
  else { /* xh && yh */
    for (n = 0; n < 8; n++) {
      for (m = 0; m < 8; m++) {
        ofx = x + xint + m;
        ofy = y + yint + n;
        pel=(*(prev->Cr+ofx    + (ofy   )*lx)+
             *(prev->Cr+ofx+xh + (ofy   )*lx)+
             *(prev->Cr+ofx    + (ofy+yh)*lx)+
             *(prev->Cr+ofx+xh + (ofy+yh)*lx)+
             2)>>2;

        pred_error->Cr[n][m] = 
          (int)(*(curr->Cr + x+m + (y+n)*cpels) - pel);

        pel=(*(prev->Cb+ofx    + (ofy   )*lx)+
             *(prev->Cb+ofx+xh + (ofy   )*lx)+
             *(prev->Cb+ofx    + (ofy+yh)*lx)+
             *(prev->Cb+ofx+xh + (ofy+yh)*lx)+
             2)>>2;

        pred_error->Cb[n][m] = 
          (int)(*(curr->Cb + x+m + (y+n)*cpels) - pel);
      
      }
    }
  }
  return;
}

/**********************************************************************
 *
 *      Name:         FindHalfPel
 *      Description:  Find the optimal half pel prediction
 *	
 *	Input:        position, vector, array with current data
 *                    pointer to previous interpolated luminance,
 *
 *	Returns:
 *
 ***********************************************************************/


void FindHalfPel(int x, int y, MotionVector *fr, unsigned char *prev, 
         int *curr, int bs, int comp)
{
  int i, m, n;
  int half_pel;
  int start_x, start_y, stop_x, stop_y, new_x, new_y, lx;
  int min_pos;
  int AE, AE_min;
  Point search[9];

  start_x = -1;
  stop_x = 1;
  start_y = -1;
  stop_y = 1;

  new_x = x + fr->x;
  new_y = y + fr->y;

  new_x += ((comp&1)<<3);
  new_y += ((comp&2)<<2);

  lx = (mv_outside_frame ? pels + (long_vectors?64:32) : pels);

  /* Make sure that no addressing is outside the frame */
  if (!mv_outside_frame) {
    if ((new_x) <= 0) 
      start_x = 0;
    if ((new_y) <= 0) 
      start_y = 0;
    if ((new_x) >= (pels-bs)) 
      stop_x = 0;
    if ((new_y) >= (lines-bs)) 
      stop_y = 0;
  }

  search[0].x = 0;        search[0].y = 0;
  search[1].x = start_x;        search[1].y = start_y; /*   1 2 3   */
  search[2].x = 0;        search[2].y = start_y; /*   4 0 5   */
  search[3].x = stop_x;        search[3].y = start_y; /*   6 7 8   */
  search[4].x = start_x;        search[4].y = 0;
  search[5].x = stop_x;        search[5].y = 0;
  search[6].x = start_x;        search[6].y = stop_y;
  search[7].x = 0;        search[7].y = stop_y;
  search[8].x = stop_x;        search[8].y = stop_y;

  AE_min = INT_MAX;
  min_pos = 0;
  for (i = 0; i < 9; i++) {
    AE = 0;
    for (n = 0; n < bs; n++) {
      for (m = 0; m < bs; m++) {
        /* Find absolute error */
        half_pel = *(prev + 2*new_x + 2*m + search[i].x +
             (2*new_y + 2*n + search[i].y)*lx*2);
        AE += abs(half_pel - *(curr + m + n*16));
      }
    }
    /*
     * if (i == 0 && fr->x == 0 && fr->y == 0 && bs == 16) 
     * AE -= PREF_NULL_VEC;
     */
    if (AE < AE_min) {
      AE_min = AE;
      min_pos = i;
    }
  }

  /* Store optimal values */
  fr->min_error = AE_min;
  fr->x_half = search[min_pos].x;
  fr->y_half = search[min_pos].y;
        
  return;
}

/**********************************************************************
 *
 *      Name:           FindPred
 *	Description:	Find the prediction block
 *	
 *      Input:          position, vector, array for prediction
 *                      pointer to previous interpolated luminance,
 *
 *	Side effects:	fills array with prediction
 *
 ***********************************************************************/


void FindPred(int x, int y, MotionVector *fr, unsigned char *prev, 
              int *pred, int bs, int comp)
{
  int m, n;
  int new_x, new_y;
  int lx;

  lx = (mv_outside_frame ? pels + (long_vectors?64:32) : pels);

  new_x = x + fr->x;
  new_y = y + fr->y;

  new_x += ((comp&1)<<3);
  new_y += ((comp&2)<<2);


  /* Fill pred. data */
  for (n = 0; n < bs; n++) {
    for (m = 0; m < bs; m++) {
      /* Find interpolated pixel-value */
      *(pred + m + n*16) = *(prev + (new_x + m)*2 + fr->x_half +
             ((new_y + n)*2 + fr->y_half)*lx*2);
    }	
  }
  return;
}

/**********************************************************************
 *
 *      Name:           FindPredOBMC
 *	Description:	Find the OBMC prediction block
 *	
 *      Input:          position, vector, array for prediction
 *                      pointer to previous interpolated luminance,
 *
 *	Returns:
 *	Side effects:	fills array with prediction
 *
 ***********************************************************************/


void FindPredOBMC(int x, int y, MotionVector *MV[6][MBR+1][MBC+2], 
          unsigned char *prev, int *pred, int comp, int PB)
{
  int m, n;
  int pc,pt,pb,pr,pl;
  int nxc,nxt,nxb,nxr,nxl;
  int nyc,nyt,nyb,nyr,nyl;
  int xit,xib,xir,xil;
  int yit,yib,yir,yil;
  int vect,vecb,vecr,vecl;
  int c8,t8,l8,r8;
  int ti8,li8,ri8;
  int xmb, ymb, lx;
  MotionVector *fc,*ft,*fb,*fr,*fl;

  int Mc[8][8] = {
    {4,5,5,5,5,5,5,4},
    {5,5,5,5,5,5,5,5},
    {5,5,6,6,6,6,5,5},
    {5,5,6,6,6,6,5,5},
    {5,5,6,6,6,6,5,5},
    {5,5,6,6,6,6,5,5},
    {5,5,5,5,5,5,5,5},
    {4,5,5,5,5,5,5,4},
  };
  int Mt[8][8] = {
    {2,2,2,2,2,2,2,2},
    {1,1,2,2,2,2,1,1},
    {1,1,1,1,1,1,1,1},
    {1,1,1,1,1,1,1,1},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
  };
  int Mb[8][8] = {
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {1,1,1,1,1,1,1,1},
    {1,1,1,1,1,1,1,1},
    {1,1,2,2,2,2,1,1},
    {2,2,2,2,2,2,2,2},
  };
  int Mr[8][8] = {
    {0,0,0,0,1,1,1,2},
    {0,0,0,0,1,1,2,2},
    {0,0,0,0,1,1,2,2},
    {0,0,0,0,1,1,2,2},
    {0,0,0,0,1,1,2,2},
    {0,0,0,0,1,1,2,2},
    {0,0,0,0,1,1,2,2},
    {0,0,0,0,1,1,1,2},
  };
  int Ml[8][8] = {
    {2,1,1,1,0,0,0,0},
    {2,2,1,1,0,0,0,0},
    {2,2,1,1,0,0,0,0},
    {2,2,1,1,0,0,0,0},
    {2,2,1,1,0,0,0,0},
    {2,2,1,1,0,0,0,0},
    {2,2,1,1,0,0,0,0},
    {2,1,1,1,0,0,0,0},
  };

  xmb = x/MB_SIZE+1;
  ymb = y/MB_SIZE+1;

  lx = (mv_outside_frame ? pels + (long_vectors?64:32) : pels);

  c8  = (MV[0][ymb][xmb]->Mode == MODE_INTER4V ? 1 : 0);

  t8  = (MV[0][ymb-1][xmb]->Mode == MODE_INTER4V ? 1 : 0);
  ti8 = (MV[0][ymb-1][xmb]->Mode == MODE_INTRA ? 1 : 0);
  ti8 = (MV[0][ymb-1][xmb]->Mode == MODE_INTRA_Q ? 1 : ti8);

  l8  = (MV[0][ymb][xmb-1]->Mode == MODE_INTER4V ? 1 : 0);
  li8 = (MV[0][ymb][xmb-1]->Mode == MODE_INTRA ? 1 : 0);
  li8 = (MV[0][ymb][xmb-1]->Mode == MODE_INTRA_Q ? 1 : li8);
  
  r8  = (MV[0][ymb][xmb+1]->Mode == MODE_INTER4V ? 1 : 0);
  ri8 = (MV[0][ymb][xmb+1]->Mode == MODE_INTRA ? 1 : 0);
  ri8 = (MV[0][ymb][xmb+1]->Mode == MODE_INTRA_Q ? 1 : ri8);

  if (PB) {
    ti8 = li8 = ri8 = 0;
  }

  switch (comp+1) {

  case 1:
    vect = (ti8 ? (c8 ? 1 : 0) : (t8 ? 3 : 0)); 
    yit  = (ti8 ? ymb : ymb - 1); 
    xit = xmb;

    vecb = (c8 ? 3 : 0) ; yib = ymb; xib = xmb;

    vecl = (li8 ? (c8 ? 1 : 0) : (l8 ? 2 : 0)); 
    yil = ymb; 
    xil = (li8 ? xmb : xmb-1);

    vecr = (c8 ? 2 : 0) ; yir = ymb; xir = xmb;

    /* edge handling */
    if (ymb == 1) {
      yit = ymb;
      vect = (c8 ? 1 : 0);
    }
    if (xmb == 1) {
      xil = xmb;
      vecl = (c8 ? 1 : 0);
    }
    break;
  
  case 2:
    vect = (ti8 ? (c8 ? 2 : 0) : (t8 ? 4 : 0)); 
    yit = (ti8 ? ymb : ymb-1); 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -