You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
263 lines
7.2 KiB
263 lines
7.2 KiB
/**************************************************************************
|
|
|
|
AVStream Simulated Hardware Sample
|
|
|
|
Copyright (c) 2001, Microsoft Corporation.
|
|
|
|
File:
|
|
|
|
capture.h
|
|
|
|
Abstract:
|
|
|
|
This file contains header 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
|
|
|
|
**************************************************************************/
|
|
|
|
//
|
|
// STREAM_POINTER_CONTEXT:
|
|
//
|
|
// This is the context structure we associate with all clone stream pointers.
|
|
// It allows the mapping code to rip apart the buffer into chunks the same
|
|
// size as the scatter/gather mappings in order to fake scatter / gather
|
|
// bus-master DMA.
|
|
//
|
|
typedef struct _STREAM_POINTER_CONTEXT {
|
|
|
|
PUCHAR BufferVirtual;
|
|
|
|
} STREAM_POINTER_CONTEXT, *PSTREAM_POINTER_CONTEXT;
|
|
|
|
//
|
|
// CCapturePin:
|
|
//
|
|
// The video capture pin class.
|
|
//
|
|
class CCapturePin :
|
|
public ICaptureSink {
|
|
|
|
private:
|
|
|
|
//
|
|
// The AVStream pin we're associated with.
|
|
//
|
|
PKSPIN m_Pin;
|
|
|
|
//
|
|
// Pointer to the internal device object for our capture device.
|
|
// We access the "fake" hardware through this object.
|
|
//
|
|
CCaptureDevice *m_Device;
|
|
|
|
//
|
|
// The state we've put the hardware into. This allows us to keep track
|
|
// of whether to do things like unpausing or restarting.
|
|
//
|
|
HARDWARE_STATE m_HardwareState;
|
|
|
|
//
|
|
// The clock we've been assigned. As with other capture filters, we do
|
|
// not expose a clock. If one has been assigned, we will use it to
|
|
// time stamp packets (plus a reasonable delta to work the capture stream
|
|
// in a preview graph).
|
|
//
|
|
PIKSREFERENCECLOCK m_Clock;
|
|
|
|
//
|
|
// The transport information for this capture pin. The settings for "fake" hardware will be
|
|
// programmed for this transport info.
|
|
//
|
|
PBDA_TRANSPORT_INFO m_TransportInfo;
|
|
|
|
//
|
|
// If we are unable to insert all of the mappings in a stream pointer into
|
|
// the "fake" hardware's scatter / gather table, we set this to the
|
|
// stream pointer that's incomplete. This is done both to make the
|
|
// relasing easier and to make it easier to fake the scatter / gather
|
|
// hardware.
|
|
//
|
|
PKSSTREAM_POINTER m_PreviousStreamPointer;
|
|
|
|
//
|
|
// An indication of whether or not we pended I/O for some reason. If this
|
|
// is set, the DPC will resume I/O when any mappings are completed.
|
|
//
|
|
BOOLEAN m_PendIo;
|
|
|
|
//
|
|
// An indication of whether or not this pin has acquired the necessary
|
|
// hardware resources to operate. When the pin reaches KSSTATE_ACQUIRE,
|
|
// we attempt to acquire the hardware. This flag will be set based on
|
|
// our success / failure.
|
|
//
|
|
BOOLEAN m_AcquiredResources;
|
|
|
|
//
|
|
// CleanupReferences():
|
|
//
|
|
// Clean up any references we hold on frames in the queue. This is called
|
|
// when we abruptly stop the fake hardware.
|
|
//
|
|
NTSTATUS
|
|
CleanupReferences (
|
|
);
|
|
|
|
//
|
|
// SetState():
|
|
//
|
|
// This is the state transition handler for the capture pin. It attempts
|
|
// to acquire resources for the capture pin (or releasing them if
|
|
// necessary) and starts and stops the hardware as required.
|
|
//
|
|
NTSTATUS
|
|
SetState (
|
|
IN KSSTATE ToState,
|
|
IN KSSTATE FromState
|
|
);
|
|
|
|
//
|
|
// Process():
|
|
//
|
|
// This is the processing dispatch for the capture pin. It handles
|
|
// programming the scatter / gather tables for the hardware as buffers
|
|
// become available. This processing routine is designed for a direct
|
|
// into the capture buffers kind of DMA as opposed to common-buffer
|
|
// and copy strategies.
|
|
//
|
|
NTSTATUS
|
|
Process (
|
|
);
|
|
|
|
//
|
|
// CaptureBdaTransportInfo():
|
|
//
|
|
// This routine stashes the BDA Transport Info for the pin connection
|
|
// in the CCapturePin object. This is used to base hardware settings.
|
|
//
|
|
PBDA_TRANSPORT_INFO
|
|
CaptureBdaTransportInfo (
|
|
);
|
|
|
|
//
|
|
// Cleanup():
|
|
//
|
|
// This is the free callback from the bagged item (CCapturePin). If we
|
|
// do not provide a callback when we bag the CCapturePin, ExFreePool
|
|
// would be called. This is not desirable for C++ constructed objects.
|
|
// We merely delete the object here.
|
|
//
|
|
static
|
|
void
|
|
Cleanup (
|
|
IN CCapturePin *Pin
|
|
)
|
|
{
|
|
delete Pin;
|
|
}
|
|
|
|
public:
|
|
|
|
//
|
|
// CCapturePin():
|
|
//
|
|
// The capture pin's constructor. Initialize any non-0, non-NULL fields
|
|
// (since new will have zero'ed the memory anyway) and set up our
|
|
// device level pointers for access during capture routines.
|
|
//
|
|
CCapturePin (
|
|
IN PKSPIN Pin
|
|
);
|
|
|
|
//
|
|
// ~CCapturePin():
|
|
//
|
|
// The capture pin's destructor.
|
|
//
|
|
~CCapturePin (
|
|
)
|
|
{
|
|
}
|
|
|
|
//
|
|
// ICaptureSink::CompleteMappings()
|
|
//
|
|
// This is the capture sink notification mechanism for mapping completion.
|
|
// When the device DPC detects that a given number of mappings have been
|
|
// completed by the fake hardware, it signals the capture sink of this
|
|
// through this method.
|
|
//
|
|
virtual
|
|
void
|
|
CompleteMappings (
|
|
IN ULONG NumMappings
|
|
);
|
|
|
|
/*************************************************
|
|
|
|
Dispatch Routines
|
|
|
|
*************************************************/
|
|
|
|
//
|
|
// DispatchCreate():
|
|
//
|
|
// This is the creation dispatch for the capture pin. It creates
|
|
// the CCapturePin object and associates it with the AVStream object
|
|
// bagging it in the process.
|
|
//
|
|
static
|
|
NTSTATUS
|
|
DispatchCreate (
|
|
IN PKSPIN Pin,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
//
|
|
// DispatchSetState():
|
|
//
|
|
// This is the set device state dispatch for the pin. The routine bridges
|
|
// to SetState() in the context of the CCapturePin.
|
|
//
|
|
static
|
|
NTSTATUS
|
|
DispatchSetState (
|
|
IN PKSPIN Pin,
|
|
IN KSSTATE ToState,
|
|
IN KSSTATE FromState
|
|
)
|
|
{
|
|
return
|
|
(reinterpret_cast <CCapturePin *> (Pin -> Context)) ->
|
|
SetState (ToState, FromState);
|
|
}
|
|
|
|
//
|
|
// DispatchProcess():
|
|
//
|
|
// This is the processing dispatch for the capture pin. The routine
|
|
// bridges to Process() in the context of the CCapturePin.
|
|
//
|
|
static
|
|
NTSTATUS
|
|
DispatchProcess (
|
|
IN PKSPIN Pin
|
|
)
|
|
{
|
|
return
|
|
(reinterpret_cast <CCapturePin *> (Pin -> Context)) ->
|
|
Process ();
|
|
}
|
|
};
|
|
|