📄 unixsurf.cpp
字号:
XFree( m_pXvImage[i] );
m_pXvImage[i] = NULL;
}
}
}
m_nVideoPitch = 0;
HX_ASSERT( m_display );
//Clear BitmapInfo struct....
HXBitmapInfo bmi;
memset( &bmi, 0, sizeof(HXBitmapInfo) );
int nResult = MakeBitmap( &bmi,
sizeof(bmi),
m_nSurfaceCID,
m_surfaceSize.cx,
m_surfaceSize.cy,
NULL,
0);
if( nResult )
{
ShmHelp::Init(m_display);
m_bUseShm = ShmHelp::ShmAvailable();
for( i=0 ; i<m_nMultiBufferCount ; i++ )
{
if( m_bUseShm )
{
HX_RESULT retVal = ShmHelp::CreateSharedRegion( bmi.bmiHeader.biSizeImage,
&m_pcVideoBuf[i],
&m_nShmId[i],
&m_shmInfo[i]
);
if( retVal != HXR_OK )
{
HX_ASSERT("Can't alloc shared memory segment." == NULL );
m_nShmId[i] = -1;
m_pcVideoBuf[i] = NULL;
}
}
//did the shm alloc work?
if( m_pcVideoBuf[i] == NULL )
{
m_bUseShm = FALSE;
m_nShmId[i] = -1;
m_pcVideoBuf[i] = new UCHAR[bmi.bmiHeader.biSizeImage];
}
HX_ASSERT( m_pcVideoBuf );
}
m_nVideoPitch = GetBitmapPitch(&bmi);
}
HX_ASSERT( m_nVideoPitch != 0 );
//Now create the XvImage to blt to.....
HX_ASSERT( m_nPortID != -1 );
for( i=0 ; i<m_nMultiBufferCount ; i++ )
{
HX_ASSERT( m_pXvImage[i] == NULL );
if( m_bUseShm )
{
m_pXvImage[i] = XvShmCreateImage( m_display,
m_nPortID,
m_ulFourCCID,
(char*)m_pcVideoBuf[i],
m_surfaceSize.cx,
m_surfaceSize.cy,
&m_shmInfo[i]
);
}
else
{
m_pXvImage[i] = XvCreateImage( m_display,
m_nPortID,
m_ulFourCCID,
(char*)m_pcVideoBuf[i],
m_surfaceSize.cx,
m_surfaceSize.cy
);
}
if( m_pXvImage[i] == NULL )
{
HX_ASSERT("Could not create overlay surface"==NULL );
//XXgfw, well, what to do here????
}
}
if( m_bUseShm )
{
//Find the shm completion event ID.
m_nCompletionEventID = XShmGetEventBase(m_display) + ShmCompletion;
}
#endif
}
BOOL CUnixSurf::_OverlayAvailable(int nFourCCWanted, int* pnPortID )
{
BOOL bRetVal = FALSE;
#if defined(_LINUX) && defined(_OVERLAY)
if( !m_bUseOverlays )
{
return bRetVal;
}
unsigned int nNumAdaptors = 0;
int nImageCount = 0;
int nPortID = -1;
int i = 0;
int j = 0;
int k = 0;
unsigned int ver = 0;
unsigned int rel = 0;
unsigned int req = 0;
unsigned int ev = 0;
unsigned int err = 0;
int nRetCode = 0;
XvImageFormatValues *pImageFormats = NULL;
XvAdaptorInfo *pAdaptorInfo = NULL;
//First, we need to map our cid to a FourCC.
ULONG32 ulFourCC = 0;
switch(nFourCCWanted)
{
case -1:
//nothing requested
break;
case CID_I420:
ulFourCC = MAKEFOURCC('I','4','2','0');
break;
case CID_YV12:
ulFourCC = MAKEFOURCC('Y','V','1','2');
break;
case CID_YVU9:
ulFourCC = MAKEFOURCC('Y','V','U','9');
break;
case CID_YUY2:
ulFourCC = MAKEFOURCC('Y','U','Y','2');
break;
case CID_UYVY:
ulFourCC = MAKEFOURCC('U','Y','V','Y');
break;
default:
HX_ASSERT( "Unkown CID" == NULL );
}
if( m_pSite )
{
HX_ASSERT( m_pSite->GetWindow() );
m_display = (Display*)((m_pSite->GetWindow())->display);
}
HX_ASSERT( m_display );
//XXXgfw this code assumes that there is *only* one overlay available
//on a machine. We need to change this as more become available....
if( zm_pXvOwner != NULL )
{
//Someone owns the *one* overlay
goto doneChecking;
}
nRetCode = XvQueryExtension(m_display, &ver, &rel, &req, &ev, &err);
if( nRetCode != Success )
{
//Our X-Server doesn't support XVideo at all.
bRetVal = FALSE;
goto doneChecking;
}
nRetCode = XvQueryAdaptors( m_display,
DefaultRootWindow(m_display),
&nNumAdaptors,
&pAdaptorInfo );
if( nRetCode == Success && nNumAdaptors ) // pjg/gfw geForceII returns 0 adaptors with garbage return pointer
{
for(i=0 ; i<nNumAdaptors ; i++)
{
if(pAdaptorInfo[i].type & XvImageMask)
{
if( ulFourCC==0 )
{
//User just wants to know if we have overlays at all.
bRetVal = TRUE;
goto doneChecking;
}
pImageFormats = XvListImageFormats(m_display, pAdaptorInfo[i].base_id, &nImageCount);
for( j=0 ; j<nImageCount ; j++)
{
if(pImageFormats[j].id == ulFourCC)
{
for( k=0 ; k<pAdaptorInfo[i].num_ports; k++)
{
if(Success == XvGrabPort(m_display, pAdaptorInfo[i].base_id+k,
CurrentTime))
{
//XXXgfw later, when we see graphics cards under linux
//that have more than one overlay available we will need
//to update this code......
//Hey! We found one!
nPortID = pAdaptorInfo[i].base_id+k;
XvUngrabPort(m_display,
pAdaptorInfo[i].base_id+k,
CurrentTime );
break;
}
}
}
if(nPortID != -1)
break;
}
XFree(pImageFormats);
}
if(nPortID != -1)
break;
}
XvFreeAdaptorInfo(pAdaptorInfo);
if( nPortID != -1 )
{
bRetVal = TRUE;
if( NULL != pnPortID )
*pnPortID = nPortID;
m_ulFourCCID = ulFourCC;
}
// fprintf( stderr, "Found a port that supports %d(%p), it is %d\n",
// nFourCCWanted, (void*)ulFourCC,nPortID );
}
doneChecking:
#endif
return bRetVal;
}
HX_RESULT CUnixSurf::_GetCaps(UINT32 *pfSurfaceCaps)
{
*pfSurfaceCaps = 0;
if( _OverlayAvailable() )
{
*pfSurfaceCaps |= HX_OVERLAY;
}
return HXR_OK;
}
HX_RESULT CUnixSurf::_CreateOverlay(BOOL bOverlay, int cid, int x, int y)
{
HX_RESULT retVal = HXR_FAIL;
int nSuc = Success;
// fprintf( stderr, "CUnixSurf::_CreateOverlay(%p): bOverlay:%d cid:%d x,y: %d %d\n",
// this, bOverlay, cid, x, y);
if( x & 15 )
{
x = (x&~15)+16;
}
#if defined(_LINUX) && defined(_OVERLAY)
if( bOverlay )
{
int nPortID = 0;
BOOL bAvailable = FALSE;
bAvailable = _OverlayAvailable( cid, &nPortID );
if( bAvailable )
{
HX_ASSERT(m_display);
//Grab the port.
nSuc = XvGrabPort( m_display, nPortID, CurrentTime );
if( nSuc == Success )
{
//Take ownership of the overlay. A connection to the XServer
//can grab the overlay port as much as it wants so we can't
//rely on that to make sure that we only have one surface
//using the overlay.
m_nPortID = nPortID;
zm_pXvOwner = this;
//So far so good. Now we need to grab all of our atoms to control
//the overlay
m_atomColorKey = XInternAtom(m_display, "XV_COLOR_KEY", True);
if( m_atomColorKey == None )
{
//There isn't a naming convention for any of these atoms. we
//have to disover at run time what they are.
m_atomColorKey = XInternAtom(m_display, "XV_COLORKEY", True);
}
m_atomClipKey = XInternAtom(m_display, "XV_PAINT_CLIPLIST", True);
m_atomBrightness = XInternAtom(m_display, "XV_BRIGHTNESS", True);
m_atomContrast = XInternAtom(m_display, "XV_CONTRAST", True);
//Now set some of the atoms we read from the prefs
if( None != m_atomClipKey)
{
XvSetPortAttribute(m_display, m_nPortID, m_atomClipKey, m_bPaintClipList);
}
if( None!=m_atomBrightness && m_nBrightness!=-9999 )
{
XvSetPortAttribute(m_display, m_nPortID, m_atomBrightness, m_nBrightness);
}
if( None!=m_atomContrast && m_nContrast!=-9999 )
{
XvSetPortAttribute( m_display, m_nPortID, m_atomContrast, m_nContrast);
}
//Now we need to create the overlay surface???
m_surfaceSize.cx = x;
m_surfaceSize.cy = y;
m_nSurfaceCID = cid;
m_nBltMode = HX_OVERLAY_BLT;
_CreateBuffer();
//Return good.
retVal = HXR_OK;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -