📄 mot_est.c
字号:
/************************************************************************ * * mot_est.c, part of tmn (TMN encoder) * * Copyright (C) 1997 University of BC, Canada * * Contacts: * Michael Gallant <mikeg@ee.ubc.ca> * Guy Cote <guyc@ee.ubc.ca> * Berna Erol <bernae@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 * * 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 * ************************************************************************//* 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. * */#include "sim.h"/********************************************************************** * * Name: MotionEstimatePicture * Description: Finds integer and half pel motion estimation * and chooses 8x8 or 16x16 * * Input: current image, previous image, interpolated * reconstructed previous image, seek_dist, * motion vector array * Returns: * Side effects: Allocates memory for MV structure * * Date: 950209 Author: Karl.Lillevold@nta.no * ***********************************************************************/void MotionEstimatePicture( unsigned char *curr, unsigned char *prev, unsigned char *next, unsigned char *prev_ipol, unsigned char *next_ipol, int seek_dist, MotionVector *MV[7][MBR+1][MBC+2], int gobsync, int estimation_type) { int i,j,k; int pmv0,pmv0b,pmv1,pmv1b,xoff,yoff, xoffb, yoffb; int curr_mb[16][16]; int sad8 = INT_MAX, sad16, sad16b, sad0, sad0b; int newgob; MotionVector *f0,*f1,*f2,*f3,*f4,*fBack; /* Do motion estimation and store result in array */ for ( j = 0; j < lines/MB_SIZE; j++) { newgob = 0; if (gobsync && j%gobsync == 0) { newgob = 1; } for ( i = 0; i < pels/MB_SIZE; i++) { /* Integer pel search */ f0 = MV[0][j+1][i+1]; f1 = MV[1][j+1][i+1]; f2 = MV[2][j+1][i+1]; f3 = MV[3][j+1][i+1]; f4 = MV[4][j+1][i+1]; fBack = MV[5][j+1][i+1]; /* P-picture or PB-picture prediction. */ if (B_PICTURE_ESTIMATION != estimation_type) { /* Here the PMV's are found using integer motion vectors for * the forward prediction only. */ FindPMV(MV,i+1,j+1,&pmv0,&pmv1,0,newgob,0); if (long_vectors && (estimation_type != PB_PICTURE_ESTIMATION) ) { /* Always divisable by two. */ xoff = pmv0/2; yoff = pmv1/2; } else { xoff = yoff = 0; } MotionEstimation( curr, prev, i*MB_SIZE, j*MB_SIZE, xoff, yoff, seek_dist, MV, &sad0,estimation_type, 0,pmv0,pmv1); sad16 = f0->min_error; if (use_4mv) { sad8 = f1->min_error + f2->min_error + f3->min_error + f4->min_error; } f0->Mode = ChooseMode(curr,i*MB_SIZE,j*MB_SIZE, mmin(sad8,sad16)); if(intra_mb_refresh && intra_refresh[j+1][i+1]>=intra_mb_refresh) { f0->Mode = MODE_INTRA; } /* Half pel search. Forward */ if (f0->Mode != MODE_INTRA) { FindMB(i*MB_SIZE,j*MB_SIZE ,curr, curr_mb); FindHalfPel(i*MB_SIZE,j*MB_SIZE,f0, prev_ipol, &curr_mb[0][0],16,0); sad16 = f0->min_error; if (use_4mv) { FindHalfPel(i*MB_SIZE,j*MB_SIZE,f1, prev_ipol, &curr_mb[0][0],8,0); FindHalfPel(i*MB_SIZE,j*MB_SIZE,f2, prev_ipol, &curr_mb[0][8],8,1); FindHalfPel(i*MB_SIZE,j*MB_SIZE,f3, prev_ipol, &curr_mb[8][0],8,2); FindHalfPel(i*MB_SIZE,j*MB_SIZE,f4, prev_ipol, &curr_mb[8][8],8,3); sad8 = f1->min_error +f2->min_error +f3->min_error +f4->min_error; sad8 += PREF_16_VEC; /* Choose Zero Vector, 8x8 or 16x16 vectors */ if (sad0 < sad8 && sad0 < sad16) { f0->x = f0->y = 0; f0->x_half = f0->y_half = 0; } else { if (sad8 < sad16) f0->Mode = MODE_INTER4V; } } else { /* Choose Zero Vector or 16x16 vectors */ if (sad0 < sad16) { f0->x = f0->y = 0; f0->x_half = f0->y_half = 0; } } } else { for (k = 0; k < 5; k++) { ZeroVec(MV[k][j+1][i+1]); } } } /* B-Picture. */ else { /* Here the PMV's are found using integer motion vectors * for both backward and forward prediction. */ FindPMV(MV,i+1,j+1,&pmv0,&pmv1,0,newgob,0); FindPMV(MV,i+1,j+1,&pmv0b,&pmv1b,5,newgob,0); if (long_vectors && (estimation_type != PB_PICTURE_ESTIMATION) ) { /* Always divisable by two. */ xoff = pmv0/2; yoff = pmv1/2; xoffb = pmv0b/2; yoffb = pmv1b/2; } else { xoff = yoff = xoffb = yoffb = 0; } /* Forward prediction. */ MotionEstimation( curr, prev, i*MB_SIZE, j*MB_SIZE, xoff, yoff, seek_dist, MV, &sad0, estimation_type, 0, pmv0, pmv1); sad16 = f0->min_error; /* Backward prediction. */ MotionEstimation( curr, next, i*MB_SIZE, j*MB_SIZE, xoffb, yoffb, seek_dist, MV, &sad0b, estimation_type, 1, pmv0b, pmv1b); sad16b = fBack->min_error; FindMB(i*MB_SIZE, j*MB_SIZE, curr, curr_mb); FindHalfPel(i*MB_SIZE,j*MB_SIZE, f0, prev_ipol, &curr_mb[0][0],16,0); sad16 = f0->min_error; /* Choose Zero Vector or 16x16 vectors */ if (sad0 < sad16) { f0->x = f0->y = 0; f0->x_half = f0->y_half = 0; } FindHalfPel(i*MB_SIZE,j*MB_SIZE, fBack, next_ipol, &curr_mb[0][0],16,0); sad16b = fBack->min_error; /* Choose Zero Vector or 16x16 vectors */ if (sad0b < sad16b) { fBack->x = fBack->y = 0; fBack->x_half = fBack->y_half = 0; } } } }#ifdef PRINTMV fprintf(stdout,"Motion estimation\n"); fprintf(stdout,"16x16 vectors:\n"); for ( j = 0; j < lines/MB_SIZE; j++) { for ( i = 0; i < pels/MB_SIZE; i++) { /* B picture. */ if (B_PICTURE_ESTIMATION == estimation_type) { /* Forward MV. */ fprintf(stdout," forward (B): %3d%3d", 2*MV[0][j+1][i+1]->x + MV[0][j+1][i+1]->x_half, 2*MV[0][j+1][i+1]->y + MV[0][j+1][i+1]->y_half); fprintf(stdout," backward (B): %3d%3d", 2*MV[5][j+1][i+1]->x + MV[5][j+1][i+1]->x_half, 2*MV[5][j+1][i+1]->y + MV[5][j+1][i+1]->y_half); } /* P picture. */ else if (MV[0][j+1][i+1]->Mode != MODE_INTRA) { fprintf(stdout," %3d%3d", 2*MV[0][j+1][i+1]->x + MV[0][j+1][i+1]->x_half, 2*MV[0][j+1][i+1]->y + MV[0][j+1][i+1]->y_half); } else { fprintf(stdout," . . "); } } fprintf(stdout,"\n"); } if (use_4mv) { fprintf(stdout,"8x8 vectors:\n"); for (k = 1; k < 5; k++) { fprintf(stdout,"Block: %d\n", k-1); for ( j = 0; j < lines/MB_SIZE; j++) { for ( i = 0; i < pels/MB_SIZE; i++) { if (MV[0][j+1][i+1]->Mode != MODE_INTRA) fprintf(stdout," %3d%3d", 2*MV[k][j+1][i+1]->x + MV[k][j+1][i+1]->x_half, 2*MV[k][j+1][i+1]->y + MV[k][j+1][i+1]->y_half); else fprintf(stdout," . . "); } fprintf(stdout,"\n"); } } }#endif return;}/********************************************************************** * * Name: MotionEstimation * Description: Estimate all motion vectors for one MB * * Input: pointers to current and reference (previous) * image, pointers to current slice and * current MB * Returns: * Side effects: motion vector information in MB changed * * Date: 930118 Author: Karl.Lillevold@nta.no * 940203 Mod. to use PGB's faster search * 941208 Mod to use spiral search from mpeg2encode * 951001 Mod for extended motion vector range * 970526 Fast motion estimation by mikeg@ee.ubc.ca * 971119 Added new motion vector range for RVLC * modified by guyc@ee.ubc.ca. * 980701 Fixed bugs with various MV extrapolation ranges * and incorporated forward and backward ME into * same routine by mikeg@ee.ubc.ca * ***********************************************************************/void MotionEstimation (unsigned char *curr, unsigned char *reference, int x_curr, int y_curr, int xoff, int yoff, int seek_dist, MotionVector * MV[7][MBR + 1][MBC + 2], int *SAD_0, int estimation_type, int backward_pred, int pmv0, int pmv1){ int Min_FRAME[7]; MotionVector MV_FRAME[7]; unsigned char *act_block, *aa, *ii; unsigned char *search_area, *adv_search_area = NULL, *zero_area = NULL; int sxy, i, k, j, l; int xlim, ylim; int ihigh, ilow, jhigh, jlow, h_length, v_length; int adv_ihigh, adv_ilow, adv_jhigh, adv_jlow, adv_h_length, adv_v_length; int xmax, ymax, block, sad, lx; int adv_x_curr, adv_y_curr, xvec, yvec;#ifndef FULLSEARCH static htp[4] = {-1, 0, 1, 0}; static vtp[4] = {0, 1, 0, -1}; int j_min_now, i_min_now, i_min_next, j_min_next, sad_layr; int distortion_0, distortion_1, distortion_2; int m;#endif xmax = pels; ymax = lines; xlim = ylim = seek_dist; /* There are 8 scenarios for motion vector extrapolaton range * and search window size combinations * 1. No optional modes * 2. Annex F (H.263 or H.263+) only. * 3. Annex D (H.263) only. * 4. Annex D (H.263) + Annex F * 5. Annex D (H.263+, uui = '01' i.e. unlimited unrestricted MVs) only * 6. Annex D (H.263+, uui = '01' i.e. unlimited unrestricted MVs) + Annex F * 7. Annex D (H.263+, uui = '1' i.e. MVs based on picture size) only
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -