📄 sys_rrv.cpp
字号:
/****************************************************************************** * * This software module was originally developed by * * Fujitsu Laboratories Ltd. (contact: Eishi Morimatsu) * * 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. No license to this software * module is granted for non MPEG-4 Video (ISO/IEC 14496-2) standard * conforming products. * * Fujitsu Laboratories Ltd. retains full right to use the software module for * his/her own purpose, assign or donate the software module 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 of the software module. * * Copyright (c) 1999. *Module Name: rrv.cppAbstract: Utility functions for Reduced Resolution Vop (RRV) modeRevision History: *****************************************************************************/#include <stdlib.h>#include <stdio.h>#include <math.h>//#include <fstream.h>//#include <iostream.h>//#include "mpeg4ip.h"#include "typeapi.h"#include "codehead.h"#include "global.hpp"#include "mode.hpp"#include "bitstrm.hpp"class ofstream;#include "sesenc.hpp"#include "vopses.hpp"#include "vopseenc.hpp"#include "vopsedec.hpp"#define RRV_MAX(x,y) (((x)>(y))?(x):(y))#define RRV_MIN(x,y) (((x)<(y))?(x):(y))#define RRV_BLOCK_SIZE 16#define RRV_C1 2.5#define RRV_C2 2.5#define RRV_FR1 6.0#define RRV_FR2 8.0#define RRV_QP1 14#define RRV_QP2 6//// functions refered from other files//Void MotionVectorScalingDown(CMotionVector*, Int, Int);Void MotionVectorScalingUp(CMotionVector*,Int, Int);Void DownSamplingTextureForRRV(PixelC*, PixelC*, Int, Int);Void DownSamplingTextureForRRV(PixelI*, PixelI*, Int, Int);Void UpSamplingTextureForRRV(PixelC*, PixelC*, Int, Int, Int);Void UpSamplingTextureForRRV(PixelI*, PixelI*, Int, Int, Int);Void writeCubicRct(Int, Int, PixelC*, PixelC*);Void writeCubicRct(Int, Int, PixelI*, PixelI*);Void MeanUpSampling(PixelC*, PixelC*, Int, Int);Void MeanUpSampling(PixelI*, PixelI*, Int, Int);//// functions refered only in this file//Void MotionVectorScalingDownMB(CMotionVector*);Void calculateMVdown(Float*);Void MotionVectorScalingUpMB(CMotionVector*);Void calculateMVup(Float *pfvec);Void MotionVectorChange(Float, Int*, Int*);Float MotionVectorChange(Int, Int);Void filterMBVarBorder(PixelC*, Int, Int, Int);Void filterMBHorBorder(PixelC*, Int, Int, Int);/*Void CVideoObjectEncoder::redefineVOLMembersRRV();Void CVideoObjectEncoder::cutoffDCTcoef();Void CVideoObjectEncoder::resetAndCalcRRV();Void CVideoObjectDecoder::redefineVOLMembersRRV();Void CVideoObject::filterCodedPictureForRRV(PixelC*, PixelC*, PixelC*, Int isizex, Int isizey, Int inumMBx,Int inumMBy, Int iwidthY, Int iwidthUV);*/Void CVideoObjectEncoder::cutoffDCTcoef(){ if((m_vopmd.RRVmode.iCutoffThr == 8)||(m_vopmd.RRVmode.iOnOff != 1)) { return; } assert((m_vopmd.RRVmode.iCutoffThr >= 4)&&(m_vopmd.RRVmode.iCutoffThr <= 7)); Int x, y, pos; for(y = 0 ; y < BLOCK_SIZE; y ++) { for(x = 0 ; x < BLOCK_SIZE; x ++) { if((x >= m_vopmd.RRVmode.iCutoffThr)||(y >= m_vopmd.RRVmode.iCutoffThr)) { pos = x +y *BLOCK_SIZE; m_rgiDCTcoef[pos] = 0; } } }}Void CVideoObjectEncoder::redefineVOLMembersRRV(){ m_iNumMBX = m_iVOPWidthY / MB_SIZE; m_iNumMBY = m_rctCurrVOPY.height () / MB_SIZE; m_iNumMB = m_iNumMBX * m_iNumMBY; m_iNumOfTotalMVPerRow = PVOP_MV_PER_REF_PER_MB * m_iNumMBX; if(m_vopmd.RRVmode.iRRVOnOff == 1) { m_iRRVScale = 2; m_iNumMBX = m_iNumMBX /2; m_iNumMBY = m_iNumMBY /2; m_iNumMB = m_iNumMB /4; m_iNumOfTotalMVPerRow = m_iNumOfTotalMVPerRow /2; } else { m_iRRVScale = 1; } m_iFrameWidthYxMBSize = (MB_SIZE *m_iRRVScale) *m_pvopcRefQ0->whereY ().width; m_iFrameWidthYxBlkSize = (BLOCK_SIZE *m_iRRVScale) *m_pvopcRefQ0->whereY ().width; m_iFrameWidthUVxBlkSize = (BLOCK_SIZE *m_iRRVScale) * m_pvopcRefQ0->whereUV ().width;}Void CVideoObjectEncoder::resetAndCalcRRV(){ assert(m_vopmd.RRVmode.iOnOff == 1); assert(m_vopmd.RRVmode.iCycle != 0); static Int iCount = 0; static Int iFirst = 0; /* fixed interval mode */ if(m_vopmd.RRVmode.iCycle == 0) { m_vopmd.RRVmode.iRRVOnOff = 0; } else if(m_vopmd.RRVmode.iCycle < 0) {// m_vopmd.RRVmode.iCutoffThr = 8; switch(iFirst) { case 0: m_vopmd.RRVmode.iRRVOnOff = 0; m_vopmd.RRVmode.iCutoffThr = 8; iCount++; iFirst = 1; break; case 1: iCount = iCount % m_vopmd.RRVmode.iCycle; if(iCount == 0) { m_vopmd.RRVmode.iRRVOnOff ^= 0x01; if(m_vopmd.RRVmode.iRRVOnOff == 0) { m_vopmd.RRVmode.iCutoffThr = 4; } else { m_vopmd.RRVmode.iCutoffThr = 8; } } else { if(m_vopmd.RRVmode.iCutoffThr < 8) { m_vopmd.RRVmode.iCutoffThr ++; } } iCount++; break; default: fprintf(stderr, "Error in resetAndCalcRRV\n"); exit(1); break; } } /* adaptive mode */ else { Float f_alpha, f_TH1, f_TH2; if(m_vopmd.RRVmode.iQave == 0) { /* perhaps first I-VOP */ m_vopmd.RRVmode.iRRVOnOff = 0; m_vopmd.RRVmode.iCutoffThr = 8; return; } f_alpha = (Float)(m_vopmd.RRVmode.iQave) *(Float)(m_vopmd.RRVmode.iNumBits); m_vopmd.RRVmode.iQP1 = RRV_QP1; m_vopmd.RRVmode.iQP2 = RRV_QP2; m_vopmd.RRVmode.fFR1 = RRV_FR1; m_vopmd.RRVmode.fFR2 = RRV_FR2; // printf("target bitrate %d\n", m_iBufferSize); f_TH1 = m_vopmd.RRVmode.iQP1 *(Float)(m_iBufferSize) /m_vopmd.RRVmode.fFR1; f_TH2 = m_vopmd.RRVmode.iQP2 *(Float)(m_iBufferSize) /m_vopmd.RRVmode.fFR2; if((m_vopmd.RRVmode.iRRVOnOff == 0)&&(f_alpha > f_TH1)) { m_vopmd.RRVmode.iRRVOnOff = 1; m_vopmd.RRVmode.iCutoffThr = 8; } else if((m_vopmd.RRVmode.iRRVOnOff == 1)&&(f_alpha < f_TH2)) { m_vopmd.RRVmode.iRRVOnOff = 0; m_vopmd.RRVmode.iCutoffThr = 4; } else if((m_vopmd.RRVmode.iRRVOnOff == 0)&&(m_vopmd.RRVmode.iCutoffThr < 8)) { m_vopmd.RRVmode.iCutoffThr ++; }// printf("RRV_debug: QxB = %f, TH1 = %f, TH2 = %f, Mode = %d, Thr = %d\n",// f_alpha, f_TH1, f_TH2, m_vopmd.RRVmode.iRRVOnOff, m_vopmd.RRVmode.iCutoffThr); }}Void CVideoObjectDecoder::redefineVOLMembersRRV(){ m_iRRVScale = (m_vopmd.RRVmode.iRRVOnOff == 1) ? (2) : (1); m_iNumMBX = m_iVOPWidthY / MB_SIZE /m_iRRVScale; m_iNumMBY = m_rctCurrVOPY.height () / MB_SIZE /m_iRRVScale; m_iFrameWidthYxMBSize = (MB_SIZE *m_iRRVScale) * m_pvopcRefQ0->whereY ().width; m_iFrameWidthYxBlkSize = (BLOCK_SIZE *m_iRRVScale) * m_pvopcRefQ0->whereY ().width; m_iFrameWidthUVxBlkSize = (BLOCK_SIZE *m_iRRVScale) * m_pvopcRefQ0->whereUV ().width; m_iNumMB = m_iNumMBX * m_iNumMBY; m_iNumOfTotalMVPerRow = PVOP_MV_PER_REF_PER_MB * m_iNumMBX;}Void MotionVectorScalingDown(CMotionVector* pmv, Int inumMB, Int iMVperMB){ Int i; for(i = 0; i < inumMB *iMVperMB; i++) { MotionVectorScalingDownMB(&pmv[i]); }}Void MotionVectorScalingDownMB(CMotionVector* pmv){//see basic.hpp pmv->computeMV(); Float vx = MotionVectorChange(pmv->iMVX,pmv->iHalfX); Float vy = MotionVectorChange(pmv->iMVY,pmv->iHalfY); calculateMVdown(&vx); calculateMVdown(&vy); MotionVectorChange(vx, &(pmv->iMVX), &(pmv->iHalfX)); MotionVectorChange(vy, &(pmv->iMVY), &(pmv->iHalfY)); pmv->computeTrueMV();}Void calculateMVdown(Float *pfvec){ Float fvec = (Float) *pfvec; if(fvec == 0.0) { *pfvec = 0.0; } else if(fvec > 0.0) { *pfvec = (fvec + 0.5) /2.0; } else if(fvec < 0.0) { *pfvec = (fvec - 0.5) /2.0; }}Void MotionVectorScalingUp(CMotionVector* pmv,Int inumMB,Int iMVperMB){ Int i; CMotionVector* plocalpmv = pmv; for (i=0;i<inumMB*iMVperMB;i++) MotionVectorScalingUpMB(plocalpmv++);}Void MotionVectorScalingUpMB(CMotionVector* pmv){//see basic.hpp pmv->computeMV(); Float fvx = MotionVectorChange(pmv->iMVX,pmv->iHalfX); Float fvy = MotionVectorChange(pmv->iMVY,pmv->iHalfY); calculateMVup(&fvx); calculateMVup(&fvy); MotionVectorChange(fvx, &(pmv->iMVX), &(pmv->iHalfX)); MotionVectorChange(fvy, &(pmv->iMVY), &(pmv->iHalfY)); pmv->computeTrueMV();}Void calculateMVup(Float *pfvec){ Float fvec = (Float) *pfvec; if(fvec == 0.0) { *pfvec = 0.0; } else if(fvec > 0.0) { *pfvec = 2.0 * fvec - 0.5; } else if(fvec < 0.0) { *pfvec = 2.0 * fvec + 0.5; }}Void MotionVectorChange(Float fvec, Int *iMV, Int *iHalfV){//Float --> Int Int ilMV,ilHV; ilMV = nint(fvec); ilHV = nint((fvec - (Float) ilMV) *2.0); *iMV = ilMV; *iHalfV = ilHV;}Float MotionVectorChange(Int iMV, Int iHalfV){//Int --> Float return((Float) iMV + ((Float) iHalfV) /2.0);}Void DownSamplingTextureForRRV(PixelC *pPxlc, PixelC *pretPxlc, Int iwidth, Int ihight){ Int i, j, ival; PixelC *pnewblock = new PixelC[iwidth *ihight /4]; for(j = 0; j < ihight /2; j++) { for(i = 0; i < iwidth /2 ;i++) { ival = pPxlc[i * 2 + j * 2 * iwidth]; ival += pPxlc[i * 2 + 1 + j * 2 * iwidth]; ival += pPxlc[i * 2 + (j * 2 + 1)* iwidth]; ival += pPxlc[i * 2 + 1 + (j * 2 + 1)* iwidth]; pnewblock[i+j*iwidth/2] = ((ival + 2) / 4); } } for(i = 0; i < iwidth *ihight /4; i++) { pretPxlc[i] = pnewblock[i]; } delete [] pnewblock;}Void DownSamplingTextureForRRV(PixelI *pPxli, PixelI *pretPxli, Int iwidth, Int ihight){ Int i,j,ival; PixelI *pnewblock = new PixelI[iwidth *ihight /4]; for(j = 0; j < ihight /2; j++) { for(i = 0; i < iwidth /2; i++) { ival = pPxli[i * 2 + j * 2 * iwidth]; ival += pPxli[i * 2 + 1 + j * 2 * iwidth]; ival += pPxli[i * 2 + (j * 2 + 1)* iwidth]; ival += pPxli[i * 2 + 1 + (j * 2 + 1)* iwidth]; pnewblock[i+j*iwidth/2]= ((ival + 2) / 4); } } for(i = 0; i < iwidth *ihight /4; i++) { pretPxli[i] = pnewblock[i]; } delete [] pnewblock;}//////UpSamplingTextureforRRV////Void UpSamplingTextureForRRV(PixelC *pPixlc, PixelC *pretPxlc, Int iwidth, Int ihight,Int iwidthofpPix){ Int ibx, iby, ix, iy, ipos, icnt; PixelC* pblock_low = new PixelC [64]; PixelC* pblock_norm = new PixelC [256]; PixelC* pnormal_data = new PixelC [iwidth *ihight *4]; Int inor_sizex = iwidth *2; Int inor_sizey = ihight *2; for(iby = 0; iby < (inor_sizey /2); iby += 8) { for(ibx = 0; ibx < (inor_sizex/2); ibx += 8) { for(iy = iby, icnt = 0; iy < iby + 8; iy ++) { ipos = ibx + (iy) * iwidthofpPix; for(ix = ibx; ix < ibx + 8; ix++) { pblock_low[icnt] = pPixlc[ipos]; icnt++; ipos++; } } MeanUpSampling(pblock_low, pblock_norm, 8, 8); for(iy = 2 * iby, icnt = 0; iy < 2 * iby + 16; iy ++) { ipos = 2 * ibx + (iy) * inor_sizex; for(ix = 2 * ibx; ix < 2 * ibx + 16; ix++) { pnormal_data[ipos] = pblock_norm[icnt]; icnt++; ipos++; } } } } for(iy = 0; iy < inor_sizey; iy++) { for(ix = 0; ix < inor_sizex; ix++) { pretPxlc[ix +(iy *iwidthofpPix)] = pnormal_data[ix +(iy *inor_sizex)]; } } delete [] pblock_norm; delete [] pblock_low;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -