📄 gmc_util.cpp
字号:
/**************************************************************************
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 hardware
or 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 products
are 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) standard
conforming products. This copyright notice must be included in all copies or
derivative works.
Copyright (c) 1998.
Module Name:
gmc_util.cpp
Abstract:
Reference points decoding for GMC.
**************************************************************************/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <iostream.h>
#include <assert.h>
#include "typeapi.h"
#include "codehead.h"
#include "global.hpp"
#include "entropy/bitstrm.hpp"
#include "entropy/entropy.hpp"
#include "entropy/huffman.hpp"
#include "mode.hpp"
#include "vopses.hpp"
Void CVideoObject::FindGlobalPredForGMC (Int cx_curr, Int cy_curr,
PixelC* ppxlcRef, const PixelC* puciRef)
{
switch(m_iNumOfPnts) {
case 0:
StationalWarpForGMC(cx_curr, cy_curr,
ppxlcRef, puciRef);
break;
case 1:
TranslationalWarpForGMC(cx_curr, cy_curr,
ppxlcRef, puciRef);
break;
case 2:
case 3:
FastAffineWarpForGMC(cx_curr, cy_curr,
ppxlcRef, puciRef);
break;
default:
assert(m_iNumOfPnts<=3);
}
}
Void CVideoObject::FindGlobalChromPredForGMC (Int cx_curr, Int cy_curr,
PixelC* ppxlcRefU, PixelC* ppxlcRefV)
{
switch(m_iNumOfPnts) {
case 0:
StationalWarpChromForGMC(cx_curr, cy_curr,
ppxlcRefU, ppxlcRefV);
break;
case 1:
TranslationalWarpChromForGMC(cx_curr, cy_curr,
ppxlcRefU, ppxlcRefV);
break;
case 2:
case 3:
FastAffineWarpChromForGMC(cx_curr, cy_curr,
ppxlcRefU, ppxlcRefV);
break;
default:
assert(m_iNumOfPnts<=3);
}
}
Void CVideoObject::StationalWarpForGMC(Int cx_curr, Int cy_curr,
PixelC *ppxlcRef, const PixelC *puciRef)
{
Int iref_width = m_rctRefFrameY.right - m_rctRefFrameY.left;
Int iref_height = m_rctRefFrameY.bottom - m_rctRefFrameY.top;
Int iref_left = (m_rctRefVOPY0.left + EXPANDY_REFVOP);
Int iref_top = (m_rctRefVOPY0.top + EXPANDY_REFVOP);
Int iref_right = (m_rctRefVOPY0.right - EXPANDY_REFVOP + 31);
Int iref_bottom = (m_rctRefVOPY0.bottom - EXPANDY_REFVOP+ 31);
PixelC* pprev = (PixelC*) puciRef +
(EXPANDY_REF_FRAME-16)*m_iFrameWidthY +EXPANDY_REF_FRAME-16 ;
Int xi,yj, ipel_in;
Int xTI,yTJ;
Int xTI_w,yTJ_w;
for (yj = 0, yTJ = cy_curr; yj < MB_SIZE; yj++, yTJ++) {
for (xi = 0, xTI = cx_curr; xi < MB_SIZE; xi++, xTI++) {
xTI_w = xTI; yTJ_w = yTJ;
if (xTI_w<iref_left||yTJ_w<iref_top||xTI_w>iref_right||yTJ_w>iref_bottom)
{
if(xTI_w<iref_left)xTI_w=iref_left;
if(xTI_w>iref_right)xTI_w=iref_right;
if(yTJ_w<iref_top)yTJ_w=iref_top;
if(yTJ_w>iref_bottom)yTJ_w=iref_bottom;
}
ipel_in = yTJ_w * iref_width + xTI_w;
ppxlcRef[xi+yj*MB_SIZE] = pprev[ipel_in];
}
}
}
Void CVideoObject::StationalWarpChromForGMC(Int cx_curry, Int cy_curry,
PixelC *ppxlcRefU, PixelC *ppxlcRefV)
{
Int iWarpingAccuracyp1 = m_uiWarpingAccuracy+1;
Int iref_width = m_rctRefFrameY.right - m_rctRefFrameY.left;
Int iref_height = m_rctRefFrameY.bottom - m_rctRefFrameY.top;
Int iref_left = ((m_rctRefVOPY0.left/2) + EXPANDUV_REFVOP)<<iWarpingAccuracyp1;
Int iref_top = ((m_rctRefVOPY0.top/2) + EXPANDUV_REFVOP)<<iWarpingAccuracyp1;
Int iref_right = ((m_rctRefVOPY0.right/2) - EXPANDUV_REFVOP + 15)<<iWarpingAccuracyp1;
Int iref_bottom = ((m_rctRefVOPY0.bottom/2) - EXPANDUV_REFVOP + 15)<<iWarpingAccuracyp1;
CU8Image *puciRefU = (CU8Image*) m_pvopcRefQ0 -> getPlane (U_PLANE);
CU8Image *puciRefV = (CU8Image*) m_pvopcRefQ0 -> getPlane (V_PLANE);
PixelC* pprevu = (PixelC*) puciRefU -> pixels () +
(EXPANDUV_REF_FRAME - 8)*m_iFrameWidthUV +EXPANDUV_REF_FRAME - 8;
PixelC* pprevv = (PixelC*) puciRefV -> pixels () +
(EXPANDUV_REF_FRAME - 8)*m_iFrameWidthUV +EXPANDUV_REF_FRAME - 8;
Int ipel_in;
Int xi, yj, xTI, yTJ;
Int xTI_w, yTJ_w;
Int cx_curr = cx_curry>> 1;
Int cy_curr = cy_curry>> 1;
iref_width = iref_width >>1;
iref_height = iref_height >>1;
for (yj = 0, yTJ = cy_curr; yj < MB_SIZE/2; yj++, yTJ++) {
for (xi = 0, xTI = cx_curr; xi < MB_SIZE/2; xi++, xTI++) {
xTI_w = xTI; yTJ_w = yTJ;
if (xTI_w<iref_left||yTJ_w<iref_top||xTI_w>iref_right||yTJ_w>iref_bottom)
{
if(xTI_w<iref_left)xTI_w=iref_left;
if(xTI_w>iref_right)xTI_w=iref_right;
if(yTJ_w<iref_top)yTJ_w=iref_top;
if(yTJ_w>iref_bottom)yTJ_w=iref_bottom;
}
ipel_in = yTJ_w * iref_width + xTI_w;
ppxlcRefU[xi+yj*BLOCK_SIZE] = pprevu[ipel_in];
ppxlcRefV[xi+yj*BLOCK_SIZE] = pprevv[ipel_in];
}
}
}
Void CVideoObject::TranslationalWarpForGMC(Int cx_curr, Int cy_curr,
PixelC *ppxlcRef, const PixelC *puciRef)
{
Int iWarpingAccuracyp1 = m_uiWarpingAccuracy+1;
Int iref_width = m_rctRefFrameY.right - m_rctRefFrameY.left;
Int iref_height = m_rctRefFrameY.bottom - m_rctRefFrameY.top;
Int iref_left = (m_rctRefVOPY0.left + EXPANDY_REFVOP)<<iWarpingAccuracyp1;
Int iref_top = (m_rctRefVOPY0.top + EXPANDY_REFVOP)<<iWarpingAccuracyp1;
Int iref_right = (m_rctRefVOPY0.right - EXPANDY_REFVOP + 31)<<iWarpingAccuracyp1;
Int iref_bottom = (m_rctRefVOPY0.bottom - EXPANDY_REFVOP + 31)<<iWarpingAccuracyp1;
PixelC* pprev = (PixelC*) puciRef +
(EXPANDY_REF_FRAME-16)*m_iFrameWidthY +EXPANDY_REF_FRAME-16;
Int xi0, yj0;
Int xi0prime, yj0prime;
Int xi,yj;
Int cxx, cyy, ipa, ipe, ioffset;
Int ibias, isqr_wac;
Int irx, iry;
Int cxx_w, cyy_w;
Int iPowerWA, iwarpmask;
iPowerWA = 1 << iWarpingAccuracyp1;
iwarpmask = iPowerWA - 1;
isqr_wac = iWarpingAccuracyp1 << 1;
ibias = 1 << (isqr_wac - 1);
xi0 = m_rctCurrVOPY.left ;
yj0 = m_rctCurrVOPY.top ;
xi0prime = (Int)((m_rgstDstQ[0].x + 16) * 2.0) ;
yj0prime = (Int)((m_rgstDstQ[0].y + 16) * 2.0) ;
xi0prime = xi0prime << m_uiWarpingAccuracy;
yj0prime = yj0prime << m_uiWarpingAccuracy;
cxx = xi0prime;
cyy = yj0prime;
ipa = iPowerWA;
ipe = iPowerWA;
xi0prime += ipa*(cx_curr-xi0);
cyy += ipe*(cy_curr-yj0);
for (yj = 0; yj < MB_SIZE; cyy+=ipe, yj++) {
for (xi = 0, cxx=xi0prime; xi < MB_SIZE; cxx+=ipa, xi++) {
cxx_w = cxx; cyy_w = cyy;
if (cxx_w<iref_left||cyy_w<iref_top||cxx_w>iref_right||cyy_w>iref_bottom)
{
if(cxx_w<iref_left)cxx_w=iref_left;
if(cxx_w>iref_right)cxx_w=iref_right;
if(cyy_w<iref_top)cyy_w=iref_top;
if(cyy_w>iref_bottom)cyy_w=iref_bottom;
}
ioffset = (cyy_w >> iWarpingAccuracyp1) * iref_width +
(cxx_w >> iWarpingAccuracyp1);
irx = cxx_w & iwarpmask;
iry = cyy_w & iwarpmask;
ppxlcRef[xi+yj*MB_SIZE] = CInterpolatePixelValue(pprev, ioffset,
iref_width, irx, iry, iPowerWA,
ibias, isqr_wac);
}
}
}
Void CVideoObject::TranslationalWarpChromForGMC(Int cx_curry, Int cy_curry,
PixelC *ppxlcRefU, PixelC *ppxlcRefV)
{
Int iWarpingAccuracyp1 = m_uiWarpingAccuracy+1;
Int iref_width = m_rctRefFrameY.right - m_rctRefFrameY.left;
Int iref_height = m_rctRefFrameY.bottom - m_rctRefFrameY.top;
Int iref_left = ((m_rctRefVOPY0.left/2) + EXPANDUV_REFVOP)<<iWarpingAccuracyp1;
Int iref_top = ((m_rctRefVOPY0.top/2) + EXPANDUV_REFVOP)<<iWarpingAccuracyp1;
Int iref_right = ((m_rctRefVOPY0.right/2) - EXPANDUV_REFVOP + 15)<<iWarpingAccuracyp1;
Int iref_bottom = ((m_rctRefVOPY0.bottom/2) - EXPANDUV_REFVOP + 15)<<iWarpingAccuracyp1;
CU8Image *puciRefU = (CU8Image*) m_pvopcRefQ0 -> getPlane (U_PLANE);
CU8Image *puciRefV = (CU8Image*) m_pvopcRefQ0 -> getPlane (V_PLANE);
PixelC* pprevu = (PixelC*) puciRefU -> pixels () +
(EXPANDUV_REF_FRAME - 8)*m_iFrameWidthUV +EXPANDUV_REF_FRAME - 8;
PixelC* pprevv = (PixelC*) puciRefV -> pixels () +
(EXPANDUV_REF_FRAME - 8)*m_iFrameWidthUV +EXPANDUV_REF_FRAME - 8;
Int xi0, yj0;
Int xi0prime, yj0prime;
Int xi,yj;
Int cxx, cyy, cxy, ipa, ipe, ioffset;
Int ibias, isqr_wac;
Int irx, iry;
Int cxx_w, cyy_w;
Int iPowerWA, iwarpmask;
iref_width = iref_width >>1;
iref_height = iref_height >>1;
iPowerWA = 1 << iWarpingAccuracyp1;
iwarpmask = iPowerWA - 1;
isqr_wac = iWarpingAccuracyp1 << 1;
ibias = 1 << (isqr_wac - 1);
xi0 = m_rctCurrVOPY.left << m_uiWarpingAccuracy;
yj0 = m_rctCurrVOPY.top << m_uiWarpingAccuracy;
Int cx_curr = cx_curry>> 1;
Int cy_curr = cy_curry>> 1;
xi0prime = (Int)(m_rgstDstQ[0].x * 2.0) ;
yj0prime = (Int)(m_rgstDstQ[0].y * 2.0) ;
xi0prime = xi0prime << m_uiWarpingAccuracy;
yj0prime = yj0prime << m_uiWarpingAccuracy;
cxx = cxy = ((xi0prime >> 1) | (xi0prime & 1)) + (8<<iWarpingAccuracyp1) - xi0;
cyy = ((yj0prime >> 1) | (yj0prime & 1)) + (8<<iWarpingAccuracyp1) - yj0;
ipa = iPowerWA;
ipe = iPowerWA;
cxy += ipa*cx_curr;
cyy += ipe*cy_curr;
for (yj = 0; yj < MB_SIZE/2; cyy+=ipe, yj++) {
for (xi = 0, cxx=cxy; xi < MB_SIZE/2; cxx+=ipa, xi++) {
cxx_w = cxx; cyy_w = cyy;
if (cxx_w<iref_left||cyy_w<iref_top||cxx_w>iref_right||cyy_w>iref_bottom)
{
if(cxx_w<iref_left)cxx_w=iref_left;
if(cxx_w>iref_right)cxx_w=iref_right;
if(cyy_w<iref_top)cyy_w=iref_top;
if(cyy_w>iref_bottom)cyy_w=iref_bottom;
}
ioffset = (cyy_w >> iWarpingAccuracyp1) * iref_width +
(cxx_w >> iWarpingAccuracyp1);
irx = cxx_w & iwarpmask;
iry = cyy_w & iwarpmask;
ppxlcRefU[xi+yj*BLOCK_SIZE] = CInterpolatePixelValue(pprevu, ioffset,
iref_width, irx, iry, iPowerWA,
ibias, isqr_wac);
ppxlcRefV[xi+yj*BLOCK_SIZE] = CInterpolatePixelValue(pprevv, ioffset,
iref_width, irx, iry, iPowerWA,
ibias, isqr_wac);
}
}
}
Void CVideoObject::FastAffineWarpForGMC(Int cx_curr, Int cy_curr,
PixelC *ppxlcRef, const PixelC *puciRef)
{
Int iWarpingAccuracyp1 = m_uiWarpingAccuracy+1;
Int iref_width = m_rctRefFrameY.right - m_rctRefFrameY.left;
Int iref_height = m_rctRefFrameY.bottom - m_rctRefFrameY.top;
Int iref_left = (m_rctRefVOPY0.left + EXPANDY_REFVOP)<<iWarpingAccuracyp1;
Int iref_top = (m_rctRefVOPY0.top + EXPANDY_REFVOP)<<iWarpingAccuracyp1;
Int iref_right = (m_rctRefVOPY0.right - EXPANDY_REFVOP + 31)<<iWarpingAccuracyp1;
Int iref_bottom = (m_rctRefVOPY0.bottom - EXPANDY_REFVOP + 31)<<iWarpingAccuracyp1;
PixelC* pprev = (PixelC*) puciRef +
(EXPANDY_REF_FRAME-16)*m_iFrameWidthY +EXPANDY_REF_FRAME-16;
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 xi, yj;
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, ioffset;
Int cxx_w, cyx_w;
Int irx, iry;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -