📄 newpred.cpp
字号:
/**************************************************************************
This software module was originally developed by
Hideaki Kimata (NTT)
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.
NTT 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) 1999.
Module Name:
newpred.cpp
Abstract:
Implementation of the CNewPred class.
Revision History:
Aug.30, 1999: change position of #ifdef _DEBUG by Hideaki Kimata (NTT)
**************************************************************************/
#ifdef __MFC_
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
#endif // __MFC_
#include "basic.hpp"
#include "typeapi.h"
#include "codehead.h"
#include "mode.hpp"
#include "global.hpp"
#include "entropy/bitstrm.hpp"
#include "newpred.hpp"
#include <string.h>
#ifdef _DEBUG
#include <crtdbg.h>
#define _CRTDBG_MAP_ALLOC
//CMemoryState CMemOld, CMemNew;
#endif
CNewPred::CNewPred()
{
m_iVopID = 0;
m_pDecbufY = NULL;
m_pDecbufU = NULL;
m_pDecbufV = NULL;
m_pchNewPredRefY = NULL;
m_pchNewPredRefU = NULL;
m_pchNewPredRefV = NULL;
m_piSlicePoint = NULL;
}
CNewPred::~CNewPred()
{
if (m_pchNewPredRefY != NULL) delete []m_pchNewPredRefY;
if (m_pchNewPredRefU != NULL) delete []m_pchNewPredRefU;
if (m_pchNewPredRefV != NULL) delete []m_pchNewPredRefV;
if (m_piSlicePoint != NULL) delete[] m_piSlicePoint;
}
Bool CNewPred::CheckSlice(int iMBX, int iMBY, Bool bChkTop)
{
int iNumMBX = m_iWidth / MB_SIZE;
int iMBNum = iMBX + (iMBY * iNumMBX);
for( int iLocal = 0; *(m_piSlicePoint + iLocal) >= 0; iLocal++ ) {
if( *(m_piSlicePoint + iLocal) > iMBNum )
break;
if( *(m_piSlicePoint + iLocal) == iMBNum ) {
if( bChkTop )
return TRUE;
else {
if( iMBNum )
return TRUE;
}
}
}
return FALSE;
}
int CNewPred::GetSliceNum(int iMBX, int iMBY)
{
int iNumMBX = m_iWidth / MB_SIZE;
int iMBNum = iMBX + (iMBY * iNumMBX);
for( int iLocal = 0; *(m_piSlicePoint + iLocal) >= 0; iLocal++ ) {
if( iMBNum < *(m_piSlicePoint + iLocal))
return (iLocal-1);
}
return (iLocal-1); // return Slice number
}
void CNewPred::IncrementVopID()
{
for( int iLocal = 0, iMask = 1; iLocal < m_iNumBitsVopID; iLocal++, iMask <<= 1 ) {
if( m_iVopID & iMask )
continue;
else {
++m_iVopID;
return;
}
}
m_iVopID = 1;
}
int CNewPred::NextSliceHeadMBA(int iMBX, int iMBY)
{
int iNumMBX = m_iWidth / MB_SIZE;
int iMBNum = iMBX + (iMBY * iNumMBX);
for( int iLocal = 0; *(m_piSlicePoint + iLocal) >= 0; iLocal++ ) {
if( *(m_piSlicePoint + iLocal) > iMBNum ) {
return(*(m_piSlicePoint + iLocal));
}
}
return(-1);
}
int CNewPred::NowMBA(int vp_id)
{
for( int i = 0; *(m_piSlicePoint + i) >= 0; i++ );
if(vp_id >= i) return(-1);
return(*(m_piSlicePoint + vp_id));
}
int CNewPred::GetCurrentVOP_id()
{
return( m_iVopID );
}
void CNewPred::CopyBuftoNPRefBuf(int iSlice, int iBufCnt)
{
if (m_bShapeOnly == FALSE) {
CopyBufUtoNPRefBufY(iSlice, iBufCnt);
CopyBufUtoNPRefBufU(iSlice, iBufCnt);
CopyBufUtoNPRefBufV(iSlice, iBufCnt);
}
return;
}
void CNewPred::SetQBuf( CVOPU8YUVBA *pRefQ0, CVOPU8YUVBA *pRefQ1 )
{
m_pNPvopcRefQ0 = pRefQ0;
m_pNPvopcRefQ1 = pRefQ1;
return;
}
void CNewPred::CopyBufUtoNPRefBufY(int iSlice, int iBufCnt)
{
Int i;
Int iSize;
iSize =0;
for( i=0; i < iSlice; i++ ) {
if (*(m_piSlicePoint+i+1)%m_iNPNumMBX)
continue;
iSize += m_pNewPredControl->NPRefBuf[i][iBufCnt]->iSizeY;
}
PixelC* RefpointY = (PixelC*) m_pNPvopcRefQ1->pixelsY () +
(EXPANDY_REF_FRAME * m_rctNPFrameY.width) + iSize;
memcpy(m_pNewPredControl->NPRefBuf[iSlice][iBufCnt]->pdata.pchY, RefpointY,
m_pNewPredControl->NPRefBuf[iSlice][iBufCnt]->iSizeY);
return;
}
void CNewPred::CopyBufUtoNPRefBufU(int iSlice, int iBufCnt)
{
Int i;
Int iSize;
iSize =0;
for( i=0; i < iSlice; i++ ) {
if (*(m_piSlicePoint+i+1)%m_iNPNumMBX)
continue;
iSize += m_pNewPredControl->NPRefBuf[i][iBufCnt]->iSizeUV;
}
PixelC* RefpointU = (PixelC*) m_pNPvopcRefQ1->pixelsU () +
((EXPANDY_REF_FRAME/2) * m_rctNPFrameUV.width) + iSize;
memcpy(m_pNewPredControl->NPRefBuf[iSlice][iBufCnt]->pdata.pchU, RefpointU,
m_pNewPredControl->NPRefBuf[iSlice][iBufCnt]->iSizeUV);
return;
}
void CNewPred::CopyBufUtoNPRefBufV(int iSlice, int iBufCnt)
{
Int i;
Int iSize;
iSize =0;
for( i=0; i < iSlice; i++ ) {
if (*(m_piSlicePoint+i+1)%m_iNPNumMBX)
continue;
iSize += m_pNewPredControl->NPRefBuf[i][iBufCnt]->iSizeUV;
}
PixelC* RefpointV = (PixelC*) m_pNPvopcRefQ1->pixelsV () +
((EXPANDY_REF_FRAME/2) * m_rctNPFrameUV.width) + iSize;
memcpy(m_pNewPredControl->NPRefBuf[iSlice][iBufCnt]->pdata.pchV, RefpointV,
m_pNewPredControl->NPRefBuf[iSlice][iBufCnt]->iSizeUV);
return;
}
NP_WHO_AM_I CNewPred::Who_Am_I()
{
return this->m_enumWho;
}
void * CNewPred::aalloc(int col, int row , int size)
{
int i;
void **buf1;
void *buf2;
buf1 = (void **)malloc(col*size);
if (buf1 == NULL) {
return ((void *)NULL);
}
buf2 = (void *)calloc(size,col*row);
if (buf2 == NULL) {
free(buf1);
return ((void *)NULL);
}
for(i=0; i<col;i++){
buf1[i] = (void *)((char *)buf2+ row*size*i );
}
return(buf1);
}
void CNewPred::afree(int **p)
{
free(p[0]);
free(p);
}
void CNewPred::SetNPRefBuf(NEWPRED_buf **pNewBuf, int vop_id, int iBufCnt)
{
pNewBuf[iBufCnt]->vop_id = vop_id;
CopyBuftoNPRefBuf(pNewBuf[iBufCnt]->iSlice, iBufCnt);
return;
}
void CNewPred::ChangeRefOfSliceYUV(const PixelC* ppxlcRef, const PixelC* Refbuf0,
Int iMBX, Int iMBY,CRct RefSize, char mode)
{
Int i=0;
Int MBA;
Int magnification;
Int flag = 0; // check whether padding in horizontal direction
Int head_x, length_x;
PixelC *left_pix, *right_pix, *point;
Int p, q;
PixelC* Refpoint = (PixelC *)ppxlcRef + RefSize.left;
switch(mode)
{
case 'Y':
CopyBufYtoRefY(Refbuf0, RefSize);
magnification = 1;
break;
case 'U':
CopyBufUtoRefU(Refbuf0, RefSize);
magnification = MB_SIZE/BLOCK_SIZE;
break;
case 'V':
CopyBufVtoRefV(Refbuf0, RefSize);
magnification = MB_SIZE/BLOCK_SIZE;
break;
default:
assert(0);
break;
}
MBA = NextSliceHeadMBA(iMBX, iMBY);
head_x = iMBX * MB_SIZE / magnification;
length_x = (((MBA - 1) % (m_iWidth / MB_SIZE)) + 1) * MB_SIZE / magnification - head_x;
if (length_x < 0)
length_x = m_iWidth / magnification - head_x;
if ((head_x == 0) && (length_x == m_iWidth/magnification))
flag = 1;
// padding in horizontal direction
if (flag == 0) {
for (p = 0; p < MB_SIZE / magnification; p++) {
left_pix = Refpoint + (-RefSize.left) + head_x;
right_pix = left_pix + length_x - 1;
point = Refpoint;
for (q = 0; q < head_x + (-RefSize.left); q++) {
memcpy(point++, left_pix, 1);
}
point = right_pix + 1;
for (q = 0; q < m_iWidth / magnification - head_x - length_x + (-RefSize.left); q++) {
memcpy(point++, right_pix, 1);
}
Refpoint += RefSize.width;
}
}
// padding above
Refpoint = (PixelC *)ppxlcRef + RefSize.left;
while(1) {
Refpoint -= RefSize.width;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -