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

📄 recon.c

📁 H.263的压缩算法
💻 C
📖 第 1 页 / 共 3 页
字号:
/************************************************************************ * *  recon.c, motion compensation routines for tmndecode (H.263 decoder) *  Copyright (C) 1995, 1996  Telenor R&D, Norway * *  Contacts: *  Robert Danielsen                  <Robert.Danielsen@nta.no> * *  Telenor Research and Development  http://www.nta.no/brukere/DVC/ *  P.O.Box 83                        tel.:   +47 63 84 84 00 *  N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76 * *  Copyright (C) 1997  University of BC, Canada *  Modified by: Michael Gallant <mikeg@ee.ubc.ca> *               Guy Cote <guyc@ee.ubc.ca> *               Berna Erol <bernae@ee.ubc.ca> * *  Contacts: *  Michael Gallant                   <mikeg@ee.ubc.ca> * *  UBC Image Processing Laboratory   http://www.ee.ubc.ca/image *  2356 Main Mall                    tel.: +1 604 822 4051 *  Vancouver BC Canada V6T1Z4        fax.: +1 604 822 5949 * ************************************************************************//* Disclaimer of Warranty *  * These software programs are available to the user without any license fee * or royalty on an "as is" basis. The University of British Columbia * disclaims any and all warranties, whether express, implied, or * statuary, including any implied warranties or merchantability or of * fitness for a particular purpose.  In no event shall the * copyright-holder be liable for any incidental, punitive, or * consequential damages of any kind whatsoever arising from the use of * these programs. *  * This disclaimer of warranty extends to the user of these programs and * user's customers, employees, agents, transferees, successors, and * assigns. *  * The University of British Columbia does not represent or warrant that the * programs furnished hereunder are free of infringement of any * third-party patents. *  * Commercial implementations of H.263, including shareware, are subject to * royalty fees to patent holders.  Many of these patents are general * enough such that they are unavoidable regardless of implementation * design. *  *//* based on mpeg2decode, (C) 1994, MPEG Software Simulation Group and * mpeg2play, (C) 1994 Stefan Eckart <stefan@lis.e-technik.tu-muenchen.de> *  */#include <stdio.h>#include <stdlib.h>#include "config.h"#include "tmndec.h"#include "global.h"/* private prototypes */static void recon_comp _ANSI_ARGS_ ((unsigned char *src, unsigned char *dst, int lx, int lx2, int w, int h, int x, int y, int dx, int dy, int flag));static void recon_comp_obmc _ANSI_ARGS_ ((unsigned char *src, unsigned char *dst, int lx, int lx2, int comp, int w, int h, int x, int y, int newgob));static void rec _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));static void recon_bidir_average _ANSI_ARGS_ ((int bx, int by));static void recc _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));static void reco _ANSI_ARGS_ ((unsigned char *s, int *d, int lx, int lx2, int addflag, int c, int xa, int xb, int ya, int yb));static void rech _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));static void rechc _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));static void recho _ANSI_ARGS_ ((unsigned char *s, int *d, int lx, int lx2, int addflag, int c, int xa, int xb, int ya, int yb));static void recv _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));static void recvc _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));static void recvo _ANSI_ARGS_ ((unsigned char *s, int *d, int lx, int lx2, int addflag, int c, int xa, int xb, int ya, int yb));static void rec4 _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));static void rec4c _ANSI_ARGS_ ((unsigned char *s, unsigned char *d, int lx, int lx2, int h));static void rec4o _ANSI_ARGS_ ((unsigned char *s, int *d, int lx, int lx2, int addflag, int c, int xa, int xb, int ya, int yb));void reconstruct (int bx, int by, int P, int bdx, int bdy, int MODB, int newgob){  int w, h, lx, lx2, dx, dy, xp, yp, comp, sum;  int x, y, mode, xvec, yvec;  unsigned char *src[3];  int store_rtype;  x = bx / 16 + 1;  y = by / 16 + 1;  lx = coded_picture_width;  if (mv_outside_frame)  {    lx2 = coded_picture_width + 64;    src[0] = edgeframe[0];    src[1] = edgeframe[1];    src[2] = edgeframe[2];  } else  {    lx2 = coded_picture_width;    src[0] = prev_I_P_frame[0];    src[1] = prev_I_P_frame[1];    src[2] = prev_I_P_frame[2];  }  mode = modemap[y][x];  if (P)  {    /* P prediction */    if (use_4mv)    {      w = 8;      h = 8;      /* Y */      /* 4 MV can be used without OBMC in        * deblocking filter mode                  */      if (overlapping_MC)      {        for (comp = 0; comp < 4; comp++)        {          xp = bx + ((comp & 1) << 3);          yp = by + ((comp & 2) << 2);          recon_comp_obmc (src[0], current_frame[0], lx, lx2, comp, w, h, xp, yp, newgob);        }      } else      {        if (mode == MODE_INTER4V || mode == MODE_INTER4V_Q)        {          for (comp = 0; comp < 4; comp++)          {            dx = MV[0][comp + 1][y][x];            dy = MV[1][comp + 1][y][x];            xp = bx + ((comp & 1) << 3);            yp = by + ((comp & 2) << 2);            recon_comp (src[0], current_frame[0], lx, lx2, w, h, xp, yp, dx, dy, 0);          }        } else        {          dx = MV[0][0][y][x];          dy = MV[1][0][y][x];          recon_comp (src[0], current_frame[0], lx, lx2, w << 1, h << 1, bx, by, dx, dy, 0);        }      }      /* Chroma */      if (mode == MODE_INTER4V || mode == MODE_INTER4V_Q)      {        sum = MV[0][1][y][x] + MV[0][2][y][x] + MV[0][3][y][x] + MV[0][4][y][x];        dx = sign (sum) * (roundtab[abs (sum) % 16] + (abs (sum) / 16) * 2);        sum = MV[1][1][y][x] + MV[1][2][y][x] + MV[1][3][y][x] + MV[1][4][y][x];        dy = sign (sum) * (roundtab[abs (sum) % 16] + (abs (sum) / 16) * 2);      } else      {        dx = MV[0][0][y][x];        dy = MV[1][0][y][x];        /* chroma rounding */        dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1);        dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1);      }      lx >>= 1;      bx >>= 1;      lx2 >>= 1;      by >>= 1;      /* Chroma */      recon_comp (src[1], current_frame[1], lx, lx2, w, h, bx, by, dx, dy, 1);      recon_comp (src[2], current_frame[2], lx, lx2, w, h, bx, by, dx, dy, 2);    } else    {                           /* normal prediction mode */      /* P prediction */      w = 16;      h = 16;      dx = MV[0][0][y][x];      dy = MV[1][0][y][x];      /* Y */      recon_comp (src[0], current_frame[0], lx, lx2, w, h, bx, by, dx, dy, 0);      lx >>= 1;      w >>= 1;      bx >>= 1;      lx2 >>= 1;      h >>= 1;      by >>= 1;      /* chroma rounding */      dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1);      dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1);      /* Chroma */      recon_comp (src[1], current_frame[1], lx, lx2, w, h, bx, by, dx, dy, 1);      recon_comp (src[2], current_frame[2], lx, lx2, w, h, bx, by, dx, dy, 2);    }  } else  {    store_rtype = rtype;    rtype = 0;    /* B forward prediction */    if (pb_frame == IM_PB_FRAMES && (MODB == PBMODE_CBPB_FRW_PRED || MODB == PBMODE_FRW_PRED))    {      w = 16;      h = 16;      dx = bdx;      dy = bdy;      /* Y */      recon_comp (src[0], bframe[0], lx, lx2, w, h, bx, by, dx, dy, 0);      lx >>= 1;      w >>= 1;      bx >>= 1;      lx2 >>= 1;      h >>= 1;      by >>= 1;      /* chroma rounding */      dx = (dx % 4 == 0 ? dx >> 1 : (dx >> 1) | 1);      dy = (dy % 4 == 0 ? dy >> 1 : (dy >> 1) | 1);      /* Chroma */      recon_comp (src[1], bframe[1], lx, lx2, w, h, bx, by, dx, dy, 1);      recon_comp (src[2], bframe[2], lx, lx2, w, h, bx, by, dx, dy, 2);    } else if (pb_frame == IM_PB_FRAMES && (MODB == PBMODE_CBPB_BCKW_PRED || MODB == PBMODE_BCKW_PRED))    {      lx2 = coded_picture_width;      src[0] = prev_I_P_frame[0];      src[1] = prev_I_P_frame[1];      src[2] = prev_I_P_frame[2];      w = 16;      h = 16;      /* Y */      recon_comp (current_frame[0], bframe[0], lx, lx2, w, h, bx, by, 0, 0, 0);      lx >>= 1;      w >>= 1;      bx >>= 1;      lx2 >>= 1;      h >>= 1;      by >>= 1;      /* Chroma */      recon_comp (current_frame[1], bframe[1], lx, lx2, w, h, bx, by, 0, 0, 1);      recon_comp (current_frame[2], bframe[2], lx, lx2, w, h, bx, by, 0, 0, 2);    } else    {      /* B bidir prediction */      if (pb_frame == IM_PB_FRAMES)      {        bdx = 0;        bdy = 0;      }      if (use_4mv && (mode == MODE_INTER4V || mode == MODE_INTER4V_Q))      {        w = 8;        h = 8;        /* Y */        xvec = yvec = 0;        for (comp = 0; comp < 4; comp++)        {          xvec += dx = (trb) * MV[0][comp + 1][y][x] / trd + bdx;          yvec += dy = (trb) * MV[1][comp + 1][y][x] / trd + bdy;          xp = bx + ((comp & 1) << 3);          yp = by + ((comp & 2) << 2);          recon_comp (src[0], bframe[0], lx, lx2, w, h, xp, yp, dx, dy, 0);        }        /* chroma rounding (table 16/H.263) */        dx = sign (xvec) * (roundtab[abs (xvec) % 16] + (abs (xvec) / 16) * 2);        dy = sign (yvec) * (roundtab[abs (yvec) % 16] + (abs (yvec) / 16) * 2);        lx >>= 1;        bx >>= 1;        lx2 >>= 1;        by >>= 1;        /* Chroma */        recon_comp (src[1], bframe[1], lx, lx2, w, h, bx, by, dx, dy, 1);        recon_comp (src[2], bframe[2], lx, lx2, w, h, bx, by, dx, dy, 2);      } else      {        /* B bidir prediction with 16x16 blocks */        w = 16;        h = 16;        dx = (trb) * MV[0][0][y][x] / trd + bdx;        dy = (trb) * MV[1][0][y][x] / trd + bdy;        /* Y */        recon_comp (src[0], bframe[0], lx, lx2, w, h, bx, by, dx, dy, 0);        lx >>= 1;        w >>= 1;        bx >>= 1;        lx2 >>= 1;        h >>= 1;        by >>= 1;        xvec = 4 * dx;        yvec = 4 * dy;        /* chroma rounding (table 16/H.263) */        dx = sign (xvec) * (roundtab[abs (xvec) % 16] + (abs (xvec) / 16) * 2);        dy = sign (yvec) * (roundtab[abs (yvec) % 16] + (abs (yvec) / 16) * 2);        /* Chroma */        recon_comp (src[1], bframe[1], lx, lx2, w, h, bx, by, dx, dy, 1);        recon_comp (src[2], bframe[2], lx, lx2, w, h, bx, by, dx, dy, 2);      }    }    rtype = store_rtype;  }}/********************************************************************** * *	Name:        reconstruct_true_B *	Description: Reconstructs true B MB  * *	Input:       position, mb prediction type *	Returns:      *	Side effects: * *	Date: 970831 Author: Michael Gallant --- mikeg@ee.ubc.ca * ***********************************************************************/void reconstruct_true_B (int bx, int by, int true_B_prediction_type){  int w, h, lx, lx2, dxf, dyf, dxb, dyb;  int x, y, mode, anchorframemode;  int bx_chroma, by_chroma;  unsigned char *src_f[3], *src_b[3];  int sumx = 0, sumy = 0, comp, dx, dy, xp, yp;  x = bx / 16 + 1;  y = by / 16 + 1;  lx = coded_picture_width;  w = 16;  h = 16;  lx2 = coded_picture_width + 64;  src_f[0] = edgeframe[0];  src_f[1] = edgeframe[1];  src_f[2] = edgeframe[2];  src_b[0] = nextedgeframe[0];  src_b[1] = nextedgeframe[1];  src_b[2] = nextedgeframe[2];  mode = modemap[y][x];  anchorframemode = anchorframemodemap[y][x];  switch (true_B_prediction_type)  {    case B_DIRECT_PREDICTION:      if (MODE_INTER4V == anchorframemode || MODE_INTER4V_Q == anchorframemode)      {        w = 8;        h = 8;            for (comp = 0; comp < 4; comp++)        {          dx = true_B_direct_mode_MV[0][comp + 1][y][x];          dy = true_B_direct_mode_MV[1][comp + 1][y][x];          dxf = (true_b_trb) * dx / trd;          dyf = (true_b_trb) * dy / trd;          dxb = (true_b_trb - trd) * dx / trd;          dyb = (true_b_trb - trd) * dy / trd;          xp = bx + ((comp & 1) << 3);          yp = by + ((comp & 2) << 2);                    /* Y */          recon_comp (src_f[0], tmp_f[0], lx, lx2, w, h, xp, yp, dxf, dyf, 0);          recon_comp (src_b[0], tmp_b[0], lx, lx2, w, h, xp, yp, dxb, dyb, 0);        }        dxf = dyf = dxb = dyb = 0;        for (comp=0; comp<4; comp++)        {          dx = true_B_direct_mode_MV[0][comp + 1][y][x];          dy = true_B_direct_mode_MV[1][comp + 1][y][x];          dxf += (true_b_trb) * dx / trd;          dyf += (true_b_trb) * dy / trd;          dxb += (true_b_trb - trd) * dx / trd;          dyb += (true_b_trb - trd) * dy / trd;        }        dxf = sign (dxf) * (roundtab[abs (dxf) % 16] + (abs (dxf) / 16) * 2);        dyf = sign (dyf) * (roundtab[abs (dyf) % 16] + (abs (dyf) / 16) * 2);        dxb = sign (dxb) * (roundtab[abs (dxb) % 16] + (abs (dxb) / 16) * 2);        dyb = sign (dyb) * (roundtab[abs (dyb) % 16] + (abs (dyb) / 16) * 2);        lx >>= 1;        bx >>= 1;        lx2 >>= 1;        by >>= 1;        /* Chroma */        recon_comp (src_f[1], tmp_f[1], lx, lx2, w, h, bx, by, dxf, dyf, 1);        recon_comp (src_f[2], tmp_f[2], lx, lx2, w, h, bx, by, dxf, dyf, 2);        recon_comp (src_b[1], tmp_b[1], lx, lx2, w, h, bx, by, dxb, dyb, 1);        recon_comp (src_b[2], tmp_b[2], lx, lx2, w, h, bx, by, dxb, dyb, 2);        bx <<= 1;        by <<= 1;      }      else      {        dxf = (true_b_trb) * true_B_direct_mode_MV[0][0][y][x] / trd;        dyf = (true_b_trb) * true_B_direct_mode_MV[1][0][y][x] / trd;        dxb = (true_b_trb - trd) * true_B_direct_mode_MV[0][0][y][x] / trd;        dyb = (true_b_trb - trd) * true_B_direct_mode_MV[1][0][y][x] / trd;        /* Y */        recon_comp (src_f[0], tmp_f[0], lx, lx2, w, h, bx, by, dxf, dyf, 0);        recon_comp (src_b[0], tmp_b[0], lx, lx2, w, h, bx, by, dxb, dyb, 0);        lx >>= 1;        w >>= 1;        bx >>= 1;        lx2 >>= 1;        h >>= 1;        by >>= 1;        /* Chroma rounding (table 16/H.263) */        dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);        dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);        dxb = (dxb % 4 == 0 ? dxb >> 1 : (dxb >> 1) | 1);        dyb = (dyb % 4 == 0 ? dyb >> 1 : (dyb >> 1) | 1);        /* Chroma */        recon_comp (src_f[1], tmp_f[1], lx, lx2, w, h, bx, by, dxf, dyf, 1);        recon_comp (src_f[2], tmp_f[2], lx, lx2, w, h, bx, by, dxf, dyf, 2);        recon_comp (src_b[1], tmp_b[1], lx, lx2, w, h, bx, by, dxb, dyb, 1);        recon_comp (src_b[2], tmp_b[2], lx, lx2, w, h, bx, by, dxb, dyb, 2);        bx <<= 1;        by <<= 1;      }        /* Average forward and backward prediction. */      recon_bidir_average (bx, by);      break;    case B_FORWARD_PREDICTION:      w = 16;      h = 16;      dxf = MV[0][0][y][x];      dyf = MV[1][0][y][x];      /* Y */      recon_comp (src_f[0], bframe[0], lx, lx2, w, h, bx, by, dxf, dyf, 0);      lx >>= 1;      w >>= 1;      bx >>= 1;      lx2 >>= 1;      h >>= 1;      by >>= 1;      /* chroma rounding */      dxf = (dxf % 4 == 0 ? dxf >> 1 : (dxf >> 1) | 1);      dyf = (dyf % 4 == 0 ? dyf >> 1 : (dyf >> 1) | 1);      /* Chroma */      recon_comp (src_f[1], bframe[1], lx, lx2, w, h, bx, by, dxf, dyf, 1);      recon_comp (src_f[2], bframe[2], lx, lx2, w, h, bx, by, dxf, dyf, 2);      break;    case B_BACKWARD_PREDICTION:      w = 16;      h = 16;      dxb = MV[0][5][y][x];

⌨️ 快捷键说明

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