Cómo implementar propiedades de control de cámara extendidas
El controlador de cámara debe implementar propiedades de control de cámara extendidas como conjuntos de propiedades individuales, es decir, cada propiedad debe implementarse como un único conjunto de propiedades. El código de ejemplo siguiente se puede usar como punto de partida para implementar estas propiedades.
Nota Dado que el tamaño de los datos de una propiedad extendida puede tener una longitud arbitraria, consulte la pila en modo de usuario para conocer el tamaño de los datos pasando un búfer nulo. Se necesita un proceso de dos pasos: en primer lugar, el controlador devuelve la longitud necesaria, como se muestra en el código de ejemplo y, a continuación, la pila en modo de usuario solicita un búfer adecuado para los datos de propiedad.
Implementación del controlador
DEFINE_KSPROPERTY_TABLE(SocSimFilterFocusPropertyItems)
{
DEFINE_KSPROPERTY_ITEM(
0,
CCaptureFilter::FocusRectHandler,
sizeof(KSPROPERTY),
0,
CCaptureFilter::FocusRectHandler,
NULL, 0, NULL, NULL, 0
)
};
DEFINE_KSPROPERTY_TABLE(SocSimFilterVideoStabPropertyItems)
{
DEFINE_KSPROPERTY_ITEM(
0,
CCaptureFilter::VideoStabilizationModeHandler,
sizeof(KSPROPERTY),
0,
CCaptureFilter::VideoStabilizationModeHandler,
NULL, 0, NULL, NULL, 0
)
};
DEFINE_KSPROPERTY_TABLE(SocSimFilterFlashPropertyItems)
{
DEFINE_KSPROPERTY_ITEM(
0,
CCaptureFilter::FlashHandler,
sizeof(KSPROPERTY),
0,
CCaptureFilter::FlashHandler,
NULL, 0, NULL, NULL, 0
)
};
DEFINE_KSPROPERTY_SET_TABLE(SocSimFilterPropertySets)
{
DEFINE_KSPROPERTY_SET(
&PROPSETID_VIDCAP_CAMERACONTROL_REGION_OF_INTEREST,
SIZEOF_ARRAY(SocSimFilterFocusPropertyItems),
SocSimFilterFocusPropertyItems,
0,
NULL),
DEFINE_KSPROPERTY_SET(
&PROPSETID_VIDCAP_CAMERACONTROL_FLASH,
SIZEOF_ARRAY(SocSimFilterFlashPropertyItems),
SocSimFilterFlashPropertyItems,
0,
NULL),
DEFINE_KSPROPERTY_SET(
&PROPSETID_VIDCAP_CAMERACONTROL_VIDEO_STABILIZATION,
SIZEOF_ARRAY(SocSimFilterVideoStabPropertyItems),
SocSimFilterVideoStabPropertyItems,
0,
NULL)
};
NTSTATUS
CCaptureFilter::FlashHandler(
__in PIRP Irp,
__in PKSPROPERTY Property,
__inout PVOID pData
)
{
PAGED_CODE();
NTSTATUS Status = STATUS_SUCCESS;
NT_ASSERT(Irp);
NT_ASSERT(Property);
CCaptureFilter* pFilter = reinterpret_cast <CCaptureFilter*>(KsGetFilterFromIrp(Irp)->Context);
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(Irp);
ULONG ulOutputBufferLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
ULONG InputBufferLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
if (Property->Flags & KSPROPERTY_TYPE_SET)
{
if (ulOutputBufferLength == 0)
{
Irp->IoStatus.Information = sizeof(KSPROPERTY_CAMERACONTROL_FLASH_S);
Status = STATUS_BUFFER_OVERFLOW;
}
else if (ulOutputBufferLength < sizeof(KSPROPERTY_CAMERACONTROL_FLASH_S))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else if (pData && ulOutputBufferLength >= sizeof(KSPROPERTY_CAMERACONTROL_FLASH_S))
{
PKSPROPERTY_CAMERACONTROL_FLASH_S pFlash = (PKSPROPERTY_CAMERACONTROL_FLASH_S)pData;
pFilter->m_Flash = pFlash->Flash;
pFilter->m_FlashCapabilites = pFlash->Capabilities;
Status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(KSPROPERTY_CAMERACONTROL_FLASH_S);
}
else
{
Status = STATUS_INVALID_PARAMETER;
}
}
else if (Property->Flags & KSPROPERTY_TYPE_GET)
{
if (ulOutputBufferLength == 0)
{
Irp->IoStatus.Information = sizeof(KSPROPERTY_CAMERACONTROL_FLASH_S);
Status = STATUS_BUFFER_OVERFLOW;
}
else if (ulOutputBufferLength < sizeof(KSPROPERTY_CAMERACONTROL_FLASH_S))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else if (pData && ulOutputBufferLength >= sizeof(KSPROPERTY_CAMERACONTROL_FLASH_S))
{
PKSPROPERTY_CAMERACONTROL_FLASH_S pFlash = (PKSPROPERTY_CAMERACONTROL_FLASH_S)pData;
pFlash->Flash = pFilter->m_Flash;
pFlash->Capabilities = pFilter->m_FlashCapabilites;
Irp->IoStatus.Information = sizeof(KSPROPERTY_CAMERACONTROL_FLASH_S);
Status = STATUS_SUCCESS;
}
else
{
Status = STATUS_INVALID_PARAMETER;
}
}
return Status;
}
NTSTATUS
CCaptureFilter::VideoStabilizationModeHandler(
__in PIRP Irp,
__in PKSPROPERTY Property,
__inout PVOID pData
)
{
PAGED_CODE();
NTSTATUS Status = STATUS_SUCCESS;
NT_ASSERT(Irp);
NT_ASSERT(Property);
CCaptureFilter* pFilter = reinterpret_cast <CCaptureFilter*>(KsGetFilterFromIrp(Irp)->Context);
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(Irp);
ULONG ulOutputBufferLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
ULONG InputBufferLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
if (Property->Flags & KSPROPERTY_TYPE_SET)
{
if (ulOutputBufferLength == 0)
{
Irp->IoStatus.Information = sizeof(KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S);
Status = STATUS_BUFFER_OVERFLOW;
}
else if (ulOutputBufferLength < sizeof(KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else if (pData && ulOutputBufferLength >= sizeof(KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S))
{
PKSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S pVideoStab = (PKSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S)pData;
pFilter->m_VideoStabMode = pVideoStab->VideoStabilizationMode;
pFilter->m_VideoStabCapabilites = pVideoStab->Capabilities;
Status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S);
}
else
{
Status = STATUS_INVALID_PARAMETER;
}
}
else if (Property->Flags & KSPROPERTY_TYPE_GET)
{
if (ulOutputBufferLength == 0)
{
Irp->IoStatus.Information = sizeof(KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S);
Status = STATUS_BUFFER_OVERFLOW;
}
else if (ulOutputBufferLength < sizeof(KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else if (pData && ulOutputBufferLength >= sizeof(KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S))
{
PKSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S pVideoStab = (PKSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S)pData;
pVideoStab->VideoStabilizationMode = pFilter->m_VideoStabMode;
pVideoStab->Capabilities = pFilter->m_VideoStabCapabilites;
Irp->IoStatus.Information = sizeof(KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S);
Status = STATUS_SUCCESS;
}
else
{
Status = STATUS_INVALID_PARAMETER;
}
}
return Status;
}
NTSTATUS
CCaptureFilter::FocusRectHandler(
__in PIRP Irp,
__in PKSPROPERTY Property,
__inout PVOID pData
)
{
PAGED_CODE();
NTSTATUS Status = STATUS_SUCCESS;
NT_ASSERT(Irp);
NT_ASSERT(Property);
CCaptureFilter* pFilter = reinterpret_cast <CCaptureFilter*>(KsGetFilterFromIrp(Irp)->Context);
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(Irp);
ULONG ulOutputBufferLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
ULONG InputBufferLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
if (Property->Flags & KSPROPERTY_TYPE_SET)
{
if (ulOutputBufferLength == 0)
{
Irp->IoStatus.Information = sizeof(KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S);
Status = STATUS_BUFFER_OVERFLOW;
}
else if (ulOutputBufferLength < sizeof(KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else if (pData && ulOutputBufferLength >= sizeof(KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S))
{
PKSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S pFocusRect = (PKSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S)pData;
pFilter->m_FocusRect.left = pFocusRect->FocusRect.left;
pFilter->m_FocusRect.top = pFocusRect->FocusRect.top;
pFilter->m_FocusRect.right = pFocusRect->FocusRect.right;
pFilter->m_FocusRect.bottom = pFocusRect->FocusRect.bottom;
pFilter->m_AutoFocusLock = pFocusRect->AutoFocusLock;
pFilter->m_AutoExposureLock = pFocusRect->AutoExposureLock;
pFilter->m_AutoWhitebalanceLock = pFocusRect->AutoWhitebalanceLock;
Status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S);
}
else
{
Status = STATUS_INVALID_PARAMETER;
}
}
else if (Property->Flags & KSPROPERTY_TYPE_GET)
{
if (ulOutputBufferLength == 0)
{
Irp->IoStatus.Information = sizeof(KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S);
Status = STATUS_BUFFER_OVERFLOW;
}
else if (ulOutputBufferLength < sizeof(KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else if (pData && ulOutputBufferLength >= sizeof(KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S))
{
PKSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S pFocusRect = (PKSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S)pData;
pFocusRect->FocusRect.left = pFilter->m_FocusRect.left;
pFocusRect->FocusRect.top = pFilter->m_FocusRect.top;
pFocusRect->FocusRect.right = pFilter->m_FocusRect.right;
pFocusRect->FocusRect.bottom = pFilter->m_FocusRect.bottom;
pFocusRect->AutoFocusLock = pFilter->m_AutoFocusLock;
pFocusRect->AutoExposureLock = pFilter->m_AutoExposureLock;
pFocusRect->AutoWhitebalanceLock = pFilter->m_AutoWhitebalanceLock;
Irp->IoStatus.Information = sizeof(KSPROPERTY_CAMERACONTROL_REGION_OF_INTEREST_S);
Status = STATUS_SUCCESS;
}
else
{
Status = STATUS_INVALID_PARAMETER;
}
}
return Status;
}