📄 capprop.c
字号:
//===========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1996 - 2000 Microsoft Corporation. All Rights Reserved.
//
//===========================================================================
/*++
Module Name:
CapProp.c
Abstract:
Stream class based WDM driver for 1934 Desktop Camera.
This file contains code to handle the video and camera control properties.
Author:
Yee J. Wu 9-Sep-97
Environment:
Kernel mode only
Revision History:
Yee J. Wu 16-Nov-00
Make getting, advertising, and setting device properties more generic
by querying feature from the device directly instead of static settings
based on the vendor. The default and initial current settings will be
read from registry (from the INF). The current setting will continue
to be updated and used thereafter. For device that does not have its INF
section, mid-range will be used as its default and initial settings.
--*/
#include "strmini.h"
#include "ksmedia.h"
#include "1394.h"
#include "wdm.h" // for DbgBreakPoint() defined in dbg.h
#include "dbg.h"
#include "dcamdef.h"
#include "dcampkt.h"
#include "capprop.h" // Video and camera property function prototype
#include "PropData.h" // Generic device properties that are readonly
//
// Registry subky and values wide character strings.
//
WCHAR wszSettings[] = L"Settings";
WCHAR wszVModeInq0[] = L"VModeInq0";
WCHAR wszBrightness[] = L"Brightness";
WCHAR wszHue[] = L"Hue";
WCHAR wszSaturation[] = L"Saturation";
WCHAR wszSharpness[] = L"Sharpness";
WCHAR wszWhiteBalance[] = L"WhiteBalance";
WCHAR wszZoom[] = L"Zoom";
WCHAR wszFocus[] = L"Focus";
WCHAR wszBrightnessDef[] = L"BrightnessDef";
WCHAR wszHueDef[] = L"HueDef";
WCHAR wszSaturationDef[] = L"SaturationDef";
WCHAR wszSharpnessDef[] = L"SharpnessDef";
WCHAR wszWhiteBalanceDef[] = L"WhiteBalanceDef";
WCHAR wszZoomDef[] = L"ZoomDef";
WCHAR wszFocusDef[] = L"FocusDef";
NTSTATUS
DCamGetProperty(
IN PIRB pIrb,
PDCAM_EXTENSION pDevExt,
ULONG ulFieldOffset,
LONG * plValue,
ULONG * pulCapability,
ULONG * pulFlags,
DCamRegArea * pFeature
)
/*
Get a device property from its register. Return the capabilites and current settings.
*/
{
NTSTATUS status, StatusWait;
// Make sure that device support this feature.
if(pFeature->Feature.PresenceInq == 0) {
DbgMsg1(("\'OffSet:%d not supported!\n", ulFieldOffset));
return STATUS_NOT_SUPPORTED;
}
// Serialize read/write to the device register
StatusWait = KeWaitForSingleObject( &pDevExt->hMutexProperty, Executive, KernelMode, FALSE, 0 );
*pulCapability = 0;
if (pFeature->Feature.AutoMode)
*pulCapability |= KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; // or == KSPROPERTY_CAMERACONTROL_FLAGS_AUTO
if (pFeature->Feature.ManualMode)
*pulCapability |= KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
pDevExt->RegArea.AsULONG = 0;
status = DCamReadRegister(pIrb, pDevExt, ulFieldOffset, &(pDevExt->RegArea.AsULONG));
if(NT_SUCCESS(status)) {
pDevExt->RegArea.AsULONG = bswap(pDevExt->RegArea.AsULONG);
DbgMsg1(("\'GetProperty: CurrentSettings: Offset:%d; %x; Pres:%d;OnePush:%d;OnOff:%d;Auto:%d;Value:%d\n",
ulFieldOffset,
pDevExt->RegArea.AsULONG,
pDevExt->RegArea.Brightness.PresenceInq,
pDevExt->RegArea.Brightness.OnePush,
pDevExt->RegArea.Brightness.OnOff,
pDevExt->RegArea.Brightness.AutoMode,
pDevExt->RegArea.Brightness.Value
));
*plValue = (LONG) pDevExt->RegArea.Brightness.Value;
// These only valid if it has these capabilities.
if (pDevExt->RegArea.Brightness.AutoMode)
*pulFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO;
else
*pulFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
} else {
ERROR_LOG(("\'DCamGetProperty: Failed %x to read setting. Offset:%x\n", status, ulFieldOffset));
status = STATUS_UNSUCCESSFUL;
}
KeReleaseMutex(&pDevExt->hMutexProperty, FALSE);
return status;
}
NTSTATUS
DCamSetProperty(
IN PIRB pIrb,
PDCAM_EXTENSION pDevExt,
ULONG ulFieldOffset,
ULONG ulFlags,
LONG lValue,
DCamRegArea * pFeature,
DCamRegArea * pCachedRegArea
)
/*
For a supported device, set to a new setting.
*/
{
NTSTATUS status, StatusWait;
LONG lRetries = MAX_READ_REG_RETRIES;
LARGE_INTEGER stableTime;
// Make sure that device support this feature.
if(pFeature->Feature.PresenceInq == 0) {
DbgMsg1(("\'OffSet:%d not supported!\n", ulFieldOffset));
return STATUS_NOT_SUPPORTED;
}
// Validate the supported range
if((LONG) pFeature->Feature.MAX_Value < lValue || lValue < (LONG) pFeature->Feature.MIN_Value) {
ERROR_LOG(("\'Invalid value:%d for supported range (%d, %d)\n", lValue, pFeature->Feature.MIN_Value, pFeature->Feature.MAX_Value));
return STATUS_INVALID_PARAMETER;
}
// Serialize read/write to the register
StatusWait = KeWaitForSingleObject( &pDevExt->hMutexProperty, Executive, KernelMode, FALSE, 0 );
// Read the current setting of this property
pDevExt->RegArea.AsULONG = 0;
do {
status = DCamReadRegister(pIrb, pDevExt, ulFieldOffset, &(pDevExt->RegArea.AsULONG));
if (!status) {
pDevExt->RegArea.AsULONG = bswap(pDevExt->RegArea.AsULONG);
DbgMsg3(("\'SetProperty: Current: %x: Pres:%d;OnePush:%d;OnOff:%d;Auto:%d;Value:%d\n",
pDevExt->RegArea.AsULONG,
pDevExt->RegArea.Brightness.PresenceInq,
pDevExt->RegArea.Brightness.OnePush,
pDevExt->RegArea.Brightness.OnOff,
pDevExt->RegArea.Brightness.AutoMode,
pDevExt->RegArea.Brightness.Value
));
// This feature might be in the transition (such as zoom or focus),
// it might return pDevExt->RegArea.Brightness.PresenceInq == 0.
if(pDevExt->RegArea.Brightness.PresenceInq == 1)
break;
else {
if(lRetries > 1) {
stableTime.LowPart = DCAM_REG_STABLE_DELAY;
stableTime.HighPart = -1;
KeDelayExecutionThread(KernelMode, TRUE, &stableTime);
ERROR_LOG(("\'DCamSetProperty: delay, and try again...\n"));
};
}
} else {
// No need to retry if we failed to read.
break;
}
lRetries--;
} while (lRetries > 0);
if(status || lRetries == 0) {
KeReleaseMutex(&pDevExt->hMutexProperty, FALSE);
ERROR_LOG(("\'DCamSetProperty: Failed! ST:%x; exceeded retried while pres is still 0\n", status));
return STATUS_UNSUCCESSFUL;
}
pDevExt->RegArea.Brightness.PresenceInq = 1; // Should be present.
if((ulFlags & KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO) == KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO) {
pDevExt->RegArea.Brightness.AutoMode = 1;
// When Auto is set to 1, Value field is ignored.
} else {
pDevExt->RegArea.Brightness.AutoMode = 0;
// special case for white balance
if(FIELDOFFSET(CAMERA_REGISTER_MAP, WhiteBalance) == ulFieldOffset) {
pDevExt->RegArea.WhiteBalance.UValue = pDevExt->RegArea.WhiteBalance.VValue = lValue;
} else
pDevExt->RegArea.Brightness.Value = lValue;
}
DbgMsg2(("\'SetProperty: NewSetting: Offset:%d; %x; Pres:%d;OnePush:%d;OnOff:%d;Auto:%d;Value:%d\n",
ulFieldOffset,
pDevExt->RegArea.AsULONG,
pDevExt->RegArea.Brightness.PresenceInq,
pDevExt->RegArea.Brightness.OnePush,
pDevExt->RegArea.Brightness.OnOff,
pDevExt->RegArea.Brightness.AutoMode,
pDevExt->RegArea.Brightness.Value
));
pDevExt->RegArea.AsULONG = bswap(pDevExt->RegArea.AsULONG);
status = DCamWriteRegister(pIrb, pDevExt, ulFieldOffset, pDevExt->RegArea.AsULONG);
if(status) {
ERROR_LOG(("\'DCamGetProperty: failed with status=0x%x\n", status));
} else {
// Update the cached setting (saved in the device extension)
// These cached values will be save to registry as the persisted values for these properties.
if(pCachedRegArea) {
// WhiteBalance is an exception
if(FIELDOFFSET(CAMERA_REGISTER_MAP, WhiteBalance) == ulFieldOffset) {
pCachedRegArea->WhiteBalance.UValue = pCachedRegArea->WhiteBalance.VValue = lValue;
} else
pCachedRegArea->Brightness.Value = lValue;
// AutoMode is the 7th bit for all the properties used here. (we do not use TRIGGER_MODE)
pCachedRegArea->Brightness.AutoMode = ((ulFlags & KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO) == KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO);
}
#if DBG
// Verify that data were written as expected.
pDevExt->RegAreaVerify.AsULONG = 0;
status = DCamReadRegister(pIrb, pDevExt, ulFieldOffset, &(pDevExt->RegAreaVerify.AsULONG));
if (!status) {
// bswap so we can compare.
pDevExt->RegArea.AsULONG = bswap(pDevExt->RegArea.AsULONG);
pDevExt->RegAreaVerify.AsULONG = bswap(pDevExt->RegAreaVerify.AsULONG);
DbgMsg2(("\'SetProperty: VerifySetting; Offset:%d; %x; Pres:%d;OnePush:%d;OnOff:%d;Auto:%d;Value:%d\n\n",
ulFieldOffset,
pDevExt->RegAreaVerify.AsULONG,
pDevExt->RegAreaVerify.Brightness.PresenceInq,
pDevExt->RegAreaVerify.Brightness.OnePush,
pDevExt->RegAreaVerify.Brightness.OnOff,
pDevExt->RegAreaVerify.Brightness.AutoMode,
pDevExt->RegAreaVerify.Brightness.Value
));
ASSERT(pDevExt->RegArea.Brightness.PresenceInq == pDevExt->RegAreaVerify.Brightness.PresenceInq);
ASSERT(pDevExt->RegArea.Brightness.OnePush == pDevExt->RegAreaVerify.Brightness.OnePush);
ASSERT(pDevExt->RegArea.Brightness.OnOff == pDevExt->RegAreaVerify.Brightness.OnOff);
ASSERT(pDevExt->RegArea.Brightness.AutoMode == pDevExt->RegAreaVerify.Brightness.AutoMode);
// If not auto mode, Value must match!
ASSERT( pDevExt->RegArea.Brightness.Value == pDevExt->RegAreaVerify.Brightness.Value ||
(pDevExt->RegArea.Brightness.Value != pDevExt->RegAreaVerify.Brightness.Value && pDevExt->RegArea.Brightness.AutoMode == 1));
}
#endif
}
KeReleaseMutex(&pDevExt->hMutexProperty, FALSE);
return status;
}
/*
** AdapterGetVideoProcAmpProperty ()
**
** Handles Set operations on the VideoProcAmp property set.
** Testcap uses this for demo purposes only.
**
** Arguments:
**
** pSRB -
** Pointer to the HW_STREAM_REQUEST_BLOCK
**
** Returns:
**
** Side Effects: none
*/
VOID
AdapterGetVideoProcAmpProperty(
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
NTSTATUS status;
PDCAM_EXTENSION pDevExt = (PDCAM_EXTENSION) pSrb->HwDeviceExtension;
PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
PKSPROPERTY_VIDEOPROCAMP_S pS = (PKSPROPERTY_VIDEOPROCAMP_S) pSPD->PropertyInfo; // pointer to the data
ASSERT (pSPD->PropertyOutputSize >= sizeof (KSPROPERTY_VIDEOPROCAMP_S));
switch (pSPD->Property->Id) {
case KSPROPERTY_VIDEOPROCAMP_BRIGHTNESS:
status = DCamGetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Brightness), &pS->Value, &pS->Capabilities, &pS->Flags, &pDevExt->DevProperty[ENUM_BRIGHTNESS].Feature);
break;
case KSPROPERTY_VIDEOPROCAMP_SHARPNESS:
status = DCamGetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Sharpness), &pS->Value, &pS->Capabilities, &pS->Flags, &pDevExt->DevProperty[ENUM_SHARPNESS].Feature);
break;
case KSPROPERTY_VIDEOPROCAMP_HUE:
status = DCamGetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Hue), &pS->Value, &pS->Capabilities, &pS->Flags, &pDevExt->DevProperty[ENUM_HUE].Feature);
break;
case KSPROPERTY_VIDEOPROCAMP_SATURATION:
status = DCamGetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Saturation), &pS->Value, &pS->Capabilities, &pS->Flags, &pDevExt->DevProperty[ENUM_SATURATION].Feature);
break;
case KSPROPERTY_VIDEOPROCAMP_WHITEBALANCE:
status = DCamGetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, WhiteBalance), &pS->Value, &pS->Capabilities, &pS->Flags, &pDevExt->DevProperty[ENUM_WHITEBALANCE].Feature);
break;
default:
DbgMsg2(("\'AdapterGetVideoProcAmpProperty, Id (%x)not supported.\n", pSPD->Property->Id));
ASSERT(FALSE);
status = STATUS_NOT_IMPLEMENTED;
break;
}
pSrb->Status = status;
pSrb->ActualBytesTransferred = sizeof (KSPROPERTY_VIDEOPROCAMP_S);
}
/*
** AdapterGetCameraControlProperty ()
**
** Handles Set operations on the VideoProcAmp property set.
** Testcap uses this for demo purposes only.
**
** Arguments:
**
** pSRB -
** Pointer to the HW_STREAM_REQUEST_BLOCK
**
** Returns:
**
** Side Effects: none
*/
VOID
AdapterGetCameraControlProperty(
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
NTSTATUS status;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -