pred.cpp
上传用户:panstart
上传日期:2022-04-12
资源大小:199k
文件大小:12k
源码类别:

IP电话/视频会议

开发平台:

C++ Builder

  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. //
  4. //    Project     : VideoNet version 1.1.
  5. //    Description : Peer to Peer Video Conferencing over the LAN.
  6. //   Author      : Nagareshwar Y Talekar ( nsry2002@yahoo.co.in)
  7. //    Date        : 15-6-2004.
  8. //
  9. //    I have converted origional fast h.263 encoder library from C to C++ 
  10. //   so that it can be integrated into any windows application easily.
  11. //   I have removed some of unnecessary codes/files from the
  12. //   fast h263 library.Also moved definitions and declarations
  13. //   in their proper .h and .cpp files.
  14. //
  15. //    File description : 
  16. //    Name    : pred.cpp
  17. //
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. /*************************************************  * libr263: fast H.263 encoder library  *  * Copyright (C) 1996, Roalt Aalmoes, Twente University  * SPA multimedia group  *  * Based on Telenor TMN 1.6 encoder (Copyright (C) 1995, Telenor R&D)  * created by Karl Lillevold   *  * Author encoder: Roalt Aalmoes, <aalmoes@huygens.nl>  *   * Date: 31-07-96  **************************************************/ #include "pred.h"
  21. #include "mot_est.h"
  22. MB_Structure *Predict_P(unsigned int *curr_image, unsigned int *prev_image, unsigned int *prev_ipol, int x, int y,  MotionVector *MV_ptr) {   int m,n;   unsigned int curr[16][16];   int pred[16][16];   MotionVector *fr0;   int dx, dy;   int xmb, ymb;   MB_Structure *pred_error;   pred_error = (MB_Structure *)malloc(sizeof(MB_Structure));        xmb = x/MB_SIZE;   ymb = y/MB_SIZE;   fr0 = MV_ptr + ymb*Global::mbc + xmb;   /* Find MB in current image */ #ifdef PRINT_DEBUG   fprintf(debugf,"FindMB(%d,%d,%p,%p)n",x,y,curr_image->Y,curr); #endif   
  23.   FindMB(x, y, curr_image,curr);   /* Find prediction based on half pel MV */   FindPred(x, y, fr0, prev_ipol, &pred[0][0]);   /* Do the actual prediction */   if (fr0->Mode == MODE_INTER) {     for (n = 0; n < MB_SIZE; n++)       for (m = 0; m < MB_SIZE; m++)  pred_error->lum[n][m] = (int)(curr[n][m] - pred[n][m]);     dx = 2*fr0->x + fr0->x_half;     dy = 2*fr0->y + fr0->y_half;     dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 );     dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 ); #ifdef PRINTDEBUG     fprintf(debugf,"DoPredChrom_P(%d,%d,%d,%d,%p,%p,%p)n",x, y, dx, dy, curr_image, prev_image, pred_error); #endif      DoPredChrom_P(x, y, dx, dy, curr_image, prev_image, pred_error);   }   else     fprintf(stderr,"Illegal Mode in Predict_P (pred.c)n");   return pred_error; } void DoPredChrom_P(int x_curr, int y_curr, int dx, int dy,    unsigned int *curr, unsigned int *prev,     MB_Structure *pred_error) {   int m,n;   int x, y, ofx, ofy, pel, lx;   int xint, yint;   int xh, yh;   lx = Global::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; /* prev+Global::vskip does not work directly... */ pel=*(prev+Global::vskip + ofx    + (ofy   )*lx); pred_error->Cr[n][m] =    (int)(*(curr+Global::vskip + x+m + (y+n)*Global::cpels) - pel); pel=*(prev+Global::uskip + ofx    + (ofy   )*lx); pred_error->Cb[n][m] =    (int)(*(curr + Global::uskip + x+m + (y+n)*Global::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+Global::vskip + ofx    + (ofy   )*lx)+      *(prev+Global::vskip + ofx    + (ofy+yh)*lx) + 1)>>1; pred_error->Cr[n][m] =    (int)(*(curr+Global::vskip + x+m + (y+n)*Global::cpels) - pel); pel=(*(prev+Global::uskip + ofx    + (ofy   )*lx)+      *(prev+Global::uskip + ofx    + (ofy+yh)*lx) + 1)>>1; pred_error->Cb[n][m] =    (int)(*( curr+Global::uskip + x+m + (y+n)*Global::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+Global::vskip+ofx    + (ofy   )*lx)+      *(prev+Global::vskip+ofx+xh + (ofy   )*lx) + 1)>>1; pred_error->Cr[n][m] =    (int)(*(curr+Global::vskip + x+m + (y+n)*Global::cpels) - pel); pel=(*(prev+Global::uskip+ofx    + (ofy   )*lx)+      *(prev+Global::uskip+ofx+xh + (ofy   )*lx) + 1)>>1; pred_error->Cb[n][m] =    (int)( *( curr+Global::uskip + x+m + (y+n)*Global::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+Global::vskip+ofx    + (ofy   )*lx)+      *(prev+Global::vskip+ofx+xh + (ofy   )*lx)+      *(prev+Global::vskip+ofx    + (ofy+yh)*lx)+      *(prev+Global::vskip+ofx+xh + (ofy+yh)*lx)+      2)>>2; pred_error->Cr[n][m] =    (int)(*(curr+Global::vskip + x+m + (y+n)*Global::cpels) - pel); pel=(*(prev+Global::uskip+ofx    + (ofy   )*lx)+      *(prev+Global::uskip+ofx+xh + (ofy   )*lx)+      *(prev+Global::uskip+ofx    + (ofy+yh)*lx)+      *(prev+Global::uskip+ofx+xh + (ofy+yh)*lx)+      2)>>2; pred_error->Cb[n][m] =    (int)(*(curr+Global::uskip + x+m + (y+n)*Global::cpels) - pel);              }     }   }   return; } void FindPred(int x, int y, MotionVector *fr, unsigned int *prev,        int *pred) {   int n;   int new_x, new_y;   int *prev_ptr;   new_x = 2*(x + fr->x) + fr->x_half;   new_y = 2*(y + fr->y) + fr->y_half;   prev_ptr =  (int *) prev + 2*new_y*Global::pels + new_x;   /* Fill pred. data */   for (n = 0; n < 16; n++) {     /* Interpolated data -> too bad it can't be done in longs... */       *(pred++) = *(prev_ptr);       prev_ptr += 2;        *(pred++) = *(prev_ptr);       prev_ptr += 2;        *(pred++) = *(prev_ptr);       prev_ptr += 2;        *(pred++) = *(prev_ptr);       prev_ptr += 2;        *(pred++) = *(prev_ptr);       prev_ptr += 2;        *(pred++) = *(prev_ptr);       prev_ptr += 2;        *(pred++) = *(prev_ptr);       prev_ptr += 2;        *(pred++) = *(prev_ptr);       prev_ptr += 2;        *(pred++) = *(prev_ptr);       prev_ptr += 2;        *(pred++) = *(prev_ptr);       prev_ptr += 2;        *(pred++) = *(prev_ptr);       prev_ptr += 2;        *(pred++) = *(prev_ptr);       prev_ptr += 2;        *(pred++) = *(prev_ptr);       prev_ptr += 2;        *(pred++) = *(prev_ptr);       prev_ptr += 2;        *(pred++) = *(prev_ptr);       prev_ptr += 2;        *(pred++) = *(prev_ptr);       prev_ptr += Global::pels*4 - 30;   }   return; } MB_Structure *MB_Recon_P(unsigned int *prev_image, unsigned int *prev_ipol,  MB_Structure *diff, int x_curr, int y_curr,   MotionVector *MV_ptr) {   MB_Structure *recon_data = (MB_Structure *)malloc(sizeof(MB_Structure));   MotionVector *fr0;   int dx, dy;   fr0 = MV_ptr + (y_curr/MB_SIZE)*Global::mbc + (x_curr/MB_SIZE);   if (fr0->Mode == MODE_INTER) {       /* Inter 16x16 */     ReconLumBlock_P(x_curr,y_curr,fr0,prev_ipol,&diff->lum[0][0]);          dx = 2*fr0->x + fr0->x_half;     dy = 2*fr0->y + fr0->y_half;     dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 );     dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 );     ReconChromBlock_P(x_curr, y_curr, dx, dy, prev_image, diff);   }   memcpy(recon_data, diff, sizeof(MB_Structure));   return recon_data; } void ReconLumBlock_P(int x, int y, MotionVector *fr,       unsigned int *prev, int *data) {   int m, n;   int x1, y1;   int *data_ptr = data;   unsigned int *prev_ptr;   x1 = 2*(x + fr->x) + fr->x_half;   y1 = 2*(y + fr->y) + fr->y_half;      prev_ptr = prev + x1 + y1*2*Global::pels;   for (n = 0; n < 16; n++) {     for (m = 0; m < 16; m++) {       *data_ptr++ += (int)(*prev_ptr);       prev_ptr += 2;     }     prev_ptr += 2*2*Global::pels - 32;   }   return; } void ReconChromBlock_P(int x_curr, int y_curr, int dx, int dy,        unsigned int *prev, MB_Structure *data) {   int m,n;   int x, y, ofx, ofy, pel,lx;   int xint, yint;   int xh, yh;   lx = Global::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+Global::vskip+ ofx    + (ofy   )*lx); data->Cr[n][m] += pel; pel=*(prev+Global::uskip + ofx    + (ofy   )*lx); data->Cb[n][m] += 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+Global::vskip+ ofx    + (ofy   )*lx)+      *(prev+Global::vskip+ ofx    + (ofy+yh)*lx) + 1)>>1; data->Cr[n][m] += pel; pel=(*(prev+Global::uskip+ofx    + (ofy   )*lx)+      *(prev+Global::uskip+ofx    + (ofy+yh)*lx) + 1)>>1; data->Cb[n][m] += 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+Global::vskip+ofx    + (ofy   )*lx)+      *(prev+Global::vskip+ofx+xh + (ofy   )*lx) + 1)>>1; data->Cr[n][m] += pel; pel=(*(prev+Global::uskip+ofx    + (ofy   )*lx)+      *(prev+Global::uskip+ofx+xh + (ofy   )*lx) + 1)>>1; data->Cb[n][m] += 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+Global::vskip+ofx    + (ofy   )*lx)+      *(prev+Global::vskip+ofx+xh + (ofy   )*lx)+      *(prev+Global::vskip+ofx    + (ofy+yh)*lx)+      *(prev+Global::vskip+ofx+xh + (ofy+yh)*lx)+      2)>>2; data->Cr[n][m] += pel; pel=(*(prev+Global::uskip+ofx    + (ofy   )*lx)+      *(prev+Global::uskip+ofx+xh + (ofy   )*lx)+      *(prev+Global::uskip+ofx    + (ofy+yh)*lx)+      *(prev+Global::uskip+ofx+xh + (ofy+yh)*lx)+      2)>>2; data->Cb[n][m] += pel;              }     }   }   return; } void FindChromBlock_P(int x_curr, int y_curr, int dx, int dy,       unsigned int *prev, MB_Structure *data) {   int m,n;   int x, y, ofx, ofy, pel,lx;   int xint, yint;   int xh, yh;   lx = Global::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+Global::vskip+ofx    + (ofy   )*lx); data->Cr[n][m] = pel; pel=*(prev+Global::uskip+ofx    + (ofy   )*lx); data->Cb[n][m] = 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+Global::vskip+ofx    + (ofy   )*lx)+      *(prev+Global::vskip+ofx    + (ofy+yh)*lx) + 1)>>1; data->Cr[n][m] = pel; pel=(*(prev+Global::uskip+ofx    + (ofy   )*lx)+      *(prev+Global::uskip+ofx    + (ofy+yh)*lx) + 1)>>1; data->Cb[n][m] = 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+Global::vskip+ofx    + (ofy   )*lx)+      *(prev+Global::vskip+ofx+xh + (ofy   )*lx) + 1)>>1; data->Cr[n][m] = pel; pel=(*(prev+Global::uskip+ofx    + (ofy   )*lx)+      *(prev+Global::uskip+ofx+xh + (ofy   )*lx) + 1)>>1; data->Cb[n][m] = 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+Global::vskip+ofx    + (ofy   )*lx)+      *(prev+Global::vskip+ofx+xh + (ofy   )*lx)+      *(prev+Global::vskip+ofx    + (ofy+yh)*lx)+      *(prev+Global::vskip+ofx+xh + (ofy+yh)*lx)+      2)>>2; data->Cr[n][m] = pel; pel=(*(prev+Global::uskip+ofx    + (ofy   )*lx)+      *(prev+Global::uskip+ofx+xh + (ofy   )*lx)+      *(prev+Global::uskip+ofx    + (ofy+yh)*lx)+      *(prev+Global::uskip+ofx+xh + (ofy+yh)*lx)+      2)>>2; data->Cb[n][m] = pel;              }     }   }   return; } int ChooseMode(unsigned int *curr, int x_pos, int y_pos, int min_SAD)
  24. {
  25.   int i,j;
  26.   int MB_mean = 0, A = 0;   int y_off;   for (j = 0; j < MB_SIZE; j++) {     y_off = (y_pos + j) * Global::pels;     for (i = 0; i < MB_SIZE; i++) {       MB_mean += *(curr + x_pos + i + y_off);     }   }   MB_mean /= (MB_SIZE*MB_SIZE);   for (j = 0; j < MB_SIZE; j++) {     y_off = (y_pos + j) * Global::pels;     for (i = 0; i < MB_SIZE; i++) {       A += abs( *(curr + x_pos + i + y_off) - MB_mean );     }   }   if (A < (min_SAD - 500))      return MODE_INTRA;   else     return MODE_INTER; }