unixsurf.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,131 行 · 第 1/3 页

CPP
1,131
字号

    for( i=0 ; i<m_nMultiBufferCount ; i++ )
    {
        HX_ASSERT( m_pXvImage[i] == NULL );

        if( m_bUseShm )
        {
	    XLockDisplay(m_display);
            m_pXvImage[i]  = XvShmCreateImage( m_display,
                                               m_nPortID,
                                               m_ulFourCCID,
                                               (char*)m_pcVideoBuf[i],
                                               m_surfaceSize.cx,
                                               m_surfaceSize.cy,
                                               &m_shmInfo[i]
                                               );
	    XUnlockDisplay(m_display);
        }
        else
        {
	    XLockDisplay(m_display);
            m_pXvImage[i] = XvCreateImage( m_display,
                                           m_nPortID,
                                           m_ulFourCCID,
                                           (char*)m_pcVideoBuf[i],
                                           m_surfaceSize.cx,
                                           m_surfaceSize.cy
                                           );
	    XUnlockDisplay(m_display);
        }
          
        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.
	XLockDisplay(m_display);
        m_nCompletionEventID = XShmGetEventBase(m_display) + ShmCompletion;
	XUnlockDisplay(m_display);
    }
   
#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;
    }
   
    XLockDisplay(m_display);
    nRetCode = XvQueryExtension(m_display, &ver, &rel, &req, &ev, &err);
    XUnlockDisplay(m_display);
    if( nRetCode != Success )
    {
        //Our X-Server doesn't support XVideo at all.
        bRetVal = FALSE;
        goto doneChecking;
    }
    XLockDisplay(m_display);
    nRetCode = XvQueryAdaptors( m_display,
                                DefaultRootWindow(m_display),
                                &nNumAdaptors,
                                &pAdaptorInfo );
    XUnlockDisplay(m_display);
    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;
                }
                XLockDisplay(m_display);
                pImageFormats = XvListImageFormats(m_display, pAdaptorInfo[i].base_id, &nImageCount);  
	        XUnlockDisplay(m_display);
                for( j=0 ; j<nImageCount ; j++)
                {
                    if(pImageFormats[j].id == ulFourCC)
                    {
                        for( k=0 ; k<pAdaptorInfo[i].num_ports; k++)
                        {
				XLockDisplay(m_display);
				int nSuc = XvGrabPort(m_display, pAdaptorInfo[i].base_id+k, CurrentTime);
                                XUnlockDisplay(m_display);
			       	if(Success == nSuc)
                            {
                                //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;
				XLockDisplay(m_display);
                                XvUngrabPort(m_display,
                                             pAdaptorInfo[i].base_id+k,
                                             CurrentTime );
				XUnlockDisplay(m_display);
                                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.
	     XLockDisplay(m_display);
            nSuc = XvGrabPort( m_display, nPortID, CurrentTime );
	     XUnlockDisplay(m_display);
            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
		XLockDisplay(m_display);
                m_atomColorKey = XInternAtom(m_display, "XV_COLOR_KEY", True);
		XUnlockDisplay(m_display);
                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.
		    XLockDisplay(m_display);
                    m_atomColorKey  = XInternAtom(m_display, "XV_COLORKEY", True);
		    XUnlockDisplay(m_display);
                }
                XLockDisplay(m_display);
                m_atomClipKey    = XInternAtom(m_display, "XV_PAINT_CLIPLIST", True);
		XUnlockDisplay(m_display);

                //Now set some of the atoms we read from the prefs
                if( None != m_atomClipKey)
                {
		     XLockDisplay(m_display);
                    XvSetPortAttribute(m_display, m_nPortID, m_atomClipKey, m_bPaintClipList);
		     XUnlockDisplay(m_display);
                }            

#if defined(HELIX_FEATURE_HARDWARE_COLOR_CONTROLS)
		XLockDisplay(m_display);
                m_atomBrightness = XInternAtom(m_display, "XV_BRIGHTNESS", True);
                m_atomContrast   = XInternAtom(m_display, "XV_CONTRAST", True);
                m_atomHue        = XInternAtom(m_display, "XV_HUE", True);
                m_atomSaturation = XInternAtom(m_display, "XV_SATURATION", True);
                //Get the min and max values for each settable atom.
                int nNumAttributes = 0;
                XvAttribute* pPAList = XvQueryPortAttributes( m_display,
                                                              m_nPortID,
                                                              &nNumAttributes );
		XUnlockDisplay(m_display);
                for( int nIdx=0; nIdx < nNumAttributes; nIdx++ )
                {
                    const char* pszName = pPAList[nIdx].name;
                    int         nMin    = pPAList[nIdx].min_value;
                    int         nMax    = pPAList[nIdx].max_value;
                    
                    stPortAttribute paTmp(nMin, nMax);
                    
                    if( !strcmp(pszName, "XV_BRIGHTNESS" ))
                    {
		         XLockDisplay(m_display);
                        XvGetPortAttribute( m_display, m_nPortID, m_atomBrightness, &m_nCurrBrightness );
			XUnlockDisplay(m_display);
                        paBrightness = paTmp;
                    }
                    if( !strcmp(pszName, "XV_CONTRAST" ))
                    {
		         XLockDisplay(m_display);
                        XvGetPortAttribute( m_display, m_nPortID, m_atomContrast, &m_nCurrContrast );
			XUnlockDisplay(m_display);
                        paContrast = paTmp;
                    }
                    if( !strcmp(pszName, "XV_HUE" ))
                    {
		         XLockDisplay(m_display);
                        XvGetPortAttribute( m_display, m_nPortID, m_atomHue, &m_nCurrHue );
			XUnlockDisplay(m_display);
                        paHue = paTmp;
                    }
                    if( !strcmp(pszName, "XV_SATURATION" ))
                    {
		         XLockDisplay(m_display);
                        XvGetPortAttribute( m_display, m_nPortID, m_atomSaturation, &m_nCurrSaturation );
			XUnlockDisplay(m_display);
                        paSaturation = paTmp;
                    }
                }
                
                if( pPAList )
		    XFree( pPAList );
#endif
                //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;
            }
        }
    } //if(bOverlay)...
#endif   
    return retVal;
}

HX_RESULT CUnixSurf::_LockInternalSurface( UCHAR**  ppSurfPtr,
                                           LONG32*  pnSurfPitch,
                                           HXxSize& notused )
{
    HX_RESULT retVal = HXR_OK;

    //Flip internal buffers....
    m_nCurrentBuffer++;
    if( m_nCurrentBuffer >= m_nMultiBufferCount )
    {
        m_nCurrentBuffer=0;
    }

    HX_ASSERT( m_pcVideoBuf[m_nCurrentBuffer] );
    HX_ASSERT( m_nVideoPitch != 0 );
   
    *ppSurfPtr   = (UCHAR*)m_pcVideoBuf[m_nCurrentBuffer];
    *pnSurfPitch = m_nVideoPitch;

    return retVal;
}

HX_RESULT CUnixSurf::_UnlockInternalSurface(UCHAR* pSurfPtr)
{
    return HXR_OK;
}

void CUnixSurf::_SetupDCObjects(HXxDC hxxDC, void** phOldBrush, void** phOldPen)
{
}

void CUnixSurf::_FillRectangle(HXxDC hxxDC,
                               UINT32 left, UINT32 top,
                               UINT32 right, UINT32 bottom)
{

⌨️ 快捷键说明

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