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

📄 ddrawoverlay.cpp

📁 direct show
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    //ddsd.dwSize = sizeof(ddsd);     // Sizeof the variable - these two steps required for most DDraw structs
	if (!IsSupportFlip)
	{
    ddsd.dwFlags = DDSD_CAPS;       // Set flags for variables we're using...
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;  // Set the variables we said we would in dwFlags
	}
	else //create primary and BACKBUFFER surface
	{
   	ddsd.dwFlags =  DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
	ddsd.dwBackBufferCount = 1;
	}

	LPDIRECTDRAWSURFACE lpDDSTemp;
    ddrval = g_lpDD2->CreateSurface( &ddsd, &lpDDSTemp, NULL );
    if( ddrval != DD_OK )
    {
		m_Err.err=ddrval;
        m_Err.errloc=DD_CreateSurface_LOC;
	    return FALSE;
    }
    ddrval = lpDDSTemp->QueryInterface(IID_IDirectDrawSurface3, (void**)&g_lpDDSPrimary);
    lpDDSTemp->Release();
    if( ddrval != DD_OK )
    {
		m_Err.err=ddrval;
        m_Err.errloc=DD_QueryIDDrawSurface3_LOC;
		::MessageBox(0,"Disp Driver do not support DDSurface3","Error",0);
	    return FALSE;
    }

//    ddrval = g_lpDD2->CreateSurface(&ddsd, &g_lpDDSPrimary, NULL);
//	m_Err.err=ddrval;
//	if (ddrval!=DD_OK) return FALSE;
	INIT_DIRECTDRAW_STRUCT(DDSDesc);
	ddrval = g_lpDDSPrimary->Lock( NULL , &DDSDesc , DDLOCK_WAIT , NULL );
	m_Err.err=ddrval;
    m_Err.errloc=DD_Lock_LOC;
    if(ddrval!=DD_OK)
	{
       DestoryPrimary();
       g_lpDDSPrimary= 0;
	   return FALSE;
	}

	g_lpPrimaryStartAddr = (UINT)DDSDesc.lpSurface; 
    g_PrimaryPitch  = DDSDesc.lPitch;
    g_PrimaryPixelDepth=(DDSDesc.ddpfPixelFormat.dwRGBBitCount>>3); //BYTES
	g_ScreenH=DDSDesc.dwHeight;
    g_ScreenW=DDSDesc.dwWidth;
    g_lpDDSPrimary->Unlock( NULL );
   	return TRUE;

}

//-----------------------------------------------------------------------------
// Name: DestroyPrimary()
// Desc: Releases the primary surface
//-----------------------------------------------------------------------------
void CDDrawOverlay::DestoryPrimary()
{
    if (g_lpDDSPrimary)
    {
        g_lpDDSPrimary->Release();
        g_lpDDSPrimary = NULL;
		g_lpPrimaryStartAddr = 0; 
        g_PrimaryPitch  = 0;
		g_PrimaryPixelDepth=0;

    }
}
//return Surf pointer
void * CDDrawOverlay::CreateSurface(int Mode, DWORD w, DWORD h )
{
	LPDIRECTDRAWSURFACE3 surf;
    LPDIRECTDRAWSURFACE lpDDSTemp;
	HRESULT ddrval;
	//DWORD bytes=w*h*(m_display.displaydepth/8);
	DDSURFACEDESC desc;
	ZeroMemory( &desc, sizeof(desc) );
	desc.dwSize = sizeof(desc);
	desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
	desc.dwWidth = w;
	desc.dwHeight = h;
	if (Mode==VIDMEMSURF)
	    desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
    if (Mode==SYSMEMSURF)
		desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;

    ddrval = g_lpDD2->CreateSurface( &desc, &lpDDSTemp, NULL );
    if( ddrval != DD_OK )
    {
		m_Err.err=ddrval;
        m_Err.errloc=DD_CreateSurface_LOC;
	    return 0;
    }
    
	HRESULT r=g_lpDD2->CreateSurface( &desc, &lpDDSTemp, 0 );
	if (r!=DD_OK)
	{
	    m_Err.err=ddrval;
        m_Err.errloc=DD_CreateSurface_LOC;
	 	return 0; //create failed
	}
	ddrval = lpDDSTemp->QueryInterface(IID_IDirectDrawSurface3, (void**)&surf);
    lpDDSTemp->Release();
	if (ddrval!=DD_OK)
	{
        m_Err.err=ddrval;
        m_Err.errloc=DD_QueryIDDrawSurface3_LOC;
	}

	if ((ddrval=surf->PageLock(0))==DD_OK)
	    return surf; //success
	else
	{
     m_Err.err=ddrval;
     m_Err.errloc=DD_PageLock_LOC;
     DestorySurface(surf);
	 return 0;
	}
}

void CDDrawOverlay::DestorySurface(void * pSurf)
{
 LPDIRECTDRAWSURFACE3 pSurface=(LPDIRECTDRAWSURFACE3)pSurf;
 if (pSurf)
 {
  pSurface->PageUnlock(0);
  pSurface->Release();
 }
}

BOOL CDDrawOverlay::IsSupportOverlay()
{
 BOOL b;
 b=     ( m_MyHWCaps.Overlay
	     &&m_MyHWCaps.OverlayStretch
         &&m_MyHWCaps.OverlayDesColorKey
		 &&(m_MyHWCaps.dwMinOverlayStretch<=1000)
		 );
 if (!b)
 {
   m_Err.err=DO_NOT_SUPPORT_OVERLAY_ERR;
   m_Err.errloc=IsSupportOverlay_LOC;
   apierr(m_MyHWCaps.Overlay,"Caps.Overlay",FALSE);
   apierr(m_MyHWCaps.OverlayStretch,"Caps.OverlayStretch",FALSE);
   apierr(m_MyHWCaps.dwMinOverlayStretch,"Caps.dwMinOverlayStretch",FALSE);
   apierr(m_MyHWCaps.OverlayDesColorKey,"Caps.OverlayDesColorKey",TRUE);

 }
 return b;
         //&&m_MyHWCaps.OverlaySrcColorKey;
}

BOOL CDDrawOverlay::GetScreenDispParams()
{
    HDC dc;
	if (!g_lpDDSPrimary) return FALSE;
	m_Err.err=g_lpDDSPrimary->GetDC(&dc);
	m_Err.errloc=DD_GetDC_LOC;
    if (m_Err.err) return FALSE;
	m_display.displaydepth=GetDeviceCaps(dc, BITSPIXEL);
	m_display.left=0;
	m_display.top=0;
	m_display.right=GetDeviceCaps(dc, HORZRES );
	m_display.bottom=GetDeviceCaps(dc, VERTRES );
	g_lpDDSPrimary->ReleaseDC(dc);
	return TRUE;
}
//videomode=VIDEO_MODE_NTSC,VIDEO_MODE_PAL
BOOL  CDDrawOverlay::GetDispSubRegionVideoWindow(HANDLE hSubRgn,VIDEOWINDOW * pHWVidWind,BOOL VideoIsPAL)
{
  BOOL ret=FALSE;
  DispRegionList  * pn=(DispRegionList  *)hSubRgn;
  DispRegion * prgn;
  DispRegion * pmrgn;
  int w,h;
  ReSetSurfaceParams(this);
  //check if the hRgn is valid HANDLE
  if ((!pn)||(pn->ValidID!=0x10540001)) return FALSE;
  //the hSubRgn must be one sub region handle
  if (pn->pDispNode->RgnType&MASKMAINREIGON) return FALSE;
  //Set sub video window type
  //pn->pDispNode->RgnType|=SVidWinType;
  prgn=pn->pDispNode;
  pmrgn=(DispRegion *)prgn->u.SRgn.pMDispRgn;
	try 
	{
	if (!pHWVidWind) {throw apierr(DDRAW_BASEERR+ZEROPOINTER," in CDDraw::GetHWDispSubRegionParams err",TRUE);};
 	ZeroMemory( pHWVidWind, sizeof(VIDEOWINDOW) );
    //if (!GetNode(hSubRgn,&Rgn)) throw apierr(DDRAW_BASEERR+9," in CDDraw::GetHWDispSubRegionParams err");
    pHWVidWind->iTop=0;
    pHWVidWind->iLeft=0;
	if (prgn->RgnType==PRIMARY_DIRECTW)
	{
   	 h=prgn->u.SRgn.DesRect.bottom-prgn->u.SRgn.DesRect.top;
	 w=prgn->u.SRgn.DesRect.right-prgn->u.SRgn.DesRect.left;
 	 pHWVidWind->iPitch=pmrgn->u.MRgn.Pitch;
 	 pHWVidWind->uiSystemOverlayAddress=prgn->u.SRgn.StartAddress;
	}
	else if (prgn->RgnType==PRIMARY_NODIRECTW)
	{
   	 h=prgn->u.SRgn.SrcRect.bottom-prgn->u.SRgn.SrcRect.top;
	 w=prgn->u.SRgn.SrcRect.right-prgn->u.SRgn.SrcRect.left;
 	 pHWVidWind->iPitch=prgn->u.SRgn.SrcPitch;
  	 pHWVidWind->uiSystemOverlayAddress=prgn->u.SRgn.SrcBufAddress;
	}
    else if (prgn->RgnType==OVERLAY_DIRECTW)
	{
   	 h=prgn->u.SRgn.DesRect.bottom-prgn->u.SRgn.DesRect.top;
	 w=prgn->u.SRgn.DesRect.right-prgn->u.SRgn.DesRect.left;
 	 pHWVidWind->iPitch=pmrgn->u.MRgn.Pitch;
 	 pHWVidWind->uiSystemOverlayAddress=prgn->u.SRgn.StartAddress;

//   h=prgn->u.SRgn.SrcRect.bottom-prgn->u.SRgn.SrcRect.top;
//	 w=prgn->u.SRgn.SrcRect.right-prgn->u.SRgn.SrcRect.left;
// 	 pHWVidWind->iPitch=prgn->u.SRgn.SrcPitch;
//   pHWVidWind->uiSystemOverlayAddress=prgn->u.SRgn.StartAddress;
	}
	else if (prgn->RgnType==OVERLAY_NODIRECTW)
    {
   	 h=prgn->u.SRgn.SrcRect.bottom-prgn->u.SRgn.SrcRect.top;
	 w=prgn->u.SRgn.SrcRect.right-prgn->u.SRgn.SrcRect.left;
 	 pHWVidWind->iPitch=prgn->u.SRgn.SrcPitch;
  	 pHWVidWind->uiSystemOverlayAddress=prgn->u.SRgn.SrcBufAddress;
	}
	else return FALSE;

	pHWVidWind->iBottom=h;//prgn->u.SRgn.DesRect.bottom-prgn->u.SRgn.DesRect.top;
	pHWVidWind->iRight=w;//prgn->u.SRgn.DesRect.right-prgn->u.SRgn.DesRect.left;
	pHWVidWind->iPixelDepth=pmrgn->u.MRgn.PixelDepth;
	if (pmrgn->u.MRgn.PixelId==RGB565DD)
    {
  	  pHWVidWind->uiPixFormat=PF_RGB16_565;
	}
    else if (pmrgn->u.MRgn.PixelId==RGB555DD)
	{
 	  pHWVidWind->uiPixFormat=PF_RGB15_A555;
	}
    else if (pmrgn->u.MRgn.PixelId==RGB888DD)
	{
	  pHWVidWind->uiPixFormat=PF_RGB24_888;
	}
	else if (pmrgn->u.MRgn.PixelId==RGB888A)
	{
     pHWVidWind->uiPixFormat=PF_RGB32_A888;
	}
	else //PixelId==YUY2_FOURCC
       pHWVidWind->uiPixFormat=PF_YUV422;

 	pHWVidWind->uiHWCompress=1; //use hw compress
  	pHWVidWind->mirror=FALSE;
	//set default offset
    pHWVidWind->HOffset=8;//0;//8;
    pHWVidWind->VOffset=24;//0;//24;
    if (VideoIsPAL)
	{
		pHWVidWind->uiVideoMode=VIDEO_MODE_PAL;
		if (h<289)
           pHWVidWind->uiWindowMode=HALF_CCIR601;
		else
           pHWVidWind->uiWindowMode=FULL_CCIR601;
    }
    else
    {
		pHWVidWind->uiVideoMode=VIDEO_MODE_NTSC;
   		if (h<241)
           pHWVidWind->uiWindowMode=HALF_CCIR601;
		else
           pHWVidWind->uiWindowMode=FULL_CCIR601;
 
	}
 
    ret=TRUE;
	}
	catch(...)
	{
     if (!g_apierr)
	 {
       throw apierr(DDRAW_BASEERR+EXCETPERROR,"except err in CDDraw::GetHWDispSubRegionParams",TRUE);    
	 }  
	}
	return TRUE;
}

//videomode=VIDEO_MODE_NTSC,VIDEO_MODE_PAL
BOOL  CDDrawOverlay::GetDispSubRegionSubVideoWindow(HANDLE hSubRgn,SVIDEOWINDOW * pSVidWin,BOOL VideoIsPAL)
{
  BOOL b;
  VIDEOWINDOW vw;
  DispRegionList  * pn;
  DispRegion * pMrgn;
  if (!GetDispSubRegionVideoWindow(hSubRgn,&vw,VideoIsPAL))
      return FALSE;
  b=ConvertVidWinToSubVidWin(&vw ,pSVidWin);
  pn=(DispRegionList  *)hSubRgn;
  if (b&&(pn->pDispNode->RgnType&OVERLAY_NODIRECTW))
  {
   pMrgn=(DispRegion *)pn->pDispNode->u.SRgn.pMDispRgn;
   pn->pDispNode->u.SRgn.SrcBufW_bytes=pSVidWin->SizeW*(pMrgn->u.MRgn.PixelDepth);
   pn->pDispNode->u.SRgn.SrcBufH=pSVidWin->SizeH;
  }
  if (!b)
  {
   pSVidWin->uiSystemOverlayAddress=0;
  }
  return b;
}

//process the DispRegion not list 
BOOL DeleteNode(DispRegion * prgn)
{
 if (prgn==0) return FALSE;
 if (m_NodeCounter<=0) return FALSE;
 free(prgn);
 m_NodeCounter--;
 return TRUE;
}

//return one RgnNo
DispRegion *  AllocNode()
{
 DispRegion * p=0;
 p=(DispRegion *)malloc(sizeof(DispRegion)); 
 if (!p) return p;
 ZeroMemory( p, sizeof(DispRegion) );
 m_NodeCounter++;
 return p;
}

//process the DispRegion list 
DispRegionList * InsertNode(DispRegion * prgn)
{
 DispRegionList * p;
 p=(DispRegionList *)malloc(sizeof(DispRegionList)); 
 if (p==NULL) return p;
 p->ValidID=0x10540001;
 p->pDispNode=prgn;
 p->pnext=NULL;
 if (pHeadList==NULL)
 { //FIRST memory node process
   pHeadList=(DispRegionList *)p;
   pTailList=(DispRegionList *)p;
   p->pfront=NULL;
 }
 else //insert tail
 {
   p->pfront=pTailList;
   pTailList->pnext=(DispRegionList *)p;
   pTailList=p;
 }

 return p;
}

//process the DispRegion list 
BOOL RemoveNode(DispRegionList *  pn)
{
  BOOL bfind=FALSE;
  pn->ValidID=0;
  if ((!pn->pfront)&&(!pn->pnext))
  { //delete only node
    pHeadList=0;
    pTailList=0;
  }
  else if (!pn->pnext)
  { //delete tail node
    pTailList=pn->pfront;
    pTailList->pnext=0;
  }
  else if (!pn->pfront)   
  { //delete head node
    pHeadList=pHeadList->pnext;
	pHeadList->pfront=0;
  }
  else
  { //delete middle node
    pn->pfront->pnext=pn->pnext;
	pn->pnext->pfront=pn->pfront;
  }
  
  if (DeleteNode(pn->pDispNode))
  {
    free(pn);
 	bfind=TRUE;
  };

  return bfind;
}

/*
BOOL GetNode(HANDLE hRgn,DispRegion * pn)
{
 DispRegionList * p=(DispRegionList *) hRgn;
 DispRegion * p=(DispRegion *)hRgn;
 //copy the data
 * pn= * (this_pn->pDispnode);
 return TRUE;
}
*/

BOOL FindNode(DispRegion * pn,DispRegionList * front_pn,DispRegionList * this_pn)
{
  DispRegionList * p=pHeadList;
  DispRegionList * pfront=pHeadList;
  if (p==NULL) return FALSE;
  do {
		//find the node
       if (p->pDispNode==pn)
	   {
         if (p==pHeadList)
		 {
          front_pn=this_pn=p;
		 }
		 else 
         {
          front_pn=pfront;
          this_pn=p;
		 }
        return TRUE; 
       }  
	   //not this node,find next 
       pfront=p;      
	   p=p->pnext;
  	} while (p!=NULL); 

	return FALSE;
}



	//create disp Region in Primary  or Overlay surface with RGB16 or RGB24 or YUY2
	//the Region is the the client region of the window
	//if success return Region HANDLE >0 ,else RETURN 0
HANDLE  CDDrawOverlay::CreateDispRegion(HWND hDispWnd,UINT RgnType,int PixelId)
{
   	RECT rect;
	POINT po1,po2;
	DispRegion  * prgn;
	HANDLE hRgn=0;
    BOOL typeOverlay=RgnType&MASKPRIMARYOVERLAY;
	if (!m_OK)	return 0; // err
	if (typeOverlay&&!g_lpDDSOverlay)
	{
     m_Err.err=DO_NOT_SUPPORT_OVERLAY_ERR;
     m_Err.errloc=CreateDispRegion_LOC;
     return 0;
	}
    ReSetSurfaceParams(this);
/*    if ((g_InitMode&SUPPORT_SINGLE_MAIN_REGION)&&g_MainDispRegionIsInstalled)
    {

⌨️ 快捷键说明

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