diff options
| author | saredd <[email protected]> | 2018-01-19 17:19:00 -0800 |
|---|---|---|
| committer | Wei Mao <[email protected]> | 2018-01-19 17:19:00 -0800 |
| commit | 6e7c8cb437135e55917c34cfebe1be944bbf6d3f (patch) | |
| tree | f7570fe170194facd45e4f9f887ff56dc683a31c /avstream/avscamera/sys | |
| parent | dd7e6f697ed67e94dc45cd33078b1dbcb643f439 (diff) | |
Updating Camera WDK Samples to RS3 version (#193)
Diffstat (limited to 'avstream/avscamera/sys')
23 files changed, 1095 insertions, 511 deletions
diff --git a/avstream/avscamera/sys/AvsCamera.vcxproj b/avstream/avscamera/sys/AvsCamera.vcxproj index d46c7277..326b1848 100644 --- a/avstream/avscamera/sys/AvsCamera.vcxproj +++ b/avstream/avscamera/sys/AvsCamera.vcxproj @@ -146,16 +146,16 @@ </Midl> </ItemDefinitionGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <NTDDI_VERSION>NTDDI_WINTHRESHOLD</NTDDI_VERSION> + <NTDDI_VERSION>NTDDI_WIN10_RS3</NTDDI_VERSION> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <NTDDI_VERSION>NTDDI_WINTHRESHOLD</NTDDI_VERSION> + <NTDDI_VERSION>NTDDI_WIN10_RS3</NTDDI_VERSION> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <NTDDI_VERSION>NTDDI_WINTHRESHOLD</NTDDI_VERSION> + <NTDDI_VERSION>NTDDI_WIN10_RS3</NTDDI_VERSION> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <NTDDI_VERSION>NTDDI_WINTHRESHOLD</NTDDI_VERSION> + <NTDDI_VERSION>NTDDI_WIN10_RS3</NTDDI_VERSION> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> diff --git a/avstream/avscamera/sys/AvsCameraFilter.cpp b/avstream/avscamera/sys/AvsCameraFilter.cpp index bff6466f..af25b691 100644 --- a/avstream/avscamera/sys/AvsCameraFilter.cpp +++ b/avstream/avscamera/sys/AvsCameraFilter.cpp @@ -229,7 +229,8 @@ DEFINE_KSPROPERTY_TABLE(ExtendedPropertyItems) DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_HISTOGRAM, CExtendedProperty, Histogram ), DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_OIS, CExtendedProperty, OpticalImageStabilization ), DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_ADVANCEDPHOTO, CExtendedProperty, AdvancedPhoto ), - DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_PROFILE, CExtendedProfile, CameraProfile ) + DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_PROFILE, CExtendedProfile, CameraProfile ), + DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOTEMPORALDENOISING, CExtendedProperty, VideoTemporalDenoising) }; // Front-facing cameras often have limited capabilities. One way to express that is to use a restricted automation table such as this one. diff --git a/avstream/avscamera/sys/CameraSimulatorCommon.h b/avstream/avscamera/sys/CameraSimulatorCommon.h new file mode 100644 index 00000000..f1e300b0 --- /dev/null +++ b/avstream/avscamera/sys/CameraSimulatorCommon.h @@ -0,0 +1,391 @@ +/************************************************************************** + +A/V Stream Camera Sample + +Copyright (c) 2017, Microsoft Corporation. + +File: + +CameraSimulatorCommon.h + +Abstract: + +Common header applicable for all camera simulators. + +History: + +created 06/05/2017 + +**************************************************************************/ + +#pragma once +#pragma warning (disable : 4100 4127 4131 4189 4701 4706) + +#define IFFAILED_EXIT(status) \ + if (!NT_SUCCESS( Status = (status) )) \ + { \ + goto done; \ + } + +#define IFNULL_EXIT(exp) \ + if ( (exp) == nullptr ) \ + { \ + Status = STATUS_INSUFFICIENT_RESOURCES; \ + goto done; \ + } + +// +// Number of 100ns in one second +// +#define ONESECOND 10000000 + +#define ABS(x) ((x) < 0 ? (-(x)) : (x)) + +#ifndef mmioFOURCC +#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \ + ( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) | \ + ( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) ) +#endif + +#define FOURCC_YUY2 mmioFOURCC('Y', 'U', 'Y', '2') +#define FOURCC_NV12 mmioFOURCC('N', 'V', '1', '2') + +#define AVSCAM_SIZE_VIDEOHEADER2(pbmi) ((pbmi)->bmiHeader.biSize + FIELD_OFFSET(KS_VIDEOINFOHEADER2,bmiHeader)) + +// RGB24 +#define STATIC_KSDATAFORMAT_SUBTYPE_RGB24\ + 0xe436eb7d, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 +DEFINE_GUIDSTRUCT("e436eb7d-524f-11ce-9f53-0020af0ba770", KSDATAFORMAT_SUBTYPE_RGB24); +#define KSDATAFORMAT_SUBTYPE_RGB24 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_RGB24) + +// RGB32 +#define STATIC_KSDATAFORMAT_SUBTYPE_RGB32\ + 0xe436eb7e, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 +DEFINE_GUIDSTRUCT("e436eb7e-524f-11ce-9f53-0020af0ba770", KSDATAFORMAT_SUBTYPE_RGB32); +#define KSDATAFORMAT_SUBTYPE_RGB32 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_RGB32) + +// NV12 +#define STATIC_KSDATAFORMAT_SUBTYPE_NV12\ + 0x3231564E, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 +DEFINE_GUIDSTRUCT("3231564E-0000-0010-8000-00AA00389B71", KSDATAFORMAT_SUBTYPE_NV12); +#define KSDATAFORMAT_SUBTYPE_NV12 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_NV12) + +// YUY2 +#define STATIC_KSDATAFORMAT_SUBTYPE_YUY2\ + 0x32595559, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 +DEFINE_GUIDSTRUCT("32595559-0000-0010-8000-00AA00389B71", KSDATAFORMAT_SUBTYPE_YUY2); +#define KSDATAFORMAT_SUBTYPE_YUY2 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_YUY2) + +//Arbitrary Maximum faces +#define MAX_FACES 15 + +// +// Define the number of frames needed in the queue for image capture. +// +#define IMAGE_CAPTURE_PIN_MINIMUM_FRAMES 3 +#define IMAGE_CAPTURE_PIN_MAXIMUM_FRAMES 20 +#define IMAGE_CAPTURE_PIN_MAXIMUM_HISTORY_FRAMES 10 + +#define AVSHWS_POOLTAG 'hSVA' + +// +// Focal length definitions +// +// These are the definitions found in MSDN for the legacy zoom controls. +// +//#define FOCALLENGTH_OCULAR 50 +//#define FOCALLENGTH_OPTICAL_MIN 10 +//#define FOCALLENGTH_OPTICAL_MAX 600 +// +// Note: Despite what MSDN says, they are NOT limits as far as the +// pipeline is conerned. You should supply values here that are +// appropriate to your hardware - whatever that may be. +// +// Also note that since both optical and ocular focal length are +// nomally measured in millimeters, and since the optical length is +// always the numerator and ocular is used as the denominator, the +// units (millimeters) cancel out. This means you can stick any set +// of values you like here that can be used to represent the min and +// maximum zoom value of your hardware as a simple rational number. +// +// Again, the rational number is: (Objective length / Ocular length) +// +// We use the following definitions in this simulation in order to have the +// values produced and used in the legacy control be the same as the ones +// in the new extended zoom control. +// +#define FOCALLENGTH_OCULAR (1<<16) // Denominator of 2^16 makes this the same as Q16 format in extended. +#define FOCALLENGTH_OPTICAL_MIN (FOCALLENGTH_OCULAR/16) // Allow a wide-field view of 1/16th. +#define FOCALLENGTH_OPTICAL_MAX (FOCALLENGTH_OCULAR*32) // Allow a zoom-in view of 32x. + +// +// Values for Power Line Frequency +// +#define POWERLINEFREQ_DISABLED 0 +#define POWERLINEFREQ_50HZ 1 +#define POWERLINEFREQ_60HZ 2 +#define POWERLINEFREQ_AUTO 3 +#define POWERLINEFREQ_DEFAULT POWERLINEFREQ_DISABLED + +// +// Q-format definitions. +// +#define BASE_Q(n) (((ULONGLONG)1)<<n) +#define TO_Q31(_x_) (LONGLONG)( (_x_) * BASE_Q(31) ) +#define TO_Q16(_x_) (LONGLONG)( (_x_) * BASE_Q(16) ) +#define FROM_Q16(_x_, _denominator_) ((LONG)( (LONGLONG)(_x_) / ( TO_Q16(1) / (LONGLONG)(_denominator_)) )) + +#define MULT_Q16(_x_, _y_) (LONGLONG)((((LONGLONG)(_x_) * (LONGLONG)(_y_)) + (BASE_Q(15)))>>16) +#define DIV_Q16(_x_, _y_) (LONGLONG)((((LONGLONG)(_x_)<<16)+(_y_/2))/(LONGLONG)(_y_)) + +#define MAKEWORD(a, b) ((WORD)(((BYTE)(((DWORD_PTR)(a)) & 0xff)) | ((WORD)((BYTE)(((DWORD_PTR)(b)) & 0xff))) << 8)) +#define MAKEDWORD(l, h) ( ( DWORD ) ( ( ( WORD ) ( l ) ) | ( ( DWORD ) ( ( WORD ) ( h ) ) ) << 16 ) ) +#define MAKELONG(a, b) ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16)) + +// +// Copy of histogram channel bitmask definitions from mfapi.h (not available in wdk). +// +#define MF_HISTOGRAM_CHANNEL_Y 0x00000001 +#define MF_HISTOGRAM_CHANNEL_R 0x00000002 +#define MF_HISTOGRAM_CHANNEL_G 0x00000004 +#define MF_HISTOGRAM_CHANNEL_B 0x00000008 +#define MF_HISTOGRAM_CHANNEL_Cb 0x00000010 +#define MF_HISTOGRAM_CHANNEL_Cr 0x00000020 + +/************************************************* + + Enums / Typedefs + +*************************************************/ + +typedef enum _PIN_STATE +{ + + PinStopped = 0, + PinPaused, + PinRunning + +} PIN_STATE, *PPIN_STATE; + +typedef enum _PIN_MODE +{ + + PinNormalMode = 0, + PinBurstMode + +} PIN_MODE, *PPIN_MODE; + +/************************************************* + + Struct / Class Definitions + +*************************************************/ + +struct ISP_FRAME_SETTINGS +{ + ULONGLONG ISOMode; + ULONG ISOValue; // for Manual ISO settings. + KSCAMERA_EXTENDEDPROP_EVCOMPENSATION EVCompensation; + ULONGLONG WhiteBalanceMode; + KSCAMERA_EXTENDEDPROP_VIDEOPROCSETTING WhiteBalanceSetting; + ULONGLONG ExposureMode; + KSCAMERA_EXTENDEDPROP_VIDEOPROCSETTING ExposureSetting; + ULONGLONG FocusMode; + KSCAMERA_EXTENDEDPROP_VIDEOPROCSETTING FocusSetting; + ULONGLONG FocusPriority; + ULONGLONG FlashMode; + ULONG FlashValue; // Adjustable power setting (0-100) + BOOLEAN bPhotoConfirmation; +} ; + +struct SOC_CAP_WITH_STEPPING +{ + KSCAMERA_PERFRAMESETTING_CAP_ITEM_HEADER Hdr; + KSPROPERTY_STEPPING_LONG Stepping; +} ; + +struct SOC_CAP_WITH_STEPPING_LONGLONG +{ + KSCAMERA_PERFRAMESETTING_CAP_ITEM_HEADER Hdr; + KSPROPERTY_STEPPING_LONGLONG Stepping; +} ; + +// +// ICapturePin: +// +// This is a capture pin interface. The device level calls back the +// CompleteMapping method passing the number of completed mappings for +// the capture pin. +// +class ICapturePin +{ + +public: + + virtual + NTSTATUS + CompleteMapping( + _In_opt_ PKSSTREAM_POINTER Clone=nullptr + ) = 0; + +}; + +class LockDevice +{ +public: + + LockDevice(PKSDEVICE device) : m_device(device) + { + NT_ASSERT(m_device); + KsAcquireDevice(m_device); + } + + ~LockDevice() + { + KsReleaseDevice(m_device); + } +private: + PKSDEVICE m_device; +}; + +class LockFilter +{ +public: + + LockFilter(PKSFILTER filter) : m_filter(filter) + { + NT_ASSERT(m_filter); + KsFilterAcquireControl(m_filter); + } + + ~LockFilter() + { + KsFilterReleaseControl(m_filter); + } +private: + PKSFILTER m_filter; +}; + +// The following class definitions and ctors are used solely +// to simplify initialization of the parent metadata structures. +// They are not here for any other purpose. + +template <class T, class U> +class CMetaRational : public U +{ +public: + CMetaRational( T Num=1, T Denom=1 ) + { + Set=TRUE; + Numerator = Num; + Denominator = Denom; + } +}; + +typedef CMetaRational<UINT32, METADATA_RATIONAL> CMetadataRational; +typedef CMetaRational<INT32, METADATA_SRATIONAL> CMetadataSRational; + +template <class T, class U> +class CMetaPrimative : public U +{ +public: + CMetaPrimative( T n ) + { + Set = TRUE; + Value = n; + } +}; + +typedef CMetaPrimative<UINT16, METADATA_UINT16> CMetadataShort; +typedef CMetaPrimative<UINT32, METADATA_UINT32> CMetadataLong; +typedef CMetaPrimative<INT64, METADATA_INT64> CMetadataLongLong; +typedef CMetaPrimative<UINT64, METADATA_UINT64> CMetadataULongLong; + +class CMetadataShortString : public METADATA_SHORTSTRING +{ +public: + CMetadataShortString( + _In_z_ const CHAR *str + ) + { + Length = (UINT32) min(strlen(str), sizeof(String)); + strncpy_s( String, str, Length ); + } +}; + +class CMetadataEVCompensation : public METADATA_EVCOMP +{ +public: + CMetadataEVCompensation( + _In_ UINT64 flags, + _In_ UINT32 value + ) + { + Set = TRUE; + Flags = flags; + Value = value; + } +}; + +typedef struct +{ + LONG Value; + ULONG Flags; + ULONG Capabilities; +} VIDCAP_PROPERTY, *PVIDCAP_PROPERTY; + +typedef struct +{ + LONG lOcularFocalLength; + LONG lObjectiveFocalLengthMin; + LONG lObjectiveFocalLengthMax; +} FOCAL_LENGTH_PROPERTY, *PFOCAL_LENGTH_PROPERTY; + +const ULONG KSCAMERA_EXTENDEDPROP_VERSION = 1; + +// +// Note: I cannot simplify this down to just the FrameIndex. +// Past frames and non-VPS photos can have a photo confirmation set +// and those images will not have an index associated with them. +// +class PHOTOCONFIRMATION_INFO +{ +public: + PHOTOCONFIRMATION_INFO( + _In_ ULONG FrameIndex, + _In_ LONGLONG Time + ) + : m_Index( FrameIndex ) + , m_Time(Time) + , m_bRequired(TRUE) + {} + + PHOTOCONFIRMATION_INFO() + : m_Index(0) + , m_Time(0) + , m_bRequired( FALSE ) + {} + + BOOL + isRequired() const + { + return m_bRequired; + } + + ULONG + getIndex() const + { + return m_Index; + } + + LONGLONG + getTime() const + { + return m_Time; + } + +private: + BOOL m_bRequired; + ULONG m_Index; + LONGLONG m_Time; +}; diff --git a/avstream/avscamera/sys/Capture.cpp b/avstream/avscamera/sys/Capture.cpp index cd62bae1..77bd618c 100644 --- a/avstream/avscamera/sys/Capture.cpp +++ b/avstream/avscamera/sys/Capture.cpp @@ -51,7 +51,6 @@ CCapturePin ( , m_PendIo(FALSE) , m_AcquiredResources(FALSE) , m_VideoInfoHeader(nullptr) - , m_pBitmapInfoHeader(nullptr) , m_PreviousStreamPointer(nullptr) , m_PresentationTime(0) , m_FrameNumber(0) @@ -100,7 +99,6 @@ CCapturePin:: { PAGED_CODE(); - SAFE_FREE( m_pBitmapInfoHeader ); SAFE_FREE( m_VideoInfoHeader ); } @@ -254,23 +252,11 @@ Return Value: const GUID ImageInfoSpecifier ={ STATICGUIDOF( KSDATAFORMAT_SPECIFIER_IMAGE ) }; const GUID VideoInfoSpecifier ={ STATICGUIDOF( KSDATAFORMAT_SPECIFIER_VIDEOINFO ) }; + const GUID VideoInfo2Specifier = { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_VIDEOINFO2) }; // Free any previous copy of these header. - SAFE_FREE(m_pBitmapInfoHeader); SAFE_FREE(m_VideoInfoHeader); - m_pBitmapInfoHeader = reinterpret_cast <PKS_BITMAPINFOHEADER> ( - ExAllocatePoolWithTag ( - NonPagedPoolNx, - sizeof(KS_BITMAPINFOHEADER), - AVSHWS_POOLTAG - ) - ); - if( !m_pBitmapInfoHeader ) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - if( IsEqualGUID( m_Pin->ConnectionFormat->Specifier, ImageInfoSpecifier ) && m_Pin->ConnectionFormat->FormatSize >= sizeof (KS_DATAFORMAT_IMAGEINFO) ) { @@ -279,40 +265,35 @@ Return Value: &((reinterpret_cast <PKS_DATAFORMAT_IMAGEINFO> (m_Pin->ConnectionFormat))->ImageInfoHeader); - // - // Copy the connection format video info header into the newly - // allocated "captured" video info header. - // - *m_pBitmapInfoHeader = *ConnectionHeader; - m_VideoInfoHeader = reinterpret_cast <PKS_VIDEOINFOHEADER> ( ExAllocatePoolWithTag ( NonPagedPoolNx, - sizeof(KS_VIDEOINFOHEADER), + max(sizeof(KS_VIDEOINFOHEADER), ConnectionHeader->biSize + KS_SIZE_PREHEADER), AVSHWS_POOLTAG ) ); if( !m_VideoInfoHeader ) { - SAFE_FREE( m_pBitmapInfoHeader ); return STATUS_INSUFFICIENT_RESOURCES; } // - // Copy the connection format video info header into the newly + // Copy the connection format bitmap info header into the newly // allocated "captured" video info header. // m_VideoInfoHeader->bmiHeader = *ConnectionHeader; + PKS_BITMAPINFOHEADER CurrentBitmapInfoHeader = &(m_VideoInfoHeader->bmiHeader); + // If we don't have a known bit-depth (compressed formats), assume the worse-case. - if( m_pBitmapInfoHeader->biBitCount==0 ) + if( CurrentBitmapInfoHeader->biBitCount==0 ) { - m_pBitmapInfoHeader->biBitCount=32; + CurrentBitmapInfoHeader->biBitCount=32; } // Estimate the image size. The derived pin can chose to override this value. - m_VideoInfoHeader->bmiHeader.biSizeImage = - (m_pBitmapInfoHeader->biWidth*m_pBitmapInfoHeader->biHeight*m_pBitmapInfoHeader->biBitCount)/8; + CurrentBitmapInfoHeader->biSizeImage = + (CurrentBitmapInfoHeader->biWidth*CurrentBitmapInfoHeader->biHeight*CurrentBitmapInfoHeader->biBitCount)/8; // Estimate a frame rate. The derived pin can chose to override this value. m_VideoInfoHeader->AvgTimePerFrame = ONESECOND/30; @@ -329,13 +310,12 @@ Return Value: m_VideoInfoHeader = reinterpret_cast <PKS_VIDEOINFOHEADER> ( ExAllocatePoolWithTag ( NonPagedPoolNx, - KS_SIZE_VIDEOHEADER (ConnectionHeader), + max(sizeof(KS_VIDEOINFOHEADER), KS_SIZE_VIDEOHEADER (ConnectionHeader)), AVSHWS_POOLTAG ) ); if( !m_VideoInfoHeader ) { - SAFE_FREE( m_pBitmapInfoHeader ); return STATUS_INSUFFICIENT_RESOURCES; } @@ -348,12 +328,42 @@ Return Value: ConnectionHeader, KS_SIZE_VIDEOHEADER (ConnectionHeader) ); + } + else + if( IsEqualGUID( m_Pin->ConnectionFormat->Specifier, VideoInfo2Specifier ) && + m_Pin->ConnectionFormat->FormatSize >= sizeof (KS_DATAFORMAT_VIDEOINFOHEADER2) ) + { + PKS_VIDEOINFOHEADER2 ConnectionHeader = + &((reinterpret_cast <PKS_DATAFORMAT_VIDEOINFOHEADER2> + (m_Pin->ConnectionFormat))-> + VideoInfoHeader2); + + m_VideoInfoHeader = reinterpret_cast <PKS_VIDEOINFOHEADER> ( + ExAllocatePoolWithTag( + NonPagedPoolNx, + max(sizeof(KS_VIDEOINFOHEADER), ConnectionHeader->bmiHeader.biSize + KS_SIZE_PREHEADER), + AVSHWS_POOLTAG + ) + ); + if (!m_VideoInfoHeader) + { + return STATUS_INSUFFICIENT_RESOURCES; + } // // Copy the connection format video info header into the newly // allocated "captured" video info header. // - *m_pBitmapInfoHeader = m_VideoInfoHeader->bmiHeader; + m_VideoInfoHeader->rcSource = ConnectionHeader->rcSource; + m_VideoInfoHeader->rcTarget = ConnectionHeader->rcTarget; + m_VideoInfoHeader->dwBitRate = ConnectionHeader->dwBitRate; + m_VideoInfoHeader->dwBitErrorRate = ConnectionHeader->dwBitErrorRate; + m_VideoInfoHeader->AvgTimePerFrame = ConnectionHeader->AvgTimePerFrame; + RtlCopyMemory ( + &m_VideoInfoHeader->bmiHeader, + &ConnectionHeader->bmiHeader, + ConnectionHeader->bmiHeader.biSize + ); } else { @@ -1165,6 +1175,7 @@ Return Value: NTSTATUS Status = STATUS_NO_MATCH; const GUID ImageInfoSpecifier = { STATICGUIDOF( KSDATAFORMAT_SPECIFIER_IMAGE ) }; const GUID VideoInfoSpecifier = { STATICGUIDOF( KSDATAFORMAT_SPECIFIER_VIDEOINFO ) }; + const GUID VideoInfo2Specifier = { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_VIDEOINFO2) }; // // Find the pin, if it exists yet. OldFormat will be an indication of @@ -1176,11 +1187,14 @@ Return Value: CCapturePin *CapPin = reinterpret_cast <CCapturePin *> (Pin->Context); // For debugging... + UNICODE_STRING NewFormatSpecifier; UNICODE_STRING NewFormat; UNICODE_STRING RefFormat; + (void)RtlStringFromGUID( Pin->ConnectionFormat->Specifier, &NewFormatSpecifier ); (void)RtlStringFromGUID( Pin->ConnectionFormat->SubFormat, &NewFormat ); (void)RtlStringFromGUID( DataRange->SubFormat, &RefFormat ); + DBG_TRACE("Format specifier for Pin %d is %wZ)", Pin->Id, &NewFormatSpecifier); if( IsEqualGUID( Pin->ConnectionFormat->Specifier, ImageInfoSpecifier ) && Pin->ConnectionFormat->FormatSize >= sizeof (KS_DATAFORMAT_IMAGEINFO) ) { @@ -1276,68 +1290,105 @@ Return Value: } } } - - else if( IsEqualGUID( Pin->ConnectionFormat->Specifier, - VideoInfoSpecifier ) && - Pin->ConnectionFormat->FormatSize >= - sizeof (KS_DATAFORMAT_VIDEOINFOHEADER) ) + else + if( ( IsEqualGUID( Pin->ConnectionFormat->Specifier, VideoInfoSpecifier ) && + Pin->ConnectionFormat->FormatSize >= sizeof (KS_DATAFORMAT_VIDEOINFOHEADER) ) || + ( IsEqualGUID( Pin->ConnectionFormat->Specifier, VideoInfo2Specifier ) && + Pin->ConnectionFormat->FormatSize >= sizeof (KS_DATAFORMAT_VIDEOINFOHEADER2) ) ) { + ULONG VideoHeaderSize = 0; + ULONG DataFormatSize = 0; + ULONG ConnectionFormatDataFormatSize = 0; + KS_BITMAPINFOHEADER ConnectionFormatBitMapInfoHeader = {}; + KS_BITMAPINFOHEADER DataRangeBitMapInfoHeader = {}; - PKS_DATAFORMAT_VIDEOINFOHEADER ConnectionFormat = - reinterpret_cast <PKS_DATAFORMAT_VIDEOINFOHEADER> - (Pin->ConnectionFormat); + if (IsEqualGUID(Pin->ConnectionFormat->Specifier, VideoInfo2Specifier)) + { + PKS_DATAFORMAT_VIDEOINFOHEADER2 ConnectionFormat = + reinterpret_cast <PKS_DATAFORMAT_VIDEOINFOHEADER2> + (Pin->ConnectionFormat); - // - // DataRange comes out of OUR data range list. I know the range - // is valid as such. - // - const KS_DATARANGE_VIDEO *VIRange = - reinterpret_cast <const KS_DATARANGE_VIDEO *> - (DataRange); + // + // DataRange comes out of OUR data range list. I know the range + // is valid as such. + // + const KS_DATARANGE_VIDEO2 *VIRange = + reinterpret_cast <const KS_DATARANGE_VIDEO2 *> + (DataRange); - // - // Check that bmiHeader.biSize is valid since we use it later. - // - ULONG VideoHeaderSize = KS_SIZE_VIDEOHEADER( - &ConnectionFormat->VideoInfoHeader - ); + VideoHeaderSize = AVSCAM_SIZE_VIDEOHEADER2( + &ConnectionFormat->VideoInfoHeader2 + ); + + DataFormatSize = FIELD_OFFSET( + KS_DATAFORMAT_VIDEOINFOHEADER2, VideoInfoHeader2 + ) + VideoHeaderSize; + + ConnectionFormatDataFormatSize = ConnectionFormat->DataFormat.FormatSize; + ConnectionFormatBitMapInfoHeader = ConnectionFormat->VideoInfoHeader2.bmiHeader; + DataRangeBitMapInfoHeader = VIRange->VideoInfoHeader.bmiHeader; + } + else + { + PKS_DATAFORMAT_VIDEOINFOHEADER ConnectionFormat = + reinterpret_cast <PKS_DATAFORMAT_VIDEOINFOHEADER> + (Pin->ConnectionFormat); + + // + // DataRange comes out of OUR data range list. I know the range + // is valid as such. + // + const KS_DATARANGE_VIDEO *VIRange = + reinterpret_cast <const KS_DATARANGE_VIDEO *> + (DataRange); + + VideoHeaderSize = KS_SIZE_VIDEOHEADER( + &ConnectionFormat->VideoInfoHeader + ); + + DataFormatSize = FIELD_OFFSET( + KS_DATAFORMAT_VIDEOINFOHEADER, VideoInfoHeader + ) + VideoHeaderSize; - ULONG DataFormatSize = FIELD_OFFSET( - KS_DATAFORMAT_VIDEOINFOHEADER, VideoInfoHeader - ) + VideoHeaderSize; + ConnectionFormatDataFormatSize = ConnectionFormat->DataFormat.FormatSize; + ConnectionFormatBitMapInfoHeader = ConnectionFormat->VideoInfoHeader.bmiHeader; + DataRangeBitMapInfoHeader = VIRange->VideoInfoHeader.bmiHeader; + } - if( VideoHeaderSize < ConnectionFormat->VideoInfoHeader.bmiHeader.biSize || + // + // Check that ConnectionFormatBitMapInfoHeader.biSize is valid since we use it later. + // + if (VideoHeaderSize < ConnectionFormatBitMapInfoHeader.biSize || DataFormatSize < VideoHeaderSize || - DataFormatSize > ConnectionFormat->DataFormat.FormatSize ) + DataFormatSize > ConnectionFormatDataFormatSize) { Status = STATUS_INVALID_PARAMETER; } - // // Check that the format is a match for the selected range. // else if( - (ConnectionFormat->VideoInfoHeader.bmiHeader.biWidth != - VIRange->VideoInfoHeader.bmiHeader.biWidth) || - (ConnectionFormat->VideoInfoHeader.bmiHeader.biHeight != - VIRange->VideoInfoHeader.bmiHeader.biHeight) || + (ConnectionFormatBitMapInfoHeader.biWidth != + DataRangeBitMapInfoHeader.biWidth) || + (ConnectionFormatBitMapInfoHeader.biHeight != + DataRangeBitMapInfoHeader.biHeight) || !IsEqualGUID( Pin->ConnectionFormat->SubFormat, DataRange->SubFormat ) ) { DBG_TRACE("FAILED: Height=(%d,%d), Width=(%d,%d), SubFormat=(%wZ,%wZ)", - ConnectionFormat->VideoInfoHeader.bmiHeader.biWidth, - VIRange->VideoInfoHeader.bmiHeader.biWidth, - ConnectionFormat->VideoInfoHeader.bmiHeader.biHeight, - VIRange->VideoInfoHeader.bmiHeader.biHeight, + ConnectionFormatBitMapInfoHeader.biWidth, + DataRangeBitMapInfoHeader.biWidth, + ConnectionFormatBitMapInfoHeader.biHeight, + DataRangeBitMapInfoHeader.biHeight, &NewFormat, &RefFormat ); Status = STATUS_NO_MATCH; } else { DBG_TRACE("MATCH: Height=(%d,%d), Width=(%d,%d), SubFormat=(%wZ,%wZ)", - ConnectionFormat->VideoInfoHeader.bmiHeader.biWidth, - VIRange->VideoInfoHeader.bmiHeader.biWidth, - ConnectionFormat->VideoInfoHeader.bmiHeader.biHeight, - VIRange->VideoInfoHeader.bmiHeader.biHeight, + ConnectionFormatBitMapInfoHeader.biWidth, + DataRangeBitMapInfoHeader.biWidth, + ConnectionFormatBitMapInfoHeader.biHeight, + DataRangeBitMapInfoHeader.biHeight, &NewFormat, &RefFormat ); // @@ -1356,9 +1407,8 @@ Return Value: ULONG ImageSize; if( !MultiplyCheckOverflow( - (ULONG) ConnectionFormat->VideoInfoHeader.bmiHeader.biWidth, - (ULONG) abs( ConnectionFormat-> - VideoInfoHeader.bmiHeader.biHeight ), + (ULONG) ConnectionFormatBitMapInfoHeader.biWidth, + (ULONG) abs( ConnectionFormatBitMapInfoHeader.biHeight ), &ImageSize ) ) { @@ -1371,8 +1421,7 @@ Return Value: // else if( !MultiplyCheckOverflow( ImageSize, - (ULONG) (ConnectionFormat-> - VideoInfoHeader.bmiHeader.biBitCount / 8), + (ULONG) (ConnectionFormatBitMapInfoHeader.biBitCount / 8), &ImageSize ) ) { @@ -1383,7 +1432,7 @@ Return Value: // Valid for the formats we use. Otherwise, this would be // checked later. // - else if( ConnectionFormat->VideoInfoHeader.bmiHeader.biSizeImage < + else if( ConnectionFormatBitMapInfoHeader.biSizeImage < ImageSize ) { Status = STATUS_INVALID_PARAMETER; @@ -1431,6 +1480,7 @@ Return Value: } } + RtlFreeUnicodeString(&NewFormatSpecifier); RtlFreeUnicodeString(&NewFormat); RtlFreeUnicodeString(&RefFormat); @@ -1509,6 +1559,7 @@ Return Value: const GUID ImageInfoSpecifier = { STATICGUIDOF( KSDATAFORMAT_SPECIFIER_IMAGE ) }; const GUID VideoInfoSpecifier = { STATICGUIDOF( KSDATAFORMAT_SPECIFIER_VIDEOINFO ) }; + const GUID VideoInfo2Specifier = { STATICGUIDOF(KSDATAFORMAT_SPECIFIER_VIDEOINFO2) }; ULONG DataFormatSize; NT_ASSERT( Filter ); @@ -1733,6 +1784,138 @@ Return Value: return STATUS_SUCCESS; + } + else if( IsEqualGUID( CallerDataRange->Specifier, VideoInfo2Specifier ) && + CallerDataRange->FormatSize >= sizeof (KS_DATARANGE_VIDEO2) ) + { + + PKS_DATARANGE_VIDEO2 callerDataRange = + reinterpret_cast <PKS_DATARANGE_VIDEO2> (CallerDataRange); + + PKS_DATARANGE_VIDEO2 descriptorDataRange = + reinterpret_cast <PKS_DATARANGE_VIDEO2> (DescriptorDataRange); + + PKS_DATAFORMAT_VIDEOINFOHEADER2 FormatVideoInfoHeader; + + // + // Check that the other fields match + // + if( (callerDataRange->bFixedSizeSamples != + descriptorDataRange->bFixedSizeSamples) || + (callerDataRange->bTemporalCompression != + descriptorDataRange->bTemporalCompression) || + (callerDataRange->StreamDescriptionFlags != + descriptorDataRange->StreamDescriptionFlags) || + (callerDataRange->MemoryAllocationFlags != + descriptorDataRange->MemoryAllocationFlags) || + (RtlCompareMemory( &callerDataRange->ConfigCaps, + &descriptorDataRange->ConfigCaps, + sizeof (KS_VIDEO_STREAM_CONFIG_CAPS) ) != + sizeof (KS_VIDEO_STREAM_CONFIG_CAPS)) ) + { + return STATUS_NO_MATCH; + } + + // + // AVSCAM_SIZE_VIDEOHEADER2() below is relying on bmiHeader.biSize from + // the caller's data range. This **MUST** be validated; the + // extended bmiHeader size (biSize) must not extend past the end + // of the range buffer. Possible arithmetic overflow is also + // checked for. + // + ULONG VideoHeaderSize = AVSCAM_SIZE_VIDEOHEADER2( + &callerDataRange->VideoInfoHeader + ); + + ULONG DataRangeSize = + FIELD_OFFSET( KS_DATARANGE_VIDEO2, VideoInfoHeader ) + + VideoHeaderSize; + + // + // Check that biSize does not extend past the buffer. The + // first two checks are for arithmetic overflow on the + // operations to compute the alleged size. (On unsigned + // math, a+b < a iff an arithmetic overflow occurred). + // + if( VideoHeaderSize < callerDataRange->VideoInfoHeader.bmiHeader.biSize || + DataRangeSize < VideoHeaderSize || + DataRangeSize > callerDataRange->DataRange.FormatSize ) + { + return STATUS_INVALID_PARAMETER; + } + + DataFormatSize = + sizeof (KSDATAFORMAT) + + AVSCAM_SIZE_VIDEOHEADER2( &callerDataRange->VideoInfoHeader ); + + + // + // If the passed buffer size is 0, it indicates that this is a size + // only query. Return the size of the intersecting data format and + // pass back STATUS_BUFFER_OVERFLOW. + // + if( BufferSize == 0 ) + { + *DataSize = DataFormatSize; + return STATUS_BUFFER_OVERFLOW; + } + + // + // Verify that the provided structure is large enough to + // accept the result. + // + if( BufferSize < DataFormatSize ) + { + return STATUS_BUFFER_TOO_SMALL; + } + + // + // Copy over the KSDATAFORMAT, followed by the actual VideoInfoHeader + // + *DataSize = DataFormatSize; + + FormatVideoInfoHeader = PKS_DATAFORMAT_VIDEOINFOHEADER2( Data ); + + // + // Copy over the KSDATAFORMAT. This is precisely the same as the + // KSDATARANGE (it's just the GUIDs, etc... not the format information + // following any data format. + // + RtlCopyMemory( + &FormatVideoInfoHeader->DataFormat, + DescriptorDataRange, + sizeof (KSDATAFORMAT) ); + + FormatVideoInfoHeader->DataFormat.FormatSize = DataFormatSize; + + // + // Copy over the callers requested VIDEOINFOHEADER + // + + RtlCopyMemory( + &FormatVideoInfoHeader->VideoInfoHeader2, + &callerDataRange->VideoInfoHeader, + AVSCAM_SIZE_VIDEOHEADER2( &callerDataRange->VideoInfoHeader ) + ); + + // + // Calculate biSizeImage for this request, and put the result in both + // the biSizeImage field of the bmiHeader AND in the SampleSize field + // of the DataFormat. + // + // Note that for compressed sizes, this calculation will probably not + // be just width * height * bitdepth + // + FormatVideoInfoHeader->VideoInfoHeader2.bmiHeader.biSizeImage = + FormatVideoInfoHeader->DataFormat.SampleSize = + KS_DIBSIZE( FormatVideoInfoHeader->VideoInfoHeader2.bmiHeader ); + + // + // REVIEW - Perform other validation such as cropping and scaling checks + // + + return STATUS_SUCCESS; + } // End of VIDEOINFOHEADER specifier return STATUS_NO_MATCH; diff --git a/avstream/avscamera/sys/Capture.h b/avstream/avscamera/sys/Capture.h index 1e0c62b9..0a065d24 100644 --- a/avstream/avscamera/sys/Capture.h +++ b/avstream/avscamera/sys/Capture.h @@ -92,7 +92,6 @@ protected: BOOLEAN m_PendIo; // An indication of whether or not we pended I/O for some reason. BOOLEAN m_AcquiredResources; // An indication of whether or not this pin has acquired the necessary hardware resources to operate. PKS_VIDEOINFOHEADER m_VideoInfoHeader; - PKS_BITMAPINFOHEADER m_pBitmapInfoHeader; // Optional info for image formats. // // If we are unable to insert all of the mappings in a stream pointer into diff --git a/avstream/avscamera/sys/Common.h b/avstream/avscamera/sys/Common.h index d54ba2f3..5c83f2fc 100644 --- a/avstream/avscamera/sys/Common.h +++ b/avstream/avscamera/sys/Common.h @@ -40,6 +40,7 @@ #include "MetadataInternal.h" #include "CustomProperties.h" #include "Dbg.h" +#include "CameraSimulatorCommon.h" #ifndef _NEW_DELETE_OPERATORS_ #define _NEW_DELETE_OPERATORS_ @@ -181,71 +182,8 @@ void __cdecl operator delete[] Misc Definitions *************************************************/ -#pragma warning (disable : 4100 4127 4131 4189 4701 4706) #define STR_MODULENAME "AvsCamera: " -#define IFFAILED_EXIT(status) \ - if (!NT_SUCCESS( Status = (status) )) \ - { \ - goto done; \ - } - -#define IFNULL_EXIT(exp) \ - if ( (exp) == nullptr ) \ - { \ - Status = STATUS_INSUFFICIENT_RESOURCES; \ - goto done; \ - } - -// -// Number of 100ns in one second -// -#define ONESECOND 10000000 - -#define ABS(x) ((x) < 0 ? (-(x)) : (x)) - -#ifndef mmioFOURCC -#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \ - ( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) | \ - ( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) ) -#endif - -#define FOURCC_YUY2 mmioFOURCC('Y', 'U', 'Y', '2') -#define FOURCC_NV12 mmioFOURCC('N', 'V', '1', '2') - -// RGB24 -#define STATIC_KSDATAFORMAT_SUBTYPE_RGB24\ - 0xe436eb7d, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 -DEFINE_GUIDSTRUCT("e436eb7d-524f-11ce-9f53-0020af0ba770", KSDATAFORMAT_SUBTYPE_RGB24); -#define KSDATAFORMAT_SUBTYPE_RGB24 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_RGB24) - -// RGB32 -#define STATIC_KSDATAFORMAT_SUBTYPE_RGB32\ - 0xe436eb7e, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 -DEFINE_GUIDSTRUCT("e436eb7e-524f-11ce-9f53-0020af0ba770", KSDATAFORMAT_SUBTYPE_RGB32); -#define KSDATAFORMAT_SUBTYPE_RGB32 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_RGB32) - -// NV12 -#define STATIC_KSDATAFORMAT_SUBTYPE_NV12\ - 0x3231564E, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 -DEFINE_GUIDSTRUCT("3231564E-0000-0010-8000-00AA00389B71", KSDATAFORMAT_SUBTYPE_NV12); -#define KSDATAFORMAT_SUBTYPE_NV12 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_NV12) - -// YUY2 -#define STATIC_KSDATAFORMAT_SUBTYPE_YUY2\ - 0x32595559, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 -DEFINE_GUIDSTRUCT("32595559-0000-0010-8000-00AA00389B71", KSDATAFORMAT_SUBTYPE_YUY2); -#define KSDATAFORMAT_SUBTYPE_YUY2 DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_YUY2) - -#define CAPTURE_FILTER_COUNT 2 - -//filter index -#define CAPTURE_FILTER_RFC 0 -#define CAPTURE_FILTER_FFC 1 - -//Arbitrary Maximum faces -#define MAX_FACES 15 - // // CAPTURE_PIN_DATA_RANGE_COUNT:(formats) // @@ -256,90 +194,12 @@ DEFINE_GUIDSTRUCT("32595559-0000-0010-8000-00AA00389B71", KSDATAFORMAT_SUBTYPE_Y #define VIDEO_PREVIEW_PIN_DATA_RANGE_COUNT 15 // -// Define the number of frames needed in the queue for each pin. -// -#define IMAGE_CAPTURE_PIN_MINIMUM_FRAMES 3 -#define VIDEO_CAPTURE_PIN_MINIMUM_FRAMES 4 -#define PREVIEW_PIN_MINIMUM_FRAMES 6 -#define IMAGE_CAPTURE_PIN_MAXIMUM_FRAMES 20 -#define IMAGE_CAPTURE_PIN_MAXIMUM_HISTORY_FRAMES 10 - -// // CAPTURE_FILTER_CATEGORIES_COUNT: // // The number of categories for the capture filter. // #define CAPTURE_FILTER_CATEGORIES_COUNT 3 -#define AVSHWS_POOLTAG 'hSVA' - -// -// Focal length definitions -// - -// These are the definitions found in MSDN for the legacy zoom controls. -// -//#define FOCALLENGTH_OCULAR 50 -//#define FOCALLENGTH_OPTICAL_MIN 10 -//#define FOCALLENGTH_OPTICAL_MAX 600 - -//#define FOCALLENGTH_OCULAR 50 -//#define FOCALLENGTH_OPTICAL_MIN 10 -//#define FOCALLENGTH_OPTICAL_MAX 600 - -// Note: Despite what MSDN says, they are NOT limits as far as the -// pipeline is conerned. You should supply values here that are -// appropriate to your hardware - whatever that may be. -// -// Also note that since both optical and ocular focal length are -// nomally measured in millimeters, and since the optical length is -// always the numerator and ocular is used as the denominator, the -// units (millimeters) cancel out. This means you can stick any set -// of values you like here that can be used to represent the min and -// maximum zoom value of your hardware as a simple rational number. -// -// Again, the rational number is: (Objective length / Ocular length) -// -// We use the following definitions in this simulation in order to have the -// values produced and used in the legacy control be the same as the ones -// in the new extended zoom control. -// -#define FOCALLENGTH_OCULAR (1<<16) // Denominator of 2^16 makes this the same as Q16 format in extended. -#define FOCALLENGTH_OPTICAL_MIN (FOCALLENGTH_OCULAR/16) // Allow a wide-field view of 1/16th. -#define FOCALLENGTH_OPTICAL_MAX (FOCALLENGTH_OCULAR*32) // Allow a zoom-in view of 32x. - -// Values for Power Line Frequency -#define POWERLINEFREQ_DISABLED 0 -#define POWERLINEFREQ_50HZ 1 -#define POWERLINEFREQ_60HZ 2 -#define POWERLINEFREQ_AUTO 3 -#define POWERLINEFREQ_DEFAULT POWERLINEFREQ_DISABLED - - -// -// Q-format definitions. -// -#define BASE_Q(n) (((ULONGLONG)1)<<n) -#define TO_Q31(_x_) (LONGLONG)( (_x_) * BASE_Q(31) ) -#define TO_Q16(_x_) (LONGLONG)( (_x_) * BASE_Q(16) ) -#define FROM_Q16(_x_, _denominator_) ((LONG)( (LONGLONG)(_x_) / ( TO_Q16(1) / (LONGLONG)(_denominator_)) )) - -#define MULT_Q16(_x_, _y_) (LONGLONG)((((LONGLONG)(_x_) * (LONGLONG)(_y_)) + (BASE_Q(15)))>>16) -#define DIV_Q16(_x_, _y_) (LONGLONG)((((LONGLONG)(_x_)<<16)+(_y_/2))/(LONGLONG)(_y_)) - -#define MAKEWORD(a, b) ((WORD)(((BYTE)(((DWORD_PTR)(a)) & 0xff)) | ((WORD)((BYTE)(((DWORD_PTR)(b)) & 0xff))) << 8)) -#define MAKELONG(a, b) ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16)) - -// -// Copy of histogram channel bitmask definitions from mfapi.h (not available in wdk). -// -#define MF_HISTOGRAM_CHANNEL_Y 0x00000001 -#define MF_HISTOGRAM_CHANNEL_R 0x00000002 -#define MF_HISTOGRAM_CHANNEL_G 0x00000004 -#define MF_HISTOGRAM_CHANNEL_B 0x00000008 -#define MF_HISTOGRAM_CHANNEL_Cb 0x00000010 -#define MF_HISTOGRAM_CHANNEL_Cr 0x00000020 - /************************************************* Externed information @@ -393,250 +253,6 @@ ImageCapturePinDispatch; /************************************************* - Enums / Typedefs - -*************************************************/ - -typedef enum _PIN_STATE -{ - - PinStopped = 0, - PinPaused, - PinRunning - -} PIN_STATE, *PPIN_STATE; - -typedef enum _PIN_MODE -{ - - PinNormalMode = 0, - PinBurstMode - -} PIN_MODE, *PPIN_MODE; - -/************************************************* - - Class Definitions - -*************************************************/ - -struct ISP_FRAME_SETTINGS -{ - ULONGLONG ISOMode; - ULONG ISOValue; // for Manual ISO settings. - KSCAMERA_EXTENDEDPROP_EVCOMPENSATION EVCompensation; - ULONGLONG WhiteBalanceMode; - KSCAMERA_EXTENDEDPROP_VIDEOPROCSETTING WhiteBalanceSetting; - ULONGLONG ExposureMode; - KSCAMERA_EXTENDEDPROP_VIDEOPROCSETTING ExposureSetting; - ULONGLONG FocusMode; - KSCAMERA_EXTENDEDPROP_VIDEOPROCSETTING FocusSetting; - ULONGLONG FocusPriority; - ULONGLONG FlashMode; - ULONG FlashValue; // Adjustable power setting (0-100) - BOOLEAN bPhotoConfirmation; -} ; - -struct SOC_CAP_WITH_STEPPING -{ - KSCAMERA_PERFRAMESETTING_CAP_ITEM_HEADER Hdr; - KSPROPERTY_STEPPING_LONG Stepping; -} ; - -struct SOC_CAP_WITH_STEPPING_LONGLONG -{ - KSCAMERA_PERFRAMESETTING_CAP_ITEM_HEADER Hdr; - KSPROPERTY_STEPPING_LONGLONG Stepping; -} ; - -// -// ICapturePin: -// -// This is a capture pin interface. The device level calls back the -// CompleteMapping method passing the number of completed mappings for -// the capture pin. -// -class ICapturePin -{ - -public: - - virtual - NTSTATUS - CompleteMapping( - _In_opt_ PKSSTREAM_POINTER Clone=nullptr - ) = 0; - -}; - -class LockDevice -{ -public: - - LockDevice(PKSDEVICE device) : m_device(device) - { - NT_ASSERT(m_device); - KsAcquireDevice(m_device); - } - - ~LockDevice() - { - KsReleaseDevice(m_device); - } -private: - PKSDEVICE m_device; -}; - -class LockFilter -{ -public: - - LockFilter(PKSFILTER filter) : m_filter(filter) - { - NT_ASSERT(m_filter); - KsFilterAcquireControl(m_filter); - } - - ~LockFilter() - { - KsFilterReleaseControl(m_filter); - } -private: - PKSFILTER m_filter; -}; - -// The following class definitions and ctors are used solely -// to simplify initialization of the parent metadata structures. -// They are not here for any other purpose. - -template <class T, class U> -class CMetaRational : public U -{ -public: - CMetaRational( T Num=1, T Denom=1 ) - { - Set=TRUE; - Numerator = Num; - Denominator = Denom; - } -}; - -typedef CMetaRational<UINT32, METADATA_RATIONAL> CMetadataRational; -typedef CMetaRational<INT32, METADATA_SRATIONAL> CMetadataSRational; - -template <class T, class U> -class CMetaPrimative : public U -{ -public: - CMetaPrimative( T n ) - { - Set = TRUE; - Value = n; - } -}; - -typedef CMetaPrimative<UINT16, METADATA_UINT16> CMetadataShort; -typedef CMetaPrimative<UINT32, METADATA_UINT32> CMetadataLong; -typedef CMetaPrimative<INT64, METADATA_INT64> CMetadataLongLong; -typedef CMetaPrimative<UINT64, METADATA_UINT64> CMetadataULongLong; - -class CMetadataShortString : public METADATA_SHORTSTRING -{ -public: - CMetadataShortString( - _In_z_ const CHAR *str - ) - { - Length = (UINT32) min(strlen(str), sizeof(String)); - strncpy_s( String, str, Length ); - } -}; - -class CMetadataEVCompensation : public METADATA_EVCOMP -{ -public: - CMetadataEVCompensation( - _In_ UINT64 flags, - _In_ UINT32 value - ) - { - Set = TRUE; - Flags = flags; - Value = value; - } -}; - -typedef struct -{ - LONG Value; - ULONG Flags; - ULONG Capabilities; -} VIDCAP_PROPERTY, *PVIDCAP_PROPERTY; - -typedef struct -{ - LONG lOcularFocalLength; - LONG lObjectiveFocalLengthMin; - LONG lObjectiveFocalLengthMax; -} FOCAL_LENGTH_PROPERTY, *PFOCAL_LENGTH_PROPERTY; - -const ULONG KSCAMERA_EXTENDEDPROP_VERSION = 1; - -// -// Note: I cannot simplify this down to just the FrameIndex. -// Past frames and non-VPS photos can have a photo confirmation set -// and those images will not have an index associated with them. -// -class PHOTOCONFIRMATION_INFO -{ -public: - PHOTOCONFIRMATION_INFO( - _In_ ULONG FrameIndex, - _In_ LONGLONG Time - ) - : m_Index( FrameIndex ) - , m_Time(Time) - , m_bRequired(TRUE) - {} - - PHOTOCONFIRMATION_INFO() - : m_Index(0) - , m_Time(0) - , m_bRequired( FALSE ) - {} - - BOOL - isRequired() - { - return m_bRequired; - } - - ULONG - getIndex() - { - return m_Index; - } - - LONGLONG - getTime() - { - return m_Time; - } - -private: - BOOL m_bRequired; - ULONG m_Index; - LONGLONG m_Time; -}; - -/************************************************* - - Global Functions - -*************************************************/ - -/************************************************* - Internal Includes *************************************************/ diff --git a/avstream/avscamera/sys/Device.cpp b/avstream/avscamera/sys/Device.cpp index 1b5f8090..ed46bdc8 100644 --- a/avstream/avscamera/sys/Device.cpp +++ b/avstream/avscamera/sys/Device.cpp @@ -688,7 +688,7 @@ Return Value: LOCALE_NEUTRAL, PLUGPLAY_PROPERTY_PERSISTENT, DEVPROP_TYPE_BINARY, - sizeof(ACPI_PLD_BUFFER), + sizeof(pld), (PVOID)&pld) ); diff --git a/avstream/avscamera/sys/NV12Synthesizer.cpp b/avstream/avscamera/sys/NV12Synthesizer.cpp index 2cdbf71b..32ee6ea8 100644 --- a/avstream/avscamera/sys/NV12Synthesizer.cpp +++ b/avstream/avscamera/sys/NV12Synthesizer.cpp @@ -49,10 +49,6 @@ #endif // ALLOC_PRAGMA -// suppressed due to Esp:773 -#pragma warning (push) -#pragma warning( disable:26015 ) // Suppress OACR error. Seems nonsensical. TODO: Must revisit. -#pragma warning( disable:26019 ) _Success_(return > 0) ULONG CNV12Synthesizer:: @@ -86,8 +82,11 @@ Return Value: --*/ { - // We assume the output stride is the same as the original width here. - UNREFERENCED_PARAMETER(Stride); + // In case stride isn't initialized. + if( Stride==0 ) + { + Stride = m_OutputStride; + } // The code actually handles this gracefully. It rounds down. NT_ASSERT( (m_Width&1) == 0 ); @@ -107,7 +106,7 @@ Return Value: ULONG MacroPixelsWide = m_Width/2; // Impossible. - if( MacroPixelsWide==0 ) + if (MacroPixelsWide == 0 || Stride < (MacroPixelsWide*2)) // 1 macropixel for NV12 is 2 bytes wide { NT_ASSERT(FALSE); return 0; @@ -117,7 +116,7 @@ Return Value: // Notice that we limit the number of macro pixel rows to what will // fit in the space available, no matter what is in the original. ULONG Y_limit = (Size /3) * 2; - ULONG MacroPixelsHigh = min( m_Height, Y_limit/m_Width)/2; + ULONG MacroPixelsHigh = min(m_Height, Y_limit / Stride) / 2; // Impossible. if( MacroPixelsHigh==0 ) @@ -127,8 +126,8 @@ Return Value: } // Now we work back to arrive at the Y & UV plane sizes. - ULONG UV_size = MacroPixelsWide * MacroPixelsHigh *2; - ULONG Y_size = MacroPixelsWide * MacroPixelsHigh *4; + ULONG UV_size = Stride * MacroPixelsHigh; + ULONG Y_size = Stride * MacroPixelsHigh * 2; ULONG YUV_size = Y_size + UV_size; // Impossible. @@ -138,12 +137,14 @@ Return Value: return 0; } - PWORD pY = (PWORD) Buffer; - PWORD pUV = (PWORD) (Buffer + Y_size); - + PUCHAR pYRow = Buffer; + PUCHAR pUVRow = Buffer + Y_size; for(ULONG row = 0; row < MacroPixelsHigh; row++) { PKS_RGBQUAD pSrc = (PKS_RGBQUAD) GetImageLocation(0, row*2); + PWORD pYUpper = (PWORD)pYRow; + PWORD pYLower = (PWORD)(pYRow + Stride); + PWORD pUV = (PWORD)pUVRow; for(ULONG col = 0; col < MacroPixelsWide; col++) { KS_RGBQUAD TL = pSrc[0]; @@ -153,9 +154,10 @@ Return Value: pSrc += 2; // Copy luma first - pY[0] = MAKEWORD(TL.rgbGreen, TR.rgbGreen); - pY[MacroPixelsWide] = MAKEWORD(BL.rgbGreen, BR.rgbGreen); - pY++; + pYUpper[0] = MAKEWORD(TL.rgbGreen, TR.rgbGreen); + pYLower[0] = MAKEWORD(BL.rgbGreen, BR.rgbGreen); + pYUpper++; + pYLower++; LONG tU = TL.rgbBlue; //top left @@ -172,12 +174,10 @@ Return Value: // Copy decimated chroma *pUV++ = MAKEWORD(((tU+2)>>2), ((tV+2)>>2)); } - // Skip a scan line, since we've already copied it. - pY += MacroPixelsWide; + // A row of macropixels covers two Y rows and one UV row + pYRow += (Stride * 2); + pUVRow += Stride; } - return (ULONG) (((PUCHAR) pUV) - Buffer); + return (ULONG)(pUVRow - Buffer); } -// suppressed due to Esp:773 -#pragma warning (pop) - diff --git a/avstream/avscamera/sys/NV12Synthesizer.h b/avstream/avscamera/sys/NV12Synthesizer.h index 27bc6ccb..1ef2f3e7 100644 --- a/avstream/avscamera/sys/NV12Synthesizer.h +++ b/avstream/avscamera/sys/NV12Synthesizer.h @@ -53,6 +53,7 @@ public: { NT_ASSERT( ( Width % 2 ) == 0 ); NT_ASSERT( ( Height % 2 ) == 0 ); + m_OutputStride = Width * sizeof(BYTE); } // diff --git a/avstream/avscamera/sys/Sensor.cpp b/avstream/avscamera/sys/Sensor.cpp index 19988073..97615250 100644 --- a/avstream/avscamera/sys/Sensor.cpp +++ b/avstream/avscamera/sys/Sensor.cpp @@ -301,6 +301,8 @@ CreateSynthesizer( // Create the necessary type of image synthesizer. // { + PAGED_CODE(); + NTSTATUS Status = STATUS_SUCCESS; LONG Width = VideoInfoHeader->bmiHeader.biWidth; LONG Height = VideoInfoHeader->bmiHeader.biHeight; @@ -1053,6 +1055,7 @@ Return Value: --*/ { PAGED_CODE(); + KScopedMutex Lock(m_SensorMutex); // Set the current ISP settings and free any prior. @@ -1090,6 +1093,8 @@ SetSynthesizerAttribute( LONGLONG Info ) { + PAGED_CODE(); + for( ULONG Pin=0; IsValidIndex(Pin); Pin++ ) { if( m_Synthesizer[Pin] ) @@ -1344,6 +1349,7 @@ DEFINE_NULL_PROPERTY(CSensor, CExtendedProperty, OpticalImageStabilization) DEFINE_NULL_PROPERTY(CSensor, CExtendedProperty, OptimizationHint) DEFINE_NULL_PROPERTY(CSensor, CExtendedProperty, AdvancedPhoto) DEFINE_NULL_PROPERTY(CSensor, CExtendedVidProcSetting, FaceDetection) +DEFINE_NULL_PROPERTY(CSensor, CExtendedProperty, VideoTemporalDenoising) DEFINE_NULL_PROPERTY(CSensor, KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S, VideoStabMode) diff --git a/avstream/avscamera/sys/Sensor.h b/avstream/avscamera/sys/Sensor.h index a40b9d0c..dac97630 100644 --- a/avstream/avscamera/sys/Sensor.h +++ b/avstream/avscamera/sys/Sensor.h @@ -574,6 +574,7 @@ public: DECLARE_PROPERTY( CExtendedProperty, OptimizationHint ); DECLARE_PROPERTY( CExtendedProperty, AdvancedPhoto ); DECLARE_PROPERTY( CExtendedVidProcSetting, FaceDetection ); + DECLARE_PROPERTY( CExtendedProperty, VideoTemporalDenoising); DECLARE_PROPERTY_VARSIZE_ASYNC( CRoiProperty, Roi ); diff --git a/avstream/avscamera/sys/SensorSimulation.cpp b/avstream/avscamera/sys/SensorSimulation.cpp index 3ebeb56b..ce6a2c17 100644 --- a/avstream/avscamera/sys/SensorSimulation.cpp +++ b/avstream/avscamera/sys/SensorSimulation.cpp @@ -299,6 +299,7 @@ Return Value: m_VideoStabilization = KSCAMERA_EXTENDEDPROP_VIDEOSTABILIZATION_OFF; m_Histogram = KSCAMERA_EXTENDEDPROP_HISTOGRAM_OFF; m_OpticalImageStabilization = KSCAMERA_EXTENDEDPROP_OIS_AUTO; + m_VideoTemporalDenoising = KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_AUTO; m_AdvancedPhoto.PinId = GetNextStillIndex(); m_AdvancedPhoto.Flags = KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_OFF; @@ -1773,6 +1774,38 @@ SetOpticalImageStabilization( return STATUS_SUCCESS; } +// Get KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOTEMPORALDENOISING. +NTSTATUS +CSensorSimulation:: +GetVideoTemporalDenoising( + _Inout_ CExtendedProperty *pProperty +) +{ + PAGED_CODE(); + KScopedMutex lock(m_SensorMutex); + + pProperty->Flags = m_VideoTemporalDenoising; + pProperty->Capability = KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_AUTO | + KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_OFF | + KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_ON; + + return STATUS_SUCCESS; +} + +// Set KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOTEMPORALDENOISING. +NTSTATUS +CSensorSimulation:: +SetVideoTemporalDenoising( + _In_ CExtendedProperty *pProperty +) +{ + PAGED_CODE(); + KScopedMutex lock(m_SensorMutex); + + m_VideoTemporalDenoising = pProperty->Flags; + return STATUS_SUCCESS; +} + // Get KSPROPERTY_CAMERACONTROL_EXTENDED_ADVANCEDPHOTO. NTSTATUS CSensorSimulation:: diff --git a/avstream/avscamera/sys/SensorSimulation.h b/avstream/avscamera/sys/SensorSimulation.h index 4b07f84e..7fb30825 100644 --- a/avstream/avscamera/sys/SensorSimulation.h +++ b/avstream/avscamera/sys/SensorSimulation.h @@ -59,7 +59,8 @@ protected: ULONGLONG m_VideoHDR; ULONGLONG m_VideoStabilization; ULONGLONG m_Histogram; - ULONGLONG m_OpticalImageStabilization; + ULONGLONG m_OpticalImageStabilization; + ULONGLONG m_VideoTemporalDenoising; CExtendedProperty m_AdvancedPhoto; CWhiteBalanceRoiIspControl m_RoiWhiteBalance; @@ -226,6 +227,7 @@ public: DECLARE_PROPERTY( CExtendedMaxVideoFpsForPhotoRes, MaxVideoFpsForPhotoRes ); DECLARE_PROPERTY_GET( CExtendedFieldOfView, FieldOfView ); DECLARE_PROPERTY_GET( CExtendedCameraAngleOffset, CameraAngleOffset ); + DECLARE_PROPERTY( CExtendedProperty, VideoTemporalDenoising); DECLARE_PROPERTY_VARSIZE_ASYNC_NOCANCEL( CRoiProperty, Roi ); diff --git a/avstream/avscamera/sys/Synthesizer.h b/avstream/avscamera/sys/Synthesizer.h index 175fa348..6612a3f6 100644 --- a/avstream/avscamera/sys/Synthesizer.h +++ b/avstream/avscamera/sys/Synthesizer.h @@ -161,7 +161,7 @@ protected: // // The assumed stride of our output format. Currently used by YUY2 and - // all image captures, except NV12. This value should be initialized by + // all image captures. This value should be initialized by // the derived classes. // LONG m_OutputStride; @@ -178,7 +178,7 @@ protected: // // A printable name identifying this format. // - PCCHAR m_FormatName; + const CHAR *m_FormatName; // // A color palette for this colorspace. @@ -213,7 +213,7 @@ public: // DEFAULT CONSTRUCTOR // CSynthesizer( - PCCHAR Name="[Unknown]", + const CHAR *Name="[Unknown]", ULONG ChannelMask=0, ULONG Width=0, ULONG Height=0 @@ -471,7 +471,7 @@ public: // Get the color channel mask associated with this format. // ULONG - GetChannelMask() + GetChannelMask() const { return m_ChannelMask; } diff --git a/avstream/avscamera/sys/Timer.h b/avstream/avscamera/sys/Timer.h index d4e6322e..1927158b 100644 --- a/avstream/avscamera/sys/Timer.h +++ b/avstream/avscamera/sys/Timer.h @@ -133,7 +133,7 @@ private: _Inout_opt_ PVOID Arg2 ) ; - TIMER_TYPE GetType() + TIMER_TYPE GetType() const { return m_type; } diff --git a/avstream/avscamera/sys/Util.cpp b/avstream/avscamera/sys/Util.cpp index 7c788990..a64dc42f 100644 --- a/avstream/avscamera/sys/Util.cpp +++ b/avstream/avscamera/sys/Util.cpp @@ -175,7 +175,7 @@ WhiteBalancePreset2Temperature( break; } - return temp; + return min( max( temp, WHITEBALANCE_MIN ), WHITEBALANCE_MAX ); } typedef struct @@ -475,6 +475,8 @@ DbgRotation2Degrees( AcpiPldRotation r ) { + PAGED_CODE(); + switch( r ) { case AcpiPldRotation0 : return 0; @@ -489,3 +491,59 @@ DbgRotation2Degrees( return -1; } +CCameraExtrinsics_2Transforms:: +CCameraExtrinsics_2Transforms( ULONG Seed ) +{ + PAGED_CODE(); + + static + KS_CAMERA_EXTRINSICS_CALIBRATEDTRANSFORM temp = + { + {0x2eef2648, 0x67e7, 0x48a0, 0xa2, 0x27, 0x46, 0xed, 0x5c, 0xdc, 0x84, 0xb4}, // CalibrationId + {0.5, 0.5, 0.5}, // Position + {0.5, 0.5, 0.5, 0.5} // Orientation + }; + + TransformCount = 2; + PKS_CAMERA_EXTRINSICS_CALIBRATEDTRANSFORM pTransform = CalibratedTransforms; + for( UINT32 i=0; i<2; i++ ) + { + *pTransform = temp; + pTransform->CalibrationId.Data4[7] = (unsigned char) i; + pTransform->CalibrationId.Data1 = Seed; + pTransform++; + } +} + +CCameraIntrinsics_2Models:: +CCameraIntrinsics_2Models() +{ + PAGED_CODE(); + + static + KS_PINHOLECAMERAINTRINSIC_INTRINSICMODEL temp = + { + 0xBADF00D, // Width + 0xBADF00D, // Height + { {1.0,2.0}, {3.0,4.0} }, // CameraModel + { 1.0, 2.0, 3.0, (float)3.1415296, (float)2.71828 } // DistortionModel + }; + + static + POINT Dimension[]= + { + {DMAX_X, DMAX_Y}, + {D_X, D_Y} + }; + + IntrinsicModelCount = 2; + PKS_PINHOLECAMERAINTRINSIC_INTRINSICMODEL pModel = IntrinsicModels; + for( UINT32 i=0; i<2; i++ ) + { + + *pModel = temp; + pModel->Width = Dimension[i].x; + pModel->Height = Dimension[i].y; + pModel++; + } +} diff --git a/avstream/avscamera/sys/Util.h b/avstream/avscamera/sys/Util.h index f235a42d..7ed08979 100644 --- a/avstream/avscamera/sys/Util.h +++ b/avstream/avscamera/sys/Util.h @@ -123,7 +123,8 @@ BoundsCheck( { NTSTATUS ntStatus = STATUS_SUCCESS; - if( ((Value - T(Bounds.Min) ) % T(Bounds.Step)) != 0 || + if( (Bounds.Step==0 && Bounds.Min!=Bounds.Max) || + (Bounds.Step!=0 && ((Value - T(Bounds.Min) ) % T(Bounds.Step)) != 0) || Value > T(Bounds.Max) || Value < T(Bounds.Min) ) { @@ -152,7 +153,8 @@ BoundsCheckSigned( { NTSTATUS ntStatus = STATUS_SUCCESS; - if( ((Value - Bounds.Bounds.SignedMinimum) % Bounds.SteppingDelta) != 0 || + if( (Bounds.SteppingDelta==0 && Bounds.Bounds.SignedMinimum!=Bounds.Bounds.SignedMaximum) || + (Bounds.SteppingDelta!=0 && (Value - Bounds.Bounds.SignedMinimum) % Bounds.SteppingDelta) != 0 || Value > Bounds.Bounds.SignedMaximum || Value < Bounds.Bounds.SignedMinimum ) { @@ -171,7 +173,8 @@ BoundsCheckSigned( { NTSTATUS ntStatus = STATUS_SUCCESS; - if( ((Value - Bounds.Bounds.SignedMinimum) % Bounds.SteppingDelta) != 0 || + if( (Bounds.SteppingDelta==0 && Bounds.Bounds.SignedMinimum!=Bounds.Bounds.SignedMaximum) || + (Bounds.SteppingDelta!=0 && ((Value - Bounds.Bounds.SignedMinimum) % Bounds.SteppingDelta) != 0) || Value > Bounds.Bounds.SignedMaximum || Value < Bounds.Bounds.SignedMinimum ) { @@ -193,7 +196,8 @@ BoundsCheckUnsigned( { NTSTATUS ntStatus = STATUS_SUCCESS; - if( ((Value - Bounds.Bounds.UnsignedMinimum) % Bounds.SteppingDelta) != 0 || + if( (Bounds.SteppingDelta==0 && Bounds.Bounds.UnsignedMinimum!=Bounds.Bounds.UnsignedMaximum) || + (Bounds.SteppingDelta!=0 && ((Value - Bounds.Bounds.UnsignedMinimum) % Bounds.SteppingDelta) != 0) || Value > Bounds.Bounds.UnsignedMaximum || Value < Bounds.Bounds.UnsignedMinimum ) { @@ -212,7 +216,8 @@ BoundsCheckUnsigned( { NTSTATUS ntStatus = STATUS_SUCCESS; - if( ((Value - Bounds.Bounds.UnsignedMinimum) % Bounds.SteppingDelta) != 0 || + if( (Bounds.SteppingDelta==0 && Bounds.Bounds.UnsignedMinimum!=Bounds.Bounds.UnsignedMaximum) || + (Bounds.SteppingDelta!=0 && ((Value - Bounds.Bounds.UnsignedMinimum) % Bounds.SteppingDelta) != 0) || Value > Bounds.Bounds.UnsignedMaximum || Value < Bounds.Bounds.UnsignedMinimum ) { @@ -267,6 +272,30 @@ DbgRotation2Degrees( AcpiPldRotation r ); +// Create a definition that self-initialize a KS_CAMERA_EXTRINSIC structure. +class CCameraExtrinsics_2Transforms : public KS_CAMERA_EXTRINSICS +{ +public: + KS_CAMERA_EXTRINSICS_CALIBRATEDTRANSFORM CalibratedTransform2; + +public: + CCameraExtrinsics_2Transforms() + { + RtlZeroMemory(this, sizeof(*this)); + } + CCameraExtrinsics_2Transforms( ULONG Seed ); +}; + +// Create a definition that self-initialize a KS_CAMERA_EXTRINSIC structure. +class CCameraIntrinsics_2Models : public KS_CAMERA_INTRINSICS +{ +public: + KS_PINHOLECAMERAINTRINSIC_INTRINSICMODEL IntrinsicModel2; + +public: + CCameraIntrinsics_2Models(); +}; + #define SAFE_FREE(_x_) \ if( _x_ ) \ diff --git a/avstream/avscamera/sys/YUVSynthesizer.h b/avstream/avscamera/sys/YUVSynthesizer.h index 819139e4..4f856dd6 100644 --- a/avstream/avscamera/sys/YUVSynthesizer.h +++ b/avstream/avscamera/sys/YUVSynthesizer.h @@ -59,7 +59,7 @@ public: //Default constructor CYUVSynthesizer ( - PCCHAR Name="[Something YUV]", + const CHAR *Name="[Something YUV]", ULONG Width=0, ULONG Height=0 ) diff --git a/avstream/avscamera/sys/avscamera.inf b/avstream/avscamera/sys/avscamera.inf Binary files differindex d855cc6f..2a17a764 100644 --- a/avstream/avscamera/sys/avscamera.inf +++ b/avstream/avscamera/sys/avscamera.inf diff --git a/avstream/avscamera/sys/filter.cpp b/avstream/avscamera/sys/filter.cpp index cb28775e..2680f503 100644 --- a/avstream/avscamera/sys/filter.cpp +++ b/avstream/avscamera/sys/filter.cpp @@ -3029,8 +3029,7 @@ SetVFR( pVFR->isValid() && pVFR->Capability == 0 && (KSCAMERA_EXTENDEDPROP_VFR_OFF == pVFR->Flags || - KSCAMERA_EXTENDEDPROP_VFR_ON == pVFR->Flags || - KSCAMERA_EXTENDEDPROP_VIDEOHDR_AUTO == pVFR->Flags ) ) + KSCAMERA_EXTENDEDPROP_VFR_ON == pVFR->Flags) ) { //Set the current VFR state Status = m_Sensor->SetVFR( pVFR ); @@ -3370,6 +3369,69 @@ SetVideoStabilization( return Status; } +// Get KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOTEMPORALDENOISING. +NTSTATUS +CCaptureFilter:: +GetVideoTemporalDenoising( + _Inout_ CExtendedProperty *pVideoTemporalDenoising +) +{ + PAGED_CODE(); + NTSTATUS Status = STATUS_INVALID_PARAMETER; + + // Call must come for filter scope only + if (pVideoTemporalDenoising->isValid() && + pVideoTemporalDenoising->PinId == KSCAMERA_EXTENDEDPROP_FILTERSCOPE) + { + //Get the current state + Status = m_Sensor->GetVideoTemporalDenoising(pVideoTemporalDenoising); + } + + DBG_TRACE("pVideoTemporalDenoising = %p, PinId = %u, Flags = %llu, Version = %u", + pVideoTemporalDenoising, pVideoTemporalDenoising->PinId, pVideoTemporalDenoising->Flags, pVideoTemporalDenoising->Version); + + return Status; +} + +// Set KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOTEMPORALDENOISING. +NTSTATUS +CCaptureFilter:: +SetVideoTemporalDenoising( + _In_ CExtendedProperty *pVideoTemporalDenoising +) +{ + PAGED_CODE(); + + NTSTATUS Status = STATUS_INVALID_PARAMETER; + + // Call must come for filter scope only and flags must be supported and mutually exclusive + if (pVideoTemporalDenoising->isValid() && + pVideoTemporalDenoising->PinId == KSCAMERA_EXTENDEDPROP_FILTERSCOPE && + !(pVideoTemporalDenoising->Capability & KSCAMERA_EXTENDEDPROP_CAPS_ASYNCCONTROL) && + (KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_AUTO == pVideoTemporalDenoising->Flags || + KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_OFF == pVideoTemporalDenoising->Flags || + KSCAMERA_EXTENDEDPROP_VIDEOTEMPORALDENOISING_ON == pVideoTemporalDenoising->Flags)) + { + CExtendedProperty Caps(*pVideoTemporalDenoising); + Status = m_Sensor->GetVideoTemporalDenoising(&Caps); + + if (NT_SUCCESS(Status)) + { + // Assume an invalid parameter. + Status = STATUS_INVALID_PARAMETER; + + if (pVideoTemporalDenoising->Flags == (pVideoTemporalDenoising->Flags & Caps.Capability)) + { + Status = m_Sensor->SetVideoTemporalDenoising(pVideoTemporalDenoising); + } + } + } + DBG_TRACE("pVideoTemporalDenoising = %p, PinId = %u, Flags = %llu, Version = %u", + pVideoTemporalDenoising, pVideoTemporalDenoising->PinId, pVideoTemporalDenoising->Flags, pVideoTemporalDenoising->Version); + + return Status; +} + // Get KSPROPERTY_CAMERACONTROL_EXTENDED_OIS. NTSTATUS CCaptureFilter:: @@ -4078,3 +4140,176 @@ GetVideoControlCaps( return Status; } +NTSTATUS +CCaptureFilter::GetExtrinsic( + _In_opt_ KS_CAMERA_EXTRINSICS *Data, + _In_ ULONG PinId, + _Inout_ ULONG *Length) +{ + PAGED_CODE(); + + if( PinId < m_pKSFilter->Descriptor->PinDescriptorsCount ) + { + CCameraExtrinsics_2Transforms Extrinsics( PinId ); // Parameters are just identification for now. + if( Data ) + { + RtlCopyMemory(Data, &Extrinsics, sizeof(Extrinsics)); + } + + *Length = sizeof(Extrinsics); + return STATUS_SUCCESS; + } + return STATUS_INVALID_PARAMETER; +} + +NTSTATUS +CCaptureFilter::GetIntrinsic( + _In_opt_ KS_CAMERA_INTRINSICS *Data, + _In_ ULONG PinId, + _Inout_ ULONG *Length) +{ + PAGED_CODE(); + + if( PinId < m_pKSFilter->Descriptor->PinDescriptorsCount ) + { + CCameraIntrinsics_2Models Intrinsics; + if( Data ) + { + RtlCopyMemory(Data, &Intrinsics, sizeof(Intrinsics)); + } + + *Length = sizeof(Intrinsics); + return STATUS_SUCCESS; + } + return STATUS_INVALID_PARAMETER; +} + +// Get KSPROPERTY_CAMERA_ATTRIBUTES_EXTRINSICS +NTSTATUS +CCaptureFilter::GetExtrinsics( + _In_ PIRP pIrp, + _In_ PKSP_PIN pProperty, + _Inout_ PVOID pData +) +{ + PAGED_CODE(); + + NT_ASSERT(pIrp); + NT_ASSERT(pProperty); + + CCaptureFilter *pFilter = reinterpret_cast <CCaptureFilter *>(KsGetFilterFromIrp(pIrp)->Context); + PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp); + ULONG ulOutputBufferLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength; + ULONG RequiredLength = 0; + + NTSTATUS Status = + pFilter->GetExtrinsic( nullptr, pProperty->PinId, &RequiredLength ); + + // Note: We may want to determine capabilities at runtime in the future. + + // We only handle GETs + if( NT_SUCCESS(Status) ) + { + RequiredLength += sizeof(KSCAMERA_ATTRIBUTES_HEADER); + + if (ulOutputBufferLength == 0) + { + pIrp->IoStatus.Information = RequiredLength; + Status = STATUS_BUFFER_OVERFLOW; + } + else if (ulOutputBufferLength < RequiredLength) + { + Status = STATUS_BUFFER_TOO_SMALL; + } + else if (pData && ulOutputBufferLength >= RequiredLength) + { + PKSCAMERA_ATTRIBUTES_HEADER pHdr = (PKSCAMERA_ATTRIBUTES_HEADER) pData; + PKS_CAMERA_EXTRINSICS pExtrinsic = (PKS_CAMERA_EXTRINSICS) (pHdr + 1); + ULONG Size=0; + + Status = + pFilter->GetExtrinsic( + pExtrinsic, + pProperty->PinId, + &Size ); + + if( NT_SUCCESS(Status) ) + { + pHdr->Size = RequiredLength; + pHdr->PinId = pProperty->PinId; + pIrp->IoStatus.Information = RequiredLength; + } + } + else + { + Status = STATUS_INVALID_PARAMETER; + } + } + return Status; +} + +// Get KSPROPERTY_CAMERA_ATTRIBUTES_INTRINSICS +NTSTATUS +CCaptureFilter::GetIntrinsics( + _In_ PIRP pIrp, + _In_ PKSP_PIN pProperty, + _Inout_ PVOID pData +) +{ + PAGED_CODE(); + + NT_ASSERT(pIrp); + NT_ASSERT(pProperty); + + CCaptureFilter *pFilter = reinterpret_cast <CCaptureFilter *>(KsGetFilterFromIrp(pIrp)->Context); + PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp); + ULONG ulOutputBufferLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength; + ULONG RequiredLength = 0; + + NTSTATUS Status = + pFilter->GetIntrinsic( nullptr, pProperty->PinId, &RequiredLength ); + + // Note: We may want to determine capabilities at runtime in the future. + + // We only handle GETs + if( NT_SUCCESS(Status) ) + { + RequiredLength += sizeof(KSCAMERA_ATTRIBUTES_HEADER); + + if (ulOutputBufferLength == 0) + { + pIrp->IoStatus.Information = RequiredLength; + Status = STATUS_BUFFER_OVERFLOW; + } + else if (ulOutputBufferLength < RequiredLength) + { + Status = STATUS_BUFFER_TOO_SMALL; + } + else if (pData && ulOutputBufferLength >= RequiredLength) + { + PKSCAMERA_ATTRIBUTES_HEADER pHdr = (PKSCAMERA_ATTRIBUTES_HEADER) pData; + PKS_CAMERA_INTRINSICS pIntrinsic = (PKS_CAMERA_INTRINSICS) (pHdr + 1); + ULONG Size=0; + + Status = + pFilter->GetIntrinsic( + pIntrinsic, + pProperty->PinId, + &Size ); + + if( NT_SUCCESS(Status) ) + { + pHdr->Size = RequiredLength; + pHdr->PinId = pProperty->PinId; + pIrp->IoStatus.Information = RequiredLength; + } + } + else + { + Status = STATUS_INVALID_PARAMETER; + } + } + return Status; +} + + diff --git a/avstream/avscamera/sys/filter.h b/avstream/avscamera/sys/filter.h index 58a0e9e8..292a6bc7 100644 --- a/avstream/avscamera/sys/filter.h +++ b/avstream/avscamera/sys/filter.h @@ -72,6 +72,18 @@ protected: void Cleanup(); + NTSTATUS + GetExtrinsic( + _In_opt_ KS_CAMERA_EXTRINSICS *Data, + _In_ ULONG PinId, + _Inout_ ULONG *Length); + + NTSTATUS + GetIntrinsic( + _In_opt_ KS_CAMERA_INTRINSICS *Data, + _In_ ULONG PinId, + _Inout_ ULONG *Length); + public: // @@ -319,6 +331,7 @@ DECLARE_PROPERTY_SET_HANDLER( type, name ) DECLARE_PROPERTY_HANDLERS( CExtendedProperty, Thumbnail ) DECLARE_PROPERTY_HANDLERS( CExtendedProperty, TriggerTime ) DECLARE_PROPERTY_HANDLERS( CExtendedProperty, TorchMode ) + DECLARE_PROPERTY_HANDLERS( CExtendedProperty, VideoTemporalDenoising) DECLARE_PROPERTY_HANDLERS( KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S, VideoStabMode ) DECLARE_PROPERTY_HANDLERS( KSPROPERTY_CAMERACONTROL_FLASH_S, Flash ) @@ -379,6 +392,22 @@ DECLARE_PROPERTY_SET_HANDLER( type, name ) _Outptr_opt_result_maybenull_ ISP_FRAME_SETTINGS **ppSettings ); + static + NTSTATUS + GetExtrinsics( + _In_ PIRP pIrp, + _In_ PKSP_PIN pProperty, + _Inout_ PVOID pData + ); + + static + NTSTATUS + GetIntrinsics( + _In_ PIRP pIrp, + _In_ PKSP_PIN pProperty, + _Inout_ PVOID pData + ); + // Helper function for finding our filter object. static CCaptureFilter * diff --git a/avstream/avscamera/sys/hwsim.cpp b/avstream/avscamera/sys/hwsim.cpp index df8240b4..4309befb 100644 --- a/avstream/avscamera/sys/hwsim.cpp +++ b/avstream/avscamera/sys/hwsim.cpp @@ -1107,7 +1107,7 @@ Return Value: **************************************************************************/ -PCCHAR +const CHAR * DVS_Text( ULONGLONG Flags ) { PAGED_CODE(); @@ -1123,12 +1123,12 @@ DVS_Text( ULONGLONG Flags ) CHAR buffer[32]; RtlStringCbPrintfA(buffer, sizeof(buffer), "Unknown [0x%016llX]", Flags); - return (PCCHAR) buffer; + return (const CHAR *) buffer; } } } -PCCHAR +const CHAR * OIS_Text( ULONGLONG Flags ) { PAGED_CODE(); @@ -1144,7 +1144,7 @@ OIS_Text( ULONGLONG Flags ) CHAR buffer[32]; RtlStringCbPrintfA(buffer, sizeof(buffer), "Unknown [0x%016llX]", Flags); - return (PCCHAR) buffer; + return (const CHAR *) buffer; } } } diff --git a/avstream/avscamera/sys/imagehwsim.cpp b/avstream/avscamera/sys/imagehwsim.cpp index 1f4d7a1a..2ba44721 100644 --- a/avstream/avscamera/sys/imagehwsim.cpp +++ b/avstream/avscamera/sys/imagehwsim.cpp @@ -884,7 +884,7 @@ Return Value: **************************************************************************/ -PCCHAR +const CHAR * AdvancedPhoto_Text( ULONGLONG Flags ) { PAGED_CODE(); @@ -908,7 +908,7 @@ AdvancedPhoto_Text( ULONGLONG Flags ) CHAR buffer[32]; RtlStringCbPrintfA(buffer, sizeof(buffer), "Unknown [0x%016llX]", Flags); - return (PCCHAR) buffer; + return (const CHAR *) buffer; } } } |
