⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 softidct.c

📁 大名鼎鼎的CE下播放软件,TCPPMP的源代码!!!2410下可以流畅的解QVGA的H264,MPEG4等格式.
💻 C
📖 第 1 页 / 共 3 页
字号:
			return ERR_NOT_SUPPORTED;

		if (Mode==0 && (p->Mode & IDCTMODE_QPEL))
		{
			p->IDCT.MComp8x8 = p->QPELMComp8x8;
			p->IDCT.MComp16x16 = p->QPELMComp16x16;
		}
		else
		{
			p->IDCT.MComp8x8 = (idctmcomp) SoftMComp8x8;
			p->IDCT.MComp16x16 = (idctmcomp) SoftMComp16x16;
		}

#if defined(CONFIG_IDCT_LOWRES)
		if (p->Shift == 1)
		{
			p->IDCT.Process = ProcessHalf[Mode];
			p->IDCT.Copy16x16 = Copy16x16Half[Mode];
			p->IDCT.Intra8x8 = (idctintra)Intra8x8Half;
		}
		else
		if (p->Shift == 2)
		{
			p->IDCT.Process = ProcessQuarter[Mode];
			p->IDCT.Intra8x8 = (idctintra)Intra8x8Quarter;
			p->IDCT.Copy16x16 = NULL;
		}
		else
#endif
#ifdef CONFIG_IDCT_SWAP
		if (p->Out.Format.Format.Video.Direction & DIR_SWAPXY)
		{
			p->IDCT.Process = ProcessSwap[Mode];
			p->IDCT.Copy16x16 = Copy16x16Swap[Mode];
			p->IDCT.Intra8x8 = p->Intra8x8Swap;
			p->IDCT.MComp8x8 = (idctmcomp) SoftMComp8x8Swap;
			p->IDCT.MComp16x16 = (idctmcomp) SoftMComp16x16Swap;

			if (Mode == 0)
			{
				p->Tab[0] = 2*(8*p->BufWidth);		//Y[0;0] -> Y[1;0]
				p->Tab[1] = 2*(8-8*p->BufWidth);	//Y[1;0] -> Y[0;1]
				p->Tab[2] = 2*(8*p->BufWidth);		//Y[0;1] -> Y[1;1]
			}
		}
		else
#endif
		{
			p->IDCT.Process = Process[Mode];
			p->IDCT.Copy16x16 = Copy16x16[Mode];
			p->IDCT.Intra8x8 = p->Intra8x8;
		}

#if defined(MIPS64)
		p->IDCT.Inter8x8 = Inter8x8Add;
#endif

	}
	return ConnectionUpdate((node*)p,IDCT_OUTPUT,p->Out.Pin.Node,p->Out.Pin.No);
}

#ifdef CONFIG_IDCT_SWAP
static int ChangeSwap(softidct* p)
{
	if (p->BufCount > 0)
	{
		int No;
		planes TmpPlanes;
		video TmpFormat;
		int Brightness;
		video Format[2];
		planes Planes[2];

		TmpFormat = p->Out.Format.Format.Video;
		TmpFormat.Width = p->BufWidth - 2*EDGE;
		TmpFormat.Height = p->BufHeight - 2*EDGE;

		if (SurfaceAlloc(TmpPlanes,&TmpFormat) == ERR_NONE)
		{
			if (Lock(p,0,Planes[0],&Brightness,&Format[0])==ERR_NONE)
			{
				SurfaceCopy(&Format[0],&TmpFormat,Planes[0],TmpPlanes,NULL);
				Unlock(p,0);
			}

			for (No=1;No<p->BufCount;++No)
				if (Lock(p,No,Planes[0],&Brightness,&Format[0])==ERR_NONE)
				{
					SwapInt(&p->BufWidth,&p->BufHeight);
					if (Lock(p,0,Planes[1],&Brightness,&Format[1])==ERR_NONE)
					{
						block Tmp;
						SurfaceRotate(&Format[0],&Format[1],Planes[0],Planes[1],DIR_SWAPXY);
						Unlock(p,0);

						SwapPByte(&p->Buffer[No],&p->Buffer[0]);
						Tmp = p->_Buffer[0];
						p->_Buffer[0] = p->_Buffer[No];
						p->_Buffer[No] = Tmp;
						p->BufBorder[No] = 0;
						SwapInt(&p->BufAlloc[No],&p->BufAlloc[0]);
					}
					SwapInt(&p->BufWidth,&p->BufHeight);
					Unlock(p,No);
				}

			SwapInt(&p->BufWidth,&p->BufHeight);
			if (Lock(p,0,Planes[0],&Brightness,&Format[0])==ERR_NONE)
			{
				SurfaceRotate(&TmpFormat,&Format[0],TmpPlanes,Planes[0],DIR_SWAPXY);
				Unlock(p,0);
				p->BufBorder[0] = 0;
			}
			SwapInt(&p->BufWidth,&p->BufHeight);

			SurfaceFree(TmpPlanes);
		}
	}

	p->Out.Format.Format.Video.Direction ^= DIR_SWAPXY;
	SwapInt(&p->Out.Format.Format.Video.Width,&p->Out.Format.Format.Video.Height);
	SwapInt(&p->OutWidth,&p->OutHeight);
	return UpdateFormat(p);
}
#endif

static int Send(softidct* p,tick_t RefTime,const flowstate* State);

static int VerifyShift(softidct* p,int Shift)
{
	// have to keep dword pitch alignment
	if (p->BufferWidth && Shift>0)
	{
		int AlignX = (8 << p->UVX2) - 1;
		int BufWidth = ((p->BufferWidth+AlignX)&~AlignX) >> (Shift+p->UVX2);
		if (BufWidth & 1)
		{
			Shift -= 2;
		}
		else
		if (BufWidth & 3)
		{
			--Shift;
		}
		if (Shift<0)
			Shift=0;
	}
	return Shift;
}

static int SetShift(softidct* p,int Shift,int Count)
{
#if !defined(CONFIG_IDCT_LOWRES)
	return ERR_NOT_SUPPORTED;
#else
	if (Shift<0 || Shift>2) 
		return ERR_NOT_SUPPORTED;

#ifdef CONFIG_IDCT_SWAP
	if (Shift>0 && (p->Out.Format.Format.Video.Direction & DIR_SWAPXY))
		ChangeSwap(p);
#endif

	Shift = VerifyShift(p,Shift);
	if (p->Shift != Shift)
	{
		flowstate State;
		blitfx FX;
		planes Src[MAXIDCTBUF];
		planes Dst;
		video SrcFormat;
		video DstFormat;
		uint8_t *TmpPtr = NULL;
		planes Tmp;
		block TmpBlock;
		int Diff = Shift - p->Shift;
		int i;

		if (AllocBlock(p->BufSize+16,&TmpBlock,0,HEAP_ANYWR))
		{
			TmpPtr = (uint8_t*)ALIGN16((uintptr_t)TmpBlock.Ptr);
			Tmp[0] = TmpPtr + EDGE + EDGE*p->BufWidth;
			Tmp[1] = TmpPtr + p->YToU + (EDGE >> p->UVX2) + (EDGE >> p->UVY2)*(p->BufWidth >> p->UVX2);
			Tmp[2] = (uint8_t*)Tmp[1] + (p->YToU >> (p->UVX2+p->UVY2));
		}

		for (i=0;i<Count;++i)
			Lock(p,i,Src[i],NULL,&SrcFormat);

		p->Out.Format.Format.Video.Width = p->OutWidth >> Shift;
		p->Out.Format.Format.Video.Height = p->OutHeight >> Shift;

		memset(&FX,0,sizeof(FX));
		if (Diff>0)
		{
			FX.ScaleX = SCALE_ONE >> Diff;
			FX.ScaleY = SCALE_ONE >> Diff;
		}
		else
		{
			FX.ScaleX = SCALE_ONE << -Diff;
			FX.ScaleY = SCALE_ONE << -Diff;
		}

		p->Shift = Shift;
		UpdateRounding(p);
		UpdateFormat(p);

		for (i=0;i<Count;++i)
		{
			if (TmpPtr)
				SurfaceCopy(&SrcFormat,&SrcFormat,Src[i],Tmp,NULL);

			if (p->BufAlloc[i] < p->BufSize)
			{
				uint8_t* Ptr;
				block Block;
				if (!AllocBuffer(p,i,&Block,&Ptr)) // realloc buffer if neccessary)
				{
					if (TmpPtr)
						FreeBlock(&TmpBlock);
					SetShift(p,Shift - Diff,i); // restore (shrinking won't need more memory)
					return ERR_OUT_OF_MEMORY;
				}
				FreeBlock(&p->_Buffer[i]);
				p->Buffer[i] = Ptr;
				p->_Buffer[i] = Block;
				p->BufAlloc[i] = p->BufSize;
			}

			if (TmpPtr)
			{
				Lock(p,i,Dst,NULL,&DstFormat);
				SurfaceCopy(&SrcFormat,&DstFormat,Tmp,Dst,&FX);
			}
			p->BufBorder[i] = 0;
		}

		if (TmpPtr)
			FreeBlock(&TmpBlock);

		State.CurrTime = TIME_RESEND;
		State.DropLevel = 0;
		Send(p,TIME_UNKNOWN,&State);
	}
	return ERR_NONE;
#endif
}

static int UpdateMode(softidct* p)
{
	if (p->Mode & ~p->ModeSupported)
		return ERR_NOT_SUPPORTED;

#ifdef CONFIG_IDCT_SWAP
	if (p->Mode && (p->Out.Format.Format.Video.Direction & DIR_SWAPXY))
		ChangeSwap(p);
#endif

#if defined(CONFIG_IDCT_LOWRES)
	if (p->Mode && p->Shift)
		return SetShift(p,0,p->BufCount);
#endif

	UpdateRounding(p);
	UpdateFormat(p);
	return ERR_NONE;
}

static int SetFormat(softidct* p, const video* Format)
{
	SetBufferCount(p,0,0);
	PacketFormatClear(&p->Out.Format);

	if (Format)
	{
		size_t Area;

		if (!(Format->Pixel.Flags & (PF_YUV420|PF_YUV422|PF_YUV444)))
			return ERR_NOT_SUPPORTED;

		p->Out.Format.Type = PACKET_VIDEO;
		p->Out.Format.Format.Video = *Format;
		if (p->Out.Format.Format.Video.Direction & DIR_SWAPXY)
			SwapInt(&p->Out.Format.Format.Video.Width,&p->Out.Format.Format.Video.Height);
		p->Out.Format.Format.Video.Direction = 0;
		p->Out.Format.Format.Video.Pixel.Flags |= PF_16ALIGNED | PF_SAFEBORDER;
		p->MaxCount = MAXBUF;
		p->Rounding = 0;

		Area = p->Out.Format.Format.Video.Width * p->Out.Format.Format.Video.Height;
		if (Area >= 1024*1024 && AvailMemory() < Area*2)
		{
			video Desktop;
			size_t DesktopArea;
			QueryDesktop(&Desktop);
			DesktopArea = Desktop.Width * Desktop.Height;
			if (Area >= DesktopArea*4 && p->Shift<1)
				p->Shift = 1;
			if (Area >= DesktopArea*16 && p->Shift<2)
				p->Shift = 2;
		}

		p->Shift = VerifyShift(p,p->Shift);

#if defined(MIPS64)
		if (p->Shift>0)
			return ERR_NOT_SUPPORTED; // fallback to mips32
#endif

		p->OutWidth = p->Out.Format.Format.Video.Width;
		p->OutHeight = p->Out.Format.Format.Video.Height;
		p->Out.Format.Format.Video.Width >>= p->Shift;
		p->Out.Format.Format.Video.Height >>= p->Shift;

		UpdateRounding(p);
	}

#ifdef FREESCALE_MX1
	if (p->MX1)
	{
		volatile int* Cmd = p->MX1-64; //0x22400
		volatile int* GCCR = p->MX1-6972; //0x1B810
		if (Format)
		{
			*GCCR |= 2;
			ThreadSleep(1);
			*Cmd = 0x284C+0x20;
			ThreadSleep(1);
			*Cmd = 0x284D;
		}
		else
		{
			*Cmd = 0x00;
			*GCCR &= ~2;
		}
	}
#endif

	return UpdateFormat(p);
}

static int Set(softidct* p, int No, const void* Data, int Size)
{
	flowstate State;
	int Result = ERR_INVALID_PARAM;

	switch (No)
	{
	case NODE_SETTINGSCHANGED:
		p->NeedLast = QueryAdvanced(ADVANCED_SLOW_VIDEO);
		break;

	case IDCT_SHOW: 
		SETVALUE(p->ShowNext,int,ERR_NONE); 
		if (p->ShowNext >= p->BufCount) p->ShowNext = -1;
		break;

	case FLOW_FLUSH:
		p->ShowCurr = -1;
		p->ShowNext = -1;
		return ERR_NONE;

	case IDCT_BACKUP: 
		assert(Size == sizeof(idctbackup));
		Result = IDCTRestore(&p->IDCT,(idctbackup*)Data);
		break;

	case IDCT_MODE: SETVALUECMP(p->Mode,int,UpdateMode(p),EqInt); break;
	case IDCT_BUFFERWIDTH: SETVALUE(p->BufferWidth,int,ERR_NONE); break;
	case IDCT_BUFFERHEIGHT: SETVALUE(p->BufferHeight,int,ERR_NONE); break;
	case IDCT_FORMAT:
		assert(Size == sizeof(video) || !Data);
		Result = SetFormat(p,(const video*)Data);
		break;

	case IDCT_OUTPUT|PIN_PROCESS: SETVALUE(p->Out.Process,packetprocess,ERR_NONE); break;

#ifdef CONFIG_IDCT_SWAP
	case IDCT_OUTPUT|PIN_FORMAT:
		assert(Size == sizeof(packetformat) || !Data);
		if (Data && QueryAdvanced(ADVANCED_IDCTSWAP) && !p->Shift && !p->Mode &&
			!(p->Out.Format.Format.Video.Pixel.Flags & PF_YUV422) &&
			PacketFormatRotatedVideo(&p->Out.Format,(packetformat*)Data,DIR_SWAPXY))
			Result = ChangeSwap(p);
		break;
#endif

	case IDCT_OUTPUT: SETVALUE(p->Out.Pin,pin,ERR_NONE); break;
	case IDCT_ROUNDING: SETVALUE(p->Rounding,bool_t,UpdateRounding(p)); break;
	case IDCT_SHIFT: 
		assert(Size == sizeof(int));
		Result = SetShift(p,*(const int*)Data,p->BufCount);
		break;

	case IDCT_BUFFERCOUNT:
		assert(Size == sizeof(int));
		Result = ERR_NONE;
		if (p->BufCount < *(const int*)Data)
			Result = SetBufferCount(p,*(const int*)Data,0);
		break;

	case FLOW_RESEND:
		State.CurrTime = TIME_RESEND;
		State.DropLevel = 0;
		Result = Send(p,TIME_UNKNOWN,&State);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -