NTSTATUS CHardwareSimulation:: GeneratePhotoConfirmation( _In_ ULONG PfsFrameNumber, _In_ LONGLONG time ) /*++ Routine Description: So a photo sim can ask a preview sim for a confirmation frame. Arguments: PfsFrameNumber - The VPS shot number. time - The precise time of the associated photo. Return Value: None --*/ { PAGED_CODE(); KScopedMutex Lock( m_ListLock ); if( PinRunning != m_PinState ) { return STATUS_DEVICE_NOT_READY; } DBG_ENTER("( Index=%d, Time=0x%016llX )", PfsFrameNumber, time ); m_PhotoConfirmationEntry = PHOTOCONFIRMATION_INFO( PfsFrameNumber, time ); // We basically used the previously synthesized preview image NTSTATUS status = FillScatterGatherBuffers(); //Clean up the photo confiramtion flag m_PhotoConfirmationEntry = PHOTOCONFIRMATION_INFO(); if(NT_SUCCESS(status)) { m_Sensor->Interrupt (m_PinID); } DBG_LEAVE("() = 0x%08X", status); return status; }
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 ); } }
void CHardwareSimulation:: 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(); 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) { // // Generate a "time stamp" just to overlay it onto the capture image. // It makes it more exciting than bars that do nothing. // ULONGLONG time = ConvertQPCtoTimeStamp(NULL); DBG_TRACE("QPC=0x%016llX", time); m_Synthesizer->SetFrameNumber( m_InterruptTime ); m_Synthesizer->SetRelativePts( (m_InterruptTime + 1) * m_TimePerFrame ); m_Synthesizer->SetQpcTime( time ); m_Synthesizer->DoSynthesize(); CHAR Text[64]; CExtendedProperty Control; m_Sensor->GetVideoStabilization( &Control ); RtlStringCbPrintfA(Text, sizeof(Text), "DVS: %s", DVS_Text(Control.Flags)); m_Synthesizer->OverlayText( 0, m_Height-38, 1, Text, BLACK, WHITE ); m_Sensor->GetOpticalImageStabilization( &Control ); RtlStringCbPrintfA(Text, sizeof(Text), "OIS: %s", OIS_Text(Control.Flags)); m_Synthesizer->OverlayText( 0, m_Height-48, 1, Text, BLACK, 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 ); } }
void CHardwareSimulation:: 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 --*/ { 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_HardwareState == HardwareRunning) { // // Generate a "time stamp" just to overlay it onto the capture image. // It makes it more exciting than bars that do nothing. // LONGLONG PtsRel = ((m_InterruptTime + 1) * m_TimePerFrame); ULONG Min = (ULONG)(PtsRel / 600000000); ULONG RemMin = (ULONG)(PtsRel % 600000000); ULONG Sec = (ULONG)(RemMin / 10000000); ULONG RemSec = (ULONG)(RemMin % 10000000); ULONG Hund = (ULONG)(RemSec / 100000); // // Synthesize a buffer in scratch space. // m_ImageSynth -> SynthesizeBars (); CHAR Text [256]; Text[0] = '\0'; (void) RtlStringCbPrintfA(Text, sizeof(Text), "%ld:%02ld.%02ld", Min, Sec, Hund); // // Overlay a clock onto the scratch space image. // m_ImageSynth -> OverlayText ( POSITION_CENTER, (m_Height - 28), 1, Text, BLACK, WHITE ); // // Overlay a counter of skipped frames onto the scratch image. // (void) RtlStringCbPrintfA(Text, sizeof(Text), "Skipped: %ld", m_NumFramesSkipped); m_ImageSynth -> OverlayText ( 10, 10, 1, Text, TRANSPARENT, BLUE ); // // 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_HardwareSink -> Interrupt (); // // Reschedule the timer if the hardware isn't being stopped. // if (!m_StopHardware) { // // Reschedule the timer for the next interrupt time. // LARGE_INTEGER NextTime; NextTime.QuadPart = m_StartTime.QuadPart + (m_TimePerFrame * (m_InterruptTime + 1)); KeSetTimer (&m_IsrTimer, NextTime, &m_IsrFakeDpc); } else { // // If someone is waiting on the hardware to stop, raise the stop // event and clear the flag. // m_StopHardware = FALSE; KeSetEvent (&m_HardwareEvent, IO_NO_INCREMENT, FALSE); } }