summaryrefslogtreecommitdiff
path: root/AVStream/avscamera/sys/PreviewHwSim.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'AVStream/avscamera/sys/PreviewHwSim.cpp')
-rw-r--r--AVStream/avscamera/sys/PreviewHwSim.cpp263
1 files changed, 263 insertions, 0 deletions
diff --git a/AVStream/avscamera/sys/PreviewHwSim.cpp b/AVStream/avscamera/sys/PreviewHwSim.cpp
new file mode 100644
index 00000000..dfe2dc1a
--- /dev/null
+++ b/AVStream/avscamera/sys/PreviewHwSim.cpp
@@ -0,0 +1,263 @@
+/**************************************************************************
+
+ A/V Stream Camera Sample
+
+ Copyright (c) 2014, Microsoft Corporation.
+
+ File:
+
+ PreviewHwSim.cpp
+
+ Abstract:
+
+ This file contains the implementation of the CPreviewHardwareSimulation
+ class.
+
+ This is a specialization of CHardwareSimulation that provides preview-
+ specific metadata.
+
+ History:
+
+ created 5/28/2014
+
+**************************************************************************/
+
+#include "Common.h"
+
+/**************************************************************************
+
+ PAGEABLE CODE
+
+**************************************************************************/
+
+#ifdef ALLOC_PRAGMA
+#pragma code_seg("PAGE")
+#endif // ALLOC_PRAGMA
+
+
+CPreviewHardwareSimulation::CPreviewHardwareSimulation(
+ _Inout_ CSensor *Sensor,
+ _In_ LONG PinID
+)
+ : CHardwareSimulation( Sensor, PinID )
+{
+ PAGED_CODE();
+}
+
+
+CPreviewHardwareSimulation::~CPreviewHardwareSimulation()
+{
+ PAGED_CODE();
+}
+
+void
+CPreviewHardwareSimulation::
+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();
+
+ // Do normal timer handling.
+ CHardwareSimulation::FakeHardware();
+
+ // Update the zoom.
+ m_Sensor->UpdateZoom();
+}
+
+//
+// Helper function that collects the current ISP settings into our metadata
+// structure.
+//
+METADATA_PREVIEWAGGREGATION
+CPreviewHardwareSimulation::
+GetMetadata()
+{
+ PAGED_CODE();
+
+ METADATA_PREVIEWAGGREGATION Metadata;
+ ISP_FRAME_SETTINGS *pSettings = GetIspSettings();
+
+ // Wipe the metadata so all settings will default to "Not Set".
+ RtlZeroMemory( &Metadata, sizeof(Metadata) );
+
+ // FocusState;
+ m_Sensor->GetFocusState( (KSCAMERA_EXTENDEDPROP_FOCUSSTATE *) &Metadata.FocusState );
+
+ // ExposureTime;
+ Metadata.ExposureTime =
+ CMetadataLongLong( GetCurrentExposureTime() );
+
+ // EVCompensation;
+ Metadata.EVCompensation = CMetadataEVCompensation(pSettings->EVCompensation.Mode, pSettings->EVCompensation.Value);
+
+ // ISOSpeed;
+ Metadata.ISOSpeed = CMetadataLong(GetCurrentISOSpeed());
+ DBG_TRACE("ISO=%d, ISO Flags=0x%016llX", Metadata.ISOSpeed.Value, pSettings->ISOMode);
+
+ // LensPosition;
+ Metadata.LensPosition = CMetadataLong( pSettings->FocusSetting.VideoProc.Value.ul );
+
+ // FlashOn;
+ Metadata.FlashOn = CMetadataLong((ULONG) pSettings->FlashMode);
+
+ // WhiteBalanceMode;
+ Metadata.WhiteBalanceMode = CMetadataLong((ULONG) pSettings->WhiteBalanceMode);
+
+ // IsoGains;
+ Metadata.IsoAnalogGain =
+ CMetadataSRational( GetRandom( (LONG)5000, (LONG)20000 ), (LONG)10000 ); // Some number from 0.5 to 2.0 - for testing.
+ Metadata.IsoDigitalGain =
+ CMetadataSRational( GetRandom( (LONG)5000, (LONG)20000 ), (LONG)10000 ); // Some number from 0.5 to 2.0 - for testing.
+
+ // SensorFrameRate;
+ ULARGE_INTEGER FrameRate;
+ FrameRate.LowPart = 60 * 60 *24;
+ FrameRate.HighPart = (ULONG) ((ONESECOND * FrameRate.LowPart) / m_TimePerFrame); // compute number of frames per day.
+ Metadata.SensorFrameRate = CMetadataULongLong( FrameRate.QuadPart );
+
+ // WhiteBalanceGains;
+ Metadata.WhiteBalanceGain_R = // MF_CAPTURE_METADATA_WHITEBALANCE_GAINS
+ CMetadataSRational( GetRandom( (LONG)5000, (LONG)20000 ), (LONG)10000 ); // Some number from 0.5 to 2.0 - for testing.
+ Metadata.WhiteBalanceGain_G = // MF_CAPTURE_METADATA_WHITEBALANCE_GAINS
+ CMetadataSRational( GetRandom( (LONG)5000, (LONG)20000 ), (LONG)10000 ); // Some number from 0.5 to 2.0 - for testing.
+ Metadata.WhiteBalanceGain_B = // MF_CAPTURE_METADATA_WHITEBALANCE_GAINS
+ CMetadataSRational( GetRandom( (LONG)5000, (LONG)20000 ), (LONG)10000 ); // Some number from 0.5 to 2.0 - for testing.
+
+ return Metadata;
+}
+
+//
+// Emit metadata here for preview pin.
+//
+void
+CPreviewHardwareSimulation::
+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
+ // Note: This call ensures the KSSTREAM_METADATA_INFO is properly initialized.
+ 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);
+ ULONG BytesLeft = pMetadata->BufferSize - pMetadata->UsedSize;
+
+ if(m_PhotoConfirmationEntry.isRequired())
+ {
+ if(BytesLeft < sizeof(KSCAMERA_METADATA_PHOTOCONFIRMATION))
+ {
+ //Fatal driver error, should never come here.
+ NT_ASSERT(FALSE);
+ return;
+ }
+ PKSCAMERA_METADATA_PHOTOCONFIRMATION pPhotoConfirmation =
+ (PKSCAMERA_METADATA_PHOTOCONFIRMATION) (((PBYTE)pMetadata->SystemVa) + pMetadata->UsedSize);
+ pPhotoConfirmation->Header.MetadataId = MetadataId_PhotoConfirmation;
+ pPhotoConfirmation->Header.Size = sizeof(*pPhotoConfirmation);
+ pPhotoConfirmation->PhotoConfirmationIndex = m_PhotoConfirmationEntry.getIndex();
+ pMetadata->UsedSize += sizeof(*pPhotoConfirmation);
+ BytesLeft -= sizeof(*pPhotoConfirmation);
+
+ DBG_TRACE("PhotoConfirmation Header.MetadataId = %u", pPhotoConfirmation->Header.MetadataId);
+ DBG_TRACE("PhotoConfirmation Header.Size = %u", pPhotoConfirmation->Header.Size);
+ DBG_TRACE("PhotoConfirmation Index = %u", pPhotoConfirmation->PhotoConfirmationIndex);
+ }
+ else
+ {
+ DBG_TRACE("Normal frame; no photo confirmation metadata.");
+ }
+
+ if( BytesLeft >= sizeof(CAMERA_METADATA_PREVIEWAGGREGATION) )
+ {
+ PCAMERA_METADATA_PREVIEWAGGREGATION pPreviewAggregation =
+ (PCAMERA_METADATA_PREVIEWAGGREGATION) (((PBYTE)pMetadata->SystemVa) + pMetadata->UsedSize);
+ pPreviewAggregation->Header.MetadataId = (ULONG) MetadataId_Custom_PreviewAggregation;
+ pPreviewAggregation->Header.Size = sizeof(*pPreviewAggregation);
+ pPreviewAggregation->Data = GetMetadata();
+ pMetadata->UsedSize += sizeof(*pPreviewAggregation);
+ BytesLeft -= sizeof(*pPreviewAggregation);
+ }
+
+ // MF_CAPTURE_METADATA_HISTOGRAM
+ //
+ // Generate the entire Histogram metadata blob here.
+ //
+ if( BytesLeft >= sizeof(CAMERA_METADATA_HISTOGRAM) )
+ {
+ PCAMERA_METADATA_HISTOGRAM pHistogram =
+ (PCAMERA_METADATA_HISTOGRAM) (((PBYTE)pMetadata->SystemVa) + pMetadata->UsedSize);
+ ULONG ChannelMask = m_Synthesizer->GetChannelMask();
+ CExtendedProperty Setting;
+
+ m_Sensor->GetHistogram( &Setting );
+ if( Setting.Flags & KSCAMERA_EXTENDEDPROP_HISTOGRAM_ON &&
+ ChannelMask != 0 )
+ {
+ // Just checking to see if we messed something up here.
+ NT_ASSERT( pMetadata->BufferSize >= CExtendedMetadata::METADATA_MAX + sizeof(CAMERA_METADATA_HISTOGRAM) );
+
+ pHistogram->Header.MetadataId = (ULONG) MetadataId_Custom_Histogram;
+ pHistogram->Header.Size = sizeof(*pHistogram);
+
+ // Acquire the data for every channel.
+ pHistogram->Data.ChannelMask = ChannelMask;
+ pHistogram->Data.Height = m_Height;
+ pHistogram->Data.Width = m_Width;
+ pHistogram->Data.FourCC = m_Sensor->GetFourCC( m_PinID );
+ m_Synthesizer->Histogram( pHistogram->Data.P0Data, pHistogram->Data.P1Data, pHistogram->Data.P2Data );
+ pMetadata->UsedSize += sizeof(*pHistogram);
+ BytesLeft -= sizeof(*pHistogram);
+ }
+ }
+
+ CExtendedVidProcSetting FaceDetect;
+ m_Sensor->GetFaceDetection(&FaceDetect);
+
+ if( FaceDetect.Flags & KSCAMERA_EXTENDEDPROP_FACEDETECTION_PREVIEW )
+ {
+ DBG_TRACE("PREVIEW");
+ EmitFaceMetadata(
+ pStreamHeader,
+ FaceDetect.GetULONG(),
+ FaceDetect.Flags & KSCAMERA_EXTENDEDPROP_FACEDETECTION_ADVANCED_MASK);
+ }
+ }
+}
+