290 lines
7.7 KiB
C
Executable File
290 lines
7.7 KiB
C
Executable File
/*****************************************************************************
|
|
*
|
|
* 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
|
|
|
|
|
|
|