📄 softidct.c
字号:
p->MaxCount = MAXBUF;
return Init(p);
}
else
{
if (p->Output.Node)
p->Output.Node->Set(p->Output.Node,p->Output.No | PACKET_FORMAT,NULL,0);
return ERR_NONE;
}
}
static int Send(softidct* p,packet* Packet,int* Dropped);
static int Set(softidct* p, int No, const void* Data, int Size )
{
packet Packet;
int Result = ERR_INVALID_PARAM;
switch (No)
{
case IDCT_SHOW:
SETVALUE(p->ShowNext,int,ERR_NONE);
if (p->ShowNext >= p->BufCount) p->ShowNext = -1;
break;
case FLOW_UPDATE:
CheckSwap(p);
Result = ERR_NONE;
break;
case FLOW_EMPTY:
p->ShowCurr = -1;
p->ShowNext = -1;
return ERR_NONE;
case IDCT_FORMAT:
//only block format is supported by softidct
if (Size == sizeof(int))
Result = (*(const int*)Data == IDCTFORMAT_BLOCK) ? ERR_NONE:ERR_NOT_SUPPORTED;
break;
case IDCT_BUFFERWIDTH: SETVALUE(p->BufferWidth,int,ERR_NONE); break;
case IDCT_BUFFERHEIGHT: SETVALUE(p->BufferHeight,int,ERR_NONE); break;
case IDCT_OUTPUT2|PACKET_FORMAT:
if (!Size || Size == sizeof(video))
{
if (!Size) Data = NULL;
Result = SetFormat(p,(const video*)Data);
}
break;
case IDCT_OUTPUT2:
if (Size == sizeof(pin))
{
Result = NodeSetPin(&p->Output,(pin*)Data,&p->OutputFormat,sizeof(video));
if (Result == ERR_NONE)
CheckSwap(p);
}
break;
case IDCT_ROUNDING:
if (Size == sizeof(bool_t))
Result = SetRounding(p,*(const bool_t*)Data);
break;
case IDCT_BUFFERCOUNT:
if (Size == sizeof(int))
{
Result = ERR_NONE;
if (p->BufCount < *(const int*)Data)
Result = SetBufferCount(p,*(const int*)Data,0);
}
break;
case FLOWBUFFER_RESEND:
Packet.CurrTime = -1;
Packet.RefTime = -1;
Packet.DropLevel = 0;
Result = Send(p,&Packet,NULL);
break;
}
return Result;
}
static int Get(softidct* p, int No, void* Data, int Size )
{
int Result = ERR_INVALID_PARAM;
switch (No)
{
case NODE_ID: GETVALUE(p->Id,int); break;
case IDCT_NATIVEFORMAT: GETVALUE(IDCTFORMAT_BLOCK,int); break;
case IDCT_FORMAT: GETVALUE(IDCTFORMAT_BLOCK,int); break;
case IDCT_OUTPUT2|PACKET_FORMAT: GETVALUE(p->OutputFormat,video); break;
case IDCT_OUTPUT2: GETVALUE(p->Output,pin); break;
case IDCT_ROUNDING: GETVALUE(p->Rounding,bool_t); break;
case IDCT_BUFFERCOUNT: GETVALUE(p->BufCount - p->LastTemp,int); break;
case IDCT_BUFFERWIDTH: GETVALUE(p->BufferWidth,int); break;
case IDCT_BUFFERHEIGHT: GETVALUE(p->BufferHeight,int); break;
case IDCT_SHOW: GETVALUE(p->ShowNext,int); break;
}
return Result;
}
static void Drop(softidct* p)
{
int i;
for (i=0;i<p->BufCount;++i)
p->BufFrameNo[i] = -1;
}
static int Send(softidct* p,packet* Packet,int* Dropped)
{
int Result = ERR_INVALID_DATA;
if (Packet->DropLevel)
{
if (Dropped)
++(*Dropped);
return ERR_NONE;
}
if (p->ShowNext < 0)
return ERR_NEED_MORE_DATA;
if (p->ShowCurr == p->ShowNext)
p->ShowCurr = -1;
if (Lock(p,p->ShowNext,Packet->Data,NULL,NULL) == ERR_NONE)
{
Lock(p,p->ShowCurr,Packet->LastData,NULL,NULL);
//DEBUG_MSG2(DEBUG_TEST,T("IDCT Show Next:%d Curr:%d"),p->ShowNext,p->ShowCurr);
Result = p->Output.Node->Set(p->Output.Node,p->Output.No,Packet,sizeof(packet));
Unlock(p,p->ShowCurr);
Unlock(p,p->ShowNext);
}
if (Result != ERR_BUFFER_FULL)
p->ShowCurr = p->ShowNext;
return Result;
}
static int FrameStart(softidct* p,int FrameNo,int DstNo,int BackNo,int FwdNo,int ShowNo,bool_t Drop)
{
int OldFrameNo;
#if defined( MIPS64_WIN32 )
// win32 doesn't support 64bit natively. thread and process
// changes won't save upper part of 64bit registers.
// we have to disable interrupt and make sure all 1KB
// code pages are in memory so no page loading is called
// during code execution
TouchPages(p);
DisableInterrupts();
p->LastY = -1;
#endif
#ifdef ARM
// ShowCurr will be the next "LastData" in output packet
// we don't want to lose it's content
if (p->ShowCurr == DstNo)
{
int SwapNo;
for (SwapNo=0;SwapNo<p->BufCount;++SwapNo)
if (SwapNo != DstNo && SwapNo != BackNo && SwapNo != FwdNo && SwapNo != ShowNo)
break;
if (SwapNo < p->BufCount || SetBufferCount(p,p->BufCount,1)==ERR_NONE)
{
//DEBUG_MSG2("IDCT Swap %d,%d",SwapNo,DstNo);
SwapPByte(&p->Buffer[SwapNo],&p->Buffer[DstNo]);
SwapPByte(&p->_Buffer[SwapNo],&p->_Buffer[DstNo]);
SwapInt(&p->BufFrameNo[SwapNo],&p->BufFrameNo[DstNo]);
SwapBool(&p->BufBorder[SwapNo],&p->BufBorder[DstNo]);
p->ShowCurr = SwapNo;
}
}
#endif
p->ShowNext = ShowNo;
OldFrameNo = p->BufFrameNo[DstNo];
p->BufFrameNo[DstNo] = FrameNo;
p->Dst = p->Buffer[DstNo];
p->Ref[0] = NULL;
p->Ref[1] = NULL;
p->RefMin[0] = NULL;
p->RefMin[1] = NULL;
p->RefMax[0] = NULL;
p->RefMax[1] = NULL;
if (BackNo>=0)
{
p->Ref[0] = p->Buffer[BackNo];
if (!p->BufBorder[BackNo])
{
p->BufBorder[BackNo] = 1;
FillEdgeYUV(p,p->Ref[0]);
}
p->RefMin[0] = p->Ref[0];
p->RefMax[0] = p->Ref[0] + p->BufSize -8-8*p->BufWidthUV;
}
if (FwdNo>=0)
{
p->Ref[1] = p->Buffer[FwdNo];
if (!p->BufBorder[FwdNo])
{
p->BufBorder[FwdNo] = 1;
FillEdgeYUV(p,p->Ref[1]);
}
p->RefMin[1] = p->Ref[1];
p->RefMax[1] = p->Ref[1] + p->BufSize -8-8*p->BufWidthUV;
}
p->BufBorder[DstNo] = 0; //invalidate border for dst
#ifndef MIPS64
#ifdef IDCTSWAP
if (p->OutputFormat.Direction & DIR_SWAPXY)
p->VMT.Inter8x8 = p->Inter8x8Swap[p->Ref[1]!=NULL];
else
#endif
p->VMT.Inter8x8 = p->Inter8x8[p->Ref[1]!=NULL];
#endif
return OldFrameNo;
}
static void FrameEnd(softidct* p)
{
#ifdef MIPS64_WIN32
EnableInterrupts();
#endif
}
static int Enum( softidct* p, int No, datadef* Param )
{
return NodeEnumType(&No,Param,NodeParams,FlowParams,FlowBufferParams,IDCTParams,NULL);
}
static softidct SoftIDCT =
{
// VMT
{
(nodeenum)Enum,
(nodeget)Get,
(nodeset)Set,
(idctsend)Send,
(idctdrop)Drop,
(idctlock)Lock,
(idctunlock)Unlock,
(idctframestart)FrameStart,
(idctframeend)FrameEnd,
NULL, //process
NULL, //copy
NULL, //mcomp16x16
NULL, //mcomp8x8
NULL, //intra8x8
NULL, //inter8x8
},
//AllCopyBlock[2][2][4]
{
{{ CopyBlock, CopyBlockHor, CopyBlockVer, CopyBlockHorVer },
{ CopyBlock, CopyBlockHorRound, CopyBlockVerRound, CopyBlockHorVerRound }},
#ifdef MIPS64
{{ CopyMBlock, CopyMBlockHor, CopyMBlockVer, CopyMBlockHorVer },
{ CopyMBlock, CopyMBlockHorRound, CopyMBlockVerRound, CopyMBlockHorVerRound }},
#endif
},
#if !defined(MIPS64) && !defined(MIPS32)
//AddBlock[4]
{AddBlock, AddBlockHor, AddBlockVer, AddBlockHorVer },
#endif
//Copy16x16[3]
{(idctcopy)Copy420,NULL,NULL},
//Process[3]
{(idctprocess)Process420,(idctprocess)Process422,(idctprocess)Process444},
//Intra8x8
(idctintra)Intra8x8,
#ifndef MIPS64
//Inter8x8[2]
{(idctinter)Inter8x8Back,(idctinter)Inter8x8BackFwd},
#endif
#ifdef IDCTSWAP
//Copy16x16Swap[3]
{(idctcopy)CopySwap420,NULL,NULL},
//ProcessSwap[3]
{(idctprocess)ProcessSwap420,(idctprocess)ProcessSwap422,(idctprocess)ProcessSwap444},
//Intra8x8Swap
(idctintra)Intra8x8Swap,
#ifndef MIPS64
//Inter8x8Swap[2]
{(idctinter)Inter8x8BackSwap,(idctinter)Inter8x8BackFwdSwap},
#endif
#endif
};
void SoftIDCT_Done()
{
NodeUnRegister((node*)&SoftIDCT);
}
idct* SoftIDCT_Init(int Id,int Priority)
{
softidct* p = &SoftIDCT;
// configure IDCT for current hardware configuration
#if defined(MMX)
if (!(QueryPlatform(PLATFORM_CAPS) & CAPS_X86_MMX))
return NULL;
#elif defined(ARM)
#if !defined(__palmos__)
if ((QueryPlatform(PLATFORM_CAPS) & CAPS_ARM_WMMX) && !QueryAdvPlatform(ADVPLATFORM_NOWMMX))
{
p->Intra8x8 = (idctintra)WMMXIntra8x8;
p->Inter8x8[0] = (idctinter)WMMXInter8x8Back;
p->Inter8x8[1] = (idctinter)WMMXInter8x8BackFwd;
#ifdef IDCTSWAP
p->Intra8x8Swap = (idctintra)WMMXIntra8x8Swap;
p->Inter8x8Swap[0] = (idctinter)WMMXInter8x8BackSwap;
p->Inter8x8Swap[1] = (idctinter)WMMXInter8x8BackFwdSwap;
#endif
p->AllCopyBlock[0][0][0] = WMMXCopyBlock;
p->AllCopyBlock[0][0][1] = WMMXCopyBlockHor;
p->AllCopyBlock[0][0][2] = WMMXCopyBlockVer;
p->AllCopyBlock[0][0][3] = WMMXCopyBlockHorVer;
p->AllCopyBlock[0][1][0] = WMMXCopyBlock;
p->AllCopyBlock[0][1][1] = WMMXCopyBlockHorRound;
p->AllCopyBlock[0][1][2] = WMMXCopyBlockVerRound;
p->AllCopyBlock[0][1][3] = WMMXCopyBlockHorVerRound;
p->AddBlock[0] = WMMXAddBlock;
p->AddBlock[1] = WMMXAddBlockHor;
p->AddBlock[2] = WMMXAddBlockVer;
p->AddBlock[3] = WMMXAddBlockHorVer;
}
else
#endif
if (QueryPlatform(PLATFORM_CAPS) & CAPS_ARM_5E)
{
if (QueryPlatform(PLATFORM_ICACHE) >= 32768)
{
p->AllCopyBlock[0][0][0] = FastCopyBlock;
p->AllCopyBlock[0][0][1] = FastCopyBlockHor;
p->AllCopyBlock[0][0][2] = FastCopyBlockVer;
p->AllCopyBlock[0][0][3] = FastCopyBlockHorVer;
p->AllCopyBlock[0][0][0] = FastCopyBlock;
p->AllCopyBlock[0][1][1] = FastCopyBlockHorRound;
p->AllCopyBlock[0][1][2] = FastCopyBlockVerRound;
p->AllCopyBlock[0][1][3] = FastCopyBlockHorVerRound;
p->AddBlock[0] = FastAddBlock;
p->AddBlock[1] = FastAddBlockHor;
p->AddBlock[2] = FastAddBlockVer;
p->AddBlock[3] = FastAddBlockHorVer;
}
else
{
p->AllCopyBlock[0][0][0] = PreLoadCopyBlock;
p->AllCopyBlock[0][0][1] = PreLoadCopyBlockHor;
p->AllCopyBlock[0][0][2] = PreLoadCopyBlockVer;
p->AllCopyBlock[0][0][3] = PreLoadCopyBlockHorVer;
p->AllCopyBlock[0][0][0] = PreLoadCopyBlock;
p->AllCopyBlock[0][1][1] = PreLoadCopyBlockHorRound;
p->AllCopyBlock[0][1][2] = PreLoadCopyBlockVerRound;
p->AllCopyBlock[0][1][3] = PreLoadCopyBlockHorVerRound;
p->AddBlock[0] = PreLoadAddBlock;
p->AddBlock[1] = PreLoadAddBlockHor;
p->AddBlock[2] = PreLoadAddBlockVer;
p->AddBlock[3] = PreLoadAddBlockHorVer;
}
}
#elif defined(MIPSVR41XX)
if (!(QueryPlatform(PLATFORM_CAPS) & CAPS_MIPS_VR41XX))
return NULL;
#endif
#if defined( MIPS64_WIN32 )
CodeFindPages(*(void**)&p->VMT.Enum,&p->CodeBegin,&p->CodeEnd,&p->CodePage);
#endif
p->Id = Id;
p->Tmp = (uint8_t*)ALIGN16(p->_Tmp);
p->MaxCount = MAXBUF;
p->BufCount = 0;
p->LastTemp = 0;
p->ShowCurr = -1;
p->ShowNext = -1;
SetRounding(p,0);
NodeRegister((node*)p,PRI_MAXIMUM);
return &p->VMT;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -