📄 gmc_motion.c
字号:
/***************************************************************************This software module was originally developed by Yoshinori Suzuki (Hitachi, Ltd.) Yuichiro Nakaya (Hitachi, Ltd.)in the course of development of the MPEG-4 Video (ISO/IEC 14496-2) standard.This software module is an implementation of a part of one or more MPEG-4 Video (ISO/IEC 14496-2) tools as specified by the MPEG-4 Video (ISO/IEC 14496-2) standard. ISO/IEC gives users of the MPEG-4 Video (ISO/IEC 14496-2) standard free license to this software module or modifications thereof for use in hardwareor software products claiming conformance to the MPEG-4 Video (ISO/IEC 14496-2) standard. Those intending to use this software module in hardware or software productsare advised that its use may infringe existing patents. The original developer of this software module and his/her company, the subsequent editors and their companies, and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. Copyright is not released for non MPEG-4 Video (ISO/IEC 14496-2) standard conforming products. Hitachi, Ltd. retains full right to use the code for his/her own purpose, assign or donate the code to a third party and to inhibit third parties from using the code for non MPEG-4 Video (ISO/IEC 14496-2) standardconforming products. This copyright notice must be included in all copies orderivative works. Copyright (c) 1998.Module Name: gmc_motion.cAbstract: Motion vector decoding for GMC blocks.**************************************************************************/#include <stdio.h>#include <math.h>#include <stdlib.h>#include <assert.h>#include "typeapi.h"#include "codehead.h"#include "global.h"#ifdef UNDER_CE#include "bitstrm.h"#include "huffman.h"#else#include "entropy/bitstrm.h"#include "entropy/huffman.h"#endif#include "mode.h"#include "vopses.h"Void globalmv(Int *, Int *, Int *, Int *, CoordI, CoordI, Int, Bool);Void FourSlashes(Int num, Int denom, Int *quot, Int *res){ *quot = num / denom; if (*quot * denom == num) *res = 0; else { if (num < 0) /* denom is larger than zero */ *quot -= 1; *res = num - denom * *quot; }}Void FourSlashesShift(Int inum, Int idenom_pwr, Int *ipquot, Int *ipres){ *ipquot = abs(inum) >> idenom_pwr; if(inum < 0) *ipquot = -*ipquot; if(*ipquot << idenom_pwr == inum) *ipres = 0; else { if(inum < 0) *ipquot -= 1; *ipres = inum - (*ipquot << idenom_pwr); }}Int LinearExtrapolation(Int x0, Int x1, Int x0p, Int x1p, Int W, Int VW){ Int quot, res, ressum, extrapolated; FourSlashes(x0p - (x0 << 4), W, ", &res); extrapolated = quot * (W - VW); FourSlashes(res * (W - VW), W, ", &res); extrapolated += quot; ressum = res; FourSlashes(x1p - (x1 << 4), W, ", &res); extrapolated += quot * VW + res; FourSlashes(res * (VW - W), W, ", &res); extrapolated += quot; ressum += res; FourSlashes(ressum, W, ", &res); extrapolated += quot; if(extrapolated >= 0) { if(res >= (W+1) / 2) extrapolated++; } else if(res > W / 2) extrapolated++; return(extrapolated);}Void TranslationalWarpMotion(Int *iXpel, Int *iYpel, Int *iXhalf, Int *iYhalf, Int iSearchRange, Bool bQuarterSample){ Int xi0, yj0; Int xi0prime, yj0prime; Int ifcode_area; Int ix_vec, iy_vec; xi0 = m_rctCurrVOPY.left ; yj0 = m_rctCurrVOPY.top ; if(bQuarterSample){ ifcode_area= iSearchRange/2; xi0prime = (Int)((m_rgstDstQ[0].x) * 4.0) ; yj0prime = (Int)((m_rgstDstQ[0].y) * 4.0) ; ix_vec = xi0prime - xi0*4; iy_vec = yj0prime - yj0*4; }else{ ifcode_area= iSearchRange; xi0prime = (Int)((m_rgstDstQ[0].x) * 2.0) ; yj0prime = (Int)((m_rgstDstQ[0].y) * 2.0) ; ix_vec = xi0prime - xi0*2; iy_vec = yj0prime - yj0*2; } if(ix_vec<-ifcode_area)ix_vec=-ifcode_area; if(ix_vec>=ifcode_area)ix_vec=ifcode_area-1; if(iy_vec<-ifcode_area)iy_vec=-ifcode_area; if(iy_vec>=ifcode_area)iy_vec=ifcode_area-1; *iXpel = ix_vec/2; *iYpel = iy_vec/2; *iXhalf = ix_vec - ((*iXpel)*2); *iYhalf = iy_vec - ((*iYpel)*2);}Void FastAffineWarpMotion(Int *iXpel, Int *iYpel, Int *iXhalf, Int *iYhalf, Int iXCurr, Int iYCurr, Int iSearchRange, Bool bQuarterSample){ Int xi0, yj0, xi1, yj1, xi2, yj2; Int xi0prime, yj0prime, xi1prime, yj1prime, xi2prime, yj2prime; Int ipa, ipb, ipc, ipd, ipe, ipf; Int ipa_i, ipa_f, ipb_i, ipb_f, ipd_i, ipd_f, ipe_i, ipe_f; Int iWidth, iHight, iWidthHight; Int xi1dprime, yj1dprime, xi2dprime, yj2dprime; Int iVW, iVH, iVWH; Int ivw_pwr, ivh_pwr, ivwh_pwr; Int ir_pwr, irat; Int cxy, cyy, idnm_pwr, ifracmask; Int cxx_i, cxx_f, cyx_i, cyx_f, cxy_i, cxy_f, cyy_i, cyy_f; Int crx, cry; Int xi,yj, xTI, yTJ; Int irx, iry; Int cx_curr, cy_curr; Int ix_vec, iy_vec; Int ifcode_area; Int iavg_x, iavg_y, ifavg, ires; Int ipp; Int iWarpingAccuracyp1 = m_uiWarpingAccuracy+1; ir_pwr = 4 - iWarpingAccuracyp1; irat = 1<<(4 - iWarpingAccuracyp1); if(bQuarterSample){ ifcode_area= iSearchRange/2; ires = 64 << m_uiWarpingAccuracy; }else{ ifcode_area= iSearchRange; ires = 128 << m_uiWarpingAccuracy; } xi0 = m_rctCurrVOPY.left ; yj0 = m_rctCurrVOPY.top ; xi1 = m_rctCurrVOPY.right ; yj1 = m_rctCurrVOPY.top ; xi0prime = (Int)((m_rgstDstQ[0].x) * 2.0) ; yj0prime = (Int)((m_rgstDstQ[0].y) * 2.0) ; xi1prime = (Int)((m_rgstDstQ[1].x) * 2.0) ; yj1prime = (Int)((m_rgstDstQ[1].y) * 2.0) ; xi0prime = xi0prime<< 3; yj0prime = yj0prime << 3; xi1prime = xi1prime << 3; yj1prime = yj1prime << 3; if(m_iNumOfPnts == 3) { xi2 = m_rctCurrVOPY.left ; yj2 = m_rctCurrVOPY.bottom ; xi2prime = (Int)((m_rgstDstQ[2].x) * 2.0) ; yj2prime = (Int)((m_rgstDstQ[2].y) * 2.0) ; xi2prime = xi2prime << 3; yj2prime = yj2prime << 3; } iWidth = xi1 - xi0; iVW = 1; ivw_pwr = 0; while(iVW < iWidth) { iVW <<= 1; ivw_pwr++; } if(m_iNumOfPnts == 3) { iHight = yj2 - yj0; iWidthHight = iWidth*iHight; iVH = 1; ivh_pwr = 0; while(iVH < iHight) { iVH <<= 1; ivh_pwr++; } iVWH = iVW * iVH; ivwh_pwr = ivw_pwr + ivh_pwr; } xi1dprime = LinearExtrapolation(xi0, xi1, xi0prime, xi1prime, iWidth, iVW) + ((xi0+iVW)<<4); yj1dprime = LinearExtrapolation(yj0, yj1, yj0prime, yj1prime, iWidth, iVW) + (yj0<<4); if(m_iNumOfPnts == 3) { xi2dprime = LinearExtrapolation(xi0, xi2, xi0prime, xi2prime, iHight, iVH) + (xi0<<4); yj2dprime = LinearExtrapolation(yj0, yj2, yj0prime, yj2prime, iHight, iVH) + ((yj0+iVH)<<4); } xi1prime = xi1dprime ; yj1prime = yj1dprime ; if(m_iNumOfPnts == 3) { xi2prime = xi2dprime ; yj2prime = yj2dprime ; if(ivw_pwr<=ivh_pwr) { iVH /= iVW; iVWH /= iVW; iVW=1; ivh_pwr -= ivw_pwr; ivwh_pwr -= ivw_pwr; ivw_pwr=0; } else { iVW /= iVH; iVWH /= iVH; iVH=1; ivw_pwr -= ivh_pwr; ivwh_pwr -= ivh_pwr; ivh_pwr=0; } } if(m_iNumOfPnts == 2) { ipa = xi1prime - xi0prime; ipb = -(yj1prime - yj0prime); ipc = xi0prime * iVW; ipd = -ipb; ipe = ipa; ipf = yj0prime * iVW; cxy = ipc; cyy = ipf; ipp = irat*iVW/2 ; idnm_pwr = ir_pwr+ivw_pwr; } else { ipa = (xi1prime - xi0prime) * iVH; ipb = (xi2prime - xi0prime) * iVW; ipc = xi0prime * iVWH; ipd = (yj1prime - yj0prime) * iVH; ipe = (yj2prime - yj0prime) * iVW; ipf = yj0prime * iVWH; cxy = ipc; cyy = ipf; ipp = irat*iVWH/2 ; idnm_pwr = ir_pwr+ivwh_pwr; } cx_curr = iXCurr - xi0; cy_curr = iYCurr - yj0; iavg_x = iavg_y = 0 ; ifavg = 0; cxy += ipb * cy_curr + ipa * cx_curr; cyy += ipe * cy_curr + ipd * cx_curr; FourSlashesShift(cxy, idnm_pwr, &cxy_i, &cxy_f); FourSlashesShift(cyy, idnm_pwr, &cyy_i, &cyy_f); FourSlashesShift(ipa, idnm_pwr, &ipa_i, &ipa_f); FourSlashesShift(ipb, idnm_pwr, &ipb_i, &ipb_f); FourSlashesShift(ipd, idnm_pwr, &ipd_i, &ipd_f); FourSlashesShift(ipe, idnm_pwr, &ipe_i, &ipe_f); ifracmask = (1 << idnm_pwr) - 1; for (yj = 0, yTJ = iYCurr; yj < MB_SIZE; cxy_i+=ipb_i, cxy_f+=ipb_f, cyy_i+=ipe_i, cyy_f+=ipe_f, yj++, yTJ++) { cxy_i += cxy_f >> idnm_pwr; cyy_i += cyy_f >> idnm_pwr; cxy_f &= ifracmask; cyy_f &= ifracmask; for (xi = 0, xTI=iXCurr, cxx_i = cxy_i, cxx_f = cxy_f, cyx_i= cyy_i, cyx_f= cyy_f;xi < MB_SIZE; cxx_i+=ipa_i, cxx_f+=ipa_f, cyx_i+=ipd_i, cyx_f+=ipd_f, xi++, xTI++) { crx = (cxx_i<<idnm_pwr)+cxx_f; cry = (cyx_i<<idnm_pwr)+cyx_f; crx = (crx + ipp) >> idnm_pwr; cry = (cry + ipp) >> idnm_pwr; cxx_i += cxx_f >> idnm_pwr; cyx_i += cyx_f >> idnm_pwr; cxx_f &= ifracmask; cyx_f &= ifracmask; irx = crx - (xTI<<iWarpingAccuracyp1); iry = cry - (yTJ<<iWarpingAccuracyp1); iavg_x += irx; iavg_y += iry; ifavg++; } } if(ifavg!=256){ fprintf(stderr, "Error : MV PREDICTION (ifavg!=256) \n"); exit(0); } if(bQuarterSample){ ix_vec = (iavg_x + (iavg_x<0 ? ires-1 : ires))>>(6+iWarpingAccuracyp1); iy_vec = (iavg_y + (iavg_y<0 ? ires-1 : ires))>>(6+iWarpingAccuracyp1); }else{ ix_vec = (iavg_x + (iavg_x<0 ? ires-1 : ires))>>(7+iWarpingAccuracyp1); iy_vec = (iavg_y + (iavg_y<0 ? ires-1 : ires))>>(7+iWarpingAccuracyp1); } if(ix_vec<-ifcode_area)ix_vec=-ifcode_area; if(ix_vec>=ifcode_area)ix_vec=ifcode_area-1; if(iy_vec<-ifcode_area)iy_vec=-ifcode_area; if(iy_vec>=ifcode_area)iy_vec=ifcode_area-1; *iXpel = ix_vec/2; *iYpel = iy_vec/2; *iXhalf = ix_vec - ((*iXpel)*2); *iYhalf = iy_vec - ((*iYpel)*2);}Void globalmv(Int *iXpel, Int *iYpel, Int *iXhalf, Int *iYhalf, CoordI iXCurr, CoordI iYCurr, Int iSearchRange, Bool bQuarterSample){ Int ifcode_area= iSearchRange; switch(m_iNumOfPnts) { case 0: *iXpel = *iYpel = *iXhalf = *iYhalf = 0; break; case 1: TranslationalWarpMotion(iXpel, iYpel, iXhalf, iYhalf,iSearchRange,bQuarterSample); break; case 2: case 3: FastAffineWarpMotion(iXpel, iYpel, iXhalf, iYhalf, iXCurr, iYCurr, ifcode_area, bQuarterSample); break;#ifndef NO_ASSERTS default: assert(m_iNumOfPnts<=3);#endif }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -