www.pudn.com > camera.rar > camerapdd.cpp


// 
// Copyright (c) Microsoft Corporation.  All rights reserved. 
// 
// 
// Use of this sample source code is subject to the terms of the Microsoft 
// license agreement under which you licensed this sample source code. If 
// you did not accept the terms of the license agreement, you are not 
// authorized to use this sample source code. For the terms of the license, 
// please see the license agreement between you and Microsoft or, if applicable, 
// see the LICENSE.RTF on your install media or the root of your tools installation. 
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES. 
// 
// 
// (C) Copyright 2006 Marvell International Ltd. 
// All Rights Reserved 
// 
 
#include "pdd_private.h" 
#include "SensorFormats.h" 
#include "SensorProperties.h" 
#include "wchar.h" 
#include "string.h" 
#include  
 
#include "sensor.h" 
#include "ov7660.h" 
#include "ov2630.h" 
#include "qci.h" 
#include "CI.h" 
 
#include "args.h" 
#include "ioctl_cfg.h" 
 
PDDFUNCTBL FuncTbl = { 
    sizeof(PDDFUNCTBL), 
    PDD_Init, 
    PDD_DeInit, 
    PDD_GetAdapterInfo, 
    PDD_HandleVidProcAmpChanges, 
    PDD_HandleCamControlChanges, 
    PDD_HandleVideoControlCapsChanges, 
    PDD_SetPowerState, 
    PDD_HandleAdapterCustomProperties, 
    PDD_InitSensorMode, 
    PDD_DeInitSensorMode, 
    PDD_SetSensorState, 
    PDD_TakeStillPicture, 
    PDD_GetSensorModeInfo, 
    PDD_SetSensorModeFormat, 
    PDD_AllocateBuffer, 
    PDD_DeAllocateBuffer, 
    PDD_RegisterClientBuffer, 
    PDD_UnRegisterClientBuffer, 
    PDD_FillBuffer, 
    PDD_HandleModeCustomProperties 
}; 
 
 
CCameraPdd::CCameraPdd() 
{ 
    m_ulCTypes = 2; 
    m_bStillCapInProgress = false; 
    m_hContext = NULL; 
    m_pModeVideoFormat = NULL; 
    m_pModeVideoCaps = NULL; 
    m_ppModeContext = NULL; 
    m_pCurrentFormat = NULL; 
    memset( &m_CsState, 0x0, sizeof(m_CsState)); 
    memset( &m_SensorModeInfo, 0x0, sizeof(m_SensorModeInfo)); 
    memset( &m_SensorProps, 0x0, sizeof(m_SensorProps)); 
    memset( &PowerCaps, 0x0, sizeof(PowerCaps)); 
 
    is_qci_capturing = FALSE; 
    qci_bus = NULL; 
} 
 
CCameraPdd::~CCameraPdd() 
{ 
    if( NULL != m_pModeVideoCaps ) 
    { 
        delete [] m_pModeVideoCaps; 
        m_pModeVideoCaps = NULL; 
    } 
 
    if( NULL != m_pCurrentFormat ) 
    { 
        delete [] m_pCurrentFormat; 
        m_pCurrentFormat = NULL; 
    } 
 
    if( NULL != m_pModeVideoFormat ) 
    { 
        delete [] m_pModeVideoFormat; 
        m_pModeVideoFormat = NULL; 
    } 
 
    if( NULL != m_ppModeContext ) 
    { 
        delete [] m_ppModeContext; 
        m_ppModeContext = NULL; 
    } 
 
    if (qci_bus)  
        CloseBusAccessHandle(qci_bus); 
} 
 
bool use_cmu = 1; 
 
LPCTSTR ov7660_name = L"ov7660"; 
LPCTSTR ov2630_name = L"ov2630"; 
 
DWORD CCameraPdd::PDDInit( PVOID MDDContext, PPDDFUNCTBL pPDDFuncTbl ) 
{ 
    m_hContext = (HANDLE)MDDContext; 
    // Real drivers may want to create their context 
 
    m_ulCTypes = 2; // Default number of Sensor Modes is 2 
     
    // Read registry to override the default number of Sensor Modes. 
    ReadMemoryModelFromRegistry();   
 
    if( pPDDFuncTbl->dwSize  > sizeof( PDDFUNCTBL ) ) 
    { 
        return ERROR_INSUFFICIENT_BUFFER; 
    } 
 
    memcpy( pPDDFuncTbl, &FuncTbl, sizeof( PDDFUNCTBL ) ); 
 
    memset( m_SensorProps, 0x0, sizeof(m_SensorProps) ); 
 
    PowerCaps.DeviceDx = 0x11;     
  
    DWORD ret; 
    DWORD sensor_size; 
    BSP_ARGS args; 
    qci_bus = CreateBusAccessHandle((LPCTSTR)m_hContext); 
    if (qci_bus == NULL)  
    { 
        ret = GetLastError(); 
        DEBUGMSG(1, (_T("CAM: Camera PDD Could not CreateBusAccessHandle. Error %u\r\n"),ret)); 
        return ret; 
    } 
 
    HKEY key; 
    key = OpenDeviceKey((LPCTSTR)m_hContext); 
    DWORD type; 
#define MAX_SENSOR_NAME_LENTH 20 
    wchar_t sensor_name[MAX_SENSOR_NAME_LENTH]; 
    DWORD size = sizeof(sensor_name); 
 
    if (KernelIoControl(IOCTL_GET_BSP_ARGS, NULL, 0, &args, sizeof(args), &sensor_size)) 
    { 
        RETAILMSG(1, (_T("CAM: EBOOT set sensor type. \r\n"))); 
    } 
 
    if (ERROR_SUCCESS == RegQueryValueEx(key, L"Sensor", 0, &type, (BYTE*)sensor_name, &size)) 
    { 
        sensor_name[MAX_SENSOR_NAME_LENTH - 1] = 0; 
    } 
 
    RegCloseKey(key); 
 
    if (args.DefaultSensor == BSP_ARGS_OV7660) 
            sensor = new Ov7660(); 
    else if (args.DefaultSensor == BSP_ARGS_OV2630) 
            sensor = new Ov2630(); 
    else             
            DEBUGMSG(ZONE_ERROR,(L"CAM: Error unknow sensor\r\n")); 
 
    init_ipm_client(); 
 
    if (!sensor) 
    {         
        DEBUGMSG(ZONE_ERROR,(L"CAM: camera pdd fatal error: no valid sensor name!!!\r\n")); 
        return E_FAIL; 
    } 
 
    if (!detect_sensor()) 
    { 
        power_off();  
        return E_FAIL; 
    } 
 
    power_off(); 
 
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    // Set all VideoProcAmp and CameraControl properties. 
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    //VideoProcAmp 
    m_SensorProps[ENUM_BRIGHTNESS].ulCurrentValue     = BrightnessDefault; 
    m_SensorProps[ENUM_BRIGHTNESS].ulDefaultValue     = BrightnessDefault; 
    m_SensorProps[ENUM_BRIGHTNESS].pRangeNStep        = &BrightnessRangeAndStep[0]; 
    m_SensorProps[ENUM_BRIGHTNESS].ulFlags            = CSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL; 
    m_SensorProps[ENUM_BRIGHTNESS].ulCapabilities     = CSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL|CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_BRIGHTNESS].fSetSupported      = VideoProcAmpProperties[ENUM_BRIGHTNESS].SetSupported; 
    m_SensorProps[ENUM_BRIGHTNESS].fGetSupported      = VideoProcAmpProperties[ENUM_BRIGHTNESS].GetSupported; 
    m_SensorProps[ENUM_BRIGHTNESS].pCsPropValues      = &BrightnessValues; 
 
    m_SensorProps[ENUM_CONTRAST].ulCurrentValue       = ContrastDefault; 
    m_SensorProps[ENUM_CONTRAST].ulDefaultValue       = ContrastDefault; 
    m_SensorProps[ENUM_CONTRAST].pRangeNStep          = &ContrastRangeAndStep[0]; 
    m_SensorProps[ENUM_CONTRAST].ulFlags              = CSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL; 
    m_SensorProps[ENUM_CONTRAST].ulCapabilities       = CSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL|CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_CONTRAST].fSetSupported        = VideoProcAmpProperties[ENUM_CONTRAST].SetSupported; 
    m_SensorProps[ENUM_CONTRAST].fGetSupported        = VideoProcAmpProperties[ENUM_CONTRAST].GetSupported; 
    m_SensorProps[ENUM_CONTRAST].pCsPropValues        = &ContrastValues; 
 
    m_SensorProps[ENUM_HUE].ulCurrentValue            = HueDefault; 
    m_SensorProps[ENUM_HUE].ulDefaultValue            = HueDefault; 
    m_SensorProps[ENUM_HUE].pRangeNStep               = &HueRangeAndStep[0]; 
    m_SensorProps[ENUM_HUE].ulFlags                   = CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_HUE].ulCapabilities            = CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_HUE].fSetSupported             = VideoProcAmpProperties[ENUM_HUE].SetSupported; 
    m_SensorProps[ENUM_HUE].fGetSupported             = VideoProcAmpProperties[ENUM_HUE].GetSupported; 
    m_SensorProps[ENUM_HUE].pCsPropValues             = &HueValues; 
 
    m_SensorProps[ENUM_SATURATION].ulCurrentValue     = SaturationDefault; 
    m_SensorProps[ENUM_SATURATION].ulDefaultValue     = SaturationDefault; 
    m_SensorProps[ENUM_SATURATION].pRangeNStep        = &SaturationRangeAndStep[0]; 
    m_SensorProps[ENUM_SATURATION].ulFlags            = CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_SATURATION].ulCapabilities     = CSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL|CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_SATURATION].fSetSupported      = VideoProcAmpProperties[ENUM_SATURATION].SetSupported; 
    m_SensorProps[ENUM_SATURATION].fGetSupported      = VideoProcAmpProperties[ENUM_SATURATION].GetSupported; 
    m_SensorProps[ENUM_SATURATION].pCsPropValues      = &SaturationValues; 
 
    m_SensorProps[ENUM_SHARPNESS].ulCurrentValue      = SharpnessDefault; 
    m_SensorProps[ENUM_SHARPNESS].ulDefaultValue      = SharpnessDefault; 
    m_SensorProps[ENUM_SHARPNESS].pRangeNStep         = &SharpnessRangeAndStep[0]; 
    m_SensorProps[ENUM_SHARPNESS].ulFlags             = CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_SHARPNESS].ulCapabilities      = CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_SHARPNESS].fSetSupported       = VideoProcAmpProperties[ENUM_SHARPNESS].SetSupported; 
    m_SensorProps[ENUM_SHARPNESS].fGetSupported       = VideoProcAmpProperties[ENUM_SHARPNESS].GetSupported; 
    m_SensorProps[ENUM_SHARPNESS].pCsPropValues       = &SharpnessValues; 
 
    m_SensorProps[ENUM_GAMMA].ulCurrentValue          = GammaDefault; 
    m_SensorProps[ENUM_GAMMA].ulDefaultValue          = GammaDefault; 
    m_SensorProps[ENUM_GAMMA].pRangeNStep             = &GammaRangeAndStep[0]; 
    m_SensorProps[ENUM_GAMMA].ulFlags                 = CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_GAMMA].ulCapabilities          = CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_GAMMA].fSetSupported           = VideoProcAmpProperties[ENUM_GAMMA].SetSupported; 
    m_SensorProps[ENUM_GAMMA].fGetSupported           = VideoProcAmpProperties[ENUM_GAMMA].GetSupported; 
    m_SensorProps[ENUM_GAMMA].pCsPropValues           = &GammaValues; 
 
    m_SensorProps[ENUM_COLORENABLE].ulCurrentValue    = ColorEnableDefault; 
    m_SensorProps[ENUM_COLORENABLE].ulDefaultValue    = ColorEnableDefault; 
    m_SensorProps[ENUM_COLORENABLE].pRangeNStep       = &ColorEnableRangeAndStep[0]; 
    m_SensorProps[ENUM_COLORENABLE].ulFlags           = CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_COLORENABLE].ulCapabilities    = CSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL|CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_COLORENABLE].fSetSupported     = VideoProcAmpProperties[ENUM_COLORENABLE].SetSupported; 
    m_SensorProps[ENUM_COLORENABLE].fGetSupported     = VideoProcAmpProperties[ENUM_COLORENABLE].GetSupported; 
    m_SensorProps[ENUM_COLORENABLE].pCsPropValues     = &ColorEnableValues; 
 
    m_SensorProps[ENUM_WHITEBALANCE].ulCurrentValue   = WhiteBalanceDefault; 
    m_SensorProps[ENUM_WHITEBALANCE].ulDefaultValue   = WhiteBalanceDefault; 
    m_SensorProps[ENUM_WHITEBALANCE].pRangeNStep      = &WhiteBalanceRangeAndStep[0]; 
    m_SensorProps[ENUM_WHITEBALANCE].ulFlags          = CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_WHITEBALANCE].ulCapabilities   = CSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL|CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_WHITEBALANCE].fSetSupported    = VideoProcAmpProperties[ENUM_WHITEBALANCE].SetSupported; 
    m_SensorProps[ENUM_WHITEBALANCE].fGetSupported    = VideoProcAmpProperties[ENUM_WHITEBALANCE].GetSupported; 
    m_SensorProps[ENUM_WHITEBALANCE].pCsPropValues    = &WhiteBalanceValues; 
 
    m_SensorProps[ENUM_BACKLIGHT_COMPENSATION].ulCurrentValue = BackLightCompensationDefault; 
    m_SensorProps[ENUM_BACKLIGHT_COMPENSATION].ulDefaultValue = BackLightCompensationDefault; 
    m_SensorProps[ENUM_BACKLIGHT_COMPENSATION].pRangeNStep    = &BackLightCompensationRangeAndStep[0]; 
    m_SensorProps[ENUM_BACKLIGHT_COMPENSATION].ulFlags        = CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_BACKLIGHT_COMPENSATION].ulCapabilities = CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_BACKLIGHT_COMPENSATION].fSetSupported  = VideoProcAmpProperties[ENUM_BACKLIGHT_COMPENSATION].SetSupported; 
    m_SensorProps[ENUM_BACKLIGHT_COMPENSATION].fGetSupported  = VideoProcAmpProperties[ENUM_BACKLIGHT_COMPENSATION].GetSupported; 
    m_SensorProps[ENUM_BACKLIGHT_COMPENSATION].pCsPropValues  = &BackLightCompensationValues; 
 
    m_SensorProps[ENUM_GAIN].ulCurrentValue           = GainDefault; 
    m_SensorProps[ENUM_GAIN].ulDefaultValue           = GainDefault; 
    m_SensorProps[ENUM_GAIN].pRangeNStep              = &GainRangeAndStep[0]; 
    m_SensorProps[ENUM_GAIN].ulFlags                  = CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_GAIN].ulCapabilities           = CSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; 
    m_SensorProps[ENUM_GAIN].fSetSupported            = VideoProcAmpProperties[ENUM_GAIN].SetSupported; 
    m_SensorProps[ENUM_GAIN].fGetSupported            = VideoProcAmpProperties[ENUM_GAIN].GetSupported; 
    m_SensorProps[ENUM_GAIN].pCsPropValues            = &GainValues; 
 
    //CameraControl 
    m_SensorProps[ENUM_PAN].ulCurrentValue            = PanDefault; 
    m_SensorProps[ENUM_PAN].ulDefaultValue            = PanDefault; 
    m_SensorProps[ENUM_PAN].pRangeNStep               = &PanRangeAndStep[0]; 
    m_SensorProps[ENUM_PAN].ulFlags                   = CSPROPERTY_CAMERACONTROL_FLAGS_AUTO; 
    m_SensorProps[ENUM_PAN].ulCapabilities            = CSPROPERTY_CAMERACONTROL_FLAGS_MANUAL|CSPROPERTY_CAMERACONTROL_FLAGS_AUTO; 
    m_SensorProps[ENUM_PAN].fSetSupported             = VideoProcAmpProperties[ENUM_PAN-NUM_VIDEOPROCAMP_ITEMS].SetSupported; 
    m_SensorProps[ENUM_PAN].fGetSupported             = VideoProcAmpProperties[ENUM_PAN-NUM_VIDEOPROCAMP_ITEMS].GetSupported; 
    m_SensorProps[ENUM_PAN].pCsPropValues             = &PanValues; 
 
    m_SensorProps[ENUM_TILT].ulCurrentValue           = TiltDefault; 
    m_SensorProps[ENUM_TILT].ulDefaultValue           = TiltDefault; 
    m_SensorProps[ENUM_TILT].pRangeNStep              = &TiltRangeAndStep[0]; 
    m_SensorProps[ENUM_TILT].ulFlags                  = CSPROPERTY_CAMERACONTROL_FLAGS_AUTO; 
    m_SensorProps[ENUM_TILT].ulCapabilities           = CSPROPERTY_CAMERACONTROL_FLAGS_MANUAL|CSPROPERTY_CAMERACONTROL_FLAGS_AUTO; 
    m_SensorProps[ENUM_TILT].fSetSupported            = VideoProcAmpProperties[ENUM_TILT-NUM_VIDEOPROCAMP_ITEMS].SetSupported; 
    m_SensorProps[ENUM_TILT].fGetSupported            = VideoProcAmpProperties[ENUM_TILT-NUM_VIDEOPROCAMP_ITEMS].GetSupported; 
    m_SensorProps[ENUM_TILT].pCsPropValues            = &TiltValues; 
 
    m_SensorProps[ENUM_ROLL].ulCurrentValue           = RollDefault; 
    m_SensorProps[ENUM_ROLL].ulDefaultValue           = RollDefault; 
    m_SensorProps[ENUM_ROLL].pRangeNStep              = &RollRangeAndStep[0]; 
    m_SensorProps[ENUM_ROLL].ulFlags                  = CSPROPERTY_CAMERACONTROL_FLAGS_AUTO; 
    m_SensorProps[ENUM_ROLL].ulCapabilities           = CSPROPERTY_CAMERACONTROL_FLAGS_MANUAL|CSPROPERTY_CAMERACONTROL_FLAGS_AUTO; 
    m_SensorProps[ENUM_ROLL].fSetSupported            = VideoProcAmpProperties[ENUM_ROLL-NUM_VIDEOPROCAMP_ITEMS].SetSupported; 
    m_SensorProps[ENUM_ROLL].fGetSupported            = VideoProcAmpProperties[ENUM_ROLL-NUM_VIDEOPROCAMP_ITEMS].GetSupported; 
    m_SensorProps[ENUM_ROLL].pCsPropValues            = &RollValues; 
 
    m_SensorProps[ENUM_ZOOM].ulCurrentValue           = ZoomDefault; 
    m_SensorProps[ENUM_ZOOM].ulDefaultValue           = ZoomDefault; 
    m_SensorProps[ENUM_ZOOM].pRangeNStep              = &ZoomRangeAndStep[0]; 
    m_SensorProps[ENUM_ZOOM].ulFlags                  = CSPROPERTY_CAMERACONTROL_FLAGS_AUTO; 
    m_SensorProps[ENUM_ZOOM].ulCapabilities           = CSPROPERTY_CAMERACONTROL_FLAGS_MANUAL|CSPROPERTY_CAMERACONTROL_FLAGS_AUTO; 
    m_SensorProps[ENUM_ZOOM].fSetSupported            = VideoProcAmpProperties[ENUM_ZOOM-NUM_VIDEOPROCAMP_ITEMS].SetSupported; 
    m_SensorProps[ENUM_ZOOM].fGetSupported            = VideoProcAmpProperties[ENUM_ZOOM-NUM_VIDEOPROCAMP_ITEMS].GetSupported; 
    m_SensorProps[ENUM_ZOOM].pCsPropValues            = &ZoomValues; 
 
    m_SensorProps[ENUM_IRIS].ulCurrentValue           = IrisDefault; 
    m_SensorProps[ENUM_IRIS].ulDefaultValue           = IrisDefault; 
    m_SensorProps[ENUM_IRIS].pRangeNStep              = &IrisRangeAndStep[0]; 
    m_SensorProps[ENUM_IRIS].ulFlags                  = CSPROPERTY_CAMERACONTROL_FLAGS_AUTO; 
    m_SensorProps[ENUM_IRIS].ulCapabilities           = CSPROPERTY_CAMERACONTROL_FLAGS_MANUAL|CSPROPERTY_CAMERACONTROL_FLAGS_AUTO; 
    m_SensorProps[ENUM_IRIS].fSetSupported            = VideoProcAmpProperties[ENUM_IRIS-NUM_VIDEOPROCAMP_ITEMS].SetSupported; 
    m_SensorProps[ENUM_IRIS].fGetSupported            = VideoProcAmpProperties[ENUM_IRIS-NUM_VIDEOPROCAMP_ITEMS].GetSupported; 
    m_SensorProps[ENUM_IRIS].pCsPropValues            = &IrisValues; 
 
    m_SensorProps[ENUM_EXPOSURE].ulCurrentValue       = ExposureDefault; 
    m_SensorProps[ENUM_EXPOSURE].ulDefaultValue       = ExposureDefault; 
    m_SensorProps[ENUM_EXPOSURE].pRangeNStep          = &ExposureRangeAndStep[0]; 
    m_SensorProps[ENUM_EXPOSURE].ulFlags              = CSPROPERTY_CAMERACONTROL_FLAGS_AUTO; 
    m_SensorProps[ENUM_EXPOSURE].ulCapabilities       = CSPROPERTY_CAMERACONTROL_FLAGS_MANUAL|CSPROPERTY_CAMERACONTROL_FLAGS_AUTO; 
    m_SensorProps[ENUM_EXPOSURE].fSetSupported        = VideoProcAmpProperties[ENUM_EXPOSURE-NUM_VIDEOPROCAMP_ITEMS].SetSupported; 
    m_SensorProps[ENUM_EXPOSURE].fGetSupported        = VideoProcAmpProperties[ENUM_EXPOSURE-NUM_VIDEOPROCAMP_ITEMS].GetSupported; 
    m_SensorProps[ENUM_EXPOSURE].pCsPropValues        = &ExposureValues; 
 
    m_SensorProps[ENUM_FOCUS].ulCurrentValue          = FocusDefault; 
    m_SensorProps[ENUM_FOCUS].ulDefaultValue          = FocusDefault; 
    m_SensorProps[ENUM_FOCUS].pRangeNStep             = &FocusRangeAndStep[0]; 
    m_SensorProps[ENUM_FOCUS].ulFlags                 = CSPROPERTY_CAMERACONTROL_FLAGS_MANUAL; 
    m_SensorProps[ENUM_FOCUS].ulCapabilities          = CSPROPERTY_CAMERACONTROL_FLAGS_MANUAL; 
    m_SensorProps[ENUM_FOCUS].fSetSupported           = VideoProcAmpProperties[ENUM_FOCUS-NUM_VIDEOPROCAMP_ITEMS].SetSupported; 
    m_SensorProps[ENUM_FOCUS].fGetSupported           = VideoProcAmpProperties[ENUM_FOCUS-NUM_VIDEOPROCAMP_ITEMS].GetSupported; 
    m_SensorProps[ENUM_FOCUS].pCsPropValues           = &FocusValues; 
 
    m_SensorProps[ENUM_FLASH].ulCurrentValue          = FlashDefault; 
    m_SensorProps[ENUM_FLASH].ulDefaultValue          = FlashDefault; 
    m_SensorProps[ENUM_FLASH].pRangeNStep             = &FlashRangeAndStep[0]; 
    m_SensorProps[ENUM_FLASH].ulFlags                 = CSPROPERTY_CAMERACONTROL_FLAGS_MANUAL; 
    m_SensorProps[ENUM_FLASH].ulCapabilities          = CSPROPERTY_CAMERACONTROL_FLAGS_MANUAL; 
    m_SensorProps[ENUM_FLASH].fSetSupported           = VideoProcAmpProperties[ENUM_FLASH-NUM_VIDEOPROCAMP_ITEMS].SetSupported; 
    m_SensorProps[ENUM_FLASH].fGetSupported           = VideoProcAmpProperties[ENUM_FLASH-NUM_VIDEOPROCAMP_ITEMS].GetSupported; 
    m_SensorProps[ENUM_FLASH].pCsPropValues           = &FlashValues; 
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
 
    m_pModeVideoFormat = NULL; 
    // Allocate Video Format specific array. 
    m_pModeVideoFormat = new PINVIDEOFORMAT[m_ulCTypes]; 
    if( NULL == m_pModeVideoFormat ) 
    { 
        return ERROR_INSUFFICIENT_BUFFER; 
    } 
 
    // Video Format initialization 
    m_pModeVideoFormat[CAPTURE].categoryGUID         = PINNAME_VIDEO_CAPTURE; 
    m_pModeVideoFormat[STILL].categoryGUID           = PINNAME_VIDEO_STILL; 
    if( 3 == m_ulCTypes ) 
        m_pModeVideoFormat[PREVIEW].categoryGUID         = PINNAME_VIDEO_PREVIEW; 
 
    for (ULONG i = 0; i < m_ulCTypes; i++) 
    { 
         
        UINT32 nformats; 
        PCS_DATARANGE_VIDEO** formats; 
        formats = &m_pModeVideoFormat[i].pCsDataRangeVideo; 
        nformats = sensor->get_formats(i, formats); 
        m_pModeVideoFormat[i].ulAvailFormats = nformats; 
 
        if ( NULL == m_pModeVideoFormat[i].pCsDataRangeVideo ) 
            return ERROR_INSUFFICIENT_BUFFER; 
    } 
 
    for (ULONG i = 0; i < m_ulCTypes; i++) 
    { 
        for (ULONG j = 0; j < m_pModeVideoFormat[i].ulAvailFormats; j++) 
        { 
            PCS_VIDEOINFOHEADER pCsVideoInfoHdr; 
            pCsVideoInfoHdr = &m_pModeVideoFormat[i].pCsDataRangeVideo[j]->VideoInfoHeader; 
            camera_cfg_t* cfg = sensor->get_camera_cfg(pCsVideoInfoHdr, i); 
 
            if (!cfg)                 
                DEBUGMSG( ZONE_IOCTL, ( _T("CAM: failed to get camera configuration!!!\r\n")) ); 
            sensor->init_camera_cfg(cfg, i); 
            qci_notify_formats(&cfg->qci_format); 
        } 
    } 
 
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
 
    m_pModeVideoCaps = NULL; 
    // Allocate Video Control Caps specific array. 
    m_pModeVideoCaps = new VIDCONTROLCAPS[m_ulCTypes]; 
    if( NULL == m_pModeVideoCaps ) 
    { 
        return ERROR_INSUFFICIENT_BUFFER; 
    } 
    // Video Control Caps 
 
    m_pModeVideoCaps[CAPTURE].DefaultVideoControlCaps     = DefaultVideoControlCaps[CAPTURE]; 
    m_pModeVideoCaps[CAPTURE].CurrentVideoControlCaps     = DefaultVideoControlCaps[CAPTURE];; 
    m_pModeVideoCaps[STILL].DefaultVideoControlCaps       = DefaultVideoControlCaps[STILL]; 
    m_pModeVideoCaps[STILL].CurrentVideoControlCaps       = DefaultVideoControlCaps[STILL];; 
    if( 3 == m_ulCTypes ) 
    { 
        // Note PREVIEW control caps are the same, so we don't differentiate 
        m_pModeVideoCaps[PREVIEW].DefaultVideoControlCaps     = DefaultVideoControlCaps[PREVIEW]; 
        m_pModeVideoCaps[PREVIEW].CurrentVideoControlCaps     = DefaultVideoControlCaps[PREVIEW];; 
    } 
 
    m_SensorModeInfo[CAPTURE].MemoryModel = CSPROPERTY_BUFFER_CLIENT_UNLIMITED; 
    m_SensorModeInfo[CAPTURE].MaxNumOfBuffers = 1; 
    m_SensorModeInfo[CAPTURE].PossibleCount = 1; 
    m_SensorModeInfo[STILL].MemoryModel = CSPROPERTY_BUFFER_CLIENT_UNLIMITED; 
    m_SensorModeInfo[STILL].MaxNumOfBuffers = 1; 
    m_SensorModeInfo[STILL].PossibleCount = 1; 
    if( 3 == m_ulCTypes ) 
    { 
        m_SensorModeInfo[PREVIEW].MemoryModel = CSPROPERTY_BUFFER_CLIENT_UNLIMITED; 
        m_SensorModeInfo[PREVIEW].MaxNumOfBuffers = 1; 
        m_SensorModeInfo[PREVIEW].PossibleCount = 1; 
    } 
 
    m_ppModeContext = new LPVOID[m_ulCTypes]; 
    if ( NULL == m_ppModeContext ) 
    { 
        return ERROR_INSUFFICIENT_BUFFER; 
    } 
 
    m_pCurrentFormat = new CS_DATARANGE_VIDEO[m_ulCTypes]; 
    if( NULL == m_pCurrentFormat ) 
    { 
        return ERROR_INSUFFICIENT_BUFFER; 
    } 
 
    return ERROR_SUCCESS; 
} 
 
DWORD CCameraPdd::GetAdapterInfo( PADAPTERINFO pAdapterInfo ) 
{ 
    pAdapterInfo->ulCTypes = m_ulCTypes; 
    pAdapterInfo->PowerCaps = PowerCaps; 
    pAdapterInfo->ulVersionID = DRIVER_VERSION; //Camera MDD and DShow support DRIVER_VERSION and DRIVER_VERSION_2. Defined in camera.h 
    memcpy( &pAdapterInfo->SensorProps, &m_SensorProps, sizeof(m_SensorProps)); 
 
    return ERROR_SUCCESS; 
 
} 
 
DWORD CCameraPdd::HandleVidProcAmpChanges( DWORD dwPropId, LONG lFlags, LONG lValue ) 
{ 
    PSENSOR_PROPERTY pDevProp = NULL; 
 
    pDevProp = m_SensorProps + dwPropId; 
     
    if( CSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL == lFlags ) 
    { 
        pDevProp->ulCurrentValue = lValue; 
    } 
 
    pDevProp->ulFlags = lFlags; 
    return ERROR_SUCCESS; 
} 
 
DWORD CCameraPdd::HandleCamControlChanges( DWORD dwPropId, LONG lFlags, LONG lValue ) 
{ 
    PSENSOR_PROPERTY pDevProp = NULL; 
     
    pDevProp = m_SensorProps + dwPropId; 
     
    if( CSPROPERTY_CAMERACONTROL_FLAGS_MANUAL == lFlags ) 
    { 
        pDevProp->ulCurrentValue = lValue; 
    } 
 
    pDevProp->ulFlags = lFlags; 
    return ERROR_SUCCESS; 
} 
 
DWORD CCameraPdd::HandleVideoControlCapsChanges( LONG lModeType ,ULONG ulCaps ) 
{ 
    m_pModeVideoCaps[lModeType].CurrentVideoControlCaps = ulCaps; 
    return ERROR_SUCCESS; 
} 
 
DWORD CCameraPdd :: SetPowerState( CEDEVICE_POWER_STATE PowerState ) 
{ 
    if (PowerState != D0 && PowerState != D1) 
        if (is_sensor_on) 
            power_off(); 
    return ERROR_SUCCESS; 
} 
 
DWORD CCameraPdd::HandleAdapterCustomProperties( PUCHAR pInBuf, DWORD  InBufLen, PUCHAR pOutBuf, DWORD  OutBufLen, PDWORD pdwBytesTransferred ) 
{ 
    DEBUGMSG( ZONE_IOCTL, ( _T("CAM: IOControl Adapter PDD: Unsupported PropertySet Request\r\n")) ); 
    return ERROR_NOT_SUPPORTED; 
} 
 
DWORD CCameraPdd::InitSensorMode( ULONG ulModeType, LPVOID ModeContext ) 
{ 
    ASSERT( ModeContext ); 
    m_ppModeContext[ulModeType] = ModeContext; 
    return ERROR_SUCCESS; 
} 
 
DWORD CCameraPdd::DeInitSensorMode( ULONG ulModeType ) 
{ 
    return ERROR_SUCCESS; 
} 
 
DWORD CCameraPdd::SetSensorState( ULONG lModeType, CSSTATE csState ) 
{ 
    DWORD dwError = ERROR_SUCCESS; 
    DEBUGMSG( ZONE_IOCTL, ( _T("CAM: CCameraPdd::SetSensorState to %d\r\n"),csState) ); 
 
    switch ( csState ) 
    { 
        case CSSTATE_STOP: 
            DEBUGMSG( ZONE_IOCTL, ( _T("CAM: CCameraPdd::SetSensorState CSSTATE_STOP\r\n")) ); 
            m_CsState[lModeType] = CSSTATE_STOP; 
 
            if( STILL == lModeType ) 
            { 
                m_bStillCapInProgress = false; 
            } 
             
            if (!is_qci_capturing) 
                break; 
 
            qci_set_capture_callback(NULL, 
                                     reinterpret_cast(this),  
                                     lModeType); 
 
            stop_capture(); 
            power_off();  
            is_qci_capturing = FALSE; 
            break; 
 
        case CSSTATE_PAUSE: 
            DEBUGMSG( ZONE_IOCTL, ( _T("CAM: CCameraPdd::SetSensorState CSSTATE_PAUSE\r\n")) ); 
            m_CsState[lModeType] = CSSTATE_PAUSE; 
 
            // start_capture(lModeType); 
            qci_set_capture_callback(NULL, 
                                     reinterpret_cast(this),  
                                     lModeType); 
            break; 
 
        case CSSTATE_RUN: 
            DEBUGMSG( ZONE_IOCTL, ( _T("CAM: CCameraPdd::SetSensorState CSSTATE_RUN\r\n")) ); 
            m_CsState[lModeType] = CSSTATE_RUN; 
 
            qci_set_capture_callback(CCameraPdd::CaptureInterruptCallBack, 
                                     reinterpret_cast(this),  
                                     lModeType); 
 
            if (is_qci_capturing) 
                break; 
 
            start_capture(lModeType); 
            is_qci_capturing = TRUE; 
 
            break; 
 
        default: 
            DEBUGMSG( ZONE_IOCTL|ZONE_ERROR, ( _T("CAM: IOControl(%08x): Incorrect State\r\n"), this ) ); 
            dwError = ERROR_INVALID_PARAMETER; 
    } 
 
    return dwError; 
} 
 
DWORD CCameraPdd::TakeStillPicture( LPVOID pBurstModeInfo ) 
{ 
    DWORD dwError = ERROR_SUCCESS; 
    m_bStillCapInProgress = true; 
    //Ignore pBurstModeInfo 
    m_CsState[STILL] = CSSTATE_RUN; 
 
    if (is_qci_capturing) 
    { 
        stop_capture(); 
        is_qci_capturing = FALSE; 
    } 
 
    start_capture(STILL); 
    is_qci_capturing = TRUE; 
 
    qci_set_capture_callback(CCameraPdd::CaptureInterruptCallBack, 
                                     reinterpret_cast(this),  
                                     STILL); 
    return dwError; 
} 
 
 
DWORD CCameraPdd::GetSensorModeInfo( ULONG ulModeType, PSENSORMODEINFO pSensorModeInfo ) 
{ 
    pSensorModeInfo->MemoryModel = m_SensorModeInfo[ulModeType].MemoryModel; 
    pSensorModeInfo->MaxNumOfBuffers = m_SensorModeInfo[ulModeType].MaxNumOfBuffers; 
    pSensorModeInfo->PossibleCount = m_SensorModeInfo[ulModeType].PossibleCount; 
    pSensorModeInfo->VideoCaps.DefaultVideoControlCaps = DefaultVideoControlCaps[ulModeType]; 
    pSensorModeInfo->VideoCaps.CurrentVideoControlCaps = m_pModeVideoCaps[ulModeType].CurrentVideoControlCaps; 
    pSensorModeInfo->pVideoFormat = &m_pModeVideoFormat[ulModeType]; 
     
    return ERROR_SUCCESS; 
} 
 
DWORD CCameraPdd::SetSensorModeFormat( ULONG ulModeType, PCS_DATARANGE_VIDEO pCsDataRangeVideo ) 
{ 
    memcpy( &m_pCurrentFormat[ulModeType], pCsDataRangeVideo, sizeof ( CS_DATARANGE_VIDEO ) ); 
    return ERROR_SUCCESS; 
} 
 
PVOID CCameraPdd::AllocateBuffer( ULONG ulModeType ) 
{   
    // Real PDD may want to save off this allocated pointer 
    // in an array. 
    ULONG ulFrameSize = CS__DIBSIZE (m_pCurrentFormat[ulModeType].VideoInfoHeader.bmiHeader); 
    return RemoteLocalAlloc( LPTR, ulFrameSize ); 
} 
 
DWORD CCameraPdd::DeAllocateBuffer( ULONG ulModeType, PVOID pBuffer ) 
{ 
    RemoteLocalFree( pBuffer ); 
    return ERROR_SUCCESS; 
} 
 
DWORD CCameraPdd::RegisterClientBuffer( ULONG ulModeType, PVOID pBuffer ) 
{ 
    // Real PDD may want to save pBuffer which is a pointer to buffer that DShow created. 
    return ERROR_SUCCESS; 
} 
 
DWORD CCameraPdd::UnRegisterClientBuffer( ULONG ulModeType, PVOID pBuffer ) 
{ 
    // DShow is not going to use pBuffer (which was originally allocated by DShow) anymore. If the PDD 
    // is keeping a cached pBuffer pointer (in RegisterClientBuffer()) then this is the right place to 
    // stop using it and maybe set the cached pointer to NULL.  
    // Note: PDD must not delete this pointer as it will be deleted by DShow itself 
    return ERROR_SUCCESS; 
} 
 
DWORD CCameraPdd::HandleSensorModeCustomProperties( ULONG ulModeType, PUCHAR pInBuf, DWORD  InBufLen, PUCHAR pOutBuf, DWORD  OutBufLen, PDWORD pdwBytesTransferred ) 
{ 
    DEBUGMSG( ZONE_IOCTL, ( _T("CAM: IOControl: Unsupported PropertySet Request\r\n")) ); 
    return ERROR_NOT_SUPPORTED; 
} 
 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
// The following code is only meant for this sample pdd 
// The real PDD should not contain any of the code below. 
// Instead the real PDD should implement its own FillPinBuffer()  
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
 
extern "C" { WINGDIAPI HBITMAP WINAPI CreateBitmapFromPointer( CONST BITMAPINFO *pbmi, int iStride, PVOID pvBits); } 
 
DWORD CCameraPdd::FillBuffer( ULONG ulModeType, PUCHAR pImage ) 
{ 
    PCS_VIDEOINFOHEADER pCsVideoInfoHdr = &m_pCurrentFormat[ulModeType].VideoInfoHeader; 
    UINT32 biSizeImage    = pCsVideoInfoHdr->bmiHeader.biSizeImage; 
 
    if (sensor && qci_frame) 
    { 
        sensor->handle_frame_interrupt(pImage,  
                                       &pCsVideoInfoHdr->bmiHeader, 
                                       qci_frame); 
        return biSizeImage; 
    } else 
        return 0; 
} 
 
void CCameraPdd :: CaptureInterruptCallBack(ULONG user, ULONG mode) 
{ 
    CCameraPdd *pCameraPdd= reinterpret_cast(user); 
 
    if( NULL == pCameraPdd ) 
    { 
        DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("CAM: IOControl: pCameraPdd is NULL.\r\n"))) ; 
    } 
    else 
    { 
        __try 
        { 
            pCameraPdd->HandleCaptureInterrupt(mode); 
        } 
        __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) 
        { 
            DEBUGMSG(ZONE_IOCTL|ZONE_ERROR, (_T("CAM: IOControl: Access violation.\r\n"))) ; 
        } 
    } 
} 
 
void CCameraPdd :: HandleCaptureInterrupt(ULONG mode) 
{ 
    if(mode != STILL && m_bStillCapInProgress ) 
        return; 
 
 
    if (mode == STILL) 
    { 
        stop_capture(); 
        power_off();  
        is_qci_capturing = FALSE; 
        m_bStillCapInProgress = false; 
    } 
 
    MDD_HandleIO( m_ppModeContext[mode], mode ); 
} 
 
bool CCameraPdd::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