diff options
| author | Wei Mao <[email protected]> | 2017-03-17 20:14:57 -0700 |
|---|---|---|
| committer | Wei Mao <[email protected]> | 2017-03-17 20:14:57 -0700 |
| commit | 406cf3e4c6cd251bf69cdd8d7b6433f3477d3980 (patch) | |
| tree | 15ca9253d190ab5e16cde06526dc17b486f32a22 /AVStream/avscamera/sys/imagehwsim.cpp | |
| parent | 1a3e0d580380e58bf336a242d2affc8a1e2d1ddf (diff) | |
Use lower case
Diffstat (limited to 'AVStream/avscamera/sys/imagehwsim.cpp')
| -rw-r--r-- | AVStream/avscamera/sys/imagehwsim.cpp | 1509 |
1 files changed, 0 insertions, 1509 deletions
diff --git a/AVStream/avscamera/sys/imagehwsim.cpp b/AVStream/avscamera/sys/imagehwsim.cpp deleted file mode 100644 index e6256d45..00000000 --- a/AVStream/avscamera/sys/imagehwsim.cpp +++ /dev/null @@ -1,1509 +0,0 @@ -/************************************************************************** - - A/V Stream Camera Sample - - Copyright (c) 2001, Microsoft Corporation. - - File: - - ImageHwSim.cpp - - Abstract: - - This file contains the implementation of the CImageHardwareSimulation - class. - - This is a specialization of CHardwareSimulation that provides photo- - specific metadata and implements specialized functionality for photo, - photo sequence and variable photo sequence. - - History: - - created 3/9/2001 - -**************************************************************************/ - -#include "Common.h" - -/************************************************************************** - - PAGEABLE CODE - -**************************************************************************/ - -#ifdef ALLOC_PRAGMA -#pragma code_seg("PAGE") -#endif // ALLOC_PRAGMA - - -CImageHardwareSimulation:: -CImageHardwareSimulation ( - _Inout_ CSensor *Sensor, - _In_ LONG PinID -) - : CHardwareSimulation( Sensor, PinID ) - , m_Clock(NULL) - , m_PfsLoopLimit(0) - , m_PfsFrameLimit(0) - , m_pIspSettings(nullptr) - , m_PfsLoopNumber(0) - , m_PfsFrameNumber(0) - , m_GlobalFrameNumber(0) - , m_bEndOfSequence(FALSE) - , m_PastBufferCount(0) // Zero only when the simulation inits. - -/*++ - -Routine Description: - - Construct a hardware simulation - -Arguments: - - Sensor - - The hardware sink interface. This is used to trigger - fake interrupt service routines from. - -Return Value: - - Success / Failure - ---*/ - -{ - PAGED_CODE(); - - InitializeListHead (&m_BurstList); -} - -CImageHardwareSimulation:: -~CImageHardwareSimulation() -{ - - PAGED_CODE(); - - SAFE_DELETE( m_pIspSettings ); - - if (m_Clock) - { - m_Clock -> Release (); - m_Clock = NULL; - } -} - -/*************************************************/ - -NTSTATUS -CImageHardwareSimulation:: -Start ( - _In_ CSynthesizer *ImageSynth, - _In_ ULONG Width, - _In_ ULONG Height, - _In_ ULONG ImageSize, - _In_ PIN_MODE pinMode -) - -/*++ - -Routine Description: - - Start capturing frames. This turns on the timer and begins frame capture, - but it we do not deliver frames until we receive a Trigger. We keep track - of starvation starting at this point. - -Arguments: - - ImageSynth - - The image synthesizer to use to generate pictures to display - on the capture buffer. - - Width - - The image width - - Height - - The image height - - ImageSize - - The size of the image. We allocate a temporary scratch buffer - based on this size to fake hardware. - - PinMode - - Normal or photosequence. - - -Return Value: - - Success / Failure (typical failure will be out of memory on the - scratch buffer, etc...) - ---*/ - -{ - - PAGED_CODE(); - - DBG_ENTER("(Width=%d, Height=%d, ImageSize=%d, pinMode=%s): m_PinID=%d", - Width, Height, ImageSize, pinMode?"PinBurstMode":"PinNormalMode", m_PinID ); - - NTSTATUS Status = STATUS_SUCCESS; - - // Prevent state-changes during this call. - KScopedMutex Lock(m_ListLock); - - m_Synthesizer = ImageSynth; - - NT_ASSERT(ImageSize); - m_ImageSize = ImageSize; - m_Height = Height; - m_Width = Width; - - m_NumMappingsCompleted = 0; - m_ScatterGatherMappingsQueued = 0; - m_NumFramesSkipped = 0; - m_InterruptTime = 0; - m_bTriggered = FALSE; - m_bEndOfSequence = FALSE; - m_pClone = NULL; - m_bPastBufferTrigger = FALSE; - m_PinMode = pinMode; - m_TriggerTime = 0; - m_bFlashed = FALSE; - - DBG_TRACE("m_bTriggered=FALSE, m_bPastBufferTrigger=FALSE"); - - m_FlashStatus = 0; - - // Initialize VPS counters. - m_PfsLoopNumber = 0 ; - m_PfsFrameNumber= 0 ; - m_GlobalFrameNumber = 0; - - KeQuerySystemTime (&m_StartTime); - - if( !m_Synthesizer->Initialize() ) - { - Status = STATUS_INSUFFICIENT_RESOURCES; - } - - // - // If everything is ok, start issuing interrupts. - // - if (NT_SUCCESS (Status)) - { - LARGE_INTEGER NextTime; - NextTime.QuadPart = m_StartTime.QuadPart + m_TimePerFrame; - - m_PinState = PinRunning; - m_IsrTimer.Set( NextTime ); - - } - - DBG_LEAVE("(Width=%d, Height=%d, ImageSize=%d, pinMode=%s): m_PinID=%d, Status=0x%08X", - Width, Height, ImageSize, pinMode?"PinBurstMode":"PinNormalMode", m_PinID, Status ); - - return Status; - -} - -NTSTATUS -CImageHardwareSimulation:: -Trigger( - _In_ LONG mode -) -/*++ - -Routine Description: - - Take a picture / Begin delivering frames. - -Arguments: - - mode - - Normal trigger, start or stop photo sequence. - - -Return Value: - - Success / Failure (typical failure will be out of memory on the - scratch buffer, etc...) - ---*/ - -{ - PAGED_CODE(); - - NTSTATUS status = STATUS_SUCCESS; - - DBG_ENTER( "(mode=0x%08X), m_PinMode=%d", mode, m_PinMode ); - - KScopedMutex Lock( m_ListLock ); - - //Start Trigger for Burst Mode - if(mode & KS_VideoControlFlag_StartPhotoSequenceCapture) - { - if(m_bTriggered == FALSE && m_PinMode == PinBurstMode) - { - m_bPastBufferTrigger = TRUE; - m_bTriggered = TRUE; - DBG_TRACE("m_bTriggered=TRUE, m_bPastBufferTrigger=TRUE"); - - status = STATUS_SUCCESS; - } - else - { - status = STATUS_INVALID_PARAMETER; - } - } - //Stop Trigger for Burst Mode - else if(mode & KS_VideoControlFlag_StopPhotoSequenceCapture) - { - if(m_bTriggered == TRUE && m_PinMode == PinBurstMode) - { - m_bTriggered = FALSE; - DBG_TRACE("m_bTriggered=FALSE"); - - // reset the PFS EOS, frame number and loop count. - m_bEndOfSequence = FALSE; - m_PfsFrameNumber = 0; - m_PfsLoopNumber = 0; - - m_bFlashed = FALSE; - status = STATUS_SUCCESS; - } - else - { - status = STATUS_INVALID_PARAMETER; - } - } - //Normal Trigger - else if(mode & KS_VideoControlFlag_Trigger ) - { - if(m_PinMode == PinBurstMode) - { - status = STATUS_INVALID_PARAMETER; - } - else - { - m_bTriggered = TRUE; - m_bEndOfSequence = FALSE; - DBG_TRACE("m_bTriggered=TRUE"); - } - } - - DBG_LEAVE("()"); - - return STATUS_SUCCESS; -} - - -LONG -CImageHardwareSimulation:: -GetTriggerMode() -/*++ - -Returns the pin's current trigger mode and state: - - Return Value: - - mode - - Normal trigger, start or stop photo sequence. - ---*/ - -{ - PAGED_CODE(); - - NTSTATUS status = STATUS_SUCCESS; - LONG mode = 0; - - DBG_ENTER( "(), m_PinMode=%d", m_PinMode ); - - KScopedMutex Lock( m_ListLock ); - - if( m_bTriggered ) - { - mode = (m_PinMode == PinBurstMode) ? - KS_VideoControlFlag_StartPhotoSequenceCapture : - KS_VideoControlFlag_Trigger; - } - - DBG_LEAVE("()=0x%08X", mode); - - return mode; -} - - -NTSTATUS -CImageHardwareSimulation:: -SetMode( - _In_ ULONGLONG Flags, - _In_ ULONG PastBuffers -) -/*++ - -Routine Description: - - Set the photo sequence mode. - -Arguments: - - Flags - - Normal or photo sequence. - - PastBuffers - - Number of history frames to gather. - - -Return Value: - - Success / Failure (typical failure will be out of memory on the - scratch buffer, etc...) - ---*/ - -{ - PAGED_CODE(); - - DBG_ENTER( "(Flags=0x%016llX, PastBuffers=%d)", Flags, PastBuffers ); - - if(m_bTriggered == TRUE) - { - return STATUS_INVALID_TRANSACTION; - } - - m_PastBufferCount = PastBuffers; - - if(Flags & KSCAMERA_EXTENDEDPROP_PHOTOMODE_SEQUENCE) - { - m_PinMode = PinBurstMode; - } - else - { - m_PinMode = PinNormalMode; - } - - DBG_LEAVE("()"); - - return STATUS_SUCCESS; -} - -// -// Set the interval between frames here. -// -NTSTATUS -CImageHardwareSimulation:: -SetPhotoFrameRate( - _In_ ULONGLONG TimePerFrame -) -{ - PAGED_CODE(); - - // Prevent state-changes during this call. - KScopedMutex Lock(m_ListLock); - - m_TimePerFrame = TimePerFrame; - - // - // Reschedule the timer if the hardware isn't being stopped. - // - if( m_PinState == PinRunning ) // && !m_StopHardware ) - { - // First restart our start time. We can't use the old time. - KeQuerySystemTime( &m_StartTime ); - - // - // Reschedule the timer for the next interrupt time. - // - m_StartTime.QuadPart += m_TimePerFrame; - m_InterruptTime = 0; - - m_IsrTimer.Set( m_StartTime ); - } - return STATUS_SUCCESS; -} - -NTSTATUS -CImageHardwareSimulation:: -Stop() - -/*++ - -Routine Description: - - Stop the hardware simulation... - - Wait until the timer has stopped, flush the queue, dereference the clock - and reset our state before returning. - -Arguments: - - None - -Return Value: - - Success / Failure - ---*/ - -{ - PAGED_CODE(); - - // If the hardware is told to stop while it's running, we need to - // halt the interrupts first. If we're already paused, this has - // already been done. - // - - DBG_ENTER("(): m_PinID=%d", m_PinID); - - // - // Protect the S/G list - // - KScopedMutex Lock( m_ListLock ); - - CHardwareSimulation::Stop(); - - // - // Free S/G buffer - // - FreeSGList( &m_ScatterGatherMappings, L"StreamPointer Stop Burst List" ); - - if (m_Clock) - { - m_Clock -> Release (); - m_Clock = NULL; - } - - m_bTriggered = FALSE; - m_bEndOfSequence = FALSE; - m_pClone = NULL; - m_bPastBufferTrigger = FALSE; - m_PinMode = PinNormalMode; - m_TriggerTime = 0; - - DBG_TRACE("m_bTriggered=FALSE, m_bPastBufferTrigger=FALSE"); - - DBG_LEAVE("(): m_PinID=%d", m_PinID); - - return STATUS_SUCCESS; -} - - -/*************************************************/ - - -// -// Helper function that collects current settings into our metadata structure. -// -METADATA_IMAGEAGGREGATION -CImageHardwareSimulation:: -GetMetadata() -{ - PAGED_CODE(); - - METADATA_IMAGEAGGREGATION Metadata; - ISP_FRAME_SETTINGS *pSettings = GetIspSettings(); - - // Wipe the metadata so all settings will default to "Not Set". - RtlZeroMemory( &Metadata, sizeof(Metadata) ); - - // Identify the current PFS frame number. - // If PFS not active, then this item is not present. - Metadata.FrameId.Set = IsPfsActive(); - Metadata.FrameId.Value = (ULONG) m_PfsFrameNumber; - DBG_TRACE("Metadata.FrameId.Set=%s, Metadata.FrameId.Value=%d", - (Metadata.FrameId.Set?"Yes":"No"), Metadata.FrameId.Value); - - // Just reflect the exposure time from the setting. - //Metadata.ExposureTime.Set = TRUE; - //Metadata.ExposureTime.Value = GetCurrentExposureTime(); - - // Just reflect the ISO Speed from the setting. - Metadata.ISOSpeed = CMetadataLong(GetCurrentISOSpeed()); - DBG_TRACE("ISO=%d, ISO Flags=0x%016llX", Metadata.ISOSpeed.Value, pSettings->ISOMode); - - // TODO: Do we need to bracket this by whether or not a flash has been taken? - // Report the current flash mode. - Metadata.FlashOn = CMetadataLong((ULONG) pSettings->FlashMode); - - // Report the current flash power. - Metadata.FlashPower = CMetadataLong(pSettings->FlashValue); - - // Set the White Balance lock state. - Metadata.WhiteBalanceLocked = CMetadataLong( - ( (pSettings->WhiteBalanceMode & KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_LOCK) - == KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_LOCK) ); - - // Set the Exposure lock state. - Metadata.ExposureLocked = CMetadataLong( - ( (pSettings->ExposureMode & KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_LOCK) - == KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_LOCK) ); - - Metadata.ExposureTime = - //CMetadataRational(GetCurrentExposureTime(), 10000000); - CMetadataLongLong( GetCurrentExposureTime() ); - - Metadata.LensPosition = CMetadataLong( pSettings->FocusSetting.VideoProc.Value.ul ); - - Metadata.SceneMode = CMetadataULongLong(KSCAMERA_EXTENDEDPROP_SCENEMODE_AUTO); //TODO: Need to fill in real value from CCaptureFilter::m_SceneMode - - Metadata.WhiteBalanceMode = CMetadataLong((ULONG) pSettings->WhiteBalanceMode); - - CExtendedVidProcSetting Zoom; - m_Sensor->GetZoom( &Zoom ); - Metadata.ZoomFactor = CMetadataLong(Zoom.GetLONG()); //TODO: Fill in a real value from zoom simulation. - - Metadata.FocusLocked = CMetadataLong(FALSE); //TODO: Fill in a real value when we complete the focus changes. - - // Add EVCompensation metadata... - Metadata.EVCompensation = CMetadataEVCompensation(pSettings->EVCompensation.Mode, pSettings->EVCompensation.Value); - - Metadata.Orientation = CMetadataShort(Metadata_Orientation_TopBottomLeftRight); //TODO: Randomize? - - { - LARGE_INTEGER SystemTime; - LARGE_INTEGER LocalTime; - - KeQuerySystemTimePrecise( &SystemTime ); - ExSystemTimeToLocalTime( &SystemTime, &LocalTime ); - RtlTimeToTimeFields( &LocalTime, &Metadata.LocalTime.Time ); - Metadata.LocalTime.Set = TRUE; - } - - Metadata.Make = CMetadataShortString("Make: Microsoft SOC Camera"); - Metadata.Model = CMetadataShortString( "Model: AvsCam" ); - Metadata.Software = CMetadataShortString( "Software: Microsoft Camera Sim" ); - - Metadata.ColorSpace.Set = TRUE; - Metadata.ColorSpace.Value = 0xFFFF; // 0xFFFF Means "uncalibrated". Use this value for all non-RGB formats. - - Metadata.Gamma = CMetadataRational(); - - Metadata.MakerNote = CMetadataShortString( "Maker's Note..." ); - - // Just reflect the exposure time from the setting. - //Metadata.ExposureTime = - // CMetadataRational( GetCurrentExposureTime(), 1000 ); // report exposure time as milliseconds. - - Metadata.FNumber = CMetadataRational(4); // Fake an FNumber of 4. // TODO: It looks like we might be able to calculate this. - - Metadata.ExposureProgram.Set = TRUE; - Metadata.ExposureProgram.Value = GetExposureProgram(); - - Metadata.ShutterSpeedValue = CMetadataSRational(); // TODO: Calculate this from the ExposureTime. *** - Metadata.Aperture = CMetadataRational(4); // TODO: Calculate this from the F-Number. (We're currently faking the FNumber.) - Metadata.Brightness = CMetadataSRational(0); // TODO: Find a more reasonable brightness value. - Metadata.ExposureBias = CMetadataSRational(0); // TODO: More reasonable? - Metadata.SubjectDistance = CMetadataRational(0xFFFFFFFF); // Distance in meters. Infinity. (Anything better?) - - Metadata.MeteringMode.Set = TRUE; - Metadata.MeteringMode.Value = (USHORT) GetRandom( (ULONG) 1, (ULONG) 6); // Pick a number ... any number. - - Metadata.LightSource.Set = TRUE; - Metadata.LightSource.Value = 1; // TODO: Pick a random value; but override when a flash occurs. - - Metadata.Flash.Set = TRUE; - Metadata.Flash.Value = (UINT16) pSettings->FlashMode; // We assume that the flash fires when requested! - DBG_TRACE("FlashMode=0x%016llX, FlashPower=%d", pSettings->FlashMode, pSettings->FlashValue); - - Metadata.FocalLength = CMetadataRational(); // TODO: Calculate? - Metadata.FocalPlaneXResolution = CMetadataRational(); // TODO: Calculate? - Metadata.FocalPlaneYResolution = CMetadataRational(); // TODO: Calculate? - Metadata.ExposureIndex = CMetadataRational(); // TODO: Calculate? - - Metadata.ExposureMode.Set = TRUE; - Metadata.ExposureMode.Value = 0 ; // Assume Auto exposure. - if( pSettings->ExposureMode & KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_MANUAL ) - { - Metadata.ExposureMode.Value = 0 ; // Manual exposure. - } - - Metadata.WhiteBalance.Set = TRUE; - Metadata.WhiteBalance.Value = 0 ; // Assume Auto white balance. - if( pSettings->WhiteBalanceMode & KSCAMERA_EXTENDEDPROP_VIDEOPROCFLAG_MANUAL ) - { - Metadata.WhiteBalance.Value = 0 ; // Manual while balance. - } - - Metadata.DigitalZoomRatio = CMetadataRational(1); - - Metadata.FocalLengthIn35mmFilm = CMetadataShort(0); - Metadata.SceneCaptureType = CMetadataShort(0); - Metadata.GainControl = CMetadataRational(); - Metadata.Contrast = CMetadataShort(0); - Metadata.Saturation = CMetadataShort(0); - Metadata.Sharpness = CMetadataShort(0); - Metadata.SubjectDistanceRange = CMetadataShort(0); - - // Report (optional) focus state. - KSCAMERA_EXTENDEDPROP_FOCUSSTATE State = KSCAMERA_EXTENDEDPROP_FOCUSSTATE_UNINITIALIZED; - if( NT_SUCCESS(m_Sensor->GetFocusState( &State )) ) - { - Metadata.FocusState = CMetadataLong((UINT32)State); - } - - return Metadata; -} - -// -// Emit metadata here for still pin. -// -void -CImageHardwareSimulation:: -EmitMetadata( - _Inout_ PKSSTREAM_HEADER pStreamHeader -) -/*++ - -Routine Description: - - Emit metadata for a photo. - -Arguments: - - None - -Return Value: - - Success / Failure - ---*/ -{ - PAGED_CODE(); - - NT_ASSERT(pStreamHeader); - - // Add the normal frame info to the metadata - CHardwareSimulation::EmitMetadata( pStreamHeader ); - - 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); - PCAMERA_METADATA_IMAGEAGGREGATION pAggregation = - (PCAMERA_METADATA_IMAGEAGGREGATION) (((PBYTE) pMetadata->SystemVa) + pMetadata->UsedSize); - ULONG BytesLeft = pMetadata->BufferSize - pMetadata->UsedSize; - - if( BytesLeft >= sizeof(*pAggregation) ) - { - pAggregation->Header.MetadataId = (ULONG) MetadataId_Custom_ImageAggregation; - pAggregation->Header.Size = sizeof(*pAggregation); - - // Just copy over the current frame's ISP settings for now. - // We still need to develop a contract between the driver and the MFT0 for these settings. - pAggregation->Data = GetMetadata(); - - pMetadata->UsedSize += sizeof(*pAggregation); - BytesLeft -= sizeof(*pAggregation); - } - - CExtendedVidProcSetting FaceDetect; - m_Sensor->GetFaceDetection(&FaceDetect); - - if( FaceDetect.Flags & KSCAMERA_EXTENDEDPROP_FACEDETECTION_PHOTO ) - { - DBG_TRACE("IMAGE"); - EmitFaceMetadata( - pStreamHeader, - FaceDetect.GetULONG(), - FaceDetect.Flags & KSCAMERA_EXTENDEDPROP_FACEDETECTION_ADVANCED_MASK, - 1); - } - } -} - -NTSTATUS -CImageHardwareSimulation:: -FillScatterGatherBuffers() - -/*++ - -Routine Description: - - The hardware has synthesized a buffer in scratch space and we're to - fill scatter / gather buffers. - -Arguments: - - None - -Return Value: - - Success / Failure - ---*/ - -{ - PAGED_CODE(); - - DBG_ENTER("() m_PinID=0x%08X, m_ImageSize=0x%08X, m_ScatterGatherMappingsQueued=%d, " - "m_ScatterGatherBytesQueue=0x%08X", - m_PinID, m_ImageSize, m_ScatterGatherMappingsQueued, m_ScatterGatherBytesQueued); - - // - // We're using this list lock to protect our scatter / gather lists instead - // of some hardware mechanism / KeSynchronizeExecution / whatever. - // - //KeAcquireSpinLockAtDpcLevel (&m_ListLock); - - ULONG BufferRemaining = m_ImageSize; - - // - // If there aren't enough scatter / gather buffers queued, consider it starvation. - // - while( BufferRemaining && - !IsListEmpty(&m_ScatterGatherMappings) && - m_ScatterGatherBytesQueued >= BufferRemaining) - { - DBG_TRACE( "BufferRemaining=0x%08X, m_ScatterGatherBytesQueued=0x%08X, m_ScatterGatherMappingsQueued=%d", - BufferRemaining, m_ScatterGatherBytesQueued, m_ScatterGatherMappingsQueued ); - - LIST_ENTRY *listEntry = RemoveHeadList (&m_ScatterGatherMappings); - m_ScatterGatherMappingsQueued--; - - PSCATTER_GATHER_ENTRY SGEntry = - reinterpret_cast <PSCATTER_GATHER_ENTRY> ( - CONTAINING_RECORD ( - listEntry, - SCATTER_GATHER_ENTRY, - ListEntry - ) - ); - - // Deal with cancellation. - PIRP pIrp = KsStreamPointerGetIrp(SGEntry->CloneEntry, FALSE, FALSE); - if (pIrp) - { - if (pIrp->Cancel) - { - DBG_TRACE( "Cancelling..." ); - FreeSGEntry( listEntry, L"StreamPointer Cancel SG List" ); - continue; - } - } - - // - // Since we're software, we'll be accessing this by virtual address... - // - ULONG BytesToCopy = min( BufferRemaining, SGEntry->ByteCount ); - - // Have the synthesizer output a frame to the buffer. - DBG_TRACE( "DataUsed before Commit() = %d", SGEntry->CloneEntry->StreamHeader->DataUsed ); - ULONG BytesCopied = - m_Synthesizer->DoCommit( SGEntry->Virtual, BytesToCopy ); - NT_ASSERT(BytesCopied); - DBG_TRACE( "BytesCopied = %d", BytesCopied ); - - BufferRemaining = 0; //-= BytesCopied; - - // Add metadata to the sample. - EmitMetadata( SGEntry -> CloneEntry -> StreamHeader ); - - ULONGLONG time = ConvertQPCtoTimeStamp(NULL); - - if (IsPhotoConfirmationNeeded()) - { - DBG_TRACE( "PhotoConfirmation is needed. Frame=%d, Time=0x%016llX", m_PfsFrameNumber, (LONGLONG) time ); - SGEntry->PhotoConfirmationInfo = PHOTOCONFIRMATION_INFO( m_PfsFrameNumber, (LONGLONG) time ); - } - - SGEntry -> CloneEntry -> StreamHeader -> PresentationTime.Time = time; - DBG_TRACE("PresentationTime = 0x%016llX", SGEntry->CloneEntry->StreamHeader->PresentationTime.Time ); - - SGEntry -> CloneEntry -> StreamHeader -> OptionsFlags |= KSSTREAM_HEADER_OPTIONSF_TIMEVALID; - - DBG_TRACE("m_FlashStatus=0x%016llX", m_FlashStatus); - - if(m_FlashStatus & KSCAMERA_EXTENDEDPROP_FLASH_ON || m_FlashStatus & KSCAMERA_EXTENDEDPROP_FLASH_ON_ADJUSTABLEPOWER || - m_FlashStatus & KSCAMERA_EXTENDEDPROP_FLASH_AUTO || m_FlashStatus & KSCAMERA_EXTENDEDPROP_FLASH_AUTO_ADJUSTABLEPOWER) - { - if(m_FlashStatus & KSCAMERA_EXTENDEDPROP_FLASH_SINGLEFLASH && time >= m_TriggerTime && m_TriggerTime != 0 && !m_bFlashed) - { - m_bFlashed = TRUE; - DBG_TRACE("(Single) FLASHED!!!"); - } - } - - // - // Release the scatter / gather entry back to our lookaside. - // - if( m_bTriggered && !IsPfsEOS() ) - { - DBG_TRACE("m_PinMode=%d", m_PinMode); - m_pClone = SGEntry->CloneEntry; - m_PhotoConfirmationInfo = SGEntry->PhotoConfirmationInfo; - m_NumMappingsCompleted++; - m_ScatterGatherBytesQueued -= SGEntry -> ByteCount; - - DBG_TRACE( "m_NumMappingsCompleted=%d, m_PhotoConfirmationInfo.isRequired()=%s", m_NumMappingsCompleted, m_PhotoConfirmationInfo.isRequired()?"TRUE":"FALSE" ); - - if(m_PinMode != PinBurstMode) - { - m_bTriggered = FALSE; - DBG_TRACE("m_bTriggered=FALSE"); - } - - // Update the VPS frame and loop numbers here. Mark the frame as the EOS - // if we've completed the sequence. - // - // Note: It's actually up to DevProxy to stop feeding us frames! - if( AdvanceFrameCounter() ) - { - // We've reached the end of a VPS sequence! Mark the frame as EOS. - SGEntry->CloneEntry->StreamHeader->OptionsFlags |= KSSTREAM_HEADER_OPTIONSF_ENDOFPHOTOSEQUENCE; - m_bEndOfSequence = TRUE; - } - - ExFreeToNPagedLookasideList ( - &m_ScatterGatherLookaside, - reinterpret_cast <PVOID> (SGEntry) - ); - } - else - { - InsertTailList( &m_ScatterGatherMappings, listEntry ); - m_ScatterGatherMappingsQueued++; - m_pClone = NULL; - } - } - - DBG_LEAVE("()"); - - if (BufferRemaining) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - else - { - return STATUS_SUCCESS; - } -} - -/************************************************************************** - - Debug helpers - -**************************************************************************/ - -PCCHAR -AdvancedPhoto_Text( ULONGLONG Flags ) -{ - PAGED_CODE(); - - switch( Flags ) - { - case KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_OFF: return "Off"; - case KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_AUTO: return "Auto"; - case KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_HDR: return "HDR"; - case KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_FNF: return "FNF"; - case KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_ULTRALOWLIGHT: return "UltraLL"; - case KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_AUTO | - KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_HDR: return "Auto|HDR"; - case KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_AUTO | - KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_FNF: return "Auto|FNF"; - case KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_AUTO | - KSCAMERA_EXTENDEDPROP_ADVANCEDPHOTO_ULTRALOWLIGHT: return "Auto|UltraLL"; - default: - { - static - CHAR buffer[32]; - - RtlStringCbPrintfA(buffer, sizeof(buffer), "Unknown [0x%016llX]", Flags); - return (PCCHAR) buffer; - } - } -} - -/*************************************************/ - -void -CImageHardwareSimulation:: -FakeHardware() - -/*++ - -Routine Description: - - Simulate an interrupt and what the hardware would have done in the - time since the previous interrupt. - -Arguments: - - None - -Return Value: - - None - ---*/ - -{ - PAGED_CODE(); - - // Prevent state-changes during this call. - KScopedMutex Lock(m_ListLock); - - m_InterruptTime++; - - // - // The hardware can be in a pause state in which case, it issues interrupts - // but does not complete mappings. In this case, don't bother synthesizing - // a frame and doing the work of looking through the mappings table. - // - if( m_PinState == PinRunning ) - { - if(m_PinMode == PinBurstMode && m_bTriggered && m_bPastBufferTrigger) - { - CompletePastBuffers(); - } - - m_Synthesizer->DoSynthesize(); - - CHAR Text[64]; - - CExtendedProperty Control; - m_Sensor->GetAdvancedPhoto(&Control); - RtlStringCbPrintfA(Text, sizeof(Text), "Adv: %s", AdvancedPhoto_Text(Control.Flags)); - m_Synthesizer->OverlayText( 0, m_Height-38, 1, Text, TRANSPARENT, WHITE ); - - // - // Fill scatter gather buffers - // - if (!NT_SUCCESS (FillScatterGatherBuffers ())) - { - InterlockedIncrement (PLONG (&m_NumFramesSkipped)); - } - } - - // - // Issue an interrupt to our hardware sink. This is a "fake" interrupt. - // It will occur at DISPATCH_LEVEL. - // - m_Sensor -> Interrupt (m_PinID); - - // - // Schedule the timer for the next interrupt time, if the pin is still running. - // - if( m_PinState == PinRunning ) - { - LARGE_INTEGER NextTime; - NextTime.QuadPart = m_StartTime.QuadPart + - (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 ) - { - NextTime.QuadPart = 0LL - m_TimePerFrame ; - } - -#endif - m_IsrTimer.Set( NextTime ); - } -} - -NTSTATUS -CImageHardwareSimulation:: -CompletePastBuffers() - -/*++ - -Routine Description: - - Find and complete any history frames. - -Arguments: - - None - -Return Value: - - Success / Failure - ---*/ - -{ - PAGED_CODE(); - - ULONG ulNumBuffers = m_PastBufferCount; - BOOLEAN bContinue = TRUE; - LIST_ENTRY *listEntry = NULL; - - DBG_ENTER("()"); - DBG_TRACE("m_PastBufferCount=%d, m_TriggerTime=0x%016llX", m_PastBufferCount, m_TriggerTime ); - - // If we're in burst mode and have ISP settings, we can't - // really support changing the ISP settings in the past... - // ... so we'll just treat them all past frames. - // Note: The upper layer will determine past frames from the - // metadata FrameId. - if( m_PinMode == PinBurstMode && - !m_pIspSettings ) - { - // Walk through the entire list of buffers, find the most - // recent frame presentation time and put all past buffers - // into another list. - while( !IsListEmpty(&m_ScatterGatherMappings) ) - { - listEntry = RemoveTailList(&m_ScatterGatherMappings); - m_ScatterGatherMappingsQueued--; - - PSCATTER_GATHER_ENTRY SGEntry = - reinterpret_cast <PSCATTER_GATHER_ENTRY> ( - CONTAINING_RECORD ( - listEntry, - SCATTER_GATHER_ENTRY, - ListEntry - ) - ); - - NT_ASSERT(SGEntry); - NT_ASSERT(SGEntry->CloneEntry); - NT_ASSERT(SGEntry->CloneEntry->StreamHeader); - - // We've found one that's not stamped. We must be at the end. - // Push it back and exit the loop. - if(SGEntry->CloneEntry->StreamHeader->PresentationTime.Time == 0) - { - InsertTailList(&m_ScatterGatherMappings, listEntry); - m_ScatterGatherMappingsQueued++; - DBG_TRACE( "No past frames found." ); - bContinue = FALSE; - break; - } - - // Since we're walking from the most recent to least recent frame, - // This one is a valid "future" frame. - DBG_TRACE( "Adding 'future frame' to the list" ); - PushCloneList(SGEntry); - - // If the presentation time is less than the trigger time, stop here - // and use this as the first triggered frame. - if((ULONGLONG)(SGEntry->CloneEntry->StreamHeader->PresentationTime.Time) < m_TriggerTime) - { - DBG_TRACE( "First matching frame time=0x%016llX", SGEntry->CloneEntry->StreamHeader->PresentationTime.Time ); - break; - } - - // Watch out! We might actually need to pick up multiple frames since - // in theory we could have generated several since the trigger time. - } - } - - // Grab N past frames from the queue, if we have them. - while( bContinue && - !IsListEmpty(&m_ScatterGatherMappings) && - ulNumBuffers) - { - listEntry = RemoveTailList(&m_ScatterGatherMappings); - m_ScatterGatherMappingsQueued--; - - PSCATTER_GATHER_ENTRY SGEntry = - reinterpret_cast <PSCATTER_GATHER_ENTRY> ( - CONTAINING_RECORD ( - listEntry, - SCATTER_GATHER_ENTRY, - ListEntry - ) - ); - - if(!(SGEntry -> CloneEntry -> StreamHeader -> OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TIMEVALID) ) - { - InsertTailList(&m_ScatterGatherMappings, listEntry); - m_ScatterGatherMappingsQueued++; - DBG_TRACE( "No more past frames found." ); - bContinue = FALSE; - } - else - { - PushCloneList(SGEntry); - ulNumBuffers--; - DBG_TRACE( "Past frame #%d found (%p)", ulNumBuffers, SGEntry->CloneEntry->StreamHeader ); - } - } - - // If we got all of the past frames we needed and didn't consume the entire queue... - if(bContinue && (m_ScatterGatherMappingsQueued > 0)) - { - //Mark the next tail as Time = 0 so that we don't output any super old frames. - listEntry = RemoveTailList(&m_ScatterGatherMappings); - m_ScatterGatherMappingsQueued--; - - PSCATTER_GATHER_ENTRY SGEntry = - reinterpret_cast <PSCATTER_GATHER_ENTRY> ( - CONTAINING_RECORD ( - listEntry, - SCATTER_GATHER_ENTRY, - ListEntry - ) - ); - // Mark the PTS as invalid. - SGEntry->CloneEntry->StreamHeader->PresentationTime.Time = 0; - SGEntry->CloneEntry->StreamHeader->OptionsFlags &= ~KSSTREAM_HEADER_OPTIONSF_TIMEVALID; - - InsertTailList(&m_ScatterGatherMappings, listEntry); - m_ScatterGatherMappingsQueued++; - } - - CompleteCloneList(); - - m_bPastBufferTrigger = FALSE; - - DBG_LEAVE("()"); - - return STATUS_SUCCESS; - -} - -// -// Put an item onto the history list. -// -void -CImageHardwareSimulation:: -PushCloneList( - _Inout_ PSCATTER_GATHER_ENTRY SGEntry -) -{ - PAGED_CODE(); - - DBG_TRACE( "Frame %p, PresentationTime=0x%016llX", - SGEntry->CloneEntry->StreamHeader, - SGEntry->CloneEntry->StreamHeader->PresentationTime.Time ); - - InsertHeadList( &m_BurstList, &SGEntry->ListEntry ); -} - -// -// Complete the history list. -// -NTSTATUS -CImageHardwareSimulation:: -CompleteCloneList() -{ - PAGED_CODE(); - - int i = 0; - while(!IsListEmpty(&m_BurstList)) - { - LIST_ENTRY *listEntry = RemoveHeadList(&m_BurstList); - - PSCATTER_GATHER_ENTRY SGEntry = - reinterpret_cast <PSCATTER_GATHER_ENTRY> ( - CONTAINING_RECORD ( - listEntry, - SCATTER_GATHER_ENTRY, - ListEntry - ) - ); - - m_pClone = SGEntry->CloneEntry; - m_PhotoConfirmationInfo = SGEntry->PhotoConfirmationInfo; - - m_NumMappingsCompleted++; - m_ScatterGatherBytesQueued -= SGEntry -> ByteCount; - - DBG_TRACE( "m_NumMappingsCompleted=%d, m_PhotoConfirmationInfo.isRequired()=%s", m_NumMappingsCompleted, m_PhotoConfirmationInfo.isRequired( )?"TRUE":"FALSE" ); - DBG_TRACE( "Frame %p, PresentationTime=0x%016llX", - SGEntry->CloneEntry->StreamHeader, - SGEntry->CloneEntry->StreamHeader->PresentationTime.Time ); - - m_Sensor -> Interrupt (m_PinID); - - ExFreeToNPagedLookasideList ( - &m_ScatterGatherLookaside, - reinterpret_cast <PVOID> (SGEntry) - ); - i++; - } - - return STATUS_SUCCESS; -} - -NTSTATUS -CImageHardwareSimulation:: -SetClock(PKSPIN pin) -{ - PAGED_CODE(); - - if(!NT_SUCCESS(KsPinGetReferenceClockInterface(pin, &m_Clock))) - { - m_Clock = NULL; - } - - return STATUS_SUCCESS; -} - -void -CImageHardwareSimulation:: -SetTriggerTime( - _In_ ULONGLONG TriggerTime -) -/*++ - -Routine Description: - - Identify exactly when the user pressed that button. - -Arguments: - - TriggerTime - - The QPC time in 100ns when the user asked for the photo. - -Return Value: - - void - ---*/ -{ - PAGED_CODE(); - - m_TriggerTime = TriggerTime; - DBG_TRACE( "Setting Trigger Time = 0x%016llX", TriggerTime ); -} - -NTSTATUS -CImageHardwareSimulation:: -Reset() -{ - PAGED_CODE(); - - KScopedMutex Lock( m_ListLock ); - DBG_ENTER("(): m_PinID=%d", m_PinID); - - // Parent class reset first... - CHardwareSimulation::Reset(); - - FreeSGList( &m_ScatterGatherMappings, L"StreamPointer Reset Burst List" ); - - m_bTriggered = FALSE; - m_bEndOfSequence = FALSE; - m_pClone = NULL; - m_bPastBufferTrigger = FALSE; - m_TriggerTime = 0; - - DBG_LEAVE("(): m_PinID=%d", m_PinID); - - return STATUS_SUCCESS; -} - -NTSTATUS -CImageHardwareSimulation:: -SetFlashStatus( - _In_ ULONGLONG ullFlashStatus -) -{ - PAGED_CODE(); - - m_FlashStatus = ullFlashStatus; - - DBG_TRACE("FlashStatus=0x%016llX", ullFlashStatus); - - return STATUS_SUCCESS; -} - -// -// Program the Per Frame Settings for simulation -// We do it before calling start so we can be ready -// to program our simulation's hardware. -// -// Note: We make a local copy. -// -NTSTATUS -CImageHardwareSimulation:: -SetPFS( - _In_ ISP_FRAME_SETTINGS *pIspSettings, - _In_ ULONG FrameLimit, - _In_ ULONG LoopLimit -) -{ - PAGED_CODE(); - - // Set the current ISP settings and free any prior. - // This has to be done at simulation start or stop or we have - // a synchronization problem. - SAFE_DELETE_ARRAY( m_pIspSettings ); - - if( pIspSettings ) - { - m_pIspSettings = new (NonPagedPoolNx) ISP_FRAME_SETTINGS[FrameLimit]; - if( !m_pIspSettings ) - { - m_PfsFrameLimit = 0; - m_PfsLoopLimit = 0; - return STATUS_INSUFFICIENT_RESOURCES; - } - - RtlCopyMemory( m_pIspSettings, pIspSettings, FrameLimit*sizeof(ISP_FRAME_SETTINGS) ); - m_PfsLoopLimit = LoopLimit; - m_PfsFrameLimit = FrameLimit; - } - else - { - m_PfsFrameLimit = 0; - m_PfsLoopLimit = 0; - } - - return STATUS_SUCCESS; -} - -// Function: -// bool CImageHardwareSimulation::AdvanceFrameCounter(void) -// -// Description: -// Advance our frame and loop pointers to the next PFS settings. -// -// Parameters: -// [None] -// -// Returns: -// bool - true if we've reached the end of our Per Frame Settings. -// -bool -CImageHardwareSimulation:: -AdvanceFrameCounter(void) -{ - PAGED_CODE(); - - bool bEOS = false; - - DBG_ENTER( "()" ); - - m_GlobalFrameNumber ++; - DBG_TRACE( "m_GlobalFrameNumber=%lld", m_GlobalFrameNumber ); - - // - // Calculate the PFS frame & loop numbers, but only if we've - // gotten ISP settings. - // - if( m_bTriggered && - m_PinMode == PinBurstMode && - m_pIspSettings ) - { - m_PfsFrameNumber ++; - - if( m_PfsFrameNumber >= m_PfsFrameLimit ) - { - m_PfsFrameNumber = 0; - m_PfsLoopNumber ++; - } - - // Only mark EOS if we're not in an infinite loop. - if( m_PfsLoopLimit != 0 ) - { - NT_ASSERT( !(m_PfsLoopNumber > m_PfsLoopLimit) ); - // Check to see if we've hit our limit. - if( m_PfsLoopNumber >= m_PfsLoopLimit ) - { - DBG_TRACE( "Marking EOS" ); - bEOS = true; - } - } - } - - DBG_TRACE( "m_PfsFrameNumber=%d, m_PfsLoopNumber=%d", m_PfsFrameNumber, m_PfsLoopNumber ); - DBG_TRACE( "m_PfsFrameLimit=%d, m_PfsLoopLimit=%d", m_PfsFrameLimit, m_PfsLoopLimit ); - DBG_LEAVE( "() = %s", bEOS ? "true" : "false" ); - return bEOS; -} - - -// Function: -// bool CImageHardwareSimulation::IsPfsEOS(void) -// -// Description: -// Determine if we're at the EOS. -// -// Parameters: -// [None] -// -// Returns: -// bool - true if we've reached the end of our Per Frame Settings. -// -bool -CImageHardwareSimulation:: -IsPfsEOS(void) -{ - PAGED_CODE(); - - DBG_ENTER( "()" ); - DBG_TRACE( "m_bTriggered=%s, m_bEndOfSequence=%s, m_PinMode=%d, m_pIspSetting=0x%p", - ( m_bTriggered ? "true" : "false" ), - ( m_bEndOfSequence ? "true" : "false" ), - m_PinMode, - m_pIspSettings ); - - // - // Make sure we're in a Variable Photo Sequence. - // - bool result = - bool( m_bTriggered == TRUE && - m_bEndOfSequence && - m_PinMode == PinBurstMode && - m_pIspSettings ); // Must have ISP settings set to be PFS EOS. - - DBG_LEAVE( "() = %s", (result ? "true" : "false") ); - return result; -} - -// Function: -// BOOL CImageHardwareSimulation::IsPfsActive(void) -// -// Description: -// Determine if we're in a Variable Photo Sequence. -// -// Parameters: -// [None] -// -// Returns: -// BOOL - TRUE if we are actively processing Per Frame Settings. -// -BOOL -CImageHardwareSimulation:: -IsPfsActive(void) -{ - PAGED_CODE(); - - return - BOOL( m_bTriggered && !m_bEndOfSequence && - m_PinMode == PinBurstMode && - m_pIspSettings ) ; -} - -// Get the current frame settings. -// -// Note: -// Call this function to acquire ISP settings for the current frame's -// simulation. Initially we'll just use it to report back the ISP -// settings originally requested in the PFS by the user. -// -ISP_FRAME_SETTINGS * -CImageHardwareSimulation:: -GetIspSettings(void) -{ - PAGED_CODE(); - - return - IsPfsActive() - ? &m_pIspSettings[m_PfsFrameNumber] - : CHardwareSimulation::GetIspSettings() ; -} - -BOOLEAN -CImageHardwareSimulation:: -IsPhotoConfirmationNeeded() -/*++ - -Routine Description: - - Check flags for photo confirmation and return - whether driver should issue confirmation. - ---*/ -{ - PAGED_CODE(); - - ISP_FRAME_SETTINGS *pSettings = GetIspSettings(); - - return pSettings ? pSettings->bPhotoConfirmation : FALSE; -} |
