📄 recon.c
字号:
/************************************************************************ * * 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 + -