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

📄 nullpdd.cpp

📁 Windows CE 5.0 摄像头分层驱动代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            PatBlt(hdc, x, y, nBoxWidth, nBoxHeight, BLACKNESS);

            // Delete the dc before the bitmap because it's still selected, deleting the dc deselects the bitmap.
            if(!DeleteObject(hdc))
            {
                DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR, (_T("BufferFill: Failed to delete allocated DC\r\n"))) ;
                return -1;
            }
        }
        if(!DeleteObject(hbmp))
        {
            DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR, (_T("BufferFill: Failed to delete allocated bitmap\r\n"))) ;
            return -1;
        }

    }
    else
    {
        DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR, (_T("BufferFill: OOM or unrecognized format\r\n"))) ;
        return -1;
    }

    // return the size of the image filled
    return(biSizeImage);    
}

DWORD CNullPdd::YUVBufferFill( ULONG ulModeType, PUCHAR pImage )
{
    PCS_VIDEOINFOHEADER pCsVideoInfoHdr = &m_pCurrentFormat[ulModeType].VideoInfoHeader;

    UINT biWidth        =   pCsVideoInfoHdr->bmiHeader.biWidth;
    UINT biHeight       =   abs(pCsVideoInfoHdr->bmiHeader.biHeight);
    UINT biSizeImage    =   pCsVideoInfoHdr->bmiHeader.biSizeImage;
    DWORD biCompression =   pCsVideoInfoHdr->bmiHeader.biCompression;
    biCompression &= ~BI_SRCPREROTATE;

    if ( ( FOURCC_YUY2 != biCompression ) && 
         ( FOURCC_YV12 != biCompression ) )
    {
        return -1;
    }

    // make the box width/height 1/8th of the screen, so it's visible but doesn't
    // overwhelm
    UINT uiBoxWidth = biWidth/BOXWIDTHDIVIDER;
    UINT uiBoxHeight = biHeight/BOXHEIGHTDIVIDER;

    float fWidthStep = (float) (biWidth - uiBoxWidth)/LOCATIONWIDTHMASK;
    float fHeightStep = (float) (biHeight - uiBoxHeight)/LOCATIONHEIGHTMASK;

    UINT x, y;
    UINT uiTickCount;
    UINT uiDirection;
    UINT uiLocationX, uiLocationY;

    uiTickCount = GetTickCount() >> SPEEDSHIFT;

    // and the result with 0x3 so the value ranges between 0 and 3 for the direction.
    uiDirection = (uiTickCount >> LOCATIONSHIFT) & 0x3;

    uiLocationX = static_cast<UINT>(fWidthStep * (uiTickCount & LOCATIONWIDTHMASK));
    uiLocationY = static_cast<UINT>(fHeightStep * (uiTickCount & LOCATIONHEIGHTMASK));

    switch (uiDirection)
    {
        case 0:
            x = uiLocationX;
            y = 0;
            break;
        case 1:
            x = biWidth - uiBoxWidth;
            y = uiLocationY;
            break;
        case 2:
            x = (biWidth - uiBoxWidth) - uiLocationX;
            y = biHeight - uiBoxHeight;
            break;
        case 3:
            x = 0;
            y = (biHeight - uiBoxHeight) - uiLocationY;
            break;
    }
    
    if (MAKEFOURCC('Y','V','1','2') == biCompression )
    {
        UINT uiStride = (2 * biSizeImage) / (3 * biHeight);
        UINT uiDelta = uiStride-biWidth;
        UINT uiSizeYPlane = uiStride * biHeight;
        UINT uiHalfStride = uiStride >> 1;
        UINT uiHalfWidth = biWidth >> 1;
        UINT uiHalfDelta = uiHalfStride - uiHalfWidth;

        // 1. Make the entire image white.

        // Y plane
        for (UINT i = 0; i < uiSizeYPlane; i += uiStride)
        {
            memset(&pImage[i], Y_WHITE, biWidth);
            memset(&pImage[i+biWidth], 0, uiDelta);
        }

        // V & U planes
        for (; i < biSizeImage; i += uiHalfStride)
        {
            memset(&pImage[i], VU_BOTH, uiHalfWidth);
            memset(&pImage[i+uiHalfWidth], 0, uiHalfDelta);
        }

        // 2. Add the black square.  Since the chroma (V & U) values are the same
        //    for both black and white, we only have to touch the luma (Y) plane.
        UINT uiBound = ((y + uiBoxHeight) * uiStride) + (x + uiBoxWidth);

        for (i = (y * uiStride) + x; i < uiBound; i += uiStride)
        {
            memset(&pImage[i], Y_BLACK, uiBoxWidth);
        }
    }
    else if (MAKEFOURCC('Y','U','Y','2') == biCompression )
    {
        UINT uiStrideDWORD = (biSizeImage / biHeight) / sizeof(DWORD);
        UINT uiWidthDWORD = biWidth / 2;
        UINT uiDeltaDWORD = uiStrideDWORD - uiWidthDWORD;

        // upcast should be safe because images are dword aligned
        DWORD* pdwImage = reinterpret_cast<DWORD*>(pImage);
        ASSERT(pdwImage);
        if (!pdwImage)
        {
            return 0;
        }

        // paint the background color first
        for (UINT i = 0; i < biHeight; i++)
        {
            for (UINT j = 0; j < uiWidthDWORD; j++)
#if 0
                *pdwImage++ = MACROPIXEL_WHITE;
#else
                *pdwImage++ = MACROPIXEL_RED;
#endif

            for (j = 0; j < uiDeltaDWORD; j++)
                *pdwImage++ = 0;
        }

        // then add the square
        UINT uiBoundDWORD = ((y + uiBoxHeight) * uiStrideDWORD) + ((x + uiBoxWidth) / 2);
        UINT uiBoxWidthDWORD = uiBoxWidth / 2;

        pdwImage = reinterpret_cast<DWORD*>(pImage);
        pdwImage += (y * uiStrideDWORD) + (x / 2);

        for (i = 0; i < uiBoxHeight; i++)
        {
            for (UINT j = 0; j < uiBoxWidthDWORD; j++)
#if 0
                *pdwImage++ = MACROPIXEL_BLACK;
#else
                *pdwImage++ = MACROPIXEL_GRN;
#endif

            pdwImage += (uiStrideDWORD - uiBoxWidthDWORD);
        }
    }

    return(biSizeImage);
}

bool CNullPdd :: CreateTimer( ULONG ulModeType )
{
    if ( NULL == m_hTimerDll )
    {
        m_hTimerDll        = LoadLibrary( L"MMTimer.dll" );
        m_pfnTimeSetEvent  = (FNTIMESETEVENT)GetProcAddress( m_hTimerDll, L"timeSetEvent" );
        m_pfnTimeKillEvent = (FNTIMEKILLEVENT)GetProcAddress( m_hTimerDll, L"timeKillEvent" );

        if ( NULL == m_pfnTimeSetEvent || NULL == m_pfnTimeKillEvent )
        {
            DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl(%08x): GetProcAddress Returned Null.\r\n"), this));
            return false;
        }
    }
    
    if ( NULL == m_hTimerDll )
    {
            DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl(%08x): LoadLibrary failedr.\r\n"), this));
            return false;
    }

    ASSERT( m_pfnTimeSetEvent );

    if ( NULL == m_TimerIdentifier[ulModeType] )
    {
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl(%08x): Creating new timer.\r\n"), this));
        if( STILL == ulModeType )
        {
            m_TimerIdentifier[ulModeType] = m_pfnTimeSetEvent( (ULONG)m_pCurrentFormat[ulModeType].VideoInfoHeader.AvgTimePerFrame/10000, 10, CNullPdd::StillTimerCallBack, reinterpret_cast<DWORD>(this), TIME_PERIODIC|TIME_CALLBACK_FUNCTION);
        }
        else
        {
            m_TimerIdentifier[ulModeType] = m_pfnTimeSetEvent( (ULONG)m_pCurrentFormat[ulModeType].VideoInfoHeader.AvgTimePerFrame/10000, 10, CNullPdd::CaptureTimerCallBack, reinterpret_cast<DWORD>(this), TIME_PERIODIC|TIME_CALLBACK_FUNCTION);
        }

        if ( NULL == m_TimerIdentifier[ulModeType] )
        {
            DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl(%08x): Timer could not be created.\r\n"), this));
            return false;
        }
    }
    else
    {
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl(%08x): Timer already created.\r\n"), this));
    }

    return true;
}

void CNullPdd :: CaptureTimerCallBack( UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2 )
{
    UNREFERENCED_PARAMETER(uTimerID) ;
    UNREFERENCED_PARAMETER(uMsg);
    UNREFERENCED_PARAMETER(dw1);
    UNREFERENCED_PARAMETER(dw2);

    CNullPdd *pNullPdd= reinterpret_cast<CNullPdd *>(dwUser);
    if( NULL == pNullPdd )
    {
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl: TimerCallBack pNullPdd is NULL.\r\n"))) ;
    }
    else
    {
        __try
        {
            pNullPdd->HandleCaptureInterrupt( uTimerID );
        }
        __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
        {
            DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl: TimerCallBack, Access violation.\r\n"))) ;
        }
    }
}

void CNullPdd :: StillTimerCallBack( UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2 )
{
    UNREFERENCED_PARAMETER(uTimerID) ;
    UNREFERENCED_PARAMETER(uMsg);
    UNREFERENCED_PARAMETER(dw1);
    UNREFERENCED_PARAMETER(dw2);

    CNullPdd *pNullPdd= reinterpret_cast<CNullPdd *>(dwUser);
    if( NULL == pNullPdd )
    {
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl: TimerCallBack pNullPdd is NULL.\r\n"))) ;
    }
    else
    {
        __try
        {
            pNullPdd->HandleStillInterrupt( uTimerID );
        }
        __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
        {
            DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("IOControl: TimerCallBack, Access violation.\r\n"))) ;
        }
    }
}

void CNullPdd :: HandleCaptureInterrupt( UINT uTimerID )
{
    ULONG ulModeType;

    if( m_bStillCapInProgress )
    {
        return;
    }
    
    if( m_TimerIdentifier[CAPTURE] == uTimerID )
    {
        ulModeType = CAPTURE;
    }
    else if ( m_ulCTypes == 3 && m_TimerIdentifier[PREVIEW] == uTimerID )
    {
        ulModeType = PREVIEW;
    }
    else
    {
        ASSERT(false);
        return;
    }

    MDD_HandleIO( m_ppModeContext[ulModeType], ulModeType );

}


void CNullPdd :: HandleStillInterrupt( UINT uTimerID )
{
    MDD_HandleIO( m_ppModeContext[STILL], STILL );
    m_bStillCapInProgress = false;
}

bool CNullPdd::ReadMemoryModelFromRegistry()
{
    HKEY  hKey = 0;
    DWORD dwType  = 0;
    DWORD dwSize  = sizeof ( DWORD );
    DWORD dwValue = -1;


    if( ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE, L"Drivers\\Capture\\SampleCam", 0, 0, &hKey ))
    {
        false;
    }

    if( ERROR_SUCCESS == RegQueryValueEx( hKey, L"MemoryModel", 0, &dwType, (BYTE *)&dwValue, &dwSize ) )
    {
        if(   ( REG_DWORD == dwType ) 
           && ( sizeof( DWORD ) == dwSize ) 
           && (( dwValue == CSPROPERTY_BUFFER_DRIVER ) || ( dwValue == CSPROPERTY_BUFFER_CLIENT_LIMITED ) || ( dwValue == CSPROPERTY_BUFFER_CLIENT_UNLIMITED )))
        {
            for( int i=0; i<MAX_SUPPORTED_PINS ; i++ )
            {
                m_SensorModeInfo[i].MemoryModel = (CSPROPERTY_BUFFER_MODE) dwValue;
            }
        }
    }

    // Find out if we should be using some other number of supported modes. The only
    // valid options are 2 or 3. Default to 2.
    if ( ERROR_SUCCESS == RegQueryValueEx( hKey, L"PinCount", 0, &dwType, (BYTE *)&dwValue, &dwSize ) )
    {
        if ( REG_DWORD == dwType
             && sizeof ( DWORD ) == dwSize
             && 3 == dwValue )
        {
            m_ulCTypes = 3;
        }
    }

    RegCloseKey( hKey );
    return true;
}

⌨️ 快捷键说明

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