gps/GPSResources/tcpmp/common/softidct/block.h

290 lines
7.7 KiB
C
Raw Normal View History

2019-05-01 12:32:35 +00:00
/*****************************************************************************
*
* This program is free software ; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: block.h 327 2005-11-04 07:09:17Z picard $
*
* The Core Pocket Media Player
* Copyright (c) 2004-2005 Gabor Kovacs
*
****************************************************************************/
#if defined(HALF)
#define Block4x4 IDCT_Block4x4
#define MV_X(v) ((v<<16)>>18)
#define MV_Y(v) (v>>18)
#define MV_SUB(v) (v&3)+((v>>14)&12)
#define AddBlock8x8 AddBlock4x4
#define CopyBlock CopyBlock4x4
#elif !defined(SWAPXY)
#define Block4x8 IDCT_Block4x8
#define Block8x8 IDCT_Block8x8
#define MV_X(v) ((v<<16)>>17)
#define MV_Y(v) (v>>17)
#define MV_SUB(v) (v&1)+((v>>15)&2)
#else
#define Block4x8 IDCT_Block4x8Swap
#define Block8x8 IDCT_Block8x8Swap
#define MV_X(v) (v>>17)
#define MV_Y(v) ((v<<16)>>17)
#define MV_SUB(v) ((v<<1)&2)+((v>>16)&1)
#endif
void Intra8x8(softidct* p,idct_block_t *Block,int Length,int ScanType)
{
Statistics(Block,Length,ScanType,0);
#ifdef QUARTER
IDCT_Block2x2(Block,p->DstPtr,p->CurrPitch,NULL);
#elif defined(HALF)
Block4x4(Block,p->DstPtr,p->CurrPitch,NULL);
#else
#ifdef SWAP8X4
if (ScanType!=IDCTSCAN_ALT_VERT && (Length < 11 || (Length<20 && Block[32]==0)))
Block4x8(Block,p->DstPtr,p->CurrPitch,NULL);
#else
if (ScanType!=IDCTSCAN_ALT_HORI && Length < 15)
Block4x8(Block,p->DstPtr,p->CurrPitch,NULL);
#endif
else
Block8x8(Block,p->DstPtr,p->CurrPitch,NULL);
#endif
EMMS();
IncPtr(p,0,0);
}
#if !defined(MIPS64) && !defined(QUARTER)
void Inter8x8BackFwd(softidct* p,idct_block_t *Block,int Length)
{
uint8_t* Ptr;
int MV;
if (Length)
{
// mcomp and idct (using tmp buffer)
Statistics(Block,Length,0,2);
if (p->MVBack)
{
MV = *(p->MVBack++);
Ptr = p->RefPtr[0] + MV_X(MV) + p->CurrPitch * MV_Y(MV);
if (Ptr >= p->RefMin[0] && Ptr < p->RefMax[0])
p->CopyBlock[MV_SUB(MV)](Ptr,p->Tmp,p->CurrPitch,8);
if (p->MVFwd)
{
MV = *(p->MVFwd++);
Ptr = p->RefPtr[1] + MV_X(MV) + p->CurrPitch * MV_Y(MV);
if (Ptr >= p->RefMin[1] && Ptr < p->RefMax[1])
{
#if defined(MIPS32)
p->CopyBlock[MV_SUB(MV)](Ptr,p->Tmp+64,p->CurrPitch,8);
AddBlock8x8(p->Tmp+64,p->Tmp,8,8);
#else
#ifdef HALF
TableAddBlock4x4[MV_SUB(MV)](Ptr,p->Tmp,p->CurrPitch);
#else
p->AddBlock[MV_SUB(MV)](Ptr,p->Tmp,p->CurrPitch);
#endif
#endif
}
}
}
else
if (p->MVFwd)
{
MV = *(p->MVFwd++);
Ptr = p->RefPtr[1] + MV_X(MV) + p->CurrPitch * MV_Y(MV);
if (Ptr >= p->RefMin[1] && Ptr < p->RefMax[1])
p->CopyBlock[MV_SUB(MV)](Ptr,p->Tmp,p->CurrPitch,8);
}
#ifdef HALF
if (Length == 1)
IDCT_Const4x4((Block[0]+4) >> 3,p->DstPtr,p->CurrPitch,p->Tmp);
else
Block4x4(Block,p->DstPtr,p->CurrPitch,p->Tmp);
#else
if (Length == 1)
IDCT_Const8x8((Block[0]+4) >> 3,p->DstPtr,p->CurrPitch,p->Tmp);
#ifdef SWAP8X4
else if (Length < 11 || (Length<20 && Block[32]==0))
Block4x8(Block,p->DstPtr,p->CurrPitch,p->Tmp);
#else
else if (Length < 15)
Block4x8(Block,p->DstPtr,p->CurrPitch,p->Tmp);
#endif
else
Block8x8(Block,p->DstPtr,p->CurrPitch,p->Tmp);
#endif
}
else
{
// interpolate back and foward (using tmp buffer)
if (p->MVBack && p->MVFwd)
{
MV = *(p->MVBack++);
Ptr = p->RefPtr[0] + MV_X(MV) + p->CurrPitch * MV_Y(MV);
if (Ptr >= p->RefMin[0] && Ptr < p->RefMax[0])
p->CopyBlock[MV_SUB(MV)](Ptr,p->Tmp,p->CurrPitch,8);
MV = *(p->MVFwd++);
Ptr = p->RefPtr[1] + MV_X(MV) + p->CurrPitch * MV_Y(MV);
if (Ptr >= p->RefMin[1] && Ptr < p->RefMax[1])
{
#if defined(MIPS32)
p->CopyBlock[MV_SUB(MV)](Ptr,p->DstPtr,p->CurrPitch,p->CurrPitch);
AddBlock8x8(p->Tmp,p->DstPtr,8,p->CurrPitch);
#else
#ifdef HALF
TableAddBlock4x4[MV_SUB(MV)](Ptr,p->Tmp,p->CurrPitch);
// copy Tmp to Dst
CopyBlock4x4(p->Tmp,p->DstPtr,8,p->CurrPitch);
#else
p->AddBlock[MV_SUB(MV)](Ptr,p->Tmp,p->CurrPitch);
// copy Tmp to Dst
CopyBlock8x8(p->Tmp,p->DstPtr,8,p->CurrPitch);
#endif
#endif
}
}
else
if (p->MVBack)
{
MV = *(p->MVBack++);
Ptr = p->RefPtr[0] + MV_X(MV) + p->CurrPitch * MV_Y(MV);
if (Ptr >= p->RefMin[0] && Ptr < p->RefMax[0])
p->CopyBlock[MV_SUB(MV)](Ptr,p->DstPtr,p->CurrPitch,p->CurrPitch);
}
else
if (p->MVFwd)
{
MV = *(p->MVFwd++);
Ptr = p->RefPtr[1] + MV_X(MV) + p->CurrPitch * MV_Y(MV);
if (Ptr >= p->RefMin[1] && Ptr < p->RefMax[1])
p->CopyBlock[MV_SUB(MV)](Ptr,p->DstPtr,p->CurrPitch,p->CurrPitch);
}
}
EMMS();
IncPtr(p,1,1);
}
void Inter8x8Back(softidct* p,idct_block_t *Block,int Length)
{
uint8_t* Ptr;
int MV;
if (Length)
{
// mcomp and idct (using tmp buffer)
MV = *(p->MVBack++);
Ptr = p->RefPtr[0] + MV_X(MV) + p->CurrPitch * MV_Y(MV);
if (Ptr >= p->RefMin[0] && Ptr < p->RefMax[0])
p->CopyBlock[MV_SUB(MV)](Ptr,p->Tmp,p->CurrPitch,8);
Statistics(Block,Length,0,1);
#ifdef HALF
if (Length == 1)
IDCT_Const4x4((Block[0]+4) >> 3,p->DstPtr,p->CurrPitch,p->Tmp);
else
Block4x4(Block,p->DstPtr,p->CurrPitch,p->Tmp);
#else
if (Length == 1)
IDCT_Const8x8((Block[0]+4) >> 3,p->DstPtr,p->CurrPitch,p->Tmp);
#ifdef SWAP8X4
else if (Length < 11 || (Length<20 && Block[32]==0))
Block4x8(Block,p->DstPtr,p->CurrPitch,p->Tmp);
#else
else if (Length < 15 || (Length<26 && ((uint32_t*)Block)[2]==0 && ((uint32_t*)Block)[6]==0))
Block4x8(Block,p->DstPtr,p->CurrPitch,p->Tmp);
#endif
else
Block8x8(Block,p->DstPtr,p->CurrPitch,p->Tmp);
#endif
}
else
{
// only back mcomp
MV = *(p->MVBack++);
Ptr = p->RefPtr[0] + MV_X(MV) + p->CurrPitch * MV_Y(MV);
if (Ptr >= p->RefMin[0] && Ptr < p->RefMax[0])
p->CopyBlock[MV_SUB(MV)](Ptr,p->DstPtr,p->CurrPitch,p->CurrPitch);
}
EMMS();
IncPtr(p,1,0);
}
#if !defined(SWAPXY) && !defined(HALF)
void Inter8x8QPEL(softidct* p,idct_block_t *Block,int Length)
{
if (Length)
{
CopyBlock8x8(p->DstPtr,p->Tmp,p->CurrPitch,8); //todo: find better solution...
if (Length == 1)
IDCT_Const8x8((Block[0]+4) >> 3,p->DstPtr,p->CurrPitch,p->Tmp);
else if (Length < 15 || (Length<26 && ((uint32_t*)Block)[2]==0 && ((uint32_t*)Block)[6]==0))
IDCT_Block4x8(Block,p->DstPtr,p->CurrPitch,p->Tmp);
else
IDCT_Block8x8(Block,p->DstPtr,p->CurrPitch,p->Tmp);
}
EMMS();
if (*p->Ptr & 1)
p->IDCT.Inter8x8 = p->inter8x8uv;
IncPtr(p,1,1);
}
void Inter8x8GMC(softidct* p,idct_block_t *Block,int Length)
{
if (Length)
{
p->DrawGMC(p,p->Tmp,8);
if (Length == 1)
IDCT_Const8x8((Block[0]+4) >> 3,p->DstPtr,p->CurrPitch,p->Tmp);
else if (Length < 15 || (Length<26 && ((uint32_t*)Block)[2]==0 && ((uint32_t*)Block)[6]==0))
IDCT_Block4x8(Block,p->DstPtr,p->CurrPitch,p->Tmp);
else
IDCT_Block8x8(Block,p->DstPtr,p->CurrPitch,p->Tmp);
}
else
p->DrawGMC(p,p->DstPtr,p->CurrPitch);
EMMS();
IncPtr(p,0,0);
}
#endif
#endif
#undef MV_X
#undef MV_Y
#undef MV_SUB
#undef Block4x8
#undef Block8x8
#undef AddBlock8x8
#undef CopyBlock