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

📄 ddrawoverlay.cpp

📁 direct show
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// DDraw.cpp: implementation of the CDDraw class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "apierr.h"
#include "math.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define INITGUID
#include <objbase.h>
#include <initguid.h>
#include "Display.h"
#include <ddraw.h>
//#include "RECFILE.H"
//DLL_IMPORT CRecFile RecObj;

#pragma comment (lib,"ddraw.lib")

// Define some macros
#define INIT_DIRECTDRAW_STRUCT(x) (ZeroMemory(&x, sizeof(x)), x.dwSize=sizeof(x))
#define FULL_SCREEN_OVERLAY_UPDATE_HANDLE  ((void *) 0x4)
#pragma data_seg(".shared")
int Dllcnt=0;
int Objcnt=0;
//LPDIRECTDRAW g_lpDD2=0; 
LPDIRECTDRAWSURFACE3    g_lpDDSOverlay=0;     
DWORD    g_lpOverlayStartAddr=0;     
int      g_OverlayPitch=0;     
int      g_OverlayPixelDepth=0;
DWORD    g_OverlayClearColor=OVERLAYCLRCOLOR;
DWORD    g_OverlayDestColorKey=DESCOLORKEY;
int      g_OverlayPixelID=-1;
DWORD    g_ScreenH;
DWORD    g_ScreenW;
BYTE *   g_MaxOverlayStartAddr=0;
#pragma data_seg()

typedef struct {
HWND  hWnd;    //the window handle of this region belong to
int   PixelId; //IF ID<0 mean I do not support this pixel
int   PixelDepth; //BYTES
int   Pitch;
//DWORD MStartAddress; //the region mem start linear address
//location relative to screen
RECT  DRect; //in Screen Primary surface
RECT  SRect; //in Overlay surface
int   StartHeight; //the Region initialized height
int   StartWidth;  //the Region initialized width
}Region;

//struct DispRegion;

//Sub region state define
#define  BVIDEO    1 //AVIDEO=0
#define  PAGELOCK  2 //NODIRECTW=0

typedef struct {
void  * pMDispRgn;  //point main region ie DispRegion *
DWORD StartAddress; //the region mem start linear address
DWORD SrcBufAddress;//use for copy op
DWORD SrcBufH;      //use for copy op  number lines
DWORD SrcBufW_bytes;  //use for copy op, one line bytes
DWORD SrcBufPitch;   //use for copy op, one line wide bytes

DWORD SrcPitch;     //only use for software write mode
RECT  SrcRect;      //in system memory (for Blt transfer)
RECT  DesRect;      //in Overlay or Screen Primary surface
RECT  StartRect;    //the sub region initialized RECT
LPDIRECTDRAWSURFACE3 pSrcSurf;
LPDIRECTDRAWSURFACE3 pDesSurf;
int   HRatio;       //use for fix sub region
int   VRatio;
int   State;
//HANDLE VidBufMutex;
PVOID  VidBufLockVar;
} SubRegion;

typedef struct {
int   RgnType; //the region type
union {
 Region    MRgn;
 SubRegion SRgn;
	} u;
} DispRegion;

typedef struct DispRegion_List {
 DWORD ValidID;  //ID=0x10540001; for check if is a valid region 
 struct DispRegion_List * pfront;
 DispRegion  * pDispNode;
 struct DispRegion_List * pnext;
} DispRegionList;

//BYTE * g_MaxOverlayStartAddr=0;
int g_DispObjID=0;
extern unsigned int g_apierr;
//Disp Regon List Op
DispRegionList * pHeadList;
DispRegionList * pTailList;
int g_StartSearch=0;
int  m_NodeCounter;
BOOL DeleteNode(DispRegion * prgn);
//return one hRgn
DispRegion * AllocNode();
//insert to tail
DispRegionList * InsertNode(DispRegion * prgn);
//remove in any location
BOOL RemoveNode(DispRegionList *  pn);
void RemoveAllNode();
void StartSearchNode();
void StopSearchNode();
void * SearchOneNode(HANDLE hRgn);
BOOL ClearGDISurfaceRect(HWND hwnd, RECT * prect,COLORREF rgb);
HRESULT DDColorMatch(IDirectDrawSurface3 * pdds, COLORREF rgb);
BOOL ClearSurface( LPDIRECTDRAWSURFACE3 surf, RECT * rect,COLORREF rgb ,BOOL UseYUY2 );
BOOL FillYUY2OverlaySurface(LPDIRECTDRAWSURFACE3 surf,RECT * prect,COLORREF rgb);
BOOL FillSurface(LPDIRECTDRAWSURFACE3 surf,RECT * pdrect,DWORD Color,BOOL IsOverlay);
BOOL LockBuffer(PVOID * pLockVar, PVOID ownid,int waitms);
#define UnLockBuffer(pv) (* pv=0)

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
static LPDIRECTDRAW g_lpDD2=0; 
static LPDIRECTDRAWSURFACE3    g_lpDDSPrimary=0;   
//static LPDIRECTDRAWSURFACE     g_lpDDSPrimary=0;   
static LPDIRECTDRAWCLIPPER     g_lpDDClipper=0;      
static DDCAPS * g_pDrvCaps=0;
static DDCAPS * g_pHELCaps=0;
static DWORD    g_lpPrimaryStartAddr =0;
static DWORD    g_PrimaryPitch=0;
static int      g_PrimaryPixelDepth=0;
static BOOL g_MainDispRegionIsInstalled=FALSE;
//static int  g_InitMode;

// These are the pixel formats this app supports.  Most display adapters
// with overlay support will recognize one or more of these formats.
// The first on our list is the 16-bit RGB formats.  These have the widest
// support.
static DDPIXELFORMAT g_ddpfOverlayFormats[] = 
{   {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x7C00, 0x03e0, 0x001F, 0},   // 0: 16-bit RGB 5:5:5 (#define RGB555DD 0)
    {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0xF800, 0x07e0, 0x001F, 0},   // 1: 16-bit RGB 5:6:5 (#define RGB565DD 1)
    {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 24,  0xFF0000, 0xFF00, 0x00FF, 0},   // 2: 24-bit RGB 8:8:8 (#define RGB888DD 2)
    {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 32,  0xFF0000, 0xFF00, 0x00FF, 0},   // 2: 24-bit RGB 8:8:8 (#define RGB888DD 2)
//    {sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('U','Y','V','Y'),0,0,0,0,0}, // UYVY
{sizeof(DDPIXELFORMAT), DDPF_FOURCC,0x32595559,0,0,0,0,0} //3: 16 bit YUY2 (#define YUY2_FOURCCDD 3)
};  

//CreateSurface Mode  define
#define SYSMEMSURF  0
#define VIDMEMSURF  1

//err=2
CDDrawOverlay::CDDrawOverlay(int Mode)
{
  int pixid;
  m_PrimaryPixelID=-1;
  m_OK=FALSE;
  m_NodeCounter=0;
  m_Err.errloc=0;
  m_Err.err=0;
  m_FirstObj=FALSE;
  g_DispObjID=Dllcnt;
  //g_InitMode=Mode;
  try {
  pHeadList=NULL;
  pTailList=NULL;
  m_Err.err=InitDDraw();
  m_Err.errloc=FN_InitDDraw_LOC;
  if (m_Err.err) {throw apierr(DDRAW_BASEERR,"call InitDDraw err",TRUE);};

  if (!GetCaps()) {throw apierr(DDRAW_BASEERR+1,"call GetCaps err",TRUE);};
  if (!CreatePrimary()) {throw apierr(DDRAW_BASEERR+2,"call CreatePrimary err",TRUE);};
  if (!GetScreenDispParams()) {throw apierr(DDRAW_BASEERR+3,"call GetScreenDispParams err",TRUE);};
  pixid=GetRGBPixelID(-1);     
  if (pixid<0)
	{
	 ::MessageBox(0,"The Current Display Mode do not support my pixel Format!","Error",MB_OK);
	 DestoryPrimary();
     return ; //return 0
 	}
  m_PrimaryPixelID=pixid;

  //if only create ddraw primary then return
  if (!(Mode&SUPPORT_OVERLAY_WIN))
  {
   m_OK=TRUE;
   Objcnt++;
   return;
  };
  //if this is not the first obj then return true (do not need create overlay)
  if (Objcnt>0)
  {
   Objcnt++;
   m_OK=TRUE;
   return;
  }

  m_FirstObj=TRUE;

  //it is not first overlay object
  //need overlay 
  if (!IsSupportOverlay())
  {  //if do not support overlay only use primary
	 //DestoryPrimary();
	  g_OverlayPixelID=-1;
	  g_lpDDSOverlay=0;     
      g_lpOverlayStartAddr=0;     
      g_OverlayPitch=0;     
      g_OverlayPixelDepth=0;
	  g_MaxOverlayStartAddr=0;
      return ; //return false
  };

  if ((Mode&(SUPPORT_OVERLAYFULL_WIN|SUPPORT_VID_B))==(SUPPORT_OVERLAYFULL_WIN|SUPPORT_VID_B))
  {
     if((pixid=CreateOverlay(g_ScreenW,g_ScreenH,YUY2_FOURCCDD))<0)
		{throw apierr(DDRAW_BASEERR+16,"call CreateOverlay err",TRUE);};
   
     ClearSurface(g_lpDDSOverlay, NULL,g_OverlayClearColor,TRUE);
  }
  else if ((Mode&(SUPPORT_OVERLAYFULL_WIN))==SUPPORT_OVERLAYFULL_WIN)
  {
     if((pixid=CreateOverlay(g_ScreenW,g_ScreenH,-1))<0)
		{throw apierr(DDRAW_BASEERR+17,"call CreateOverlay err",TRUE);};
     ClearSurface(g_lpDDSOverlay, NULL,g_OverlayClearColor,FALSE);
  }
  else
  {
   m_Err.err=NOT_SUPPORT_ERR;
   m_Err.errloc=CHECK_PARAMS_LOC;
   return;
  }

  if (!DisplayOverlay(FULL_SCREEN_OVERLAY_UPDATE_HANDLE))
	 {throw apierr(DDRAW_BASEERR+18,"UpdateOverlay err",TRUE);};

  Objcnt++;
  g_OverlayPixelID=pixid;
  m_OK=TRUE;
  }

  catch(...)
  {
   //the error I do not expect
   if (!g_apierr)
		{throw apierr(DDRAW_BASEERR+EXCETPERROR,"except err in CDDraw::CDDraw()",TRUE);};    
  }

}

CDDrawOverlay::~CDDrawOverlay()
{
   if (m_OK)
   {
    try {
    DestoryAllRegions();   
    DestoryDDraw();
	}
	catch (...)
	{
     throw apierr(DDRAW_BASEERR+EXCETPERROR,"except err in CDDraw::~CDDraw()",TRUE);    
	 
	}
    m_OK=FALSE;
   }
}

BOOL CDDrawOverlay::IsTheClassOK()
{
 return m_OK;
}

BOOL  CDDrawOverlay::GetErrCode(ErrDispCode * pErr)
{
  if (pErr)
  {
   * pErr=m_Err;
   //clear err
   m_Err.err=0;
   m_Err.errloc=0;
   return TRUE;
  }
  else
   return FALSE;
}

HRESULT CDDrawOverlay::InitDDraw()
{
 HRESULT ddrval; 
 LPDIRECTDRAW lpDDraw1; 
// LPDIRECTDRAWSURFACE lpDDSPrimary;
// DDSURFACEDESC  desc;
// lpDDSPrimary=0;
 lpDDraw1=0;
// m_Ok=FALSE;
 ddrval = DirectDrawCreate(NULL, &lpDDraw1, NULL); 
 if (ddrval != DD_OK) return ddrval; 
 ddrval=lpDDraw1->QueryInterface(IID_IDirectDraw2,(void**)&g_lpDD2);
 lpDDraw1->Release();
 if (ddrval!=S_OK) return ddrval;
 ddrval=g_lpDD2->SetCooperativeLevel( 0, DDSCL_NORMAL);

 return ddrval;  
}

void CDDrawOverlay::DestoryDDraw()
{
// DestoryPrimary();
 if (Objcnt==1)
 {
   DestoryOverlay();
   Objcnt=0;
 }
 else
 {
  Objcnt--;
  if (Objcnt<0)
      Objcnt=0;
 };
 DestoryPrimary();

 if (g_lpDD2)
 { 
    g_lpDD2->Release(); 
	g_lpDD2=0;
 }
 
}

BOOL CDDrawOverlay::GetCaps()
{
 DDCAPS DrvCaps,HELCaps;
 HRESULT ddrval; 
 
 	ZeroMemory( &DrvCaps, sizeof(DDCAPS) );
	ZeroMemory( &HELCaps, sizeof(DDCAPS) );
	DrvCaps.dwSize = sizeof(DrvCaps);   //make sure DD knows size
	HELCaps.dwSize = sizeof(HELCaps);   //make sure DD knows size
    ddrval=g_lpDD2->GetCaps(&DrvCaps,&HELCaps);
	m_Err.err=ddrval;
	m_Err.errloc=DD_GetCaps_LOC;
	if (ddrval!=DD_OK) return FALSE;
	g_pDrvCaps=&DrvCaps;
    g_pHELCaps=&HELCaps;
    OutPutCaps();
	g_pDrvCaps=0;
    g_pHELCaps=0;
	return TRUE; 
}

BOOL CDDrawOverlay::GetCaps(MyCaps * pMyHWCaps,MyCaps * pMyHELCaps)
{
 BOOL ret=FALSE;
 try {
 if (!m_OK) return FALSE;
 memcpy (pMyHWCaps,&m_MyHWCaps,sizeof(m_MyHWCaps));
 memcpy (pMyHELCaps,&m_MyHELCaps,sizeof(m_MyHELCaps));
 ret=TRUE;
 }
 catch(...)
 {
   throw apierr(DDRAW_BASEERR+EXCETPERROR,"except err in CDDraw::GetCaps",TRUE);    
 }
 return ret;
}


void CDDrawOverlay::OutPutCaps()
{
 ZeroMemory( &m_MyHWCaps, sizeof(m_MyHWCaps) );
 if (g_pDrvCaps)
 {
 m_MyHWCaps.Blt=g_pDrvCaps->dwCaps&DDCAPS_BLT;
 m_MyHWCaps.BltStetch=g_pDrvCaps->dwCaps&DDCAPS_BLTSTRETCH;
 m_MyHWCaps.BltSys=g_pDrvCaps->dwCaps&DDCAPS_CANBLTSYSMEM;
 //pMyHWCaps->BltQueue=g_pDrvCaps->dwCaps&DDCAPS_BLTQUEUE;
 m_MyHWCaps.BltFOURCC=g_pDrvCaps->dwCaps&DDCAPS_BLTFOURCC;
 m_MyHWCaps.Overlay=g_pDrvCaps->dwCaps&DDCAPS_OVERLAY;
 m_MyHWCaps.OverlayFOURCC=g_pDrvCaps->dwCaps&DDCAPS_OVERLAYFOURCC;
 m_MyHWCaps.OverlayStretch=g_pDrvCaps->dwCaps&DDCAPS_OVERLAYSTRETCH;
 m_MyHWCaps.OverlayDesColorKey=g_pDrvCaps->dwCKeyCaps & DDCKEYCAPS_DESTOVERLAY;
 m_MyHWCaps.OverlaySrcColorKey=g_pDrvCaps->dwCKeyCaps & DDCKEYCAPS_SRCOVERLAY;
 //m_MyHWCaps.OverlayClip=g_pDrvCaps->dwCaps&DDCAPS_OVERLAYCANTCLIP;
// m_MyHWCaps.AutoFlipOverlay=g_pDrvCaps.;
 m_MyHWCaps.dwNumFourCCCodes=g_pDrvCaps->dwNumFourCCCodes;
// minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3
 m_MyHWCaps.dwMinOverlayStretch=g_pDrvCaps->dwMinOverlayStretch;
 // maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3
 m_MyHWCaps.dwMaxOverlayStretch=g_pDrvCaps->dwMaxOverlayStretch;	
 // maximum number of visible overlays
 m_MyHWCaps.dwMaxVisibleOverlays=g_pDrvCaps->dwMaxVisibleOverlays;	
 // current number of visible overlays
 m_MyHWCaps.dwCurrVisibleOverlays=g_pDrvCaps->dwCurrVisibleOverlays;	

//BLT Caps
 //system to video
 m_MyHWCaps.SysToVidBlt=g_pDrvCaps->dwSVBCaps;
//video to system 
 m_MyHWCaps.VidToSysBlt=g_pDrvCaps->dwVSBCaps;
 m_MyHWCaps.dwAlignBoundarySrc=g_pDrvCaps->dwAlignBoundarySrc;
 m_MyHWCaps.dwAlignSizeSrc=g_pDrvCaps->dwAlignSizeSrc;
 m_MyHWCaps.dwAlignBoundaryDest=g_pDrvCaps->dwAlignBoundaryDest;
 m_MyHWCaps.dwAlignSizeDest=g_pDrvCaps->dwAlignSizeDest;
 }
 ZeroMemory( &m_MyHELCaps, sizeof(m_MyHELCaps) );
 if (g_pHELCaps)
 {
 m_MyHELCaps.Blt=g_pHELCaps->dwCaps&DDCAPS_BLT;
 m_MyHELCaps.BltStetch=g_pHELCaps->dwCaps&DDCAPS_BLTSTRETCH;
 m_MyHELCaps.BltSys=g_pHELCaps->dwCaps&DDCAPS_CANBLTSYSMEM;
 //m_MyHWCaps.BltQueue=g_pDrvCaps.dwCaps&DDCAPS_BLTQUEUE;
 
 m_MyHELCaps.Overlay=g_pHELCaps->dwCaps&DDCAPS_OVERLAY;
 m_MyHELCaps.OverlayFOURCC=g_pHELCaps->dwCaps&DDCAPS_OVERLAYFOURCC;
 m_MyHELCaps.BltFOURCC=g_pHELCaps->dwCaps&DDCAPS_BLTFOURCC;
 m_MyHELCaps.OverlayStretch=g_pHELCaps->dwCaps&DDCAPS_OVERLAYSTRETCH;
 //pMyHELCaps.OverlayClip=g_pHELCaps->dwCaps&DDCAPS_OVERLAYCANTCLIP;
// pMyHELCaps.AutoFlipOverlay=g_DrvCaps.;
// minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3
 m_MyHELCaps.dwMinOverlayStretch=g_pHELCaps->dwMinOverlayStretch;
 // maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3
 m_MyHELCaps.dwMaxOverlayStretch=g_pHELCaps->dwMaxOverlayStretch;	
 // maximum number of visible overlays
 m_MyHELCaps.dwMaxVisibleOverlays=g_pHELCaps->dwMaxVisibleOverlays;	
 // current number of visible overlays
 m_MyHELCaps.dwCurrVisibleOverlays=g_pHELCaps->dwCurrVisibleOverlays;	

//BLT Caps
 //system to video
 m_MyHELCaps.SysToVidBlt=g_pHELCaps->dwSVBCaps;
//video to system 
 m_MyHELCaps.VidToSysBlt=g_pHELCaps->dwVSBCaps;
 }
}

//the Primary and Backbuff Surf is FULL screen
BOOL CDDrawOverlay::CreatePrimary(BOOL IsSupportFlip)
{
	HRESULT ddrval; 
    DDSURFACEDESC ddsd;  // A surface description structure
	DDSURFACEDESC DDSDesc;

    // Create the primary surface.  The primary surface is the full screen -
    // since we're a windowed app - we'll just write to the portion of the
    // screen within our window.
	INIT_DIRECTDRAW_STRUCT(ddsd);
    //memset(&ddsd, 0, sizeof(ddsd)); // Set all fields of struct to 0 and set .dwSize to

⌨️ 快捷键说明

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