diff options
| author | Adonais Romero González <[email protected]> | 2020-04-07 16:17:44 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2020-04-07 16:17:44 -0700 |
| commit | 13c61ceeb3f7da66a2b57730d12d14eb7463c46a (patch) | |
| tree | ff52f9ac442a60625936a266db1bef12ac694a8e /avstream/avscamera | |
| parent | dd4fad494b996f5729be98e0271ea74ef1a5d2ad (diff) | |
| parent | 27c8560ba860165db5a173b37591271397d20bb7 (diff) | |
Update all the AvStream samples for Vibranium.
Diffstat (limited to 'avstream/avscamera')
23 files changed, 480 insertions, 114 deletions
diff --git a/avstream/avscamera/Package/package.VcxProj b/avstream/avscamera/Package/package.VcxProj index 5b8aa6ef..92690b1a 100644 --- a/avstream/avscamera/Package/package.VcxProj +++ b/avstream/avscamera/Package/package.VcxProj @@ -42,22 +42,18 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <TargetVersion>Windows10</TargetVersion> <UseDebugLibraries>true</UseDebugLibraries> - <DriverTargetPlatform>Universal</DriverTargetPlatform> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <TargetVersion>Windows10</TargetVersion> <UseDebugLibraries>false</UseDebugLibraries> - <DriverTargetPlatform>Universal</DriverTargetPlatform> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <TargetVersion>Windows10</TargetVersion> <UseDebugLibraries>true</UseDebugLibraries> - <DriverTargetPlatform>Universal</DriverTargetPlatform> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <TargetVersion>Windows10</TargetVersion> <UseDebugLibraries>false</UseDebugLibraries> - <DriverTargetPlatform>Universal</DriverTargetPlatform> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> diff --git a/avstream/avscamera/mft0/MFT0Impl.cpp b/avstream/avscamera/mft0/MFT0Impl.cpp index 992be0e9..26d40f99 100644 --- a/avstream/avscamera/mft0/MFT0Impl.cpp +++ b/avstream/avscamera/mft0/MFT0Impl.cpp @@ -1950,14 +1950,14 @@ HRESULT CSocMft0::ParseMetadata_FaceDetection( } PMETADATA_FACEDATA pFaceData = (PMETADATA_FACEDATA)(pFaceHeader + 1); UINT32 cbRectSize = sizeof(FaceRectInfoBlobHeader) + (sizeof(FaceRectInfo) * (pFaceHeader->Count)); - BYTE *pRectBuf = new BYTE[cbRectSize]; + BYTE *pRectBuf = new (std::nothrow) BYTE[cbRectSize]; if (pRectBuf == NULL) { return E_OUTOFMEMORY; } UINT32 cbCharSize = sizeof(FaceCharacterizationBlobHeader) + (sizeof(FaceCharacterization) * (pFaceHeader->Count)); - BYTE *pCharBuf = new BYTE[cbCharSize]; + BYTE *pCharBuf = new (std::nothrow) BYTE[cbCharSize]; if (pCharBuf == NULL) { delete[] pRectBuf; diff --git a/avstream/avscamera/mft0/stdafx.h b/avstream/avscamera/mft0/stdafx.h index 037376ec..6d784805 100644 --- a/avstream/avscamera/mft0/stdafx.h +++ b/avstream/avscamera/mft0/stdafx.h @@ -16,7 +16,12 @@ #endif #include "targetver.h" +#if (NTDDI_VERSION >= NTDDI_WIN10_VB) +#pragma message("MFT0 is deprecated for this target Windows version and beyond- Change project settings to target an older version of Windows") +#endif + #if (NTDDI_VERSION <= NTDDI_WIN7) +// TODO: disable the MFT0 conditional to the target system version #pragma message("MFT0 is in not supported in this target Windows version - Change project settings to target a newer version of Windows") #endif diff --git a/avstream/avscamera/sys/AvsCamera.cpp b/avstream/avscamera/sys/AvsCamera.cpp index 3563b3dd..3c51323f 100644 --- a/avstream/avscamera/sys/AvsCamera.cpp +++ b/avstream/avscamera/sys/AvsCamera.cpp @@ -29,13 +29,7 @@ PVOID operator new POOL_TYPE poolType ) { - PVOID result = ExAllocatePoolWithTag(poolType,iSize,'wNCK'); - - if (result) { - RtlZeroMemory(result,iSize); - } - - return result; + return ExAllocatePoolZero(poolType,iSize,'wNCK'); } PVOID operator new @@ -48,13 +42,7 @@ PVOID operator new ULONG tag ) { - PVOID result = ExAllocatePoolWithTag(poolType,iSize,tag); - - if (result) { - RtlZeroMemory(result,iSize); - } - - return result; + return ExAllocatePoolZero(poolType,iSize,tag); } PVOID @@ -67,14 +55,7 @@ operator new[]( ULONG tag ) { - PVOID result = ExAllocatePoolWithTag(poolType, iSize, tag); - - if (result) - { - RtlZeroMemory(result, iSize); - } - - return result; + return ExAllocatePoolZero(poolType, iSize, tag); } /*++ diff --git a/avstream/avscamera/sys/AvsCamera.vcxproj b/avstream/avscamera/sys/AvsCamera.vcxproj index 326b1848..81d0078b 100644 --- a/avstream/avscamera/sys/AvsCamera.vcxproj +++ b/avstream/avscamera/sys/AvsCamera.vcxproj @@ -232,7 +232,7 @@ <ResourceCompile Include="AvsCamera.rc" /> </ItemGroup> <ItemGroup> - <Inf Exclude="@(Inf)" Include="*.inf" /> + <Inf Exclude="@(Inf)" Include="*.inf;*.inx" /> <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> </ItemGroup> <ItemGroup> @@ -244,4 +244,4 @@ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> -</Project>
\ No newline at end of file +</Project> diff --git a/avstream/avscamera/sys/AvsCameraFilter.cpp b/avstream/avscamera/sys/AvsCameraFilter.cpp index af25b691..1a41997a 100644 --- a/avstream/avscamera/sys/AvsCameraFilter.cpp +++ b/avstream/avscamera/sys/AvsCameraFilter.cpp @@ -221,7 +221,7 @@ DEFINE_KSPROPERTY_TABLE(ExtendedPropertyItems) CCaptureFilter::SetRoiIspControl, NULL, 0, NULL, NULL, 0 ), - DEFINE_PROP_ITEM(CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_ZOOM, CExtendedVidProcSetting, Zoom), + DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_ZOOM, CExtendedVidProcSetting, Zoom), DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOHDR, CExtendedProperty, VideoHDR ), DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_VFR, CExtendedProperty, VFR ), DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_ISO_ADVANCED, CExtendedVidProcSetting, IsoAdvanced ), @@ -230,7 +230,8 @@ DEFINE_KSPROPERTY_TABLE(ExtendedPropertyItems) 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_VIDEOTEMPORALDENOISING, CExtendedProperty, VideoTemporalDenoising) + DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOTEMPORALDENOISING, CExtendedProperty, VideoTemporalDenoising), + DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_RELATIVEPANELOPTIMIZATION, CExtendedProperty, RelativePanel) }; // Front-facing cameras often have limited capabilities. One way to express that is to use a restricted automation table such as this one. @@ -244,6 +245,7 @@ DEFINE_KSPROPERTY_TABLE(ExtendedPropertyItemsFFC) DEFINE_PROP_ITEM_NO_SET( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_MAXVIDFPS_PHOTORES, CExtendedMaxVideoFpsForPhotoRes, MaxVideoFpsForPhotoRes ), DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_SCENEMODE, CExtendedProperty, SceneMode ), DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_TORCHMODE, CExtendedProperty, TorchMode ), + DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_IRTORCHMODE, CExtendedVidProcSetting, IRTorch ), DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_OPTIMIZATIONHINT, CExtendedProperty, OptimizationHint ), DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_WHITEBALANCEMODE, CExtendedVidProcSetting, WhiteBalance ), DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_EXPOSUREMODE, CExtendedVidProcSetting, Exposure ), @@ -258,11 +260,12 @@ DEFINE_KSPROPERTY_TABLE(ExtendedPropertyItemsFFC) DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_ISO_ADVANCED, CExtendedVidProcSetting, IsoAdvanced ), DEFINE_PROP_ITEM( CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOSTABILIZATION, CExtendedProperty, VideoStabilization ), 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_RELATIVEPANELOPTIMIZATION, CExtendedProperty, RelativePanel) }; //-------------------------------------------------------------- -// Legacy Camera Contorl properties +// Legacy Camera Control properties DEFINE_KSPROPERTY_TABLE(CameraControlPropertyTable) { DEFINE_PROP_ITEM_WITH_VALUES(CCaptureFilter, KSPROPERTY_CAMERACONTROL_EXPOSURE, KSPROPERTY_CAMERACONTROL_S, Exposure, &ExposureValues), diff --git a/avstream/avscamera/sys/Capture.cpp b/avstream/avscamera/sys/Capture.cpp index e5d43ddd..25e6a5f8 100644 --- a/avstream/avscamera/sys/Capture.cpp +++ b/avstream/avscamera/sys/Capture.cpp @@ -266,7 +266,7 @@ Return Value: (m_Pin->ConnectionFormat))->ImageInfoHeader); m_VideoInfoHeader = reinterpret_cast <PKS_VIDEOINFOHEADER> ( - ExAllocatePoolWithTag ( + ExAllocatePoolZero ( NonPagedPoolNx, max(sizeof(KS_VIDEOINFOHEADER), ConnectionHeader->biSize + KS_SIZE_PREHEADER), AVSHWS_POOLTAG @@ -308,7 +308,7 @@ Return Value: VideoInfoHeader); m_VideoInfoHeader = reinterpret_cast <PKS_VIDEOINFOHEADER> ( - ExAllocatePoolWithTag ( + ExAllocatePoolZero ( NonPagedPoolNx, max(sizeof(KS_VIDEOINFOHEADER), KS_SIZE_VIDEOHEADER (ConnectionHeader)), AVSHWS_POOLTAG @@ -339,7 +339,7 @@ Return Value: VideoInfoHeader2); m_VideoInfoHeader = reinterpret_cast <PKS_VIDEOINFOHEADER> ( - ExAllocatePoolWithTag( + ExAllocatePoolZero( NonPagedPoolNx, max(sizeof(KS_VIDEOINFOHEADER), ConnectionHeader->bmiHeader.biSize + KS_SIZE_PREHEADER), AVSHWS_POOLTAG @@ -2100,7 +2100,18 @@ Return Value: { PAGED_CODE( ); + // If the host process did not stop the pin, we need to do that before + // the CCapturePin object gets freed. + if (m_Pin->DeviceState != KSSTATE_STOP) + { + // Skip straight to the STOP state because our simulation doesn't + // really need the PAUSE and ACQUIRE transitions when stopping. + SetState(KSSTATE_STOP, m_Pin->DeviceState); + } + // Some reasonable default behavior. + GetFilter()->setPin(nullptr, m_Pin->Id); + return STATUS_SUCCESS; } diff --git a/avstream/avscamera/sys/Common.h b/avstream/avscamera/sys/Common.h index fdcb1c48..7cde102f 100644 --- a/avstream/avscamera/sys/Common.h +++ b/avstream/avscamera/sys/Common.h @@ -23,11 +23,15 @@ #define _NO_SYS_GUID_OPERATOR_EQ_ +#ifdef NTDDI_VERSION +#undef NTDDI_VERSION +#endif //NTDDI_VERSION +#define NTDDI_VERSION NTDDI_WIN10_VB + #include <stdio.h> #include <stdlib.h> #include <wdm.h> -#include <wdmguid.h> #include <windef.h> #include <unknown.h> #include <ks.h> diff --git a/avstream/avscamera/sys/Device.cpp b/avstream/avscamera/sys/Device.cpp index 99bc60ce..2741da08 100644 --- a/avstream/avscamera/sys/Device.cpp +++ b/avstream/avscamera/sys/Device.cpp @@ -33,6 +33,10 @@ #pragma code_seg("PAGE") #endif // ALLOC_PRAGMA +#ifndef DEVPKEY_Device_PanelId +DEFINE_DEVPROPKEY(DEVPKEY_Device_PanelId, 0x8dbc9c86, 0x97a9, 0x4bff, 0x9b, 0xc6, 0xbf, 0xe9, 0x5d, 0x3e, 0x6d, 0xad, 2); // DEVPROP_TYPE_STRING +#endif + CCaptureDevice:: CCaptureDevice ( _In_ PKSDEVICE Device @@ -616,9 +620,12 @@ Return Value: pld.Revision = 2; pld.Panel = m_Context[i].AcpiPosition; pld.Rotation = m_Context[i].AcpiRotation; - static - const - GUID FFC_Filter = {STATIC_FrontCamera_Filter}; + pld.CabinetNumber = 0; + WCHAR PanelId[MAX_PATH] = { 0 }; + size_t cchDest = MAX_PATH; + + IFFAILED_EXIT( + RtlStringCchPrintfW(PanelId, cchDest, L"{00000000-0000-0000-ffff-ffffffffffff}\\%04X\\%u", pld.CabinetNumber, PnpAcpiPanelSideMap[pld.Panel])); IFFAILED_EXIT( IoSetDeviceInterfacePropertyData(SymbolicLinkName, @@ -629,6 +636,15 @@ Return Value: sizeof(pld), (PVOID)&pld) ); + + // Also set Panel ID manually, because PnP does not do this for the interface currently + IoSetDeviceInterfacePropertyData(SymbolicLinkName, + &DEVPKEY_Device_PanelId, + LOCALE_NEUTRAL, + PLUGPLAY_PROPERTY_PERSISTENT, + DEVPROP_TYPE_STRING, + (ULONG)(wcslen(PanelId)+1)*sizeof(WCHAR), + (PVOID)PanelId); } // On a real device this object would be constructed whenever the sensor hardware is ready... diff --git a/avstream/avscamera/sys/Device.h b/avstream/avscamera/sys/Device.h index 95debada..c203f70e 100644 --- a/avstream/avscamera/sys/Device.h +++ b/avstream/avscamera/sys/Device.h @@ -34,6 +34,17 @@ struct CSensorContext AcpiPldRotation AcpiRotation; // How the device is oriented with respect to the panel. }; +static constexpr ULONG PnpAcpiPanelSideMap[] +{ + 1, // AcpiPldPanelTop + 2, // AcpiPldPanelBottom + 3, // AcpiPldPanelLeft + 4, // AcpiPldPanelRight + 5, // AcpiPldPanelFront + 6, // AcpiPldPanelBack + 0, // AcpiPldPanelUnknown +}; + class CCaptureDevice { protected: @@ -393,7 +404,7 @@ public: PDEVICE_OBJECT GetDeviceObject(); - static IO_COMPLETION_ROUTINE CCaptureDevice::IrpSynchronousCompletion; + static IO_COMPLETION_ROUTINE IrpSynchronousCompletion; virtual NTSTATUS diff --git a/avstream/avscamera/sys/PreviewHwSim.cpp b/avstream/avscamera/sys/PreviewHwSim.cpp index 775c6b8d..f55ffa20 100644 --- a/avstream/avscamera/sys/PreviewHwSim.cpp +++ b/avstream/avscamera/sys/PreviewHwSim.cpp @@ -40,6 +40,7 @@ CPreviewHardwareSimulation::CPreviewHardwareSimulation( _In_ LONG PinID ) : CHardwareSimulation( Sensor, PinID ) + , m_Illuminated(FALSE) { PAGED_CODE(); } @@ -299,6 +300,11 @@ Return Value: BytesLeft -= sizeof(CAMERA_METADATA_INTRINSICS); } + // TODO: This metadata should only be exposed on a sensor category preview pin. + // It's possible I should derive a new preview sim to handle this; but for now + // we just populate the IR illumination state on every preview pin. Hopefully + // the app is smart enough to realize that this is meaningless if they have not + // selected an IR mediatype. if (BytesLeft >= sizeof(KSCAMERA_METADATA_FRAMEILLUMINATION)) { PKSCAMERA_METADATA_FRAMEILLUMINATION pPreviewIllumination = @@ -308,7 +314,31 @@ Return Value: pPreviewIllumination->Header.MetadataId = (ULONG)MetadataId_FrameIllumination; pPreviewIllumination->Header.Size = sizeof(KSCAMERA_METADATA_FRAMEILLUMINATION); - pPreviewIllumination->Flags = KSCAMERA_METADATA_FRAMEILLUMINATION_FLAG_ON; + // Toggle the Illumination state for an IR frame. + CExtendedVidProcSetting State; + (void) m_Sensor->GetIRTorch(&State); + + if (State.Flags & KSCAMERA_EXTENDEDPROP_IRTORCHMODE_ALWAYS_ON) + { + m_Illuminated = TRUE; + pPreviewIllumination->Flags = KSCAMERA_METADATA_FRAMEILLUMINATION_FLAG_ON; + } + else if ((State.Flags & KSCAMERA_EXTENDEDPROP_IRTORCHMODE_ALTERNATING_FRAME_ILLUMINATION)) + { + m_Illuminated = !m_Illuminated; + if (m_Illuminated) + { + pPreviewIllumination->Flags = KSCAMERA_METADATA_FRAMEILLUMINATION_FLAG_ON; + } + } + else + { + m_Illuminated = FALSE; + } + + DBG_TRACE("Frame Illumination: Flags=0x%016llX, State=%s", + State.Flags, + (pPreviewIllumination->Flags==KSCAMERA_METADATA_FRAMEILLUMINATION_FLAG_ON ?"ON":"OFF")); pMetadata->UsedSize += sizeof(KSCAMERA_METADATA_FRAMEILLUMINATION); BytesLeft -= sizeof(KSCAMERA_METADATA_FRAMEILLUMINATION); diff --git a/avstream/avscamera/sys/PreviewHwSim.h b/avstream/avscamera/sys/PreviewHwSim.h index e5a4f536..1d26f692 100644 --- a/avstream/avscamera/sys/PreviewHwSim.h +++ b/avstream/avscamera/sys/PreviewHwSim.h @@ -43,7 +43,6 @@ public: protected: METADATA_PREVIEWAGGREGATION - CPreviewHardwareSimulation:: GetMetadata(); VOID GetCaptureStats( @@ -57,5 +56,8 @@ protected: _Inout_ PKSSTREAM_HEADER pStreamHeader ); +private: + BOOLEAN m_Illuminated; + }; diff --git a/avstream/avscamera/sys/Sensor.cpp b/avstream/avscamera/sys/Sensor.cpp index 9215f6b6..654ea666 100644 --- a/avstream/avscamera/sys/Sensor.cpp +++ b/avstream/avscamera/sys/Sensor.cpp @@ -188,7 +188,7 @@ Initialize() m_InterruptTime[i] = 0; m_LastMappingsCompleted[i] = 0; } - return STATUS_SUCCESS; + return m_Device ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER; } void @@ -356,7 +356,7 @@ CreateSynthesizer( if( NT_SUCCESS( Status ) ) { - DBG_TRACE( "Setting Mounting Orientation to %d�", DbgRotation2Degrees(m_MountingOrientation) ) + DBG_TRACE( "Setting Mounting Orientation to %d°", DbgRotation2Degrees(m_MountingOrientation) ) m_Synthesizer[ Pin->Id ]->SetRotation( m_MountingOrientation ); } @@ -412,15 +412,17 @@ Return Value: NTSTATUS Status = STATUS_SUCCESS; LONG lPindex = Pin->Id; + + // Hold off all image generation while we manipulate the capture pin and synthensizer arrays. + KScopedMutex Lock(m_SensorMutex); + // // If we're the first pin to go into acquire (remember we can have // a filter in another graph going simultaneously), grab the resources for Preview // - if( InterlockedCompareExchangePointer( - (PVOID *) &m_CapturePin[lPindex], - CapturePin, - nullptr) == nullptr) + if (m_CapturePin[lPindex] == nullptr) { + m_CapturePin[lPindex] = CapturePin; m_VideoInfoHeader[lPindex] = VideoInfoHeader; // @@ -449,7 +451,6 @@ Return Value: // // If everything has succeeded thus far, set the capture pin. // - m_CapturePin[lPindex] = CapturePin; *pSim = m_HardwareSimulation[lPindex]; } @@ -460,6 +461,8 @@ Return Value: // acquired. // ReleaseHardwareResources(Pin); + *pSim = nullptr; + m_CapturePin[lPindex] = nullptr; } } else @@ -1088,20 +1091,23 @@ Return Value: void CSensor:: -SetSynthesizerAttribute( - CSynthesizer::Attribute Attrib, - LONGLONG Info, - LONG PinId +SetSynthesizerAttributeList( + _In_ size_t Count, + _In_ SynthesizerAttributeEntry AttributeList[] ) { PAGED_CODE(); - - for( ULONG Pin=0; IsValidIndex(Pin); Pin++ ) + // Syncrhonize access to sensor. + KScopedMutex Lock(m_SensorMutex); + for (size_t item = 0; item < Count; item++) { - if( (Pin==(ULONG)PinId || IsStillIndex(Pin)) && - m_Synthesizer[Pin] ) + for (ULONG Pin = 0; IsValidIndex(Pin); Pin++) { - m_Synthesizer[Pin]->Set( Attrib, Info ); + if ((Pin == (ULONG)AttributeList[item].PinId || IsStillIndex(Pin)) && + m_Synthesizer[Pin]) + { + m_Synthesizer[Pin]->Set(AttributeList[item].Attrib, AttributeList[item].Info); + } } } } @@ -1140,11 +1146,15 @@ Return Value: DBG_ENTER( "( Pin=%d )\n", Pin->Id ) ; LONG lPindex = Pin->Id; + // // Blow away the image synth. // m_HardwareSimulation[lPindex]->Reset(); + // Hold off all image generation while we free the capture pin and synthensizer arrays. + KScopedMutex Lock(m_SensorMutex); + SAFE_DELETE( m_Synthesizer[lPindex] ); m_VideoInfoHeader[lPindex] = NULL; @@ -1152,10 +1162,7 @@ Return Value: // Release our "lock" on hardware resources. This will allow another // pin (perhaps in another graph) to acquire them. // - InterlockedExchangePointer( - (PVOID *) &(m_CapturePin[lPindex]), - nullptr - ); + m_CapturePin[lPindex] = nullptr; DBG_LEAVE( "( Pin=%d )\n", Pin->Id ) ; } @@ -1322,6 +1329,7 @@ DEFINE_NULL_PROPERTY_GET(CSensor, KSPROPERTY_CAMERACONTROL_IMAGE_PIN_CAPABILITY_ DEFINE_NULL_PROPERTY(CSensor, CExtendedProperty, TriggerTime) DEFINE_NULL_PROPERTY(CSensor, CExtendedProperty, TorchMode) +DEFINE_NULL_PROPERTY(CSensor, CExtendedVidProcSetting, IRTorch) DEFINE_NULL_PROPERTY(CSensor, CExtendedProperty, ExtendedFlash) DEFINE_NULL_PROPERTY_GET(CSensor, CExtendedProperty, PhotoFrameRate) @@ -1352,6 +1360,7 @@ 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, CExtendedProperty, RelativePanel) 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 327b860a..31b0f3a2 100644 --- a/avstream/avscamera/sys/Sensor.h +++ b/avstream/avscamera/sys/Sensor.h @@ -517,8 +517,18 @@ public: m_MountingOrientation = Orientation; } + struct SynthesizerAttributeEntry + { + CSynthesizer::Attribute Attrib; + LONGLONG Info; + LONG PinId; + }; + void - SetSynthesizerAttribute( CSynthesizer::Attribute Attrib, LONGLONG Info, LONG PinId ); + SetSynthesizerAttributeList( + _In_ size_t Count, + _In_ SynthesizerAttributeEntry AttributeList[] + ); protected: LONG @@ -554,6 +564,7 @@ public: DECLARE_PROPERTY( CExtendedProperty, TriggerTime ); DECLARE_PROPERTY( CExtendedProperty, TorchMode ); + DECLARE_PROPERTY( CExtendedVidProcSetting, IRTorch ); DECLARE_PROPERTY_ASYNC( CExtendedVidProcSetting, Focus ); DECLARE_PROPERTY_ASYNC( CExtendedProperty, Iso ); @@ -576,6 +587,7 @@ public: DECLARE_PROPERTY( CExtendedProperty, AdvancedPhoto ); DECLARE_PROPERTY( CExtendedVidProcSetting, FaceDetection ); DECLARE_PROPERTY( CExtendedProperty, VideoTemporalDenoising); + DECLARE_PROPERTY( CExtendedProperty, RelativePanel); DECLARE_PROPERTY_VARSIZE_ASYNC( CRoiProperty, Roi ); diff --git a/avstream/avscamera/sys/SensorSimulation.cpp b/avstream/avscamera/sys/SensorSimulation.cpp index 6ecd9007..e60372c1 100644 --- a/avstream/avscamera/sys/SensorSimulation.cpp +++ b/avstream/avscamera/sys/SensorSimulation.cpp @@ -331,6 +331,15 @@ Return Value: } m_TorchMode.Flags = KSCAMERA_EXTENDEDPROP_VIDEOTORCH_OFF; m_TorchMode = 50UL; + m_IRTorch.Flags = KSCAMERA_EXTENDEDPROP_IRTORCHMODE_ALWAYS_ON; + m_IRTorch.Capability = + KSCAMERA_EXTENDEDPROP_IRTORCHMODE_OFF | + KSCAMERA_EXTENDEDPROP_IRTORCHMODE_ALWAYS_ON | + KSCAMERA_EXTENDEDPROP_IRTORCHMODE_ALTERNATING_FRAME_ILLUMINATION; + m_IRTorch = 100UL; + m_IRTorch.Min() = 20; + m_IRTorch.Max() = 100; + m_IRTorch.Step() = 5; m_OptimizationHint.Flags = KSCAMERA_EXTENDEDPROP_OPTIMIZATION_PHOTO; @@ -471,6 +480,14 @@ Return Value: m_PowerLineFreq.Value = POWERLINEFREQ_DEFAULT; m_PowerLineFreq.Flags = KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL; + // Set up our relative panel. + m_RelativePanel.Capability = + KSCAMERA_EXTENDEDPROP_RELATIVEPANELOPTIMIZATION_ON | + KSCAMERA_EXTENDEDPROP_RELATIVEPANELOPTIMIZATION_OFF | + KSCAMERA_EXTENDEDPROP_RELATIVEPANELOPTIMIZATION_DYNAMIC; + m_RelativePanel.Flags = KSCAMERA_EXTENDEDPROP_RELATIVEPANELOPTIMIZATION_OFF; + m_RelativePanel = (ULONG)AcpiPldPanelUnknown; + m_IsoResult = STATUS_SUCCESS; m_EvCompResult = STATUS_SUCCESS; m_WhiteBalanceResult= STATUS_SUCCESS; @@ -1791,6 +1808,40 @@ SetOpticalImageStabilization( return STATUS_SUCCESS; } +// Get KSPROPERTY_CAMERACONTROL_EXTENDED_RELATIVEPANEL. +NTSTATUS +CSensorSimulation:: +GetRelativePanel( + _Inout_ CExtendedProperty *pProperty +) +{ + PAGED_CODE(); + KScopedMutex lock(m_SensorMutex); + + *pProperty = m_RelativePanel; + pProperty->Flags = m_RelativePanel.Flags; + pProperty->Capability = KSCAMERA_EXTENDEDPROP_RELATIVEPANELOPTIMIZATION_ON | + KSCAMERA_EXTENDEDPROP_RELATIVEPANELOPTIMIZATION_OFF | + KSCAMERA_EXTENDEDPROP_RELATIVEPANELOPTIMIZATION_DYNAMIC; + + return STATUS_SUCCESS; +} + +// Set KSPROPERTY_CAMERACONTROL_EXTENDED_RELATIVEPANEL. +NTSTATUS +CSensorSimulation:: +SetRelativePanel( + _In_ CExtendedProperty *pProperty +) +{ + PAGED_CODE(); + KScopedMutex lock(m_SensorMutex); + + m_RelativePanel = *pProperty; + m_RelativePanel.Flags = pProperty->Flags; + return STATUS_SUCCESS; +} + // Get KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOTEMPORALDENOISING. NTSTATUS CSensorSimulation:: @@ -3024,6 +3075,37 @@ SetTorchMode( return STATUS_SUCCESS; } +// Get KSPROPERTY_CAMERACONTROL_EXTENDED_IRTORCHMODE +NTSTATUS +CSensorSimulation:: +GetIRTorch( + _Inout_ CExtendedVidProcSetting *pTorch +) +{ + PAGED_CODE(); + KScopedMutex lock(m_SensorMutex); + + *pTorch = m_IRTorch; + return STATUS_SUCCESS; +} + +// Set KSPROPERTY_CAMERACONTROL_EXTENDED_IRTORCHMODE +NTSTATUS +CSensorSimulation:: +SetIRTorch( + _In_ CExtendedVidProcSetting *pTorch +) +{ + PAGED_CODE(); + KScopedMutex lock(m_SensorMutex); + + // Only overwrite the IR Torch Flags and value. + m_IRTorch.Flags = pTorch->Flags; + m_IRTorch = pTorch->GetULONG(); + + return STATUS_SUCCESS; +} + // Get KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOMODE NTSTATUS CSensorSimulation:: diff --git a/avstream/avscamera/sys/SensorSimulation.h b/avstream/avscamera/sys/SensorSimulation.h index a2dd1fe7..6124762c 100644 --- a/avstream/avscamera/sys/SensorSimulation.h +++ b/avstream/avscamera/sys/SensorSimulation.h @@ -50,6 +50,7 @@ protected: ULONG m_FaceDetectionCurrentMax; ULONGLONG m_SceneMode; CExtendedProperty m_TorchMode; + CExtendedVidProcSetting m_IRTorch; CExtendedProperty m_OptimizationHint; CExtendedMetadata *m_MetadataInfo; PKSCAMERA_PERFRAMESETTING_HEADER m_pPerFrameSettings; @@ -61,7 +62,8 @@ protected: ULONGLONG m_Histogram; ULONGLONG m_OpticalImageStabilization; ULONGLONG m_VideoTemporalDenoising; - CExtendedProperty m_AdvancedPhoto; + CExtendedProperty m_RelativePanel; + CExtendedProperty m_AdvancedPhoto; CWhiteBalanceRoiIspControl m_RoiWhiteBalance; CExposureRoiIspControl m_RoiExposureMode; @@ -207,6 +209,7 @@ public: DECLARE_PROPERTY_GET( KSPROPERTY_CAMERACONTROL_IMAGE_PIN_CAPABILITY_S, PinDependence ); DECLARE_PROPERTY( CExtendedProperty, TriggerTime ); DECLARE_PROPERTY( CExtendedProperty, TorchMode ); + DECLARE_PROPERTY( CExtendedVidProcSetting, IRTorch ); DECLARE_PROPERTY( CExtendedProperty, ExtendedFlash ); @@ -236,6 +239,7 @@ public: DECLARE_PROPERTY_GET( CExtendedFieldOfView, FieldOfView ); DECLARE_PROPERTY_GET( CExtendedCameraAngleOffset, CameraAngleOffset ); DECLARE_PROPERTY( CExtendedProperty, VideoTemporalDenoising); + DECLARE_PROPERTY( CExtendedProperty, RelativePanel); DECLARE_PROPERTY_VARSIZE_ASYNC_NOCANCEL( CRoiProperty, Roi ); @@ -288,4 +292,4 @@ const LONG WHITEBALANCE_DEF = 5000; const LONG EXPOSURE_BILOG_MIN = -10; const LONG EXPOSURE_BILOG_MAX = 9; const LONG EXPOSURE_BILOG_STEP = 1; -const LONG EXPOSURE_BILOG_DEF = -5;
\ No newline at end of file +const LONG EXPOSURE_BILOG_DEF = -5; diff --git a/avstream/avscamera/sys/VideoHwSim.cpp b/avstream/avscamera/sys/VideoHwSim.cpp index 33b6de90..839af530 100644 --- a/avstream/avscamera/sys/VideoHwSim.cpp +++ b/avstream/avscamera/sys/VideoHwSim.cpp @@ -27,6 +27,7 @@ CVideoHardwareSimulation::CVideoHardwareSimulation( _In_ LONG PinID ) : CHardwareSimulation( Sensor, PinID ) + , m_Illuminated(FALSE) {} @@ -50,6 +51,54 @@ EmitMetadata( if (0 != (pStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_METADATA)) { + PKS_FRAME_INFO pFrameInfo = (PKS_FRAME_INFO)(pStreamHeader + 1); + PKSSTREAM_METADATA_INFO pMetadata = (PKSSTREAM_METADATA_INFO)(pFrameInfo + 1); + ULONG BytesLeft = pMetadata->BufferSize - pMetadata->UsedSize; + + // TODO: This metadata should only be exposed on a sensor category preview pin. + // It's possible I should derive a new preview sim to handle this; but for now + // we just populate the IR illumination state on every preview pin. Hopefully + // the app is smart enough to realize that this is meaningless if they have not + // selected an IR mediatype. + if (BytesLeft >= sizeof(KSCAMERA_METADATA_FRAMEILLUMINATION)) + { + PKSCAMERA_METADATA_FRAMEILLUMINATION pPreviewIllumination = + (PKSCAMERA_METADATA_FRAMEILLUMINATION)(((PBYTE)pMetadata->SystemVa) + pMetadata->UsedSize); + RtlZeroMemory(pPreviewIllumination, sizeof(KSCAMERA_METADATA_FRAMEILLUMINATION)); + + pPreviewIllumination->Header.MetadataId = (ULONG)MetadataId_FrameIllumination; + pPreviewIllumination->Header.Size = sizeof(KSCAMERA_METADATA_FRAMEILLUMINATION); + + // Toggle the Illumination state for an IR frame. + CExtendedVidProcSetting State; + (void)m_Sensor->GetIRTorch(&State); + + if (State.Flags & KSCAMERA_EXTENDEDPROP_IRTORCHMODE_ALWAYS_ON) + { + m_Illuminated = TRUE; + pPreviewIllumination->Flags = KSCAMERA_METADATA_FRAMEILLUMINATION_FLAG_ON; + } + else if ((State.Flags & KSCAMERA_EXTENDEDPROP_IRTORCHMODE_ALTERNATING_FRAME_ILLUMINATION)) + { + m_Illuminated = !m_Illuminated; + if (m_Illuminated) + { + pPreviewIllumination->Flags = KSCAMERA_METADATA_FRAMEILLUMINATION_FLAG_ON; + } + } + else + { + m_Illuminated = FALSE; + } + + DBG_TRACE("Frame Illumination: Flags=0x%016llX, State=%s", + State.Flags, + (pPreviewIllumination->Flags == KSCAMERA_METADATA_FRAMEILLUMINATION_FLAG_ON ? "ON" : "OFF")); + + pMetadata->UsedSize += sizeof(KSCAMERA_METADATA_FRAMEILLUMINATION); + BytesLeft -= sizeof(KSCAMERA_METADATA_FRAMEILLUMINATION); + } + CExtendedVidProcSetting FaceDetect; m_Sensor->GetFaceDetection(&FaceDetect); diff --git a/avstream/avscamera/sys/VideoHwSim.h b/avstream/avscamera/sys/VideoHwSim.h index 40b0b24b..a576d9a1 100644 --- a/avstream/avscamera/sys/VideoHwSim.h +++ b/avstream/avscamera/sys/VideoHwSim.h @@ -38,5 +38,9 @@ public: EmitMetadata( _Inout_ PKSSTREAM_HEADER pStreamHeader ); + +private: + BOOLEAN m_Illuminated; + }; diff --git a/avstream/avscamera/sys/avscamera.inf b/avstream/avscamera/sys/avscamera.inx Binary files differindex 2a17a764..f6f1e846 100644 --- a/avstream/avscamera/sys/avscamera.inf +++ b/avstream/avscamera/sys/avscamera.inx diff --git a/avstream/avscamera/sys/filter.cpp b/avstream/avscamera/sys/filter.cpp index 2680f503..dfb6ce1f 100644 --- a/avstream/avscamera/sys/filter.cpp +++ b/avstream/avscamera/sys/filter.cpp @@ -64,6 +64,7 @@ Return Value: m_pCaptureDevice(NULL), m_pPerFrameSettings(nullptr), m_pinArray(nullptr), + m_pMinimumRequestedFrames(nullptr), m_PhotoModeNotifier( Filter, &KSEVENTSETID_ExtendedCameraControl, KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOMODE ), m_PhotoMaxFrameRateNotifier( Filter, &KSEVENTSETID_ExtendedCameraControl, KSPROPERTY_CAMERACONTROL_EXTENDED_PHOTOMAXFRAMERATE) , m_FocusNotifier( Filter, &KSEVENTSETID_ExtendedCameraControl, KSPROPERTY_CAMERACONTROL_EXTENDED_FOCUSMODE ), @@ -141,10 +142,12 @@ Return Value: IFFAILED_EXIT( m_Sensor->AddFilter(m_pKSFilter) ); IFNULL_EXIT(m_pinArray = new (PagedPool, 'sniP') CCapturePin *[m_Sensor->GetPinCount()]); + IFNULL_EXIT(m_pMinimumRequestedFrames = new (PagedPool, 'sniP') ULONG[m_Sensor->GetPinCount()]); for( ULONG i=0; i<m_Sensor->GetPinCount(); i++ ) { m_pinArray[i] = nullptr; + m_pMinimumRequestedFrames[i] = IMAGE_CAPTURE_PIN_MINIMUM_FRAMES; } done: @@ -209,6 +212,7 @@ CCaptureFilter::~CCaptureFilter() // may need to have some things reset. m_Sensor->Reset(); + delete [] m_pMinimumRequestedFrames; delete [] m_pinArray; DBG_LEAVE("(%S)", Name); @@ -352,6 +356,11 @@ Return Value: // Take out a weak reference to the pin object. m_pinArray[Id] = pPin; + if (m_pinArray[Id] != nullptr) + { + m_pinArray[Id]->SetDesiredFrames(m_pMinimumRequestedFrames[Id]); + (void)m_pinArray[Id]->UpdateAllocatorFraming(); + } } CCapturePin * @@ -391,7 +400,8 @@ Return Value: NTSTATUS CCaptureFilter:: UpdateAllocatorFraming( - _In_ ULONG PinId + _In_ ULONG PinId, + _In_ ULONG DesiredFrames ) /*++ @@ -412,15 +422,20 @@ Return Value: { PAGED_CODE(); - NTSTATUS Status = STATUS_INVALID_PARAMETER; + NTSTATUS Status = STATUS_SUCCESS; // Acquire the lock and update the Pin's allocator framing. LockFilter Lock(m_pKSFilter); if( m_pinArray[PinId] ) { + m_pinArray[PinId]->SetDesiredFrames(DesiredFrames); Status = m_pinArray[PinId]->UpdateAllocatorFraming(); } + else + { + m_pMinimumRequestedFrames[PinId] = DesiredFrames; + } DBG_LEAVE("()=0x%08X",Status); return Status; @@ -636,6 +651,7 @@ SetPhotoMode( PAGED_CODE(); NTSTATUS Status = STATUS_INVALID_PARAMETER; + ULONG TotalFrames = IMAGE_CAPTURE_PIN_MINIMUM_FRAMES; DBG_ENTER( "()" ); @@ -645,10 +661,6 @@ SetPhotoMode( { CExtendedPhotoMode Caps(*pMode); Status = m_Sensor->GetPhotoMode( &Caps ); - CCapturePin *pPin = getPin(pMode->PinId); - - // Should always be valid. - NT_ASSERT(pPin); if( NT_SUCCESS(Status) ) { @@ -686,7 +698,7 @@ SetPhotoMode( // Assume the normal photo sequence case. // For normal photo sequence, we provide history frames +1 or at least a minimum of 3 frames. - ULONG TotalFrames = pMode->RequestedHistoryFrames() + 1; + TotalFrames = pMode->RequestedHistoryFrames() + 1; // Modify TotalFrames for the VPS case. // For VPS, we need LoopCount * FrameCount; but limit by the minimum(3) and maximum (20) frames. @@ -708,14 +720,12 @@ SetPhotoMode( DBG_TRACE( "Advertising Framing requirement: %d", TotalFrames ); - pPin->SetDesiredFrames(TotalFrames); Status = STATUS_SUCCESS; break; } case KSCAMERA_EXTENDEDPROP_PHOTOMODE_NORMAL: { // Set it back to the minimum number of frames. - pPin->SetDesiredFrames(IMAGE_CAPTURE_PIN_MINIMUM_FRAMES); Status = STATUS_SUCCESS; break; } @@ -724,7 +734,7 @@ SetPhotoMode( // Update allocator framing. if( NT_SUCCESS( Status ) ) { - Status = UpdateAllocatorFraming( pMode->PinId ); + Status = UpdateAllocatorFraming( pMode->PinId, TotalFrames ); } // Update the sensor object... @@ -1118,13 +1128,13 @@ GetTorchMode( NTSTATUS Status = STATUS_INVALID_PARAMETER; - if( pTorchMode->isValid() && - pTorchMode->PinId == KSCAMERA_EXTENDEDPROP_FILTERSCOPE ) + if (pTorchMode->isValid() && + pTorchMode->PinId == KSCAMERA_EXTENDEDPROP_FILTERSCOPE) { - Status = m_Sensor->GetTorchMode( pTorchMode ); + Status = m_Sensor->GetTorchMode(pTorchMode); } DBG_LEAVE("(PinId=%d, Flags=0x%016llX, Cap=0x%016llX)=0x%08X", - pTorchMode->PinId, pTorchMode->Flags, pTorchMode->Capability, Status ); + pTorchMode->PinId, pTorchMode->Flags, pTorchMode->Capability, Status); return Status; } @@ -1139,34 +1149,101 @@ SetTorchMode( NTSTATUS Status = STATUS_INVALID_PARAMETER; - if( !(pTorchMode->Capability & KSCAMERA_EXTENDEDPROP_CAPS_ASYNCCONTROL) && - pTorchMode->isValid() && - pTorchMode->PinId == KSCAMERA_EXTENDEDPROP_FILTERSCOPE && - pTorchMode->m_Value.Value.ul <= 100 ) + if (!(pTorchMode->Capability & KSCAMERA_EXTENDEDPROP_CAPS_ASYNCCONTROL) && + pTorchMode->isValid() && + pTorchMode->PinId == KSCAMERA_EXTENDEDPROP_FILTERSCOPE && + pTorchMode->m_Value.Value.ul <= 100) { CExtendedProperty Caps(*pTorchMode); Status = m_Sensor->GetTorchMode(&Caps); - if( NT_SUCCESS(Status) ) + if (NT_SUCCESS(Status)) { // Assume an invalid parameter. Status = STATUS_INVALID_PARAMETER; - if( pTorchMode->Flags == (pTorchMode->Flags & Caps.Capability) ) + if (pTorchMode->Flags == (pTorchMode->Flags & Caps.Capability)) { - switch( pTorchMode->Flags ) + switch (pTorchMode->Flags) { case KSCAMERA_EXTENDEDPROP_VIDEOTORCH_OFF: case KSCAMERA_EXTENDEDPROP_VIDEOTORCH_ON: case KSCAMERA_EXTENDEDPROP_VIDEOTORCH_ON_ADJUSTABLEPOWER: - Status = m_Sensor->SetTorchMode( pTorchMode ); + Status = m_Sensor->SetTorchMode(pTorchMode); break; } } } } DBG_LEAVE("(PinId=%d, Flags=0x%016llX, Cap=0x%016llX)=0x%08X", - pTorchMode->PinId, pTorchMode->Flags, pTorchMode->Capability, Status ); + pTorchMode->PinId, pTorchMode->Flags, pTorchMode->Capability, Status); + return Status; +} + +// Get KSPROPERTY_CAMERACONTROL_EXTENDED_IRTORCHMODE +NTSTATUS +CCaptureFilter:: +GetIRTorch( + _Inout_ CExtendedVidProcSetting *pTorch +) +{ + PAGED_CODE(); + + NTSTATUS Status = STATUS_INVALID_PARAMETER; + + if (pTorch->isValid() && + pTorch->PinId == KSCAMERA_EXTENDEDPROP_FILTERSCOPE) + { + Status = m_Sensor->GetIRTorch(pTorch); + } + DBG_LEAVE("(PinId=%d, Flags=0x%016llX, Cap=0x%016llX)=0x%08X", + pTorch->PinId, pTorch->Flags, pTorch->Capability, Status); + return Status; +} + +// Set KSPROPERTY_CAMERACONTROL_EXTENDED_IRTORCHMODE +NTSTATUS +CCaptureFilter:: +SetIRTorch( + _In_ CExtendedVidProcSetting *pTorch +) +{ + PAGED_CODE(); + + NTSTATUS Status = STATUS_INVALID_PARAMETER; + + if (!(pTorch->Capability & KSCAMERA_EXTENDEDPROP_CAPS_ASYNCCONTROL) && + pTorch->isValid() && + pTorch->PinId == KSCAMERA_EXTENDEDPROP_FILTERSCOPE) + { + CExtendedVidProcSetting Caps(*pTorch); + Status = m_Sensor->GetIRTorch(&Caps); + + if (NT_SUCCESS(Status)) + { + Status = Caps.BoundsCheck(pTorch->GetULONG()); + + if (NT_SUCCESS(Status)) + { + // Assume an invalid parameter. + Status = STATUS_INVALID_PARAMETER; + + if (pTorch->Flags == (pTorch->Flags & Caps.Capability)) + { + switch (pTorch->Flags) + { + case KSCAMERA_EXTENDEDPROP_IRTORCHMODE_OFF: + case KSCAMERA_EXTENDEDPROP_IRTORCHMODE_ALWAYS_ON: + case KSCAMERA_EXTENDEDPROP_IRTORCHMODE_ALTERNATING_FRAME_ILLUMINATION: + Status = m_Sensor->SetIRTorch(pTorch); + break; + } + } + } + } + } + DBG_LEAVE("(PinId=%d, Flags=0x%016llX, Cap=0x%016llX)=0x%08X", + pTorch->PinId, pTorch->Flags, pTorch->Capability, Status); return Status; } @@ -3494,6 +3571,66 @@ SetOpticalImageStabilization( return Status; } +// Get KSPROPERTY_CAMERACONTROL_EXTENDED_RELATIVEPANEL. +NTSTATUS +CCaptureFilter:: +GetRelativePanel( + _Inout_ CExtendedProperty *pRelativePanel +) +{ + PAGED_CODE(); + NTSTATUS Status = STATUS_INVALID_PARAMETER; + + if (pRelativePanel->PinId == KSCAMERA_EXTENDEDPROP_FILTERSCOPE && + pRelativePanel->isValid()) + { + //Get the current state + Status = m_Sensor->GetRelativePanel(pRelativePanel); + } + + DBG_TRACE("pRelativePanel = %p, PinId = %u, Flags = %llu, Version = %u", + pRelativePanel, pRelativePanel->PinId, pRelativePanel->Flags, pRelativePanel->Version); + + return Status; +} + +// Set KSPROPERTY_CAMERACONTROL_EXTENDED_RELATIVEPANEL. +NTSTATUS +CCaptureFilter:: +SetRelativePanel( + _In_ CExtendedProperty *pRelativePanel +) +{ + PAGED_CODE(); + + NTSTATUS Status = STATUS_INVALID_PARAMETER; + + // Call must be Filter and flags must be supported and version must be 1 + if (pRelativePanel->PinId == KSCAMERA_EXTENDEDPROP_FILTERSCOPE && + pRelativePanel->isValid() && + (KSCAMERA_EXTENDEDPROP_RELATIVEPANELOPTIMIZATION_ON == pRelativePanel->Flags || + KSCAMERA_EXTENDEDPROP_RELATIVEPANELOPTIMIZATION_OFF == pRelativePanel->Flags)) + { + CExtendedProperty Caps(*pRelativePanel); + Status = m_Sensor->GetRelativePanel(&Caps); + + if (NT_SUCCESS(Status)) + { + // Assume an invalid parameter. + Status = STATUS_INVALID_PARAMETER; + + if (pRelativePanel->Flags == (pRelativePanel->Flags & Caps.Capability)) + { + Status = m_Sensor->SetRelativePanel(pRelativePanel); + } + } + } + DBG_TRACE("pOIS = %p, PinId = %u, Flags = %llu, Version = %u", + pRelativePanel, pRelativePanel->PinId, pRelativePanel->Flags, pRelativePanel->Version); + + return Status; +} + // Get KSPROPERTY_CAMERACONTROL_EXTENDED_ADVANCEDPHOTO. NTSTATUS CCaptureFilter:: diff --git a/avstream/avscamera/sys/filter.h b/avstream/avscamera/sys/filter.h index 292a6bc7..5b272a9d 100644 --- a/avstream/avscamera/sys/filter.h +++ b/avstream/avscamera/sys/filter.h @@ -58,6 +58,7 @@ private: // The AVStream filter object associated with this CCaptureFilter. // CCapturePin **m_pinArray; + ULONG *m_pMinimumRequestedFrames; protected: // @@ -331,7 +332,9 @@ DECLARE_PROPERTY_SET_HANDLER( type, name ) DECLARE_PROPERTY_HANDLERS( CExtendedProperty, Thumbnail ) DECLARE_PROPERTY_HANDLERS( CExtendedProperty, TriggerTime ) DECLARE_PROPERTY_HANDLERS( CExtendedProperty, TorchMode ) + DECLARE_PROPERTY_HANDLERS( CExtendedVidProcSetting, IRTorch ) DECLARE_PROPERTY_HANDLERS( CExtendedProperty, VideoTemporalDenoising) + DECLARE_PROPERTY_HANDLERS( CExtendedProperty, RelativePanel) DECLARE_PROPERTY_HANDLERS( KSPROPERTY_CAMERACONTROL_VIDEOSTABILIZATION_MODE_S, VideoStabMode ) DECLARE_PROPERTY_HANDLERS( KSPROPERTY_CAMERACONTROL_FLASH_S, Flash ) @@ -385,7 +388,7 @@ DECLARE_PROPERTY_SET_HANDLER( type, name ) // Make sure the PERFRAMESETTINGs passed to us are valid. _Success_(return == 0) NTSTATUS - CCaptureFilter::ParsePFSBuffer( + ParsePFSBuffer( _In_reads_bytes_(BufferLimit) PKSCAMERA_PERFRAMESETTING_HEADER pPFS, _In_ ULONG BufferLimit, @@ -434,7 +437,8 @@ DECLARE_PROPERTY_SET_HANDLER( type, name ) // Update the pin's allocator to a specific frame count. NTSTATUS UpdateAllocatorFraming( - _In_ ULONG PinId + _In_ ULONG PinId, + _In_ ULONG DesiredFrames ); private: diff --git a/avstream/avscamera/sys/hwsim.cpp b/avstream/avscamera/sys/hwsim.cpp index 5322cff3..fdf7b367 100644 --- a/avstream/avscamera/sys/hwsim.cpp +++ b/avstream/avscamera/sys/hwsim.cpp @@ -1207,7 +1207,7 @@ Return Value: { PAGED_CODE(); - KScopedMutex Lock( m_ListLock ); + KScopedMutex Lock(m_ListLock); m_InterruptTime++; @@ -1218,10 +1218,10 @@ Return Value: // if (m_PinState == PinRunning) { - LONGLONG Qpc = (LONGLONG) ConvertQPCtoTimeStamp(nullptr); + LONGLONG Qpc = (LONGLONG)ConvertQPCtoTimeStamp(nullptr); LARGE_INTEGER Now; - KeQuerySystemTimePrecise( &Now ); + KeQuerySystemTimePrecise(&Now); // // Generate a "time stamp" just to overlay it onto the capture image. // It makes it more exciting than bars that do nothing. @@ -1230,12 +1230,16 @@ Return Value: // the most recent streaming pin's index. if (!m_Sensor->IsStillIndex(m_PinID)) { + CSensor::SynthesizerAttributeEntry AttributeList[] = + { + { CSynthesizer::FrameNumber, m_InterruptTime, m_PinID }, + { CSynthesizer::RelativePts, (m_InterruptTime + 1) * m_TimePerFrame, m_PinID }, + { CSynthesizer::QpcTime, Qpc, m_PinID } + }; DBG_TRACE("QPC=0x%016llX", Qpc); // Broadcast the preview pin's info to all pin simulations. - m_Sensor->SetSynthesizerAttribute(CSynthesizer::FrameNumber, m_InterruptTime, m_PinID); - m_Sensor->SetSynthesizerAttribute(CSynthesizer::RelativePts, (m_InterruptTime + 1) * m_TimePerFrame, m_PinID); - m_Sensor->SetSynthesizerAttribute(CSynthesizer::QpcTime, Qpc, m_PinID); + m_Sensor->SetSynthesizerAttributeList(SIZEOF_ARRAY(AttributeList), AttributeList); } m_Synthesizer->DoSynthesize(); @@ -1243,13 +1247,13 @@ Return Value: CHAR Text[64]; CExtendedProperty Control; - m_Sensor->GetVideoStabilization( &Control ); + m_Sensor->GetVideoStabilization(&Control); RtlStringCbPrintfA(Text, sizeof(Text), "DVS: %s", DVS_Text(Control.Flags)); - m_Synthesizer->OverlayText( 0, m_Height-38, 1, Text, TRANSPARENT, TEXT_COLOR ); + m_Synthesizer->OverlayText(0, m_Height - 38, 1, Text, TRANSPARENT, TEXT_COLOR); - m_Sensor->GetOpticalImageStabilization( &Control ); + m_Sensor->GetOpticalImageStabilization(&Control); RtlStringCbPrintfA(Text, sizeof(Text), "OIS: %s", OIS_Text(Control.Flags)); - m_Synthesizer->OverlayText( 0, m_Height-48, 1, Text, TRANSPARENT, TEXT_COLOR ); + m_Synthesizer->OverlayText(0, m_Height - 48, 1, Text, TRANSPARENT, TEXT_COLOR); // // Add the Missed frame count @@ -1257,7 +1261,7 @@ Return Value: size_t len = 0; RtlStringCchLengthA(Text, sizeof(Text), &len); m_Synthesizer->OverlayText( - (m_Width - (((ULONG)len*8))), // right-adjust text. + (m_Width - (((ULONG)len * 8))), // right-adjust text. (m_Height - 48), 1, Text, @@ -1268,12 +1272,12 @@ Return Value: // // Add the estimated FPS LONGLONG Target = NANOSECONDS / m_TimePerFrame; - LONGLONG FPS = ((LONGLONG)m_InterruptTime * NANOSECONDS) / ( (Now.QuadPart - m_StartTime.QuadPart) + (NANOSECONDS/2) ); + LONGLONG FPS = ((LONGLONG)m_InterruptTime * NANOSECONDS) / ((Now.QuadPart - m_StartTime.QuadPart) + (NANOSECONDS / 2)); RtlStringCbPrintfA(Text, sizeof(Text), "%lld/%lld FPS", FPS, Target); len = 0; RtlStringCchLengthA(Text, sizeof(Text), &len); - m_Synthesizer->OverlayText ( - (m_Width - (((ULONG)len*8))), // right-adjust text. + m_Synthesizer->OverlayText( + (m_Width - (((ULONG)len * 8))), // right-adjust text. (m_Height - 38), 1, Text, @@ -1284,7 +1288,7 @@ Return Value: // // Fill scatter gather buffers // - if (!NT_SUCCESS (FillScatterGatherBuffers ())) + if (!NT_SUCCESS(FillScatterGatherBuffers())) { m_NumFramesSkipped++; } @@ -1294,28 +1298,28 @@ Return Value: // Issue an interrupt to our hardware sink. This is a "fake" interrupt. // It will occur at DISPATCH_LEVEL. // - m_Sensor -> Interrupt (m_PinID); + m_Sensor->Interrupt(m_PinID); // // Schedule the timer for the next interrupt time, if the pin is still running. // - if( m_PinState == PinRunning ) + if (m_PinState == PinRunning) { LARGE_INTEGER NextTime; NextTime.QuadPart = m_StartTime.QuadPart + - (m_TimePerFrame * (m_InterruptTime + 1)); + (m_TimePerFrame * (m_InterruptTime + 1)); #ifdef ENABLE_TRACING // To keep us from a tight spin when trying to debug this code... LARGE_INTEGER Now; KeQuerySystemTime(&Now); - if( Now.QuadPart >= NextTime.QuadPart ) + if (Now.QuadPart >= NextTime.QuadPart) { - NextTime.QuadPart = 0LL - m_TimePerFrame ; + NextTime.QuadPart = 0LL - m_TimePerFrame; } #endif - m_IsrTimer.Set( NextTime ); + m_IsrTimer.Set(NextTime); } } diff --git a/avstream/avscamera/sys/imagecapture.cpp b/avstream/avscamera/sys/imagecapture.cpp index 06d334d3..7ba53fa4 100644 --- a/avstream/avscamera/sys/imagecapture.cpp +++ b/avstream/avscamera/sys/imagecapture.cpp @@ -121,9 +121,11 @@ Close( { PAGED_CODE(); + // Reset the image sim's counts and queues. Reset(); - return STATUS_SUCCESS; + // Call the base Close operation. + return CCapturePin::Close(Irp); } // ImageCapturePinDispatch: |
