From 96eb96dfb613e4c745db6bd1f53a92fe7e2290fc Mon Sep 17 00:00:00 2001 From: karlf Date: Thu, 11 Aug 2016 13:28:13 -0700 Subject: Updated for "Windows 10 Anniversary Update" (Version 1607) --- AVStream/avscamera/sys/Roi.cpp | 629 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 629 insertions(+) create mode 100644 AVStream/avscamera/sys/Roi.cpp (limited to 'AVStream/avscamera/sys/Roi.cpp') diff --git a/AVStream/avscamera/sys/Roi.cpp b/AVStream/avscamera/sys/Roi.cpp new file mode 100644 index 00000000..e1118996 --- /dev/null +++ b/AVStream/avscamera/sys/Roi.cpp @@ -0,0 +1,629 @@ +/************************************************************************** + + A/V Stream Camera Sample + + Copyright (c) 2013, Microsoft Corporation. + + File: + + Roi.cpp + + Abstract: + + This file contains the implemention of CRoiConfig, CRoiProperty and + related classes used in the filter to implement ROI handling. + + History: + + created 6/27/2013 + +**************************************************************************/ + +#include "Common.h" + +/************************************************************************** + + PAGED CODE + +**************************************************************************/ + +#ifdef ALLOC_PRAGMA +#pragma code_seg("PAGE") +#endif // ALLOC_PRAGMA + +// Helper function to diff ptrs. +inline +UINT_PTR +ByteDiffPtrs( PVOID pBase, PVOID pCurrent ) +{ + PAGED_CODE(); + + return reinterpret_cast(pCurrent) - reinterpret_cast(pBase) ; +} + +// Helper function to get the size of an ROI control based just on the ID. +static +ULONG +GetSizeOfRoiInfo( ULONG ControlId ) +{ + PAGED_CODE(); + + switch( ControlId ) + { + case KSPROPERTY_CAMERACONTROL_EXTENDED_WHITEBALANCEMODE: + return sizeof(KSCAMERA_EXTENDEDPROP_ROI_WHITEBALANCE); + break; + + case KSPROPERTY_CAMERACONTROL_EXTENDED_EXPOSUREMODE: + return sizeof(KSCAMERA_EXTENDEDPROP_ROI_EXPOSURE); + break; + + case KSPROPERTY_CAMERACONTROL_EXTENDED_FOCUSMODE: + return sizeof(KSCAMERA_EXTENDEDPROP_ROI_FOCUS); + break; + + default: + NT_ASSERT(FALSE); + return 0; + } +} + +// Helper function to get the size of an ROI control. +static +ULONG +GetSize( + _In_ PKSCAMERA_EXTENDEDPROP_ROI_ISPCONTROL pCtrl +) +{ + PAGED_CODE(); + + // This actually needs to return the type based on the ROI_INFO size + ULONG RoiInfoSize = GetSizeOfRoiInfo( pCtrl->ControlId ); + + if( RoiInfoSize ) + { + return + sizeof(KSCAMERA_EXTENDEDPROP_ROI_ISPCONTROL) + + (pCtrl->ROICount * RoiInfoSize); + } + else + { + NT_ASSERTMSG("GetSizeOfRoiInfo( pCtrl->ControlId ) returned 0! Should never happen!", FALSE); + return 0; + } +} + +// Helper function to walk to the next ROI control. +static +PKSCAMERA_EXTENDEDPROP_ROI_ISPCONTROL +NextCtrl( + _In_ PKSCAMERA_EXTENDEDPROP_ROI_ISPCONTROL pCtrl +) +{ + PAGED_CODE(); + + ULONG Size = GetSize( pCtrl ); + + if( Size ) + { + return + reinterpret_cast + (((PBYTE) pCtrl) + Size); + } + else + { + NT_ASSERTMSG("GetSize( pCtrl ) returned 0! Should never happen!", FALSE); + return nullptr; + } +} + +PKSCAMERA_EXTENDEDPROP_ROI_ISPCONTROL +CRoiProperty:: +Find( + _In_ KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY Property +) +/*++ + +Routine Description: + + Search this ROI property for a property ID. + +Arguments: + + Property - + Which control to find. + +Return Value: + + A pointer to the ROI control structure. + +--*/ +{ + PAGED_CODE(); + + // We assume the controls have been validated first. + PKSCAMERA_EXTENDEDPROP_ROI_ISPCONTROL pIspCtrl = + reinterpret_cast (this+1); + + // Loop thru the controls. + for( ULONG i=0; iControlId == (ULONG) Property ) + { + return pIspCtrl; + } + + // Advance to the next control. + pIspCtrl = NextCtrl( pIspCtrl ); + } + + return nullptr; +} + +PKSCAMERA_EXTENDEDPROP_ROI_ISPCONTROL +CRoiProperty:: +Add( + _In_ PKSCAMERA_EXTENDEDPROP_ROI_ISPCONTROL pCtrl +) +/*++ + +Routine Description: + + Add a control to the end of this header. + + Note: This function does not reallocate memory. Be careful to ensure + there is space available. + +Arguments: + + pCtrl - + An ROI control to append. + +Return Value: + + A pointer to the appended ROI control structure. + +--*/ +{ + PAGED_CODE(); + + // Only bother to add if there are ROIs. + if( pCtrl->ROICount > 0 ) + { + // We assume the controls have been validated first. + PKSCAMERA_EXTENDEDPROP_ROI_ISPCONTROL pIspCtrl = + reinterpret_cast (this+1); + + // Loop thru all the controls. + for( ULONG i=0; i (this+1); + + // Loop thru the controls. + for( ULONG i=0; iControlId ) + { + case KSPROPERTY_CAMERACONTROL_EXTENDED_WHITEBALANCEMODE: + case KSPROPERTY_CAMERACONTROL_EXTENDED_EXPOSUREMODE: + case KSPROPERTY_CAMERACONTROL_EXTENDED_FOCUSMODE: + break; + + default: + //NT_ASSERT(FALSE); + DBG_LEAVE( "()=false : Invalid ControlId = 0x%08X", pIspCtrl->ControlId ); + return false; + } + + // Make sure there is room for the # of ROIs reported + if( Size < ByteDiffPtrs( this, NextCtrl(pIspCtrl) ) || + m_Hdr.Size < ByteDiffPtrs( &m_Hdr, NextCtrl(pIspCtrl) ) ) + { + //NT_ASSERT(FALSE); + DBG_TRACE( "Failed(2): Size=%d, should be at least %Iu", Size, ByteDiffPtrs( this, NextCtrl(pIspCtrl) ) ); + DBG_TRACE( " Or: m_Hdr.Size=%d, should be at least %Iu", m_Hdr.Size, ByteDiffPtrs( &m_Hdr, NextCtrl(pIspCtrl) ) ); + DBG_LEAVE( "()=false" ); + return false; + } + + // Validate the ROIs + for( ULONG j=0; jROICount; j++ ) + { + // Index into to the control's ROI list. Get the equivilent of "pIspCtrl->RoiInfo[j]" + PKSCAMERA_EXTENDEDPROP_ROI_INFO pRoiInfo = + reinterpret_cast + (((PBYTE) (pIspCtrl+1)) + (j * GetSizeOfRoiInfo(pIspCtrl->ControlId) )); + + // Validate the cooridinates + if( pRoiInfo->Region.top < (LONG) TO_Q31(0) || + pRoiInfo->Region.bottom < (LONG) TO_Q31(0) || + pRoiInfo->Region.left < (LONG) TO_Q31(0) || + pRoiInfo->Region.right < (LONG) TO_Q31(0) ) + { + //NT_ASSERT(FALSE); + DBG_TRACE( "Failed: Region out of range." ); + DBG_TRACE( " (top=0x%08X, left=0x%08X, bottom=0x%08X, right=0x%08X)" + , pRoiInfo->Region.top + , pRoiInfo->Region.bottom + , pRoiInfo->Region.left + , pRoiInfo->Region.right ); + DBG_LEAVE( "()=false" ); + return false; + } + + // Validate the RegionOfInterestType + switch( pRoiInfo->RegionOfInterestType ) + { + case KSCAMERA_EXTENDEDPROP_ROITYPE_UNKNOWN: + case KSCAMERA_EXTENDEDPROP_ROITYPE_FACE: + break; + default: + //NT_ASSERT(FALSE); + DBG_LEAVE( "()=false Failed: RegionOfInterestType=%d", pRoiInfo->RegionOfInterestType ); + return false; + } + + // Validate the Weight + if( pRoiInfo->Weight > 100 ) + { + //NT_ASSERT(FALSE); + DBG_LEAVE( "()=false Failed: Weight=%d", pRoiInfo->Weight ); + return false; + } + + // Validate the Flags. + // Note: the driver doesn't allow mis-matched ROI Flags. + ULONGLONG RoiFlags = pRoiInfo->Flags & ~KSCAMERA_EXTENDEDPROP_FLAG_CANCELOPERATION; + + switch( pIspCtrl->ControlId ) + { + // Exposure & WhiteBalance only support Auto, Manual & Lock. + case KSPROPERTY_CAMERACONTROL_EXTENDED_EXPOSUREMODE: + if( j!=0 ) + { + if( RoiFlags != ExposureFlags ) + { + DBG_LEAVE( "()=false : Mismatched Exposure Flags" ); + return false; + } + } + else + { + switch( RoiFlags & + (KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_AUTO| + KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_LOCK) ) + { + case KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_AUTO: + case KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_AUTO + KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_LOCK: + case 0: + break; + default: + DBG_LEAVE( "()=false : Invalid Exposure Flags" ); + return false; + } + ExposureFlags = RoiFlags; + } + break; + + case KSPROPERTY_CAMERACONTROL_EXTENDED_WHITEBALANCEMODE: + if( j!=0 ) + { + if( RoiFlags != WhiteBalanceFlags ) + { + DBG_LEAVE( "()=false : Mismatched WhiteBalance Flags" ); + return false; + } + } + else + { + switch( RoiFlags & + (KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_AUTO| + KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_LOCK) ) + { + case KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_AUTO: + case KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_AUTO + KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_LOCK: + case 0: + break; + default: + DBG_LEAVE( "()=false : Invalid WhiteBalance Flags" ); + return false; + } + WhiteBalanceFlags = RoiFlags; + } + break; + + // Focus supports additional flags... + case KSPROPERTY_CAMERACONTROL_EXTENDED_FOCUSMODE: + if( j!=0 ) + { + if( RoiFlags != FocusFlags ) + { + DBG_LEAVE( "()=false : Mismatched Focus Flags" ); + return false; + } + } + else + { + switch( RoiFlags & + (KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_AUTO | + KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_LOCK | + KSCAMERA_EXTENDEDPROP_FOCUS_CONTINUOUS | + KSCAMERA_EXTENDEDPROP_FOCUS_CONTINUOUSLOCK) ) + { + case KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_AUTO: + case KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_AUTO + KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_LOCK: + case KSCAMERA_EXTENDEDPROP_FOCUS_CONTINUOUS: + case KSCAMERA_EXTENDEDPROP_FOCUS_CONTINUOUS + KSCAMERA_EXTENDEDPROP_FOCUS_CONTINUOUSLOCK: + case 0: + break; + default: + DBG_LEAVE( "()=false : Invalid Focus Flags" ); + return false; + } + + switch( RoiFlags & KSCAMERA_EXTENDEDPROP_FOCUS_RANGE_MASK ) + { + case KSCAMERA_EXTENDEDPROP_FOCUS_RANGE_MACRO: + case KSCAMERA_EXTENDEDPROP_FOCUS_RANGE_NORMAL: + case KSCAMERA_EXTENDEDPROP_FOCUS_RANGE_FULLRANGE: + // Depreciated cases are not supported: + //case KSCAMERA_EXTENDEDPROP_FOCUS_RANGE_INFINITY: + //case KSCAMERA_EXTENDEDPROP_FOCUS_RANGE_HYPERFOCAL: + case 0: + break; + default: + DBG_LEAVE( "()=false : Invalid Focus Range" ); + return false; + } + FocusFlags = RoiFlags; + } + break; + } + } + + // Advance to the next control. + pIspCtrl = NextCtrl( pIspCtrl ) ; + } + + DBG_LEAVE( "()=true" ); + return true; +} + +// Log to the debug output. +void +CRoiProperty:: +Log() +{ + PAGED_CODE(); + + DBG_TRACE("Version=%d, PinId=%d, Capability=0x%016llX, Flags=0x%016llX, Size=%d", + Version, PinId, Capability, Flags, Size ); + + CRoiIspControl *pIspCtrl = reinterpret_cast (this+1); + + // Loop thru the controls. + for( ULONG i=0; iLog(); + + // Advance to the next control. + pIspCtrl = reinterpret_cast( NextCtrl( pIspCtrl ) ) ; + } +} + +// +// Initialize a block of memory from another ROI control +// +// Note: This function assumes enough ROI_INFO structures follow +// such that this copy will not overrun. +// +BOOL +CRoiIspControl:: +Init( + _In_ CRoiProperty *pRoiProperty, + _In_ KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY Property +) +/*++ + +Routine Description: + + Initialize a block of memory from another ROI control + + Note: This function assumes enough ROI_INFO structures follow + such that this copy will not overrun. + +Arguments: + + pRoiProperty - + The extended ROI control payload. + + Property - + Which ISP control to copy from the payload. + +Return Value: + + TRUE - The ROI was set. + FALSE - The ROI was cleared. + +--*/ +{ + PAGED_CODE(); + + CRoiIspControl * + pCtrl = reinterpret_cast (pRoiProperty->Find( Property )); + + if( pCtrl ) + { + memcpy( this, + pCtrl, + pCtrl->GetSize() ); + return TRUE; + } + + ControlId = Property; + ROICount = 0; + return FALSE; +} + +// Log to the debug output. +void +CRoiIspControl:: +Log() +{ + PAGED_CODE(); + + switch( ControlId ) + { + case KSPROPERTY_CAMERACONTROL_EXTENDED_WHITEBALANCEMODE: + DBG_TRACE("WhiteBalance"); + break; + + case KSPROPERTY_CAMERACONTROL_EXTENDED_EXPOSUREMODE: + DBG_TRACE("Exposure"); + break; + + case KSPROPERTY_CAMERACONTROL_EXTENDED_FOCUSMODE: + DBG_TRACE("Focus"); + break; + + default: + DBG_TRACE("[Unknown]"); + NT_ASSERT(FALSE); + break; + } + + DBG_TRACE("Result=0x%08X", Result); + + for( ULONG i=0; iRoiInfo[j]" + PKSCAMERA_EXTENDEDPROP_ROI_INFO pRoiInfo = + reinterpret_cast + (((PBYTE) (this+1)) + (i * GetSizeOfRoiInfo(ControlId) )); + + DBG_TRACE(" | Flags=0x%016llX [Top=0x%08X, Left=0x%08X, Bottom=0x%08X, Right=0x%08X]", + pRoiInfo->Flags, + pRoiInfo->Region.top, + pRoiInfo->Region.left, + pRoiInfo->Region.bottom, + pRoiInfo->Region.right ); + } +} + +// +// Initialize a block of memory with an empty control list. +// +CRoiIspControl:: +CRoiIspControl( + _In_ KSPROPERTY_CAMERACONTROL_EXTENDED_PROPERTY Property +) +{ + PAGED_CODE(); + + ControlId = Property; + ROICount = 0; + Result = 0; + Reserved = 0; +} + +ULONG +CRoiIspControl:: +GetSize() +{ + PAGED_CODE(); + + return (ROICount>0) ? ::GetSize( this ) : 0; +} + -- cgit v1.3.1