summaryrefslogtreecommitdiff
path: root/AVStream/avshws/capture.cpp
diff options
context:
space:
mode:
authorWei Mao <[email protected]>2017-03-17 20:14:57 -0700
committerWei Mao <[email protected]>2017-03-17 20:14:57 -0700
commit406cf3e4c6cd251bf69cdd8d7b6433f3477d3980 (patch)
tree15ca9253d190ab5e16cde06526dc17b486f32a22 /AVStream/avshws/capture.cpp
parent1a3e0d580380e58bf336a242d2affc8a1e2d1ddf (diff)
Use lower case
Diffstat (limited to 'AVStream/avshws/capture.cpp')
-rw-r--r--AVStream/avshws/capture.cpp1704
1 files changed, 0 insertions, 1704 deletions
diff --git a/AVStream/avshws/capture.cpp b/AVStream/avshws/capture.cpp
deleted file mode 100644
index f23ec0e7..00000000
--- a/AVStream/avshws/capture.cpp
+++ /dev/null
@@ -1,1704 +0,0 @@
-/**************************************************************************
-
- AVStream Simulated Hardware Sample
-
- Copyright (c) 2001, Microsoft Corporation.
-
- File:
-
- capture.cpp
-
- Abstract:
-
- This file contains source for the video capture pin on the capture
- filter. The capture sample performs "fake" DMA directly into
- the capture buffers. Common buffer DMA will work slightly differently.
-
- For common buffer DMA, the general technique would be DPC schedules
- processing with KsPinAttemptProcessing. The processing routine grabs
- the leading edge, copies data out of the common buffer and advances.
- Cloning would not be necessary with this technique. It would be
- similiar to the way "AVSSamp" works, but it would be pin-centric.
-
- History:
-
- created 3/8/2001
-
-**************************************************************************/
-
-#include "avshws.h"
-#include <ksmedia.h>
-#include "ntintsafe.h"
-
-/**************************************************************************
-
- PAGEABLE CODE
-
-**************************************************************************/
-
-
-#ifdef ALLOC_PRAGMA
-#pragma code_seg("PAGE")
-#endif // ALLOC_PRAGMA
-
-#define DMAX_X 320
-#define DMAX_Y 240
-#define D_X 320
-#define D_Y 240
-
-CCapturePin::
-CCapturePin (
- IN PKSPIN Pin
- ) :
- m_Pin (Pin)
- ,m_PresentationTime (0)
-
-/*++
-
-Routine Description:
-
- Construct a new capture pin.
-
-Arguments:
-
- Pin -
- The AVStream pin object corresponding to the capture pin
-
-Return Value:
-
- None
-
---*/
-
-{
-
- PAGED_CODE();
-
- PKSDEVICE Device = KsPinGetDevice (Pin);
-
- //
- // Set up our device pointer. This gives us access to "hardware I/O"
- // during the capture routines.
- //
- m_Device = reinterpret_cast <CCaptureDevice *> (Device -> Context);
-}
-
-/*************************************************/
-
-
-NTSTATUS
-CCapturePin::
-DispatchCreate (
- IN PKSPIN Pin,
- IN PIRP Irp
- )
-
-/*++
-
-Routine Description:
-
- Create a new capture pin. This is the creation dispatch for
- the video capture pin.
-
-Arguments:
-
- Pin -
- The pin being created
-
- Irp -
- The creation Irp
-
-Return Value:
-
- Success / Failure
-
---*/
-
-{
-
- PAGED_CODE();
-
- NTSTATUS Status = STATUS_SUCCESS;
-
- CCapturePin *CapPin = new (NonPagedPoolNx, 'niPC') CCapturePin (Pin);
-
- if (!CapPin) {
- //
- // Return failure if we couldn't create the pin.
- //
- Status = STATUS_INSUFFICIENT_RESOURCES;
-
- } else {
- //
- // Add the item to the object bag if we we were successful.
- // Whenever the pin closes, the bag is cleaned up and we will be
- // freed.
- //
- Status = KsAddItemToObjectBag (
- Pin -> Bag,
- reinterpret_cast <PVOID> (CapPin),
- reinterpret_cast <PFNKSFREE> (CCapturePin::Cleanup)
- );
-
- if (!NT_SUCCESS (Status)) {
- delete CapPin;
- } else {
- Pin -> Context = reinterpret_cast <PVOID> (CapPin);
- }
-
- }
-
- //
- // If we succeeded so far, stash the video info header away and change
- // our allocator framing to reflect the fact that only now do we know
- // the framing requirements based on the connection format.
- //
- PKS_VIDEOINFOHEADER VideoInfoHeader = NULL;
-
- if (NT_SUCCESS (Status)) {
-
- VideoInfoHeader = CapPin -> CaptureVideoInfoHeader ();
- if (!VideoInfoHeader) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
- }
-
- if (NT_SUCCESS(Status)) {
- //
- // We need to edit the descriptor to ensure we don't mess up any other
- // pins using the descriptor or touch read-only memory.
- //
- Status = KsEdit (
- Pin,
- &Pin -> Descriptor,
- AVSHWS_POOLTAG);
-
- if (NT_SUCCESS (Status)) {
-
- //
- // If the edits proceeded without running out of memory, adjust
- // the framing based on the video info header.
- //
- Status = KsEdit (
- Pin,
- &Pin -> Descriptor -> AllocatorFraming,
- AVSHWS_POOLTAG);
-
- if (NT_SUCCESS (Status)) {
-
- //
- // We've KsEdit'ed this... I'm safe to cast away constness as
- // long as the edit succeeded.
- //
- PKSALLOCATOR_FRAMING_EX Framing =
- const_cast <PKSALLOCATOR_FRAMING_EX> (
- Pin -> Descriptor -> AllocatorFraming
- );
-
- Framing -> FramingItem [0].Frames = 2;
-
- //
- // The physical and optimal ranges must be biSizeImage. We only
- // support one frame size, precisely the size of each capture
- // image.
- //
- Framing -> FramingItem [0].PhysicalRange.MinFrameSize =
- Framing -> FramingItem [0].PhysicalRange.MaxFrameSize =
- Framing -> FramingItem [0].FramingRange.Range.MinFrameSize =
- Framing -> FramingItem [0].FramingRange.Range.MaxFrameSize =
- VideoInfoHeader -> bmiHeader.biSizeImage;
-
- Framing -> FramingItem [0].PhysicalRange.Stepping =
- Framing -> FramingItem [0].FramingRange.Range.Stepping =
- 0;
-
- }
-
- }
- }
-
- if (NT_SUCCESS (Status)) {
- //
- // Adjust the stream header size. The video packets have extended
- // header info (KS_FRAME_INFO).
- //
- Pin -> StreamHeaderSize = sizeof (KSSTREAM_HEADER) +
- sizeof (KS_FRAME_INFO);
-
- }
- return Status;
-}
-
-/*************************************************/
-
-
-PKS_VIDEOINFOHEADER
-CCapturePin::
-CaptureVideoInfoHeader (
- )
-
-/*++
-
-Routine Description:
-
- Capture the video info header out of the connection format. This
- is what we use to base synthesized images off.
-
-Arguments:
-
- None
-
-Return Value:
-
- The captured video info header or NULL if there is insufficient
- memory.
-
---*/
-
-{
-
- PAGED_CODE();
-
- PKS_VIDEOINFOHEADER ConnectionHeader =
- &((reinterpret_cast <PKS_DATAFORMAT_VIDEOINFOHEADER>
- (m_Pin -> ConnectionFormat)) ->
- VideoInfoHeader);
-
- m_VideoInfoHeader = reinterpret_cast <PKS_VIDEOINFOHEADER> (
- ExAllocatePoolWithTag (
- NonPagedPoolNx,
- KS_SIZE_VIDEOHEADER (ConnectionHeader),
- AVSHWS_POOLTAG
- )
- );
-
- if (!m_VideoInfoHeader)
- return NULL;
-
- //
- // Bag the newly allocated header space. This will get cleaned up
- // automatically when the pin closes.
- //
- NTSTATUS Status =
- KsAddItemToObjectBag (
- m_Pin -> Bag,
- reinterpret_cast <PVOID> (m_VideoInfoHeader),
- NULL
- );
-
- if (!NT_SUCCESS (Status)) {
-
- ExFreePool (m_VideoInfoHeader);
- return NULL;
-
- } else {
-
- //
- // Copy the connection format video info header into the newly
- // allocated "captured" video info header.
- //
- RtlCopyMemory (
- m_VideoInfoHeader,
- ConnectionHeader,
- KS_SIZE_VIDEOHEADER (ConnectionHeader)
- );
-
- }
-
- return m_VideoInfoHeader;
-
-}
-
-
-NTSTATUS
-CCapturePin::
-Process (
- )
-
-/*++
-
-Routine Description:
-
- The process dispatch for the pin bridges to this location.
- We handle setting up scatter gather mappings, etc...
-
-Arguments:
-
- None
-
-Return Value:
-
- Success / Failure
-
---*/
-
-{
-
- PAGED_CODE();
-
- NTSTATUS Status = STATUS_SUCCESS;
- PKSSTREAM_POINTER Leading;
-
- _DbgPrintF(DEBUGLVL_VERBOSE, ("Process"));
-
- Leading = KsPinGetLeadingEdgeStreamPointer (
- m_Pin,
- KSSTREAM_POINTER_STATE_LOCKED
- );
-
- while (NT_SUCCESS (Status) && Leading) {
-
- PKSSTREAM_POINTER ClonePointer;
- PSTREAM_POINTER_CONTEXT SPContext = NULL;
-
- //
- // If no data is present in the Leading edge stream pointer, just
- // move on to the next frame
- //
- if ( NULL == Leading -> StreamHeader -> Data ) {
- Status = KsStreamPointerAdvance(Leading);
- continue;
- }
- //
- // For optimization sake in this particular sample, I will only keep
- // one clone stream pointer per frame. This complicates the logic
- // here but simplifies the completions.
- //
- // I'm also choosing to do this since I need to keep track of the
- // virtual addresses corresponding to each mapping since I'm faking
- // DMA. It simplifies that too.
- //
- if (!m_PreviousStreamPointer) {
- //
- // First thing we need to do is clone the leading edge. This allows
- // us to keep reference on the frames while they're in DMA.
- //
- Status = KsStreamPointerClone (
- Leading,
- NULL,
- sizeof (STREAM_POINTER_CONTEXT),
- &ClonePointer
- );
-
- //
- // I use this for easy chunking of the buffer. We're not really
- // dealing with physical addresses. This keeps track of what
- // virtual address in the buffer the current scatter / gather
- // mapping corresponds to for the fake hardware.
- //
- if (NT_SUCCESS (Status)) {
-
- //
- // Set the stream header data used to 0. We update this
- // in the DMA completions. For queues with DMA, we must
- // update this field ourselves.
- //
- ClonePointer -> StreamHeader -> DataUsed = 0;
-
- SPContext = reinterpret_cast <PSTREAM_POINTER_CONTEXT>
- (ClonePointer -> Context);
-
- SPContext -> BufferVirtual =
- reinterpret_cast <PUCHAR> (
- ClonePointer -> StreamHeader -> Data
- );
- }
-
- } else {
-
- ClonePointer = m_PreviousStreamPointer;
- SPContext = reinterpret_cast <PSTREAM_POINTER_CONTEXT>
- (ClonePointer -> Context);
- Status = STATUS_SUCCESS;
- }
-
- //
- // If the clone failed, likely we're out of resources. Break out
- // of the loop for now. We may end up starving DMA.
- //
- if (!NT_SUCCESS (Status)) {
- KsStreamPointerUnlock (Leading, FALSE);
- break;
- }
-
- //
- // Program the fake hardware. I would use Clone -> OffsetOut.*, but
- // because of the optimization of one stream pointer per frame, it
- // doesn't make complete sense.
- //
- ULONG MappingsUsed =
- m_Device -> ProgramScatterGatherMappings (
- ClonePointer,
- &(SPContext -> BufferVirtual),
- Leading -> OffsetOut.Mappings,
- Leading -> OffsetOut.Remaining
- );
-
- //
- // In order to keep one clone per frame and simplify the fake DMA
- // logic, make a check to see if we completely used the mappings in
- // the leading edge. Set a flag.
- //
- if (MappingsUsed == Leading -> OffsetOut.Remaining) {
- m_PreviousStreamPointer = NULL;
- } else {
- m_PreviousStreamPointer = ClonePointer;
- }
-
- if (MappingsUsed) {
- //
- // If any mappings were added to scatter / gather queues,
- // advance the leading edge by that number of mappings. If
- // we run off the end of the queue, Status will be
- // STATUS_DEVICE_NOT_READY. Otherwise, the leading edge will
- // point to a new frame. The previous one will not have been
- // dismissed (unless "DMA" completed) since there's a clone
- // pointer referencing the frames.
- //
- Status =
- KsStreamPointerAdvanceOffsets (
- Leading,
- 0,
- MappingsUsed,
- FALSE
- );
- } else {
-
- //
- // The hardware was incapable of adding more entries. The S/G
- // table is full.
- //
- Status = STATUS_PENDING;
- break;
-
- }
-
- }
-
- //
- // If the leading edge failed to lock (this is always possible, remember
- // that locking CAN occassionally fail), don't blow up passing NULL
- // into KsStreamPointerUnlock. Also, set m_PendIo to kick us later...
- //
- if (!Leading) {
-
- m_PendIo = TRUE;
-
- //
- // If the lock failed, there's no point in getting called back
- // immediately. The lock could fail due to insufficient memory,
- // etc... In this case, we don't want to get called back immediately.
- // Return pending. The m_PendIo flag will cause us to get kicked
- // later.
- //
- Status = STATUS_PENDING;
- }
-
- //
- // If we didn't run the leading edge off the end of the queue, unlock it.
- //
- if (NT_SUCCESS (Status) && Leading) {
- KsStreamPointerUnlock (Leading, FALSE);
- } else {
- //
- // DEVICE_NOT_READY indicates that the advancement ran off the end
- // of the queue. We couldn't lock the leading edge.
- //
- if (Status == STATUS_DEVICE_NOT_READY) Status = STATUS_SUCCESS;
- }
-
- //
- // If we failed with something that requires pending, set the pending I/O
- // flag so we know we need to start it again in a completion DPC.
- //
- if (!NT_SUCCESS (Status) || Status == STATUS_PENDING) {
- m_PendIo = TRUE;
- }
-
- _DbgPrintF(DEBUGLVL_VERBOSE, ("Leaving Process..."));
- return Status;
-
-}
-
-/*************************************************/
-
-
-NTSTATUS
-CCapturePin::
-CleanupReferences (
- )
-
-/*++
-
-Routine Description:
-
- Clean up any references we're holding on frames after we abruptly
- stop the hardware.
-
-Arguments:
-
- None
-
-Return Value:
-
- Success / Failure
-
---*/
-
-{
-
- PAGED_CODE();
-
- PKSSTREAM_POINTER Clone = KsPinGetFirstCloneStreamPointer (m_Pin);
- PKSSTREAM_POINTER NextClone = NULL;
-
- //
- // Walk through the clones, deleting them, and setting DataUsed to
- // zero since we didn't use any data!
- //
- while (Clone) {
-
- NextClone = KsStreamPointerGetNextClone (Clone);
-
- Clone -> StreamHeader -> DataUsed = 0;
- KsStreamPointerDelete (Clone);
-
- Clone = NextClone;
-
- }
-
- return STATUS_SUCCESS;
-
-}
-
-/*************************************************/
-
-
-NTSTATUS
-CCapturePin::
-SetState (
- IN KSSTATE ToState,
- IN KSSTATE FromState
- )
-
-/*++
-
-Routine Description:
-
- This is called when the caputre pin transitions state. The routine
- attempts to acquire / release any hardware resources and start up
- or shut down capture based on the states we are transitioning to
- and away from.
-
-Arguments:
-
- ToState -
- The state we're transitioning to
-
- FromState -
- The state we're transitioning away from
-
-Return Value:
-
- Success / Failure
-
---*/
-
-{
-
- PAGED_CODE();
-
- NTSTATUS Status = STATUS_SUCCESS;
-
- switch (ToState) {
-
- case KSSTATE_STOP:
-
- //
- // First, stop the hardware if we actually did anything to it.
- //
- if (m_HardwareState != HardwareStopped) {
- Status = m_Device -> Stop ();
- NT_ASSERT (NT_SUCCESS (Status));
-
- m_HardwareState = HardwareStopped;
- }
-
- //
- // We've stopped the "fake hardware". It has cleared out
- // it's scatter / gather tables and will no longer be
- // completing clones. We had locks on some frames that were,
- // however, in hardware. This will clean them up. An
- // alternative location would be in the reset dispatch.
- // Note, however, that the reset dispatch can occur in any
- // state and this should be understood.
- //
- // Some hardware may fill all S/G mappings before stopping...
- // in this case, you may not have to do this. The
- // "fake hardware" here simply stops filling mappings and
- // cleans its scatter / gather tables out on the Stop call.
- //
- Status = CleanupReferences ();
-
- //
- // Release any hardware resources related to this pin.
- //
- if (m_AcquiredResources) {
- //
- // If we got an interface to the clock, we must release it.
- //
- if (m_Clock) {
- m_Clock -> Release ();
- m_Clock = NULL;
- }
-
- m_Device -> ReleaseHardwareResources (
- );
-
- m_AcquiredResources = FALSE;
- }
-
- break;
-
- case KSSTATE_ACQUIRE:
- //
- // Acquire any hardware resources related to this pin. We should
- // only acquire them here -- **NOT** at filter create time.
- // This means we do not fail creation of a filter because of
- // limited hardware resources.
- //
- if (FromState == KSSTATE_STOP) {
- Status = m_Device -> AcquireHardwareResources (
- this,
- m_VideoInfoHeader
- );
-
- if (NT_SUCCESS (Status)) {
- m_AcquiredResources = TRUE;
-
- //
- // Attempt to get an interface to the master clock.
- // This will fail if one has not been assigned. Since
- // one must be assigned while the pin is still in
- // KSSTATE_STOP, this is a guranteed method of getting
- // the clock should one be assigned.
- //
- if (!NT_SUCCESS (
- KsPinGetReferenceClockInterface (
- m_Pin,
- &m_Clock
- )
- )) {
-
- //
- // If we could not get an interface to the clock,
- // don't use one.
- //
- m_Clock = NULL;
-
- }
-
- } else {
- m_AcquiredResources = FALSE;
- }
-
- } else {
- //
- // Standard transport pins will always receive transitions in
- // +/- 1 manner. This means we'll always see a PAUSE->ACQUIRE
- // transition before stopping the pin.
- //
- // The below is done because on DirectX 8.0, when the pin gets
- // a message to stop, the queue is inaccessible. The reset
- // which comes on every stop happens after this (at which time
- // the queue is inaccessible also). So, for compatibility with
- // DirectX 8.0, I am stopping the "fake" hardware at this
- // point and cleaning up all references we have on frames. See
- // the comments above regarding the CleanupReferences call.
- //
- // If this sample were targeting XP only, the below code would
- // not be here. Again, I only do this so the sample does not
- // hang when it is stopped running on a configuration such as
- // Win2K + DX8.
- //
- if (m_HardwareState != HardwareStopped) {
- Status = m_Device -> Stop ();
- NT_ASSERT (NT_SUCCESS (Status));
-
- m_HardwareState = HardwareStopped;
- }
-
- Status = CleanupReferences ();
- }
-
- m_FrameNumber = 0;
- m_DroppedFrames = 0;
- break;
-
- case KSSTATE_PAUSE:
- //
- // Stop the hardware simulation if we're coming down from run.
- //
- if (FromState == KSSTATE_RUN) {
-
- m_PresentationTime = 0;
- Status = m_Device -> Pause (TRUE);
-
- if (NT_SUCCESS (Status)) {
- m_HardwareState = HardwarePaused;
- }
-
- }
- m_FrameNumber = 0;
- break;
-
- case KSSTATE_RUN:
- //
- // Start the hardware simulation or unpause it depending on
- // whether we're initially running or we've paused and restarted.
- //
- if (m_HardwareState == HardwarePaused) {
- Status = m_Device -> Pause (FALSE);
- } else {
- Status = m_Device -> Start ();
- }
-
- if (NT_SUCCESS (Status)) {
- m_HardwareState = HardwareRunning;
- }
-
- break;
-
- }
-
- return Status;
-
-}
-
-/*************************************************/
-
-
-NTSTATUS
-CCapturePin::
-IntersectHandler (
- IN PKSFILTER Filter,
- IN PIRP Irp,
- IN PKSP_PIN PinInstance,
- IN PKSDATARANGE CallerDataRange,
- IN PKSDATARANGE DescriptorDataRange,
- IN ULONG BufferSize,
- OUT PVOID Data OPTIONAL,
- OUT PULONG DataSize
- )
-
-/*++
-
-Routine Description:
-
- This routine handles video pin intersection queries by determining the
- intersection between two data ranges.
-
-Arguments:
-
- Filter -
- Contains a void pointer to the filter structure.
-
- Irp -
- Contains a pointer to the data intersection property request.
-
- PinInstance -
- Contains a pointer to a structure indicating the pin in question.
-
- CallerDataRange -
- Contains a pointer to one of the data ranges supplied by the client
- in the data intersection request. The format type, subtype and
- specifier are compatible with the DescriptorDataRange.
-
- DescriptorDataRange -
- Contains a pointer to one of the data ranges from the pin descriptor
- for the pin in question. The format type, subtype and specifier are
- compatible with the CallerDataRange.
-
- BufferSize -
- Contains the size in bytes of the buffer pointed to by the Data
- argument. For size queries, this value will be zero.
-
- Data -
- Optionally contains a pointer to the buffer to contain the data
- format structure representing the best format in the intersection
- of the two data ranges. For size queries, this pointer will be
- NULL.
-
- DataSize -
- Contains a pointer to the location at which to deposit the size
- of the data format. This information is supplied by the function
- when the format is actually delivered and in response to size
- queries.
-
-Return Value:
-
- STATUS_SUCCESS if there is an intersection and it fits in the supplied
- buffer, STATUS_BUFFER_OVERFLOW for successful size queries,
- STATUS_NO_MATCH if the intersection is empty, or
- STATUS_BUFFER_TOO_SMALL if the supplied buffer is too small.
-
---*/
-
-{
- PAGED_CODE();
-
- const GUID VideoInfoSpecifier =
- {STATICGUIDOF(KSDATAFORMAT_SPECIFIER_VIDEOINFO)};
-
- NT_ASSERT(Filter);
- NT_ASSERT(Irp);
- NT_ASSERT(PinInstance);
- NT_ASSERT(CallerDataRange);
- NT_ASSERT(DescriptorDataRange);
- NT_ASSERT(DataSize);
-
- ULONG DataFormatSize;
-
- //
- // Specifier FORMAT_VideoInfo for VIDEOINFOHEADER
- //
- if (IsEqualGUID(CallerDataRange->Specifier, VideoInfoSpecifier) &&
- CallerDataRange -> FormatSize >= sizeof (KS_DATARANGE_VIDEO)) {
-
- PKS_DATARANGE_VIDEO callerDataRange =
- reinterpret_cast <PKS_DATARANGE_VIDEO> (CallerDataRange);
-
- PKS_DATARANGE_VIDEO descriptorDataRange =
- reinterpret_cast <PKS_DATARANGE_VIDEO> (DescriptorDataRange);
-
- PKS_DATAFORMAT_VIDEOINFOHEADER FormatVideoInfoHeader;
-
- //
- // Check that the other fields match
- //
- if ((callerDataRange->bFixedSizeSamples !=
- descriptorDataRange->bFixedSizeSamples) ||
- (callerDataRange->bTemporalCompression !=
- descriptorDataRange->bTemporalCompression) ||
- (callerDataRange->StreamDescriptionFlags !=
- descriptorDataRange->StreamDescriptionFlags) ||
- (callerDataRange->MemoryAllocationFlags !=
- descriptorDataRange->MemoryAllocationFlags) ||
- (RtlCompareMemory (&callerDataRange->ConfigCaps,
- &descriptorDataRange->ConfigCaps,
- sizeof (KS_VIDEO_STREAM_CONFIG_CAPS)) !=
- sizeof (KS_VIDEO_STREAM_CONFIG_CAPS)))
- {
- return STATUS_NO_MATCH;
- }
-
- //
- // KS_SIZE_VIDEOHEADER() below is relying on bmiHeader.biSize from
- // the caller's data range. This **MUST** be validated; the
- // extended bmiHeader size (biSize) must not extend past the end
- // of the range buffer. Possible arithmetic overflow is also
- // checked for.
- //
- {
- ULONG VideoHeaderSize = KS_SIZE_VIDEOHEADER (
- &callerDataRange->VideoInfoHeader
- );
-
- ULONG DataRangeSize =
- FIELD_OFFSET (KS_DATARANGE_VIDEO, VideoInfoHeader) +
- VideoHeaderSize;
-
- //
- // Check that biSize does not extend past the buffer. The
- // first two checks are for arithmetic overflow on the
- // operations to compute the alleged size. (On unsigned
- // math, a+b < a iff an arithmetic overflow occurred).
- //
- if (
- VideoHeaderSize < callerDataRange->
- VideoInfoHeader.bmiHeader.biSize ||
- DataRangeSize < VideoHeaderSize ||
- DataRangeSize > callerDataRange -> DataRange.FormatSize
- ) {
-
- return STATUS_INVALID_PARAMETER;
-
- }
-
- }
-
- DataFormatSize =
- sizeof (KSDATAFORMAT) +
- KS_SIZE_VIDEOHEADER (&callerDataRange->VideoInfoHeader);
-
-
- //
- // If the passed buffer size is 0, it indicates that this is a size
- // only query. Return the size of the intersecting data format and
- // pass back STATUS_BUFFER_OVERFLOW.
- //
- if (BufferSize == 0) {
-
- *DataSize = DataFormatSize;
- return STATUS_BUFFER_OVERFLOW;
-
- }
-
- //
- // Verify that the provided structure is large enough to
- // accept the result.
- //
- if (BufferSize < DataFormatSize)
- {
- return STATUS_BUFFER_TOO_SMALL;
- }
-
- //
- // Copy over the KSDATAFORMAT, followed by the actual VideoInfoHeader
- //
- *DataSize = DataFormatSize;
-
- FormatVideoInfoHeader = PKS_DATAFORMAT_VIDEOINFOHEADER( Data );
-
- //
- // Copy over the KSDATAFORMAT. This is precisely the same as the
- // KSDATARANGE (it's just the GUIDs, etc... not the format information
- // following any data format.
- //
- RtlCopyMemory (
- &FormatVideoInfoHeader->DataFormat,
- DescriptorDataRange,
- sizeof (KSDATAFORMAT));
-
- FormatVideoInfoHeader->DataFormat.FormatSize = DataFormatSize;
-
- //
- // Copy over the callers requested VIDEOINFOHEADER
- //
-
- RtlCopyMemory (
- &FormatVideoInfoHeader->VideoInfoHeader,
- &callerDataRange->VideoInfoHeader,
- KS_SIZE_VIDEOHEADER (&callerDataRange->VideoInfoHeader)
- );
-
- //
- // Calculate biSizeImage for this request, and put the result in both
- // the biSizeImage field of the bmiHeader AND in the SampleSize field
- // of the DataFormat.
- //
- // Note that for compressed sizes, this calculation will probably not
- // be just width * height * bitdepth
- //
- FormatVideoInfoHeader->VideoInfoHeader.bmiHeader.biSizeImage =
- FormatVideoInfoHeader->DataFormat.SampleSize =
- KS_DIBSIZE (FormatVideoInfoHeader->VideoInfoHeader.bmiHeader);
-
- //
- // REVIEW - Perform other validation such as cropping and scaling checks
- //
-
- return STATUS_SUCCESS;
-
- } // End of VIDEOINFOHEADER specifier
-
- return STATUS_NO_MATCH;
-}
-
-/*************************************************/
-
-BOOL
-MultiplyCheckOverflow (
- ULONG a,
- ULONG b,
- ULONG *pab
- )
-
-/*++
-
-Routine Description:
-
- Perform a 32 bit unsigned multiplication and check for arithmetic overflow.
-
-Arguments:
-
- a -
- First operand
-
- b -
- Second operand
-
- pab -
- Result
-
-Return Value:
-
- TRUE -
- no overflow
-
- FALSE -
- overflow occurred
-
---*/
-
-{
- PAGED_CODE();
-
- *pab = a * b;
- if ((a == 0) || (((*pab) / a) == b)) {
- return TRUE;
- }
- return FALSE;
-}
-
-/*************************************************/
-
-
-NTSTATUS
-CCapturePin::
-DispatchSetFormat (
- IN PKSPIN Pin,
- IN PKSDATAFORMAT OldFormat OPTIONAL,
- IN PKSMULTIPLE_ITEM OldAttributeList OPTIONAL,
- IN const KSDATARANGE *DataRange,
- IN const KSATTRIBUTE_LIST *AttributeRange OPTIONAL
- )
-
-/*++
-
-Routine Description:
-
- This is the set data format dispatch for the capture pin. It is called
- in two circumstances.
-
- 1: before Pin's creation dispatch has been made to verify that
- Pin -> ConnectionFormat is an acceptable format for the range
- DataRange. In this case OldFormat is NULL.
-
- 2: after Pin's creation dispatch has been made and an initial format
- selected in order to change the format for the pin. In this case,
- OldFormat will not be NULL.
-
- Validate that the format is acceptible and perform the actions necessary
- to change format if appropriate.
-
-Arguments:
-
- Pin -
- The pin this format is being set on. The format itself will be in
- Pin -> ConnectionFormat.
-
- OldFormat -
- The previous format used on this pin. If this is NULL, it is an
- indication that Pin's creation dispatch has not yet been made and
- that this is a request to validate the initial format and not to
- change formats.
-
- OldAttributeList -
- The old attribute list for the prior format
-
- DataRange -
- A range out of our list of data ranges which was determined to be
- at least a partial match for Pin -> ConnectionFormat. If the format
- there is unacceptable for the range, STATUS_NO_MATCH should be
- returned.
-
- AttributeRange -
- The attribute range
-
-Return Value:
-
- Success / Failure
-
- STATUS_SUCCESS -
- The format is acceptable / the format has been changed
-
- STATUS_NO_MATCH -
- The format is not-acceptable / the format has not been changed
-
---*/
-
-{
-
- PAGED_CODE();
-
- NTSTATUS Status = STATUS_NO_MATCH;
-
- const GUID VideoInfoSpecifier =
- {STATICGUIDOF(KSDATAFORMAT_SPECIFIER_VIDEOINFO)};
-
- CCapturePin *CapPin = NULL;
-
- //
- // Find the pin, if it exists yet. OldFormat will be an indication of
- // this. If we're changing formats, OldFormat will be non-NULL.
- //
- // You cannot use Pin -> Context to make the determination. AVStream
- // preinitializes this to the filter's context.
- //
- if (OldFormat) {
- CapPin = reinterpret_cast <CCapturePin *> (Pin -> Context);
- }
-
- if (IsEqualGUID (Pin -> ConnectionFormat -> Specifier,
- VideoInfoSpecifier) &&
- Pin -> ConnectionFormat -> FormatSize >=
- sizeof (KS_DATAFORMAT_VIDEOINFOHEADER)) {
-
- PKS_DATAFORMAT_VIDEOINFOHEADER ConnectionFormat =
- reinterpret_cast <PKS_DATAFORMAT_VIDEOINFOHEADER>
- (Pin -> ConnectionFormat);
-
- //
- // DataRange comes out of OUR data range list. I know the range
- // is valid as such.
- //
- const KS_DATARANGE_VIDEO *VIRange =
- reinterpret_cast <const KS_DATARANGE_VIDEO *>
- (DataRange);
-
- //
- // Check that bmiHeader.biSize is valid since we use it later.
- //
- ULONG VideoHeaderSize = KS_SIZE_VIDEOHEADER (
- &ConnectionFormat -> VideoInfoHeader
- );
-
- ULONG DataFormatSize = FIELD_OFFSET (
- KS_DATAFORMAT_VIDEOINFOHEADER, VideoInfoHeader
- ) + VideoHeaderSize;
-
- if (
- VideoHeaderSize < ConnectionFormat->
- VideoInfoHeader.bmiHeader.biSize ||
- DataFormatSize < VideoHeaderSize ||
- DataFormatSize > ConnectionFormat -> DataFormat.FormatSize
- ) {
-
- Status = STATUS_INVALID_PARAMETER;
-
- }
-
- //
- // Check that the format is a match for the selected range.
- //
- else if (
- (ConnectionFormat -> VideoInfoHeader.bmiHeader.biWidth !=
- VIRange -> VideoInfoHeader.bmiHeader.biWidth) ||
-
- (ConnectionFormat -> VideoInfoHeader.bmiHeader.biHeight !=
- VIRange -> VideoInfoHeader.bmiHeader.biHeight) ||
-
- (ConnectionFormat -> VideoInfoHeader.bmiHeader.biCompression !=
- VIRange -> VideoInfoHeader.bmiHeader.biCompression)
-
- ) {
-
- Status = STATUS_NO_MATCH;
-
- } else {
-
- //
- // Compute the minimum size of our buffers to validate against.
- // The image synthesis routines synthesize |biHeight| rows of
- // biWidth pixels in either RGB24 or UYVY. In order to ensure
- // safe synthesis into the buffer, we need to know how large an
- // image this will produce.
- //
- // I do this explicitly because of the method that the data is
- // synthesized. A variation of this may or may not be necessary
- // depending on the mechanism the driver in question fills the
- // capture buffers. The important thing is to ensure that they
- // aren't overrun during capture.
- //
- ULONG ImageSize;
-
- if (!MultiplyCheckOverflow (
- (ULONG)ConnectionFormat->VideoInfoHeader.bmiHeader.biWidth,
- (ULONG)abs (ConnectionFormat->
- VideoInfoHeader.bmiHeader.biHeight),
- &ImageSize
- )) {
-
- Status = STATUS_INVALID_PARAMETER;
- }
-
- //
- // We only support KS_BI_RGB (24) and KS_BI_YUV422 (16), so
- // this is valid for those formats.
- //
- else if (!MultiplyCheckOverflow (
- ImageSize,
- (ULONG)(ConnectionFormat->
- VideoInfoHeader.bmiHeader.biBitCount / 8),
- &ImageSize
- )) {
-
- Status = STATUS_INVALID_PARAMETER;
-
- }
-
- //
- // Valid for the formats we use. Otherwise, this would be
- // checked later.
- //
- else if (ConnectionFormat->VideoInfoHeader.bmiHeader.biSizeImage <
- ImageSize) {
-
- Status = STATUS_INVALID_PARAMETER;
-
- } else {
-
- //
- // We can accept the format.
- //
- Status = STATUS_SUCCESS;
-
- //
- // OldFormat is an indication that this is a format change.
- // Since I do not implement the
- // KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT, by default, I do
- // not handle dynamic format changes.
- //
- // If something changes while we're in the stop state, we're
- // fine to handle it since we haven't "configured the hardware"
- // yet.
- //
- if (OldFormat) {
- //
- // If we're in the stop state, we can handle just about any
- // change. We don't support dynamic format changes.
- //
- if (Pin -> DeviceState == KSSTATE_STOP) {
- if (!CapPin -> CaptureVideoInfoHeader ()) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
- } else {
- //
- // Because we don't accept dynamic format changes, we
- // should never get here. Just being over-protective.
- //
- Status = STATUS_INVALID_DEVICE_STATE;
- }
- }
-
- }
-
- }
-
- }
- return Status;
-}
-
-/**************************************************************************
-
- LOCKED CODE
-
-**************************************************************************/
-
-#ifdef ALLOC_PRAGMA
-#pragma code_seg()
-#endif // ALLOC_PRAGMA
-
-void
-CCapturePin::
-CompleteMappings (
- IN ULONG NumMappings
- )
-
-/*++
-
-Routine Description:
-
- Called to notify the pin that a given number of scatter / gather
- mappings have completed. Let the buffers go if possible.
- We're called at DPC.
-
-Arguments:
-
- NumMappings -
- The number of mappings that have completed.
-
-Return Value:
-
- None
-
---*/
-
-{
-
- ULONG MappingsRemaining = NumMappings;
-
- //
- // Walk through the clones list and delete clones whose time has come.
- // The list is guaranteed to be kept in the order they were cloned.
- //
- PKSSTREAM_POINTER Clone = KsPinGetFirstCloneStreamPointer (m_Pin);
-
- while (MappingsRemaining && Clone) {
-
- PKSSTREAM_POINTER NextClone = KsStreamPointerGetNextClone (Clone);
-
-#if defined(_X86_)
- //
- // Count up the number of bytes we've completed and mark this
- // in the Stream Header. In mapped queues
- // (KSPIN_FLAG_GENERATE_MAPPINGS), this is the responsibility of
- // the minidriver. In non-mapped queues, AVStream performs this.
- //
- ULONG MappingsToCount =
- (MappingsRemaining > Clone -> OffsetOut.Remaining) ?
- Clone -> OffsetOut.Remaining :
- MappingsRemaining;
-
- //
- // Update DataUsed according to the mappings.
- //
- for (ULONG CurMapping = 0; CurMapping < MappingsToCount; CurMapping++) {
- Clone -> StreamHeader -> DataUsed +=
- Clone -> OffsetOut.Mappings [CurMapping].ByteCount;
- }
-#endif
-
- //
- // If we have completed all remaining mappings in this clone, it
- // is an indication that the clone is ready to be deleted and the
- // buffer released. Set anything required in the stream header which
- // has not yet been set. If we have a clock, we can timestamp the
- // sample.
- //
-#if !defined(_X86_)
- if (Clone -> StreamHeader -> DataUsed >= Clone -> OffsetOut.Remaining) {
-#else
- if (MappingsRemaining >= Clone -> OffsetOut.Remaining) {
-#endif
- Clone -> StreamHeader -> Duration =
- m_VideoInfoHeader -> AvgTimePerFrame;
-
- Clone -> StreamHeader -> PresentationTime.Numerator =
- Clone -> StreamHeader -> PresentationTime.Denominator = 1;
-
- //
- // If a clock has been assigned, timestamp the packets with the
- // time shown on the clock.
- //
- if (m_Clock) {
-
- LONGLONG ClockTime = m_Clock -> GetTime ();
-
- Clone -> StreamHeader -> PresentationTime.Time = ClockTime;
-
- Clone -> StreamHeader -> OptionsFlags =
- KSSTREAM_HEADER_OPTIONSF_TIMEVALID |
- KSSTREAM_HEADER_OPTIONSF_DURATIONVALID;
-
- } else {
- //
- // If there is no clock, don't time stamp the packets.
- //
- Clone -> StreamHeader -> PresentationTime.Time = 0;
-
- }
-
- //
- // Increment the frame number. This is the total count of frames which
- // have attempted capture.
- //
- m_FrameNumber++;
-
- //
- // Double check the Stream Header size. AVStream makes no guarantee
- // that because StreamHeaderSize is set to a specific size that you
- // will get that size. If the proper data type handlers are not
- // installed, the stream header will be of default size.
- //
- if ( Clone -> StreamHeader -> Size >= sizeof (KSSTREAM_HEADER) +
- sizeof (KS_FRAME_INFO)) {
-
- PKS_FRAME_INFO FrameInfo = reinterpret_cast <PKS_FRAME_INFO> (
- Clone -> StreamHeader + 1
- );
-
- FrameInfo -> ExtendedHeaderSize = sizeof (KS_FRAME_INFO);
- FrameInfo -> dwFrameFlags = KS_VIDEO_FLAG_FRAME;
- FrameInfo -> PictureNumber = (LONGLONG)m_FrameNumber;
-
- // I don't really have a way to tell if the device has dropped a frame
- // or was not able to send a frame on time.
- FrameInfo -> DropCount = (LONGLONG)m_DroppedFrames;
- }
-
-
- //
- // If all of the mappings in this clone have been completed,
- // delete the clone. We've already updated DataUsed above.
- //
-
-#if !defined(_X86_)
- MappingsRemaining--;
-#else
- MappingsRemaining -= Clone -> OffsetOut.Remaining;
-#endif
- KsStreamPointerDelete (Clone);
-
- } else {
- //
- // If only part of the mappings in this clone have been completed,
- // update the pointers. Since we're guaranteed this won't advance
- // to a new frame by the check above, it won't fail.
- //
-#if !defined(_X86_)
- (void)KsStreamPointerAdvanceOffsets (
- Clone,
- 0,
- Clone -> StreamHeader -> DataUsed,
- FALSE
- );
-
-#else
- (void)KsStreamPointerAdvanceOffsets (
- Clone,
- 0,
- MappingsRemaining,
- FALSE
- );
-
-#endif
- MappingsRemaining = 0;
-
- }
-
- //
- // Go to the next clone.
- //
- Clone = NextClone;
-
- }
-
- //
- // If we've used all the mappings in hardware and pended, we can kick
- // processing to happen again if we've completed mappings.
- //
- if (m_PendIo) {
- m_PendIo = TRUE;
- KsPinAttemptProcessing (m_Pin, TRUE);
- }
-
-}
-
-/**************************************************************************
-
- DISPATCH AND DESCRIPTOR LAYOUT
-
-**************************************************************************/
-
-//
-// FormatRGB24Bpp_Capture:
-//
-// This is the data range description of the RGB24 capture format we support.
-//
-const
-KS_DATARANGE_VIDEO
-FormatRGB24Bpp_Capture = {
-
- //
- // KSDATARANGE
- //
- {
- sizeof (KS_DATARANGE_VIDEO), // FormatSize
- 0, // Flags
- D_X * D_Y * 3, // SampleSize
- 0, // Reserved
-
- STATICGUIDOF (KSDATAFORMAT_TYPE_VIDEO), // aka. MEDIATYPE_Video
- 0xe436eb7d, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20,
- 0xaf, 0x0b, 0xa7, 0x70, // aka. MEDIASUBTYPE_RGB24,
- STATICGUIDOF (KSDATAFORMAT_SPECIFIER_VIDEOINFO) // aka. FORMAT_VideoInfo
- },
-
- TRUE, // BOOL, bFixedSizeSamples (all samples same size?)
- FALSE, // BOOL, bTemporalCompression (all I frames?)
- 0, // Reserved (was StreamDescriptionFlags)
- 0, // Reserved (was MemoryAllocationFlags
- // (KS_VIDEO_ALLOC_*))
- //
- // _KS_VIDEO_STREAM_CONFIG_CAPS
- //
- {
- STATICGUIDOF( KSDATAFORMAT_SPECIFIER_VIDEOINFO ), // GUID
- KS_AnalogVideo_None, // AnalogVideoStandard
- D_X,D_Y, // InputSize, (the inherent size of the incoming signal
- // with every digitized pixel unique)
- D_X,D_Y, // MinCroppingSize, smallest rcSrc cropping rect allowed
- D_X,D_Y, // MaxCroppingSize, largest rcSrc cropping rect allowed
- 8, // CropGranularityX, granularity of cropping size
- 1, // CropGranularityY
- 8, // CropAlignX, alignment of cropping rect
- 1, // CropAlignY;
- D_X, D_Y, // MinOutputSize, smallest bitmap stream can produce
- D_X, D_Y, // MaxOutputSize, largest bitmap stream can produce
- 8, // OutputGranularityX, granularity of output bitmap size
- 1, // OutputGranularityY;
- 0, // StretchTapsX (0 no stretch, 1 pix dup, 2 interp...)
- 0, // StretchTapsY
- 0, // ShrinkTapsX
- 0, // ShrinkTapsY
- 333667, // MinFrameInterval, 100 nS units
- 640000000, // MaxFrameInterval, 100 nS units
- 8 * 3 * 30 * D_X * D_Y, // MinBitsPerSecond;
- 8 * 3 * 30 * D_X * D_Y // MaxBitsPerSecond;
- },
-
- //
- // KS_VIDEOINFOHEADER (default format)
- //
- {
- 0,0,0,0, // RECT rcSource;
- 0,0,0,0, // RECT rcTarget;
- D_X * D_Y * 3 * 8 * 30, // DWORD dwBitRate;
- 0L, // DWORD dwBitErrorRate;
- 333667, // REFERENCE_TIME AvgTimePerFrame;
- sizeof (KS_BITMAPINFOHEADER), // DWORD biSize;
- D_X, // LONG biWidth;
- D_Y, // LONG biHeight;
- 1, // WORD biPlanes;
- 24, // WORD biBitCount;
- KS_BI_RGB, // DWORD biCompression;
- D_X * D_Y * 3, // DWORD biSizeImage;
- 0, // LONG biXPelsPerMeter;
- 0, // LONG biYPelsPerMeter;
- 0, // DWORD biClrUsed;
- 0 // DWORD biClrImportant;
- }
-};
-
-//
-// FormatYUY2_Capture:
-//
-// This is the data range description of the YUY2 format we support.
-//
-const
-KS_DATARANGE_VIDEO
-FormatYUY2_Capture = {
-
- //
- // KSDATARANGE
- //
- {
- sizeof (KS_DATARANGE_VIDEO), // FormatSize
- 0, // Flags
- DMAX_X * DMAX_Y * 2, // SampleSize
- 0, // Reserved
- STATICGUIDOF (KSDATAFORMAT_TYPE_VIDEO), // aka. MEDIATYPE_Video
- 0x32595559, 0x0000, 0x0010, 0x80, 0x00,
- 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71, //aka. MEDIASUBTYPE_YUY2,
- STATICGUIDOF (KSDATAFORMAT_SPECIFIER_VIDEOINFO) // aka. FORMAT_VideoInfo
- },
-
- TRUE, // BOOL, bFixedSizeSamples (all samples same size?)
- FALSE, // BOOL, bTemporalCompression (all I frames?)
- 0, // Reserved (was StreamDescriptionFlags)
- 0, // Reserved (was MemoryAllocationFlags
- // (KS_VIDEO_ALLOC_*))
-
- //
- // _KS_VIDEO_STREAM_CONFIG_CAPS
- //
- {
- STATICGUIDOF( KSDATAFORMAT_SPECIFIER_VIDEOINFO ), // GUID
- KS_AnalogVideo_None, // AnalogVideoStandard
- DMAX_X, DMAX_Y, // InputSize, (the inherent size of the incoming signal
- // with every digitized pixel unique)
- D_X,D_Y, // MinCroppingSize, smallest rcSrc cropping rect allowed
- DMAX_X, DMAX_Y, // MaxCroppingSize, largest rcSrc cropping rect allowed
- 8, // CropGranularityX, granularity of cropping size
- 1, // CropGranularityY
- 8, // CropAlignX, alignment of cropping rect
- 1, // CropAlignY;
- D_X, D_Y, // MinOutputSize, smallest bitmap stream can produce
- DMAX_X, DMAX_Y, // MaxOutputSize, largest bitmap stream can produce
- 8, // OutputGranularityX, granularity of output bitmap size
- 1, // OutputGranularityY;
- 0, // StretchTapsX (0 no stretch, 1 pix dup, 2 interp...)
- 0, // StretchTapsY
- 0, // ShrinkTapsX
- 0, // ShrinkTapsY
- 333667, // MinFrameInterval, 100 nS units
- 640000000, // MaxFrameInterval, 100 nS units
- 8 * 2 * 30 * D_X * D_Y, // MinBitsPerSecond;
- 8 * 2 * 30 * DMAX_X * DMAX_Y, // MaxBitsPerSecond;
- },
-
- //
- // KS_VIDEOINFOHEADER (default format)
- //
- {
- 0, 0, 0, 0, // RECT rcSource;
- 0, 0, 0, 0, // RECT rcTarget;
- DMAX_X * DMAX_Y * 2 * 8 * 30, // DWORD dwBitRate;
- 0L, // DWORD dwBitErrorRate;
- 333667, // REFERENCE_TIME AvgTimePerFrame;
- sizeof (KS_BITMAPINFOHEADER), // DWORD biSize;
- DMAX_X, // LONG biWidth;
- DMAX_Y, // LONG biHeight;
- 1, // WORD biPlanes;
- 16, // WORD biBitCount;
- FOURCC_YUY2, // DWORD biCompression;
- DMAX_X * DMAX_Y * 2, // DWORD biSizeImage;
- 0, // LONG biXPelsPerMeter;
- 0, // LONG biYPelsPerMeter;
- 0, // DWORD biClrUsed;
- 0 // DWORD biClrImportant;
- }
-};
-
-//
-// CapturePinDispatch:
-//
-// This is the dispatch table for the capture pin. It provides notifications
-// about creation, closure, processing, data formats, etc...
-//
-const
-KSPIN_DISPATCH
-CapturePinDispatch = {
- CCapturePin::DispatchCreate, // Pin Create
- NULL, // Pin Close
- CCapturePin::DispatchProcess, // Pin Process
- NULL, // Pin Reset
- CCapturePin::DispatchSetFormat, // Pin Set Data Format
- CCapturePin::DispatchSetState, // Pin Set Device State
- NULL, // Pin Connect
- NULL, // Pin Disconnect
- NULL, // Clock Dispatch
- NULL // Allocator Dispatch
-};
-
-//
-// CapturePinAllocatorFraming:
-//
-// This is the simple framing structure for the capture pin. Note that this
-// will be modified via KsEdit when the actual capture format is determined.
-//
-DECLARE_SIMPLE_FRAMING_EX (
- CapturePinAllocatorFraming,
- STATICGUIDOF (KSMEMORY_TYPE_KERNEL_NONPAGED),
- KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY |
- KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY,
- 2,
- 0,
- 2 * PAGE_SIZE,
- 2 * PAGE_SIZE
- );
-
-//
-// CapturePinDataRanges:
-//
-// This is the list of data ranges supported on the capture pin. We support
-// two: one RGB24, and one YUY2.
-//
-const
-PKSDATARANGE
-CapturePinDataRanges [CAPTURE_PIN_DATA_RANGE_COUNT] = {
- (PKSDATARANGE) &FormatYUY2_Capture,
- (PKSDATARANGE) &FormatRGB24Bpp_Capture
- };