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

📄 ave2koverlay.c

📁 driver wdk
💻 C
📖 第 1 页 / 共 3 页
字号:
//
//File name: AVE2KOVERLAY.C
//This file contains code to control overlay function of SAA7146A
#include "ave2k.h"
#include "ave2kregs.h"
#include "ave2koverlay.h"
#include "SAA7111.h"
#include "hpsv.h"
#include "hpsh.h"
#include "rps.h"

//Predeclaration of local used functions
static ULONG Dcgx(ULONG x);
static void UploadVideo(PDEVICE_EXTENSION pDE);
static void Setup_HScale(PDEVICE_EXTENSION pDE, int nip, int nop, ULONG hxo);
static void Setup_VScale(PDEVICE_EXTENSION pDE, int nil, int nol, ULONG hyo);
void StopVideo(PDEVICE_EXTENSION pDE);
static void StartVideo(PDEVICE_EXTENSION pDE);
static void Shift(PDEVICE_EXTENSION pDE, int nChannel);
static void BuildClipInfo(ULONG ClipDmaBuffer[], PAVE2KCLIPLIST pClipList);
static void DisableAllClip(PDEVICE_EXTENSION pDE);
static void GetHScaleParas(int nip, int nop, ULONG hxo, ULONG *HPreScale, ULONG *HScale);
static void GetVScaleParas(int nil, int nol, ULONG hyo, ULONG *VScale, ULONG *VGain);
//#define NIP 703
//#define NIL  288
static void SetDual(PDEVICE_EXTENSION pDE);
static void SetFullDual(PDEVICE_EXTENSION pDE);
static void SetFrameRate(PDEVICE_EXTENSION pDE);
static BOOLEAN JudgeInterlace(PDEVICE_EXTENSION pDE);
#define HXO        0x10
#define HYO        0x1a

#define LOCALBUFFER 1

#if _WIN32_WINNT==0x0400
//Simulate win 2k ddk function.
//#define MmGetMdlPfnArray(pMdl) ((PULONG)(pMdl+1))
#endif

ULONG CaptureBitmap(PDEVICE_EXTENSION pDE, PMDL pMdl, PAVE2K_BITMAP_PARA pBitmapPara)
{
	int rpsIndex;
	ULONG outformat;
	int nChannel; 
	ULONG dFrame;
	int nWidth, nHeight;
	int pitch,depth,nFormat;
	ULONG nol;
	ULONG nil;
	int i;
	ULONG lPage[470];
	int nTotalPage;
	PHYSICAL_ADDRESS Phy;
	ULONG reg_Page, reg_Dma;
	PULONG pPage;
	LARGE_INTEGER Elapse;
	pPage=MmGetMdlPfnArray(pMdl);
	nWidth=pBitmapPara->nWidth;
	nHeight=pBitmapPara->nHeight;
	nChannel=pBitmapPara->nChannel;
	
	nFormat=pBitmapPara->nFormat;
	switch(nFormat)
	{
	case 0:
		depth=3;
		break;
	case 1:
		depth=4;
		break;
	case 2:
		depth=2;
		break;
	case 3:
		depth=1;
		break;
default:
		depth=3;
		break;
	}
/*	if(pBitmapPara->nFormat==0)
		depth=3;//RGB24
	else
		if(pBitmapPara->nFormat==2)
			depth=2;//YUYV
		else
			depth=4;//RGB32*/
	//1. pitch
	pitch = (nWidth*depth+3)&0xfffffffc;
	//pitch =	pDE->DisplayParameter.Pitch;
	//nWidth=320;
	//nHeight=288;
#if(LOCALBUFFER==0)
	//A new way to get total MDL page compatible with WIN2K
	nTotalPage=(MmSizeOfMdl(MmGetMdlVirtualAddress(pMdl), 
		MmGetMdlByteCount(pMdl)))/4;
	//2.
	//nTotalPage=(pMdl->Size-sizeof(MDL))/4;
	//nTotalPage=(800*600*4)/4096+2;
	for(i=0; i<nTotalPage; i++)
		//3.
		lPage[i]=*(pPage+i)<<12;
		//lPage[i]=pDE->DisplayParameter.PhysicalAddress+(i<<12);
	Phy=MmGetPhysicalAddress(lPage);
#endif
	//4.
#if(LOCALBUFFER)
	reg_Page=0x0;
#else
	reg_Page=(Phy.u.LowPart&0xfffff000)|(1<<11);//|0x08;
#endif
	//5.
#if(LOCALBUFFER)
	reg_Dma=pDE->BitmapCommonBuffer.DMAAddress;
#else
	reg_Dma=((Phy.u.LowPart&0xffc)<<10)|pMdl->ByteOffset;
	//reg_Dma=((Phy.u.LowPart&0xffc)<<10);
	//reg_Dma=pDE->DisplayParameter.PhysicalAddress;
#endif
	pDE->NIP = 702;//702->700
	if(pDE->VideoType[nChannel]==VIDEOTYPE_UNKNOWN)
	{
		//pDE->VideoType[nChannel] = GetVideoType(pDE, nChannel);
		int nVT=GetVideoType(pDE,nChannel);
		if(nVT==VIDEOTYPE_NONE)
			pDE->VideoType[nChannel]=pDE->nPreVideoType[nChannel];
		else
			pDE->VideoType[nChannel] =nVT;
	
	}
	if(pDE->VideoType[nChannel] == VIDEOTYPE_NTSC)
		pDE->NIL = 240;
	else
		pDE->NIL = 288;
	//Ave2kWriteRegister(pDE, DD1_INIT, 0x07000700);

    //------ setup HPS ------
	StopVideo(pDE);
	dFrame=reg_Dma;
	nol = nHeight;
	nil = pDE->NIL;
	if(nol>nil){
		Ave2kWriteRegister(pDE, BASE_ODD1, dFrame+pitch*nol);
		Ave2kWriteRegister(pDE, BASE_EVEN1, dFrame+pitch*(nol+1));
		Ave2kWriteRegister(pDE, PROT_ADDR1, dFrame-4);
		Ave2kWriteRegister(pDE, PITCH1, -pitch*2);
	}
	else{
		Ave2kWriteRegister(pDE, BASE_ODD1, dFrame+ pitch *nol);
		Ave2kWriteRegister(pDE, BASE_EVEN1, dFrame+ pitch *nol);
		Ave2kWriteRegister(pDE, PROT_ADDR1,  dFrame-4);
		Ave2kWriteRegister(pDE, PITCH1, -pitch);
		nWidth-=2;
		//reg_Page |= 0x08;//One-shot
	}
	Ave2kWriteRegister(pDE, BASE_PAGE1, reg_Page);
	Ave2kWriteRegister(pDE, NUM_LINE_BYTE1, (nil << 16) + pDE->NIP);
	Ave2kWriteRegister(pDE, MC2, (UPLD_DMA1<<16)|UPLD_DMA1);

	Setup_HScale(pDE, pDE->NIP, nWidth, HXO);
	Setup_VScale(pDE, pDE->NIL, nol, HYO);
	if(nChannel==0)
		Ave2kWriteRegister(pDE, HPS_CTRL, (HYO << 12));				// port_a & vert offs
	else
		Ave2kWriteRegister(pDE, HPS_CTRL, (1<<30)|(1<<28)|(HYO << 12));				// port_b & vert offs
	//------ setup BCS ------
	Ave2kWriteRegister(pDE, BCS_CTRL, 0x90430040);	// brig cont xx sat
	switch(depth)
	{
	case 4:
		outformat=RGB32;
		break;
	case 3:
		outformat=RGB24;
		break;
	case 2:
		outformat=YUV422;
		break;
	case 1:
		outformat=Y8;
		break;
default:
	    outformat=RGB24;
		break;
	}
	/*if(depth==4)
		outformat = RGB32;
	else
		if(depth==2)
			outformat = YUV422;
		else
			outformat = RGB24;*/
	pDE->outformat= (pDE->outformat & 0xffff)|(((0x00|outformat) << 24)+0x10000);
	Ave2kWriteRegister(pDE, CLIP_FORMAT_CTRL, pDE->outformat);				// outformat w.o. clip,chroma


	UploadVideo(pDE);
	//Ave2kWriteRegister(pDE, MC1, 0x20000000); //Disable EPS1
	Ave2kWriteRegister(pDE, RPS_TOV1, 0);
	Ave2kWriteRegister(pDE, ISR, MASK_28);//clear RPS interrupt
	pDE->RPS[1].PhysicalAddress=MmGetPhysicalAddress(&pDE->RPS[1].RPSBuffer[0]).u.LowPart;
	Ave2kWriteRegister(pDE, RPS_ADDR1, pDE->RPS[1].PhysicalAddress);
	//Fill the RPS sequence
	rpsIndex=0;
	{//start DMA1
	pDE->RPS[1].RPSBuffer[rpsIndex++]=CMD_WR_REG|(1<<8)|(MC1/4);
	pDE->RPS[1].RPSBuffer[rpsIndex++] =	(TR_E_1<<16)|TR_E_1;
	}
	//pDE->RPS[1].RPSBuffer[rpsIndex++]=CMD_STOP;
	//pDE->RPS[1].RPSBuffer[rpsIndex++]=CMD_UPLOAD|0x0C;
	if(nol>nil){
		pDE->RPS[1].RPSBuffer[rpsIndex++]=CMD_CLR_EVENT|RE_HPS_EAW;
		pDE->RPS[1].RPSBuffer[rpsIndex++]=CMD_PAUSE|RE_HPS_EAW;
	}
	pDE->RPS[1].RPSBuffer[rpsIndex++]=CMD_CLR_EVENT|RE_HPS_EAW;
	pDE->RPS[1].RPSBuffer[rpsIndex++]=CMD_PAUSE|RE_HPS_EAW;
	pDE->RPS[1].RPSBuffer[rpsIndex++]=CMD_CLR_EVENT|RE_HPS_EAW;
	pDE->RPS[1].RPSBuffer[rpsIndex++]=CMD_PAUSE|RE_HPS_EAW;
	//send interrupt
	pDE->RPS[1].RPSBuffer[rpsIndex++]=CMD_INTERRUPT|RE_HPS_EAW;
	//stop DMA1
	pDE->RPS[1].RPSBuffer[rpsIndex++]=CMD_WR_REG|(1<<8)|(MC1/4);
	pDE->RPS[1].RPSBuffer[rpsIndex++] =	(TR_E_1<<16);
	pDE->RPS[1].RPSBuffer[rpsIndex++]=CMD_STOP;
	KeClearEvent(&pDE->EventVDone);
	pDE->IERValue |= MASK_28;
	KeSynchronizeExecution(
	  pDE->pInterrupt,
	  Ave2kSetInterrupts,
	  pDE);
	//Ave2kWriteRegister(pDE, PCI_BT_V1, 0x07070707); //video1 burst length
	Ave2kWriteRegister(pDE, MC1, 0x20002000); //Enable EPS1
	Elapse.QuadPart = -(10 * 1000 * 100); 

	if(KeWaitForSingleObject(&pDE->EventVDone, UserRequest, UserMode, FALSE, &Elapse)==STATUS_TIMEOUT){
		KdPrint(("Timeout!\n"));
		//disable DMA1
		Ave2kWriteRegister(pDE, MC1,(TR_E_1<<16));
	}
	KeClearEvent(&pDE->EventVDone);

	pDE->IERValue &= ~MASK_28;
	KeSynchronizeExecution(
	  pDE->pInterrupt,
	  Ave2kSetInterrupts,
	  pDE);
	//Ave2kWriteRegister(pDE, PCI_BT_V1, 0x07070707); //video1 burst length
#if(LOCALBUFFER)
	memcpy(MmGetMdlVirtualAddress(pMdl), pDE->BitmapCommonBuffer.BaseAddress, pitch*(nol));
#endif
	return 1;
}
//This function make SAA7146A ready for overlay function
ULONG ave2kInitOverlay(PDEVICE_EXTENSION pDE)
{
  ULONG outformat;
  ULONG bSwitch=0;
	ULONG ClipDmaPhyAddr;
	StopVideo(pDE);
	Ave2kWriteRegister(pDE, RPS_TOV1, 0);
  if(0 == pDE->OverlayWindow.OpenClose && 0 == pDE->OverlayWindow.OpenClose2){
	  //StopVideo(pDE);
	  return 1;
  }
  if(1 == pDE->OverlayWindow.OpenClose && 1 == pDE->OverlayWindow.OpenClose2)
	  bSwitch=1;
  //Get current video type
	pDE->NIP =702;//702->652
	if(pDE->OverlayWindow.OpenClose){
		if(pDE->VideoType[0]==VIDEOTYPE_UNKNOWN)
		{
		//	pDE->VideoType[0] = GetVideoType(pDE, 0);
			int nVT=GetVideoType(pDE,0);
			if(nVT==VIDEOTYPE_NONE)
				pDE->VideoType[0]=pDE->nPreVideoType[0];
			else
				pDE->VideoType[0] =nVT;
		
		}
	}
	if(pDE->OverlayWindow.OpenClose2){
		if(pDE->VideoType[1]==VIDEOTYPE_UNKNOWN)
		{
		//	pDE->VideoType[1] = GetVideoType(pDE, 1);
			int nVT=GetVideoType(pDE,1);
			if(nVT==VIDEOTYPE_NONE)
				pDE->VideoType[1]=pDE->nPreVideoType[1];
			else
				pDE->VideoType[1] =nVT;
		}
	}
	if(pDE->VideoType[0] == VIDEOTYPE_NONE)
		pDE->VideoType[0] = pDE->VideoType[1];
	if(pDE->VideoType[1] == VIDEOTYPE_NONE)
		pDE->VideoType[1] = pDE->VideoType[0];
	if(pDE->VideoType[0] == VIDEOTYPE_NTSC)
		pDE->NIL = 240;
	else
		pDE->NIL = 288;
	if(pDE->VideoType[1] == VIDEOTYPE_NTSC)
		pDE->NIL2 = 240;
	else
		pDE->NIL2 = 288;


    //------ setup HPS ------
	if(!bSwitch){
		//StopVideo(pDE);
		if(pDE->OverlayWindow.OpenClose){
			if(pDE->OverlayWindow.Bottom - pDE->OverlayWindow.Top > 2*pDE->NIL)
				pDE->OverlayWindow.Bottom=pDE->OverlayWindow.Top+2*pDE->NIL;
			Shift(pDE, 0);
			Setup_HScale(pDE, pDE->NIP, (pDE->OverlayWindow.Right - pDE->OverlayWindow.Left), HXO);
			Setup_VScale(pDE, pDE->NIL, pDE->OverlayWindow.Bottom - pDE->OverlayWindow.Top, HYO);
			Ave2kWriteRegister(pDE, HPS_CTRL, (HYO << 12));				// port_a & vert offs
			ClipDmaPhyAddr=MmGetPhysicalAddress(&pDE->Clips[0].ClipDmaBuffer[0]).u.LowPart;
		}
		else{
			if(pDE->OverlayWindow.Bottom2 - pDE->OverlayWindow.Top2 > 2*pDE->NIL2)
				pDE->OverlayWindow.Bottom2=pDE->OverlayWindow.Top2+2*pDE->NIL2;
			Shift(pDE, 1);
			Setup_HScale(pDE, pDE->NIP, (pDE->OverlayWindow.Right2 - pDE->OverlayWindow.Left2), HXO);
			Setup_VScale(pDE, pDE->NIL2, pDE->OverlayWindow.Bottom2 - pDE->OverlayWindow.Top2, HYO);
		    Ave2kWriteRegister(pDE, HPS_CTRL, (1<<30)|(1<<28)|(HYO << 12));				// port_a & vert offs
			ClipDmaPhyAddr=MmGetPhysicalAddress(&pDE->Clips[1].ClipDmaBuffer[0]).u.LowPart;
		}
		Ave2kWriteRegister(pDE,BASE_ODD2, ClipDmaPhyAddr);
		Ave2kWriteRegister(pDE,BASE_EVEN2, ClipDmaPhyAddr);
		Ave2kWriteRegister(pDE,PROT_ADDR2, ClipDmaPhyAddr + 64*sizeof(ULONG));
		Ave2kWriteRegister(pDE, MC2,(UPLD_DMA2<<16)|UPLD_DMA2); 
	}
	else{
		//Ave2kWriteRegister(pDE, NUM_LINE_BYTE1, (pDE->NIL << 16) + pDE->NIP);
		if(pDE->OverlayWindow.Bottom - pDE->OverlayWindow.Top > pDE->NIL-4)
			pDE->OverlayWindow.Bottom=pDE->OverlayWindow.Top+pDE->NIL-4;
		if(pDE->OverlayWindow.Bottom2 - pDE->OverlayWindow.Top2 > pDE->NIL2-4)
			pDE->OverlayWindow.Bottom2=pDE->OverlayWindow.Top2+pDE->NIL2-4;
	}
  //------ setup BCS ------
  Ave2kWriteRegister(pDE, BCS_CTRL, 0x90430040);				// brig cont xx sat
  //--- outformat & clip --
    if(pDE->DisplayParameter.BitCount&0x80000000){
		outformat = YUV422;
	   /* if(pDE->DisplayParameter.BitCount==15)
			outformat = YUV2;
		else
			outformat = YUV422;*/
	}
	else{
		// 80 = 64K, 81= RGB24, 82 = True Color, 83=RGB1555
		if(pDE->DisplayParameter.Depth == 2) //64k colors
		{
			if(pDE->DisplayParameter.BitCount == 15)
				outformat = RGB1555;
			else
				outformat = RGB16;
		}
		else if(pDE->DisplayParameter.Depth == 3)//24 bits colors
			outformat = RGB24;	
		else if(pDE->DisplayParameter.Depth == 4)//32 bits colors
			outformat = RGB32;
		else if(pDE->DisplayParameter.Depth == 1)//8 bits colors
			outformat = RGB8;
	}
	pDE->outformat= (pDE->outformat & 0xffff)|(((0x00|outformat) << 24)+0x10000);
	Ave2kWriteRegister(pDE, CLIP_FORMAT_CTRL, pDE->outformat);				// outformat w.o. clip,chroma

	Ave2kWriteRegister(pDE,PITCH2,0x00000000);
	Ave2kWriteRegister(pDE,BASE_PAGE2,0x00000004);
	Ave2kWriteRegister(pDE,NUM_LINE_BYTE2,0x4040);

#if 0
	pDE->outformat= (pDE->outformat & 0xffff0000)|0x200;
	Ave2kWriteRegister(pDE, CLIP_FORMAT_CTRL, pDE->outformat);				// outformat w.o. clip,chroma
	//CHROMA KEY: BLUE
	Ave2kWriteRegister(pDE, CHROMA_KEY_RANGE, 0xe8f84858);
	//UL UU VL VU 0xe8f84a54=BLUE
#endif
	UploadVideo(pDE);
	Ave2kWriteRegister(pDE, MC1, ((TR_E_2<<16)|TR_E_2)); 
	//DisableAllClip(pDE);
	if(!bSwitch){
		if(pDE->FrameRate==FRMRATE_FULL)
			StartVideo(pDE);
		else
			SetFrameRate(pDE);
	}
	else{
		//if(pDE->Compress)
			SetDual(pDE);
		//else
		//	SetFullDual(pDE);
	}
	return 1;
}

static void SetFrameRate(PDEVICE_EXTENSION pDE)
{
	int rpsIndex,i;
	int RpsTov;
	int TovValues[]={9,4,3,2,1};
	int TovValue=TovValues[pDE->FrameRate-1];
	int Pause=1;
	//if(TovValue==1){
	//	TovValue=2;
	//	Pause=2;
	//}
	StartVideo(pDE);
	if(pDE->OverlayWindow.OpenClose){
		RpsTov=(2<<30)|(1<<29);
	}
	else{
		RpsTov=(2<<30)|(0<<29);
	}
	Ave2kWriteRegister(pDE, MC1, 0x20000000); //Disable EPS1
	pDE->RPS[1].PhysicalAddress=MmGetPhysicalAddress(&pDE->RPS[1].RPSBuffer[0]).u.LowPart;
	Ave2kWriteRegister(pDE, RPS_ADDR1, pDE->RPS[1].PhysicalAddress);
	//Fill the RPS sequence
	rpsIndex=0;
	{//start DMA1
	pDE->RPS[1].RPSBuffer[rpsIndex++]=CMD_WR_REG|(1<<8)|(MC1/4);
	pDE->RPS[1].RPSBuffer[rpsIndex++] =	(TR_E_1<<16)|TR_E_1;
	}
	for(i=0; i<TovValue; i++){

⌨️ 快捷键说明

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